/* * ReadFSHDblock * */ RETCODE adfReadFSHDblock( struct Device* dev, long nSect, struct bFSHDblock* blk) { UCHAR buf[sizeof(struct bFSHDblock)]; struct nativeFunctions *nFct; RETCODE rc; nFct = adfEnv.nativeFct; if (dev->isNativeDev) rc = (*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bFSHDblock), buf); else rc = adfReadDumpSector(dev, nSect, sizeof(struct bFSHDblock), buf); if (rc!=RC_OK) return RC_ERROR; memcpy(blk, buf, sizeof(struct bFSHDblock)); #ifdef LITT_ENDIAN /* big to little = 68000 to x86 */ swapEndian((unsigned char*)blk, SWBL_FSHD); #endif if ( strncmp(blk->id,"FSHD",4)!=0 ) { (*adfEnv.eFct)("ReadFSHDblock : FSHD id not found"); return RC_ERROR; } if ( blk->size != 64 ) (*adfEnv.wFct)("ReadFSHDblock : size != 64"); if ( blk->checksum != adfNormalSum(buf,8,256) ) (*adfEnv.wFct)( "ReadFSHDblock : incorrect checksum"); return RC_OK; }
/* * ReadLSEGblock * */ RETCODE adfReadLSEGblock(struct Device* dev, int32_t nSect, struct bLSEGblock* blk) { UCHAR buf[sizeof(struct bLSEGblock)]; struct nativeFunctions *nFct; RETCODE rc; nFct = adfEnv.nativeFct; if (dev->isNativeDev) rc=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bLSEGblock), buf); else rc=adfReadDumpSector(dev, nSect, sizeof(struct bLSEGblock), buf); if (rc!=RC_OK) return RC_ERROR; memcpy(blk, buf, sizeof(struct bLSEGblock)); #ifdef LITT_ENDIAN /* big to little = 68000 to x86 */ swapEndian((uint8_t*)blk, SWBL_LSEG); #endif if ( strncmp(blk->id,"LSEG",4)!=0 ) { (*adfEnv.eFct)("ReadLSEGblock : LSEG id not found"); return RC_ERROR; } if ( blk->checksum != adfNormalSum(buf,8,sizeof(struct bLSEGblock)) ) (*adfEnv.wFct)("ReadLSEGBlock : incorrect checksum"); if ( blk->next!=-1 && blk->size != 128 ) (*adfEnv.wFct)("ReadLSEGBlock : size != 128"); return RC_OK; }
/*! \brief Read a logical block. * \param vol - the parent volume. * \param nSect - the location of the target block. * \param buf - a buffer to receive the read data. * \return RC_OK or RC_ERROR. */ RETCODE adfReadBlock(struct Volume* vol, long nSect, unsigned char* buf) { #ifdef _DEBUG_PRINTF_ char strBuf[80]; #endif /*_DEBUG_PRINTF_*/ long pSect; struct nativeFunctions *nFct; RETCODE rc; if (!vol->mounted) { (*adfEnv.eFct)("the volume isn't mounted, adfReadBlock not possible"); return RC_ERROR; } /* translate logical sect to physical sect */ pSect = nSect+vol->firstBlock; if (adfEnv.useRWAccess) (*adfEnv.rwhAccess)(pSect,nSect,FALSE); #ifdef _DEBUG_PRINTF_ printf("psect=%ld nsect=%ld\n",pSect,nSect); sprintf(strBuf,"ReadBlock : accessing logical block #%ld", nSect); (*adfEnv.vFct)(strBuf); #endif /*_DEBUG_PRINTF_*/ if (pSect<vol->firstBlock || pSect>vol->lastBlock) { (*adfEnv.wFct)("adfReadBlock : nSect out of range"); } #ifdef _DEBUG_PRINTF_ printf("pSect R =%ld\n",pSect); #endif /*_DEBUG_PRINTF_*/ nFct = adfEnv.nativeFct; if (vol->dev->isNativeDev) rc = (*nFct->adfNativeReadSector)(vol->dev, pSect, 512, buf); else rc = adfReadDumpSector(vol->dev, pSect, 512, buf); #ifdef _DEBUG_PRINTF_ printf("rc=%ld\n",rc); #endif /*_DEBUG_PRINTF_*/ if (rc!=RC_OK) return RC_ERROR; else return RC_OK; }
/* * adfMountHdFile * */ RETCODE adfMountHdFile(struct Device *dev) { struct Volume* vol; uint8_t buf[512]; int32_t size; BOOL found; dev->devType = DEVTYPE_HARDFILE; dev->nVol = 0; dev->volList = (struct Volume**)malloc(sizeof(struct Volume*)); if (!dev->volList) { (*adfEnv.eFct)("adfMountHdFile : malloc"); return RC_ERROR; } vol=(struct Volume*)malloc(sizeof(struct Volume)); if (!vol) { (*adfEnv.eFct)("adfMountHdFile : malloc"); return RC_ERROR; } dev->volList[0] = vol; dev->nVol++; /* fixed by Dan, ... and by Gary */ vol->volName=NULL; dev->cylinders = dev->size/512; dev->heads = 1; dev->sectors = 1; vol->firstBlock = 0; size = dev->size + 512-(dev->size%512); /*printf("size=%ld\n",size);*/ vol->rootBlock = (size/512)/2; /*printf("root=%ld\n",vol->rootBlock);*/ do { adfReadDumpSector(dev, vol->rootBlock, 512, buf); found = swapLong(buf)==T_HEADER && swapLong(buf+508)==ST_ROOT; if (!found) (vol->rootBlock)--; }while (vol->rootBlock>1 && !found); if (vol->rootBlock==1) { (*adfEnv.eFct)("adfMountHdFile : rootblock not found"); return RC_ERROR; } vol->lastBlock = vol->rootBlock*2 - 1 ; return RC_OK; }
/* * ReadRDSKblock * */ RETCODE adfReadRDSKblock( struct Device* dev, struct bRDSKblock* blk ) { UCHAR buf[256]; struct nativeFunctions *nFct; RETCODE rc2; RETCODE rc = RC_OK; nFct = adfEnv.nativeFct; if (dev->isNativeDev) rc2 =(*nFct->adfNativeReadSector)(dev, 0, 256, buf); else rc2 = adfReadDumpSector(dev, 0, 256, buf); if (rc2!=RC_OK) return(RC_ERROR); memcpy(blk, buf, 256); #ifdef LITT_ENDIAN /* big to little = 68000 to x86 */ swapEndian((uint8_t*)blk, SWBL_RDSK); #endif if ( strncmp(blk->id,"RDSK",4)!=0 ) { (*adfEnv.eFct)("ReadRDSKblock : RDSK id not found"); return RC_ERROR; } if ( blk->size != 64 ) (*adfEnv.wFct)("ReadRDSKBlock : size != 64"); /* BV */ if ( blk->checksum != adfNormalSum(buf,8,256) ) { (*adfEnv.wFct)("ReadRDSKBlock : incorrect checksum"); /* BV FIX: Due to malicious Win98 write to sector rc|=RC_BLOCKSUM;*/ } if ( blk->blockSize != 512 ) (*adfEnv.wFct)("ReadRDSKBlock : blockSize != 512"); /* BV */ if ( blk->cylBlocks != blk->sectors*blk->heads ) (*adfEnv.wFct)( "ReadRDSKBlock : cylBlocks != sectors*heads"); return rc; }
/* * ReadPARTblock * */ RETCODE adfReadPARTblock( struct Device* dev, int32_t nSect, struct bPARTblock* blk ) { UCHAR buf[ sizeof(struct bPARTblock) ]; struct nativeFunctions *nFct; RETCODE rc2, rc = RC_OK; nFct = adfEnv.nativeFct; if (dev->isNativeDev) rc2=(*nFct->adfNativeReadSector)(dev, nSect, sizeof(struct bPARTblock), buf); else rc2=adfReadDumpSector(dev, nSect, sizeof(struct bPARTblock), buf); if (rc2!=RC_OK) return RC_ERROR; memcpy(blk, buf, sizeof(struct bPARTblock)); #ifdef LITT_ENDIAN /* big to little = 68000 to x86 */ swapEndian((uint8_t*)blk, SWBL_PART); #endif if ( strncmp(blk->id,"PART",4)!=0 ) { (*adfEnv.eFct)("ReadPARTblock : PART id not found"); return RC_ERROR; } if ( blk->size != 64 ) (*adfEnv.wFct)("ReadPARTBlock : size != 64"); if ( blk->blockSize!=128 ) { (*adfEnv.eFct)("ReadPARTblock : blockSize!=512, not supported (yet)"); return RC_ERROR; } if ( blk->checksum != adfNormalSum(buf,8,256) ) (*adfEnv.wFct)( "ReadPARTBlock : incorrect checksum"); return rc; }
/* * adfMountDev * * mount a dump file (.adf) or a real device (uses adf_nativ.c and .h) * * adfInitDevice() must fill dev->size ! */ struct Device* adfMountDev( char* filename, BOOL ro) { struct Device* dev; struct nativeFunctions *nFct; RETCODE rc; uint8_t buf[512]; dev = (struct Device*)malloc(sizeof(struct Device)); if (!dev) { (*adfEnv.eFct)("adfMountDev : malloc error"); return NULL; } dev->readOnly = ro; /* switch between dump files and real devices */ nFct = adfEnv.nativeFct; dev->isNativeDev = (*nFct->adfIsDevNative)(filename); if (dev->isNativeDev) rc = (*nFct->adfInitDevice)(dev, filename,ro); else rc = adfInitDumpDevice(dev,filename,ro); if (rc!=RC_OK) { free(dev); return(NULL); } dev->devType = adfDevType(dev); switch( dev->devType ) { case DEVTYPE_FLOPDD: case DEVTYPE_FLOPHD: if (adfMountFlop(dev)!=RC_OK) { if (dev->isNativeDev) /* BV */ (*nFct->adfReleaseDevice)(dev); /* BV */ else /* BV */ adfReleaseDumpDevice(dev); /* BV */ free(dev); return NULL; } break; case DEVTYPE_HARDDISK: /* to choose between hardfile or harddisk (real or dump) */ if (dev->isNativeDev) /* BV ...from here*/ rc = (*nFct->adfNativeReadSector)(dev, 0, 512, buf); else rc = adfReadDumpSector(dev, 0, 512, buf); if( rc!=RC_OK ) { nFct = adfEnv.nativeFct; if (dev->isNativeDev) (*nFct->adfReleaseDevice)(dev); else adfReleaseDumpDevice(dev); (*adfEnv.eFct)("adfMountDev : adfReadDumpSector failed"); free(dev); return NULL; } /* a file with the first three bytes equal to 'DOS' */ if (!dev->isNativeDev && strncmp("DOS",(char*)buf,3)==0) { if (adfMountHdFile(dev)!=RC_OK) { if (dev->isNativeDev) (*nFct->adfReleaseDevice)(dev); else adfReleaseDumpDevice(dev); free(dev); return NULL; } } else if (adfMountHd(dev)!=RC_OK) { if (dev->isNativeDev) (*nFct->adfReleaseDevice)(dev); else adfReleaseDumpDevice(dev); free(dev); return NULL; /* BV ...to here.*/ } break; default: (*adfEnv.eFct)("adfMountDev : unknown device type"); if (dev->isNativeDev) /* BV */ (*nFct->adfReleaseDevice)(dev); /* BV */ else /* BV */ adfReleaseDumpDevice(dev); /* BV */ free(dev); return NULL; /* BV */ } return dev; }