|
|
1.1 ! root 1: /* Copyright (C) 2004 TrueCrypt Team, truecrypt.org ! 2: This product uses components written by Paul Le Roux <[email protected]> ! 3: Majority of this code originally Copyright (C) 1998/9 by Aman. Used with ! 4: permission. Other parts originally Copyright (C) 1995 by Walter Oney used ! 5: with implied permission. */ ! 6: ! 7: #include "TCdefs.h" ! 8: ! 9: #pragma VxD_LOCKED_CODE_SEG ! 10: #pragma VxD_LOCKED_DATA_SEG ! 11: ! 12: #include "crypto.h" ! 13: #include "fat.h" ! 14: #include "volumes.h" ! 15: #include "cache.h" ! 16: #include "apidrvr.h" ! 17: #include "tc9x.h" ! 18: #include "queue.h" ! 19: ! 20: #include "ifshook.h" ! 21: #include "ifsmgr.inc" ! 22: ! 23: ! 24: #define NUMSLOTS 8 /* Only up to 8 volumes at a time */ ! 25: #define MAXBLOCK 128 /* 64k was 256.... */ ! 26: ! 27: #define MAX_MESSAGES 8 /* Max number of queued driver messages */ ! 28: ! 29: #define DEVICE_TYPE 0 /* We are a fixed disk (even files on ! 30: removables) */ ! 31: ! 32: #ifdef DEBUG ! 33: #define EXTRA_INFO 1 ! 34: #endif ! 35: ! 36: int halfseccount=0xc9; ! 37: ! 38: char *transferbuffer = NULL; /* IO transfer buffer */ ! 39: char *appaccessbuffer = NULL; /* win32 GUI IO buffer */ ! 40: char *partitiontestbuffer = NULL; /* Buffer for the MBR */ ! 41: int dcbcount = 0; /* DCB hack */ ! 42: PDCB dcblist[128]; /* DCB hack */ ! 43: ! 44: PDCB dcb_boot; /* Boot device */ ! 45: ! 46: extern DRP theDRP; /* Device registration packet */ ! 47: ! 48: int bAllowFastShutdown = 0; ! 49: ! 50: cryptvol cv1 = ! 51: {0, 0, 0, 0, 0, 0, 0, 0}; ! 52: ! 53: cryptvol cv2 = ! 54: {0, 0, 0, 0, 0, 0, 0, 0}; ! 55: ! 56: cryptvol cv3 = ! 57: {0, 0, 0, 0, 0, 0, 0, 0}; ! 58: ! 59: cryptvol cv4 = ! 60: {0, 0, 0, 0, 0, 0, 0, 0}; ! 61: ! 62: cryptvol cv5 = ! 63: {0, 0, 0, 0, 0, 0, 0, 0}; ! 64: ! 65: cryptvol cv6 = ! 66: {0, 0, 0, 0, 0, 0, 0, 0}; ! 67: ! 68: cryptvol cv7 = ! 69: {0, 0, 0, 0, 0, 0, 0, 0}; ! 70: ! 71: cryptvol cv8 = ! 72: {0, 0, 0, 0, 0, 0, 0, 0}; ! 73: ! 74: cryptvol *cryptvols[]= ! 75: { ! 76: &cv1, ! 77: &cv2, ! 78: &cv3, ! 79: &cv4, ! 80: &cv5, ! 81: &cv6, ! 82: &cv7, ! 83: &cv8 ! 84: }; ! 85: ! 86: typedef struct MessageBox_t ! 87: { ! 88: char *MessageHdr; ! 89: char *MessageBody; ! 90: int PostPlease; ! 91: } MessageBox; ! 92: ! 93: MessageBox Msgs[MAX_MESSAGES]; ! 94: ! 95: ! 96: VOID ! 97: OnAsyncRequest (PAEP aep) ! 98: { ! 99: typedef USHORT (*PEF) (PAEP); ! 100: ! 101: static PEF evproc[AEP_MAX_FUNC + 1] = ! 102: {(PEF) OnInitialize /* 0 AEP_INITIALIZE */ ! 103: ,NULL /* 1 AEP_SYSTEM_CRIT_SHUTDOWN */ ! 104: ,(PEF) OnBootComplete /* 2 AEP_BOOT_COMPLETE */ ! 105: ,(PEF) OnConfigDcb /* 3 AEP_CONFIG_DCB */ ! 106: ,(PEF) OnUnconfigDcb /* 4 AEP_UNCONFIG_DCB */ ! 107: ,NULL /* 5 AEP_IOP_TIMEOUT */ ! 108: ,NULL /* 6 AEP_DEVICE_INQUIRY */ ! 109: ,(PEF) OnHalfSec /* 7 AEP_HALF_SEC */ ! 110: ,NULL /* 8 AEP_1_SEC */ ! 111: ,NULL /* 9 AEP_2_SECS */ ! 112: ,NULL /* 10 AEP_4_SECS */ ! 113: ,NULL /* 11 AEP_DBG_DOT_CMD */ ! 114: ,NULL /* 12 AEP_ASSOCIATE_DCB */ ! 115: ,NULL /* 13 AEP_REAL_MODE_HANDOFF */ ! 116: ,(PEF) OnSystemExit /* 14 AEP_SYSTEM_SHUTDOWN */ ! 117: ,(PEF) OnUninitialize /* 15 AEP_UNINITIALIZE */ ! 118: ,NULL /* 16 AEP_DCB_LOCK */ ! 119: ,NULL /* 17 AEP_MOUNT_VERIFY */ ! 120: ,NULL /* 18 AEP_CREATE_VRP */ ! 121: ,NULL /* 19 AEP_DESTROY_VRP */ ! 122: ,NULL /* 20 AEP_REFRESH_DRIVE */ ! 123: ,NULL /* 21 AEP_PEND_UNCONFIG_DCB */ ! 124: ,NULL /* 22 AEP_1E_VEC_UPDATE */ ! 125: ,NULL /* 23 AEP_CHANGE_RPM */ ! 126: }; ! 127: PEF proc; ! 128: ! 129: if (aep->AEP_func < arraysize (evproc) && (proc = evproc[aep->AEP_func])) ! 130: aep->AEP_result = proc (aep); ! 131: else ! 132: aep->AEP_result = (USHORT) AEP_FAILURE; ! 133: } ! 134: ! 135: ! 136: USHORT ! 137: OnInitialize (PAEP_bi_init aep) ! 138: { ! 139: /* allocate our (smaller) memory buffer..... */ ! 140: ! 141: static int initalready = 0; ! 142: ! 143: if (initalready) ! 144: return AEP_SUCCESS; ! 145: ! 146: initalready++; ! 147: ! 148: transferbuffer = (char *) _PageAllocate (50, PG_SYS, 0, 0, 0, MBYTE16, NULL, PAGEZEROINIT | PAGEFIXED | PAGECONTIG | PAGEUSEALIGN); ! 149: partitiontestbuffer = (char *) transferbuffer + (265 * 512); ! 150: appaccessbuffer = transferbuffer + (265 * 512); ! 151: ! 152: ! 153: if (transferbuffer) ! 154: return AEP_SUCCESS; ! 155: ! 156: return (USHORT) AEP_FAILURE; ! 157: } ! 158: ! 159: USHORT ! 160: OnUninitialize (PAEP_bi_uninit aep) ! 161: { ! 162: return AEP_SUCCESS; ! 163: } ! 164: ! 165: /* asks us if we want to stay loaded or not. */ ! 166: ! 167: USHORT ! 168: OnBootComplete (PAEP_boot_done aep) ! 169: { ! 170: installhook (); ! 171: return AEP_SUCCESS; ! 172: } ! 173: ! 174: USHORT ! 175: OnConfigDcb (PAEP_dcb_config aep) ! 176: { ! 177: PDCB dcb = (PDCB) aep->AEP_d_c_dcb; ! 178: if (!(dcb->DCB_cmn.DCB_device_flags & DCB_DEV_PHYSICAL)) ! 179: { ! 180: return AEP_SUCCESS; ! 181: } ! 182: ! 183: /* Sadly for SCSI some port drivers have not set apparent_blk_shift ! 184: up at this point.. if ((dcb->DCB_cmn.DCB_apparent_blk_shift!=9) ! 185: && (dcb->DCB_cmn.DCB_device_type!=DCB_type_cdrom) ) return ! 186: AEP_SUCCESS; */ ! 187: ! 188: if (dcbcount < 100) ! 189: { ! 190: if ((dcb->DCB_cmn.DCB_device_type == 0) || (dcb->DCB_cmn.DCB_device_type == DCB_type_cdrom)) ! 191: { ! 192: if (cmpvend ((char *) &dcb->DCB_vendor_id, "JETICO", 6) != 0) ! 193: { ! 194: if (CheckDcbAlready (dcb)) ! 195: return AEP_SUCCESS; ! 196: dcblist[dcbcount] = dcb; ! 197: dcblist[dcbcount + 1] = NULL; ! 198: dcbcount++; ! 199: } ! 200: } ! 201: } ! 202: ! 203: ! 204: if (dcb->DCB_cmn.DCB_device_type == 0) ! 205: ((IspInsertCalldown (dcb, OnRequest, (PDDB) aep->AEP_d_c_hdr.AEP_ddb, 0, ! 206: dcb->DCB_cmn.DCB_dmd_flags, aep->AEP_d_c_hdr.AEP_lgn))); ! 207: ! 208: return AEP_SUCCESS; ! 209: } ! 210: ! 211: /* AEP_UNCONFIG_DCB informs us that the physical device represented by a DCB ! 212: is going away */ ! 213: ! 214: USHORT ! 215: OnUnconfigDcb (PAEP_dcb_unconfig aep) ! 216: { ! 217: return AEP_SUCCESS; ! 218: } ! 219: ! 220: VOID ! 221: OnRequest (PIOP iop) ! 222: { ! 223: DoCallDown (iop); /* do normal unencryped disk stuff... */ ! 224: } ! 225: ! 226: int ! 227: cmpvend (char *a, char *b, int len) ! 228: { ! 229: int n; ! 230: for (n = 0; n < len; n++) ! 231: if (a[n] != b[n]) ! 232: return 1; ! 233: return 0; ! 234: } ! 235: ! 236: ! 237: int ! 238: CheckDcbAlready (PDCB dcb) ! 239: { ! 240: int n; ! 241: /* sometimes the same dcb is passed more than once, on some drivers!! */ ! 242: if (!dcbcount) ! 243: return 0; ! 244: ! 245: for (n = 0; n < dcbcount; n++) ! 246: if (dcblist[n] == dcb) ! 247: return 1; ! 248: ! 249: return 0; ! 250: } ! 251: ! 252: /* DoCallDown passes a request to the next lower layer. Note that the ! 253: documentation about how to do this is totally wrong: you don't just add ! 254: sizeof(DCB_cd_entry) to the calldown pointer, you follow a linked list ! 255: from one calldown entry to the next. */ ! 256: ! 257: void ! 258: DoCallDown (PIOP iop) ! 259: { ! 260: _asm ! 261: { /* call down to next layer */ ! 262: pushfd ! 263: pushad ! 264: mov ecx,[iop] ! 265: mov eax,[ecx] IOP.IOP_calldown_ptr ! 266: mov eax,[eax] DCB_cd_entry.DCB_cd_next ! 267: mov[ecx] IOP.IOP_calldown_ptr, eax ! 268: push ecx ! 269: call[eax] DCB_cd_entry.DCB_cd_io_address ! 270: add esp, 4 ! 271: popad ! 272: popfd ! 273: } ! 274: } ! 275: ! 276: BOOL ! 277: OnSysDynamicDeviceInit () ! 278: { ! 279: cv1.cryptsectorfirst = 0x7fffffff; ! 280: cv1.cryptsectorlast = 0; ! 281: ! 282: cv2.cryptsectorfirst = 0x7fffffff; ! 283: cv2.cryptsectorlast = 0; ! 284: ! 285: cv3.cryptsectorfirst = 0x7fffffff; ! 286: cv3.cryptsectorlast = 0; ! 287: ! 288: cv4.cryptsectorfirst = 0x7fffffff; ! 289: cv4.cryptsectorlast = 0; ! 290: ! 291: cv5.cryptsectorfirst = 0x7fffffff; ! 292: cv5.cryptsectorlast = 0; ! 293: ! 294: cv6.cryptsectorfirst = 0x7fffffff; ! 295: cv6.cryptsectorlast = 0; ! 296: ! 297: cv7.cryptsectorfirst = 0x7fffffff; ! 298: cv7.cryptsectorlast = 0; ! 299: ! 300: cv8.cryptsectorfirst = 0x7fffffff; ! 301: cv8.cryptsectorlast = 0; ! 302: ! 303: IOS_Register (&theDRP); ! 304: return TRUE; /* stay resident no matter what IOS says */ ! 305: } ! 306: ! 307: BOOL ! 308: OnSysDynamicDeviceExit () ! 309: { ! 310: return TRUE; ! 311: } ! 312: ! 313: DWORD ! 314: OnDeviceIoControl (PDIOCPARAMETERS p) ! 315: { ! 316: installhook (); /* make sure hook is installed */ ! 317: InstallTCThread (); ! 318: ! 319: /* select on IOCTL code */ ! 320: switch (p->dwIoControlCode) ! 321: { ! 322: ! 323: case 0: /* VWIN32 pinging us during CreateFile */ ! 324: case -1: /* CloseHandle */ ! 325: break; ! 326: ! 327: case ALLOW_FAST_SHUTDOWN: ! 328: { ! 329: bAllowFastShutdown = 1; ! 330: break; ! 331: } ! 332: ! 333: case DRIVER_VERSION: ! 334: { ! 335: LONG *tmp = (LONG *) p->lpvInBuffer; ! 336: LONG tmp2 = VERSION_NUM; ! 337: ! 338: if (tmp == NULL) ! 339: return ERROR_GEN_FAILURE; ! 340: ! 341: memcpy (tmp, &tmp2, 4); ! 342: break; ! 343: } ! 344: ! 345: case WIPE_CACHE: ! 346: WipeCache (); ! 347: break; ! 348: ! 349: case CACHE_STATUS: ! 350: return cacheEmpty ? ERROR_GEN_FAILURE : 0; ! 351: ! 352: case DISKIO: /* Call to read and write sectors from ! 353: application */ ! 354: { ! 355: DISKIO_STRUCT *dio = (DISKIO_STRUCT *) p->lpvInBuffer; ! 356: int s; ! 357: ! 358: if (dio == NULL) ! 359: return ERROR_GEN_FAILURE; ! 360: ! 361: s = AppAccessBlockDevice (dio->devicenum, dio->sectorstart, dio->sectorlen, dio->bufferad, dio->mode); ! 362: dio->nReturnCode = s; ! 363: ! 364: break; ! 365: } ! 366: ! 367: case OPEN_TEST: ! 368: { ! 369: OPEN_TEST_STRUCT *item = (OPEN_TEST_STRUCT *) p->lpvInBuffer; ! 370: unsigned long *tmp = (void *) partitiontestbuffer; ! 371: MOUNT_STRUCT mount; ! 372: ! 373: if (item == NULL) ! 374: return ERROR_GEN_FAILURE; ! 375: ! 376: strcpy ((char *) mount.wszVolume, (char *) item->wszFileName); ! 377: ! 378: item->nReturnCode = ERR_BAD_DRIVE_LETTER; ! 379: ! 380: readallpartitions (&mount, TRUE); ! 381: ! 382: item->nReturnCode = mount.nReturnCode; ! 383: ! 384: item->secstart = tmp[0]; ! 385: item->seclast = tmp[1]; ! 386: item->device = tmp[2]; ! 387: ! 388: break; ! 389: } ! 390: ! 391: case MOUNT_LIST_N: ! 392: { ! 393: MOUNT_LIST_N_STRUCT *item = (MOUNT_LIST_N_STRUCT *) p->lpvInBuffer; ! 394: cryptvol *cv; ! 395: int c; ! 396: ! 397: if (item == NULL) ! 398: return ERROR_GEN_FAILURE; ! 399: ! 400: item->nReturnCode = ERR_BAD_DRIVE_LETTER; ! 401: ! 402: for (c = 0; c < NUMSLOTS; c++) ! 403: { ! 404: cv = cryptvols[c]; ! 405: ! 406: if ((cv->booted == 0) && (cv->physdevDCB == 0)) ! 407: continue; ! 408: ! 409: if (item->nDosDriveNo == cv->drive) ! 410: { ! 411: /* 16/9/99 This is safe as ! 412: item->wszVolume is > ! 413: cv->mounted_file_name */ ! 414: strcpy ((char *) item->wszVolume, cv->mounted_file_name); ! 415: item->nReturnCode = 0; ! 416: break; ! 417: } ! 418: } ! 419: ! 420: break; ! 421: } ! 422: ! 423: case RELEASE_TIME_SLICE: ! 424: ReleaseTimeSlice (); ! 425: break; ! 426: ! 427: case MOUNT: ! 428: { ! 429: MOUNT_STRUCT *mount = (MOUNT_STRUCT *) p->lpvInBuffer; ! 430: char tmp[9]; ! 431: ! 432: if (mount == NULL) ! 433: return ERROR_GEN_FAILURE; ! 434: ! 435: #if EXTRA_INFO ! 436: _Debug_Printf_Service ("MOUNT\n"); ! 437: #endif ! 438: ! 439: memcpy (tmp, (char *) mount->wszVolume, 8); ! 440: tmp[8] = 0; ! 441: ! 442: if (strcmp (tmp, "\\Device\\") == 0) ! 443: readallpartitions (mount, FALSE); ! 444: else ! 445: mountdiskfileR0 (mount); ! 446: ! 447: if (mount->nReturnCode == 0 && bAllowFastShutdown == 1) ! 448: { ! 449: IFSMgr_PNPEvent (DBT_DEVICEARRIVAL, mount->nDosDriveNo, PNPT_VOLUME | DBTF_MEDIA ); ! 450: } ! 451: ! 452: ! 453: #if EXTRA_INFO ! 454: _Debug_Printf_Service ("MOUNT end\n"); ! 455: #endif ! 456: ! 457: break; ! 458: } ! 459: ! 460: case UNMOUNT: ! 461: case UNMOUNT_PENDING: ! 462: { ! 463: UNMOUNT_STRUCT *unmount = (UNMOUNT_STRUCT *) p->lpvInBuffer; ! 464: cryptvol *cv; ! 465: int c; ! 466: ! 467: if (unmount == NULL) ! 468: return ERROR_GEN_FAILURE; ! 469: ! 470: unmount->nReturnCode = ERR_BAD_DRIVE_LETTER; ! 471: ! 472: for (c = 0; c < NUMSLOTS; c++) ! 473: { ! 474: cv = cryptvols[c]; ! 475: ! 476: if ((cv->booted == 0) && (cv->physdevDCB == 0)) ! 477: continue; ! 478: ! 479: if (unmount->nDosDriveNo == cv->drive) ! 480: { ! 481: if (p->dwIoControlCode == UNMOUNT_PENDING) ! 482: { ! 483: if (closeCrDevice (cv, 0) != 0) ! 484: unmount->nReturnCode = ERR_FILES_OPEN; ! 485: else ! 486: unmount->nReturnCode = 0; ! 487: } ! 488: else ! 489: { ! 490: if (closeCrDevice (cv, 1) != 0) ! 491: unmount->nReturnCode = ERR_FILES_OPEN; ! 492: else ! 493: unmount->nReturnCode = 0; ! 494: } ! 495: ! 496: break; ! 497: } ! 498: } ! 499: ! 500: break; ! 501: } ! 502: ! 503: case MOUNT_LIST: ! 504: { ! 505: MOUNT_LIST_STRUCT *list = (MOUNT_LIST_STRUCT *) p->lpvInBuffer; ! 506: cryptvol *cv; ! 507: int c; ! 508: ! 509: if (list == NULL) ! 510: return ERROR_GEN_FAILURE; ! 511: ! 512: list->ulMountedDrives = 0; ! 513: ! 514: for (c = 0; c < NUMSLOTS; c++) ! 515: { ! 516: int nDosDriveNo; ! 517: ! 518: cv = cryptvols[c]; ! 519: ! 520: if ((cv->booted == 0) && (cv->physdevDCB == 0)) ! 521: continue; ! 522: ! 523: nDosDriveNo = cv->drive; ! 524: ! 525: list->ulMountedDrives |= 1 << nDosDriveNo; ! 526: ! 527: if (strlen (cv->mounted_file_name) < 64) ! 528: { ! 529: strcpy ((char *) list->wszVolume[nDosDriveNo], cv->mounted_file_name); ! 530: } ! 531: else ! 532: { ! 533: memcpy ((char *) list->wszVolume[nDosDriveNo], cv->mounted_file_name, 60); ! 534: ((char *) list->wszVolume[nDosDriveNo])[60] = '.'; ! 535: ((char *) list->wszVolume[nDosDriveNo])[61] = '.'; ! 536: ((char *) list->wszVolume[nDosDriveNo])[62] = '.'; ! 537: ((char *) list->wszVolume[nDosDriveNo])[63] = 0; ! 538: } ! 539: ! 540: list->cipher[nDosDriveNo] = cv->cryptoInfo->cipher; ! 541: ! 542: if(!cv->mountfilehandle) ! 543: list->diskLength[nDosDriveNo] = (cv->cryptsectorlast - cv->cryptsectorfirst) * 512I64; ! 544: else ! 545: list->diskLength[nDosDriveNo] = 0; ! 546: ! 547: list->cipher[nDosDriveNo] = cv->cryptoInfo->cipher; ! 548: ! 549: } ! 550: ! 551: break; ! 552: } ! 553: ! 554: case VOLUME_PROPERTIES: ! 555: { ! 556: VOLUME_PROPERTIES_STRUCT *prop = (VOLUME_PROPERTIES_STRUCT *) p->lpvInBuffer; ! 557: cryptvol *cv; ! 558: int c; ! 559: ! 560: if (prop == NULL) ! 561: return ERROR_GEN_FAILURE; ! 562: ! 563: for (c = 0; c < NUMSLOTS; c++) ! 564: { ! 565: int nDosDriveNo; ! 566: ! 567: cv = cryptvols[c]; ! 568: ! 569: if ((cv->booted == 0) && (cv->physdevDCB == 0)) ! 570: continue; ! 571: ! 572: nDosDriveNo = cv->drive; ! 573: ! 574: if (nDosDriveNo != prop->driveNo) ! 575: continue; ! 576: ! 577: if (strlen (cv->mounted_file_name) < 64) ! 578: { ! 579: strcpy ((char *) prop->wszVolume, cv->mounted_file_name); ! 580: } ! 581: else ! 582: { ! 583: memcpy ((char *) prop->wszVolume, cv->mounted_file_name, 60); ! 584: ((char *) prop->wszVolume)[60] = '.'; ! 585: ((char *) prop->wszVolume)[61] = '.'; ! 586: ((char *) prop->wszVolume)[62] = '.'; ! 587: ((char *) prop->wszVolume)[63] = 0; ! 588: } ! 589: ! 590: prop->cipher = cv->cryptoInfo->cipher; ! 591: ! 592: if(!cv->mountfilehandle) ! 593: prop->diskLength = (cv->cryptsectorlast - cv->cryptsectorfirst) * 512I64; ! 594: else ! 595: prop->diskLength = 0; ! 596: ! 597: prop->cipher = cv->cryptoInfo->cipher; ! 598: prop->pkcs5 = cv->cryptoInfo->pkcs5; ! 599: prop->pkcs5Iterations = cv->cryptoInfo->noIterations; ! 600: prop->volumeCreationTime = cv->cryptoInfo->volume_creation_time; ! 601: prop->headerCreationTime = cv->cryptoInfo->header_creation_time; ! 602: ! 603: return 0; ! 604: } ! 605: ! 606: return ERROR_GEN_FAILURE; ! 607: } ! 608: ! 609: ! 610: default: ! 611: return ERROR_INVALID_FUNCTION; ! 612: ! 613: } ! 614: ! 615: return 0; ! 616: } ! 617: ! 618: BOOL ! 619: Kill_Drive (cryptvol * cv) ! 620: { ! 621: BOOL result = FALSE; ! 622: ! 623: if (cv->booted != 0 || cv->physdevDCB != 0) ! 624: { ! 625: if ((cv->drive >= 0) && (cv->drive < 26)) ! 626: { ! 627: result = IspDisassociateDcb (cv->drive); ! 628: if (cv->mountfilehandle) ! 629: R0_CloseFile (cv->mountfilehandle); ! 630: ! 631: if (result == TRUE) ! 632: { ! 633: PDCB dcb; ! 634: ! 635: if (!cv->mountfilehandle) ! 636: unlockdrive (cv); /* files to be handled ! 637: by win32 app. */ ! 638: ! 639: crypto_close (cv->cryptoInfo); ! 640: ! 641: dcb = cv->ldcb; ! 642: dcb->DCB_Port_Specific = 0; ! 643: memset (cv, 0, sizeof (cryptvol)); ! 644: cv->cryptsectorfirst = 0x7fffffff; ! 645: } ! 646: } ! 647: } ! 648: ! 649: return result; ! 650: } ! 651: ! 652: int ! 653: closeCrDevice (cryptvol * cv, int mode) ! 654: { ! 655: if (mode == 0) /* pre flush volume call..... */ ! 656: { ! 657: if (cv->drive != 0) ! 658: { ! 659: if (cv->booted <= 2) ! 660: { ! 661: _VolFlush (cv->drive, 0); /* flush stuff out ! 662: before the ! 663: dismount... */ ! 664: //%% NotifyVolumeRemoval (cv->drive); ! 665: } ! 666: return 0; ! 667: } ! 668: else ! 669: return 1; ! 670: } ! 671: else ! 672: { ! 673: if (Kill_Drive (cv) == TRUE) ! 674: return 0; ! 675: else ! 676: return 0x42424242; ! 677: } ! 678: } ! 679: ! 680: int ! 681: installthread (void *t) ! 682: { ! 683: int id; ! 684: _asm ! 685: { ! 686: mov ecx, 4096 ! 687: mov edi, 0 ! 688: mov ebx,[t]; ! 689: xor esi, esi ! 690: } ! 691: ! 692: VxDCall (_VWIN32_CreateRing0Thread) ! 693: _asm mov[id], eax ! 694: return id; ! 695: } ! 696: ! 697: void ! 698: sectorcopy (char *dest, char *source, int num) ! 699: { ! 700: _asm ! 701: { ! 702: pushad ! 703: mov edi,[dest] ! 704: mov esi,[source] ! 705: mov ecx,[num] ! 706: shl ecx, 9 /* *512 */ ! 707: sar ecx, 4 /* 16 in pass... */ ! 708: cpylp: ! 709: mov eax,[esi] ! 710: mov ebx,[esi + 4] ! 711: mov[edi], eax ! 712: mov[edi + 4], ebx ! 713: mov eax,[esi + 8] ! 714: mov ebx,[esi + 12] ! 715: mov[edi + 8], eax ! 716: mov[edi + 12], ebx ! 717: add edi, 16 ! 718: add esi, 16 ! 719: dec ecx ! 720: jnz cpylp ! 721: popad ! 722: } ! 723: } ! 724: ! 725: void ! 726: cryptproc (PIOP iop, cryptvol * cv) ! 727: { ! 728: PDCB dcbx; ! 729: unsigned int buffernum, totalsectors; ! 730: unsigned int sectorstart, sectorcount; ! 731: char *outbuffer, *bufadr, *buffercopy; ! 732: _BlockDev_Scatter_Gather *sgd; ! 733: ! 734: dcbx = (PDCB) iop->IOP_physical_dcb; ! 735: ior.IOR_status = 0; ! 736: if (ior.IOR_func == IOR_WRITEV) ! 737: { ! 738: ior.IOR_status = IORS_INVALID_COMMAND; ! 739: return; ! 740: } ! 741: ! 742: sectorcount = ior.IOR_xfer_count; ! 743: ! 744: if (!sectorcount) ! 745: { ! 746: ior.IOR_status = 0; ! 747: return; ! 748: } ! 749: ! 750: if ((ior.IOR_func == IOR_READ) || (ior.IOR_func == IOR_WRITE)) ! 751: { ! 752: if (iop->IOP_ior.IOR_flags & IORF_CHAR_COMMAND) ! 753: { ! 754: ior.IOR_status = IORS_INVALID_COMMAND; ! 755: return; /* Char command NOT supported or needed.... */ ! 756: } ! 757: } ! 758: else ! 759: { ! 760: ior.IOR_status = 0; ! 761: if (!cv->mountfilehandle) ! 762: DoCallDown (iop); ! 763: return; ! 764: } ! 765: ! 766: if (ior.IOR_func == IOR_READ) ! 767: { ! 768: sectorstart = ior.IOR_start_addr[0]; ! 769: sectorcount = ior.IOR_xfer_count; ! 770: outbuffer = (char *) ior.IOR_buffer_ptr; /* may be scatter gather ! 771: pointer... */ ! 772: if (ior.IOR_flags & IORF_SCATTER_GATHER) ! 773: { ! 774: sgd = (_BlockDev_Scatter_Gather *) outbuffer; ! 775: while ((sectorcount = sgd->BD_SG_Count)) ! 776: { ! 777: outbuffer = (char *) sgd->BD_SG_Buffer_Ptr; ! 778: inblock (iop, outbuffer, sectorstart, sectorcount, cv); ! 779: ! 780: if (sectorstart == 0) ! 781: { ! 782: (unsigned char) outbuffer[0] = 0xeb; ! 783: outbuffer[1] = 0x3c; ! 784: (unsigned char) outbuffer[2] = 0x90; ! 785: ! 786: outbuffer[510] = 0x55; /* boot sector ! 787: bodge...... */ ! 788: (unsigned char) outbuffer[511] = 0xAA; ! 789: } ! 790: ! 791: sectorstart += sectorcount; ! 792: ++sgd; ! 793: } ! 794: } ! 795: else ! 796: /* linear buffer */ ! 797: { ! 798: inblock (iop, outbuffer, sectorstart, sectorcount, cv); ! 799: ! 800: /* The following code LIES to win98, who won't ! 801: otherwise mount disks created by earlier versions, ! 802: because the boot sector had stuff missing. (fixed ! 803: now...) */ ! 804: if (sectorstart == 0) ! 805: { ! 806: (unsigned char) outbuffer[0] = 0xeb; ! 807: outbuffer[1] = 0x3c; ! 808: (unsigned char) outbuffer[2] = 0x90; ! 809: outbuffer[510] = 0x55; ! 810: (unsigned char) outbuffer[511] = 0xAA; ! 811: } ! 812: } ! 813: } /* end read op */ ! 814: else if (ior.IOR_func == IOR_WRITE) ! 815: { ! 816: if (cv->booted == 0) ! 817: { ! 818: ior.IOR_status = 0; ! 819: return; ! 820: } ! 821: ! 822: buffernum = 0; ! 823: ! 824: bufadr = transferbuffer; ! 825: bufadr += (buffernum * (MAXBLOCK * 512)); ! 826: sectorstart = ior.IOR_start_addr[0]; ! 827: sectorcount = ior.IOR_xfer_count; ! 828: outbuffer = (char *) ior.IOR_buffer_ptr; /* may be scatter gather ! 829: pointer...; */ ! 830: totalsectors = 0; ! 831: buffercopy = bufadr; ! 832: ! 833: if (ior.IOR_flags & IORF_SCATTER_GATHER) ! 834: { ! 835: sgd = (_BlockDev_Scatter_Gather *) outbuffer; ! 836: while ((sectorcount = sgd->BD_SG_Count)) ! 837: { ! 838: outbuffer = (char *) sgd->BD_SG_Buffer_Ptr; ! 839: if ((totalsectors + sectorcount) <= MAXBLOCK) ! 840: { ! 841: sectorcopy (buffercopy, outbuffer, sectorcount); ! 842: totalsectors += sectorcount; ! 843: buffercopy += sectorcount * 512; ! 844: } ! 845: else ! 846: /* write any previous buffer..... */ ! 847: { ! 848: if (totalsectors) /* was it too big to ! 849: start with ? */ ! 850: { ! 851: outblock (iop, bufadr, sectorstart, totalsectors, cv, NULL); ! 852: ! 853: buffernum = 0; ! 854: ! 855: bufadr = transferbuffer; ! 856: bufadr += (buffernum * (MAXBLOCK * 512)); ! 857: sectorstart += totalsectors; ! 858: totalsectors = 0; ! 859: buffercopy = bufadr; ! 860: --sgd; /* back to previous for ! 861: next pass..... */ ! 862: } ! 863: else ! 864: { /* initial buffer was too ! 865: big, to start with! */ ! 866: outblock (iop, outbuffer, sectorstart, sectorcount, cv, bufadr); ! 867: ! 868: buffernum = 0; ! 869: ! 870: bufadr = transferbuffer; ! 871: bufadr += (buffernum * (MAXBLOCK * 512)); ! 872: sectorstart += sectorcount; ! 873: buffercopy = bufadr; ! 874: } ! 875: ! 876: } ! 877: ++sgd; ! 878: } /* end while */ ! 879: ! 880: if (totalsectors) ! 881: outblock (iop, bufadr, sectorstart, totalsectors, cv, NULL); /* last one ? */ ! 882: } /* end if scatter gather */ ! 883: else ! 884: /* not scatter gather but is linear buffer */ ! 885: { ! 886: ! 887: outblock (iop, outbuffer, sectorstart, sectorcount, cv, bufadr); /* get it to copy and do ! 888: large bit... */ ! 889: } ! 890: } /* end write op */ ! 891: ! 892: } ! 893: ! 894: /* DoCallBack handles completion of an I/O request by calling the previous ! 895: level's callback routine. */ ! 896: ! 897: void ! 898: DoCallBack (PIOP iop) ! 899: { ! 900: _asm ! 901: { /* call back to previous layer */ ! 902: pushfd ! 903: pushad ! 904: mov ecx,[iop] ! 905: sub[ecx] IOP.IOP_callback_ptr, size IOP_callback_entry ! 906: mov eax,[ecx] IOP.IOP_callback_ptr ! 907: push ecx ! 908: call[eax] IOP_callback_entry.IOP_CB_address ! 909: add esp, 4 ! 910: popad ! 911: popfd ! 912: ! 913: } ! 914: } ! 915: ! 916: VOID ! 917: partfilerequest (PIOP iop) ! 918: { ! 919: PDCB dcb; ! 920: cryptvol *cv; ! 921: ! 922: dcb = (PDCB) iop->IOP_physical_dcb; ! 923: cv = (cryptvol *) dcb->DCB_Port_Specific; ! 924: ! 925: ! 926: if ((cv != &cv1) && (cv != &cv2) && (cv != &cv3) && (cv != &cv4) && (cv != &cv5) && (cv != &cv6) && (cv != &cv7) && (cv != &cv8)) ! 927: { ! 928: DoCallDown (iop); ! 929: return; ! 930: } ! 931: ! 932: if (cv->booted > 2) ! 933: { ! 934: ior.IOR_status = IORS_NOT_READY; /* HW_FAILURE; */ ! 935: DoCallBack (iop); ! 936: return; ! 937: } ! 938: ! 939: if (ior.IOR_func == IOR_COMPUTE_GEOM) ! 940: { ! 941: dcb->DCB_actual_sector_cnt[0] = cv->cryptsectorlast - cv->cryptsectorfirst; ! 942: dcb->DCB_actual_sector_cnt[0]++; ! 943: dcb->DCB_actual_sector_cnt[1] = 0; ! 944: dcb->DCB_actual_blk_size = 512; ! 945: dcb->DCB_actual_head_cnt = 1; /* number of heads */ ! 946: dcb->DCB_actual_cyl_cnt = 1; /* number of cylinders */ ! 947: dcb->DCB_cmn.DCB_apparent_blk_shift = 9; ! 948: dcb->DCB_cmn.DCB_TSD_Flags |= DCB_TSD_ACTUAL_PRE_SET; ! 949: ior.IOR_status = IORS_SUCCESS; ! 950: DoCallBack (iop); ! 951: return; ! 952: } ! 953: ! 954: if (ior.IOR_func == IOR_GEN_IOCTL) ! 955: { ! 956: iop->IOP_ior.IOR_ioctl_return = 01; ! 957: ior.IOR_status = IORS_INVALID_PARM; /* All the time now.... */ ! 958: DoCallBack (iop); ! 959: return; ! 960: } ! 961: ! 962: if ((ior.IOR_func == IOR_READ) || (ior.IOR_func == IOR_WRITE)) ! 963: { ! 964: dcb = (PDCB) iop->IOP_physical_dcb; ! 965: ior.IOR_status = IORS_CMD_IN_PROGRESS; /* 0 */ ! 966: ! 967: dcb->DCB_cmn.DCB_device_flags |= DCB_DEV_IO_ACTIVE; ! 968: QueueMyIop (iop); ! 969: return; ! 970: } ! 971: ! 972: if ((ior.IOR_func == IOR_MEDIA_CHECK) || (ior.IOR_func == IOR_MEDIA_CHECK_RESET)) ! 973: { ! 974: dcb = (PDCB) iop->IOP_original_dcb; ! 975: ! 976: ior.IOR_status = IORS_UNCERTAIN_MEDIA; /* IORS_SUCCESS; */ ! 977: DoCallBack (iop); ! 978: return; ! 979: } ! 980: ! 981: ior.IOR_status = IORS_INVALID_COMMAND; ! 982: DoCallBack (iop); ! 983: return; ! 984: } ! 985: ! 986: int ! 987: Add_Drive (PDCB dcb, cryptvol * cv, int prefdrive) ! 988: { ! 989: int md = 0; ! 990: PDCB ldcb; ! 991: unsigned int flags; ! 992: unsigned int dmdbits; ! 993: ldcb = &cv->logicaldcb; ! 994: cv->ldcb = ldcb; ! 995: ! 996: #if EXTRA_INFO ! 997: _Debug_Printf_Service ("Add_Drive\n"); ! 998: #endif ! 999: ! 1000: if (1) ! 1001: { ! 1002: ldcb = &cv->logicaldcb; ! 1003: flags = ldcb->DCB_cmn.DCB_device_flags; ! 1004: ! 1005: if (dcb) ! 1006: memcpy ((char *) ldcb, (char *) dcb, sizeof (DCB)); ! 1007: ! 1008: ldcb->DCB_cmn.DCB_device_flags = flags; ! 1009: flags = dcb->DCB_cmn.DCB_device_flags; ! 1010: dmdbits = dcb->DCB_cmn.DCB_dmd_flags; ! 1011: dmdbits &= ~DCB_dmd_phys_sgd; ! 1012: cv->ldcb = ldcb; ! 1013: if (!cv->mountfilehandle) ! 1014: IspInsertCalldown (ldcb, partfilerequest, (PDDB) & cv->addb, ! 1015: (USHORT) dcb->DCB_cmn.DCB_expansion_length, ! 1016: dmdbits, (UCHAR) DRP_VSD_3); ! 1017: else ! 1018: IspInsertCalldown (ldcb, partfilerequest, (PDDB) & cv->addb, 0, ! 1019: 0, (UCHAR) DRP_VSD_3); ! 1020: ! 1021: ldcb->DCB_Port_Specific = (ULONG) cv; ! 1022: ldcb->DCB_cmn.DCB_physical_dcb = (ULONG) ldcb; ! 1023: ldcb->DCB_max_xfer_len = MAXBLOCK * 512; /* 256*512 */ ! 1024: ! 1025: if ((dcb->DCB_max_xfer_len < MAXBLOCK * 512) && (cv->mountfilehandle == 0)) ! 1026: ldcb->DCB_max_xfer_len = dcb->DCB_max_xfer_len; ! 1027: ! 1028: if (!cv->mountfilehandle) ! 1029: { ! 1030: ldcb->DCB_max_sg_elements = dcb->DCB_max_sg_elements; /* 1; */ ! 1031: ldcb->DCB_cmn.DCB_expansion_length = dcb->DCB_cmn.DCB_expansion_length; ! 1032: ldcb->DCB_cmn.DCB_dmd_flags = dmdbits; ! 1033: } ! 1034: else ! 1035: ldcb->DCB_max_sg_elements = 17; ! 1036: ! 1037: ldcb->DCB_cmn.DCB_device_flags |= DCB_DEV_PHYSICAL; ! 1038: ldcb->DCB_cmn.DCB_device_flags2 = 0; ! 1039: ldcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_REMOVABLE; /* support removable as ! 1040: fixed... */ ! 1041: ldcb->DCB_cmn.DCB_device_type = DEVICE_TYPE; ! 1042: ldcb->DCB_cmn.DCB_user_drvlet = (USHORT) md; ! 1043: ldcb->DCB_cmn.DCB_partition_type = 0; ! 1044: ldcb->DCB_cmn.DCB_Sstor_Host = 0; ! 1045: ldcb->DCB_actual_sector_cnt[0] = 0; ! 1046: ldcb->DCB_actual_sector_cnt[0]++; ! 1047: ldcb->DCB_actual_sector_cnt[1] = 0; ! 1048: ldcb->DCB_actual_blk_size = 512; ! 1049: ldcb->DCB_actual_head_cnt = 1; /* number of heads */ ! 1050: ldcb->DCB_actual_cyl_cnt = 1; /* number of cylinders */ ! 1051: ldcb->DCB_cmn.DCB_apparent_blk_shift = 9; ! 1052: ldcb->DCB_actual_spt = ldcb->DCB_actual_sector_cnt[0]; ! 1053: ldcb->DCB_bdd.DCB_apparent_sector_cnt[0] = ldcb->DCB_actual_sector_cnt[0]; ! 1054: ldcb->DCB_bdd.DCB_apparent_sector_cnt[1] = 0; ! 1055: ldcb->DCB_bdd.DCB_apparent_head_cnt = 1; ! 1056: ldcb->DCB_bdd.DCB_apparent_blk_size = 512; ! 1057: ldcb->DCB_bdd.DCB_apparent_cyl_cnt = 1; ! 1058: ldcb->DCB_bdd.DCB_apparent_spt = ldcb->DCB_actual_sector_cnt[0]; ! 1059: } ! 1060: ! 1061: ldcb->DCB_cmn.DCB_drive_lttr_equiv = 0; ! 1062: ldcb->DCB_cmn.DCB_user_drvlet = 0; ! 1063: ldcb->DCB_cmn.DCB_device_type = DEVICE_TYPE; ! 1064: ! 1065: if (prefdrive != -1) ! 1066: md = IspDriveLetterPickPref (ldcb, (UCHAR) ISP_PDL_FL_USE_RANGE, (UCHAR) prefdrive); ! 1067: else ! 1068: md = (unsigned char) 255; ! 1069: ! 1070: ! 1071: if (md == 255) ! 1072: md = IspDriveLetterPick (ldcb, 0); ! 1073: ! 1074: ldcb->DCB_cmn.DCB_unit_number = (UCHAR) md; ! 1075: ldcb->DCB_cmn.DCB_vrp_ptr = 0; /* clear the copied VRP pointer...... */ ! 1076: ldcb->DCB_cmn.DCB_device_flags |= DCB_DEV_WRITEABLE; ! 1077: ! 1078: if (!(flags & DCB_DEV_WRITEABLE)) ! 1079: ldcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_WRITEABLE; ! 1080: ! 1081: ldcb->DCB_cmn.DCB_drive_lttr_equiv = md; ! 1082: ldcb->DCB_cmn.DCB_user_drvlet = (UCHAR) md; ! 1083: ldcb->DCB_cmn.DCB_unit_number = (UCHAR) md; /* 0; */ ! 1084: ! 1085: cv->drive = (ULONG) md; ! 1086: ldcb->DCB_cmn.DCB_TSD_Flags = DCB_TSD_APPARENT_PRE_SET | DCB_TSD_MBPB_PBR; ! 1087: ldcb->DCB_cmn.DCB_partition_type = 0; ! 1088: ldcb->DCB_cmn.DCB_device_flags &= ~DCB_DEV_TSD_PROCESSED; ! 1089: ldcb->DCB_cmn.DCB_Partition_Start = 0; ! 1090: ldcb->DCB_cmn.DCB_device_flags |= DCB_DEV_LOGICAL | DCB_DEV_MEDIA_CHANGED | DCB_DEV_UNCERTAIN_MEDIA; ! 1091: ! 1092: ldcb->DCB_cmn.DCB_cAssoc = 1; ! 1093: ! 1094: ldcb->DCB_cmn.DCB_user_drvlet = 0xFF; ! 1095: ! 1096: #if EXTRA_INFO ! 1097: _Debug_Printf_Service ("Add_Drive end\n"); ! 1098: #endif ! 1099: ! 1100: if ((md <= 26) && (md > 1)) ! 1101: { ! 1102: IspAssociateDcb (ldcb, (char) md, ISP_D_A_FL_NOSHELLMSG); ! 1103: ! 1104: cv->notifytime = 2; /* 2 second to notify arrival of disk */ ! 1105: ! 1106: return 0; ! 1107: } ! 1108: ! 1109: return 1; ! 1110: } ! 1111: ! 1112: #define FIRST_READ_SIZE SECTOR_SIZE ! 1113: ! 1114: int ! 1115: trymountfile (PDCB dcb, cryptvol * cv, MOUNT_STRUCT * mf) ! 1116: { ! 1117: USHORT offset; ! 1118: USHORT size; ! 1119: PIOP myiop; ! 1120: PIOR myior; ! 1121: int mounted = 0; ! 1122: char *readBuffer = NULL; ! 1123: ! 1124: if (dcb->DCB_cmn.DCB_device_type == DCB_type_disk) ! 1125: { ! 1126: int status; ! 1127: ! 1128: offset = (USHORT) (dcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET (IOP, IOP_ior)); ! 1129: size = offset + sizeof (IOR) + dcb->DCB_max_sg_elements * sizeof (SGD); ! 1130: myiop = IspCreateIop (size, offset, ISP_M_FL_MUST_SUCCEED | ISP_M_FL_SMART_ALLOC | ISP_M_FL_INTERRUPT_TIME | ISP_M_FL_PERSISTENT_IOP); ! 1131: myior = &myiop->IOP_ior; ! 1132: myior->IOR_private_client = offset; ! 1133: ! 1134: readBuffer = TCalloc (FIRST_READ_SIZE); ! 1135: if (readBuffer == NULL) ! 1136: goto error; ! 1137: ! 1138: dophysblock (myiop, cv->cryptsectorfirst, FIRST_READ_SIZE / 512, readBuffer, cv, IOR_READ); ! 1139: ! 1140: status = VolumeReadHeaderCache (mf->bCache, readBuffer, mf->szPassword, ! 1141: mf->nPasswordLen, &cv->cryptoInfo); ! 1142: ! 1143: if (status != 0) ! 1144: { ! 1145: memset (cv, 0, sizeof (cryptvol)); ! 1146: cv->cryptsectorfirst = 0x7fffffff; ! 1147: mounted = 0; ! 1148: goto error; ! 1149: } ! 1150: else ! 1151: cv->booted = 1; ! 1152: ! 1153: if (Add_Drive (dcb, cv, mf->nDosDriveNo) == 0) ! 1154: { ! 1155: mounted = 1; ! 1156: } ! 1157: else ! 1158: { ! 1159: /* No Drive letter available */ ! 1160: memset (cv, 0, sizeof (cryptvol)); ! 1161: cv->cryptsectorfirst = 0x7fffffff; ! 1162: mounted = -1; ! 1163: } ! 1164: ! 1165: error: ! 1166: if (readBuffer != NULL) ! 1167: TCfree (readBuffer); ! 1168: ! 1169: IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client)); ! 1170: return mounted; ! 1171: } ! 1172: ! 1173: return mounted; ! 1174: } ! 1175: ! 1176: void ! 1177: readnullfilesize (int hand) ! 1178: { ! 1179: int bytes; ! 1180: char buffer[512]; ! 1181: R0_ReadFile (FALSE, hand, 0, 0, buffer, &bytes); ! 1182: } ! 1183: ! 1184: void ! 1185: mountdiskfileR0 (MOUNT_STRUCT * mf) ! 1186: { ! 1187: DWORD hfile; ! 1188: DWORD action; ! 1189: int tmf; ! 1190: int code; ! 1191: cryptvol *cv; ! 1192: int c; ! 1193: int writeable = 1; ! 1194: PDCB dcb; ! 1195: int flag = 0; ! 1196: unsigned char openflag = 0x81; ! 1197: ! 1198: char *fname = (char *) mf->wszVolume; ! 1199: ! 1200: ! 1201: installhook (); /* only installs if not done already... */ ! 1202: ! 1203: for (c = 0; c < NUMSLOTS; c++) ! 1204: { ! 1205: cv = cryptvols[c]; ! 1206: if (strcmp (fname, (char *) &cv->mounted_file_name) == 0) ! 1207: { ! 1208: flag = 3 + 128; /* already present */ ! 1209: goto done; ! 1210: } ! 1211: } ! 1212: ! 1213: if (writeable) ! 1214: { ! 1215: code = R0_OpenCreateFile (FALSE, ACCESS_READWRITE | SHARE_DENYREADWRITE, ! 1216: 0, ACTION_OPENEXISTING, 0x81, fname, &hfile, &action); /* R0_NO_CACHE(UBYTE) ! 1217: ((R0_NO_CACHE)>>8) */ ! 1218: ! 1219: if (code != 0) ! 1220: { ! 1221: writeable = 0; ! 1222: code = R0_OpenCreateFile (FALSE, ACCESS_READONLY | SHARE_DENYREAD, ! 1223: 0, ACTION_OPENEXISTING, 0x81, fname, &hfile, &action); /* R0_NO_CACHE(UBYTE) ! 1224: ((R0_NO_CACHE)>>8) */ ! 1225: } ! 1226: ! 1227: if (code == 0) ! 1228: readnullfilesize (hfile); ! 1229: } ! 1230: else ! 1231: { ! 1232: code = R0_OpenCreateFile (FALSE, ACCESS_READONLY | SHARE_DENYREAD, ! 1233: 0, ACTION_OPENEXISTING, 0x81, fname, &hfile, &action); /* R0_NO_CACHE(UBYTE) ! 1234: ((R0_NO_CACHE)>>8) */ ! 1235: ! 1236: if (code == 0) ! 1237: readnullfilesize (hfile); ! 1238: } ! 1239: ! 1240: if (code != 0) ! 1241: { ! 1242: flag = 1; ! 1243: goto done; ! 1244: } ! 1245: ! 1246: for (c = 0; c < NUMSLOTS; c++) ! 1247: { ! 1248: cv = cryptvols[c]; ! 1249: ! 1250: if ((cv->booted == 0) && (cv->physdevDCB == 0)) ! 1251: { ! 1252: cv->filehostdcb = 0; ! 1253: cv->mountfilehandle = hfile; ! 1254: cv->physdevDCB = &cv->logicaldcb; ! 1255: cv->cryptsectorfirst = 0x00000000; ! 1256: cv->cryptsectorlast = 0x7ffffff0; ! 1257: dcb = (PDCB) cv->physdevDCB; ! 1258: flag = 2; ! 1259: ! 1260: if (writeable != 0) ! 1261: dcb->DCB_cmn.DCB_device_flags = DCB_DEV_WRITEABLE; ! 1262: ! 1263: /* clears cv set above if failed.... */ ! 1264: tmf = trymountfile (dcb, cv, mf); ! 1265: ! 1266: if (tmf) ! 1267: { ! 1268: _asm cli ! 1269: flag = 3; ! 1270: ! 1271: mf->nReturnCode = flag; ! 1272: ! 1273: if (tmf > 0) /* if tmg is -ve then no ! 1274: drive letter (already had ! 1275: blue screen..) */ ! 1276: { ! 1277: mf->nReturnCode = flag; ! 1278: ! 1279: cv->booted = 2; ! 1280: strcpy ((char *) &cv->mounted_file_name, fname); ! 1281: ! 1282: goto done; ! 1283: } ! 1284: } /* trymountfile */ ! 1285: ! 1286: } /* if cv->.... */ ! 1287: ! 1288: if (flag) ! 1289: break; /* out of for loop */ ! 1290: } ! 1291: ! 1292: ! 1293: R0_CloseFile (hfile); ! 1294: ! 1295: done: ! 1296: ! 1297: switch (flag) ! 1298: { ! 1299: case 3 + 128: ! 1300: mf->nReturnCode = ERR_VOL_ALREADY_MOUNTED; ! 1301: break; ! 1302: case 1: ! 1303: mf->nReturnCode = ERR_FILE_OPEN_FAILED; ! 1304: break; ! 1305: case 2: ! 1306: mf->nReturnCode = ERR_VOL_MOUNT_FAILED; ! 1307: break; ! 1308: case 3: ! 1309: if (tmf > 0) ! 1310: { ! 1311: mf->nReturnCode = 0; ! 1312: mf->nDosDriveNo = cv->drive; ! 1313: } ! 1314: else ! 1315: mf->nReturnCode = ERR_NO_FREE_DRIVES; ! 1316: break; ! 1317: case 0: ! 1318: mf->nReturnCode = ERR_NO_FREE_SLOTS; ! 1319: break; ! 1320: } ! 1321: } ! 1322: ! 1323: ! 1324: void ! 1325: outblock (PIOP iop, char *outbuffer, int sectorstart, int sectorcount, cryptvol * cv, char *workbuff) ! 1326: { ! 1327: int logsec = sectorstart + 1; /* get logical volume sector. */ ! 1328: ! 1329: char *sendbuffer; ! 1330: ! 1331: if (!sectorcount) ! 1332: return; ! 1333: ! 1334: do ! 1335: { ! 1336: if (sectorcount <= MAXBLOCK) ! 1337: { ! 1338: sendbuffer = outbuffer; ! 1339: ! 1340: /* if copyflag 0, then buffer already set by caller. */ ! 1341: ior.IOR_status = 0; ! 1342: if (workbuff) ! 1343: { ! 1344: sectorcopy (workbuff, outbuffer, sectorcount); ! 1345: sendbuffer = workbuff; ! 1346: } ! 1347: ! 1348: writelogical (iop, logsec, sectorcount, sendbuffer, cv); ! 1349: ! 1350: sectorcount = 0; ! 1351: return; ! 1352: } ! 1353: else ! 1354: { ! 1355: sendbuffer = outbuffer; ! 1356: if (workbuff) ! 1357: { ! 1358: sectorcopy (workbuff, outbuffer, MAXBLOCK); ! 1359: sendbuffer = workbuff; ! 1360: } ! 1361: ! 1362: writelogical (iop, logsec, MAXBLOCK, sendbuffer, cv); ! 1363: logsec += MAXBLOCK; ! 1364: sectorcount -= MAXBLOCK; ! 1365: outbuffer += (MAXBLOCK * 512); ! 1366: } ! 1367: } ! 1368: while ((sectorcount > 0) && (ior.IOR_status < 16)); ! 1369: } ! 1370: ! 1371: void ! 1372: inblock (PIOP iop, char *outbuffer, int sectorstart, int sectorcount, cryptvol * cv) ! 1373: { ! 1374: int logsec = sectorstart + 1; /* get logical volume sector. */ ! 1375: ! 1376: do ! 1377: { ! 1378: ior.IOR_status = 0; ! 1379: if (sectorcount < MAXBLOCK) ! 1380: { ! 1381: readlogical (iop, logsec, sectorcount, (char *) transferbuffer, cv); ! 1382: memcpy (outbuffer, transferbuffer, sectorcount * 512); ! 1383: sectorcount = 0; ! 1384: return; ! 1385: } ! 1386: else ! 1387: { ! 1388: readlogical (iop, logsec, MAXBLOCK, (char *) transferbuffer, cv); ! 1389: memcpy (outbuffer, transferbuffer, MAXBLOCK * 512); ! 1390: logsec += MAXBLOCK; ! 1391: sectorcount -= MAXBLOCK; ! 1392: outbuffer += (MAXBLOCK * 512); ! 1393: } ! 1394: } ! 1395: while ((sectorcount > 0) && (ior.IOR_status < 16)); ! 1396: } ! 1397: ! 1398: int ! 1399: doR0fileio (int sector, int numsectors, char *buffer, cryptvol * cv, int iorop) ! 1400: { ! 1401: CLIENT_STRUCT sregs; /* static */ ! 1402: PVRP v; ! 1403: ! 1404: int res; ! 1405: int bytes; /* static */ ! 1406: ! 1407: ! 1408: if (iorop == IOR_READ) ! 1409: { ! 1410: if (numsectors) ! 1411: { ! 1412: SaveClientState ((CLIENT_STRUCT *) & sregs); ! 1413: ! 1414: res = R0_ReadFile (FALSE, cv->mountfilehandle, numsectors << 9, sector << 9, buffer, &bytes); ! 1415: ! 1416: RestoreClientState ((CLIENT_STRUCT *) & sregs); ! 1417: } ! 1418: ! 1419: return res; ! 1420: } /* IOR read */ ! 1421: ! 1422: res = 0; ! 1423: if (iorop == IOR_WRITE) ! 1424: { ! 1425: if (numsectors) ! 1426: { ! 1427: SaveClientState ((CLIENT_STRUCT *) & sregs); ! 1428: ! 1429: res = R0_WriteFile (FALSE, cv->mountfilehandle, numsectors * 512, sector * 512, buffer, &bytes); ! 1430: ! 1431: RestoreClientState ((CLIENT_STRUCT *) & sregs); ! 1432: } ! 1433: ! 1434: if (res) ! 1435: { ! 1436: if (res == 5) ! 1437: res = 0x13; /* WHY ARE WE GETTING ACCESS ! 1438: DENIED 005 ON CD RATHER ! 1439: THAN WP ? */ ! 1440: ! 1441: if (res == 0x13) ! 1442: { ! 1443: if (cv->booted >= 2) ! 1444: { ! 1445: v = (PVRP) cv->ldcb->DCB_cmn.DCB_vrp_ptr; ! 1446: if (v) ! 1447: { ! 1448: if ((v->VRP_event_flags & VRP_ef_write_protected) == 0) ! 1449: { ! 1450: v->VRP_event_flags |= VRP_ef_write_protected | VRP_ef_media_uncertain; ! 1451: } ! 1452: } ! 1453: } /* cv->booted */ ! 1454: } /* res=13 */ ! 1455: } /* res= something */ ! 1456: ! 1457: return res; ! 1458: } /* IOR write */ ! 1459: ! 1460: return 0; ! 1461: } ! 1462: ! 1463: int ! 1464: MapDosError (int error) ! 1465: { ! 1466: int e; ! 1467: ! 1468: if (error == 0x13) ! 1469: return (IORS_WRITE_PROTECT); ! 1470: ! 1471: e = IORS_NOT_READY; /* IORS_HW_FAILURE; */ ! 1472: return e; ! 1473: } ! 1474: ! 1475: char fileerrorstr[]= ! 1476: { ! 1477: "TC has encountered an error reading a host file which\n" ! 1478: "it is using for a currently open scrambled disk volume.\n\n" ! 1479: "You should immediately dismount the file using the TC mount\n" ! 1480: "application, correct the error, and re mount the disk image file.\n\n\n" ! 1481: "The related disk will be unavailable, until you do, and you should\n" ! 1482: "save your work elsewhere." ! 1483: }; ! 1484: ! 1485: int ! 1486: dophysblock2 (PIOP iop, int sector, int numsectors, char *buffr, cryptvol * cv, USHORT iorop) ! 1487: { ! 1488: int rstatus = 0; /* status return value.... */ ! 1489: PIOP myiop; ! 1490: PIOR myior; ! 1491: ! 1492: _BlockDev_Scatter_Gather *sgd; ! 1493: ! 1494: PDCB mydcb = cv->physdevDCB; /* (PDCB) iop->IOP_physical_dcb; */ ! 1495: USHORT offset; ! 1496: USHORT size; ! 1497: ! 1498: if (cv->mountfilehandle) ! 1499: { ! 1500: if (cv->booted <= 2) ! 1501: rstatus = doR0fileio (sector, numsectors, buffr, cv, iorop); ! 1502: else ! 1503: rstatus = 23; ! 1504: ! 1505: if ((rstatus) && (rstatus != 0x13)) ! 1506: { ! 1507: iop->IOP_timer = iop->IOP_timer_orig = 32000; ! 1508: rstatus = MapDosError (rstatus); ! 1509: ! 1510: if (cv->booted <= 2 && (cv->booted)) ! 1511: { ! 1512: Post_message (fileerrorstr, "TC: Mounted file error"); ! 1513: cv->booted = 256; ! 1514: } ! 1515: } ! 1516: ! 1517: iop->IOP_ior.IOR_status = rstatus; ! 1518: return rstatus; ! 1519: } ! 1520: ! 1521: /* End up here, if we are handling a disk partition rather than ! 1522: container file */ ! 1523: offset = (USHORT) (mydcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET (IOP, IOP_ior)); ! 1524: size = offset + sizeof (IOR) + (8 * sizeof (SGD)); ! 1525: iop->IOP_timer = iop->IOP_timer_orig = 160; ! 1526: ! 1527: myiop = IspCreateIop (size, offset, ISP_M_FL_SMART_ALLOC); ! 1528: ! 1529: if (myiop == NULL) ! 1530: { ! 1531: ! 1532: iop->IOP_ior.IOR_status = IORS_MEMORY_ERROR; ! 1533: return IORS_MEMORY_ERROR; ! 1534: } ! 1535: ! 1536: myior = &myiop->IOP_ior; ! 1537: ! 1538: /* Be aware that Criteria routine reads it's dmd bits from THIS dcb! */ ! 1539: ! 1540: myiop->IOP_original_dcb = (ULONG) mydcb; /* iop->IOP_original_dcb; ! 1541: (ULONG) mydcb; */ ! 1542: myiop->IOP_physical_dcb = (ULONG) mydcb->DCB_cmn.DCB_physical_dcb; ! 1543: if (cv->booted == 1) ! 1544: cv->booted = 2; /* Irrelevant here..... */ ! 1545: myior->IOR_next = 0; ! 1546: myior->IOR_start_addr[1] = 0; ! 1547: myior->IOR_flags = IORF_VERSION_002; ! 1548: myior->IOR_private_client = offset; ! 1549: myior->IOR_req_vol_handle = mydcb->DCB_cmn.DCB_vrp_ptr; ! 1550: myior->IOR_sgd_lin_phys = (ULONG) (myior + 1); ! 1551: myior->IOR_num_sgds = 0; ! 1552: myior->IOR_vol_designtr = mydcb->DCB_cmn.DCB_unit_number; ! 1553: myior->IOR_func = iorop; ! 1554: myior->IOR_flags |= IORF_BYPASS_VOLTRK | IORF_HIGH_PRIORITY | IORF_SCATTER_GATHER | IORF_SYNC_COMMAND | IORF_DONT_CACHE; ! 1555: if (iorop == IOR_READ) ! 1556: myior->IOR_flags |= IORF_DATA_IN; ! 1557: if (iorop == IOR_WRITE) ! 1558: myior->IOR_flags |= IORF_DATA_OUT; ! 1559: myior->IOR_start_addr[0] = sector; ! 1560: myior->IOR_xfer_count = numsectors; ! 1561: sgd = (_BlockDev_Scatter_Gather *) myior->IOR_sgd_lin_phys; /* scatter gather ! 1562: array... */ ! 1563: sgd->BD_SG_Buffer_Ptr = (ULONG) buffr; /* Buffer in LOCKED ram, ! 1564: below 16mbyte, 4K ! 1565: boundary.. */ ! 1566: sgd->BD_SG_Count = numsectors; ! 1567: myior->IOR_buffer_ptr = (ULONG) sgd; /* Implement as Scatter ! 1568: gather, with One block */ ! 1569: sgd++; ! 1570: sgd->BD_SG_Buffer_Ptr = 0; ! 1571: sgd->BD_SG_Count = 0; ! 1572: sgd++; ! 1573: myior->IOR_sgd_lin_phys = (ULONG) sgd; ! 1574: rstatus = myior->IOR_status; ! 1575: sgd->BD_SG_Buffer_Ptr = 0; ! 1576: sgd->BD_SG_Count = 0; ! 1577: sgd++; ! 1578: sgd->BD_SG_Buffer_Ptr = 0; ! 1579: sgd->BD_SG_Count = 0; ! 1580: sgd++; ! 1581: sgd->BD_SG_Buffer_Ptr = 0; ! 1582: sgd->BD_SG_Count = 0; ! 1583: myiop->IOP_timer = 40; ! 1584: myiop->IOP_timer_orig = 40; ! 1585: /* Call criteria, to set phys SGDs physical addresses if needed..... */ ! 1586: if (IlbIntIoCriteria (myiop)) ! 1587: myior->IOR_flags |= IORF_DOUBLE_BUFFER; /* Double buffer, will ! 1588: also make no ! 1589: difference */ ! 1590: IlbInternalRequest (myiop, mydcb, OnRequest); ! 1591: rstatus = myior->IOR_status; ! 1592: iop->IOP_ior.IOR_status = rstatus; /* myior->IOR_status; */ ! 1593: IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client)); ! 1594: return rstatus; ! 1595: } ! 1596: ! 1597: int ! 1598: dophysblock (PIOP iop, int sector, int numsectors, char *buffr, cryptvol * cv, USHORT iorop) ! 1599: { ! 1600: int s, c; ! 1601: ! 1602: for (c = 0; c < 3; c++) ! 1603: { ! 1604: s = dophysblock2 (iop, sector, numsectors, buffr, cv, iorop); ! 1605: if (s == IORS_SUCCESS_WITH_RETRY) ! 1606: return 0; ! 1607: if (!s) ! 1608: return 0; ! 1609: } ! 1610: ! 1611: return s; ! 1612: } ! 1613: ! 1614: void ! 1615: readlogical (PIOP iop, int temp_block, int num_sectors, char *buffer, cryptvol * cv) ! 1616: { ! 1617: int secNum; ! 1618: ! 1619: secNum = temp_block; ! 1620: ! 1621: #if EXTRA_INFO ! 1622: _Debug_Printf_Service ("secNum=%d,num_sectors=%d\n", secNum, num_sectors); ! 1623: #endif ! 1624: ! 1625: dophysblock (iop, secNum + cv->cryptsectorfirst, num_sectors, buffer, cv, IOR_READ); ! 1626: ! 1627: #if EXTRA_INFO ! 1628: _Debug_Printf_Service ("0x%08x\n", *((int *) buffer)); ! 1629: #endif ! 1630: ! 1631: cv->cryptoInfo->decrypt_sector ((unsigned long *) buffer, ! 1632: (unsigned __int64) secNum, num_sectors, ! 1633: &cv->cryptoInfo->ks[0], ! 1634: cv->cryptoInfo->iv, ! 1635: cv->cryptoInfo->cipher); ! 1636: ! 1637: #if EXTRA_INFO ! 1638: _Debug_Printf_Service ("0x%08x\n", *((int *) buffer)); ! 1639: #endif ! 1640: ! 1641: } ! 1642: ! 1643: void ! 1644: writelogical (PIOP iop, int temp_block, int num_sectors, char *buffer, cryptvol * cv) ! 1645: { ! 1646: int secNum; ! 1647: ! 1648: secNum = temp_block; ! 1649: ! 1650: #if EXTRA_INFO ! 1651: _Debug_Printf_Service ("0x%08x\n", *((int *) buffer)); ! 1652: #endif ! 1653: ! 1654: cv->cryptoInfo->encrypt_sector ((unsigned long *) buffer, ! 1655: (unsigned __int64) secNum, num_sectors, ! 1656: &cv->cryptoInfo->ks[0], ! 1657: cv->cryptoInfo->iv, ! 1658: cv->cryptoInfo->cipher); ! 1659: ! 1660: #if EXTRA_INFO ! 1661: _Debug_Printf_Service ("0x%08x\n", *((int *) buffer)); ! 1662: #endif ! 1663: ! 1664: dophysblock (iop, secNum + cv->cryptsectorfirst, num_sectors, buffer, cv, IOR_WRITE); ! 1665: } ! 1666: ! 1667: ! 1668: BOOL ! 1669: OnSystemExit (void) ! 1670: { ! 1671: /* Called when Win32 is about to die. We must close down the files, ! 1672: for any files mounted as encrypted disks. this call seems to be ! 1673: the only chance we get. the system pukes amd hangsif we don't. ! 1674: Corrupt screen etc. nd refuses to shut down..... */ ! 1675: ! 1676: cryptvol *cv; ! 1677: int c; ! 1678: ! 1679: for (c = 0; c < NUMSLOTS; c++) ! 1680: { ! 1681: cv = cryptvols[c]; ! 1682: unlockdrive (cv); ! 1683: if (cv->mountfilehandle) ! 1684: R0_CloseFile (cv->mountfilehandle); ! 1685: } ! 1686: ! 1687: killthread (); ! 1688: return AEP_SUCCESS; ! 1689: } ! 1690: ! 1691: void ! 1692: Post_message (char *msg, char *header) ! 1693: { ! 1694: MessageBox *m; ! 1695: int n; ! 1696: ! 1697: for (n = 0; n < MAX_MESSAGES - 1; n++) ! 1698: { ! 1699: m = &Msgs[n]; ! 1700: if (m->PostPlease == 0) ! 1701: break; ! 1702: ! 1703: } ! 1704: ! 1705: m->PostPlease = 1; ! 1706: m->MessageHdr = header; ! 1707: m->MessageBody = msg; ! 1708: } ! 1709: ! 1710: void ! 1711: ProcessWinMessagesBlueScreen (void) ! 1712: { ! 1713: MessageBox *m; ! 1714: int n; ! 1715: ! 1716: for (n = 0; n < MAX_MESSAGES; n++) ! 1717: { ! 1718: m = &Msgs[n]; ! 1719: if (m->PostPlease) ! 1720: { ! 1721: ShellMessageNCB (0, m->MessageBody, m->MessageHdr); ! 1722: m->PostPlease = 0; ! 1723: } ! 1724: } ! 1725: } ! 1726: ! 1727: /* The code below gets called by the IOS *every* 0.5 seconds... */ ! 1728: USHORT ! 1729: OnHalfSec (PAEP_boot_done aep) /* dummy param */ ! 1730: { ! 1731: #if 0 ! 1732: cryptvol *cv; ! 1733: int c; ! 1734: int notified = 0; ! 1735: #endif ! 1736: ! 1737: halfseccount++; ! 1738: ! 1739: ProcessWinMessagesBlueScreen (); ! 1740: ! 1741: #if 0 ! 1742: for (c = 0; c < 8; c++) ! 1743: { ! 1744: cv = cryptvols[c]; ! 1745: ! 1746: if (cv->notifytime) ! 1747: { ! 1748: cv->notifytime--; ! 1749: if (cv->notifytime == 0) ! 1750: { ! 1751: cv->notifytime = 0x8000ffff; ! 1752: if (!notified) /* prevent multiple notifications */ ! 1753: { ! 1754: notified++; ! 1755: SHELL_CallAtAppyTime ((APPY_CALLBACK) & drivearrived, 0, 0); ! 1756: } ! 1757: } ! 1758: ! 1759: } ! 1760: } ! 1761: #endif ! 1762: ! 1763: return AEP_SUCCESS; ! 1764: } ! 1765: ! 1766: ! 1767: /* ------------------------------------partition support ! 1768: ------------------------------------------- */ ! 1769: ! 1770: /* go round every drive reading all the partitions.... */ ! 1771: void ! 1772: readallpartitions (MOUNT_STRUCT * mf, BOOL bVerifyOnly) ! 1773: { ! 1774: int c = 0; ! 1775: PDCB dcb; ! 1776: USHORT offset; ! 1777: USHORT size; ! 1778: PIOP myiop; ! 1779: PIOR myior; ! 1780: int x, disks, z; ! 1781: char *vol = (char *) mf->wszVolume; ! 1782: ! 1783: mf->nReturnCode = ERR_INVALID_DEVICE; /* Assume failure */ ! 1784: ! 1785: if (strlen ((char *) mf->wszVolume) < 28) ! 1786: return; ! 1787: ! 1788: x = vol[16] - '0'; /* Disk number starting from 0 */ ! 1789: z = vol[27] - '0'; /* Partition number start from 1 */ ! 1790: disks = 0; /* Count of disks */ ! 1791: ! 1792: if (x < 0 || z < 1) ! 1793: return; ! 1794: ! 1795: #if EXTRA_INFO ! 1796: _Debug_Printf_Service ("readallpartitions\n"); ! 1797: #endif ! 1798: ! 1799: while (dcb = dcblist[++c]) ! 1800: { ! 1801: if ((dcb->DCB_cmn.DCB_device_type == 0) && (dcb->DCB_cmn.DCB_apparent_blk_shift == 9)) ! 1802: { ! 1803: if (x != disks++) ! 1804: continue; ! 1805: ! 1806: offset = (USHORT) (dcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET (IOP, IOP_ior)); ! 1807: size = offset + sizeof (IOR) + dcb->DCB_max_sg_elements * sizeof (SGD); ! 1808: myiop = IspCreateIop (size, offset, ISP_M_FL_MUST_SUCCEED | ISP_M_FL_SMART_ALLOC | ISP_M_FL_INTERRUPT_TIME | ISP_M_FL_PERSISTENT_IOP); ! 1809: myior = &myiop->IOP_ior; ! 1810: myior->IOR_private_client = offset; ! 1811: ! 1812: DiskRead (dcb, myiop, 0, 1, partitiontestbuffer, IOR_READ); /* ;single read in case ! 1813: of media change... */ ! 1814: memset (partitiontestbuffer, 0, 512); ! 1815: ! 1816: if (!DiskRead (dcb, myiop, 0, 1, partitiontestbuffer, IOR_READ)) /* +32768 */ ! 1817: { ! 1818: UsePartitionInfo (dcb, myiop, partitiontestbuffer, 0, 0, &z, mf, bVerifyOnly); /* +32768 */ ! 1819: } ! 1820: ! 1821: IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client)); ! 1822: ! 1823: } ! 1824: } ! 1825: ! 1826: #if EXTRA_INFO ! 1827: _Debug_Printf_Service ("readallpartitions end\n"); ! 1828: #endif ! 1829: ! 1830: } ! 1831: ! 1832: ! 1833: int ! 1834: DiskRead (PDCB mydcb, PIOP myiop, unsigned int sector, unsigned int numsectors, char *buffr, USHORT iorop) ! 1835: { ! 1836: int rstatus = 0; /* status return value.... */ ! 1837: unsigned long *errnl = (unsigned long *) buffr; /* no load test... */ ! 1838: PIOR myior; ! 1839: _BlockDev_Scatter_Gather *sgd; ! 1840: ! 1841: myior = &myiop->IOP_ior; ! 1842: myiop->IOP_original_dcb = (ULONG) mydcb; ! 1843: myiop->IOP_physical_dcb = (ULONG) mydcb->DCB_cmn.DCB_physical_dcb; ! 1844: myior->IOR_next = 0; ! 1845: myior->IOR_start_addr[1] = 0; ! 1846: myior->IOR_flags = IORF_VERSION_002; ! 1847: myior->IOR_req_vol_handle = mydcb->DCB_cmn.DCB_vrp_ptr; ! 1848: myior->IOR_sgd_lin_phys = (ULONG) (myior + 1); ! 1849: myior->IOR_num_sgds = 0; ! 1850: myior->IOR_vol_designtr = mydcb->DCB_cmn.DCB_unit_number; ! 1851: myior->IOR_func = iorop; ! 1852: myior->IOR_flags |= IORF_BYPASS_VOLTRK | IORF_HIGH_PRIORITY | IORF_SCATTER_GATHER | IORF_SYNC_COMMAND; ! 1853: if (iorop == IOR_READ) ! 1854: { ! 1855: myior->IOR_flags |= IORF_DATA_IN; ! 1856: memset (buffr, 0, numsectors * 512); ! 1857: errnl[0] = 0xACE01DE4; ! 1858: errnl[1] = 0xEDB0CD01; ! 1859: errnl[2] = 0x4caf3321; ! 1860: errnl[3] = 0xa35a32c4; ! 1861: } ! 1862: ! 1863: if (iorop == IOR_WRITE) ! 1864: myior->IOR_flags |= IORF_DATA_OUT; ! 1865: myior->IOR_start_addr[0] = sector; ! 1866: myior->IOR_xfer_count = numsectors; ! 1867: myior->IOR_buffer_ptr = (ULONG) buffr; ! 1868: ! 1869: sgd = (_BlockDev_Scatter_Gather *) myior->IOR_sgd_lin_phys; /* scatter gather ! 1870: array... */ ! 1871: sgd->BD_SG_Buffer_Ptr = (ULONG) buffr; /* Buffer in LOCKED ram, ! 1872: below 16mbyte, 4K ! 1873: boundary.. */ ! 1874: sgd->BD_SG_Count = numsectors; ! 1875: myior->IOR_buffer_ptr = (ULONG) sgd; /* Implement as Scatter ! 1876: gather, with One block */ ! 1877: sgd++; ! 1878: sgd->BD_SG_Buffer_Ptr = 0; ! 1879: sgd->BD_SG_Count = 0; ! 1880: ! 1881: sgd++; ! 1882: myior->IOR_sgd_lin_phys = (ULONG) sgd; ! 1883: rstatus = myior->IOR_status; ! 1884: ! 1885: myiop->IOP_timer = 40; ! 1886: myiop->IOP_timer_orig = 40; ! 1887: ! 1888: if (mydcb->DCB_cmn.DCB_Sstor_Host == FALSE) ! 1889: { ! 1890: if (IlbIntIoCriteria (myiop)) ! 1891: myior->IOR_flags |= IORF_DOUBLE_BUFFER; ! 1892: IlbInternalRequest (myiop, mydcb, 0); ! 1893: rstatus = myior->IOR_status; ! 1894: ! 1895: if (iorop == IOR_READ) ! 1896: { ! 1897: /* checks for partion reads of simulated drives that ! 1898: dont return either data or error.... */ ! 1899: if ((errnl[0] == 0xACE01DE4) && ! 1900: (errnl[1] == 0xEDB0CD01) && ! 1901: (errnl[2] == 0x4caf3321) && ! 1902: (errnl[3] == 0xa35a32c4)) ! 1903: ! 1904: rstatus = 16; ! 1905: ! 1906: } ! 1907: ! 1908: return rstatus; ! 1909: } ! 1910: ! 1911: return 16; ! 1912: ! 1913: ! 1914: } ! 1915: ! 1916: /* This routine finds partitions */ ! 1917: ! 1918: void ! 1919: UsePartitionInfo (PDCB dcb, PIOP myiop, char *diskbuffer, unsigned int relative, int recursed, int *partnum, ! 1920: MOUNT_STRUCT * mf, BOOL bVerifyOnly) ! 1921: { ! 1922: /* Note that this is recursive..... */ ! 1923: partitionrec *pr; ! 1924: char *c; ! 1925: char *ndb; ! 1926: int flag = 0; ! 1927: cryptvol *cv = NULL; ! 1928: ! 1929: unsigned int ComputedStartSector; ! 1930: unsigned int ComputedEndSector; ! 1931: unsigned int cyl; ! 1932: unsigned int cylsize; ! 1933: unsigned int headsize; ! 1934: ! 1935: #if EXTRA_INFO ! 1936: _Debug_Printf_Service ("UsePartitionInfo\n"); ! 1937: #endif ! 1938: ! 1939: c = diskbuffer; ! 1940: ndb = c + 512; /* next disk buffer */ ! 1941: c += 0x1be; ! 1942: ! 1943: headsize = dcb->DCB_bdd.DCB_apparent_spt; ! 1944: cylsize = dcb->DCB_bdd.DCB_apparent_head_cnt; ! 1945: cylsize = cylsize * headsize; ! 1946: ! 1947: c = diskbuffer; ! 1948: c += 0x1be; ! 1949: pr = (partitionrec *) c; ! 1950: ! 1951: ! 1952: cyl = (pr->ss) & (128 + 64); ! 1953: cyl = cyl << 2; ! 1954: cyl += pr->sc; ! 1955: cyl *= cylsize; /* 16065; */ ! 1956: ! 1957: ComputedStartSector = pr->sh * headsize; /* 63; */ ! 1958: ComputedStartSector += (((pr->ss) & 63) - 1); ! 1959: ComputedStartSector += cyl; ! 1960: ! 1961: ! 1962: cyl = (pr->es) & (128 + 64); ! 1963: cyl = cyl << 2; ! 1964: cyl += pr->ec; ! 1965: cyl *= cylsize; /* 16065; */ ! 1966: ! 1967: ComputedEndSector = pr->eh * headsize; /* 63 */ ! 1968: ComputedEndSector += (((pr->es) & 63) - 1); ! 1969: ComputedEndSector += cyl; ! 1970: ComputedEndSector = ComputedEndSector - ComputedStartSector; ! 1971: ComputedEndSector += 1; /* allow for inclusive sectors... */ ! 1972: ! 1973: ! 1974: pr = (partitionrec *) c; ! 1975: ! 1976: if (pr->boot == 0x80) ! 1977: dcb_boot = dcb; ! 1978: ! 1979: if ((pr->system == 5) || (pr->system == 0xF)) ! 1980: { ! 1981: if (!recursed) ! 1982: relative = pr->StartSector; ! 1983: else ! 1984: pr->StartSector += relative; ! 1985: ! 1986: ! 1987: memset (ndb, 0, 512); ! 1988: DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ); ! 1989: UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also ! 1990: offset */ ! 1991: } ! 1992: else ! 1993: { ! 1994: if (recursed) ! 1995: pr->StartSector += recursed; ! 1996: ! 1997: if (--(*partnum) == 0) ! 1998: { ! 1999: if (bVerifyOnly == TRUE) ! 2000: flag = 1; ! 2001: else ! 2002: flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 1 */ ! 2003: goto error; ! 2004: } ! 2005: } ! 2006: ! 2007: pr++; ! 2008: ! 2009: if (pr->boot == 0x80) ! 2010: dcb_boot = dcb; ! 2011: ! 2012: if ((pr->system == 5) || (pr->system == 0xF)) ! 2013: { ! 2014: if (!recursed) ! 2015: relative = pr->StartSector; ! 2016: else ! 2017: pr->StartSector += relative; ! 2018: ! 2019: memset (ndb, 0, 512); ! 2020: DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ); ! 2021: UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also ! 2022: offset */ ! 2023: } ! 2024: else if (!recursed) ! 2025: { ! 2026: if (--(*partnum) == 0) ! 2027: { ! 2028: if (bVerifyOnly == TRUE) ! 2029: flag = 1; ! 2030: else ! 2031: flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 2 */ ! 2032: goto error; ! 2033: } ! 2034: } ! 2035: ! 2036: if (recursed) ! 2037: goto error; ! 2038: ! 2039: pr++; ! 2040: ! 2041: if (pr->boot == 0x80) ! 2042: dcb_boot = dcb; ! 2043: ! 2044: if ((pr->system == 5) || (pr->system == 0xF)) ! 2045: { ! 2046: if (!recursed) ! 2047: relative = pr->StartSector; ! 2048: else ! 2049: pr->StartSector += relative; ! 2050: ! 2051: memset (ndb, 0, 512); ! 2052: DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ); ! 2053: UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also ! 2054: offset */ ! 2055: } ! 2056: else if (!recursed) ! 2057: { ! 2058: if (--(*partnum) == 0) ! 2059: { ! 2060: if (bVerifyOnly == TRUE) ! 2061: flag = 1; ! 2062: else ! 2063: flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 3 */ ! 2064: goto error; ! 2065: } ! 2066: } ! 2067: ! 2068: pr++; ! 2069: ! 2070: if (pr->boot == 0x80) ! 2071: dcb_boot = dcb; ! 2072: ! 2073: if ((pr->system == 5) || (pr->system == 0xF)) ! 2074: { ! 2075: if (!recursed) ! 2076: relative = pr->StartSector; ! 2077: else ! 2078: pr->StartSector += relative; ! 2079: ! 2080: memset (ndb, 0, 512); ! 2081: DiskRead (dcb, myiop, pr->StartSector, 1, ndb, IOR_READ); ! 2082: UsePartitionInfo (dcb, myiop, ndb, relative, pr->StartSector, partnum, mf, bVerifyOnly); /* recursed, and also ! 2083: offset */ ! 2084: } ! 2085: else if (!recursed) ! 2086: { ! 2087: if (--(*partnum) == 0) ! 2088: { ! 2089: if (bVerifyOnly == TRUE) ! 2090: flag = 1; ! 2091: else ! 2092: flag = tryvol (dcb, myiop, pr, mf, &cv); /* partition 4 */ ! 2093: goto error; ! 2094: } ! 2095: } ! 2096: ! 2097: error: ! 2098: ! 2099: #if EXTRA_INFO ! 2100: _Debug_Printf_Service ("UsePartitionInfo end\n"); ! 2101: #endif ! 2102: ! 2103: if (bVerifyOnly == TRUE) ! 2104: { ! 2105: if (flag == 1) ! 2106: { ! 2107: /* Return partition info in the 'diskbuffer' buffer */ ! 2108: ! 2109: char *peek = (char *) &pr->system; ! 2110: unsigned long *tmp = (void *) partitiontestbuffer; ! 2111: unsigned long secstart, seclast; ! 2112: ! 2113: mf->nReturnCode = 0; ! 2114: ! 2115: peek -= 4; ! 2116: peek += 8; /* point at starting sector... */ ! 2117: secstart = *(unsigned long *) peek; ! 2118: peek += 4; ! 2119: ! 2120: seclast = (secstart + *(unsigned long *) peek); ! 2121: ! 2122: if (pr->boot == 0x80) ! 2123: { ! 2124: /* For safety reasons we return 0 length for ! 2125: the boot device */ ! 2126: seclast = secstart; ! 2127: } ! 2128: ! 2129: tmp[0] = secstart; ! 2130: tmp[1] = seclast; ! 2131: tmp[2] = (unsigned long) dcb; /* device */ ! 2132: ! 2133: } ! 2134: } ! 2135: else if (cv != NULL) ! 2136: { ! 2137: /* cv is only set by tryvol, flag is set only when cv is set */ ! 2138: switch (flag) ! 2139: { ! 2140: case 0: ! 2141: mf->nReturnCode = ERR_VOL_MOUNT_FAILED; ! 2142: break; ! 2143: case 1: ! 2144: mf->nReturnCode = 0; ! 2145: mf->nDosDriveNo = cv->drive; ! 2146: strcpy (cv->mounted_file_name, (char *) mf->wszVolume); ! 2147: break; ! 2148: case -1: ! 2149: mf->nReturnCode = ERR_NO_FREE_DRIVES; ! 2150: break; ! 2151: } ! 2152: } ! 2153: } ! 2154: ! 2155: int ! 2156: tryvol (PDCB dcb, PIOP myiop, partitionrec * pr, MOUNT_STRUCT * mf, cryptvol ** pcv) ! 2157: { ! 2158: cryptvol *cv; ! 2159: char *readBuffer; ! 2160: int mounted = 0; ! 2161: ! 2162: readBuffer = TCalloc (FIRST_READ_SIZE); ! 2163: if (readBuffer == NULL) ! 2164: goto error; ! 2165: ! 2166: if (cv = checkpartition (myiop, pr)) ! 2167: { ! 2168: if (cv->booted == 0) ! 2169: { ! 2170: int status; ! 2171: ! 2172: dophysblock (myiop, cv->cryptsectorfirst, FIRST_READ_SIZE / 512, readBuffer, cv, IOR_READ); ! 2173: ! 2174: status = VolumeReadHeaderCache (mf->bCache, readBuffer, mf->szPassword, ! 2175: mf->nPasswordLen, &cv->cryptoInfo); ! 2176: ! 2177: if (status != 0) ! 2178: { ! 2179: memset (cv, 0, sizeof (cryptvol)); ! 2180: cv->cryptsectorfirst = 0x7fffffff; ! 2181: mounted = 0; ! 2182: goto error; ! 2183: } ! 2184: else ! 2185: cv->booted = 1; ! 2186: ! 2187: if (Add_Drive (dcb, cv, mf->nDosDriveNo) == 0) ! 2188: { ! 2189: cv->filehostdcb = dcb; ! 2190: lockdrive (cv->filehostdcb, myiop, 1); ! 2191: mounted = 1; ! 2192: } ! 2193: else ! 2194: { ! 2195: /* No Drive letter available */ ! 2196: memset (cv, 0, sizeof (cryptvol)); ! 2197: cv->cryptsectorfirst = 0x7fffffff; ! 2198: mounted = -1; ! 2199: } ! 2200: } ! 2201: } ! 2202: else ! 2203: { ! 2204: /* If the checkpartition fails it could be because the ! 2205: partitions is already mounted or because there are no free ! 2206: slots */ ! 2207: mounted = 0; ! 2208: } ! 2209: ! 2210: error: ! 2211: if (readBuffer != NULL) ! 2212: TCfree (readBuffer); ! 2213: ! 2214: *pcv = cv; ! 2215: ! 2216: return mounted; ! 2217: ! 2218: } ! 2219: ! 2220: struct cryptvol * ! 2221: checkpartition (PIOP iop, partitionrec * pr) ! 2222: { ! 2223: ! 2224: cryptvol *flag = 0; ! 2225: cryptvol *cv; ! 2226: PDCB dcb = (PDCB) iop->IOP_physical_dcb; ! 2227: ! 2228: char *peek = (char *) &pr->system; ! 2229: ! 2230: pr->system = 0x74; ! 2231: ! 2232: if (pr->system == 0x74) ! 2233: { ! 2234: if (cv = addcryptedpartition (iop, peek)) ! 2235: { ! 2236: flag = cv; ! 2237: } ! 2238: } ! 2239: ! 2240: return flag; ! 2241: ! 2242: } ! 2243: ! 2244: int ! 2245: cmppart (PDCB dcb, unsigned int secstart, cryptvol * cv) ! 2246: { ! 2247: if (cv->physdevDCB != dcb) ! 2248: return 0; ! 2249: if (cv->cryptsectorfirst != secstart) ! 2250: return 0; ! 2251: return 1; ! 2252: } ! 2253: ! 2254: struct cryptvol * ! 2255: addcryptedpartition (PIOP iop, char *peek) ! 2256: { ! 2257: ! 2258: unsigned int secstart; ! 2259: unsigned int seclast; ! 2260: PDCB device; ! 2261: int d; ! 2262: peek -= 4; ! 2263: peek += 8; /* point at starting sector... */ ! 2264: secstart = *(unsigned long *) peek; ! 2265: peek += 4; ! 2266: ! 2267: seclast = (secstart + *(unsigned long *) peek); ! 2268: device = (PDCB) iop->IOP_physical_dcb; ! 2269: ! 2270: /* have we got it already ? */ ! 2271: if (cmppart (device, secstart, (cryptvol *) & cv1)) ! 2272: return NULL; ! 2273: if (cmppart (device, secstart, (cryptvol *) & cv2)) ! 2274: return NULL; ! 2275: if (cmppart (device, secstart, (cryptvol *) & cv3)) ! 2276: return NULL; ! 2277: if (cmppart (device, secstart, (cryptvol *) & cv4)) ! 2278: return NULL; ! 2279: if (cmppart (device, secstart, (cryptvol *) & cv5)) ! 2280: return NULL; ! 2281: if (cmppart (device, secstart, (cryptvol *) & cv6)) ! 2282: return NULL; ! 2283: if (cmppart (device, secstart, (cryptvol *) & cv7)) ! 2284: return NULL; ! 2285: if (cmppart (device, secstart, (cryptvol *) & cv8)) ! 2286: return NULL; ! 2287: ! 2288: d = tryaddpart ((cryptvol *) & cv1, secstart, seclast, device); ! 2289: if (d == 1) ! 2290: return &cv1; ! 2291: if (d == 2) ! 2292: return 0; ! 2293: ! 2294: d = tryaddpart ((cryptvol *) & cv2, secstart, seclast, device); ! 2295: if (d == 1) ! 2296: return &cv2; ! 2297: if (d == 2) ! 2298: return 0; ! 2299: ! 2300: d = tryaddpart ((cryptvol *) & cv3, secstart, seclast, device); ! 2301: if (d == 1) ! 2302: return &cv3; ! 2303: if (d == 2) ! 2304: return 0; ! 2305: ! 2306: d = tryaddpart ((cryptvol *) & cv4, secstart, seclast, device); ! 2307: if (d == 1) ! 2308: return &cv4; ! 2309: if (d == 2) ! 2310: return 0; ! 2311: ! 2312: d = tryaddpart ((cryptvol *) & cv5, secstart, seclast, device); ! 2313: if (d == 1) ! 2314: return &cv5; ! 2315: if (d == 2) ! 2316: return 0; ! 2317: ! 2318: d = tryaddpart ((cryptvol *) & cv6, secstart, seclast, device); ! 2319: if (d == 1) ! 2320: return &cv6; ! 2321: if (d == 2) ! 2322: return 0; ! 2323: ! 2324: d = tryaddpart ((cryptvol *) & cv7, secstart, seclast, device); ! 2325: if (d == 1) ! 2326: return &cv7; ! 2327: if (d == 2) ! 2328: return 0; ! 2329: ! 2330: d = tryaddpart ((cryptvol *) & cv8, secstart, seclast, device); ! 2331: if (d == 1) ! 2332: return &cv8; ! 2333: if (d == 2) ! 2334: return 0; ! 2335: ! 2336: return NULL; ! 2337: } ! 2338: ! 2339: int ! 2340: tryaddpart (cryptvol * cv, unsigned int secstart, unsigned int seclast, PDCB device) ! 2341: { ! 2342: /* THIS if CAN NEVER BE TRUE because cmppart does this job before ! 2343: this func is called */ ! 2344: if ((cv->physdevDCB == device) && (cv->cryptsectorfirst == secstart)) ! 2345: return (2); ! 2346: ! 2347: if (cv->physdevDCB == 0) ! 2348: { ! 2349: cv->physdevDCB = device; ! 2350: cv->cryptsectorfirst = secstart; ! 2351: cv->cryptsectorlast = seclast; ! 2352: ! 2353: return (1); ! 2354: } ! 2355: ! 2356: return (0); ! 2357: } ! 2358: ! 2359: int ! 2360: unlockdrive (cryptvol * cv) ! 2361: { ! 2362: PDCB dcb = cv->filehostdcb; /* physdevDCB; */ ! 2363: PIOP myiop; ! 2364: PIOR myior; ! 2365: USHORT offset; ! 2366: USHORT size; ! 2367: ! 2368: if (!dcb) ! 2369: return -1; ! 2370: ! 2371: offset = (USHORT) (dcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET (IOP, IOP_ior)); ! 2372: size = offset + sizeof (IOR) + dcb->DCB_max_sg_elements * sizeof (SGD); ! 2373: myiop = IspCreateIop (size, offset, ISP_M_FL_MUST_SUCCEED | ISP_M_FL_SMART_ALLOC | ISP_M_FL_INTERRUPT_TIME | ISP_M_FL_PERSISTENT_IOP); ! 2374: myior = &myiop->IOP_ior; ! 2375: myior->IOR_private_client = offset; ! 2376: lockdrive (dcb, myiop, 0); /* unlock it! */ ! 2377: IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client)); ! 2378: return 1; ! 2379: } ! 2380: ! 2381: int ! 2382: lockdrive (PDCB mydcb, PIOP myiop, int lockmode) ! 2383: { ! 2384: PIOR myior; ! 2385: int rstatus; ! 2386: int iorop; ! 2387: ! 2388: if (!mydcb) ! 2389: return -1; ! 2390: ! 2391: if (lockmode) ! 2392: iorop = IOR_LOCK_MEDIA; ! 2393: else ! 2394: iorop = IOR_UNLOCK_MEDIA; ! 2395: ! 2396: if ((mydcb->DCB_cmn.DCB_device_flags & DCB_DEV_REMOVABLE) == 0) ! 2397: return -1; ! 2398: ! 2399: myior = &myiop->IOP_ior; ! 2400: myiop->IOP_original_dcb = (ULONG) mydcb; ! 2401: myiop->IOP_physical_dcb = (ULONG) mydcb->DCB_cmn.DCB_physical_dcb; ! 2402: myior->IOR_next = 0; ! 2403: myior->IOR_start_addr[1] = 0; ! 2404: myior->IOR_flags = IORF_VERSION_002; ! 2405: myior->IOR_req_vol_handle = 0; ! 2406: myior->IOR_vol_designtr = 0xff; ! 2407: myior->IOR_func = iorop; ! 2408: myior->IOR_flags |= IORF_BYPASS_VOLTRK | IORF_HIGH_PRIORITY | IORF_SYNC_COMMAND; ! 2409: myior->IOR_start_addr[0] = 0; ! 2410: myior->IOR_xfer_count = 0; ! 2411: myior->IOR_buffer_ptr = 0; ! 2412: ! 2413: myiop->IOP_timer = 40; ! 2414: myiop->IOP_timer_orig = 40; ! 2415: ! 2416: IlbInternalRequest (myiop, mydcb, 0); ! 2417: rstatus = myior->IOR_status; ! 2418: return rstatus; ! 2419: } ! 2420: ! 2421: ! 2422: /* the ring 0 code to allow win32 gui to access disk sectors */ ! 2423: ! 2424: int ! 2425: AppAccessBlockDevice (unsigned int devicenum, unsigned int sectorstart, unsigned int sectorlen, char *buffer, int mode) ! 2426: { ! 2427: PDCB dcb; ! 2428: USHORT offset; ! 2429: USHORT size; ! 2430: PIOP myiop; ! 2431: PIOR myior; ! 2432: int status; ! 2433: USHORT diskop; ! 2434: ! 2435: if (mode == 0) ! 2436: diskop = IOR_READ; ! 2437: else ! 2438: diskop = IOR_WRITE; ! 2439: ! 2440: if (devicenum < 128) ! 2441: dcb = dcblist[devicenum + 1]; ! 2442: else ! 2443: dcb = (PDCB) devicenum; ! 2444: ! 2445: if (diskop == IOR_WRITE && dcb == dcb_boot) ! 2446: { ! 2447: if (sectorstart == 0) ! 2448: { ! 2449: return ERR_ACCESS_DENIED; ! 2450: } ! 2451: } ! 2452: ! 2453: offset = (USHORT) (dcb->DCB_cmn.DCB_expansion_length + FIELDOFFSET (IOP, IOP_ior)); ! 2454: size = offset + sizeof (IOR) + dcb->DCB_max_sg_elements * sizeof (SGD); ! 2455: myiop = IspCreateIop (size, offset, ISP_M_FL_MUST_SUCCEED | ISP_M_FL_SMART_ALLOC | ISP_M_FL_INTERRUPT_TIME | ISP_M_FL_PERSISTENT_IOP); ! 2456: myior = &myiop->IOP_ior; ! 2457: myior->IOR_private_client = offset; ! 2458: ! 2459: if (diskop == IOR_WRITE) ! 2460: memcpy (appaccessbuffer, buffer, sectorlen * 512); ! 2461: ! 2462: status = DiskRead (dcb, myiop, sectorstart, sectorlen, appaccessbuffer, diskop); /* mode later...... */ ! 2463: ! 2464: if (diskop == IOR_READ) ! 2465: memcpy (buffer, appaccessbuffer, sectorlen * 512); ! 2466: ! 2467: IspDeallocMem ((PVOID) ((DWORD) myior - myior->IOR_private_client)); ! 2468: ! 2469: if (status != 0) ! 2470: { ! 2471: if (mode == 0) ! 2472: status = ERR_VOL_READING; ! 2473: else ! 2474: status = ERR_VOL_WRITING; ! 2475: } ! 2476: ! 2477: return status; ! 2478: } ! 2479: ! 2480: /* This code informs Windows of a drives arrival, this code ! 2481: crashes windows 95 for some cd's; so it's currently never called */ ! 2482: ! 2483: void ! 2484: drivearrived (void) ! 2485: { ! 2486: cryptvol *cv; ! 2487: int c; ! 2488: ! 2489: for (c = 0; c < 8; c++) ! 2490: { ! 2491: cv = cryptvols[c]; ! 2492: ! 2493: if (cv->notifytime & 0x80000000) ! 2494: { ! 2495: cv->notifytime = 0; ! 2496: ! 2497: IFSMgr_PNPEvent (DBT_DEVICEARRIVAL, cv->drive, PNPT_VOLUME | DBTF_MEDIA ); ! 2498: } ! 2499: } ! 2500: } ! 2501:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.