Annotation of truecrypt/driver vxd/tc9x.c, revision 1.1.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.