Annotation of ntddk/src/scsi/qic117/main.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1993 - Colorado Memory Systems, Inc.
                      4: All Rights Reserved
                      5: 
                      6: Module Name:
                      7: 
                      8:     main.c
                      9: 
                     10: Abstract:
                     11: 
                     12:     This is the tape class driver.
                     13: 
                     14: Revision History:
                     15: 
                     16: 
                     17: 
                     18: 
                     19: --*/
                     20: 
                     21: //
                     22: // Includes
                     23: //
                     24: 
                     25: #include <ntddk.h>
                     26: #include <ntddtape.h>   // tape device driver I/O control codes
                     27: #include <ntiologc.h>
                     28: #include "common.h"
                     29: #include "q117.h"
                     30: #include "cms.h"
                     31: #include "protos.h"
                     32: #include "hilevel.h"
                     33: #include "q117log.h"
                     34: 
                     35: //
                     36: // Protos for entry points
                     37: //
                     38: 
                     39: NTSTATUS
                     40: q117CreateNumericKey(
                     41:     IN HANDLE Root,
                     42:     IN ULONG Name,
                     43:     IN PWSTR Prefix,
                     44:     OUT PHANDLE NewKey
                     45:     );
                     46: 
                     47: NTSTATUS
                     48: q117CreateRegistryInfo(
                     49:     IN ULONG TapeNumber,
                     50:     IN PUNICODE_STRING RegistryPath,
                     51:     IN PQ117_CONTEXT Context
                     52:     );
                     53: 
                     54: #ifdef ALLOC_PRAGMA
                     55: #pragma alloc_text(init,q117Initialize)
                     56: #endif
                     57: 
                     58: 
                     59: //
                     60: // Start of code
                     61: //
                     62: 
                     63: 
                     64: NTSTATUS
                     65: q117Initialize(
                     66:     IN PDRIVER_OBJECT DriverObject,
                     67:     IN PDEVICE_OBJECT q117iDeviceObject,
                     68:     IN PUNICODE_STRING RegistryPath,
                     69:     PADAPTER_OBJECT AdapterObject,
                     70:     ULONG           NumberOfMapRegisters
                     71:     )
                     72: 
                     73: /*++
                     74: 
                     75: Routine Description:
                     76: 
                     77:     This routine initializes the SCSI Tape class driver.
                     78: 
                     79: Arguments:
                     80: 
                     81:     DriverObject
                     82: 
                     83: Return Value:
                     84: 
                     85:     NT Status
                     86: 
                     87: --*/
                     88: 
                     89: {
                     90:     PDEVICE_OBJECT  q117DeviceObject;
                     91:     NTSTATUS        status;
                     92:     UNICODE_STRING  ntUnicodeString;
                     93:     UCHAR           ntNameBuffer[256];
                     94:     STRING          ntNameString;
                     95:     BOOLEAN         tapeDeviceFound = FALSE;
                     96:     PQ117_CONTEXT   context;
                     97:     ULONG           tapeNumber;
                     98:     STRING          dosString;
                     99:     UNICODE_STRING  dosUnicodeString;
                    100:     CCHAR           dosNameBuffer[64];
                    101: 
                    102:     //
                    103:     // Build the unicode name for the floppy tape.
                    104:     //
                    105:     tapeNumber = IoGetConfigurationInformation()->TapeCount;
                    106: 
                    107:     sprintf(ntNameBuffer,
                    108:             "\\Device\\Tape%d",
                    109:             tapeNumber);
                    110: 
                    111:     RtlInitString(&ntNameString, ntNameBuffer);
                    112: 
                    113:     status = RtlAnsiStringToUnicodeString(
                    114:         &ntUnicodeString,
                    115:         &ntNameString,
                    116:         TRUE );
                    117: 
                    118:     if (!NT_SUCCESS(status)) {
                    119:         return(status);
                    120:     }
                    121: 
                    122:     //
                    123:     // Create a device object for this floppy drive.
                    124:     //
                    125: 
                    126:     status = IoCreateDevice(
                    127:         DriverObject,
                    128:         sizeof( struct _Q117_CONTEXT ),
                    129:         &ntUnicodeString,
                    130:         FILE_DEVICE_UNKNOWN,
                    131:         FILE_REMOVABLE_MEDIA,
                    132:         FALSE,
                    133:         &q117DeviceObject );
                    134: 
                    135: 
                    136:     if (!NT_SUCCESS(status)) {
                    137:         return(status);
                    138:     }
                    139: 
                    140:     //
                    141:     // Create the DOS port driver name.
                    142:     //
                    143: 
                    144:     sprintf(dosNameBuffer,
                    145:             "\\DosDevices\\TAPE%d",
                    146:             tapeNumber);
                    147: 
                    148:     RtlInitString(&dosString, dosNameBuffer);
                    149: 
                    150:     status = RtlAnsiStringToUnicodeString(&dosUnicodeString,
                    151:                                           &dosString,
                    152:                                           TRUE);
                    153: 
                    154:     if (!NT_SUCCESS(status)) {
                    155: 
                    156:         dosUnicodeString.Buffer = NULL;
                    157: 
                    158:     } else {
                    159: 
                    160:         IoAssignArcName(&dosUnicodeString, &ntUnicodeString);
                    161: 
                    162:     }
                    163: 
                    164:     RtlFreeUnicodeString(&ntUnicodeString);
                    165: 
                    166:     if (dosUnicodeString.Buffer != NULL) {
                    167: 
                    168:         RtlFreeUnicodeString(&dosUnicodeString);
                    169: 
                    170:     }
                    171: 
                    172: 
                    173:     //
                    174:     // Increment system tape count.
                    175:     //
                    176:     ++IoGetConfigurationInformation()->TapeCount;
                    177: 
                    178:     //
                    179:     // Get device extension address.
                    180:     //
                    181: 
                    182:     context = q117DeviceObject->DeviceExtension;
                    183:     context->q117iDeviceObject = q117iDeviceObject;
                    184: 
                    185:     //
                    186:     // Allocate memory for the filer
                    187:     //
                    188: 
                    189:     status = q117AllocatePermanentMemory(
                    190:         context,
                    191:         AdapterObject,
                    192:         NumberOfMapRegisters
                    193:         );
                    194: 
                    195:     if (status) {
                    196:         IoDeleteDevice(q117DeviceObject);
                    197:         return status;
                    198:     }
                    199: 
                    200:     //
                    201:     // Indicate MDLs required.
                    202:     //
                    203: 
                    204:     q117DeviceObject->Flags = DO_DIRECT_IO;
                    205: 
                    206:     status = q117CreateRegistryInfo(tapeNumber, RegistryPath, context);
                    207: 
                    208:     q117RdsInitReed();
                    209: 
                    210:     return status;
                    211: 
                    212: } // end Q117Initialize()
                    213: 
                    214: NTSTATUS
                    215: q117CreateRegistryInfo(
                    216:     IN ULONG TapeNumber,
                    217:     IN PUNICODE_STRING RegistryPath,
                    218:     IN PQ117_CONTEXT Context
                    219:     )
                    220: 
                    221: /*++
                    222: 
                    223: Routine Description:
                    224: 
                    225:     This function adds Tape\Unit x to the devicemap and puts the Id info
                    226:     and type info values in it.
                    227: 
                    228: Arguments:
                    229: 
                    230:     tapeNumber - unit number of the tape (current tape count)
                    231: 
                    232:     Context - current context of the driver (this is used to
                    233:                 identify the device).
                    234: 
                    235: 
                    236: Return Value:
                    237: 
                    238:    Returns the status of the operation.
                    239: 
                    240: --*/
                    241: 
                    242: {
                    243:     HANDLE          lunKey;
                    244:     HANDLE          unitKey;
                    245:     UNICODE_STRING  ntUnicodeString;
                    246:     UCHAR           ntNameBuffer[80];
                    247:     STRING          ntNameString;
                    248:     UNICODE_STRING  name;
                    249:     OBJECT_ATTRIBUTES objectAttributes;
                    250:     ULONG           disposition;
                    251:     NTSTATUS        status;
                    252: 
                    253:     //
                    254:     // Create the Tape key in the device map.
                    255:     //
                    256: 
                    257:     RtlInitUnicodeString(
                    258:         &name,
                    259:         L"\\Registry\\Machine\\Hardware\\DeviceMap\\Tape"
                    260:         );
                    261: 
                    262:     //
                    263:     // Initialize the object for the key.
                    264:     //
                    265: 
                    266:     InitializeObjectAttributes( &objectAttributes,
                    267:                                 &name,
                    268:                                 OBJ_CASE_INSENSITIVE,
                    269:                                 NULL,
                    270:                                 (PSECURITY_DESCRIPTOR) NULL );
                    271: 
                    272:     //
                    273:     // Create the key or open it.
                    274:     //
                    275: 
                    276:     status = ZwCreateKey(&lunKey,
                    277:                         KEY_READ | KEY_WRITE,
                    278:                         &objectAttributes,
                    279:                         0,
                    280:                         (PUNICODE_STRING) NULL,
                    281:                         REG_OPTION_VOLATILE,
                    282:                         &disposition );
                    283: 
                    284:     if (!NT_SUCCESS(status)) {
                    285:         return status;
                    286:     }
                    287: 
                    288:     status = q117CreateNumericKey(lunKey, TapeNumber, L"Unit ", &unitKey);
                    289: 
                    290:     ZwClose(lunKey);
                    291: 
                    292:     if (!NT_SUCCESS(status)) {
                    293:         return status;
                    294:     }
                    295: 
                    296: 
                    297:     //
                    298:     // Add Identifier value.
                    299:     //
                    300: 
                    301:     RtlInitUnicodeString(&name, L"Identifier");
                    302: 
                    303:     status = ZwSetValueKey(
                    304:         unitKey,
                    305:         &name,
                    306:         0,
                    307:         REG_SZ,
                    308:         L"QIC-40/QIC-80 floppy tape drive",
                    309:         sizeof(L"QIC-40/QIC-80 floppy tape drive")
                    310:         );
                    311: 
                    312:     if ( NT_SUCCESS(status) ) {
                    313:         //
                    314:         // Add driver value.
                    315:         //
                    316: 
                    317:         RtlInitUnicodeString(&name, L"Driver");
                    318: 
                    319:         status = ZwSetValueKey(
                    320:             unitKey,
                    321:             &name,
                    322:             0,
                    323:             REG_SZ,
                    324:             RegistryPath->Buffer,
                    325:             RegistryPath->Length
                    326:             );
                    327:     }
                    328: 
                    329:     if ( NT_SUCCESS(status) ) {
                    330:         //
                    331:         // Add DeviceName value.
                    332:         //
                    333: 
                    334:         RtlInitUnicodeString(&name, L"DeviceName");
                    335: 
                    336:         sprintf(ntNameBuffer,
                    337:                 "Tape%d",
                    338:                 TapeNumber);
                    339: 
                    340:         RtlInitString(&ntNameString, ntNameBuffer);
                    341: 
                    342:         status = RtlAnsiStringToUnicodeString(&ntUnicodeString,
                    343:                                               &ntNameString,
                    344:                                               TRUE);
                    345: 
                    346:         status = ZwSetValueKey(
                    347:             unitKey,
                    348:             &name,
                    349:             0,
                    350:             REG_SZ,
                    351:             ntUnicodeString.Buffer,
                    352:             ntUnicodeString.Length
                    353:             );
                    354: 
                    355:         RtlFreeUnicodeString(&ntUnicodeString);
                    356:     }
                    357: 
                    358:     if ( NT_SUCCESS(status) ) {
                    359:         //
                    360:         // Add UniqueID
                    361:         //
                    362: 
                    363:         RtlInitUnicodeString(&name, L"UniqueId");
                    364: 
                    365:         status = ZwSetValueKey(
                    366:             unitKey,
                    367:             &name,
                    368:             0,
                    369:             REG_SZ,
                    370:             L"",
                    371:             0
                    372:             );
                    373:     }
                    374: 
                    375: 
                    376:     ZwClose(unitKey);
                    377: 
                    378:     return status;
                    379: 
                    380: } // end q117CreateRegistryInfo
                    381: 
                    382: NTSTATUS
                    383: q117CreateNumericKey(
                    384:     IN HANDLE Root,
                    385:     IN ULONG Name,
                    386:     IN PWSTR Prefix,
                    387:     OUT PHANDLE NewKey
                    388:     )
                    389: 
                    390: /*++
                    391: 
                    392: Routine Description:
                    393: 
                    394:     This function creates a registry key.  The name of the key is a string
                    395:     version of numeric value passed in.
                    396: 
                    397: Arguments:
                    398: 
                    399:     RootKey - Supplies a handle to the key where the new key should be inserted.
                    400: 
                    401:     Name - Supplies the numeric value to name the key.
                    402: 
                    403:     Prefix - Supplies a prefix name to add to name.
                    404: 
                    405:     NewKey - Returns the handle for the new key.
                    406: 
                    407: Return Value:
                    408: 
                    409:    Returns the status of the operation.
                    410: 
                    411: --*/
                    412: 
                    413: {
                    414: 
                    415:     UNICODE_STRING string;
                    416:     UNICODE_STRING stringNum;
                    417:     OBJECT_ATTRIBUTES objectAttributes;
                    418:     WCHAR bufferNum[16];
                    419:     WCHAR buffer[64];
                    420:     ULONG disposition;
                    421:     NTSTATUS status;
                    422: 
                    423:     //
                    424:     // Copy the Prefix into a string.
                    425:     //
                    426: 
                    427:     string.Length = 0;
                    428:     string.MaximumLength=64;
                    429:     string.Buffer = buffer;
                    430: 
                    431:     RtlInitUnicodeString(&stringNum, Prefix);
                    432: 
                    433:     RtlCopyUnicodeString(&string, &stringNum);
                    434: 
                    435:     //
                    436:     // Create a port number key entry.
                    437:     //
                    438: 
                    439:     stringNum.Length = 0;
                    440:     stringNum.MaximumLength = 16;
                    441:     stringNum.Buffer = bufferNum;
                    442: 
                    443:     status = RtlIntegerToUnicodeString(Name, 10, &stringNum);
                    444: 
                    445:     if (!NT_SUCCESS(status)) {
                    446:         return status;
                    447:     }
                    448: 
                    449:     //
                    450:     // Append the prefix and the numeric name.
                    451:     //
                    452: 
                    453:     RtlAppendUnicodeStringToString(&string, &stringNum);
                    454: 
                    455:     InitializeObjectAttributes( &objectAttributes,
                    456:                                 &string,
                    457:                                 OBJ_CASE_INSENSITIVE,
                    458:                                 Root,
                    459:                                 (PSECURITY_DESCRIPTOR) NULL );
                    460: 
                    461:     status = ZwCreateKey(NewKey,
                    462:                         KEY_READ | KEY_WRITE,
                    463:                         &objectAttributes,
                    464:                         0,
                    465:                         (PUNICODE_STRING) NULL,
                    466:                         REG_OPTION_VOLATILE,
                    467:                         &disposition );
                    468: 
                    469:     return(status);
                    470: 
                    471: } // end q117CreateNumericKey
                    472: 
                    473: NTSTATUS
                    474: q117Read(
                    475:     IN PDEVICE_OBJECT DeviceObject,
                    476:     IN PIRP Irp
                    477:     )
                    478: 
                    479: /*++
                    480: 
                    481: Routine Description:
                    482: 
                    483:     This is the tape class driver IO handler routine.
                    484: 
                    485: Arguments:
                    486: 
                    487:     DeviceObject
                    488:     Irp - IO request
                    489: 
                    490: Return Value:
                    491: 
                    492:     NT Status
                    493: 
                    494: --*/
                    495: 
                    496: {
                    497: 
                    498:     PIO_STACK_LOCATION  currentIrpStack;
                    499:     KIRQL               currentIrql;
                    500:     STATUS              status;
                    501:     NTSTATUS            ntStatus;
                    502:     PVOID               usrBuf;
                    503:     PQ117_CONTEXT       context;
                    504:     ULONG               amount;
                    505:     BOOLEAN             endOfVolume = FALSE;
                    506: 
                    507: 
                    508:     context = DeviceObject->DeviceExtension;
                    509:     currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
                    510: 
                    511:     status = NoErr;
                    512:     ntStatus = STATUS_SUCCESS;
                    513: 
                    514:     //
                    515:     // If this is the first read,  find the NT volume and read
                    516:     if (context->CurrentOperation.Type == NoOperation) {
                    517: 
                    518:         ntStatus = q117OpenForRead(
                    519:                     context->CurrentOperation.BytesRead,
                    520:                     context,
                    521:                     DeviceObject);
                    522: 
                    523:         if (ntStatus == STATUS_NO_DATA_DETECTED) {
                    524: 
                    525:             //
                    526:             // Flag no bytes read (end of media,  end of data,  etc.)
                    527:             //
                    528: 
                    529:             ntStatus = STATUS_SUCCESS;
                    530:             Irp->IoStatus.Information = 0;
                    531:             endOfVolume = TRUE;
                    532: 
                    533:         }
                    534: 
                    535:     }
                    536: 
                    537: 
                    538:     if (NT_SUCCESS(ntStatus)) {
                    539: 
                    540:         //
                    541:         // Return the results of the call to the port driver.
                    542:         //
                    543:         usrBuf = MmGetSystemAddressForMdl(Irp->MdlAddress);
                    544: 
                    545:         //
                    546:         // Check to see if user is asking for more data than is there
                    547:         //  (bytes on tape - current offset)
                    548:         //
                    549: 
                    550:         amount = currentIrpStack->Parameters.Read.Length;
                    551: 
                    552:         ntStatus = q117ConvertStatus(
                    553:             DeviceObject,
                    554:             q117ReadTape(usrBuf,&amount,context)
                    555:             );
                    556: 
                    557:         //
                    558:         // Set the amount read to the amount we copied out of the buffer
                    559:         //
                    560:         Irp->IoStatus.Information = amount;
                    561: 
                    562:         CheckedDump(QIC117SHOWTD,("%x=Read(%x) - Status: %x\n",amount,currentIrpStack->Parameters.Read.Length, status));
                    563: 
                    564:     }
                    565: 
                    566:     if (endOfVolume && NT_SUCCESS(ntStatus)) {
                    567: 
                    568:         status = STATUS_NO_DATA_DETECTED;
                    569: 
                    570:     }
                    571: 
                    572:     Irp->IoStatus.Status = ntStatus;
                    573: 
                    574:     KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
                    575:     IoCompleteRequest(Irp, 0);
                    576:     KeLowerIrql(currentIrql);
                    577: 
                    578:     return ntStatus;
                    579: 
                    580: 
                    581: } // end Q117Read()
                    582: 
                    583: 
                    584: NTSTATUS
                    585: q117Write(
                    586:     IN PDEVICE_OBJECT DeviceObject,
                    587:     IN PIRP Irp
                    588:     )
                    589: 
                    590: /*++
                    591: 
                    592: Routine Description:
                    593: 
                    594:     This is the tape class driver IO handler routine.
                    595: 
                    596: Arguments:
                    597: 
                    598:     DeviceObject
                    599:     Irp - IO request
                    600: 
                    601: Return Value:
                    602: 
                    603:     NT Status
                    604: 
                    605: --*/
                    606: 
                    607: {
                    608: 
                    609:     PIO_STACK_LOCATION  currentIrpStack;
                    610:     KIRQL               currentIrql;
                    611:     STATUS              status;
                    612:     NTSTATUS            ntStatus;
                    613:     PVOID               usrBuf;
                    614:     PQ117_CONTEXT       context;
                    615: 
                    616:     context = DeviceObject->DeviceExtension;
                    617:     currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
                    618: 
                    619:     //
                    620:     // Make sure we are in write mode
                    621:     //
                    622:     status = q117OpenForWrite(context);
                    623: 
                    624:     if (!status) {
                    625: 
                    626:         //
                    627:         // Return the results of the call to the port driver.
                    628:         //
                    629:         usrBuf = MmGetSystemAddressForMdl(Irp->MdlAddress);
                    630: 
                    631:         status = q117WriteTape(usrBuf,currentIrpStack->Parameters.Write.Length,context);
                    632:         //
                    633:         // Set the amount written to the amount we copied out of the buffer
                    634:         //
                    635:         if (!status || status == EarlyWarning)
                    636:             Irp->IoStatus.Information = currentIrpStack->Parameters.Write.Length;
                    637:     }
                    638: 
                    639:     ntStatus = q117ConvertStatus(DeviceObject, status);
                    640: 
                    641:     Irp->IoStatus.Status = ntStatus;
                    642: 
                    643:     KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
                    644:     IoCompleteRequest(Irp, 0);
                    645:     KeLowerIrql(currentIrql);
                    646: 
                    647:     return ntStatus;
                    648: 
                    649: } // end Q117Write()
                    650: 
                    651: NTSTATUS
                    652: q117ConvertStatus(
                    653:     IN PDEVICE_OBJECT DeviceObject,
                    654:     IN STATUS Status
                    655:     )
                    656: {
                    657:     NTSTATUS            ntStatus;
                    658:     PQ117_CONTEXT       context;
                    659:     BOOLEAN             suppressLog = FALSE;
                    660: 
                    661:     context = DeviceObject->DeviceExtension;
                    662: 
                    663:     switch(Status) {
                    664:     case NoVols:
                    665:     case InvalVol:
                    666:     case EndOfVol:
                    667:         // or maybe STATUS_END_OF_RECORDED_DATA?
                    668:         ntStatus = STATUS_NO_DATA_DETECTED;
                    669:         suppressLog = TRUE;
                    670:         break;
                    671: 
                    672:     case EarlyWarning:
                    673:         ntStatus = STATUS_END_OF_MEDIA;
                    674:         suppressLog = TRUE;
                    675:         break;
                    676: 
                    677:     case NoTape:
                    678:         ntStatus = STATUS_NO_MEDIA_IN_DEVICE;
                    679:         break;
                    680: 
                    681:     case NoErr:
                    682:         ntStatus = STATUS_SUCCESS;
                    683:         break;
                    684: 
                    685: #ifndef NO_MARKS
                    686:     case FileMark:
                    687:     case LongFileMark:
                    688:     case ShortFileMark:
                    689:         ntStatus = STATUS_FILEMARK_DETECTED;
                    690:         suppressLog = TRUE;
                    691:         break;
                    692: 
                    693:     case SetMark:
                    694:         ntStatus = STATUS_SETMARK_DETECTED;
                    695:         suppressLog = TRUE;
                    696:         break;
                    697: #endif
                    698: 
                    699:     case UnknownFormat:
                    700:     case Unformat:
                    701:     case BadFmt:
                    702:         ntStatus = STATUS_UNRECOGNIZED_MEDIA;
                    703:         break;
                    704: 
                    705:     case FMemErr:
                    706:         ntStatus = STATUS_INSUFFICIENT_RESOURCES;
                    707:         break;
                    708: 
                    709:     case WProt:
                    710:         ntStatus = STATUS_MEDIA_WRITE_PROTECTED;
                    711:         break;
                    712: 
                    713:     case NewCart:
                    714:         ntStatus = STATUS_MEDIA_CHANGED;
                    715:         break;
                    716: 
                    717:     case UpdErr:
                    718:     case BadTape:
                    719:         ntStatus = STATUS_DATA_ERROR;
                    720:         break;
                    721: 
                    722:     case RdncUnsc:
                    723:         ntStatus = STATUS_CRC_ERROR;
                    724:         break;
                    725: 
                    726:     default:
                    727:         CheckedDump(QIC117DBGP,("Error %d reported\n",Status));
                    728:         ntStatus = (NTSTATUS)(STATUS_SEVERITY_WARNING << 30);
                    729:         ntStatus |= (FILE_DEVICE_TAPE << 16) & 0x3fff0000;
                    730:         ntStatus |= Status & 0x0000ffff;
                    731: 
                    732:     }
                    733: 
                    734:     if (Status != NoErr && !suppressLog) {
                    735:         NTSTATUS logStatus = q117MapStatus(Status);
                    736: 
                    737:         if (logStatus != QIC117_NOTAPE) {
                    738:             CheckedDump(QIC117SHOWTD,("Error %d logged\n",Status));
                    739:     
                    740:             q117LogError(
                    741:                 DeviceObject,
                    742:                 context->ErrorSequence++,
                    743:                 context->MajorFunction,
                    744:                 0,
                    745:                 Status,
                    746:                 ntStatus,
                    747:                 logStatus
                    748:                 );
                    749:         }
                    750: 
                    751:     } else {
                    752: #if DBG
                    753:         if (Status) {
                    754:             CheckedDump(QIC117SHOWTD,("Error %d reported to API\n",Status));
                    755:         }
                    756: #endif
                    757:     }
                    758: 
                    759:     return ntStatus;
                    760: }
                    761: 
                    762: NTSTATUS q117MapStatus(
                    763:     IN STATUS Status
                    764:     )
                    765: {
                    766:     NTSTATUS            mapped;
                    767: 
                    768:     switch(Status) {
                    769:         case UnusTape:
                    770:             mapped = QIC117_UNUSTAPE;
                    771:             break;
                    772:         case BadTape:
                    773:             mapped = QIC117_BADTAPE;
                    774:             break;
                    775:         case FMemErr:
                    776:             mapped = QIC117_FMEMERR;
                    777:             break;
                    778:         case TapeFull:
                    779:             mapped = QIC117_TAPEFULL;
                    780:             break;
                    781:         case VolFull:
                    782:             mapped = QIC117_VOLFULL;
                    783:             break;
                    784:         case RdncUnsc:
                    785:             mapped = QIC117_RDNCUNSC;
                    786:             break;
                    787:         case EndOfVol:
                    788:             mapped = QIC117_ENDOFVOL;
                    789:             break;
                    790:         case FCodeErr:
                    791:             mapped = QIC117_FCODEERR;
                    792:             break;
                    793:         case UpdErr:
                    794:             mapped = QIC117_UPDERR;
                    795:             break;
                    796:         case InvalVol:
                    797:             mapped = QIC117_INVALVOL;
                    798:             break;
                    799:         case NoVols:
                    800:             mapped = QIC117_NOVOLS;
                    801:             break;
                    802:         case Unformat:
                    803:             mapped = QIC117_UNFORMAT;
                    804:             break;
                    805:         case UnknownFormat:
                    806:             mapped = QIC117_UNKNOWNFORMAT;
                    807:             break;
                    808:         case BadBlk:
                    809:             mapped = QIC117_BADBLK;
                    810:             break;
                    811:         case EndTapeErr:
                    812:             mapped = QIC117_ENDTAPEERR;
                    813:             break;
                    814:         case DriveFlt:
                    815:             mapped = QIC117_DRIVEFLT;
                    816:             break;
                    817:         case WProt:
                    818:             mapped = QIC117_WPROT;
                    819:             break;
                    820:         case NoTape:
                    821:             mapped = QIC117_NOTAPE;
                    822:             break;
                    823:         case SeekErr:
                    824:             mapped = QIC117_SEEKERR;
                    825:             break;
                    826:         case NoDrive:
                    827:             mapped = QIC117_NODRIVE;
                    828:             break;
                    829:         case InvalCmd:
                    830:             mapped = QIC117_INVALCMD;
                    831:             break;
                    832:         case CodeErr:
                    833:             mapped = QIC117_CODEERR;
                    834:             break;
                    835:         case NECFlt:
                    836:             mapped = QIC117_NECFLT;
                    837:             break;
                    838:         case NoFDC:
                    839:             mapped = QIC117_NOFDC;
                    840:             break;
                    841:         case BadFmt:
                    842:             mapped = QIC117_BADFMT;
                    843:             break;
                    844:         case CmdFlt:
                    845:             mapped = QIC117_CMDFLT;
                    846:             break;
                    847:         case BadNEC:
                    848:             mapped = QIC117_BADNEC;
                    849:             break;
                    850:         case BadReq:
                    851:             mapped = QIC117_BADREQ;
                    852:             break;
                    853:         case TooFast:
                    854:             mapped = QIC117_TOOFAST;
                    855:             break;
                    856:         case NoData:
                    857:             mapped = QIC117_NODATA;
                    858:             break;
                    859:         case DAbort:
                    860:             mapped = QIC117_DABORT;
                    861:             break;
                    862:         case TapeFlt:
                    863:             mapped = QIC117_TAPEFLT;
                    864:             break;
                    865:         case UnspRate:
                    866:             mapped = QIC117_UNSPRATE;
                    867:             break;
                    868:         case Already:
                    869:             mapped = QIC117_ALREADY;
                    870:             break;
                    871:         case TooNoisy:
                    872:             mapped = QIC117_TOONOISY;
                    873:             break;
                    874:         case TimeOut:
                    875:             mapped = QIC117_TIMEOUT;
                    876:             break;
                    877:         case BadMark:
                    878:             mapped = QIC117_BADMARK;
                    879:             break;
                    880:         case NewCart:
                    881:             mapped = QIC117_NEWCART;
                    882:             break;
                    883:         case WrongFmt:
                    884:             mapped = QIC117_WRONGFMT;
                    885:             break;
                    886:         case FmtMisMatch:
                    887:             mapped = QIC117_FMTMISMATCH;
                    888:             break;
                    889:         case IncompTapeFmt:
                    890:             mapped = QIC117_INCOMPTAPEFMT;
                    891:             break;
                    892:         case SCSIFmtMsmtch:
                    893:             mapped = QIC117_SCSIFMTMSMTCH;
                    894:             break;
                    895:         case QIC40InEagle:
                    896:             mapped = QIC117_QIC40INEAGLE;
                    897:             break;
                    898:         case QIC80InEagle:
                    899:             mapped = QIC117_QIC80INEAGLE;
                    900:             break;
                    901:         case ControllerBusy:
                    902:             mapped = QIC117_CONTROLLERBUSY;
                    903:             break;
                    904:         case InQue:
                    905:             mapped = QIC117_INQUE;
                    906:             break;
                    907:         case SplitRequests:
                    908:             mapped = QIC117_SPLITREQUESTS;
                    909:             break;
                    910:         case EarlyWarning:
                    911:             mapped = QIC117_EARLYWARNING;
                    912:             break;
                    913:         default:
                    914:             mapped = QIC117_BOGUS;
                    915:     }
                    916:     return mapped;
                    917: }
                    918: 
                    919: NTSTATUS
                    920: q117DeviceControl(
                    921:     IN PDEVICE_OBJECT DeviceObject,
                    922:     IN PIRP Irp
                    923:     )
                    924: 
                    925: /*++
                    926: 
                    927: Routine Description:
                    928: 
                    929:     This routine is the dispatcher for device control requests. It
                    930:     looks at the IOCTL code and calls the appropriate tape device
                    931:     routine.
                    932: 
                    933: Arguments:
                    934: 
                    935:     DeviceObject
                    936:     Irp - Request packet
                    937: 
                    938: Return Value:
                    939: 
                    940: --*/
                    941: 
                    942: {
                    943:     PIO_STACK_LOCATION  irpStack;
                    944:     KIRQL               currentIrql;
                    945:     NTSTATUS            status;
                    946:     PQ117_CONTEXT       context;
                    947: 
                    948:     context = DeviceObject->DeviceExtension;
                    949:     irpStack = IoGetCurrentIrpStackLocation(Irp);
                    950: 
                    951:     status = 0;
                    952: 
                    953:     CheckedDump(QIC117SHOWPOLL,("Curmark: %x TotalMarks: %x\n", context->CurrentMark, context->MarkArray.TotalMarks));
                    954: 
                    955:     switch (irpStack->Parameters.DeviceIoControl.IoControlCode) {
                    956: 
                    957:     case IOCTL_TAPE_GET_DRIVE_PARAMS:
                    958: 
                    959:         status = q117IoCtlGetDriveParameters(DeviceObject, Irp);
                    960:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_GET_DRIVE_PARAMS done"));
                    961:         break;
                    962: 
                    963:     case IOCTL_TAPE_SET_DRIVE_PARAMS:
                    964: 
                    965:         status = q117IoCtlSetDriveParameters(DeviceObject, Irp);
                    966:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_SET_DRIVE_PARAMS done"));
                    967:         break;
                    968: 
                    969:     case IOCTL_TAPE_GET_MEDIA_PARAMS:
                    970: 
                    971:         status = q117IoCtlGetMediaParameters(DeviceObject, Irp);
                    972:         CheckedDump(QIC117SHOWPOLL,("IOCTL_TAPE_GET_MEDIA_PARAMS done"));
                    973:         break;
                    974: 
                    975:     case IOCTL_TAPE_SET_MEDIA_PARAMS:
                    976: 
                    977:         status = q117IoCtlSetMediaParameters(DeviceObject, Irp);
                    978:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_SET_MEDIA_PARAMS done\n"));
                    979:         break;
                    980: 
                    981:     case IOCTL_TAPE_CREATE_PARTITION:
                    982: 
                    983:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_CREATE_PARTITION attempted\n"));
                    984:         status = STATUS_INVALID_DEVICE_REQUEST;
                    985:         break;
                    986: 
                    987:     case IOCTL_TAPE_ERASE:
                    988: 
                    989:         status = q117IoCtlErase(DeviceObject, Irp);
                    990:         CheckedDump(QIC117SHOWTD,("Curmark: %x TotalMarks: %x\n", context->CurrentMark, context->MarkArray.TotalMarks));
                    991:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_ERASE done"));
                    992:         break;
                    993: 
                    994:     case IOCTL_TAPE_PREPARE:
                    995: 
                    996:         status = q117IoCtlPrepare(DeviceObject, Irp);
                    997:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_PREPARE done"));
                    998:         break;
                    999: 
                   1000:     case IOCTL_TAPE_WRITE_MARKS:
                   1001: 
                   1002:         status = q117IoCtlWriteMarks(DeviceObject, Irp);
                   1003:         CheckedDump(QIC117SHOWTD,("Curmark: %x TotalMarks: %x\n", context->CurrentMark, context->MarkArray.TotalMarks));
                   1004:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_WRITE_MARKS done"));
                   1005:         break;
                   1006: 
                   1007:     case IOCTL_TAPE_GET_POSITION:
                   1008: 
                   1009:         status = q117IoCtlGetPosition(DeviceObject, Irp);
                   1010:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_GET_POSITION done"));
                   1011:         break;
                   1012: 
                   1013:     case IOCTL_TAPE_SET_POSITION:
                   1014: 
                   1015:         status = q117IoCtlSetPosition(DeviceObject, Irp);
                   1016:         CheckedDump(QIC117SHOWTD,("Curmark: %x TotalMarks: %x\n", context->CurrentMark, context->MarkArray.TotalMarks));
                   1017:         CheckedDump(QIC117SHOWTD,("IOCTL_TAPE_SET_POSITION done"));
                   1018:         break;
                   1019: 
                   1020:     case IOCTL_TAPE_GET_STATUS:
                   1021: 
                   1022:         status = q117IoCtlGetStatus (DeviceObject, Irp);
                   1023:         CheckedDump(QIC117SHOWPOLL,("IOCTL_TAPE_GET_STATUS done"));
                   1024:         break;
                   1025: 
                   1026:     case IOCTL_CMS_WRITE_ABS_BLOCK:
                   1027: 
                   1028:         status = q117IoCtlWriteAbs(DeviceObject, Irp);
                   1029:         CheckedDump(QIC117SHOWTD,("IOCTL_CMS_WRITE_ABS_BLOCK done"));
                   1030:         break;
                   1031: 
                   1032:     case IOCTL_CMS_READ_ABS_BLOCK:
                   1033: 
                   1034:         status = q117IoCtlReadAbs(DeviceObject, Irp);
                   1035:         CheckedDump(QIC117SHOWTD,("IOCTL_CMS_READ_ABS_BLOCK done"));
                   1036:         break;
                   1037: 
                   1038: 
                   1039:     default:
                   1040: 
                   1041:         status = STATUS_INVALID_DEVICE_REQUEST;
                   1042: 
                   1043:     } // end switch()
                   1044: 
                   1045:     //
                   1046:     // Complete the request.
                   1047:     //
                   1048: 
                   1049:     CheckedDump(QIC117SHOWTD,(" -- Status:  %x\n",status));
                   1050:     Irp->IoStatus.Status = status;
                   1051: 
                   1052:     KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
                   1053:     IoCompleteRequest(Irp, 2);
                   1054:     KeLowerIrql(currentIrql);
                   1055: 
                   1056:     return status;
                   1057: 
                   1058: } // end Q117DeviceControl()
                   1059: 
                   1060: 
                   1061: NTSTATUS
                   1062: q117Create (
                   1063:     IN PDEVICE_OBJECT DeviceObject,
                   1064:     IN PIRP Irp
                   1065:     )
                   1066: 
                   1067: /*++
                   1068: 
                   1069: Routine Description:
                   1070: 
                   1071:     This routine handles CREATE/OPEN requests and does
                   1072:     nothing more than return successful status.
                   1073: 
                   1074: Arguments:
                   1075: 
                   1076:     DeviceObject
                   1077:     Irp
                   1078: 
                   1079: Return Value:
                   1080: 
                   1081:     NT Status
                   1082: 
                   1083: --*/
                   1084: 
                   1085: {
                   1086:     KIRQL currentIrql;
                   1087:     PQ117_CONTEXT     context;
                   1088:     NTSTATUS ntStatus;
                   1089: 
                   1090:     context = DeviceObject->DeviceExtension;
                   1091: 
                   1092:     if (!context->DriverOpened) {
                   1093: 
                   1094:         ntStatus = q117ConvertStatus(DeviceObject, q117Start(context));
                   1095: 
                   1096:         //
                   1097:         // If everything went OK,  then flag that the driver is now open
                   1098:         //
                   1099:         if (NT_SUCCESS(ntStatus)) {
                   1100:             context->DriverOpened = TRUE;
                   1101:         } else {
                   1102:             q117Stop(context);
                   1103:         }
                   1104: 
                   1105:     } else {
                   1106: 
                   1107:         ntStatus = STATUS_DEVICE_BUSY;
                   1108: 
                   1109:     }
                   1110: 
                   1111:     Irp->IoStatus.Status = ntStatus;
                   1112: 
                   1113:     KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
                   1114:     IoCompleteRequest(Irp, 0);
                   1115:     KeLowerIrql(currentIrql);
                   1116: 
                   1117:     return ntStatus;
                   1118: 
                   1119: } // end Q117Create()
                   1120: 
                   1121: NTSTATUS
                   1122: q117Close (
                   1123:     IN PDEVICE_OBJECT DeviceObject,
                   1124:     IN PIRP Irp
                   1125:     )
                   1126: 
                   1127: /*++
                   1128: 
                   1129: Routine Description:
                   1130: 
                   1131: 
                   1132: Arguments:
                   1133: 
                   1134:     DeviceObject
                   1135:     Irp
                   1136: 
                   1137: Return Value:
                   1138: 
                   1139:     NT Status
                   1140: 
                   1141: --*/
                   1142: 
                   1143: {
                   1144:     KIRQL currentIrql;
                   1145:     PQ117_CONTEXT     context;
                   1146:     NTSTATUS ntStatus;
                   1147: 
                   1148:     context = DeviceObject->DeviceExtension;
                   1149: 
                   1150:     ntStatus = q117ConvertStatus(DeviceObject, q117Stop(context));
                   1151: 
                   1152:     context->DriverOpened = FALSE;
                   1153: 
                   1154:     Irp->IoStatus.Status = ntStatus;
                   1155: 
                   1156:     KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
                   1157:     IoCompleteRequest(Irp, 0);
                   1158:     KeLowerIrql(currentIrql);
                   1159: 
                   1160:     return ntStatus;
                   1161: 
                   1162: } // end Q117Close()
                   1163: 
                   1164: VOID
                   1165: q117LogError(
                   1166:     IN PDEVICE_OBJECT DeviceObject,
                   1167:     IN ULONG SequenceNumber,
                   1168:     IN UCHAR MajorFunctionCode,
                   1169:     IN UCHAR RetryCount,
                   1170:     IN ULONG UniqueErrorValue,
                   1171:     IN NTSTATUS FinalStatus,
                   1172:     IN NTSTATUS SpecificIOStatus
                   1173:     )
                   1174: 
                   1175: /*++
                   1176: 
                   1177: Routine Description:
                   1178: 
                   1179:     This routine allocates an error log entry, copies the supplied data
                   1180:     to it, and requests that it be written to the error log file.
                   1181: 
                   1182: Arguments:
                   1183: 
                   1184:     DeviceObject - a pointer to the device object associated with the
                   1185:     device that had the error.
                   1186: 
                   1187:     SequenceNumber - A ulong value that is unique to an IRP over the
                   1188:     life of the irp in this driver - 0 generally means an error not
                   1189:     associated with an irp.
                   1190: 
                   1191:     MajorFunctionCode - If there is an error associated with the irp,
                   1192:     this is the major function code of that irp.
                   1193: 
                   1194:     RetryCount - The number of times a particular operation has been
                   1195:     retried.
                   1196: 
                   1197:     UniqueErrorValue - A unique long word that identifies the particular
                   1198:     call to this function.
                   1199: 
                   1200:     FinalStatus - The final status given to the irp that was associated
                   1201:     with this error.  If this log entry is being made during one of
                   1202:     the retries this value will be STATUS_SUCCESS.
                   1203: 
                   1204:     SpecificIOStatus - The IO status for a particular error.
                   1205: 
                   1206: Return Value:
                   1207: 
                   1208:     None.
                   1209: 
                   1210: --*/
                   1211: 
                   1212: {
                   1213:     PIO_ERROR_LOG_PACKET errorLogEntry;
                   1214: 
                   1215:     errorLogEntry = IoAllocateErrorLogEntry(
                   1216:                         DeviceObject,
                   1217:                         sizeof(IO_ERROR_LOG_PACKET)
                   1218:                         );
                   1219: 
                   1220:     if ( errorLogEntry != NULL ) {
                   1221:         errorLogEntry->ErrorCode = SpecificIOStatus;
                   1222:         errorLogEntry->SequenceNumber = SequenceNumber;
                   1223:         errorLogEntry->MajorFunctionCode = MajorFunctionCode;
                   1224:         errorLogEntry->RetryCount = RetryCount;
                   1225:         errorLogEntry->UniqueErrorValue = UniqueErrorValue;
                   1226:         errorLogEntry->FinalStatus = FinalStatus;
                   1227:         errorLogEntry->DumpDataSize = 0;
                   1228:         IoWriteErrorLogEntry(errorLogEntry);
                   1229: 
                   1230:     }
                   1231: 
                   1232: }
                   1233: #ifdef NOT_NOW
                   1234: 
                   1235: VOID
                   1236: q117Cancel(
                   1237:     IN PDEVICE_OBJECT DeviceObject,
                   1238:     IN PIRP Irp
                   1239:     )
                   1240: 
                   1241: /*++
                   1242: 
                   1243: Routine Description:
                   1244: 
                   1245:     This routine is called from the I/O system when a request is cancelled.
                   1246: 
                   1247:     N.B.  The cancel spinlock is already held upon entry to this routine.
                   1248: 
                   1249: Arguments:
                   1250: 
                   1251:     DeviceObject - Pointer to class device object.
                   1252: 
                   1253:     Irp - Pointer to the request packet to be cancelled.
                   1254: 
                   1255: Return Value:
                   1256: 
                   1257:     None.
                   1258: 
                   1259: --*/
                   1260: 
                   1261: {
                   1262: 
                   1263:     CheckedDump(QIC117INFO,("q117Cancel: enter\n"));
                   1264: 
                   1265:     if (Irp == DeviceObject->CurrentIrp) {
                   1266: 
                   1267:         //
                   1268:         // The current request is being cancelled.  Set the CurrentIrp to
                   1269:         // null and release the cancel spinlock before starting the next packet.
                   1270:         //
                   1271: 
                   1272:         DeviceObject->CurrentIrp = NULL;
                   1273:         IoReleaseCancelSpinLock(Irp->CancelIrql);
                   1274:         IoStartNextPacket(DeviceObject, TRUE);
                   1275: 
                   1276:     } else {
                   1277: 
                   1278:         //
                   1279:         // Cancel a request in the device queue.  Remove it from queue and
                   1280:         // release the cancel spinlock.
                   1281:         //
                   1282: 
                   1283:         if (TRUE != KeRemoveEntryDeviceQueue(
                   1284:                         &DeviceObject->DeviceQueue,
                   1285:                         &Irp->Tail.Overlay.DeviceQueueEntry
                   1286:                         )) {
                   1287:             CheckedDump(QIC117SHOWTD,(
                   1288:                 "q117Cancel: Irp 0x%x not in device queue?!?\n",
                   1289:                 Irp
                   1290:                 ));
                   1291:         }
                   1292:         IoReleaseCancelSpinLock(Irp->CancelIrql);
                   1293:     }
                   1294: 
                   1295:     //
                   1296:     // Complete the request with STATUS_CANCELLED.
                   1297:     //
                   1298: 
                   1299:     Irp->IoStatus.Status = STATUS_CANCELLED;
                   1300:     Irp->IoStatus.Information = 0;
                   1301:     IoCompleteRequest (Irp, IO_NO_INCREMENT);
                   1302: 
                   1303:     CheckedDump(QIC117INFO,("q117Cancel: exit\n"));
                   1304: 
                   1305:     return;
                   1306: }
                   1307: #endif
                   1308: 
                   1309: NTSTATUS
                   1310: q117Cleanup(
                   1311:     IN PDEVICE_OBJECT DeviceObject,
                   1312:     IN PIRP Irp
                   1313:     )
                   1314: 
                   1315: /*++
                   1316: 
                   1317: Routine Description:
                   1318: 
                   1319:     This routine is the dispatch routine for cleanup requests.
                   1320:     All queued q117 requests are completed with STATUS_CANCELLED,
                   1321:     and the lower level driver's queue is cleared.
                   1322: 
                   1323: Arguments:
                   1324: 
                   1325:     DeviceObject - Pointer to class device object.
                   1326: 
                   1327:     Irp - Pointer to the request packet.
                   1328: 
                   1329: Return Value:
                   1330: 
                   1331:     Status is returned.
                   1332: 
                   1333: --*/
                   1334: 
                   1335: {
                   1336:     KIRQL currentIrql;
                   1337:     KIRQL cancelIrql;
                   1338:     PKDEVICE_QUEUE_ENTRY packet;
                   1339:     PIRP  currentIrp;
                   1340: 
                   1341:     CheckedDump(QIC117INFO,("q117Cleanup: enter\n"));
                   1342: 
                   1343:     /* clear everything from the low-level driver */
                   1344:     q117ClearQueue(
                   1345:         DeviceObject->DeviceExtension
                   1346:         );
                   1347:     //
                   1348:     // Raise IRQL to DISPATCH_LEVEL.
                   1349:     //
                   1350: 
                   1351:     KeRaiseIrql(DISPATCH_LEVEL, &currentIrql);
                   1352: 
                   1353:     //
                   1354:     // Acquire the cancel spinlock.
                   1355:     //
                   1356: 
                   1357:     IoAcquireCancelSpinLock(&cancelIrql);
                   1358: 
                   1359:     //
                   1360:     // Complete all queued requests with STATUS_CANCELLED.
                   1361:     // Start with the real CurrentIrp, and run down the list of requests in the
                   1362:     // device queue.  Be sure to set the real CurrentIrp to NULL, so that
                   1363:     // the interrupt service callback routine won't attempt to complete it.
                   1364:     //
                   1365: 
                   1366:     currentIrp = DeviceObject->CurrentIrp;
                   1367:     DeviceObject->CurrentIrp = NULL;
                   1368: 
                   1369:     while (currentIrp != NULL) {
                   1370: 
                   1371:         //
                   1372:         // Remove the CurrentIrp from the cancellable state.
                   1373:         //
                   1374:         //
                   1375: 
                   1376:         IoSetCancelRoutine(currentIrp, NULL);
                   1377: 
                   1378:         //
                   1379:         // Set Status to CANCELLED, release the cancel spinlock,
                   1380:         // and complete the request.  Note that the IRQL is reset to
                   1381:         // DISPATCH_LEVEL when we release the cancel spinlock.
                   1382:         //
                   1383: 
                   1384:         currentIrp->IoStatus.Status = STATUS_CANCELLED;
                   1385:         currentIrp->IoStatus.Information = 0;
                   1386: 
                   1387:         IoReleaseCancelSpinLock(cancelIrql);
                   1388:         IoCompleteRequest(currentIrp, IO_NO_INCREMENT);
                   1389: 
                   1390:         //
                   1391:         // Reacquire the cancel spinlock.
                   1392:         //
                   1393: 
                   1394:         IoAcquireCancelSpinLock(&cancelIrql);
                   1395: 
                   1396:         //
                   1397:         // Dequeue the next packet (IRP) from the device work queue.
                   1398:         //
                   1399: 
                   1400:         packet = KeRemoveDeviceQueue(&DeviceObject->DeviceQueue);
                   1401:         if (packet != NULL) {
                   1402:             currentIrp =
                   1403:                 CONTAINING_RECORD(packet, IRP, Tail.Overlay.DeviceQueueEntry);
                   1404:         } else {
                   1405:             currentIrp = (PIRP) NULL;
                   1406:         }
                   1407:     } // end while
                   1408: 
                   1409:     //
                   1410:     // Release the cancel spinlock and lower IRQL.
                   1411:     //
                   1412: 
                   1413:     IoReleaseCancelSpinLock(cancelIrql);
                   1414:     KeLowerIrql(currentIrql);
                   1415: 
                   1416:     //
                   1417:     // Complete the cleanup request with STATUS_SUCCESS.
                   1418:     //
                   1419: 
                   1420:     Irp->IoStatus.Status = STATUS_SUCCESS;
                   1421:     Irp->IoStatus.Information = 0;
                   1422:     IoCompleteRequest (Irp, IO_NO_INCREMENT);
                   1423: 
                   1424:     CheckedDump(QIC117INFO,("q117Cleanup: exit\n"));
                   1425: 
                   1426:     return(STATUS_SUCCESS);
                   1427: 
                   1428: }
                   1429: 

unix.superglobalmegacorp.com

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