|
|
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.