Annotation of truecrypt/driver vxd/tc9x.c, revision 1.1

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: 

unix.superglobalmegacorp.com

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