|
|
1.1 ! root 1: /*++ ! 2: ! 3: Copyright (c) 1993 - Colorado Memory Systems, Inc. ! 4: All Rights Reserved ! 5: ! 6: Module Name: ! 7: ! 8: ntopen.c ! 9: ! 10: Abstract: ! 11: ! 12: Performs psuedo open, read, close and open write, close. ! 13: ! 14: Revision History: ! 15: ! 16: ! 17: ! 18: ! 19: --*/ ! 20: ! 21: ! 22: #include <ntddk.h> ! 23: #include <ntddtape.h> // tape device driver I/O control codes ! 24: #include "common.h" ! 25: #include "q117.h" ! 26: #include "protos.h" ! 27: ! 28: ! 29: STATUS ! 30: q117Start ( ! 31: IN OUT PQ117_CONTEXT Context ! 32: ) ! 33: ! 34: /*++ ! 35: ! 36: Routine Description: ! 37: ! 38: Allocates memory and loads current tape information ! 39: ! 40: Arguments: ! 41: ! 42: Context - ! 43: ! 44: Return Value: ! 45: ! 46: --*/ ! 47: ! 48: { ! 49: STATUS stat; ! 50: ! 51: if (Context->IoRequest == NULL) { ! 52: ! 53: q117GetTemporaryMemory(Context); ! 54: ! 55: // ! 56: // Initialize some globals ! 57: // ! 58: ! 59: Context->CurrentOperation.Type = NoOperation; ! 60: Context->CurrentTape.State = NeedInfoLoaded; ! 61: Context->CurrentOperation.SegmentStatus = NoErr; ! 62: ! 63: q117QueueNormal(Context); ! 64: } ! 65: ! 66: // ! 67: // Look for the drive ! 68: // ! 69: stat = q117CheckDrive(Context); ! 70: ! 71: // if (stat == NoErr) { ! 72: // ! 73: // stat = q117CheckNewTape(Context); ! 74: // ! 75: // } ! 76: ! 77: return stat; ! 78: } ! 79: ! 80: STATUS ! 81: q117Stop ( ! 82: IN OUT PQ117_CONTEXT Context ! 83: ) ! 84: ! 85: /*++ ! 86: ! 87: Routine Description: ! 88: ! 89: Shut down the lower level driver (q117i) ! 90: ! 91: Arguments: ! 92: ! 93: Context - ! 94: ! 95: Return Value: ! 96: ! 97: --*/ ! 98: { ! 99: IO_REQUEST ioreq; ! 100: STATUS stat; ! 101: ! 102: stat = NoErr; ! 103: ! 104: switch(Context->CurrentOperation.Type) { ! 105: ! 106: case BackupInProgress: ! 107: stat = q117EndWriteOperation(Context); ! 108: break; ! 109: ! 110: case RestoreInProgress: ! 111: stat = q117EndReadOperation(Context); ! 112: break; ! 113: } ! 114: ! 115: if (!stat) { ! 116: ! 117: // ! 118: // Deselect the driver ! 119: // ! 120: stat = q117DoCmd(&ioreq, DDeselect, NULL, Context); ! 121: ! 122: } ! 123: ! 124: if (!stat) { ! 125: ! 126: // ! 127: // Free any memory associated with the tape ! 128: // ! 129: //q117ClearQueue(Context); ! 130: //q117FreeTemporaryMemory(Context); ! 131: ! 132: } ! 133: ! 134: ! 135: return stat; ! 136: } ! 137: ! 138: STATUS ! 139: q117OpenForWrite ( ! 140: IN OUT PQ117_CONTEXT Context ! 141: ) ! 142: ! 143: /*++ ! 144: ! 145: Routine Description: ! 146: ! 147: Prepare driver for a write operation ! 148: ! 149: Arguments: ! 150: ! 151: Context - ! 152: ! 153: Return Value: ! 154: ! 155: --*/ ! 156: ! 157: { ! 158: STATUS status; ! 159: PCMS_VOLUME_VENDOR *vv_ptr; ! 160: ULONG saveSize; ! 161: USHORT saveVolNum; ! 162: IO_REQUEST ioreq; ! 163: ! 164: status = NoErr; ! 165: ! 166: switch ( Context->CurrentOperation.Type ) { ! 167: case BackupInProgress: ! 168: ! 169: // ! 170: // We are set ! 171: // ! 172: return NoErr; ! 173: ! 174: case RestoreInProgress: ! 175: ! 176: // ! 177: // Chop the data off at the current position ! 178: // ! 179: Context->ActiveVolume.DataSize = Context->CurrentOperation.BytesRead; ! 180: Context->CurrentOperation.Position = TAPE_SPACE_END_OF_DATA; ! 181: ! 182: // ! 183: // Chop off any marks that we will write over ! 184: // ! 185: Context->MarkArray.TotalMarks = Context->CurrentMark; ! 186: Context->MarkArray.MarkEntry[Context->CurrentMark].Offset = 0xffffffff; ! 187: ! 188: ! 189: // ! 190: // End the read operation ! 191: // ! 192: ! 193: status = q117EndReadOperation(Context); ! 194: ! 195: if (status) { ! 196: ! 197: return status; ! 198: ! 199: } ! 200: break; ! 201: ! 202: case NoOperation: ! 203: ! 204: break; ! 205: } ! 206: ! 207: // ! 208: // If we got here, then we need to transition into backup mode. ! 209: // ! 210: ! 211: CheckedDump(QIC117INFO,("q117CheckNewTape()...")); ! 212: ! 213: if (status = q117CheckNewTape(Context)) { ! 214: ! 215: CheckedDump(QIC117INFO,("Failed\n")); ! 216: return(status); ! 217: ! 218: } else { ! 219: ! 220: CheckedDump(QIC117INFO,("OK\n")); ! 221: ! 222: } ! 223: ! 224: // ! 225: // Check to see if tape is correct format ! 226: // ! 227: status = q117DoCmd(&ioreq, DChkFmt, NULL, Context); ! 228: ! 229: if (status) { ! 230: return status; ! 231: } ! 232: ! 233: if (!Context->CurrentTape.MediaInfo->WriteProtected) { ! 234: ! 235: if (Context->CurrentOperation.Position == TAPE_SPACE_END_OF_DATA) { ! 236: saveSize = Context->ActiveVolume.DataSize; ! 237: saveVolNum = Context->ActiveVolumeNumber; ! 238: ! 239: #ifndef NO_MARKS ! 240: ! 241: // ! 242: // Use the directorySize field as the start of the volume ! 243: // ! 244: Context->CurrentOperation.EndOfUsedTape = ! 245: (SEGMENT)Context->ActiveVolume.DirectorySize-1; ! 246: ! 247: #else ! 248: // ! 249: // Set the current end of tape to the start of this volume ! 250: // (q117StartAppend will skip to the proper place to start ! 251: // backup) ! 252: Context->CurrentOperation.EndOfUsedTape = ! 253: Context->ActiveVolume.StartSegment-1; ! 254: ! 255: #endif ! 256: Context->ActiveVolumeNumber = 0; ! 257: ! 258: } else { ! 259: ! 260: CheckedDump(QIC117INFO,("q117EraseQ()\n")); ! 261: if (status = q117EraseQ(Context)) { ! 262: CheckedDump(QIC117INFO,("Failed\n")); ! 263: return(status); ! 264: } else { ! 265: CheckedDump(QIC117INFO,("OK\n")); ! 266: } ! 267: ! 268: // ! 269: // Fill in identification information ! 270: // ! 271: vv_ptr = &(Context->ActiveVolume.Vendor.cms_QIC40); ! 272: RtlMoveMemory((PVOID)(vv_ptr->Signature),"CMS",3); ! 273: vv_ptr->SoftwareRevision = 0x300; ! 274: vv_ptr->FirmwareRevision = 0 /*cmd_firmwarerev */; ! 275: vv_ptr->OpSysType = OP_WINDOWS_NT; ! 276: Context->ActiveVolume.VendorSpecific = TRUE; ! 277: ! 278: strcpy(Context->ActiveVolume.Description,"Microsoft Windows NT Format 1.0"); ! 279: q117SpacePadString(Context->ActiveVolume.Description,sizeof(Context->ActiveVolume.Description)); ! 280: ! 281: } ! 282: ! 283: if (Context->CurrentOperation.Position == TAPE_SPACE_END_OF_DATA) { ! 284: ! 285: CheckedDump(QIC117INFO,("q117StartAppend(saveSize, &Context->ActiveVolume)...")); ! 286: status = q117StartAppend(saveSize, &Context->ActiveVolume, Context); ! 287: ! 288: // ! 289: // Set volume number for q117Update back to saved value ! 290: // minus one (q117AppVolTd assumes the volume we are working on ! 291: // does not exist yet). ! 292: // ! 293: Context->ActiveVolumeNumber = saveVolNum-1; ! 294: ! 295: } else { ! 296: ! 297: CheckedDump(QIC117INFO,("q117StartBack(&Context->ActiveVolume)...")); ! 298: status = q117StartBack(&Context->ActiveVolume,Context); ! 299: ! 300: } ! 301: ! 302: if (status) { ! 303: CheckedDump(QIC117INFO,("Failed\n")); ! 304: return(status); ! 305: } else { ! 306: Context->CurrentOperation.Type = BackupInProgress; ! 307: CheckedDump(QIC117INFO,("OK\n")); ! 308: } ! 309: } else { ! 310: status = WProt; ! 311: } ! 312: ! 313: return status; ! 314: } ! 315: ! 316: STATUS ! 317: q117EndWriteOperation ( ! 318: IN OUT PQ117_CONTEXT Context ! 319: ) ! 320: ! 321: /*++ ! 322: ! 323: Routine Description: ! 324: ! 325: Terminates a write operation and updates the tape header ! 326: ! 327: Arguments: ! 328: ! 329: Context - ! 330: ! 331: Return Value: ! 332: ! 333: --*/ ! 334: ! 335: { ! 336: STATUS status; ! 337: ! 338: Context->CurrentOperation.Type = NoOperation; ! 339: ! 340: // ! 341: // We are at end of tape, because we just finished writing. ! 342: // If the user writes again, this data will be appended to. ! 343: // ! 344: Context->CurrentOperation.Position = TAPE_SPACE_END_OF_DATA; ! 345: Context->CurrentOperation.BytesRead = Context->CurrentOperation.BytesOnTape; ! 346: ! 347: status = q117EndBack(Context); ! 348: ! 349: if (!status) { ! 350: ! 351: status = q117Update(Context); ! 352: ! 353: } ! 354: ! 355: ! 356: ! 357: return status; ! 358: } ! 359: ! 360: NTSTATUS ! 361: q117OpenForRead ( ! 362: IN ULONG StartPosition, ! 363: IN OUT PQ117_CONTEXT Context, ! 364: IN PDEVICE_OBJECT DeviceObject ! 365: ) ! 366: ! 367: /*++ ! 368: ! 369: Routine Description: ! 370: ! 371: Prepare for a read operation. ! 372: ! 373: Arguments: ! 374: ! 375: Context - ! 376: ! 377: Return Value: ! 378: ! 379: --*/ ! 380: ! 381: { ! 382: NTSTATUS ret; ! 383: ! 384: ret = STATUS_SUCCESS; ! 385: ! 386: CheckedDump(QIC117INFO,("q117CheckNewTape()...")); ! 387: if (ret = q117CheckNewTape (Context)) { ! 388: CheckedDump(QIC117INFO,("Failed\n")); ! 389: return q117ConvertStatus(DeviceObject, ret); ! 390: } else { ! 391: CheckedDump(QIC117INFO,("OK\n")); ! 392: } ! 393: ! 394: // ! 395: // If CheckNewTape did not find a volume ! 396: // ! 397: ! 398: if ( Context->ActiveVolumeNumber == 0 ) { ! 399: ! 400: // ! 401: // Insure subsequent reads will return no data ! 402: // ! 403: Context->CurrentOperation.BytesOnTape = 0; ! 404: ! 405: return q117ConvertStatus(DeviceObject, NoVols); ! 406: } ! 407: ! 408: #ifndef NO_MARKS ! 409: Context->CurrentMark = 0; ! 410: #endif ! 411: ! 412: if ( ret = q117SelectVol(&Context->ActiveVolume,Context) ) { ! 413: ! 414: return q117ConvertStatus(DeviceObject, ret); ! 415: ! 416: } ! 417: ! 418: Context->CurrentOperation.Type = RestoreInProgress; ! 419: ! 420: if (StartPosition) { ! 421: ! 422: CheckedDump(QIC117SHOWTD,( ! 423: "ReadRestore: SeekBlock(%d)\n", ! 424: StartPosition)); ! 425: ! 426: // BOBRI, this is the logical block from one line ! 427: // you need to remove -1 if you want it to start from zero ! 428: ret = q117SeekToOffset(StartPosition, Context, DeviceObject); ! 429: ! 430: } ! 431: ! 432: return ret; ! 433: } ! 434: ! 435: STATUS ! 436: q117EndReadOperation ( ! 437: IN OUT PQ117_CONTEXT Context ! 438: ) ! 439: ! 440: /*++ ! 441: ! 442: Routine Description: ! 443: ! 444: Prepare for a read operation. ! 445: ! 446: Arguments: ! 447: ! 448: Context - ! 449: ! 450: Return Value: ! 451: ! 452: --*/ ! 453: ! 454: { ! 455: STATUS status; ! 456: ! 457: Context->CurrentOperation.Type = NoOperation; ! 458: status = q117EndRest(Context); ! 459: //Context->CurrentOperation.BytesRead = 0; ! 460: ! 461: return status; ! 462: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.