Annotation of ntddk/src/scsi/qic117/ioctl.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:     ioctl.c
                      9: 
                     10: Abstract:
                     11: 
                     12:     Tape IOCTL support for NT Backup aplication.
                     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 "common.h"
                     28: #include "q117.h"
                     29: #include "protos.h"
                     30: #include "cms.h"
                     31: 
                     32: 
                     33: NTSTATUS
                     34: q117IoCtlGetPosition (
                     35:     IN PDEVICE_OBJECT DeviceObject,
                     36:     IN PIRP Irp
                     37:     )
                     38: /*++
                     39: 
                     40: Routine Description:
                     41: 
                     42: 
                     43: 
                     44: Arguments:
                     45: 
                     46:     DeviceObject
                     47: 
                     48: 
                     49: Return Value:
                     50: 
                     51:     NT Status
                     52: 
                     53: --*/
                     54: 
                     55: {
                     56:     PQ117_CONTEXT       context;
                     57:     PTAPE_GET_POSITION  currentPosition;
                     58:     PLARGE_INTEGER      offset;
                     59: 
                     60:     context = DeviceObject->DeviceExtension;
                     61:     currentPosition = Irp->AssociatedIrp.SystemBuffer;
                     62: 
                     63:     Irp->IoStatus.Information = sizeof(TAPE_GET_POSITION);
                     64: 
                     65:     //
                     66:     // signal no partition support
                     67:     //
                     68:     currentPosition->Partition = 0;
                     69: 
                     70:     //
                     71:     // Fill in the CurrentOperation.Position based on the mode
                     72:     //
                     73:     offset = &currentPosition->Offset;
                     74: 
                     75:     offset->HighPart = (LONG)0;
                     76: 
                     77: 
                     78:     switch (context->CurrentOperation.Type) {
                     79: 
                     80:         case BackupInProgress:
                     81:             offset->LowPart = context->CurrentOperation.BytesOnTape;
                     82:             break;
                     83: 
                     84:         case RestoreInProgress:
                     85:             offset->LowPart = context->CurrentOperation.BytesRead;
                     86:             break;
                     87: 
                     88:         case NoOperation:
                     89:             offset->LowPart = context->CurrentOperation.BytesRead;
                     90:             break;
                     91: 
                     92:     }
                     93:     offset->LowPart /= BLOCK_SIZE;
                     94: 
                     95:     CheckedDump(QIC117SHOWTD,("%d=GetPosition()",currentPosition->Offset.LowPart));
                     96: 
                     97:     return STATUS_SUCCESS;
                     98: }
                     99: 
                    100: NTSTATUS
                    101: q117IoCtlGetMediaParameters (
                    102:     IN PDEVICE_OBJECT DeviceObject,
                    103:     IN PIRP Irp
                    104:     )
                    105: /*++
                    106: 
                    107: Routine Description:
                    108: 
                    109: 
                    110: 
                    111: Arguments:
                    112: 
                    113:     DeviceObject
                    114: 
                    115: 
                    116: Return Value:
                    117: 
                    118:     NT Status
                    119: 
                    120: --*/
                    121: 
                    122: {
                    123:     PQ117_CONTEXT   context;
                    124:     NTSTATUS        ntStatus;
                    125: 
                    126:     context = DeviceObject->DeviceExtension;
                    127: 
                    128:     //
                    129:     // Make sure there is a tape in the drive and that the tape information
                    130:     // has been loaded
                    131:     //
                    132:     if (context->CurrentOperation.Type == NoOperation) {
                    133: 
                    134:         ntStatus = q117ConvertStatus(DeviceObject, q117CheckNewTape(context));
                    135: 
                    136:     } else {
                    137: 
                    138:         ntStatus = STATUS_SUCCESS;
                    139: 
                    140:     }
                    141: 
                    142: 
                    143:     if ( NT_SUCCESS( ntStatus ) ) {
                    144:         //
                    145:         // Copy already formed (by q117CheckNewTape) information into callers buffer
                    146:         //
                    147:         Irp->IoStatus.Information = sizeof(TAPE_GET_MEDIA_PARAMETERS);
                    148: 
                    149:         *(PTAPE_GET_MEDIA_PARAMETERS)Irp->AssociatedIrp.SystemBuffer =
                    150:             *context->CurrentTape.MediaInfo;
                    151: 
                    152:     }
                    153: 
                    154:     return ntStatus;
                    155: }
                    156: 
                    157: NTSTATUS
                    158: q117IoCtlSetMediaParameters (
                    159:     IN PDEVICE_OBJECT DeviceObject,
                    160:     IN PIRP Irp
                    161:     )
                    162: /*++
                    163: 
                    164: Routine Description:
                    165: 
                    166: 
                    167: 
                    168: Arguments:
                    169: 
                    170:     DeviceObject
                    171: 
                    172: 
                    173: Return Value:
                    174: 
                    175:     NT Status
                    176: 
                    177: --*/
                    178: 
                    179: {
                    180:     PQ117_CONTEXT                context;
                    181:     PTAPE_SET_MEDIA_PARAMETERS   setMedia;
                    182: 
                    183:     context = DeviceObject->DeviceExtension;
                    184: 
                    185:     setMedia = (PTAPE_SET_MEDIA_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
                    186: 
                    187:     CheckedDump((QIC117SHOWTD | QIC117WARN),("SetDriveParameters not implemented yet\n"));
                    188:     CheckedDump(QIC117SHOWTD,("BlockSize: %x",setMedia->BlockSize));
                    189: 
                    190:     if (setMedia->BlockSize != BLOCK_SIZE)
                    191:         return STATUS_INVALID_PARAMETER;
                    192:     else
                    193:         return STATUS_SUCCESS;
                    194: }
                    195: 
                    196: NTSTATUS
                    197: q117IoCtlGetDriveParameters (
                    198:     IN PDEVICE_OBJECT DeviceObject,
                    199:     IN PIRP Irp
                    200:     )
                    201: /*++
                    202: 
                    203: Routine Description:
                    204: 
                    205: 
                    206: 
                    207: Arguments:
                    208: 
                    209:     DeviceObject
                    210: 
                    211: 
                    212: Return Value:
                    213: 
                    214:     NT Status
                    215: 
                    216: --*/
                    217: 
                    218: {
                    219:     PQ117_CONTEXT             context;
                    220:     PTAPE_GET_DRIVE_PARAMETERS driveInfo;
                    221: 
                    222:     context = DeviceObject->DeviceExtension;
                    223: 
                    224:     //
                    225:     // Copy already formed (by q117CheckNewTape) information into callers buffer
                    226:     //
                    227:     //
                    228:     driveInfo = (PTAPE_GET_DRIVE_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
                    229:     Irp->IoStatus.Information = sizeof(TAPE_GET_DRIVE_PARAMETERS);
                    230: 
                    231:     driveInfo->ECC = TRUE;
                    232:     driveInfo->Compression = FALSE;
                    233:     driveInfo->DataPadding = FALSE;
                    234:     driveInfo->ReportSetmarks = TRUE;
                    235:     driveInfo->DefaultBlockSize = BLOCK_SIZE;
                    236:     driveInfo->MaximumBlockSize = BLOCK_SIZE;
                    237:     driveInfo->MinimumBlockSize = BLOCK_SIZE;
                    238:     driveInfo->MaximumPartitionCount = 0;
                    239:     driveInfo->FeaturesLow =
                    240:         TAPE_DRIVE_ERASE_SHORT |
                    241:         TAPE_DRIVE_ERASE_BOP_ONLY |
                    242:         TAPE_DRIVE_TAPE_CAPACITY |
                    243:         TAPE_DRIVE_TAPE_REMAINING |
                    244:         TAPE_DRIVE_FIXED_BLOCK |
                    245:         TAPE_DRIVE_WRITE_PROTECT |
                    246:         TAPE_DRIVE_ECC |
                    247:         TAPE_DRIVE_COMPRESSION |
                    248:         TAPE_DRIVE_REPORT_SMKS |
                    249:         TAPE_DRIVE_GET_ABSOLUTE_BLK |
                    250:         TAPE_DRIVE_GET_LOGICAL_BLK;
                    251:     driveInfo->FeaturesHigh =
                    252:         TAPE_DRIVE_LOAD_UNLOAD |
                    253:         TAPE_DRIVE_TENSION |
                    254:         TAPE_DRIVE_LOCK_UNLOCK |
                    255:         TAPE_DRIVE_ABSOLUTE_BLK |
                    256:         TAPE_DRIVE_LOGICAL_BLK |
                    257:         TAPE_DRIVE_END_OF_DATA |
                    258:         TAPE_DRIVE_RELATIVE_BLKS |
                    259:         TAPE_DRIVE_FILEMARKS |
                    260:         TAPE_DRIVE_SEQUENTIAL_FMKS |
                    261:         TAPE_DRIVE_SETMARKS |
                    262:         TAPE_DRIVE_SEQUENTIAL_SMKS |
                    263:         TAPE_DRIVE_REVERSE_POSITION |
                    264:         TAPE_DRIVE_WRITE_SETMARKS |
                    265:         TAPE_DRIVE_WRITE_FILEMARKS |
                    266:         TAPE_DRIVE_FORMAT;
                    267: 
                    268:     driveInfo->FeaturesHigh &= ~TAPE_DRIVE_HIGH_FEATURES;
                    269: 
                    270:     return STATUS_SUCCESS;
                    271: }
                    272: 
                    273: NTSTATUS
                    274: q117IoCtlSetDriveParameters (
                    275:     IN PDEVICE_OBJECT DeviceObject,
                    276:     IN PIRP Irp
                    277:     )
                    278: /*++
                    279: 
                    280: Routine Description:
                    281: 
                    282: 
                    283: 
                    284: Arguments:
                    285: 
                    286:     DeviceObject
                    287: 
                    288: 
                    289: Return Value:
                    290: 
                    291:     NT Status
                    292: 
                    293: --*/
                    294: 
                    295: {
                    296:     PQ117_CONTEXT             context;
                    297:     PTAPE_SET_DRIVE_PARAMETERS driveInfo;
                    298:     NTSTATUS            ntStatus;
                    299: 
                    300:     context = DeviceObject->DeviceExtension;
                    301: 
                    302:     //
                    303:     // Copy already formed (by q117CheckNewTape) information into callers buffer
                    304:     //
                    305:     //
                    306:     driveInfo = (PTAPE_SET_DRIVE_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
                    307: 
                    308:     CheckedDump((QIC117SHOWTD | QIC117WARN),("SetDriveParameters not implemented yet\n"));
                    309:     CheckedDump(QIC117SHOWTD,("ECC: %x",driveInfo->ECC));
                    310:     CheckedDump(QIC117SHOWTD,("Compression: %x",driveInfo->Compression));
                    311:     CheckedDump(QIC117SHOWTD,("DataPadding: %x",driveInfo->DataPadding));
                    312:     CheckedDump(QIC117SHOWTD,("ReportSetmarks: %x",driveInfo->ReportSetmarks));
                    313:     ntStatus = STATUS_SUCCESS;
                    314:     if (!driveInfo->ECC ||
                    315:         driveInfo->Compression ||
                    316:         driveInfo->DataPadding ||
                    317:         !driveInfo->ReportSetmarks) {
                    318: 
                    319:         ntStatus = STATUS_INVALID_DEVICE_REQUEST;
                    320:     }
                    321: 
                    322:     return ntStatus;
                    323: }
                    324: 
                    325: NTSTATUS
                    326: q117IoCtlWriteMarks (
                    327:     IN PDEVICE_OBJECT DeviceObject,
                    328:     IN PIRP Irp
                    329:     )
                    330: /*++
                    331: 
                    332: Routine Description:
                    333: 
                    334:     Handle user request to write tape mark
                    335: 
                    336: Arguments:
                    337: 
                    338:     DeviceObject
                    339: 
                    340: 
                    341: Return Value:
                    342: 
                    343:     NT Status
                    344: 
                    345: --*/
                    346: 
                    347: {
                    348: #ifndef NO_MARKS
                    349: 
                    350:     PQ117_CONTEXT       context;
                    351:     PTAPE_WRITE_MARKS   tapeMarks = Irp->AssociatedIrp.SystemBuffer;
                    352:     ULONG               numMarks;
                    353:     NTSTATUS            ntStatus;
                    354:     ULONG               type;
                    355: 
                    356:     context = DeviceObject->DeviceExtension;
                    357: 
                    358:     //
                    359:     // Make sure we are in write mode
                    360:     //
                    361:     ntStatus = q117ConvertStatus(DeviceObject, q117OpenForWrite(context));
                    362: 
                    363:     numMarks = tapeMarks->Count;
                    364:     type = tapeMarks->Type;
                    365: 
                    366:     //
                    367:     // Don't allow long/short filemarks
                    368:     //
                    369:     switch(type) {
                    370:         case TAPE_LONG_FILEMARKS:
                    371:         case TAPE_SHORT_FILEMARKS:
                    372:             ntStatus = STATUS_INVALID_DEVICE_REQUEST;
                    373:     }
                    374: 
                    375:     //
                    376:     // Put as many marks as the user asked for,  in the mark array
                    377:     //
                    378:     while (numMarks && NT_SUCCESS( ntStatus )) {
                    379: 
                    380:         context->MarkArray.MarkEntry[
                    381:             context->MarkArray.TotalMarks].Type = tapeMarks->Type;
                    382: 
                    383:         context->MarkArray.MarkEntry[
                    384:             context->MarkArray.TotalMarks].Offset =
                    385:             context->CurrentOperation.BytesOnTape;
                    386: 
                    387:         --numMarks;
                    388: 
                    389:         ++context->MarkArray.TotalMarks;
                    390:         ++context->CurrentMark;
                    391: 
                    392:         //
                    393:         // Always make the (last mark) huge so we don't have to check
                    394:         // for the end of the table in the rest of the code.
                    395:         //
                    396:         context->MarkArray.MarkEntry[
                    397:             context->MarkArray.TotalMarks].Offset = 0xffffffff;
                    398: 
                    399:         //
                    400:         // For each mark, write a "fake" block on the tape.  This
                    401:         // is due to the ntBackup program assuming that a filemark
                    402:         // takes a block
                    403:         //
                    404: 
                    405:         ntStatus = q117ConvertStatus(
                    406:             DeviceObject,
                    407:             q117WriteTape(NULL,BLOCK_SIZE,context)
                    408:             );
                    409:     }
                    410: 
                    411:     return ntStatus;
                    412: 
                    413: #else
                    414: 
                    415:     return STATUS_INVALID_DEVICE_REQUEST;
                    416: 
                    417: #endif
                    418: }
                    419: 
                    420: NTSTATUS
                    421: q117IoCtlSetPosition (
                    422:     IN PDEVICE_OBJECT DeviceObject,
                    423:     IN PIRP Irp
                    424:     )
                    425: /*++
                    426: 
                    427: Routine Description:
                    428: 
                    429: 
                    430: 
                    431: Arguments:
                    432: 
                    433:     DeviceObject
                    434: 
                    435: 
                    436: Return Value:
                    437: 
                    438:     NT Status
                    439: 
                    440: --*/
                    441: 
                    442: {
                    443:     PQ117_CONTEXT             context;
                    444:     PTAPE_SET_POSITION tapePosition = Irp->AssociatedIrp.SystemBuffer;
                    445:     STATUS status;
                    446:     NTSTATUS ntStatus;
                    447:     IO_REQUEST ioreq;
                    448:     ULONG offset;
                    449: #ifndef NO_MARKS
                    450:     int x = 0;
                    451: #endif
                    452: 
                    453:     context = DeviceObject->DeviceExtension;
                    454: 
                    455:     status = NoErr;
                    456:     ntStatus = STATUS_SUCCESS;
                    457: 
                    458:     if (context->CurrentOperation.Type != NoOperation) {
                    459:         switch(context->CurrentOperation.Type) {
                    460: 
                    461:             case BackupInProgress:
                    462:                 status = q117EndWriteOperation(context);
                    463:                 break;
                    464: 
                    465:             case RestoreInProgress:
                    466:                 if (
                    467:                     tapePosition->Method == TAPE_REWIND
                    468:                     ) {
                    469:                     status = q117EndReadOperation(context);
                    470:                 }
                    471: 
                    472:                 break;
                    473:         }
                    474:     }
                    475: 
                    476:     context->CurrentOperation.Position = tapePosition->Method;
                    477:     switch(tapePosition->Method) {
                    478: 
                    479:         case TAPE_REWIND:
                    480: 
                    481:             CheckedDump(QIC117INFO,("Rewind()\n"));
                    482:             status = q117DoCmd(&ioreq, DEject, NULL, context);
                    483: 
                    484: //            context->TapeStatus.Status |= TAPE_STATUS_BEGINNING_OF_MEDIA;
                    485: //            context->TapeStatus.Status &= ~TAPE_STATUS_END_OF_MEDIA;
                    486: 
                    487:             context->CurrentOperation.BytesRead = 0;
                    488: 
                    489: #ifndef NO_MARKS
                    490:             context->CurrentMark = 0;
                    491: #endif
                    492:             break;
                    493: 
                    494:         case TAPE_LOGICAL_BLOCK:
                    495:         case TAPE_ABSOLUTE_BLOCK:
                    496: 
                    497:             CheckedDump(QIC117SHOWTD,(
                    498:                 "%s SeekBlock(%d)\n",
                    499:                 tapePosition->Method==TAPE_LOGICAL_BLOCK?"Logical":"Absolute",
                    500:                 tapePosition->Offset.LowPart
                    501:                 ));
                    502: 
                    503:             offset = (tapePosition->Offset.LowPart)*BLOCK_SIZE;
                    504: 
                    505:             ntStatus = q117SeekToOffset(offset, context, DeviceObject);
                    506: 
                    507:             break;
                    508: 
                    509:         case TAPE_SPACE_END_OF_DATA:
                    510:             //
                    511:             // This will be taken care of when backup starts
                    512:             //  by using the context->CurrentOperation.Position
                    513:             //
                    514:             // It is assumed that this function will only be called prior
                    515:             //  to a backup operation only.
                    516: 
                    517:             CheckedDump(QIC117SHOWTD,("SeekEOD()\n"));
                    518:             context->CurrentOperation.BytesRead =
                    519:                 context->ActiveVolume.DataSize;
                    520: 
                    521: #ifndef NO_MARKS
                    522:             context->CurrentMark = context->MarkArray.TotalMarks;
                    523: #endif
                    524: 
                    525: //            context->TapeStatus.Status |= TAPE_STATUS_END_OF_MEDIA;
                    526: //            context->TapeStatus.Status &= ~TAPE_STATUS_BEGINNING_OF_MEDIA;
                    527:             break;
                    528: 
                    529: 
                    530:         case TAPE_SPACE_RELATIVE_BLOCKS:
                    531: 
                    532: 
                    533:             CheckedDump(QIC117SHOWTD,("SeekRelBlock(%d)\n",tapePosition->Offset.LowPart));
                    534:             //
                    535:             // Convert relative offset into absolute
                    536:             //
                    537:             offset = (LONG)context->CurrentOperation.BytesRead +
                    538:                     ((LONG)tapePosition->Offset.LowPart*BLOCK_SIZE);
                    539: 
                    540:             //
                    541:             // Perform absolute seek.
                    542:             //
                    543:             ntStatus = q117SeekToOffset(offset,context, DeviceObject);
                    544: 
                    545:             break;
                    546: 
                    547: #ifndef NO_MARKS
                    548:         case TAPE_SPACE_SETMARKS:
                    549:             ++x;
                    550:         case TAPE_SPACE_FILEMARKS:
                    551:             ++x;
                    552:         case TAPE_SPACE_SEQUENTIAL_FMKS:
                    553:             ++x;
                    554:         case TAPE_SPACE_SEQUENTIAL_SMKS:
                    555:             if (1) {
                    556:                 static char *type[4] = {"SequentialSet","SequentialFile","File","Set"};
                    557: 
                    558:                 CheckedDump(QIC117SHOWTD,("Seek%sMark(%d)\n",type[x],tapePosition->Offset.LowPart));
                    559:             }
                    560:             ntStatus = q117FindMark(tapePosition->Method,
                    561:                          tapePosition->Offset.LowPart, context, DeviceObject);
                    562:             break;
                    563: #else
                    564:         case TAPE_SPACE_SETMARKS:
                    565:         case TAPE_SPACE_FILEMARKS:
                    566:         case TAPE_SPACE_SEQUENTIAL_FMKS:
                    567:         case TAPE_SPACE_SEQUENTIAL_SMKS:
                    568: #endif
                    569:         default:
                    570:             CheckedDump(QIC117DBGP,("TAPE: Position: Invalid Position Code (%x)\n",
                    571:                 tapePosition->Method));
                    572: 
                    573:             ntStatus = STATUS_INVALID_DEVICE_REQUEST;
                    574:             break;
                    575: 
                    576:     } // end switch(tapePosition->Method)
                    577: 
                    578:     if (status)
                    579:         ntStatus = q117ConvertStatus(DeviceObject, status);
                    580: 
                    581:     return ntStatus;
                    582: 
                    583: }
                    584: 
                    585: #ifndef NO_MARKS
                    586: NTSTATUS
                    587: q117FindMark(
                    588:     ULONG Type,
                    589:     LONG Number,
                    590:     PQ117_CONTEXT Context,
                    591:     IN PDEVICE_OBJECT DeviceObject
                    592:     )
                    593: 
                    594: /*++
                    595: 
                    596: Routine Description:
                    597: 
                    598: 
                    599: 
                    600: Arguments:
                    601: 
                    602: 
                    603: Return Value:
                    604: 
                    605:     NT Status
                    606: 
                    607: --*/
                    608: 
                    609: {
                    610:     NTSTATUS ntStatus;
                    611:     BOOLEAN forwardSeek;
                    612: 
                    613:     ntStatus = STATUS_SUCCESS;
                    614: 
                    615:     //
                    616:     // Convert the SetPosition commands into WriteMark types
                    617:     //
                    618:     switch(Type) {
                    619: 
                    620:         case TAPE_SPACE_SEQUENTIAL_FMKS:
                    621: 
                    622:             //
                    623:             // If sequential mark,  then always start from the first mark.
                    624:             //
                    625:             Context->CurrentMark = 0;
                    626: 
                    627:         case TAPE_SPACE_FILEMARKS:
                    628: 
                    629:             Type = TAPE_FILEMARKS;
                    630:             break;
                    631: 
                    632:         case TAPE_SPACE_SEQUENTIAL_SMKS:
                    633: 
                    634:             //
                    635:             // If sequential mark,  then always start from the first mark.
                    636:             //
                    637:             Context->CurrentMark = 0;
                    638: 
                    639:         case TAPE_SPACE_SETMARKS:
                    640: 
                    641:             Type = TAPE_SETMARKS;
                    642:             break;
                    643: 
                    644:     }
                    645: 
                    646:     if (Number > 0) {
                    647:         forwardSeek = TRUE;
                    648:     } else {
                    649:         forwardSeek = FALSE;
                    650:     }
                    651: 
                    652: 
                    653:     //
                    654:     // Now seek the appropriate amount
                    655:     //
                    656:     while (NT_SUCCESS( ntStatus ) && Number != 0) {
                    657: 
                    658:         if (forwardSeek) {
                    659: 
                    660:             if (Context->CurrentMark >= Context->MarkArray.TotalMarks) {
                    661: 
                    662:                 ntStatus = STATUS_END_OF_MEDIA;
                    663: 
                    664:             } else {
                    665: 
                    666:                 if (Context->MarkArray.MarkEntry[Context->CurrentMark].Type ==
                    667:                     Type) {
                    668: 
                    669:                     //
                    670:                     // If we found one,  decrement the count
                    671:                     //
                    672: 
                    673:                     --Number;
                    674: 
                    675: 
                    676:                     //
                    677:                     // Don't increment the current mark on the last one we
                    678:                     // find.  This is because current mark points to
                    679:                     // the mark we are going to hit next.
                    680:                     //
                    681: 
                    682:                     if (Number) {
                    683: 
                    684:                         ++Context->CurrentMark;
                    685:                     }
                    686: 
                    687:                 } else {
                    688: 
                    689:                     ++Context->CurrentMark;
                    690: 
                    691:                 }
                    692:             }
                    693: 
                    694:         } else {
                    695: 
                    696:             if (Context->CurrentMark == 0) {
                    697: 
                    698:                 ntStatus = STATUS_END_OF_MEDIA;
                    699: 
                    700:             } else {
                    701: 
                    702:                 --Context->CurrentMark;
                    703: 
                    704:                 if (Context->MarkArray.MarkEntry[Context->CurrentMark].Type ==
                    705:                     Type) {
                    706: 
                    707:                     ++Number;
                    708: 
                    709:                 }
                    710: 
                    711:             }
                    712: 
                    713:         }
                    714: 
                    715:     }
                    716: 
                    717:     if (NT_SUCCESS( ntStatus )) {
                    718: 
                    719:         if (Context->CurrentMark >= Context->MarkArray.TotalMarks) {
                    720: 
                    721:             ntStatus = STATUS_END_OF_MEDIA;
                    722: 
                    723:         } else {
                    724: 
                    725:             //
                    726:             // Seek to proper location.  Note:  forward seek
                    727:             // seeks to block after file mark (successive read will return
                    728:             // block after filemark.
                    729:             // A backward seek will position at the filemark.  The next read
                    730:             // will return filemark found,  and successive reads will read
                    731:             // data after the mark)
                    732:             //
                    733:             ntStatus = q117SeekToOffset(
                    734:                 Context->MarkArray.MarkEntry[Context->CurrentMark].Offset+
                    735:                     (forwardSeek?BLOCK_SIZE:0),
                    736:                 Context,
                    737:                 DeviceObject
                    738:                 );
                    739: 
                    740:         }
                    741: 
                    742:     }
                    743: 
                    744:     return ntStatus;
                    745: }
                    746: #endif
                    747: 
                    748: NTSTATUS
                    749: q117SeekToOffset(
                    750:     ULONG Offset,
                    751:     PQ117_CONTEXT Context,
                    752:     IN PDEVICE_OBJECT DeviceObject
                    753:     )
                    754: 
                    755: /*++
                    756: 
                    757: Routine Description:
                    758: 
                    759:     Seek to specified offset on the tape (absolute offset from 0) in bytes
                    760: 
                    761: Arguments:
                    762: 
                    763:     Offset - Bytes from begining of the volume to seek.
                    764: 
                    765: Return Value:
                    766: 
                    767:     NT Status
                    768: 
                    769: --*/
                    770: 
                    771: {
                    772:     NTSTATUS ntStatus;
                    773: 
                    774: 
                    775:     CheckedDump(QIC117SHOWTD,("Absolute seek: %x\n",Offset));
                    776: 
                    777:     ntStatus = STATUS_SUCCESS;
                    778: 
                    779:     //
                    780:     // If not in read mode,  switch into read mode
                    781:     //
                    782:     if (Context->CurrentOperation.Type == NoOperation) {
                    783: 
                    784:         ntStatus = q117OpenForRead(0, Context, DeviceObject);
                    785: 
                    786:         //
                    787:         // if there is no data on the tape
                    788:         //
                    789:         if (ntStatus == STATUS_NO_DATA_DETECTED) {
                    790:             return ntStatus;
                    791:         }
                    792: 
                    793:         Context->CurrentOperation.Type = RestoreInProgress;
                    794:     }
                    795: 
                    796: 
                    797:     if (Offset < Context->CurrentOperation.BytesRead) {
                    798: 
                    799:         //
                    800:         // Backward seek,  so stop current operation,
                    801:         //  rewind to begining of volume,  and drop
                    802:         //  through to a forward seek.
                    803:         //
                    804: 
                    805:         ntStatus = q117ConvertStatus(
                    806:             DeviceObject,
                    807:             q117EndReadOperation(Context)
                    808:             );
                    809: 
                    810:         if (NT_SUCCESS(ntStatus)) {
                    811: 
                    812:             ntStatus = q117OpenForRead(0, Context, DeviceObject);
                    813: 
                    814:             //
                    815:             // if there is no data on the tape
                    816:             //
                    817:             if (ntStatus == STATUS_NO_DATA_DETECTED) {
                    818:                 return ntStatus;
                    819:             }
                    820: 
                    821:             Context->CurrentOperation.Type = RestoreInProgress;
                    822:         }
                    823:     }
                    824: 
                    825: 
                    826:     if (NT_SUCCESS(ntStatus)) {
                    827:         //
                    828:         // Forward seek only (if we were doing a backward seek,  the operation
                    829:         // has been re-started this point and BytesRead == 0)
                    830:         //
                    831:         Offset -= Context->CurrentOperation.BytesRead;
                    832: 
                    833:         //
                    834:         // Skip to the appropriate place
                    835:         //
                    836:         ntStatus = q117ConvertStatus(
                    837:                         DeviceObject,
                    838:                         q117SkipBlock(&Offset, Context)
                    839:                         );
                    840: 
                    841:     }
                    842: 
                    843:     return ntStatus;
                    844: }
                    845: 
                    846: NTSTATUS
                    847: q117IoCtlErase (
                    848:     IN PDEVICE_OBJECT DeviceObject,
                    849:     IN PIRP Irp
                    850:     )
                    851: /*++
                    852: 
                    853: Routine Description:
                    854: 
                    855: 
                    856: 
                    857: Arguments:
                    858: 
                    859:     DeviceObject
                    860: 
                    861: 
                    862: Return Value:
                    863: 
                    864:     NT Status
                    865: 
                    866: --*/
                    867: 
                    868: {
                    869:     PQ117_CONTEXT             context;
                    870:     NTSTATUS ntStatus;
                    871:     STATUS status;
                    872: 
                    873:     context = DeviceObject->DeviceExtension;
                    874: 
                    875:     //
                    876:     // Complete any operation in progress
                    877:     //
                    878:     switch(context->CurrentOperation.Type) {
                    879: 
                    880:         case BackupInProgress:
                    881:             status = q117EndWriteOperation(context);
                    882:             break;
                    883: 
                    884:         case RestoreInProgress:
                    885:             status = q117EndReadOperation(context);
                    886:             break;
                    887:     }
                    888: 
                    889:     //
                    890:     // Make sure there is a tape in the drive and that the tape information
                    891:     // has been loaded
                    892:     //
                    893:     ntStatus = q117ConvertStatus(
                    894:         DeviceObject,
                    895:         q117CheckNewTape(context));
                    896: 
                    897:     if ( NT_SUCCESS( ntStatus ) ) {
                    898:         //
                    899:         // Don't allow an erase if write protected
                    900:         //
                    901:         if (context->CurrentTape.MediaInfo->WriteProtected) {
                    902:             return STATUS_MEDIA_WRITE_PROTECTED;
                    903:         }
                    904: 
                    905:         //
                    906:         // Erase the tape
                    907:         //
                    908:         status = q117EraseQ(context);
                    909: 
                    910:         ntStatus = q117ConvertStatus(DeviceObject, status);
                    911:     }
                    912: 
                    913:     return ntStatus;
                    914: }
                    915: 
                    916: NTSTATUS
                    917: q117IoCtlPrepare (
                    918:     IN PDEVICE_OBJECT DeviceObject,
                    919:     IN PIRP Irp
                    920:     )
                    921: /*++
                    922: 
                    923: Routine Description:
                    924: 
                    925: 
                    926: 
                    927: Arguments:
                    928: 
                    929:     DeviceObject
                    930: 
                    931: 
                    932: Return Value:
                    933: 
                    934:     NT Status
                    935: 
                    936: --*/
                    937: 
                    938: {
                    939:     PQ117_CONTEXT       context;
                    940:     NTSTATUS            ntStatus;
                    941:     STATUS              status;
                    942:     PTAPE_PREPARE       tapePrepare;
                    943:     IO_REQUEST          ioreq;
                    944:     QIC40_VENDOR_UNIQUE vendorUnique;
                    945:     LONG                numberBad;
                    946: 
                    947:     context = DeviceObject->DeviceExtension;
                    948: 
                    949:     status = NoErr;
                    950: 
                    951:     //
                    952:     // Complete any operation in progress
                    953:     //
                    954:     switch(context->CurrentOperation.Type) {
                    955: 
                    956:         case BackupInProgress:
                    957:             status = q117EndWriteOperation(context);
                    958:             break;
                    959: 
                    960:         case RestoreInProgress:
                    961:             status = q117EndReadOperation(context);
                    962:             break;
                    963:     }
                    964: 
                    965:     //
                    966:     // All prepare except LOCK and UNLOCK operations rewind the media.
                    967:     //
                    968:     tapePrepare = Irp->AssociatedIrp.SystemBuffer;
                    969: 
                    970:     if ((tapePrepare->Operation != TAPE_LOCK) &&
                    971:         (tapePrepare->Operation != TAPE_UNLOCK)) {
                    972:         context->CurrentOperation.BytesRead = 0;
                    973:         context->CurrentOperation.Position = 0;
                    974: #ifndef NO_MARKS
                    975:         context->CurrentMark = 0;
                    976: #endif
                    977:     }
                    978: 
                    979: 
                    980:     if (status) {
                    981:         return q117ConvertStatus(DeviceObject, status);
                    982:     }
                    983: 
                    984:     ntStatus = STATUS_SUCCESS;
                    985: 
                    986:     switch (tapePrepare->Operation) {
                    987: 
                    988:         case TAPE_LOAD:
                    989:             CheckedDump(QIC117SHOWTD,("TAPE_LOAD  ... "));
                    990:             ntStatus = q117ConvertStatus(DeviceObject, q117CheckNewTape(context));
                    991:             break;
                    992: 
                    993:         case TAPE_UNLOAD:
                    994: 
                    995:             //
                    996:             // Just rewind the tape
                    997:             //
                    998:             CheckedDump(QIC117SHOWTD,("TAPE_UNLOAD  ... "));
                    999:             ntStatus = q117ConvertStatus (
                   1000:                     DeviceObject,
                   1001:                     q117DoCmd(&ioreq, DEject, NULL, context) );
                   1002: 
                   1003:             break;
                   1004: 
                   1005:         case TAPE_TENSION:
                   1006: 
                   1007:             CheckedDump(QIC117SHOWTD,("TAPE_TENSION  ... "));
                   1008:             ntStatus = q117ConvertStatus (
                   1009:                     DeviceObject,
                   1010:                     q117DoCmd(&ioreq, DReten, NULL, context) );
                   1011: 
                   1012:             break;
                   1013: 
                   1014:         case TAPE_UNLOCK:
                   1015:             CheckedDump(QIC117SHOWTD,("UN"));
                   1016:         case TAPE_LOCK:
                   1017:             CheckedDump(QIC117SHOWTD,("LOCK TAPE ..."));
                   1018: 
                   1019:             //
                   1020:             // These commands mean nothing for a QIC-40 drive.  However,  the current
                   1021:             // operation will be flushed allowing user to remove cartridge.
                   1022:             //
                   1023:             break;
                   1024: 
                   1025:         case TAPE_FORMAT:
                   1026:             CheckedDump(QIC117SHOWTD,("TAPE_FORMAT  ... "));
                   1027: 
                   1028:             ntStatus = q117ConvertStatus (
                   1029:                         DeviceObject,
                   1030:                         q117Format(
                   1031:                             &numberBad,
                   1032:                             TRUE,
                   1033:                             &vendorUnique,
                   1034:                             context ) );
                   1035:             break;
                   1036: 
                   1037:         default:
                   1038:             CheckedDump(QIC117SHOWTD,("INVALID  ... "));
                   1039: 
                   1040:             ntStatus = STATUS_INVALID_DEVICE_REQUEST;
                   1041: 
                   1042:     } // end switch (tapePrepare->Operation)
                   1043: 
                   1044:     return ntStatus;
                   1045: }
                   1046: 
                   1047: NTSTATUS
                   1048: q117IoCtlGetStatus (
                   1049:     IN PDEVICE_OBJECT DeviceObject,
                   1050:     IN PIRP Irp
                   1051:     )
                   1052: /*++
                   1053: 
                   1054: Routine Description:
                   1055: 
                   1056: 
                   1057: 
                   1058: Arguments:
                   1059: 
                   1060:     DeviceObject
                   1061: 
                   1062: 
                   1063: Return Value:
                   1064: 
                   1065:     NT Status
                   1066: 
                   1067: --*/
                   1068: 
                   1069: {
                   1070:     PQ117_CONTEXT             context;
                   1071: //    PTAPE_STATUS tapeStatus;
                   1072:     STATUS status;
                   1073: 
                   1074:     context = DeviceObject->DeviceExtension;
                   1075: 
                   1076: 
                   1077:     //
                   1078:     // Complete any operation in progress
                   1079:     //
                   1080:     switch(context->CurrentOperation.Type) {
                   1081: 
                   1082:         case BackupInProgress:
                   1083:             status = NoErr;
                   1084:             break;
                   1085: 
                   1086:         case RestoreInProgress:
                   1087:             status = NoErr;
                   1088:             break;
                   1089: 
                   1090:         case NoOperation:
                   1091:             status = q117CheckNewTape(context);
                   1092:             break;
                   1093: 
                   1094:         default:
                   1095:             status = FCodeErr;
                   1096: 
                   1097:     }
                   1098: 
                   1099:     //tapeStatus = Irp->UserBuffer;
                   1100: 
                   1101:     //
                   1102:     // Is this supported in the tape API ?????
                   1103:     //
                   1104: //    *tapeStatus = context->TapeStatus;
                   1105: 
                   1106:     //
                   1107:     // Reset media changed flag.
                   1108:     //
                   1109: //    context->TapeStatus.Status &= ~TAPE_STATUS_MEDIA_CHANGED;
                   1110: 
                   1111:     return q117ConvertStatus(DeviceObject, status);
                   1112: }
                   1113: 
                   1114: NTSTATUS
                   1115: q117IoCtlReadAbs (
                   1116:     IN PDEVICE_OBJECT DeviceObject,
                   1117:     IN PIRP Irp
                   1118:     )
                   1119: /*++
                   1120: 
                   1121: Routine Description:
                   1122: 
                   1123: 
                   1124: 
                   1125: Arguments:
                   1126: 
                   1127:     DeviceObject
                   1128: 
                   1129: 
                   1130: Return Value:
                   1131: 
                   1132:     NT Status
                   1133: 
                   1134: --*/
                   1135: 
                   1136: {
                   1137:     PQ117_CONTEXT   context;
                   1138:     PSEGMENT_BUFFER bufferInfo;
                   1139:     PVOID           scrbuf;
                   1140:     PIO_REQUEST     ioreq;
                   1141:     PCMS_RW_ABS     readWrite;
                   1142:     STATUS          status;
                   1143:     ULONG           len;
                   1144:     PIO_STACK_LOCATION  irpStack;
                   1145: 
                   1146:     context = DeviceObject->DeviceExtension;
                   1147:     readWrite = Irp->AssociatedIrp.SystemBuffer;
                   1148:     irpStack = IoGetCurrentIrpStackLocation(Irp);
                   1149: 
                   1150:     scrbuf = q117GetFreeBuffer(&bufferInfo,context);
                   1151: 
                   1152:     status=q117IssIOReq(
                   1153:                 scrbuf,
                   1154:                 DRead,
                   1155:                 readWrite->Block,
                   1156:                 bufferInfo,
                   1157:                 context
                   1158:                 );
                   1159: 
                   1160:     if (!status) {
                   1161: 
                   1162:         //
                   1163:         // Wait for data to be written
                   1164:         //
                   1165:         ioreq=q117Dequeue(WaitForItem,context);
                   1166: 
                   1167:         status = ioreq->Status;
                   1168: 
                   1169:     }
                   1170: 
                   1171:     readWrite->Status = status;
                   1172: 
                   1173:     len = BYTES_PER_SECTOR*readWrite->Count;
                   1174: 
                   1175:     if (len > irpStack->Parameters.DeviceIoControl.OutputBufferLength) {
                   1176: 
                   1177:         len = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
                   1178: 
                   1179:     }
                   1180: 
                   1181:     RtlMoveMemory(
                   1182:         readWrite+1,
                   1183:         scrbuf,
                   1184:         len
                   1185:         );
                   1186: 
                   1187:     Irp->IoStatus.Information = sizeof(CMS_RW_ABS)+len;
                   1188: 
                   1189:     return q117ConvertStatus(DeviceObject, status);
                   1190: 
                   1191: 
                   1192: }
                   1193: 
                   1194: NTSTATUS
                   1195: q117IoCtlWriteAbs (
                   1196:     IN PDEVICE_OBJECT DeviceObject,
                   1197:     IN PIRP Irp
                   1198:     )
                   1199: /*++
                   1200: 
                   1201: Routine Description:
                   1202: 
                   1203: 
                   1204: 
                   1205: Arguments:
                   1206: 
                   1207:     DeviceObject
                   1208: 
                   1209: 
                   1210: Return Value:
                   1211: 
                   1212:     NT Status
                   1213: 
                   1214: --*/
                   1215: 
                   1216: {
                   1217:     PQ117_CONTEXT   context;
                   1218:     PSEGMENT_BUFFER bufferInfo;
                   1219:     PVOID           scrbuf;
                   1220:     PIO_REQUEST     ioreq;
                   1221:     PCMS_RW_ABS     readWrite;
                   1222:     STATUS          status;
                   1223: 
                   1224:     context = DeviceObject->DeviceExtension;
                   1225:     readWrite = Irp->AssociatedIrp.SystemBuffer;
                   1226: 
                   1227:     scrbuf = q117GetFreeBuffer(&bufferInfo,context);
                   1228: 
                   1229:     RtlMoveMemory(
                   1230:         scrbuf,
                   1231:         readWrite+1,
                   1232:         BYTES_PER_SECTOR*readWrite->Count
                   1233:         );
                   1234: 
                   1235:     status = q117IssIOReq(
                   1236:         scrbuf,
                   1237:         DWrite,
                   1238:         readWrite->Block,
                   1239:         bufferInfo,
                   1240:         context);
                   1241: 
                   1242:     if (!status) {
                   1243: 
                   1244:         //
                   1245:         // Wait for data to be written
                   1246:         //
                   1247:         ioreq=q117Dequeue(WaitForItem,context);
                   1248: 
                   1249:         status = ioreq->Status;
                   1250: 
                   1251:     }
                   1252: 
                   1253:     readWrite->Status = status;
                   1254: 
                   1255:     return q117ConvertStatus(DeviceObject, status);
                   1256: 
                   1257: }
                   1258: 
                   1259: STATUS
                   1260: q117CheckNewTape (
                   1261:     PQ117_CONTEXT             Context
                   1262:     )
                   1263: /*++
                   1264: 
                   1265: Routine Description:
                   1266: 
                   1267:     This routine checks for new tape and reads header if necessary
                   1268: 
                   1269: Arguments:
                   1270: 
                   1271:     Context - Current context information
                   1272: 
                   1273: Return Value:
                   1274: 
                   1275:     NT Status
                   1276: 
                   1277: --*/
                   1278: 
                   1279: {
                   1280:     STATUS              stat;
                   1281:     IO_REQUEST          ioreq;
                   1282:     PTAPE_HEADER        header;
                   1283:     VOLUME_TABLE_ENTRY  tempVolume;
                   1284:     UCHAR               tapeType;
                   1285:     BOOLEAN             found;
                   1286:     BOOLEAN             notNt;
                   1287:     USHORT              volumesRead;
                   1288:     DRIVE_CAPACITY      driveCapacity;
                   1289:     SEGMENT             curseg;
                   1290: 
                   1291: 
                   1292:     //
                   1293:     // Check to see if there is a tape in the drive
                   1294:     //
                   1295:     stat = q117DoCmd(&ioreq, DGetCart, &tapeType, Context);
                   1296: 
                   1297:     //
                   1298:     // If we found a tape and need to read the header and volume tables,
                   1299:     //   do it now.
                   1300:     //
                   1301:     if (stat == NewCart) {
                   1302: //        Context->TapeStatus.Status |= TAPE_STATUS_MEDIA_CHANGED;
                   1303:     }
                   1304: 
                   1305:     if (stat == NewCart ||
                   1306:             (stat == NoErr && Context->CurrentTape.State == NeedInfoLoaded) ) {
                   1307: 
                   1308:         CheckedDump(QIC117SHOWTD,("New Cart Detected\n"));
                   1309: 
                   1310:         //
                   1311:         // Check to see if there is a tape in the drive
                   1312:         //
                   1313: 
                   1314:         stat = q117DoCmd(&ioreq, DClearNewCart, NULL, Context);
                   1315: 
                   1316:         if (stat) {
                   1317:             return stat;
                   1318:         }
                   1319: 
                   1320:         //
                   1321:         // Saw new cart,  so set need loaded flag
                   1322:         //
                   1323:         Context->CurrentTape.State = NeedInfoLoaded;
                   1324: 
                   1325:         // clear no media flag and end of media flag
                   1326: //        Context->TapeStatus.Status &=
                   1327: //            ~(TAPE_STATUS_NO_MEDIA|TAPE_STATUS_END_OF_MEDIA);
                   1328: 
                   1329:         // Set bom and device ready.
                   1330: //        Context->TapeStatus.Status |=
                   1331: //            TAPE_STATUS_DEVICE_READY|TAPE_STATUS_BEGINNING_OF_MEDIA;
                   1332: 
                   1333:         //
                   1334:         // Check to see if tape is write protected
                   1335:         //
                   1336:         if (stat = q117DoCmd(&ioreq, DSndWPro, NULL, Context)) {
                   1337: 
                   1338:             if (stat != WProt) {
                   1339:                 return stat;
                   1340:             }
                   1341: 
                   1342:         }
                   1343: 
                   1344:         Context->CurrentTape.MediaInfo->WriteProtected = (stat == WProt);
                   1345:         if (stat == WProt) {
                   1346: //            Context->TapeStatus.Status |= TAPE_STATUS_WRITE_PROTECTED;
                   1347:         }
                   1348: 
                   1349:         //
                   1350:         // Check to see if drive is formatted
                   1351:         //
                   1352:         stat = q117DoCmd(&ioreq, DGetCap, &driveCapacity, Context);
                   1353: 
                   1354:         if (stat) {
                   1355:             return stat;
                   1356:         }
                   1357: 
                   1358:         //
                   1359:         // If tape not referenced.
                   1360:         //
                   1361:         if (driveCapacity.referenced == FALSE) {
                   1362:             return BadFmt;
                   1363:         }
                   1364: 
                   1365:         //
                   1366:         // Check to see if tape is correct format
                   1367:         //
                   1368:         stat = q117DoCmd(&ioreq, DChkFmt, NULL, Context);
                   1369: 
                   1370:         if (stat) {
                   1371:             if (stat == WrongFmt) {
                   1372:                 Context->CurrentTape.MediaInfo->WriteProtected =
                   1373:                     TRUE;
                   1374:                 stat = NoErr;
                   1375:             } else {
                   1376:                 return stat;
                   1377:             }
                   1378:         }
                   1379: 
                   1380:         //
                   1381:         // Now read the tape header (and bad sector map)
                   1382:         //
                   1383:         if (stat = q117LoadTape(&header,Context)) {
                   1384:             return stat;
                   1385:         }
                   1386:         CheckedDump(QIC117SHOWTD,("LoadTape successful\n"));
                   1387: 
                   1388:         //
                   1389:         // If this capacity not supported by this drive,
                   1390:         // (i.e..  Pegasus cart in a QIC-40 drive)
                   1391:         // return invalid format
                   1392:         //
                   1393:         if (header->FormatCode != driveCapacity.TapeFormatCode) {
                   1394:             return BadFmt;
                   1395:         }
                   1396: 
                   1397:         //
                   1398:         // Copy over bad sector map, etc.
                   1399:         //
                   1400:         RtlMoveMemory(
                   1401:             Context->CurrentTape.TapeHeader,
                   1402:             header,
                   1403:             sizeof(*Context->CurrentTape.TapeHeader) );
                   1404: 
                   1405:         //
                   1406:         // Now scan volume list and get last volume on tape as well as the
                   1407:         // NT volume (if one exists
                   1408:         //
                   1409: 
                   1410:         if (stat = q117SelectTD(Context))
                   1411:             return stat;
                   1412: 
                   1413:         volumesRead = 0;
                   1414: 
                   1415:         found = FALSE;
                   1416: 
                   1417:         do {
                   1418:             /* get a volume directory from the tape (if error then)*/
                   1419:             stat = q117ReadVolumeEntry(&tempVolume,Context);
                   1420: 
                   1421:             if (stat && (stat != EndOfVol))
                   1422:                 return stat;
                   1423: 
                   1424:             if (!stat) {
                   1425:                 volumesRead++;
                   1426: 
                   1427:                 //
                   1428:                 // For now,  let the system find ANY volume type and select
                   1429:                 // it.  This will allow NT Backup software to read the
                   1430:                 // volume and detect that it is a non-nt format.
                   1431:                 // To do this,  the if statement is removed,  allowing
                   1432:                 // the first volume found,  be the one that we select.
                   1433:                 //
                   1434:                 if (!(tempVolume.VendorSpecific &&
                   1435:                     tempVolume.Vendor.cms_QIC40.OpSysType == OP_WINDOWS_NT)) {
                   1436: 
                   1437:                     Context->CurrentOperation.BytesOnTape =
                   1438:                         Context->CurrentOperation.BytesRead = 0;
                   1439: 
                   1440:                     notNt = TRUE;
                   1441: 
                   1442: #ifndef NO_MARKS
                   1443:                     Context->MarkArray.TotalMarks = 0;
                   1444:                     Context->CurrentMark = Context->MarkArray.TotalMarks;
                   1445:                     Context->MarkArray.MarkEntry[Context->CurrentMark].Offset =
                   1446:                         0xffffffff;
                   1447: #endif
                   1448: 
                   1449:                     /* force the data size to be the entire backup */
                   1450:                     tempVolume.DataSize = 0;
                   1451:                     curseg = tempVolume.StartSegment;
                   1452:                     while (curseg <= tempVolume.EndingSegment) {
                   1453: 
                   1454:                         tempVolume.DataSize +=
                   1455:                             q117GoodDataBytes(
                   1456:                                 curseg,
                   1457:                                 Context);
                   1458:                         ++curseg;
                   1459: 
                   1460: 
                   1461:                     }
                   1462: 
                   1463:                 } else {
                   1464: 
                   1465:                     notNt = FALSE;
                   1466: 
                   1467:                 }
                   1468:                 found = TRUE;
                   1469:                 Context->ActiveVolume = tempVolume;
                   1470:             }
                   1471: 
                   1472:         } while (!stat && volumesRead < Context->CurrentTape.MaximumVolumes);
                   1473: 
                   1474:         if (stat = q117EndRest(Context))
                   1475:             return(stat);
                   1476: 
                   1477:         //
                   1478:         // If we did not find a volume,  then signal others that
                   1479:         //  the ActiveVolume information is invalid.
                   1480:         //
                   1481:         if (!found)
                   1482:             Context->ActiveVolumeNumber = 0;
                   1483: 
                   1484:         //
                   1485:         // Zero out bytes saved (incase user trys to read)
                   1486:         // Also set CurrentOperation.BytesRead to zero (start of tape)
                   1487:         //
                   1488:         Context->CurrentOperation.BytesOnTape =
                   1489:             Context->CurrentOperation.BytesRead = 0;
                   1490: 
                   1491:         //
                   1492:         // Flag that we have done everything
                   1493:         //
                   1494:         Context->CurrentTape.State = TapeInfoLoaded;
                   1495: 
                   1496: #ifndef NO_MARKS
                   1497: 
                   1498:         //
                   1499:         // Read the mark list from the active volume
                   1500:         //
                   1501:         if (found && !notNt) {
                   1502: 
                   1503:             stat = q117GetMarks(Context);
                   1504: 
                   1505:         }
                   1506: 
                   1507: #endif
                   1508: 
                   1509:         //
                   1510:         // If no more pressing error,  return NewCart
                   1511:         // so application can be aware of the new insertion.
                   1512:         //
                   1513:         if (stat == NoErr) {
                   1514:             stat = NewCart;
                   1515:         }
                   1516: 
                   1517:     } else {
                   1518: 
                   1519:         if (stat == NoTape) {
                   1520: //            Context->TapeStatus.Status |= TAPE_STATUS_NO_MEDIA;
                   1521:             Context->ActiveVolumeNumber = 0;
                   1522:             Context->CurrentOperation.BytesOnTape =
                   1523:                 Context->CurrentOperation.BytesRead = 0;
                   1524: 
                   1525: #ifndef NO_MARKS
                   1526:             Context->MarkArray.TotalMarks = 0;
                   1527:             Context->CurrentMark = Context->MarkArray.TotalMarks;
                   1528:             Context->MarkArray.MarkEntry[Context->CurrentMark].Offset =
                   1529:                 0xffffffff;
                   1530: #endif
                   1531: 
                   1532:         }
                   1533: 
                   1534:     }
                   1535: 
                   1536:     return stat;
                   1537: }
                   1538: 

unix.superglobalmegacorp.com

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