1
0
mirror of https://github.com/gryf/ADFlib.git synced 2026-02-07 16:55:48 +01:00

Initial import

This commit is contained in:
Toni G
2013-02-21 22:36:30 +01:00
parent 113fdf2a9e
commit f3af9e019f
72 changed files with 18613 additions and 0 deletions

44
src/Makefile.am Normal file
View File

@@ -0,0 +1,44 @@
NATIVE_DIR = generic
lib_LTLIBRARIES = libadf.la
libadf_la_SOURCES = adf_hd.c \
adf_disk.c \
adf_raw.c \
adf_bitm.c \
adf_dump.c \
adf_util.c \
adf_env.c \
$(NATIVE_DIR)/adf_nativ.c \
adf_dir.c \
adf_file.c \
adf_cache.c \
adf_link.c \
adf_salv.c
include_HEADERS = adf_defs.h \
adf_blk.h \
adf_err.h \
adf_str.h \
adflib.h \
adf_bitm.h \
adf_cache.h \
adf_dir.h \
adf_disk.h \
adf_dump.h \
adf_env.h \
adf_file.h \
adf_hd.h \
adf_link.h \
adf_raw.h \
adf_salv.h \
adf_util.h \
defendian.h \
hd_blk.h \
prefix.h \
$(NATIVE_DIR)/adf_nativ.h
libadf_la_LDFLAGS = -version-info 0:12:0
AM_CPPFLAGS = -D_XOPEN_SOURCE -D_SVID_SOURCE -D_BSD_SOURCE -D_GNU_SOURCE -I$(srcdir) -I$(srcdir)/$(NATIVE_DIR)
AM_CFLAGS = -std=c99 -pedantic -Wall

561
src/adf_bitm.c Normal file
View File

@@ -0,0 +1,561 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_bitm.c
*
* $Id$
*
* bitmap code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <stdlib.h>
#include <string.h>
#include"adf_raw.h"
#include"adf_bitm.h"
#include"adf_err.h"
#include"adf_disk.h"
#include"adf_util.h"
#include"defendian.h"
extern uint32_t bitMask[32];
extern struct Env adfEnv;
/*
* adfUpdateBitmap
*
*/
RETCODE adfUpdateBitmap(struct Volume *vol)
{
int i;
struct bRootBlock root;
/*printf("adfUpdateBitmap\n");*/
if (adfReadRootBlock(vol, vol->rootBlock,&root)!=RC_OK)
return RC_ERROR;
root.bmFlag = BM_INVALID;
if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
return RC_ERROR;
for(i=0; i<vol->bitmapSize; i++)
if (vol->bitmapBlocksChg[i]) {
if (adfWriteBitmapBlock(vol, vol->bitmapBlocks[i], vol->bitmapTable[i])!=RC_OK)
return RC_ERROR;
vol->bitmapBlocksChg[i] = FALSE;
}
root.bmFlag = BM_VALID;
adfTime2AmigaTime(adfGiveCurrentTime(),&(root.days),&(root.mins),&(root.ticks));
if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
return RC_ERROR;
return RC_OK;
}
/*
* adfCountFreeBlocks
*
*/
int32_t adfCountFreeBlocks(struct Volume* vol)
{
int32_t freeBlocks;
int j;
freeBlocks = 0L;
for(j=vol->firstBlock+2; j<=(vol->lastBlock - vol->firstBlock); j++)
if ( adfIsBlockFree(vol,j) )
freeBlocks++;
return freeBlocks;
}
/*
* adfReadBitmap
*
*/
RETCODE adfReadBitmap(struct Volume* vol, int32_t nBlock, struct bRootBlock* root)
{
int32_t mapSize, nSect;
int32_t j, i;
struct bBitmapExtBlock bmExt;
mapSize = nBlock / (127*32);
if ( (nBlock%(127*32))!=0 )
mapSize++;
vol->bitmapSize = mapSize;
vol->bitmapTable = (struct bBitmapBlock**) malloc(sizeof(struct bBitmapBlock*)*mapSize);
if (!vol->bitmapTable) {
(*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapTable");
return RC_MALLOC;
}
vol->bitmapBlocks = (SECTNUM*) malloc(sizeof(SECTNUM)*mapSize);
if (!vol->bitmapBlocks) {
free(vol->bitmapTable);
(*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
return RC_MALLOC;
}
vol->bitmapBlocksChg = (BOOL*) malloc(sizeof(BOOL)*mapSize);
if (!vol->bitmapBlocksChg) {
free(vol->bitmapTable); free(vol->bitmapBlocks);
(*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
return RC_MALLOC;
}
for(i=0; i<mapSize; i++) {
vol->bitmapBlocksChg[i] = FALSE;
vol->bitmapTable[i] = (struct bBitmapBlock*)malloc(sizeof(struct bBitmapBlock));
if (!vol->bitmapTable[i]) {
free(vol->bitmapBlocksChg); free(vol->bitmapBlocks);
for(j=0; j<i; j++)
free(vol->bitmapTable[j]);
free(vol->bitmapTable);
(*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
return RC_MALLOC;
}
}
j=0; i=0;
/* bitmap pointers in rootblock : 0 <= i <BM_SIZE */
while(i<BM_SIZE && root->bmPages[i]!=0) {
vol->bitmapBlocks[j] = nSect = root->bmPages[i];
if ( !isSectNumValid(vol,nSect) ) {
(*adfEnv.wFct)("adfReadBitmap : sector out of range");
}
if (adfReadBitmapBlock(vol, nSect, vol->bitmapTable[j])!=RC_OK) {
adfFreeBitmap(vol);
return RC_ERROR;
}
j++; i++;
}
nSect = root->bmExt;
while(nSect!=0) {
/* bitmap pointers in bitmapExtBlock, j <= mapSize */
if (adfReadBitmapExtBlock(vol, nSect, &bmExt)!=RC_OK) {
adfFreeBitmap(vol);
return RC_ERROR;
}
i=0;
while(i<127 && j<mapSize) {
nSect = bmExt.bmPages[i];
if ( !isSectNumValid(vol,nSect) )
(*adfEnv.wFct)("adfReadBitmap : sector out of range");
vol->bitmapBlocks[j] = nSect;
if (adfReadBitmapBlock(vol, nSect, vol->bitmapTable[j])!=RC_OK) {
adfFreeBitmap(vol);
return RC_ERROR;
}
i++; j++;
}
nSect = bmExt.nextBlock;
}
return RC_OK;
}
/*
* adfIsBlockFree
*
*/
BOOL adfIsBlockFree(struct Volume* vol, SECTNUM nSect)
{
int sectOfMap = nSect-2;
int block = sectOfMap/(127*32);
int indexInMap = (sectOfMap/32)%127;
/*printf("sect=%d block=%d ind=%d, ",sectOfMap,block,indexInMap);
printf("bit=%d, ",sectOfMap%32);
printf("bitm=%x, ",bitMask[ sectOfMap%32]);
printf("res=%x, ",vol->bitmapTable[ block ]->map[ indexInMap ]
& bitMask[ sectOfMap%32 ]);
*/
return ( (vol->bitmapTable[ block ]->map[ indexInMap ]
& bitMask[ sectOfMap%32 ])!=0 );
}
/*
* adfSetBlockFree OK
*
*/
void adfSetBlockFree(struct Volume* vol, SECTNUM nSect)
{
uint32_t oldValue;
int sectOfMap = nSect-2;
int block = sectOfMap/(127*32);
int indexInMap = (sectOfMap/32)%127;
/*printf("sect=%d block=%d ind=%d, ",sectOfMap,block,indexInMap);
printf("bit=%d, ",sectOfMap%32);
*printf("bitm=%x, ",bitMask[ sectOfMap%32]);*/
oldValue = vol->bitmapTable[ block ]->map[ indexInMap ];
/*printf("old=%x, ",oldValue);*/
vol->bitmapTable[ block ]->map[ indexInMap ]
= oldValue | bitMask[ sectOfMap%32 ];
/*printf("new=%x, ",vol->bitmapTable[ block ]->map[ indexInMap ]);*/
vol->bitmapBlocksChg[ block ] = TRUE;
}
/*
* adfSetBlockUsed
*
*/
void adfSetBlockUsed(struct Volume* vol, SECTNUM nSect)
{
uint32_t oldValue;
int sectOfMap = nSect-2;
int block = sectOfMap/(127*32);
int indexInMap = (sectOfMap/32)%127;
oldValue = vol->bitmapTable[ block ]->map[ indexInMap ];
vol->bitmapTable[ block ]->map[ indexInMap ]
= oldValue & (~bitMask[ sectOfMap%32 ]);
vol->bitmapBlocksChg[ block ] = TRUE;
}
/*
* adfGet1FreeBlock
*
*/
SECTNUM adfGet1FreeBlock(struct Volume *vol) {
SECTNUM block[1];
if (!adfGetFreeBlocks(vol,1,block))
return(-1);
else
return(block[0]);
}
/*
* adfGetFreeBlocks
*
*/
BOOL adfGetFreeBlocks(struct Volume* vol, int nbSect, SECTNUM* sectList)
{
int i, j;
BOOL diskFull;
int32_t block = vol->rootBlock;
i = 0;
diskFull = FALSE;
/*printf("lastblock=%ld\n",vol->lastBlock);*/
while( i<nbSect && !diskFull ) {
if ( adfIsBlockFree(vol, block) ) {
sectList[i] = block;
i++;
}
/* if ( block==vol->lastBlock )
block = vol->firstBlock+2;*/
if ( (block+vol->firstBlock)==vol->lastBlock )
block = 2;
else if (block==vol->rootBlock-1)
diskFull = TRUE;
else
block++;
}
if (!diskFull)
for(j=0; j<nbSect; j++)
adfSetBlockUsed( vol, sectList[j] );
return (i==nbSect);
}
/*
* adfCreateBitmap
*
* create bitmap structure in vol
*/
RETCODE adfCreateBitmap(struct Volume *vol)
{
int32_t nBlock, mapSize ;
int i, j;
nBlock = vol->lastBlock - vol->firstBlock +1 - 2;
mapSize = nBlock / (127*32);
if ( (nBlock%(127*32))!=0 )
mapSize++;
vol->bitmapSize = mapSize;
vol->bitmapTable = (struct bBitmapBlock**)malloc( sizeof(struct bBitmapBlock*)*mapSize );
if (!vol->bitmapTable) {
(*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapTable");
return RC_MALLOC;
}
vol->bitmapBlocksChg = (BOOL*) malloc(sizeof(BOOL)*mapSize);
if (!vol->bitmapBlocksChg) {
free(vol->bitmapTable);
(*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocksChg");
return RC_MALLOC;
}
vol->bitmapBlocks = (SECTNUM*) malloc(sizeof(SECTNUM)*mapSize);
if (!vol->bitmapBlocks) {
free(vol->bitmapTable); free(vol->bitmapBlocksChg);
(*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocks");
return RC_MALLOC;
}
for(i=0; i<mapSize; i++) {
vol->bitmapTable[i] = (struct bBitmapBlock*)malloc(sizeof(struct bBitmapBlock));
if (!vol->bitmapTable[i]) {
free(vol->bitmapTable); free(vol->bitmapBlocksChg);
for(j=0; j<i; j++)
free(vol->bitmapTable[j]);
free(vol->bitmapTable);
(*adfEnv.eFct)("adfCreateBitmap : malloc");
return RC_MALLOC;
}
}
for(i=vol->firstBlock+2; i<=(vol->lastBlock - vol->firstBlock); i++)
adfSetBlockFree(vol, i);
return RC_OK;
}
/*
* adfWriteNewBitmap
*
* write ext blocks and bitmap
*
* uses vol->bitmapSize,
*/
RETCODE adfWriteNewBitmap(struct Volume *vol)
{
struct bBitmapExtBlock bitme;
SECTNUM *bitExtBlock;
int n, i, k;
int nExtBlock;
int nBlock;
SECTNUM *sectList;
struct bRootBlock root;
sectList=(SECTNUM*)malloc(sizeof(SECTNUM)*vol->bitmapSize);
if (!sectList) {
(*adfEnv.eFct)("adfCreateBitmap : sectList");
return RC_MALLOC;
}
if (!adfGetFreeBlocks(vol, vol->bitmapSize, sectList)) {
free(sectList);
return RC_ERROR;
}
if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
free(sectList);
return RC_ERROR;
}
nBlock = 0;
n = min( vol->bitmapSize, BM_SIZE );
for(i=0; i<n; i++) {
root.bmPages[i] = vol->bitmapBlocks[i] = sectList[i];
}
nBlock = n;
/* for devices with more than 25*127 blocks == hards disks */
if (vol->bitmapSize>BM_SIZE) {
nExtBlock = (vol->bitmapSize-BM_SIZE)/127;
if ((vol->bitmapSize-BM_SIZE)%127)
nExtBlock++;
bitExtBlock=(SECTNUM*)malloc(sizeof(SECTNUM)*nExtBlock);
if (!bitExtBlock) {
free(sectList);
adfEnv.eFct("adfWriteNewBitmap : malloc failed");
return RC_MALLOC;
}
if (!adfGetFreeBlocks(vol, nExtBlock, bitExtBlock)) {
free(sectList); free(bitExtBlock);
return RC_MALLOC;
}
k = 0;
root.bmExt = bitExtBlock[ k ];
while( nBlock<vol->bitmapSize ) {
i=0;
while( i<127 && nBlock<vol->bitmapSize ) {
bitme.bmPages[i] = vol->bitmapBlocks[nBlock] = sectList[i];
i++;
nBlock++;
}
if ( k+1<nExtBlock )
bitme.nextBlock = bitExtBlock[ k+1 ];
else
bitme.nextBlock = 0;
if (adfWriteBitmapExtBlock(vol, bitExtBlock[ k ], &bitme)!=RC_OK) {
free(sectList); free(bitExtBlock);
return RC_ERROR;
}
k++;
}
free( bitExtBlock );
}
free( sectList);
if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
return RC_ERROR;
return RC_OK;
}
/*
* adfReadBitmapBlock
*
* ENDIAN DEPENDENT
*/
RETCODE
adfReadBitmapBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapBlock* bitm)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
/*printf("bitmap %ld\n",nSect);*/
if (adfReadBlock(vol, nSect, buf)!=RC_OK)
return RC_ERROR;
memcpy(bitm, buf, LOGICAL_BLOCK_SIZE);
#ifdef LITT_ENDIAN
/* big to little = 68000 to x86 */
swapEndian((uint8_t*)bitm, SWBL_BITMAP);
#endif
if (bitm->checkSum!=adfNormalSum(buf,0,LOGICAL_BLOCK_SIZE))
(*adfEnv.wFct)("adfReadBitmapBlock : invalid checksum");
return RC_OK;
}
/*
* adfWriteBitmapBlock
*
* OK
*/
RETCODE
adfWriteBitmapBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapBlock* bitm)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
uint32_t newSum;
memcpy(buf,bitm,LOGICAL_BLOCK_SIZE);
#ifdef LITT_ENDIAN
/* little to big */
swapEndian(buf, SWBL_BITMAP);
#endif
newSum = adfNormalSum(buf, 0, LOGICAL_BLOCK_SIZE);
swLong(buf,newSum);
/* dumpBlock((uint8_t*)buf);*/
if (adfWriteBlock(vol, nSect, (uint8_t*)buf)!=RC_OK)
return RC_ERROR;
return RC_OK;
}
/*
* adfReadBitmapExtBlock
*
* ENDIAN DEPENDENT
*/
RETCODE
adfReadBitmapExtBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapExtBlock* bitme)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
if (adfReadBlock(vol, nSect, buf)!=RC_OK)
return RC_ERROR;
memcpy(bitme, buf, LOGICAL_BLOCK_SIZE);
#ifdef LITT_ENDIAN
swapEndian((uint8_t*)bitme, SWBL_BITMAP);
#endif
return RC_OK;
}
/*
* adfWriteBitmapExtBlock
*
*/
RETCODE
adfWriteBitmapExtBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapExtBlock* bitme)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
memcpy(buf,bitme, LOGICAL_BLOCK_SIZE);
#ifdef LITT_ENDIAN
/* little to big */
swapEndian(buf, SWBL_BITMAPE);
#endif
/* dumpBlock((uint8_t*)buf);*/
if (adfWriteBlock(vol, nSect, (uint8_t*)buf)!=RC_OK)
return RC_ERROR;
return RC_OK;
}
/*
* adfFreeBitmap
*
*/
void adfFreeBitmap(struct Volume* vol)
{
int i;
for(i=0; i<vol->bitmapSize; i++)
free(vol->bitmapTable[i]);
vol->bitmapSize = 0;
free(vol->bitmapTable);
vol->bitmapTable = 0;
free(vol->bitmapBlocks);
vol->bitmapBlocks = 0;
free(vol->bitmapBlocksChg);
vol->bitmapBlocksChg = 0;
}
/*#######################################################################################*/

52
src/adf_bitm.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef ADF_BITM_H
#define ADF_BITM_H
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_bitm.h
*
* $Id$
*
* bitmap code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"adf_str.h"
#include"prefix.h"
RETCODE adfReadBitmapBlock(struct Volume*, SECTNUM nSect, struct bBitmapBlock*);
RETCODE adfWriteBitmapBlock(struct Volume*, SECTNUM nSect, struct bBitmapBlock*);
RETCODE adfReadBitmapExtBlock(struct Volume*, SECTNUM nSect, struct bBitmapExtBlock*);
RETCODE adfWriteBitmapExtBlock(struct Volume*, SECTNUM, struct bBitmapExtBlock* );
SECTNUM adfGet1FreeBlock(struct Volume *vol);
RETCODE adfUpdateBitmap(struct Volume *vol);
PREFIX int32_t adfCountFreeBlocks(struct Volume* vol);
RETCODE adfReadBitmap(struct Volume* , SECTNUM nBlock, struct bRootBlock* root);
BOOL adfIsBlockFree(struct Volume* vol, SECTNUM nSect);
void adfSetBlockFree(struct Volume* vol, SECTNUM nSect);
void adfSetBlockUsed(struct Volume* vol, SECTNUM nSect);
BOOL adfGetFreeBlocks(struct Volume* vol, int nbSect, SECTNUM* sectList);
RETCODE adfCreateBitmap(struct Volume *vol);
RETCODE adfWriteNewBitmap(struct Volume *vol);
void adfFreeBitmap(struct Volume *vol);
#endif /* ADF_BITM_H */
/*#######################################################################################*/

288
src/adf_blk.h Normal file
View File

@@ -0,0 +1,288 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_blk.h
*
* $Id$
*
* general blocks structures
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef ADF_BLK_H
#define ADF_BLK_H 1
#define ULONG uint32_t
#define USHORT uint16_t
#define UCHAR uint8_t
#define LOGICAL_BLOCK_SIZE 512
/* ----- FILE SYSTEM ----- */
#define FSMASK_FFS 1
#define FSMASK_INTL 2
#define FSMASK_DIRCACHE 4
#define isFFS(c) ((c)&FSMASK_FFS)
#define isOFS(c) (!((c)&FSMASK_FFS))
#define isINTL(c) ((c)&FSMASK_INTL)
#define isDIRCACHE(c) ((c)&FSMASK_DIRCACHE)
/* ----- ENTRIES ----- */
/* access constants */
#define ACCMASK_D (1<<0)
#define ACCMASK_E (1<<1)
#define ACCMASK_W (1<<2)
#define ACCMASK_R (1<<3)
#define ACCMASK_A (1<<4)
#define ACCMASK_P (1<<5)
#define ACCMASK_S (1<<6)
#define ACCMASK_H (1<<7)
#define hasD(c) ((c)&ACCMASK_D)
#define hasE(c) ((c)&ACCMASK_E)
#define hasW(c) ((c)&ACCMASK_W)
#define hasR(c) ((c)&ACCMASK_R)
#define hasA(c) ((c)&ACCMASK_A)
#define hasP(c) ((c)&ACCMASK_P)
#define hasS(c) ((c)&ACCMASK_S)
#define hasH(c) ((c)&ACCMASK_H)
/* ----- BLOCKS ----- */
/* block constants */
#define BM_VALID -1
#define BM_INVALID 0
#define HT_SIZE 72
#define BM_SIZE 25
#define MAX_DATABLK 72
#define MAXNAMELEN 30
#define MAXCMMTLEN 79
/* block primary and secondary types */
#define T_HEADER 2
#define ST_ROOT 1
#define ST_DIR 2
#define ST_FILE -3
#define ST_LFILE -4
#define ST_LDIR 4
#define ST_LSOFT 3
#define T_LIST 16
#define T_DATA 8
#define T_DIRC 33
/*--- blocks structures --- */
struct bBootBlock {
/*000*/ char dosType[4];
/*004*/ ULONG checkSum;
/*008*/ int32_t rootBlock;
/*00c*/ UCHAR data[500+512];
};
struct bRootBlock {
/*000*/ int32_t type;
int32_t headerKey;
int32_t highSeq;
/*00c*/ int32_t hashTableSize;
int32_t firstData;
/*014*/ ULONG checkSum;
/*018*/ int32_t hashTable[HT_SIZE]; /* hash table */
/*138*/ int32_t bmFlag; /* bitmap flag, -1 means VALID */
/*13c*/ int32_t bmPages[BM_SIZE];
/*1a0*/ int32_t bmExt;
/*1a4*/ int32_t cDays; /* creation date FFS and OFS */
/*1a8*/ int32_t cMins;
/*1ac*/ int32_t cTicks;
/*1b0*/ char nameLen;
/*1b1*/ char diskName[MAXNAMELEN+1];
char r2[8];
/*1d8*/ int32_t days; /* last access : days after 1 jan 1978 */
/*1dc*/ int32_t mins; /* hours and minutes in minutes */
/*1e0*/ int32_t ticks; /* 1/50 seconds */
/*1e4*/ int32_t coDays; /* creation date OFS */
/*1e8*/ int32_t coMins;
/*1ec*/ int32_t coTicks;
int32_t nextSameHash; /* == 0 */
int32_t parent; /* == 0 */
/*1f8*/ int32_t extension; /* FFS: first directory cache block */
/*1fc*/ int32_t secType; /* == 1 */
};
struct bFileHeaderBlock {
/*000*/ int32_t type; /* == 2 */
/*004*/ int32_t headerKey; /* current block number */
/*008*/ int32_t highSeq; /* number of data block in this hdr block */
/*00c*/ int32_t dataSize; /* == 0 */
/*010*/ int32_t firstData;
/*014*/ ULONG checkSum;
/*018*/ int32_t dataBlocks[MAX_DATABLK];
/*138*/ int32_t r1;
/*13c*/ int32_t r2;
/*140*/ int32_t access; /* bit0=del, 1=modif, 2=write, 3=read */
/*144*/ uint32_t byteSize;
/*148*/ char commLen;
/*149*/ char comment[MAXCMMTLEN+1];
char r3[91-(MAXCMMTLEN+1)];
/*1a4*/ int32_t days;
/*1a8*/ int32_t mins;
/*1ac*/ int32_t ticks;
/*1b0*/ char nameLen;
/*1b1*/ char fileName[MAXNAMELEN+1];
int32_t r4;
/*1d4*/ int32_t real; /* unused == 0 */
/*1d8*/ int32_t nextLink; /* link chain */
int32_t r5[5];
/*1f0*/ int32_t nextSameHash; /* next entry with sane hash */
/*1f4*/ int32_t parent; /* parent directory */
/*1f8*/ int32_t extension; /* pointer to extension block */
/*1fc*/ int32_t secType; /* == -3 */
};
/*--- file header extension block structure ---*/
struct bFileExtBlock {
/*000*/ int32_t type; /* == 0x10 */
/*004*/ int32_t headerKey;
/*008*/ int32_t highSeq;
/*00c*/ int32_t dataSize; /* == 0 */
/*010*/ int32_t firstData; /* == 0 */
/*014*/ ULONG checkSum;
/*018*/ int32_t dataBlocks[MAX_DATABLK];
int32_t r[45];
int32_t info; /* == 0 */
int32_t nextSameHash; /* == 0 */
/*1f4*/ int32_t parent; /* header block */
/*1f8*/ int32_t extension; /* next header extension block */
/*1fc*/ int32_t secType; /* -3 */
};
struct bDirBlock {
/*000*/ int32_t type; /* == 2 */
/*004*/ int32_t headerKey;
/*008*/ int32_t highSeq; /* == 0 */
/*00c*/ int32_t hashTableSize; /* == 0 */
int32_t r1; /* == 0 */
/*014*/ ULONG checkSum;
/*018*/ int32_t hashTable[HT_SIZE]; /* hash table */
int32_t r2[2];
/*140*/ int32_t access;
int32_t r4; /* == 0 */
/*148*/ char commLen;
/*149*/ char comment[MAXCMMTLEN+1];
char r5[91-(MAXCMMTLEN+1)];
/*1a4*/ int32_t days; /* last access */
/*1a8*/ int32_t mins;
/*1ac*/ int32_t ticks;
/*1b0*/ char nameLen;
/*1b1*/ char dirName[MAXNAMELEN+1];
int32_t r6;
/*1d4*/ int32_t real; /* ==0 */
/*1d8*/ int32_t nextLink; /* link list */
int32_t r7[5];
/*1f0*/ int32_t nextSameHash;
/*1f4*/ int32_t parent;
/*1f8*/ int32_t extension; /* FFS : first directory cache */
/*1fc*/ int32_t secType; /* == 2 */
};
struct bOFSDataBlock{
/*000*/ int32_t type; /* == 8 */
/*004*/ int32_t headerKey; /* pointer to file_hdr block */
/*008*/ int32_t seqNum; /* file data block number */
/*00c*/ int32_t dataSize; /* <= 0x1e8 */
/*010*/ int32_t nextData; /* next data block */
/*014*/ ULONG checkSum;
/*018*/ UCHAR data[488];
/*200*/ };
/* --- bitmap --- */
struct bBitmapBlock {
/*000*/ ULONG checkSum;
/*004*/ ULONG map[127];
};
struct bBitmapExtBlock {
/*000*/ int32_t bmPages[127];
/*1fc*/ int32_t nextBlock;
};
struct bLinkBlock {
/*000*/ int32_t type; /* == 2 */
/*004*/ int32_t headerKey; /* self pointer */
int32_t r1[3];
/*014*/ ULONG checkSum;
/*018*/ char realName[64];
int32_t r2[83];
/*1a4*/ int32_t days; /* last access */
/*1a8*/ int32_t mins;
/*1ac*/ int32_t ticks;
/*1b0*/ char nameLen;
/*1b1*/ char name[MAXNAMELEN+1];
int32_t r3;
/*1d4*/ int32_t realEntry;
/*1d8*/ int32_t nextLink;
int32_t r4[5];
/*1f0*/ int32_t nextSameHash;
/*1f4*/ int32_t parent;
int32_t r5;
/*1fc*/ int32_t secType; /* == -4, 4, 3 */
};
/*--- directory cache block structure ---*/
struct bDirCacheBlock {
/*000*/ int32_t type; /* == 33 */
/*004*/ int32_t headerKey;
/*008*/ int32_t parent;
/*00c*/ int32_t recordsNb;
/*010*/ int32_t nextDirC;
/*014*/ ULONG checkSum;
/*018*/ uint8_t records[488];
};
#endif /* ADF_BLK_H */
/*##########################################################################*/

615
src/adf_cache.c Normal file
View File

@@ -0,0 +1,615 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_cache.c
*
* $Id$
*
* directory cache code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<stdlib.h>
#include<string.h>
#include"adf_defs.h"
#include"adf_str.h"
#include"adf_err.h"
#include"defendian.h"
#include"adf_cache.h"
#include"adf_raw.h"
#include"adf_disk.h"
#include"adf_bitm.h"
#include"adf_util.h"
#include"adf_dir.h"
extern struct Env adfEnv;
/*
freeEntCache(struct CacheEntry *cEntry)
{
if (cEntry->name!=NULL)
free(cEntry->name);
if (cEntry->comm!=NULL)
free(cEntry->comm);
}
*/
/*
* adfGetDirEntCache
*
* replace 'adfGetDirEnt'. returns a the dir contents based on the dircache list
*/
struct List* adfGetDirEntCache(struct Volume *vol, SECTNUM dir, BOOL recurs)
{
struct bEntryBlock parent;
struct bDirCacheBlock dirc;
int offset, n;
struct List *cell, *head;
struct CacheEntry caEntry;
struct Entry *entry;
SECTNUM nSect;
if (adfReadEntryBlock(vol,dir,&parent)!=RC_OK)
return NULL;
nSect = parent.extension;
cell = head = NULL;
do {
/* one loop per cache block */
n = offset = 0;
if (adfReadDirCBlock(vol, nSect, &dirc)!=RC_OK)
return NULL;
while (n<dirc.recordsNb) {
/* one loop per record */
entry = (struct Entry*)malloc(sizeof(struct Entry));
if (!entry) {
adfFreeDirList(head);
return NULL;
}
adfGetCacheEntry(&dirc, &offset, &caEntry);
/* converts a cache entry into a dir entry */
entry->type = (int)caEntry.type;
entry->name = strdup(caEntry.name);
if (entry->name==NULL) {
free(entry); adfFreeDirList(head);
return NULL;
}
entry->sector = caEntry.header;
entry->comment = strdup(caEntry.comm);
if (entry->comment==NULL) {
free(entry->name); adfFreeDirList(head);
return NULL;
}
entry->size = caEntry.size;
entry->access = caEntry.protect;
adfDays2Date( caEntry.days, &(entry->year), &(entry->month),
&(entry->days) );
entry->hour = caEntry.mins/60;
entry->mins = caEntry.mins%60;
entry->secs = caEntry.ticks/50;
/* add it into the linked list */
if (head==NULL)
head = cell = newCell(NULL, (void*)entry);
else
cell = newCell(cell, (void*)entry);
if (cell==NULL) {
adfFreeEntry(entry);
adfFreeDirList(head);
return NULL;
}
if (recurs && entry->type==ST_DIR)
cell->subdir = adfGetDirEntCache(vol,entry->sector,recurs);
n++;
}
nSect = dirc.nextDirC;
}while (nSect!=0);
return head;
}
/*
* adfGetCacheEntry
*
* Returns a cache entry, starting from the offset p (the index into records[])
* This offset is updated to the end of the returned entry.
*/
void adfGetCacheEntry(struct bDirCacheBlock *dirc, int *p, struct CacheEntry *cEntry)
{
int ptr;
ptr = *p;
/*printf("p=%d\n",ptr);*/
#ifdef LITT_ENDIAN
cEntry->header = swapLong(dirc->records+ptr);
cEntry->size = swapLong(dirc->records+ptr+4);
cEntry->protect = swapLong(dirc->records+ptr+8);
cEntry->days = swapShort(dirc->records+ptr+16);
cEntry->mins = swapShort(dirc->records+ptr+18);
cEntry->ticks = swapShort(dirc->records+ptr+20);
#else
cEntry->header = Long(dirc->records+ptr);
cEntry->size = Long(dirc->records+ptr+4);
cEntry->protect = Long(dirc->records+ptr+8);
cEntry->days = Short(dirc->records+ptr+16);
cEntry->mins = Short(dirc->records+ptr+18);
cEntry->ticks = Short(dirc->records+ptr+20);
#endif
cEntry->type =(signed char) dirc->records[ptr+22];
cEntry->nLen = dirc->records[ptr+23];
/* cEntry->name = (char*)malloc(sizeof(char)*(cEntry->nLen+1));
if (!cEntry->name)
return;
*/ memcpy(cEntry->name, dirc->records+ptr+24, cEntry->nLen);
cEntry->name[(int)(cEntry->nLen)]='\0';
cEntry->cLen = dirc->records[ptr+24+cEntry->nLen];
if (cEntry->cLen>0) {
/* cEntry->comm =(char*)malloc(sizeof(char)*(cEntry->cLen+1));
if (!cEntry->comm) {
free( cEntry->name ); cEntry->name=NULL;
return;
}
*/ memcpy(cEntry->comm,dirc->records+ptr+24+cEntry->nLen+1,cEntry->cLen);
}
cEntry->comm[(int)(cEntry->cLen)]='\0';
/*printf("cEntry->nLen %d cEntry->cLen %d %s\n",cEntry->nLen,cEntry->cLen,cEntry->name);*/
*p = ptr+24+cEntry->nLen+1+cEntry->cLen;
/* the starting offset of each record must be even (68000 constraint) */
if ((*p%2)!=0)
*p=(*p)+1;
}
/*
* adfPutCacheEntry
*
* remplaces one cache entry at the p offset, and returns its length
*/
int adfPutCacheEntry( struct bDirCacheBlock *dirc, int *p, struct CacheEntry *cEntry)
{
int ptr, l;
ptr = *p;
#ifdef LITT_ENDIAN
swLong(dirc->records+ptr, cEntry->header);
swLong(dirc->records+ptr+4, cEntry->size);
swLong(dirc->records+ptr+8, cEntry->protect);
swShort(dirc->records+ptr+16, cEntry->days);
swShort(dirc->records+ptr+18, cEntry->mins);
swShort(dirc->records+ptr+20, cEntry->ticks);
#else
memcpy(dirc->records+ptr,&(cEntry->header),4);
memcpy(dirc->records+ptr+4,&(cEntry->size),4);
memcpy(dirc->records+ptr+8,&(cEntry->protect),4);
memcpy(dirc->records+ptr+16,&(cEntry->days),2);
memcpy(dirc->records+ptr+18,&(cEntry->mins),2);
memcpy(dirc->records+ptr+20,&(cEntry->ticks),2);
#endif
dirc->records[ptr+22] =(signed char)cEntry->type;
dirc->records[ptr+23] = cEntry->nLen;
memcpy(dirc->records+ptr+24, cEntry->name, cEntry->nLen);
dirc->records[ptr+24+cEntry->nLen] = cEntry->cLen;
memcpy(dirc->records+ptr+24+cEntry->nLen+1, cEntry->comm, cEntry->cLen);
/*puts("adfPutCacheEntry");*/
l = 25+cEntry->nLen+cEntry->cLen;
if ((l%2)==0)
return l;
else {
dirc->records[ptr+l] =(char)0;
return l+1;
}
/* ptr%2 must be == 0, if l%2==0, (ptr+l)%2==0 */
}
/*
* adfEntry2CacheEntry
*
* converts one dir entry into a cache entry, and return its future length in records[]
*/
int adfEntry2CacheEntry(struct bEntryBlock *entry, struct CacheEntry *newEntry)
{
int entryLen;
/* new entry */
newEntry->header = entry->headerKey;
if (entry->secType==ST_FILE)
newEntry->size = entry->byteSize;
else
newEntry->size = 0L;
newEntry->protect = entry->access;
newEntry->days = (short)entry->days;
newEntry->mins = (short)entry->mins;
newEntry->ticks = (short)entry->ticks;
newEntry->type = (signed char)entry->secType;
newEntry->nLen = entry->nameLen;
memcpy(newEntry->name, entry->name, newEntry->nLen);
newEntry->name[(int)(newEntry->nLen)] = '\0';
newEntry->cLen = entry->commLen;
if (newEntry->cLen>0)
memcpy(newEntry->comm, entry->comment, newEntry->cLen);
entryLen = 24+newEntry->nLen+1+newEntry->cLen;
/*printf("entry->name %d entry->comment %d\n",entry->nameLen,entry->commLen);
printf("newEntry->nLen %d newEntry->cLen %d\n",newEntry->nLen,newEntry->cLen);
*/ if ((entryLen%2)==0)
return entryLen;
else
return entryLen+1;
}
/*
* adfDelFromCache
*
* delete one cache entry from its block. don't do 'records garbage collecting'
*/
RETCODE adfDelFromCache(struct Volume *vol, struct bEntryBlock *parent,
SECTNUM headerKey)
{
struct bDirCacheBlock dirc;
SECTNUM nSect, prevSect;
struct CacheEntry caEntry;
int offset, oldOffset, n;
BOOL found;
int entryLen;
int i;
RETCODE rc = RC_OK;
prevSect = -1;
nSect = parent->extension;
found = FALSE;
do {
adfReadDirCBlock(vol, nSect, &dirc);
offset = 0; n = 0;
while(n < dirc.recordsNb && !found) {
oldOffset = offset;
adfGetCacheEntry(&dirc, &offset, &caEntry);
found = (caEntry.header==headerKey);
if (found) {
entryLen = offset-oldOffset;
if (dirc.recordsNb>1 || prevSect==-1) {
if (n<dirc.recordsNb-1) {
/* not the last of the block : switch the following records */
for(i=oldOffset; i<(488-entryLen); i++)
dirc.records[i] = dirc.records[i+entryLen];
/* and clear the following bytes */
for(i=488-entryLen; i<488; i++)
dirc.records[i] = 0;
}
else {
/* the last record of this cache block */
for(i=oldOffset; i<offset; i++)
dirc.records[i] = 0;
}
dirc.recordsNb--;
if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
return -1;
}
else {
/* dirc.recordsNb ==1 or == 0 , prevSect!=-1 :
* the only record in this dirc block and a previous dirc block exists
*/
adfSetBlockFree(vol, dirc.headerKey);
adfReadDirCBlock(vol, prevSect, &dirc);
dirc.nextDirC = 0L;
adfWriteDirCBlock(vol, prevSect, &dirc);
adfUpdateBitmap(vol);
}
}
n++;
}
prevSect = nSect;
nSect = dirc.nextDirC;
}while(nSect!=0 && !found);
if (!found)
(*adfEnv.wFct)("adfUpdateCache : entry not found");
return rc;
}
/*
* adfAddInCache
*
*/
RETCODE adfAddInCache(struct Volume *vol, struct bEntryBlock *parent,
struct bEntryBlock *entry)
{
struct bDirCacheBlock dirc, newDirc;
SECTNUM nSect, nCache;
struct CacheEntry caEntry, newEntry;
int offset, n;
int entryLen;
entryLen = adfEntry2CacheEntry(entry, &newEntry);
/*printf("adfAddInCache--%4ld %2d %6ld %8lx %4d %2d:%02d:%02d %30s %22s\n",
newEntry.header, newEntry.type, newEntry.size, newEntry.protect,
newEntry.days, newEntry.mins/60, newEntry.mins%60,
newEntry.ticks/50,
newEntry.name, newEntry.comm);
*/
nSect = parent->extension;
do {
if (adfReadDirCBlock(vol, nSect, &dirc)!=RC_OK)
return RC_ERROR;
offset = 0; n = 0;
/*printf("parent=%4ld\n",dirc.parent);*/
while(n < dirc.recordsNb) {
adfGetCacheEntry(&dirc, &offset, &caEntry);
/*printf("*%4ld %2d %6ld %8lx %4d %2d:%02d:%02d %30s %22s\n",
caEntry.header, caEntry.type, caEntry.size, caEntry.protect,
caEntry.days, caEntry.mins/60, caEntry.mins%60,
caEntry.ticks/50,
caEntry.name, caEntry.comm);
*/
n++;
}
/* if (offset+entryLen<=488) {
adfPutCacheEntry(&dirc, &offset, &newEntry);
dirc.recordsNb++;
adfWriteDirCBlock(vol, dirc.headerKey, &dirc);
return rc;
}*/
nSect = dirc.nextDirC;
}while(nSect!=0);
/* in the last block */
if (offset+entryLen<=488) {
adfPutCacheEntry(&dirc, &offset, &newEntry);
dirc.recordsNb++;
/*printf("entry name=%s\n",newEntry.name);*/
}
else {
/* request one new block free */
nCache = adfGet1FreeBlock(vol);
if (nCache==-1) {
(*adfEnv.wFct)("adfCreateDir : nCache==-1");
return RC_VOLFULL;
}
/* create a new dircache block */
memset(&newDirc,0,512);
if (parent->secType==ST_ROOT)
newDirc.parent = vol->rootBlock;
else if (parent->secType==ST_DIR)
newDirc.parent = parent->headerKey;
else
(*adfEnv.wFct)("adfAddInCache : unknown secType");
newDirc.recordsNb = 0L;
newDirc.nextDirC = 0L;
adfPutCacheEntry(&dirc, &offset, &newEntry);
newDirc.recordsNb++;
if (adfWriteDirCBlock(vol, nCache, &newDirc)!=RC_OK)
return RC_ERROR;
dirc.nextDirC = nCache;
}
/*printf("dirc.headerKey=%ld\n",dirc.headerKey);*/
if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
return RC_ERROR;
/*if (strcmp(entry->name,"file_5u")==0)
dumpBlock(&dirc);
*/
return RC_OK;
}
/*
* adfUpdateCache
*
*/
RETCODE adfUpdateCache(struct Volume *vol, struct bEntryBlock *parent,
struct bEntryBlock *entry, BOOL entryLenChg)
{
struct bDirCacheBlock dirc;
SECTNUM nSect;
struct CacheEntry caEntry, newEntry;
int offset, oldOffset, n;
BOOL found;
int i, oLen, nLen;
int sLen; /* shift length */
nLen = adfEntry2CacheEntry(entry, &newEntry);
nSect = parent->extension;
found = FALSE;
do {
/*printf("dirc=%ld\n",nSect);*/
if (adfReadDirCBlock(vol, nSect, &dirc)!=RC_OK)
return RC_ERROR;
offset = 0; n = 0;
/* search entry to update with its header_key */
while(n < dirc.recordsNb && !found) {
oldOffset = offset;
/* offset is updated */
adfGetCacheEntry(&dirc, &offset, &caEntry);
oLen = offset-oldOffset;
sLen = oLen-nLen;
/*printf("olen=%d nlen=%d\n",oLen,nLen);*/
found = (caEntry.header==newEntry.header);
if (found) {
if (!entryLenChg || oLen==nLen) {
/* same length : remplace the old values */
adfPutCacheEntry(&dirc, &oldOffset, &newEntry);
/*if (entryLenChg) puts("oLen==nLen");*/
if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
return RC_ERROR;
}
else if (oLen>nLen) {
/*puts("oLen>nLen");*/
/* the new record is shorter, write it,
* then shift down the following records
*/
adfPutCacheEntry(&dirc, &oldOffset, &newEntry);
for(i=oldOffset+nLen; i<(488-sLen); i++)
dirc.records[i] = dirc.records[i+sLen];
/* then clear the following bytes */
for(i=488-sLen; i<488; i++)
dirc.records[i] = (char)0;
if (adfWriteDirCBlock(vol, dirc.headerKey, &dirc)!=RC_OK)
return RC_ERROR;
}
else {
/* the new record is larger */
/*puts("oLen<nLen");*/
adfDelFromCache(vol,parent,entry->headerKey);
adfAddInCache(vol,parent,entry);
/*puts("oLen<nLen end");*/
}
}
n++;
}
nSect = dirc.nextDirC;
}while(nSect!=0 && !found);
if (found) {
if (adfUpdateBitmap(vol)!=RC_OK)
return RC_ERROR;
}
else
(*adfEnv.wFct)("adfUpdateCache : entry not found");
return RC_OK;
}
/*
* adfCreateEmptyCache
*
*/
RETCODE adfCreateEmptyCache(struct Volume *vol, struct bEntryBlock *parent, SECTNUM nSect)
{
struct bDirCacheBlock dirc;
SECTNUM nCache;
if (nSect==-1) {
nCache = adfGet1FreeBlock(vol);
if (nCache==-1) {
(*adfEnv.wFct)("adfCreateDir : nCache==-1");
return RC_VOLFULL;
}
}
else
nCache = nSect;
if (parent->extension==0)
parent->extension = nCache;
memset(&dirc,0, sizeof(struct bDirCacheBlock));
if (parent->secType==ST_ROOT)
dirc.parent = vol->rootBlock;
else if (parent->secType==ST_DIR)
dirc.parent = parent->headerKey;
else {
(*adfEnv.wFct)("adfCreateEmptyCache : unknown secType");
/*printf("secType=%ld\n",parent->secType);*/
}
dirc.recordsNb = 0;
dirc.nextDirC = 0;
if (adfWriteDirCBlock(vol, nCache, &dirc)!=RC_OK)
return RC_ERROR;
return RC_OK;
}
/*
* adfReadDirCBlock
*
*/
RETCODE adfReadDirCBlock(struct Volume *vol, SECTNUM nSect, struct bDirCacheBlock *dirc)
{
uint8_t buf[512];
if (adfReadBlock(vol, nSect, buf)!=RC_OK)
return RC_ERROR;
memcpy(dirc,buf,512);
#ifdef LITT_ENDIAN
swapEndian((uint8_t*)dirc,SWBL_CACHE);
#endif
if (dirc->checkSum!=adfNormalSum(buf,20,512))
(*adfEnv.wFct)("adfReadDirCBlock : invalid checksum");
if (dirc->type!=T_DIRC)
(*adfEnv.wFct)("adfReadDirCBlock : T_DIRC not found");
if (dirc->headerKey!=nSect)
(*adfEnv.wFct)("adfReadDirCBlock : headerKey!=nSect");
return RC_OK;
}
/*
* adfWriteDirCblock
*
*/
RETCODE adfWriteDirCBlock(struct Volume* vol, int32_t nSect, struct bDirCacheBlock* dirc)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
uint32_t newSum;
dirc->type = T_DIRC;
dirc->headerKey = nSect;
memcpy(buf, dirc, LOGICAL_BLOCK_SIZE);
#ifdef LITT_ENDIAN
swapEndian(buf, SWBL_CACHE);
#endif
newSum = adfNormalSum(buf, 20, LOGICAL_BLOCK_SIZE);
swLong(buf+20,newSum);
/* *(int32_t*)(buf+20) = swapLong((uint8_t*)&newSum);*/
if (adfWriteBlock(vol, nSect, buf)!=RC_OK)
return RC_ERROR;
/*puts("adfWriteDirCBlock");*/
return RC_OK;
}
/*################################################################################*/

48
src/adf_cache.h Normal file
View File

@@ -0,0 +1,48 @@
#ifndef _ADF_CACHE_H
#define _ADF_CACHE_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_cache.h
*
* $Id$
*
* directory cache code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "adf_str.h"
void adfGetCacheEntry(struct bDirCacheBlock *dirc, int *p, struct CacheEntry *cEntry);
int adfPutCacheEntry( struct bDirCacheBlock *dirc, int *p, struct CacheEntry *cEntry);
struct List* adfGetDirEntCache(struct Volume *vol, SECTNUM dir, BOOL recurs);
RETCODE adfCreateEmptyCache(struct Volume *vol, struct bEntryBlock *parent, SECTNUM nSect);
RETCODE adfAddInCache(struct Volume *vol, struct bEntryBlock *parent, struct bEntryBlock *entry);
RETCODE adfUpdateCache(struct Volume *vol, struct bEntryBlock *parent, struct bEntryBlock *entry, BOOL);
RETCODE adfDelFromCache(struct Volume *vol, struct bEntryBlock *parent, SECTNUM);
RETCODE adfReadDirCBlock(struct Volume *vol, SECTNUM nSect, struct bDirCacheBlock *dirc);
RETCODE adfWriteDirCBlock(struct Volume*, int32_t, struct bDirCacheBlock* dirc);
#endif /* _ADF_CACHE_H */
/*##########################################################################*/

71
src/adf_defs.h Normal file
View File

@@ -0,0 +1,71 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_defs.h
*
* $Id$
*
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef _ADF_DEFS_H
#define _ADF_DEFS_H 1
#define ADFLIB_VERSION "0.7.11a"
#define ADFLIB_DATE "January 20th, 2007"
#define SECTNUM int32_t
#define RETCODE int32_t
#define TRUE 1
#define FALSE 0
#include <stdint.h>
#define ULONG uint32_t
#define USHORT uint16_t
#define UCHAR uint8_t
#define BOOL int
/* defines max and min */
#ifndef max
#define max(a,b) (a)>(b) ? (a) : (b)
#endif
#ifndef min
#define min(a,b) (a)<(b) ? (a) : (b)
#endif
/* (*byte) to (*short) and (*byte) to (*long) conversion */
#define Short(p) ((p)[0]<<8 | (p)[1])
#define Long(p) (Short(p)<<16 | Short(p+2))
/* swap short and swap long macros for little endian machines */
#define swapShort(p) ((p)[0]<<8 | (p)[1])
#define swapLong(p) (swapShort(p)<<16 | swapShort(p+2))
#endif /* _ADF_DEFS_H */
/*##########################################################################*/

1042
src/adf_dir.c Normal file

File diff suppressed because it is too large Load Diff

70
src/adf_dir.h Normal file
View File

@@ -0,0 +1,70 @@
#ifndef ADF_DIR_H
#define ADF_DIR_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_dir.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"adf_str.h"
#include"adf_err.h"
#include"adf_defs.h"
#include"prefix.h"
PREFIX RETCODE adfToRootDir(struct Volume *vol);
BOOL isDirEmpty(struct bDirBlock *dir);
PREFIX RETCODE adfRemoveEntry(struct Volume *vol, SECTNUM pSect, char *name);
PREFIX struct List* adfGetDirEnt(struct Volume* vol, SECTNUM nSect );
PREFIX struct List* adfGetRDirEnt(struct Volume* vol, SECTNUM nSect, BOOL recurs );
PREFIX void adfFreeDirList(struct List* list);
RETCODE adfEntBlock2Entry(struct bEntryBlock *entryBlk, struct Entry *entry);
PREFIX void adfFreeEntry(struct Entry *entry);
RETCODE adfCreateFile(struct Volume* vol, SECTNUM parent, char *name,
struct bFileHeaderBlock *fhdr);
PREFIX RETCODE adfCreateDir(struct Volume* vol, SECTNUM parent, char* name);
SECTNUM adfCreateEntry(struct Volume *vol, struct bEntryBlock *dir, char *name, SECTNUM );
PREFIX RETCODE adfRenameEntry(struct Volume *vol, SECTNUM, char *old,SECTNUM,char *new);
RETCODE adfReadEntryBlock(struct Volume* vol, SECTNUM nSect, struct bEntryBlock* ent);
RETCODE adfWriteDirBlock(struct Volume* vol, SECTNUM nSect, struct bDirBlock *dir);
RETCODE adfWriteEntryBlock(struct Volume* vol, SECTNUM nSect, struct bEntryBlock *ent);
char* adfAccess2String(int32_t acc);
uint8_t adfIntlToUpper(uint8_t c);
int adfGetHashValue(uint8_t *name, BOOL intl);
void myToUpper( uint8_t *ostr, uint8_t *nstr, int,BOOL intl );
PREFIX RETCODE adfChangeDir(struct Volume* vol, char *name);
PREFIX RETCODE adfParentDir(struct Volume* vol);
PREFIX RETCODE adfSetEntryAccess(struct Volume*, SECTNUM, char*, int32_t);
PREFIX RETCODE adfSetEntryComment(struct Volume*, SECTNUM, char*, char*);
SECTNUM adfNameToEntryBlk(struct Volume *vol, int32_t ht[], char* name,
struct bEntryBlock *entry, SECTNUM *);
PREFIX void printEntry(struct Entry* entry);
void adfFreeDirList(struct List* list);
#endif /* ADF_DIR_H */

454
src/adf_disk.c Normal file
View File

@@ -0,0 +1,454 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_disk.c
*
* $Id$
*
* logical disk/volume code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "adf_str.h"
#include "adf_disk.h"
#include "adf_raw.h"
#include "adf_hd.h"
#include "adf_bitm.h"
#include "adf_util.h"
#include "adf_nativ.h"
#include "adf_dump.h"
#include "adf_err.h"
#include "adf_cache.h"
extern struct Env adfEnv;
uint32_t bitMask[32] = {
0x1, 0x2, 0x4, 0x8,
0x10, 0x20, 0x40, 0x80,
0x100, 0x200, 0x400, 0x800,
0x1000, 0x2000, 0x4000, 0x8000,
0x10000, 0x20000, 0x40000, 0x80000,
0x100000, 0x200000, 0x400000, 0x800000,
0x1000000, 0x2000000, 0x4000000, 0x8000000,
0x10000000, 0x20000000, 0x40000000, 0x80000000 };
RETCODE adfInstallBootBlock(struct Volume *vol, uint8_t* code)
{
int i;
struct bBootBlock boot;
if (vol->dev->devType!=DEVTYPE_FLOPDD && vol->dev->devType!=DEVTYPE_FLOPHD)
return RC_ERROR;
if (adfReadBootBlock(vol, &boot)!=RC_OK)
return RC_ERROR;
boot.rootBlock = 880;
for(i=0; i<1024-12; i++) /* bootcode */
boot.data[i] = code[i+12];
if (adfWriteBootBlock(vol, &boot)!=RC_OK)
return RC_ERROR;
vol->bootCode = TRUE;
return RC_OK;
}
/*
* isSectNumValid
*
*/
BOOL isSectNumValid(struct Volume *vol, SECTNUM nSect)
{
return( 0<=nSect && nSect<=(vol->lastBlock - vol->firstBlock) );
}
/*
* adfVolumeInfo
*
*/
void adfVolumeInfo(struct Volume *vol)
{
struct bRootBlock root;
char diskName[35];
int days,month,year;
if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
return;
memset(diskName, 0, 35);
memcpy(diskName, root.diskName, root.nameLen);
printf ("Name : %-30s\n",vol->volName);
printf ("Type : ");
switch(vol->dev->devType) {
case DEVTYPE_FLOPDD:
printf ("Floppy Double Density : 880 KBytes\n");
break;
case DEVTYPE_FLOPHD:
printf ("Floppy High Density : 1760 KBytes\n");
break;
case DEVTYPE_HARDDISK:
printf ("Hard Disk partition : %3.1f KBytes\n",
(vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
break;
case DEVTYPE_HARDFILE:
printf ("HardFile : %3.1f KBytes\n",
(vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
break;
default:
printf ("Unknown devType!\n");
}
printf ("Filesystem : ");
printf("%s ",isFFS(vol->dosType) ? "FFS" : "OFS");
if (isINTL(vol->dosType))
printf ("INTL ");
if (isDIRCACHE(vol->dosType))
printf ("DIRCACHE ");
putchar('\n');
printf("Free blocks = %d\n", adfCountFreeBlocks(vol));
if (vol->readOnly)
printf("Read only\n");
else
printf("Read/Write\n");
/* created */
adfDays2Date(root.coDays, &year, &month, &days);
printf ("created %d/%02d/%02d %d:%02d:%02d\n",days,month,year,
root.coMins/60,root.coMins%60,root.coTicks/50);
adfDays2Date(root.days, &year, &month, &days);
printf ("last access %d/%02d/%02d %d:%02d:%02d, ",days,month,year,
root.mins/60,root.mins%60,root.ticks/50);
adfDays2Date(root.cDays, &year, &month, &days);
printf ("%d/%02d/%02d %d:%02d:%02d\n",days,month,year,
root.cMins/60,root.cMins%60,root.cTicks/50);
}
/*
* adfMount
*
*
*/
struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly )
{
int32_t nBlock;
struct bRootBlock root;
struct bBootBlock boot;
struct Volume* vol;
if (dev==NULL || nPart<nPart || nPart >= dev->nVol) {
(*adfEnv.eFct)("adfMount : invalid parameter(s)");
return NULL;
}
vol = dev->volList[nPart];
vol->dev = dev;
vol->mounted = TRUE;
/*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
vol->lastBlock, vol->rootBlock);
*/
if (adfReadBootBlock(vol, &boot)!=RC_OK) {
(*adfEnv.wFct)("adfMount : BootBlock invalid");
return NULL;
}
vol->dosType = boot.dosType[3];
if (isFFS(vol->dosType))
vol->datablockSize=512;
else
vol->datablockSize=488;
if (dev->readOnly /*|| isDIRCACHE(vol->dosType)*/)
vol->readOnly = TRUE;
else
vol->readOnly = readOnly;
if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
(*adfEnv.wFct)("adfMount : RootBlock invalid");
return NULL;
}
nBlock = vol->lastBlock - vol->firstBlock +1 - 2;
adfReadBitmap( vol, nBlock, &root );
vol->curDirPtr = vol->rootBlock;
/*printf("blockSize=%d\n",vol->blockSize);*/
return( vol );
}
/*
*
* adfUnMount
*
* free bitmap structures
* free current dir
*/
void adfUnMount(struct Volume *vol)
{
if (!vol) {
(*adfEnv.eFct)("adfUnMount : vol is null");
return;
}
adfFreeBitmap(vol);
vol->mounted = FALSE;
}
/*
* adfCreateVol
*
*
*/
struct Volume* adfCreateVol( struct Device* dev, int32_t start, int32_t len,
char* volName, int volType )
{
struct bBootBlock boot;
struct bRootBlock root;
/* struct bDirCacheBlock dirc;*/
SECTNUM blkList[2];
struct Volume* vol;
int nlen;
if (adfEnv.useProgressBar)
(*adfEnv.progressBar)(0);
vol=(struct Volume*)malloc(sizeof(struct Volume));
if (!vol) {
(*adfEnv.eFct)("adfCreateVol : malloc vol");
return NULL;
}
vol->dev = dev;
vol->firstBlock = (dev->heads * dev->sectors)*start;
vol->lastBlock = (vol->firstBlock + (dev->heads * dev->sectors)*len)-1;
vol->rootBlock = (vol->lastBlock - vol->firstBlock+1)/2;
/*printf("first=%ld last=%ld root=%ld\n",vol->firstBlock,
vol->lastBlock, vol->rootBlock);
*/
vol->curDirPtr = vol->rootBlock;
vol->readOnly = dev->readOnly;
vol->mounted = TRUE;
nlen = min( MAXNAMELEN, strlen(volName) );
vol->volName = (char*)malloc(nlen+1);
if (!vol->volName) {
(*adfEnv.eFct)("adfCreateVol : malloc");
free(vol); return NULL;
}
memcpy(vol->volName, volName, nlen);
vol->volName[nlen]='\0';
if (adfEnv.useProgressBar)
(*adfEnv.progressBar)(25);
memset(&boot, 0, 1024);
boot.dosType[3] = volType;
/*printf("first=%d last=%d\n", vol->firstBlock, vol->lastBlock);
printf("name=%s root=%d\n", vol->volName, vol->rootBlock);
*/
if (adfWriteBootBlock(vol, &boot)!=RC_OK) {
free(vol->volName); free(vol);
return NULL;
}
if (adfEnv.useProgressBar)
(*adfEnv.progressBar)(20);
if (adfCreateBitmap( vol )!=RC_OK) {
free(vol->volName); free(vol);
return NULL;
}
if (adfEnv.useProgressBar)
(*adfEnv.progressBar)(40);
/*for(i=0; i<127; i++)
printf("%3d %x, ",i,vol->bitmapTable[0]->map[i]);
*/
if ( isDIRCACHE(volType) )
adfGetFreeBlocks( vol, 2, blkList );
else
adfGetFreeBlocks( vol, 1, blkList );
/*printf("[0]=%d [1]=%d\n",blkList[0],blkList[1]);*/
memset(&root, 0, LOGICAL_BLOCK_SIZE);
if (strlen(volName)>MAXNAMELEN)
volName[MAXNAMELEN]='\0';
root.nameLen = strlen(volName);
memcpy(root.diskName,volName,root.nameLen);
adfTime2AmigaTime(adfGiveCurrentTime(),&(root.coDays),&(root.coMins),&(root.coTicks));
/* dircache block */
if ( isDIRCACHE(volType) ) {
root.extension = 0L;
root.secType = ST_ROOT; /* needed by adfCreateEmptyCache() */
adfCreateEmptyCache(vol, (struct bEntryBlock*)&root, blkList[1]);
}
if (adfEnv.useProgressBar)
(*adfEnv.progressBar)(60);
if (adfWriteRootBlock(vol, blkList[0], &root)!=RC_OK) {
free(vol->volName); free(vol);
return NULL;
}
/* fills root->bmPages[] and writes filled bitmapExtBlocks */
if (adfWriteNewBitmap(vol)!=RC_OK)
return NULL;
if (adfEnv.useProgressBar)
(*adfEnv.progressBar)(80);
if (adfUpdateBitmap(vol)!=RC_OK)
return NULL;
if (adfEnv.useProgressBar)
(*adfEnv.progressBar)(100);
/*printf("free blocks %ld\n",adfCountFreeBlocks(vol));*/
/* will be managed by adfMount() later */
adfFreeBitmap(vol);
vol->mounted = FALSE;
return(vol);
}
/*-----*/
/*
* adfReadBlock
*
* read logical block
*/
RETCODE
adfReadBlock(struct Volume* vol, int32_t nSect, uint8_t* buf)
{
/* char strBuf[80];*/
int32_t 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);
/*printf("psect=%ld nsect=%ld\n",pSect,nSect);*/
/* sprintf(strBuf,"ReadBlock : accessing logical block #%ld", nSect);
(*adfEnv.vFct)(strBuf);
*/
if (pSect<vol->firstBlock || pSect>vol->lastBlock) {
(*adfEnv.wFct)("adfReadBlock : nSect out of range");
}
/*printf("pSect R =%ld\n",pSect);*/
nFct = adfEnv.nativeFct;
if (vol->dev->isNativeDev)
rc = (*nFct->adfNativeReadSector)(vol->dev, pSect, 512, buf);
else
rc = adfReadDumpSector(vol->dev, pSect, 512, buf);
/*printf("rc=%ld\n",rc);*/
if (rc!=RC_OK)
return RC_ERROR;
else
return RC_OK;
}
/*
* adfWriteBlock
*
*/
RETCODE adfWriteBlock(struct Volume* vol, int32_t nSect, uint8_t *buf)
{
int32_t pSect;
struct nativeFunctions *nFct;
RETCODE rc;
if (!vol->mounted) {
(*adfEnv.eFct)("the volume isn't mounted, adfWriteBlock not possible");
return RC_ERROR;
}
if (vol->readOnly) {
(*adfEnv.wFct)("adfWriteBlock : can't write block, read only volume");
return RC_ERROR;
}
pSect = nSect+vol->firstBlock;
/*printf("write nsect=%ld psect=%ld\n",nSect,pSect);*/
if (adfEnv.useRWAccess)
(*adfEnv.rwhAccess)(pSect,nSect,TRUE);
if (pSect<vol->firstBlock || pSect>vol->lastBlock) {
(*adfEnv.wFct)("adfWriteBlock : nSect out of range");
}
nFct = adfEnv.nativeFct;
/*printf("nativ=%d\n",vol->dev->isNativeDev);*/
if (vol->dev->isNativeDev)
rc = (*nFct->adfNativeWriteSector)(vol->dev, pSect, 512, buf);
else
rc = adfWriteDumpSector(vol->dev, pSect, 512, buf);
if (rc!=RC_OK)
return RC_ERROR;
else
return RC_OK;
}
/*#######################################################################################*/

52
src/adf_disk.h Normal file
View File

@@ -0,0 +1,52 @@
#ifndef _ADF_DISK_H
#define _ADF_DISK_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_disk.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "prefix.h"
#include "adf_str.h"
#include "adf_defs.h"
PREFIX RETCODE adfInstallBootBlock(struct Volume *vol,uint8_t*);
PREFIX BOOL isSectNumValid(struct Volume *vol, SECTNUM nSect);
PREFIX struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly );
PREFIX void adfUnMount(struct Volume *vol);
PREFIX void adfVolumeInfo(struct Volume *vol);
struct Volume* adfCreateVol( struct Device* dev, int32_t start, int32_t len,
char* volName, int volType );
/*void adfReadBitmap(struct Volume* , int32_t nBlock, struct bRootBlock* root);
void adfUpdateBitmap(struct Volume*);
*/
PREFIX RETCODE adfReadBlock(struct Volume* , int32_t nSect, uint8_t* buf);
PREFIX RETCODE adfWriteBlock(struct Volume* , int32_t nSect, uint8_t* buf);
#endif /* _ADF_DISK_H */
/*##########################################################################*/

262
src/adf_dump.c Normal file
View File

@@ -0,0 +1,262 @@
/*
* ADF Library
*
* adf_dump.c
*
* $Id$
*
* Amiga Dump File specific routines
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include"adf_defs.h"
#include"adf_str.h"
#include"adf_disk.h"
#include"adf_nativ.h"
#include"adf_err.h"
extern struct Env adfEnv;
/*
* adfInitDumpDevice
*
*/
RETCODE adfInitDumpDevice(struct Device* dev, char* name, BOOL ro)
{
struct nativeDevice* nDev;
int32_t size;
nDev = (struct nativeDevice*)dev->nativeDev;
nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
if (!nDev) {
(*adfEnv.eFct)("adfInitDumpDevice : malloc");
return RC_MALLOC;
}
dev->nativeDev = nDev;
dev->readOnly = ro;
errno = 0;
if (!ro) {
nDev->fd = fopen(name,"rb+");
/* force read only */
if (!nDev->fd && (errno==EACCES || errno==EROFS) ) {
nDev->fd = fopen(name,"rb");
dev->readOnly = TRUE;
if (nDev->fd)
(*adfEnv.wFct)("myInitDevice : fopen, read-only mode forced");
}
}
else
/* read only requested */
nDev->fd = fopen(name,"rb");
if (!nDev->fd) {
free(nDev);
(*adfEnv.eFct)("myInitDevice : fopen");
return RC_ERROR;
}
/* determines size */
fseek(nDev->fd, 0, SEEK_END);
size = ftell(nDev->fd);
fseek(nDev->fd, 0, SEEK_SET);
dev->size = size;
return RC_OK;
}
/*
* adfReadDumpSector
*
*/
RETCODE adfReadDumpSector(struct Device *dev, int32_t n, int size, uint8_t* buf)
{
struct nativeDevice* nDev;
int r;
/*puts("adfReadDumpSector");*/
nDev = (struct nativeDevice*)dev->nativeDev;
r = fseek(nDev->fd, 512*n, SEEK_SET);
/*printf("nnn=%ld size=%d\n",n,size);*/
if (r==-1)
return RC_ERROR;
/*puts("123");*/
if ((r=fread(buf, 1, size, nDev->fd))!=size) {
/*printf("rr=%d\n",r);*/
return RC_ERROR;
}
/*puts("1234");*/
return RC_OK;
}
/*
* adfWriteDumpSector
*
*/
RETCODE adfWriteDumpSector(struct Device *dev, int32_t n, int size, uint8_t* buf)
{
struct nativeDevice* nDev;
int r;
nDev = (struct nativeDevice*)dev->nativeDev;
r=fseek(nDev->fd, 512*n, SEEK_SET);
if (r==-1)
return RC_ERROR;
if ( fwrite(buf, 1, size, nDev->fd)!=(unsigned int)(size) )
return RC_ERROR;
/*puts("adfWriteDumpSector");*/
return RC_OK;
}
/*
* adfReleaseDumpDevice
*
*/
RETCODE adfReleaseDumpDevice(struct Device *dev)
{
struct nativeDevice* nDev;
if (!dev->nativeDev)
return RC_ERROR;
nDev = (struct nativeDevice*)dev->nativeDev;
fclose(nDev->fd);
free(nDev);
return RC_OK;
}
/*
* adfCreateHdFile
*
*/
RETCODE adfCreateHdFile(struct Device* dev, char* volName, int volType)
{
if (dev==NULL) {
(*adfEnv.eFct)("adfCreateHdFile : dev==NULL");
return RC_ERROR;
}
dev->volList =(struct Volume**) malloc(sizeof(struct Volume*));
if (!dev->volList) {
(*adfEnv.eFct)("adfCreateHdFile : unknown device type");
return RC_ERROR;
}
dev->volList[0] = adfCreateVol( dev, 0L, (int32_t)dev->cylinders, volName, volType );
if (dev->volList[0]==NULL) {
free(dev->volList);
return RC_ERROR;
}
dev->nVol = 1;
dev->devType = DEVTYPE_HARDFILE;
return RC_OK;
}
/*
* adfCreateDumpDevice
*
* returns NULL if failed
*/
struct Device*
adfCreateDumpDevice(char* filename, int32_t cylinders, int32_t heads, int32_t sectors)
{
struct Device* dev;
uint8_t buf[LOGICAL_BLOCK_SIZE];
struct nativeDevice* nDev;
/* int32_t i;*/
int r;
dev=(struct Device*)malloc(sizeof(struct Device));
if (!dev) {
(*adfEnv.eFct)("adfCreateDumpDevice : malloc dev");
return NULL;
}
nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
if (!nDev) {
free(dev);
(*adfEnv.eFct)("adfCreateDumpDevice : malloc nDev");
return NULL;
}
dev->nativeDev = nDev;
nDev->fd = (FILE*)fopen(filename,"wb");
if (!nDev->fd) {
free(nDev); free(dev);
(*adfEnv.eFct)("adfCreateDumpDevice : fopen");
return NULL;
}
/* for(i=0; i<cylinders*heads*sectors; i++)
fwrite(buf, sizeof(uint8_t), 512 , nDev->fd);
*/
r=fseek(nDev->fd, ((cylinders*heads*sectors)-1)*LOGICAL_BLOCK_SIZE, SEEK_SET);
if (r==-1) {
fclose(nDev->fd); free(nDev); free(dev);
(*adfEnv.eFct)("adfCreateDumpDevice : fseek");
return NULL;
}
fwrite(buf, LOGICAL_BLOCK_SIZE, 1, nDev->fd);
fclose(nDev->fd);
nDev->fd=(FILE*)fopen(filename,"rb+");
if (!nDev->fd) {
free(nDev); free(dev);
(*adfEnv.eFct)("adfCreateDumpDevice : fopen");
return NULL;
}
dev->cylinders = cylinders;
dev->heads = heads;
dev->sectors = sectors;
dev->size = cylinders*heads*sectors* LOGICAL_BLOCK_SIZE;
if (dev->size==80*11*2*LOGICAL_BLOCK_SIZE)
dev->devType = DEVTYPE_FLOPDD;
else if (dev->size==80*22*2*LOGICAL_BLOCK_SIZE)
dev->devType = DEVTYPE_FLOPHD;
else
dev->devType = DEVTYPE_HARDDISK;
dev->nVol = 0;
dev->isNativeDev = FALSE;
dev->readOnly = FALSE;
return(dev);
}
/*##################################################################################*/

39
src/adf_dump.h Normal file
View File

@@ -0,0 +1,39 @@
#ifndef ADF_DUMP_H
#define ADF_DUMP_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_dump.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
PREFIX struct Device*
adfCreateDumpDevice(char* filename, int32_t cyl, int32_t heads, int32_t sec);
PREFIX RETCODE adfCreateHdFile(struct Device* dev, char* volName, int volType);
BOOL adfInitDumpDevice(struct Device* dev, char* name,BOOL);
BOOL adfReadDumpSector(struct Device *dev, int32_t n, int size, uint8_t* buf);
BOOL adfWriteDumpSector(struct Device *dev, int32_t n, int size, uint8_t* buf);
void adfReleaseDumpDevice(struct Device *dev);
#endif /* ADF_DUMP_H */
/*##########################################################################*/

261
src/adf_env.c Normal file
View File

@@ -0,0 +1,261 @@
/*
* ADF Library
*
* adf_env.c
*
* $Id$
*
* library context and customization code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<stdio.h>
#include<stdlib.h>
#include"adf_defs.h"
#include"adf_str.h"
#include"adf_nativ.h"
#include"adf_env.h"
#include"defendian.h"
union u{
int32_t l;
char c[4];
};
ENV_DECLARATION;
void rwHeadAccess(SECTNUM physical, SECTNUM logical, BOOL write)
{
/* display the physical sector, the logical block, and if the access is read or write */
fprintf(stderr, "phy %d / log %d : %c\n", physical, logical, write ? 'W' : 'R');
}
void progressBar(int perCentDone)
{
fprintf(stderr,"%d %% done\n",perCentDone);
}
void Warning(char* msg) {
fprintf(stderr,"Warning <%s>\n",msg);
}
void Error(char* msg) {
fprintf(stderr,"Error <%s>\n",msg);
/* exit(1);*/
}
void Verbose(char* msg) {
fprintf(stderr,"Verbose <%s>\n",msg);
}
void Changed(SECTNUM nSect, int changedType)
{
/* switch(changedType) {
case ST_FILE:
fprintf(stderr,"Notification : sector %ld (FILE)\n",nSect);
break;
case ST_DIR:
fprintf(stderr,"Notification : sector %ld (DIR)\n",nSect);
break;
case ST_ROOT:
fprintf(stderr,"Notification : sector %ld (ROOT)\n",nSect);
break;
default:
fprintf(stderr,"Notification : sector %ld (???)\n",nSect);
}
*/}
/*
* adfInitEnv
*
*/
void adfEnvInitDefault()
{
/* char str[80];*/
union u val;
/* internal checking */
if (sizeof(short)!=2)
{ fprintf(stderr,"Compilation error : sizeof(short)!=2\n"); exit(1); }
if (sizeof(int32_t)!=4)
{ fprintf(stderr,"Compilation error : sizeof(short)!=2\n"); exit(1); }
if (sizeof(struct bEntryBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bEntryBlock)!=512\n"); exit(1); }
if (sizeof(struct bRootBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bRootBlock)!=512\n"); exit(1); }
if (sizeof(struct bDirBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bDirBlock)!=512\n"); exit(1); }
if (sizeof(struct bBootBlock)!=1024)
{ fprintf(stderr,"Internal error : sizeof(struct bBootBlock)!=1024\n"); exit(1); }
if (sizeof(struct bFileHeaderBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bFileHeaderBlock)!=512\n"); exit(1); }
if (sizeof(struct bFileExtBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bFileExtBlock)!=512\n"); exit(1); }
if (sizeof(struct bOFSDataBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bOFSDataBlock)!=512\n"); exit(1); }
if (sizeof(struct bBitmapBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bBitmapBlock)!=512\n"); exit(1); }
if (sizeof(struct bBitmapExtBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bBitmapExtBlock)!=512\n"); exit(1); }
if (sizeof(struct bLinkBlock)!=512)
{ fprintf(stderr,"Internal error : sizeof(struct bLinkBlock)!=512\n"); exit(1); }
val.l=1L;
/* if LITT_ENDIAN not defined : must be BIG endian */
#ifndef LITT_ENDIAN
if (val.c[3]!=1) /* little endian : LITT_ENDIAN must be defined ! */
{ fprintf(stderr,"Compilation error : #define LITT_ENDIAN must exist\n"); exit(1); }
#else
if (val.c[3]==1) /* big endian : LITT_ENDIAN must not be defined ! */
{ fprintf(stderr,"Compilation error : #define LITT_ENDIAN must not exist\n"); exit(1); }
#endif
adfEnv.wFct = Warning;
adfEnv.eFct = Error;
adfEnv.vFct = Verbose;
adfEnv.notifyFct = Changed;
adfEnv.rwhAccess = rwHeadAccess;
adfEnv.progressBar = progressBar;
adfEnv.useDirCache = FALSE;
adfEnv.useRWAccess = FALSE;
adfEnv.useNotify = FALSE;
adfEnv.useProgressBar = FALSE;
/* sprintf(str,"ADFlib %s (%s)",adfGetVersionNumber(),adfGetVersionDate());
(*adfEnv.vFct)(str);
*/
adfEnv.nativeFct=(struct nativeFunctions*)malloc(sizeof(struct nativeFunctions));
if (!adfEnv.nativeFct) (*adfEnv.wFct)("adfInitDefaultEnv : malloc");
adfInitNativeFct();
}
/*
* adfEnvCleanUp
*
*/
void adfEnvCleanUp()
{
free(adfEnv.nativeFct);
}
/*
* adfChgEnvProp
*
* compilation warnings
* adf_env.c: In function adfChgEnvProp:
* adf_env.c:176: warning: ISO C forbids conversion of object pointer to function pointer type
* adf_env.c:179: warning: ISO C forbids conversion of object pointer to function pointer type
* adf_env.c:182: warning: ISO C forbids conversion of object pointer to function pointer type
* adf_env.c:185: warning: ISO C forbids conversion of object pointer to function pointer type
* adf_env.c:192: warning: ISO C forbids conversion of object pointer to function pointer type
* adf_env.c:203: warning: ISO C forbids conversion of object pointer to function pointer type
*
*/
void adfChgEnvProp(int prop, void *new)
{
BOOL *newBool;
/* int *newInt;*/
switch(prop) {
case PR_VFCT:
adfEnv.vFct = (void(*)(char*))new;
break;
case PR_WFCT:
adfEnv.wFct = (void(*)(char*))new;
break;
case PR_EFCT:
adfEnv.eFct = (void(*)(char*))new;
break;
case PR_NOTFCT:
adfEnv.notifyFct = (void(*)(SECTNUM,int))new;
break;
case PR_USE_NOTFCT:
newBool = (BOOL*)new;
adfEnv.useNotify = *newBool;
break;
case PR_PROGBAR:
adfEnv.progressBar = (void(*)(int))new;
break;
case PR_USE_PROGBAR:
newBool = (BOOL*)new;
adfEnv.useProgressBar = *newBool;
break;
case PR_USE_RWACCESS:
newBool = (BOOL*)new;
adfEnv.useRWAccess = *newBool;
break;
case PR_RWACCESS:
adfEnv.rwhAccess = (void(*)(SECTNUM,SECTNUM,BOOL))new;
break;
case PR_USEDIRC:
newBool = (BOOL*)new;
adfEnv.useDirCache = *newBool;
break;
}
}
/*
* adfSetEnv
*
*/
void adfSetEnvFct( void(*eFct)(char*), void(*wFct)(char*), void(*vFct)(char*),
void(*notFct)(SECTNUM,int) )
{
if (*eFct!=0)
adfEnv.eFct = *eFct;
if (*wFct!=0)
adfEnv.wFct = *wFct;
if (*vFct!=0)
adfEnv.vFct = *vFct;
if (*notFct!=0)
adfEnv.notifyFct = *notFct;
}
/*
* adfGetVersionNumber
*
*/
char* adfGetVersionNumber()
{
return(ADFLIB_VERSION);
}
/*
* adfGetVersionDate
*
*/
char* adfGetVersionDate()
{
return(ADFLIB_DATE);
}
/*##################################################################################*/

40
src/adf_env.h Normal file
View File

@@ -0,0 +1,40 @@
#ifndef ADF_ENV_H
#define ADF_ENV_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_env.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"prefix.h"
PREFIX void adfEnvInitDefault();
PREFIX void adfSetEnvFct( void(*e)(char*), void(*w)(char*), void(*v)(char*),
void(*n)(SECTNUM,int) );
PREFIX void adfEnvCleanUp();
PREFIX void adfChgEnvProp(int prop, void *new);
PREFIX char* adfGetVersionNumber();
PREFIX char* adfGetVersionDate();
#endif /* ADF_ENV_H */
/*##########################################################################*/

86
src/adf_err.h Normal file
View File

@@ -0,0 +1,86 @@
#ifndef ADF_ERR_H
#define ADF_ERR_H
/*
* adf_err.h
*
* $Id$
*
* error codes
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#define hasRC(rc,c) ((rc)&(c))
#define RC_OK 0
#define RC_ERROR -1
#define RC_MALLOC 1
#define RC_VOLFULL 2
#define RC_FOPEN 1<<10
#define RC_NULLPTR 1<<12
/* adfRead*Block() */
#define RC_BLOCKTYPE 1
#define RC_BLOCKSTYPE 1<<1
#define RC_BLOCKSUM 1<<2
#define RC_HEADERKEY 1<<3
#define RC_BLOCKREAD 1<<4
/* adfWrite*Block */
#define RC_BLOCKWRITE 1<<4
/* adfReadBlock() */
#define RC_BLOCKOUTOFRANGE 1
#define RC_BLOCKNATREAD 1<<1
/* adfWriteBlock() */
/* RC_BLOCKOUTOFRANGE */
#define RC_BLOCKNATWRITE 1<<1
#define RC_BLOCKREADONLY 1<<2
/* adfInitDumpDevice() */
/* RC_FOPEN */
/* RC_MALLOC */
/* adfNativeReadBlock(), adfReadDumpSector() */
#define RC_BLOCKSHORTREAD 1
#define RC_BLOCKFSEEK 1<<1
/* adfNativeWriteBlock(), adfWriteDumpSector() */
#define RC_BLOCKSHORTWRITE 1
/* RC_BLOCKFSEEK */
/*-- adfReadRDSKblock --*/
#define RC_BLOCKID 1<<5
/*-- adfWriteRDSKblock() --*/
/*RC_BLOCKREADONLY*/
#endif /* ADF_ERR_H */
/*############################################################################*/

781
src/adf_file.c Normal file
View File

@@ -0,0 +1,781 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_file.c
*
* $Id$
*
* file code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<stdlib.h>
#include<string.h>
#include"adf_util.h"
#include"adf_file.h"
#include"adf_str.h"
#include"defendian.h"
#include"adf_raw.h"
#include"adf_disk.h"
#include"adf_dir.h"
#include"adf_bitm.h"
#include"adf_cache.h"
extern struct Env adfEnv;
void adfFileTruncate(struct Volume *vol, SECTNUM nParent, char *name)
{
}
/*
* adfFileFlush
*
*/
void adfFlushFile(struct File *file)
{
struct bEntryBlock parent;
struct bOFSDataBlock *data;
if (file->currentExt) {
if (file->writeMode)
adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
file->currentExt);
}
if (file->currentData) {
if (file->writeMode) {
file->fileHdr->byteSize = file->pos;
if (isOFS(file->volume->dosType)) {
data = (struct bOFSDataBlock *)file->currentData;
data->dataSize = file->posInDataBlk;
}
if (file->fileHdr->byteSize>0)
adfWriteDataBlock(file->volume, file->curDataPtr,
file->currentData);
}
}
if (file->writeMode) {
file->fileHdr->byteSize = file->pos;
/*printf("pos=%ld\n",file->pos);*/
adfTime2AmigaTime(adfGiveCurrentTime(),
&(file->fileHdr->days),&(file->fileHdr->mins),&(file->fileHdr->ticks) );
adfWriteFileHdrBlock(file->volume, file->fileHdr->headerKey, file->fileHdr);
if (isDIRCACHE(file->volume->dosType)) {
/*printf("parent=%ld\n",file->fileHdr->parent);*/
adfReadEntryBlock(file->volume, file->fileHdr->parent, &parent);
adfUpdateCache(file->volume, &parent, (struct bEntryBlock*)file->fileHdr,FALSE);
}
adfUpdateBitmap(file->volume);
}
}
/*
* adfGetFileBlocks
*
*/
RETCODE adfGetFileBlocks(struct Volume* vol, struct bFileHeaderBlock* entry,
struct FileBlocks* fileBlocks)
{
int32_t n, m;
SECTNUM nSect;
struct bFileExtBlock extBlock;
int32_t i;
fileBlocks->header = entry->headerKey;
adfFileRealSize( entry->byteSize, vol->datablockSize,
&(fileBlocks->nbData), &(fileBlocks->nbExtens) );
fileBlocks->data=(SECTNUM*)malloc(fileBlocks->nbData * sizeof(SECTNUM));
if (!fileBlocks->data) {
(*adfEnv.eFct)("adfGetFileBlocks : malloc");
return RC_MALLOC;
}
fileBlocks->extens=(SECTNUM*)malloc(fileBlocks->nbExtens * sizeof(SECTNUM));
if (!fileBlocks->extens) {
(*adfEnv.eFct)("adfGetFileBlocks : malloc");
return RC_MALLOC;
}
n = m = 0;
/* in file header block */
for(i=0; i<entry->highSeq; i++)
fileBlocks->data[n++] = entry->dataBlocks[MAX_DATABLK-1-i];
/* in file extension blocks */
nSect = entry->extension;
while(nSect!=0) {
fileBlocks->extens[m++] = nSect;
adfReadFileExtBlock(vol, nSect, &extBlock);
for(i=0; i<extBlock.highSeq; i++)
fileBlocks->data[n++] = extBlock.dataBlocks[MAX_DATABLK-1-i];
nSect = extBlock.extension;
}
if ( (fileBlocks->nbExtens+fileBlocks->nbData) != (n+m) )
(*adfEnv.wFct)("adfGetFileBlocks : less blocks than expected");
return RC_OK;
}
/*
* adfFreeFileBlocks
*
*/
RETCODE adfFreeFileBlocks(struct Volume* vol, struct bFileHeaderBlock *entry)
{
int i;
struct FileBlocks fileBlocks;
RETCODE rc = RC_OK;
adfGetFileBlocks(vol,entry,&fileBlocks);
for(i=0; i<fileBlocks.nbData; i++) {
adfSetBlockFree(vol, fileBlocks.data[i]);
}
for(i=0; i<fileBlocks.nbExtens; i++) {
adfSetBlockFree(vol, fileBlocks.extens[i]);
}
free(fileBlocks.data);
free(fileBlocks.extens);
return rc;
}
/*
* adfFileRealSize
*
* Compute and return real number of block used by one file
* Compute number of datablocks and file extension blocks
*
*/
int32_t adfFileRealSize(uint32_t size, int blockSize, int32_t *dataN, int32_t *extN)
{
int32_t data, ext;
/*--- number of data blocks ---*/
data = size / blockSize;
if ( size % blockSize )
data++;
/*--- number of header extension blocks ---*/
ext = 0;
if (data>MAX_DATABLK) {
ext = (data-MAX_DATABLK) / MAX_DATABLK;
if ( (data-MAX_DATABLK) % MAX_DATABLK )
ext++;
}
if (dataN)
*dataN = data;
if (extN)
*extN = ext;
return(ext+data+1);
}
/*
* adfWriteFileHdrBlock
*
*/
RETCODE adfWriteFileHdrBlock(struct Volume *vol, SECTNUM nSect, struct bFileHeaderBlock* fhdr)
{
uint8_t buf[512];
uint32_t newSum;
RETCODE rc = RC_OK;
/*printf("adfWriteFileHdrBlock %ld\n",nSect);*/
fhdr->type = T_HEADER;
fhdr->dataSize = 0;
fhdr->secType = ST_FILE;
memcpy(buf, fhdr, sizeof(struct bFileHeaderBlock));
#ifdef LITT_ENDIAN
swapEndian(buf, SWBL_FILE);
#endif
newSum = adfNormalSum(buf,20,sizeof(struct bFileHeaderBlock));
swLong(buf+20, newSum);
/* *(uint32_t*)(buf+20) = swapLong((uint8_t*)&newSum);*/
adfWriteBlock(vol, nSect, buf);
return rc;
}
/*
* adfFileSeek
*
*/
void adfFileSeek(struct File *file, uint32_t pos)
{
SECTNUM extBlock, nSect;
uint32_t nPos;
int i;
nPos = min(pos, file->fileHdr->byteSize);
file->pos = nPos;
extBlock = adfPos2DataBlock(nPos, file->volume->datablockSize,
&(file->posInExtBlk), &(file->posInDataBlk), &(file->curDataPtr) );
if (extBlock==-1) {
adfReadDataBlock(file->volume,
file->fileHdr->dataBlocks[MAX_DATABLK-1-file->curDataPtr],
file->currentData);
}
else {
nSect = file->fileHdr->extension;
i = 0;
while( i<extBlock && nSect!=0 ) {
adfReadFileExtBlock(file->volume, nSect, file->currentExt );
nSect = file->currentExt->extension;
}
if (i!=extBlock)
(*adfEnv.wFct)("error");
adfReadDataBlock(file->volume,
file->currentExt->dataBlocks[file->posInExtBlk], file->currentData);
}
}
/*
* adfFileOpen
*
*/
struct File* adfOpenFile(struct Volume *vol, char* name, char *mode)
{
struct File *file;
SECTNUM nSect;
struct bEntryBlock entry, parent;
BOOL write;
char filename[200];
write=( strcmp("w",mode)==0 || strcmp("a",mode)==0 );
if (write && vol->dev->readOnly) {
(*adfEnv.wFct)("adfFileOpen : device is mounted 'read only'");
return NULL;
}
adfReadEntryBlock(vol, vol->curDirPtr, &parent);
nSect = adfNameToEntryBlk(vol, parent.hashTable, name, &entry, NULL);
if (!write && nSect==-1) {
sprintf(filename,"adfFileOpen : file \"%s\" not found.",name);
(*adfEnv.wFct)(filename);
/*fprintf(stdout,"filename %s %d, parent =%d\n",name,strlen(name),vol->curDirPtr);*/
return NULL;
}
if (!write && hasR(entry.access)) {
(*adfEnv.wFct)("adfFileOpen : access denied"); return NULL; }
/* if (entry.secType!=ST_FILE) {
(*adfEnv.wFct)("adfFileOpen : not a file"); return NULL; }
if (write && (hasE(entry.access)||hasW(entry.access))) {
(*adfEnv.wFct)("adfFileOpen : access denied"); return NULL; }
*/ if (write && nSect!=-1) {
(*adfEnv.wFct)("adfFileOpen : file already exists"); return NULL; }
file = (struct File*)malloc(sizeof(struct File));
if (!file) { (*adfEnv.wFct)("adfFileOpen : malloc"); return NULL; }
file->fileHdr = (struct bFileHeaderBlock*)malloc(sizeof(struct bFileHeaderBlock));
if (!file->fileHdr) {
(*adfEnv.wFct)("adfFileOpen : malloc");
free(file); return NULL;
}
file->currentData = malloc(512*sizeof(uint8_t));
if (!file->currentData) {
(*adfEnv.wFct)("adfFileOpen : malloc");
free(file->fileHdr); free(file); return NULL;
}
file->volume = vol;
file->pos = 0;
file->posInExtBlk = 0;
file->posInDataBlk = 0;
file->writeMode = write;
file->currentExt = NULL;
file->nDataBlock = 0;
if (strcmp("w",mode)==0) {
memset(file->fileHdr,0,512);
adfCreateFile(vol,vol->curDirPtr,name,file->fileHdr);
file->eof = TRUE;
}
else if (strcmp("a",mode)==0) {
memcpy(file->fileHdr,&entry,sizeof(struct bFileHeaderBlock));
file->eof = TRUE;
adfFileSeek(file, file->fileHdr->byteSize);
}
else if (strcmp("r",mode)==0) {
memcpy(file->fileHdr,&entry,sizeof(struct bFileHeaderBlock));
file->eof = FALSE;
}
/*puts("adfOpenFile");*/
return(file);
}
/*
* adfCloseFile
*
*/
void adfCloseFile(struct File *file)
{
if (file==0)
return;
/*puts("adfCloseFile in");*/
adfFlushFile(file);
if (file->currentExt)
free(file->currentExt);
if (file->currentData)
free(file->currentData);
free(file->fileHdr);
free(file);
/*puts("adfCloseFile out");*/
}
/*
* adfReadFile
*
*/
int32_t adfReadFile(struct File* file, int32_t n, uint8_t *buffer)
{
int32_t bytesRead;
uint8_t *dataPtr, *bufPtr;
int blockSize, size;
if (n==0) return(n);
blockSize = file->volume->datablockSize;
/*puts("adfReadFile");*/
if (file->pos+n > file->fileHdr->byteSize)
n = file->fileHdr->byteSize - file->pos;
if (isOFS(file->volume->dosType))
dataPtr = (uint8_t*)(file->currentData)+24;
else
dataPtr = file->currentData;
if (file->pos==0 || file->posInDataBlk==blockSize) {
adfReadNextFileBlock(file);
file->posInDataBlk = 0;
}
bytesRead = 0; bufPtr = buffer;
size = 0;
while ( bytesRead < n ) {
size = min(n-bytesRead, blockSize-file->posInDataBlk);
memcpy(bufPtr, dataPtr+file->posInDataBlk, size);
bufPtr += size;
file->pos += size;
bytesRead += size;
file->posInDataBlk += size;
if (file->posInDataBlk==blockSize && bytesRead<n) {
adfReadNextFileBlock(file);
file->posInDataBlk = 0;
}
}
file->eof = (file->pos==file->fileHdr->byteSize);
return( bytesRead );
}
/*
* adfEndOfFile
*
*/
BOOL adfEndOfFile(struct File* file)
{
return(file->eof);
}
/*
* adfReadNextFileBlock
*
*/
RETCODE adfReadNextFileBlock(struct File* file)
{
SECTNUM nSect;
struct bOFSDataBlock *data;
RETCODE rc = RC_OK;
data =(struct bOFSDataBlock *) file->currentData;
if (file->nDataBlock==0) {
nSect = file->fileHdr->firstData;
}
else if (isOFS(file->volume->dosType)) {
nSect = data->nextData;
}
else {
if (file->nDataBlock<MAX_DATABLK)
nSect = file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock];
else {
if (file->nDataBlock==MAX_DATABLK) {
file->currentExt=(struct bFileExtBlock*)malloc(sizeof(struct bFileExtBlock));
if (!file->currentExt) (*adfEnv.eFct)("adfReadNextFileBlock : malloc");
adfReadFileExtBlock(file->volume, file->fileHdr->extension,
file->currentExt);
file->posInExtBlk = 0;
}
else if (file->posInExtBlk==MAX_DATABLK) {
adfReadFileExtBlock(file->volume, file->currentExt->extension,
file->currentExt);
file->posInExtBlk = 0;
}
nSect = file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk];
file->posInExtBlk++;
}
}
adfReadDataBlock(file->volume,nSect,file->currentData);
if (isOFS(file->volume->dosType) && data->seqNum!=file->nDataBlock+1)
(*adfEnv.wFct)("adfReadNextFileBlock : seqnum incorrect");
file->nDataBlock++;
return rc;
}
/*
* adfWriteFile
*
*/
int32_t adfWriteFile(struct File *file, int32_t n, uint8_t *buffer)
{
int32_t bytesWritten;
uint8_t *dataPtr, *bufPtr;
int size, blockSize;
struct bOFSDataBlock *dataB;
bytesWritten = 0;
if (n==0) return (n);
/*puts("adfWriteFile");*/
blockSize = file->volume->datablockSize;
if (isOFS(file->volume->dosType)) {
dataB =(struct bOFSDataBlock *)file->currentData;
dataPtr = dataB->data;
}
else
dataPtr = file->currentData;
if (file->pos==0 || file->posInDataBlk==blockSize) {
if (adfCreateNextFileBlock(file)==-1) {
/* bug found by Rikard */
(*adfEnv.wFct)("adfWritefile : no more free sector availbale");
return bytesWritten;
}
file->posInDataBlk = 0;
}
bytesWritten = 0; bufPtr = buffer;
while( bytesWritten<n ) {
size = min(n-bytesWritten, blockSize-file->posInDataBlk);
memcpy(dataPtr+file->posInDataBlk, bufPtr, size);
bufPtr += size;
file->pos += size;
bytesWritten += size;
file->posInDataBlk += size;
if (file->posInDataBlk==blockSize && bytesWritten<n) {
if (adfCreateNextFileBlock(file)==-1) {
/* bug found by Rikard */
(*adfEnv.wFct)("adfWritefile : no more free sector availbale");
return bytesWritten;
}
file->posInDataBlk = 0;
}
}
return( bytesWritten );
}
/*
* adfCreateNextFileBlock
*
*/
SECTNUM adfCreateNextFileBlock(struct File* file)
{
SECTNUM nSect, extSect;
struct bOFSDataBlock *data;
unsigned int blockSize;
int i;
/*puts("adfCreateNextFileBlock");*/
blockSize = file->volume->datablockSize;
data = file->currentData;
/* the first data blocks pointers are inside the file header block */
if (file->nDataBlock<MAX_DATABLK) {
nSect = adfGet1FreeBlock(file->volume);
if (nSect==-1) return -1;
/*printf("adfCreateNextFileBlock fhdr %ld\n",nSect);*/
if (file->nDataBlock==0)
file->fileHdr->firstData = nSect;
file->fileHdr->dataBlocks[MAX_DATABLK-1-file->nDataBlock] = nSect;
file->fileHdr->highSeq++;
}
else {
/* one more sector is needed for one file extension block */
if ((file->nDataBlock%MAX_DATABLK)==0) {
extSect = adfGet1FreeBlock(file->volume);
/*printf("extSect=%ld\n",extSect);*/
if (extSect==-1) return -1;
/* the future block is the first file extension block */
if (file->nDataBlock==MAX_DATABLK) {
file->currentExt=(struct bFileExtBlock*)malloc(sizeof(struct bFileExtBlock));
if (!file->currentExt) {
adfSetBlockFree(file->volume, extSect);
(*adfEnv.eFct)("adfCreateNextFileBlock : malloc");
return -1;
}
file->fileHdr->extension = extSect;
}
/* not the first : save the current one, and link it with the future */
if (file->nDataBlock>=2*MAX_DATABLK) {
file->currentExt->extension = extSect;
/*printf ("write ext=%d\n",file->currentExt->headerKey);*/
adfWriteFileExtBlock(file->volume, file->currentExt->headerKey,
file->currentExt);
}
/* initializes a file extension block */
for(i=0; i<MAX_DATABLK; i++)
file->currentExt->dataBlocks[i] = 0L;
file->currentExt->headerKey = extSect;
file->currentExt->parent = file->fileHdr->headerKey;
file->currentExt->highSeq = 0L;
file->currentExt->extension = 0L;
file->posInExtBlk = 0L;
/*printf("extSect=%ld\n",extSect);*/
}
nSect = adfGet1FreeBlock(file->volume);
if (nSect==-1)
return -1;
/*printf("adfCreateNextFileBlock ext %ld\n",nSect);*/
file->currentExt->dataBlocks[MAX_DATABLK-1-file->posInExtBlk] = nSect;
file->currentExt->highSeq++;
file->posInExtBlk++;
}
/* builds OFS header */
if (isOFS(file->volume->dosType)) {
/* writes previous data block and link it */
if (file->pos>=blockSize) {
data->nextData = nSect;
adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
/*printf ("writedata=%d\n",file->curDataPtr);*/
}
/* initialize a new data block */
for(i=0; i<(int)blockSize; i++)
data->data[i]=0;
data->seqNum = file->nDataBlock+1;
data->dataSize = blockSize;
data->nextData = 0L;
data->headerKey = file->fileHdr->headerKey;
}
else
if (file->pos>=blockSize) {
adfWriteDataBlock(file->volume, file->curDataPtr, file->currentData);
/*printf ("writedata=%d\n",file->curDataPtr);*/
memset(file->currentData,0,512);
}
/*printf("datablk=%d\n",nSect);*/
file->curDataPtr = nSect;
file->nDataBlock++;
return(nSect);
}
/*
* adfPos2DataBlock
*
*/
int32_t adfPos2DataBlock(int32_t pos, int blockSize,
int *posInExtBlk, int *posInDataBlk, int32_t *curDataN )
{
int32_t extBlock;
*posInDataBlk = pos%blockSize;
*curDataN = pos/blockSize;
if (*posInDataBlk==0)
(*curDataN)++;
if (*curDataN<72) {
*posInExtBlk = 0;
return -1;
}
else {
*posInExtBlk = (pos-72*blockSize)%blockSize;
extBlock = (pos-72*blockSize)/blockSize;
if (*posInExtBlk==0)
extBlock++;
return extBlock;
}
}
/*
* adfReadDataBlock
*
*/
RETCODE adfReadDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
{
uint8_t buf[512];
struct bOFSDataBlock *dBlock;
RETCODE rc = RC_OK;
adfReadBlock(vol, nSect,buf);
memcpy(data,buf,512);
if (isOFS(vol->dosType)) {
#ifdef LITT_ENDIAN
swapEndian(data, SWBL_DATA);
#endif
dBlock = (struct bOFSDataBlock*)data;
/*printf("adfReadDataBlock %ld\n",nSect);*/
if (dBlock->checkSum!=adfNormalSum(buf,20,sizeof(struct bOFSDataBlock)))
(*adfEnv.wFct)("adfReadDataBlock : invalid checksum");
if (dBlock->type!=T_DATA)
(*adfEnv.wFct)("adfReadDataBlock : id T_DATA not found");
if (dBlock->dataSize<0 || dBlock->dataSize>488)
(*adfEnv.wFct)("adfReadDataBlock : dataSize incorrect");
if ( !isSectNumValid(vol,dBlock->headerKey) )
(*adfEnv.wFct)("adfReadDataBlock : headerKey out of range");
if ( !isSectNumValid(vol,dBlock->nextData) )
(*adfEnv.wFct)("adfReadDataBlock : nextData out of range");
}
return rc;
}
/*
* adfWriteDataBlock
*
*/
RETCODE adfWriteDataBlock(struct Volume *vol, SECTNUM nSect, void *data)
{
uint8_t buf[512];
uint32_t newSum;
struct bOFSDataBlock *dataB;
RETCODE rc = RC_OK;
newSum = 0L;
if (isOFS(vol->dosType)) {
dataB = (struct bOFSDataBlock *)data;
dataB->type = T_DATA;
memcpy(buf,dataB,512);
#ifdef LITT_ENDIAN
swapEndian(buf, SWBL_DATA);
#endif
newSum = adfNormalSum(buf,20,512);
swLong(buf+20,newSum);
/* *(int32_t*)(buf+20) = swapLong((uint8_t*)&newSum);*/
adfWriteBlock(vol,nSect,buf);
}
else {
adfWriteBlock(vol,nSect,data);
}
/*printf("adfWriteDataBlock %ld\n",nSect);*/
return rc;
}
/*
* adfReadFileExtBlock
*
*/
RETCODE adfReadFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext)
{
uint8_t buf[sizeof(struct bFileExtBlock)];
RETCODE rc = RC_OK;
adfReadBlock(vol, nSect,buf);
/*printf("read fext=%d\n",nSect);*/
memcpy(fext,buf,sizeof(struct bFileExtBlock));
#ifdef LITT_ENDIAN
swapEndian((uint8_t*)fext, SWBL_FEXT);
#endif
if (fext->checkSum!=adfNormalSum(buf,20,sizeof(struct bFileExtBlock)))
(*adfEnv.wFct)("adfReadFileExtBlock : invalid checksum");
if (fext->type!=T_LIST)
(*adfEnv.wFct)("adfReadFileExtBlock : type T_LIST not found");
if (fext->secType!=ST_FILE)
(*adfEnv.wFct)("adfReadFileExtBlock : stype ST_FILE not found");
if (fext->headerKey!=nSect)
(*adfEnv.wFct)("adfReadFileExtBlock : headerKey!=nSect");
if (fext->highSeq<0 || fext->highSeq>MAX_DATABLK)
(*adfEnv.wFct)("adfReadFileExtBlock : highSeq out of range");
if ( !isSectNumValid(vol, fext->parent) )
(*adfEnv.wFct)("adfReadFileExtBlock : parent out of range");
if ( fext->extension!=0 && !isSectNumValid(vol, fext->extension) )
(*adfEnv.wFct)("adfReadFileExtBlock : extension out of range");
return rc;
}
/*
* adfWriteFileExtBlock
*
*/
RETCODE adfWriteFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext)
{
uint8_t buf[512];
uint32_t newSum;
RETCODE rc = RC_OK;
fext->type = T_LIST;
fext->secType = ST_FILE;
fext->dataSize = 0L;
fext->firstData = 0L;
memcpy(buf,fext,512);
#ifdef LITT_ENDIAN
swapEndian(buf, SWBL_FEXT);
#endif
newSum = adfNormalSum(buf,20,512);
swLong(buf+20,newSum);
/* *(int32_t*)(buf+20) = swapLong((uint8_t*)&newSum);*/
adfWriteBlock(vol,nSect,buf);
return rc;
}
/*###########################################################################*/

60
src/adf_file.h Normal file
View File

@@ -0,0 +1,60 @@
#ifndef ADF_FILE_H
#define ADF_FILE_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_file.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"prefix.h"
#include"adf_str.h"
RETCODE adfGetFileBlocks(struct Volume* vol, struct bFileHeaderBlock* entry,
struct FileBlocks* );
RETCODE adfFreeFileBlocks(struct Volume* vol, struct bFileHeaderBlock *entry);
PREFIX int32_t adfFileRealSize(uint32_t size, int blockSize, int32_t *dataN, int32_t *extN);
int32_t adfPos2DataBlock(int32_t pos, int blockSize, int *posInExtBlk, int *posInDataBlk, int32_t *curDataN );
RETCODE adfWriteFileHdrBlock(struct Volume *vol, SECTNUM nSect, struct bFileHeaderBlock* fhdr);
RETCODE adfReadDataBlock(struct Volume *vol, SECTNUM nSect, void *data);
RETCODE adfWriteDataBlock(struct Volume *vol, SECTNUM nSect, void *data);
RETCODE adfReadFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext);
RETCODE adfWriteFileExtBlock(struct Volume *vol, SECTNUM nSect, struct bFileExtBlock* fext);
PREFIX struct File* adfOpenFile(struct Volume *vol, char* name, char *mode);
PREFIX void adfCloseFile(struct File *file);
PREFIX int32_t adfReadFile(struct File* file, int32_t n, uint8_t *buffer);
PREFIX BOOL adfEndOfFile(struct File* file);
PREFIX void adfFileSeek(struct File *file, uint32_t pos); /* BV */
RETCODE adfReadNextFileBlock(struct File* file);
PREFIX int32_t adfWriteFile(struct File *file, int32_t n, uint8_t *buffer);
SECTNUM adfCreateNextFileBlock(struct File* file);
PREFIX void adfFlushFile(struct File *file);
#endif /* ADF_FILE_H */

1035
src/adf_hd.c Normal file

File diff suppressed because it is too large Load Diff

66
src/adf_hd.h Normal file
View File

@@ -0,0 +1,66 @@
#ifndef _ADF_HD_H
#define _ADF_HD_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_hd.h
*
* $Id$
*
* Harddisk and devices code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"prefix.h"
#include "adf_str.h"
#include "hd_blk.h"
#include "adf_err.h"
int adfDevType(struct Device *dev);
PREFIX void adfDeviceInfo(struct Device *dev);
RETCODE adfMountHd(struct Device *dev);
RETCODE adfMountFlop(struct Device* dev);
PREFIX struct Device* adfMountDev( char* filename,BOOL);
PREFIX void adfUnMountDev( struct Device* dev);
RETCODE adfCreateHdHeader(struct Device* dev, int n, struct Partition** partList );
PREFIX RETCODE adfCreateFlop(struct Device* dev, char* volName, int volType );
PREFIX RETCODE adfCreateHd(struct Device* dev, int n, struct Partition** partList );
PREFIX RETCODE adfCreateHdFile(struct Device* dev, char* volName, int volType);
struct Device* adfCreateDev(char* filename, int32_t cylinders, int32_t heads, int32_t sectors);
RETCODE adfReadBlockDev( struct Device* dev, int32_t nSect, int32_t size, uint8_t* buf );
RETCODE adfWriteBlockDev(struct Device* dev, int32_t nSect, int32_t size, uint8_t* buf );
RETCODE adfReadRDSKblock( struct Device* dev, struct bRDSKblock* blk );
RETCODE adfWriteRDSKblock(struct Device *dev, struct bRDSKblock* rdsk);
RETCODE adfReadPARTblock( struct Device* dev, int32_t nSect, struct bPARTblock* blk );
RETCODE adfWritePARTblock(struct Device *dev, int32_t nSect, struct bPARTblock* part);
RETCODE adfReadFSHDblock( struct Device* dev, int32_t nSect, struct bFSHDblock* blk);
RETCODE adfWriteFSHDblock(struct Device *dev, int32_t nSect, struct bFSHDblock* fshd);
RETCODE adfReadLSEGblock(struct Device* dev, int32_t nSect, struct bLSEGblock* blk);
RETCODE adfWriteLSEGblock(struct Device *dev, int32_t nSect, struct bLSEGblock* lseg);
#endif /* _ADF_HD_H */
/*##########################################################################*/

86
src/adf_link.c Normal file
View File

@@ -0,0 +1,86 @@
/*
* ADF Library
*
* adf_link.c
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<string.h>
#include"adf_defs.h"
#include"adf_str.h"
#include"adf_link.h"
#include"adf_dir.h"
extern struct Env adfEnv;
/*
*
*
*/
char* path(struct Volume *vol, SECTNUM parent)
{
struct bEntryBlock entryBlk;
char *tmpPath;
int len;
tmpPath = NULL;
adfReadEntryBlock(vol, parent, &entryBlk);
len = min(entryBlk.nameLen, MAXNAMELEN);
memcpy(tmpPath,entryBlk.name,len);
tmpPath[len]='\0';
/* if (entryBlk.parent!=vol->rootBlock) {
return(strcat(path(vol,entryBlk.parent), tmpPath));
}
else
*/ return(tmpPath);
}
/*
*
*
*/
RETCODE adfBlockPtr2EntryName(struct Volume *vol, SECTNUM nSect, SECTNUM lPar,
char **name, int32_t *size)
{
struct bEntryBlock entryBlk;
struct Entry entry;
if (*name==0) {
adfReadEntryBlock(vol, nSect, &entryBlk);
*size = entryBlk.byteSize;
return RC_OK;
adfEntBlock2Entry(&entryBlk, &entry); /*error*/
/* if (entryBlk.secType!=ST_ROOT && entry.parent!=lPar)
printf("path=%s\n",path(vol,entry.parent));
*/
*name = strdup("");
if (*name==NULL)
return RC_MALLOC;
return RC_OK;
}
else
return RC_OK;
}
/*##################################################################################*/

36
src/adf_link.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef ADF_LINK_H
#define ADF_LINK_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_link.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"prefix.h"
#include <stdint.h>
PREFIX RETCODE adfBlockPtr2EntryName(struct Volume *vol, SECTNUM nSect, SECTNUM lPar,
char **name, int32_t *size);
#endif /* ADF_LINK_H */
/*##########################################################################*/

337
src/adf_raw.c Normal file
View File

@@ -0,0 +1,337 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_raw.c
*
* $Id$
*
* logical disk/volume code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include "adf_str.h"
#include "adf_raw.h"
#include "adf_blk.h"
#include "adf_disk.h"
#include "adf_util.h"
#include "adf_err.h"
#include "defendian.h"
extern struct Env adfEnv;
int swapTable[MAX_SWTYPE+1][15]={
{ 4, SW_CHAR, 2, SW_LONG, 1012, SW_CHAR, 0, 1024 }, /* first bytes of boot */
{ 108, SW_LONG, 40, SW_CHAR, 10, SW_LONG, 0, 512 }, /* root */
{ 6, SW_LONG, 488, SW_CHAR, 0, 512 }, /* data */
/* file, dir, entry */
{ 82, SW_LONG, 92, SW_CHAR, 3, SW_LONG, 36, SW_CHAR, 11, SW_LONG, 0, 512 },
{ 6, SW_LONG, 0, 24 }, /* cache */
{ 128, SW_LONG, 0, 512 }, /* bitmap, fext */
/* link */
{ 6, SW_LONG, 64, SW_CHAR, 86, SW_LONG, 32, SW_CHAR, 12, SW_LONG, 0, 512 },
{ 4, SW_CHAR, 39, SW_LONG, 56, SW_CHAR, 10, SW_LONG, 0, 256 }, /* RDSK */
{ 4, SW_CHAR, 127, SW_LONG, 0, 512 }, /* BADB */
{ 4, SW_CHAR, 8, SW_LONG, 32, SW_CHAR, 31, SW_LONG, 4, SW_CHAR, /* PART */
15, SW_LONG, 0, 256 },
{ 4, SW_CHAR, 7, SW_LONG, 4, SW_CHAR, 55, SW_LONG, 0, 256 }, /* FSHD */
{ 4, SW_CHAR, 4, SW_LONG, 492, SW_CHAR, 0, 512 } /* LSEG */
};
/*
* swapEndian
*
* magic :-) endian swap function (big -> little for read, little to big for write)
*/
void
swapEndian( uint8_t *buf, int type )
{
int i,j;
int p;
i=0;
p=0;
if (type>MAX_SWTYPE || type<0)
adfEnv.eFct("SwapEndian: type do not exist");
while( swapTable[type][i]!=0 ) {
for(j=0; j<swapTable[type][i]; j++) {
switch( swapTable[type][i+1] ) {
case SW_LONG:
*(uint32_t*)(buf+p)=Long(buf+p);
p+=4;
break;
case SW_SHORT:
*(uint32_t*)(buf+p)=Short(buf+p);
p+=2;
break;
case SW_CHAR:
p++;
break;
default:
;
}
}
i+=2;
}
if (p!=swapTable[type][i+1])
(*adfEnv.wFct)("Warning: Endian Swapping length"); /* BV */
}
/*
* adfReadRootBlock
*
* ENDIAN DEPENDENT
*/
RETCODE
adfReadRootBlock(struct Volume* vol, int32_t nSect, struct bRootBlock* root)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
if (adfReadBlock(vol, nSect, buf)!=RC_OK)
return RC_ERROR;
memcpy(root, buf, LOGICAL_BLOCK_SIZE);
#ifdef LITT_ENDIAN
swapEndian((uint8_t*)root, SWBL_ROOT);
#endif
if (root->type!=T_HEADER || root->secType!=ST_ROOT) {
(*adfEnv.wFct)("adfReadRootBlock : id not found");
return RC_ERROR;
}
if (root->checkSum!=adfNormalSum(buf, 20, LOGICAL_BLOCK_SIZE)) {
(*adfEnv.wFct)("adfReadRootBlock : invalid checksum");
return RC_ERROR;
}
return RC_OK;
}
/*
* adfWriteRootBlock
*
*
*/
RETCODE adfWriteRootBlock(struct Volume* vol, int32_t nSect, struct bRootBlock* root)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
uint32_t newSum;
root->type = T_HEADER;
root->headerKey = 0L;
root->highSeq = 0L;
root->hashTableSize = HT_SIZE;
root->firstData = 0L;
/* checkSum, hashTable */
/* bmflag */
/* bmPages, bmExt */
root->nextSameHash = 0L;
root->parent = 0L;
root->secType = ST_ROOT;
memcpy(buf, root, LOGICAL_BLOCK_SIZE);
#ifdef LITT_ENDIAN
swapEndian(buf, SWBL_ROOT);
#endif
newSum = adfNormalSum(buf,20,LOGICAL_BLOCK_SIZE);
swLong(buf+20, newSum);
/* *(uint32_t*)(buf+20) = swapLong((uint8_t*)&newSum);*/
/* dumpBlock(buf);*/
if (adfWriteBlock(vol, nSect, buf)!=RC_OK)
return RC_ERROR;
/*printf("adfWriteRootBlock %ld\n",nSect);*/
return RC_OK;
}
/*
* adfReadBootBlock
*
* ENDIAN DEPENDENT
*/
RETCODE
adfReadBootBlock(struct Volume* vol, struct bBootBlock* boot)
{
uint8_t buf[1024];
/*puts("22");*/
if (adfReadBlock(vol, 0, buf)!=RC_OK)
return RC_ERROR;
/*puts("11");*/
if (adfReadBlock(vol, 1, buf+LOGICAL_BLOCK_SIZE)!=RC_OK)
return RC_ERROR;
memcpy(boot, buf, LOGICAL_BLOCK_SIZE*2);
#ifdef LITT_ENDIAN
swapEndian((uint8_t*)boot,SWBL_BOOT);
#endif
if ( strncmp("DOS",boot->dosType,3)!=0 ) {
(*adfEnv.wFct)("adfReadBootBlock : DOS id not found");
return RC_ERROR;
}
if ( boot->data[0]!=0 && adfBootSum(buf)!=boot->checkSum ) {
/*printf("compsum=%lx sum=%lx\n", adfBootSum(buf),boot->checkSum );*/ /* BV */
(*adfEnv.wFct)("adfReadBootBlock : incorrect checksum");
}
return RC_OK;
}
/*
* adfWriteBootBlock
*
*
* write bootcode ?
*/
RETCODE
adfWriteBootBlock(struct Volume* vol, struct bBootBlock* boot)
{
uint8_t buf[LOGICAL_BLOCK_SIZE*2];
uint32_t newSum;
boot->dosType[0] = 'D';
boot->dosType[1] = 'O';
boot->dosType[2] = 'S';
memcpy(buf, boot, LOGICAL_BLOCK_SIZE*2);
#ifdef LITT_ENDIAN
swapEndian(buf, SWBL_BOOT);
#endif
if (boot->rootBlock==880 || boot->data[0]!=0) {
newSum = adfBootSum(buf);
/*fprintf(stderr,"sum %x %x\n",newSum,adfBootSum2(buf));*/
swLong(buf+4,newSum);
/* *(uint32_t*)(buf+4) = swapLong((uint8_t*)&newSum);*/
}
/* dumpBlock(buf);
dumpBlock(buf+512);
*/
if (adfWriteBlock(vol, 0, buf)!=RC_OK)
return RC_ERROR;
if (adfWriteBlock(vol, 1, buf+512)!=RC_OK)
return RC_ERROR;
/*puts("adfWriteBootBlock");*/
return RC_OK;
}
/*
* NormalSum
*
* buf = where the block is stored
* offset = checksum place (in bytes)
* bufLen = buffer length (in bytes)
*/
uint32_t
adfNormalSum( UCHAR* buf, int offset, int bufLen )
{
int32_t newsum;
int i;
newsum=0L;
for(i=0; i < (bufLen/4); i++)
if ( i != (offset/4) ) /* old chksum */
newsum+=Long(buf+i*4);
newsum=(-newsum); /* WARNING */
return(newsum);
}
/*
* adfBitmapSum
*
*/
uint32_t
adfBitmapSum(uint8_t *buf)
{
uint32_t newSum;
int i;
newSum = 0L;
for(i=1; i<128; i++)
newSum-=Long(buf+i*4);
return(newSum);
}
/*
* adfBootSum
*
*/
uint32_t
adfBootSum(uint8_t *buf)
{
uint32_t d, newSum;
int i;
newSum=0L;
for(i=0; i<256; i++) {
if (i!=1) {
d = Long(buf+i*4);
if ( (ULONG_MAX-newSum)<d )
newSum++;
newSum+=d;
}
}
newSum = ~newSum; /* not */
return(newSum);
}
uint32_t
adfBootSum2(uint8_t *buf)
{
uint32_t prevsum, newSum;
int i;
prevsum = newSum=0L;
for(i=0; i<1024/sizeof(uint32_t); i++) {
if (i!=1) {
prevsum = newSum;
newSum += Long(buf+i*4);
if (newSum < prevsum)
newSum++;
}
}
newSum = ~newSum; /* not */
return(newSum);
}
/*#######################################################################################*/

68
src/adf_raw.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_raw.h
*
* $Id$
*
* blocks level code
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef _ADF_RAW_H
#define _ADF_RAW_H 1
#include "adf_str.h"
#define SW_LONG 4
#define SW_SHORT 2
#define SW_CHAR 1
#define MAX_SWTYPE 11
#define SWBL_BOOT 0
#define SWBL_ROOT 1
#define SWBL_DATA 2
#define SWBL_FILE 3
#define SWBL_ENTRY 3
#define SWBL_DIR 3
#define SWBL_CACHE 4
#define SWBL_BITMAP 5
#define SWBL_FEXT 5
#define SWBL_LINK 6
#define SWBL_BITMAPE 5
#define SWBL_RDSK 7
#define SWBL_BADB 8
#define SWBL_PART 9
#define SWBL_FSHD 10
#define SWBL_LSEG 11
RETCODE adfReadRootBlock(struct Volume*, int32_t nSect, struct bRootBlock* root);
RETCODE adfWriteRootBlock(struct Volume* vol, int32_t nSect, struct bRootBlock* root);
RETCODE adfReadBootBlock(struct Volume*, struct bBootBlock* boot);
RETCODE adfWriteBootBlock(struct Volume* vol, struct bBootBlock* boot);
uint32_t adfBootSum(uint8_t *buf);
uint32_t adfNormalSum( uint8_t *buf, int offset, int bufLen );
void swapEndian( uint8_t *buf, int type );
#endif /* _ADF_RAW_H */
/*##########################################################################*/

399
src/adf_salv.c Normal file
View File

@@ -0,0 +1,399 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_salv.c
*
* $Id$
*
* undelete and salvage code : EXPERIMENTAL !
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<string.h>
#include<stdlib.h>
#include "adf_salv.h"
#include "adf_bitm.h"
#include "adf_util.h"
#include "adf_disk.h"
#include "adf_dir.h"
#include "adf_file.h"
#include "adf_cache.h"
extern struct Env adfEnv;
/*
* adfFreeGenBlock
*
*/
void adfFreeGenBlock(struct GenBlock* block)
{
if (block->name!=NULL)
free(block->name);
}
/*
* adfFreeDelList
*
*/
void adfFreeDelList(struct List* list)
{
struct List *cell;
cell = list;
while(cell!=NULL) {
adfFreeGenBlock((struct GenBlock*)cell->content);
cell = cell->next;
}
freeList(list);
}
/*
* adfGetDelEnt
*
*/
struct List* adfGetDelEnt(struct Volume *vol)
{
struct GenBlock *block;
int32_t i;
struct List *list, *head;
BOOL delEnt;
list = head = NULL;
block = NULL;
delEnt = TRUE;
for(i=vol->firstBlock; i<=vol->lastBlock; i++) {
if (adfIsBlockFree(vol, i)) {
if (delEnt) {
block = (struct GenBlock*)malloc(sizeof(struct GenBlock));
if (!block) return NULL;
/*printf("%p\n",block);*/
}
adfReadGenBlock(vol, i, block);
delEnt = (block->type==T_HEADER
&& (block->secType==ST_DIR || block->secType==ST_FILE) );
if (delEnt) {
if (head==NULL)
list = head = newCell(NULL, (void*)block);
else
list = newCell(list, (void*)block);
}
}
}
if (block!=NULL && list!=NULL && block!=list->content) {
free(block);
/* printf("%p\n",block);*/
}
return head;
}
/*
* adfReadGenBlock
*
*/
RETCODE adfReadGenBlock(struct Volume *vol, SECTNUM nSect, struct GenBlock *block)
{
uint8_t buf[LOGICAL_BLOCK_SIZE];
int len;
char name[MAXNAMELEN+1];
if (adfReadBlock(vol, nSect, buf)!=RC_OK)
return RC_ERROR;
block->type =(int) swapLong(buf);
block->secType =(int) swapLong(buf+vol->blockSize-4);
block->sect = nSect;
block->name = NULL;
if (block->type==T_HEADER) {
switch(block->secType) {
case ST_FILE:
case ST_DIR:
case ST_LFILE:
case ST_LDIR:
len = min(MAXNAMELEN, buf[vol->blockSize-80]);
strncpy(name, (char*)buf+vol->blockSize-79, len);
name[len] = '\0';
block->name = strdup(name);
block->parent = swapLong(buf+vol->blockSize-12);
break;
case ST_ROOT:
break;
default:
;
}
}
return RC_OK;
}
/*
* adfCheckParent
*
*/
RETCODE adfCheckParent(struct Volume* vol, SECTNUM pSect)
{
struct GenBlock block;
if (adfIsBlockFree(vol, pSect)) {
(*adfEnv.wFct)("adfCheckParent : parent doesn't exists");
return RC_ERROR;
}
/* verify if parent is a DIR or ROOT */
adfReadGenBlock(vol, pSect, &block);
if ( block.type!=T_HEADER
|| (block.secType!=ST_DIR && block.secType!=ST_ROOT) ) {
(*adfEnv.wFct)("adfCheckParent : parent secType is incorrect");
return RC_ERROR;
}
return RC_OK;
}
/*
* adfUndelDir
*
*/
RETCODE adfUndelDir(struct Volume* vol, SECTNUM pSect, SECTNUM nSect,
struct bDirBlock* entry)
{
RETCODE rc;
struct bEntryBlock parent;
char name[MAXNAMELEN+1];
/* check if the given parent sector pointer seems OK */
if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
return rc;
if (pSect!=entry->parent) {
(*adfEnv.wFct)("adfUndelDir : the given parent sector isn't the entry parent");
return RC_ERROR;
}
if (!adfIsBlockFree(vol, entry->headerKey))
return RC_ERROR;
if (isDIRCACHE(vol->dosType) && !adfIsBlockFree(vol,entry->extension))
return RC_ERROR;
if (adfReadEntryBlock(vol, pSect, &parent)!=RC_OK)
return RC_ERROR;
strncpy(name, entry->dirName, entry->nameLen);
name[(int)entry->nameLen] = '\0';
/* insert the entry in the parent hashTable, with the headerKey sector pointer */
adfSetBlockUsed(vol,entry->headerKey);
adfCreateEntry(vol, &parent, name, entry->headerKey);
if (isDIRCACHE(vol->dosType)) {
adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);
adfSetBlockUsed(vol,entry->extension);
}
adfUpdateBitmap(vol);
return RC_OK;
}
/*
* adfUndelFile
*
*/
RETCODE adfUndelFile(struct Volume* vol, SECTNUM pSect, SECTNUM nSect, struct bFileHeaderBlock* entry)
{
int32_t i;
char name[MAXNAMELEN+1];
struct bEntryBlock parent;
RETCODE rc;
struct FileBlocks fileBlocks;
/* check if the given parent sector pointer seems OK */
if ( (rc=adfCheckParent(vol,pSect)) != RC_OK)
return rc;
if (pSect!=entry->parent) {
(*adfEnv.wFct)("adfUndelFile : the given parent sector isn't the entry parent");
return RC_ERROR;
}
adfGetFileBlocks(vol, entry, &fileBlocks);
for(i=0; i<fileBlocks.nbData; i++)
if ( !adfIsBlockFree(vol,fileBlocks.data[i]) )
return RC_ERROR;
else
adfSetBlockUsed(vol, fileBlocks.data[i]);
for(i=0; i<fileBlocks.nbExtens; i++)
if ( !adfIsBlockFree(vol,fileBlocks.extens[i]) )
return RC_ERROR;
else
adfSetBlockUsed(vol, fileBlocks.extens[i]);
free(fileBlocks.data);
free(fileBlocks.extens);
if (adfReadEntryBlock(vol, pSect, &parent)!=RC_OK)
return RC_ERROR;
strncpy(name, entry->fileName, entry->nameLen);
name[(int)entry->nameLen] = '\0';
/* insert the entry in the parent hashTable, with the headerKey sector pointer */
adfCreateEntry(vol, &parent, name, entry->headerKey);
if (isDIRCACHE(vol->dosType))
adfAddInCache(vol, &parent, (struct bEntryBlock *)entry);
adfUpdateBitmap(vol);
return RC_OK;
}
/*
* adfUndelEntry
*
*/
RETCODE adfUndelEntry(struct Volume* vol, SECTNUM parent, SECTNUM nSect)
{
struct bEntryBlock entry;
adfReadEntryBlock(vol,nSect,&entry);
switch(entry.secType) {
case ST_FILE:
adfUndelFile(vol, parent, nSect, (struct bFileHeaderBlock*)&entry);
break;
case ST_DIR:
adfUndelDir(vol, parent, nSect, (struct bDirBlock*)&entry);
break;
default:
;
}
return RC_OK;
}
/*
* adfCheckFile
*
*/
RETCODE adfCheckFile(struct Volume* vol, SECTNUM nSect,
struct bFileHeaderBlock* file, int level)
{
struct bFileExtBlock extBlock;
struct bOFSDataBlock dataBlock;
struct FileBlocks fileBlocks;
int n;
adfGetFileBlocks(vol,file,&fileBlocks);
/*printf("data %ld ext %ld\n",fileBlocks.nbData,fileBlocks.nbExtens);*/
if (isOFS(vol->dosType)) {
/* checks OFS datablocks */
for(n=0; n<fileBlocks.nbData; n++) {
/*printf("%ld\n",fileBlocks.data[n]);*/
adfReadDataBlock(vol,fileBlocks.data[n],&dataBlock);
if (dataBlock.headerKey!=fileBlocks.header)
(*adfEnv.wFct)("adfCheckFile : headerKey incorrect");
if (dataBlock.seqNum!=n+1)
(*adfEnv.wFct)("adfCheckFile : seqNum incorrect");
if (n<fileBlocks.nbData-1) {
if (dataBlock.nextData!=fileBlocks.data[n+1])
(*adfEnv.wFct)("adfCheckFile : nextData incorrect");
if (dataBlock.dataSize!=vol->datablockSize)
(*adfEnv.wFct)("adfCheckFile : dataSize incorrect");
}
else { /* last datablock */
if (dataBlock.nextData!=0)
(*adfEnv.wFct)("adfCheckFile : nextData incorrect");
}
}
}
for(n=0; n<fileBlocks.nbExtens; n++) {
adfReadFileExtBlock(vol,fileBlocks.extens[n],&extBlock);
if (extBlock.parent!=file->headerKey)
(*adfEnv.wFct)("adfCheckFile : extBlock parent incorrect");
if (n<fileBlocks.nbExtens-1) {
if (extBlock.extension!=fileBlocks.extens[n+1])
(*adfEnv.wFct)("adfCheckFile : nextData incorrect");
}
else
if (extBlock.extension!=0)
(*adfEnv.wFct)("adfCheckFile : nextData incorrect");
}
free(fileBlocks.data);
free(fileBlocks.extens);
return RC_OK;
}
/*
* adfCheckDir
*
*/
RETCODE adfCheckDir(struct Volume* vol, SECTNUM nSect, struct bDirBlock* dir,
int level)
{
return RC_OK;
}
/*
* adfCheckEntry
*
*/
RETCODE adfCheckEntry(struct Volume* vol, SECTNUM nSect, int level)
{
struct bEntryBlock entry;
RETCODE rc;
adfReadEntryBlock(vol,nSect,&entry);
switch(entry.secType) {
case ST_FILE:
rc = adfCheckFile(vol, nSect, (struct bFileHeaderBlock*)&entry, level);
break;
case ST_DIR:
rc = adfCheckDir(vol, nSect, (struct bDirBlock*)&entry, level);
break;
default:
/* printf("adfCheckEntry : not supported\n");*/ /* BV */
rc = RC_ERROR;
}
return rc;
}
/*#############################################################################*/

42
src/adf_salv.h Normal file
View File

@@ -0,0 +1,42 @@
#ifndef _ADF_SALV_H
#define _ADF_SALV_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_salv.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"prefix.h"
#include "adf_str.h"
RETCODE adfReadGenBlock(struct Volume *vol, SECTNUM nSect, struct GenBlock *block);
PREFIX RETCODE adfCheckEntry(struct Volume* vol, SECTNUM nSect, int level);
PREFIX RETCODE adfUndelEntry(struct Volume* vol, SECTNUM parent, SECTNUM nSect);
PREFIX struct List* adfGetDelEnt(struct Volume *vol);
PREFIX void adfFreeDelList(struct List* list);
/*##########################################################################*/
#endif /* _ADF_SALV_H */

235
src/adf_str.h Normal file
View File

@@ -0,0 +1,235 @@
#ifndef _ADF_STR_H
#define _ADF_STR_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_str.h
*
* $Id$
*
* structures/constants definitions
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* aint32_t with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<stdio.h>
#include"adf_defs.h"
#include"adf_blk.h"
#include"adf_err.h"
/* ----- VOLUME ----- */
struct Volume {
struct Device* dev;
SECTNUM firstBlock; /* first block of data area (from beginning of device) */
SECTNUM lastBlock; /* last block of data area (from beginning of device) */
SECTNUM rootBlock; /* root block (from firstBlock) */
char dosType; /* FFS/OFS, DIRCACHE, INTERNATIONAL */
BOOL bootCode;
BOOL readOnly;
int datablockSize; /* 488 or 512 */
int blockSize; /* 512 */
char *volName;
BOOL mounted;
int32_t bitmapSize; /* in blocks */
SECTNUM *bitmapBlocks; /* bitmap blocks pointers */
struct bBitmapBlock **bitmapTable;
BOOL *bitmapBlocksChg;
SECTNUM curDirPtr;
};
struct Partition {
int32_t startCyl;
int32_t lenCyl;
char* volName;
int volType;
};
/* ----- DEVICES ----- */
#define DEVTYPE_FLOPDD 1
#define DEVTYPE_FLOPHD 2
#define DEVTYPE_HARDDISK 3
#define DEVTYPE_HARDFILE 4
struct Device {
int devType; /* see below */
BOOL readOnly;
int32_t size; /* in bytes */
int nVol; /* partitions */
struct Volume** volList;
int32_t cylinders; /* geometry */
int32_t heads;
int32_t sectors;
BOOL isNativeDev;
void *nativeDev;
};
/* ----- FILE ----- */
struct File {
struct Volume *volume;
struct bFileHeaderBlock* fileHdr;
void *currentData;
struct bFileExtBlock* currentExt;
int32_t nDataBlock;
SECTNUM curDataPtr;
uint32_t pos;
int posInDataBlk;
int posInExtBlk;
BOOL eof, writeMode;
};
/* ----- ENTRY ---- */
struct Entry{
int type;
char* name;
SECTNUM sector;
SECTNUM real;
SECTNUM parent;
char* comment;
uint32_t size;
int32_t access;
int year, month, days;
int hour, mins, secs;
};
struct CacheEntry{
int32_t header, size, protect;
short days, mins, ticks;
signed char type;
char nLen, cLen;
char name[MAXNAMELEN+1], comm[MAXCMMTLEN+1];
/* char *name, *comm;*/
};
struct DateTime{
int year,mon,day,hour,min,sec;
};
/* ----- ENVIRONMENT ----- */
#define PR_VFCT 1
#define PR_WFCT 2
#define PR_EFCT 3
#define PR_NOTFCT 4
#define PR_USEDIRC 5
#define PR_USE_NOTFCT 6
#define PR_PROGBAR 7
#define PR_USE_PROGBAR 8
#define PR_RWACCESS 9
#define PR_USE_RWACCESS 10
struct Env{
void (*vFct)(char*); /* verbose callback function */
void (*wFct)(char*); /* warning callback function */
void (*eFct)(char*); /* error callback function */
void (*notifyFct)(SECTNUM, int);
BOOL useNotify;
void (*rwhAccess)(SECTNUM,SECTNUM,BOOL);
BOOL useRWAccess;
void (*progressBar)(int);
BOOL useProgressBar;
BOOL useDirCache;
void *nativeFct;
};
struct List{ /* generic linked tree */
void *content;
struct List* subdir;
struct List* next;
};
struct GenBlock{
SECTNUM sect;
SECTNUM parent;
int type;
int secType;
char *name; /* if (type == 2 and (secType==2 or secType==-3)) */
};
struct FileBlocks{
SECTNUM header;
int32_t nbExtens;
SECTNUM* extens;
int32_t nbData;
SECTNUM* data;
};
struct bEntryBlock {
/*000*/ int32_t type; /* T_HEADER == 2 */
/*004*/ int32_t headerKey; /* current block number */
int32_t r1[3];
/*014*/ uint32_t checkSum;
/*018*/ int32_t hashTable[HT_SIZE];
int32_t r2[2];
/*140*/ int32_t access; /* bit0=del, 1=modif, 2=write, 3=read */
/*144*/ int32_t byteSize;
/*148*/ char commLen;
/*149*/ char comment[MAXCMMTLEN+1];
char r3[91-(MAXCMMTLEN+1)];
/*1a4*/ int32_t days;
/*1a8*/ int32_t mins;
/*1ac*/ int32_t ticks;
/*1b0*/ char nameLen;
/*1b1*/ char name[MAXNAMELEN+1];
int32_t r4;
/*1d4*/ int32_t realEntry;
/*1d8*/ int32_t nextLink;
int32_t r5[5];
/*1f0*/ int32_t nextSameHash;
/*1f4*/ int32_t parent;
/*1f8*/ int32_t extension;
/*1fc*/ int32_t secType;
};
#define ENV_DECLARATION struct Env adfEnv
#endif /* _ADF_STR_H */
/*##########################################################################*/

254
src/adf_util.c Normal file
View File

@@ -0,0 +1,254 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_util.c
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<stdlib.h>
#include<time.h>
#include "adf_util.h"
#include "adf_err.h"
#include "adf_disk.h"
extern struct Env adfEnv;
/*
* swLong
*
* write an uint32_t value (val) (in)
* to an uint8_t* buffer (buf) (out)
*
* used in adfWrite----Block() functions
*/
void swLong(uint8_t* buf, uint32_t val)
{
buf[0]= (uint8_t)((val & 0xff000000) >>24UL);
buf[1]= (uint8_t)((val & 0x00ff0000) >>16UL);
buf[2]= (uint8_t)((val & 0x0000ff00) >>8UL);
buf[3]= (uint8_t)(val & 0x000000ff);
}
void swShort(uint8_t* buf, uint16_t val)
{
buf[0]= (val & 0xff00) >>8UL;
buf[1]= (val & 0x00ff) ;
}
/*
* newCell
*
* adds a cell at the end the list
*/
struct List* newCell(struct List* list, void* content)
{
struct List* cell;
cell=(struct List*)malloc(sizeof(struct List));
if (!cell) {
(*adfEnv.eFct)("newCell : malloc");
return NULL;
}
cell->content = content;
cell->next = cell->subdir = 0;
if (list!=NULL)
list->next = cell;
return cell;
}
/*
* freeList
*
*/
void freeList(struct List* list)
{
if (list==NULL)
return;
if (list->next)
freeList(list->next);
free(list);
}
/*
* Days2Date
*
* amiga disk date format (days) to normal dd/mm/yy format (out)
*/
void
adfDays2Date(int32_t days, int *yy, int *mm, int *dd)
{
int y,m;
int nd;
int jm[12]={ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/* 0 = 1 Jan 1978, 6988 = 18 feb 1997 */
/*--- year ---*/
y=1978;
if (adfIsLeap(y))
nd=366;
else
nd=365;
while( days >= nd ) {
days-=nd;
y++;
if (adfIsLeap(y))
nd=366;
else
nd=365;
}
/*--- month ---*/
m=1;
if (adfIsLeap(y))
jm[2-1]=29;
while( days >= jm[m-1] ) {
days-=jm[m-1];
m++;
}
*yy=y;
*mm=m;
*dd=days+1;
}
/*
* IsLeap
*
* true if a year (y) is leap
*/
BOOL
adfIsLeap(int y)
{
return( (BOOL) ( !(y%100) ? !(y%400) : !(y%4) ) );
}
/*
* adfCurrentDateTime
*
* return the current system date and time
*/
struct DateTime
adfGiveCurrentTime( void )
{
struct tm *local;
time_t cal;
struct DateTime r;
time(&cal);
local=localtime(&cal);
r.year=local->tm_year; /* since 1900 */
r.mon=local->tm_mon+1;
r.day=local->tm_mday;
r.hour=local->tm_hour;
r.min=local->tm_min;
r.sec=local->tm_sec;
return(r);
}
/*
* adfTime2AmigaTime
*
* converts date and time (dt) into Amiga format : day, min, ticks
*/
void
adfTime2AmigaTime(struct DateTime dt, int32_t *day, int32_t *min, int32_t *ticks )
{
int jm[12]={ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
*min= dt.hour*60 + dt.min; /* mins */
*ticks= dt.sec*50; /* ticks */
/*--- days ---*/
*day= dt.day-1; /* current month days */
/* previous months days downto january */
if (dt.mon>1) { /* if previous month exists */
dt.mon--;
if (dt.mon>2 && adfIsLeap(dt.year)) /* months after a leap february */
jm[2-1]=29;
while(dt.mon>0) {
*day=*day+jm[dt.mon-1];
dt.mon--;
}
}
/* years days before current year downto 1978 */
if (dt.year>78) {
dt.year--;
while(dt.year>=78) {
if (adfIsLeap(dt.year))
*day=*day+366;
else
*day=*day+365;
dt.year--;
}
}
}
/*
* dumpBlock
*
* debug function : to dump a block before writing the check its contents
*
*/
void dumpBlock(uint8_t *buf)
{
int i, j;
for(i=0; i<32; i++) {
printf("%5x ",i*16);
for (j=0; j<4; j++) {
printf("%08x ",Long(buf+j*4+i*16));
}
printf(" ");
for (j=0; j<16; j++)
if (buf[i*16+j]<32 || buf[i*16+j]>127)
putchar('.');
else
putchar(buf[i*16+j]);
putchar('\n');
}
}
/*################################################################################*/

50
src/adf_util.h Normal file
View File

@@ -0,0 +1,50 @@
#ifndef _ADF_UTIL_H
#define _ADF_UTIL_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adf_util.h
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include"prefix.h"
#include "adf_str.h"
void swLong(uint8_t* buf, uint32_t val);
void swShort(uint8_t* buf, uint16_t val);
PREFIX struct List* newCell(struct List* list, void* content);
PREFIX void freeList(struct List* list);
void adfDays2Date(int32_t days, int *yy, int *mm, int *dd);
BOOL adfIsLeap(int y);
void
adfTime2AmigaTime(struct DateTime dt, int32_t *day, int32_t *min, int32_t *ticks );
struct DateTime
adfGiveCurrentTime( void );
void dumpBlock(uint8_t *buf);
/*##########################################################################*/
#endif /* _ADF_UTIL_H */

127
src/adflib.h Normal file
View File

@@ -0,0 +1,127 @@
#ifndef ADFLIB_H
#define ADFLIB_H 1
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* adflib.h
*
* $Id$
*
* general include file
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* Visual C++ DLL specific, define WIN32DLL or not in the makefile */
#ifdef WIN32DLL
#define PREFIX __declspec(dllimport)
#else
#define PREFIX
#endif /* WIN32DLL */
#include "adf_defs.h"
#include "adf_str.h"
/* util */
PREFIX struct List* newCell(struct List* list, void* content);
PREFIX void freeList(struct List* list);
/* dir */
PREFIX RETCODE adfToRootDir(struct Volume *vol);
PREFIX RETCODE adfCreateDir(struct Volume* vol, SECTNUM parent, char* name);
PREFIX RETCODE adfChangeDir(struct Volume* vol, char *name);
PREFIX RETCODE adfParentDir(struct Volume* vol);
PREFIX RETCODE adfRemoveEntry(struct Volume *vol, SECTNUM pSect, char *name);
PREFIX struct List* adfGetDirEnt(struct Volume* vol, SECTNUM nSect );
PREFIX struct List* adfGetRDirEnt(struct Volume* vol, SECTNUM nSect, BOOL recurs );
PREFIX void printEntry(struct Entry* entry);
PREFIX void adfFreeDirList(struct List* list);
PREFIX void adfFreeEntry(struct Entry *);
PREFIX RETCODE adfRenameEntry(struct Volume *vol, SECTNUM, char *old,SECTNUM,char *pNew); /* BV */
PREFIX RETCODE adfSetEntryAccess(struct Volume*, SECTNUM, char*, int32_t);
PREFIX RETCODE adfSetEntryComment(struct Volume*, SECTNUM, char*, char*);
/* file */
PREFIX int32_t adfFileRealSize(uint32_t size, int blockSize, int32_t *dataN, int32_t *extN);
PREFIX struct File* adfOpenFile(struct Volume *vol, char* name, char *mode);
PREFIX void adfCloseFile(struct File *file);
PREFIX int32_t adfReadFile(struct File* file, int32_t n, uint8_t *buffer);
PREFIX BOOL adfEndOfFile(struct File* file);
PREFIX int32_t adfWriteFile(struct File *file, int32_t n, uint8_t *buffer);
PREFIX void adfFlushFile(struct File *file);
PREFIX void adfFileSeek(struct File *file, uint32_t pos);
/* volume */
PREFIX RETCODE adfInstallBootBlock(struct Volume *vol,uint8_t*);
PREFIX struct Volume* adfMount( struct Device *dev, int nPart, BOOL readOnly );
PREFIX void adfUnMount(struct Volume *vol);
PREFIX void adfVolumeInfo(struct Volume *vol);
/* device */
PREFIX void adfDeviceInfo(struct Device *dev);
PREFIX struct Device* adfMountDev( char* filename,BOOL ro);
PREFIX void adfUnMountDev( struct Device* dev);
PREFIX RETCODE adfCreateHd(struct Device* dev, int n, struct Partition** partList );
PREFIX RETCODE adfCreateFlop(struct Device* dev, char* volName, int volType );
PREFIX RETCODE adfCreateHdFile(struct Device* dev, char* volName, int volType);
/* dump device */
PREFIX struct Device* adfCreateDumpDevice(char* filename, int32_t cyl, int32_t heads, int32_t sec);
/* env */
PREFIX void adfEnvInitDefault();
PREFIX void adfEnvCleanUp();
PREFIX void adfChgEnvProp(int prop, void *pNew); /* BV */
PREFIX char* adfGetVersionNumber();
PREFIX char* adfGetVersionDate();
/* obsolete */
PREFIX void adfSetEnvFct( void(*e)(char*), void(*w)(char*), void(*v)(char*) );
/* link */
PREFIX RETCODE adfBlockPtr2EntryName(struct Volume *, SECTNUM, SECTNUM,char **, int32_t *);
/* salv */
PREFIX struct List* adfGetDelEnt(struct Volume *vol);
PREFIX RETCODE adfUndelEntry(struct Volume* vol, SECTNUM parent, SECTNUM nSect);
PREFIX void adfFreeDelList(struct List* list);
PREFIX RETCODE adfCheckEntry(struct Volume* vol, SECTNUM nSect, int level);
/* middle level API */
PREFIX BOOL isSectNumValid(struct Volume *vol, SECTNUM nSect);
/* low level API */
PREFIX RETCODE adfReadBlock(struct Volume* , int32_t nSect, uint8_t* buf);
PREFIX RETCODE adfWriteBlock(struct Volume* , int32_t nSect, uint8_t* buf);
PREFIX int32_t adfCountFreeBlocks(struct Volume* vol);
#ifdef __cplusplus
}
#endif
#endif /* ADFLIB_H */
/*##########################################################################*/

13
src/defendian.h Normal file
View File

@@ -0,0 +1,13 @@
#include "config.h"
#ifndef LITT_ENDIAN
#if defined(__hppa__) || \
defined(__m68k__) || defined(mc68000) || defined(_M_M68K) || \
(defined(__MIPS__) && defined(__MISPEB__)) || \
defined(__ppc__) || defined(__POWERPC__) || defined(_M_PPC) || \
defined(__sparc__)
#else
#define LITT_ENDIAN 1
#endif
#endif

126
src/generic/adf_nativ.c Normal file
View File

@@ -0,0 +1,126 @@
/*
* adf_nativ.c
*
* $Id$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"adf_str.h"
#include"adf_nativ.h"
#include"adf_err.h"
extern struct Env adfEnv;
/*
* myInitDevice
*
* must fill 'dev->size'
*/
RETCODE myInitDevice(struct Device* dev, char* name,BOOL ro)
{
struct nativeDevice* nDev;
nDev = (struct nativeDevice*)dev->nativeDev;
nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
if (!nDev) {
(*adfEnv.eFct)("myInitDevice : malloc");
return RC_ERROR;
}
dev->nativeDev = nDev;
if (!ro)
/* check if device is writable, if not, force readOnly to TRUE */
dev->readOnly = FALSE;
else
/* mount device as read only */
dev->readOnly = TRUE;
dev->size = 0;
return RC_OK;
}
/*
* myReadSector
*
*/
RETCODE myReadSector(struct Device *dev, int32_t n, int size, uint8_t* buf)
{
return RC_OK;
}
/*
* myWriteSector
*
*/
RETCODE myWriteSector(struct Device *dev, int32_t n, int size, uint8_t* buf)
{
return RC_OK;
}
/*
* myReleaseDevice
*
* free native device
*/
RETCODE myReleaseDevice(struct Device *dev)
{
struct nativeDevice* nDev;
nDev = (struct nativeDevice*)dev->nativeDev;
free(nDev);
return RC_OK;
}
/*
* adfInitNativeFct
*
*/
void adfInitNativeFct()
{
struct nativeFunctions *nFct;
nFct = (struct nativeFunctions*)adfEnv.nativeFct;
nFct->adfInitDevice = myInitDevice ;
nFct->adfNativeReadSector = myReadSector ;
nFct->adfNativeWriteSector = myWriteSector ;
nFct->adfReleaseDevice = myReleaseDevice ;
nFct->adfIsDevNative = myIsDevNative;
}
/*
* myIsDevNative
*
*/
BOOL myIsDevNative(char *devName)
{
return (strncmp(devName,"/dev/",5)==0);
}
/*##########################################################################*/

68
src/generic/adf_nativ.h Normal file
View File

@@ -0,0 +1,68 @@
/*
* adf_nativ.h
*
* $ID$
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef ADF_NATIV_H
#define ADF_NATIV_H
#include<stdio.h>
#include"adf_str.h"
#define NATIVE_FILE 8001
#ifndef BOOL
#define BOOL int
#endif
#ifndef RETCODE
#define RETCODE int32_t
#endif
struct nativeDevice{
FILE* fd;
};
struct nativeFunctions{
/* called by adfMount() */
RETCODE (*adfInitDevice)(struct Device*, char*,BOOL);
/* called by adfReadBlock() */
RETCODE (*adfNativeReadSector)(struct Device*, int32_t, int, uint8_t*);
/* called by adfWriteBlock() */
RETCODE (*adfNativeWriteSector)(struct Device*, int32_t, int, uint8_t*);
/* called by adfMount() */
BOOL (*adfIsDevNative)(char*);
/* called by adfUnMount() */
RETCODE (*adfReleaseDevice)();
};
void adfInitNativeFct();
RETCODE myReadSector(struct Device *dev, int32_t n, int size, uint8_t* buf);
RETCODE myWriteSector(struct Device *dev, int32_t n, int size, uint8_t* buf);
RETCODE myInitDevice(struct Device *dev, char* name,BOOL);
RETCODE myReleaseDevice(struct Device *dev);
BOOL myIsDevNative(char*);
#endif /* ADF_NATIV_H */
/*#######################################################################################*/

167
src/hd_blk.h Normal file
View File

@@ -0,0 +1,167 @@
/*
* ADF Library. (C) 1997-2002 Laurent Clevy
*
* hd_blk.h
*
* $Id$
*
* hard disk blocks structures
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* aint32_t with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef _HD_BLK_H
#define _HD_BLK_H 1
#include "adf_str.h"
/* ------- RDSK ---------*/
struct bRDSKblock {
/*000*/ char id[4]; /* RDSK */
/*004*/ int32_t size; /* 64 int32_ts */
/*008*/ ULONG checksum;
/*00c*/ int32_t hostID; /* 7 */
/*010*/ int32_t blockSize; /* 512 bytes */
/*014*/ int32_t flags; /* 0x17 */
/*018*/ int32_t badBlockList;
/*01c*/ int32_t partitionList;
/*020*/ int32_t fileSysHdrList;
/*024*/ int32_t driveInit;
/*028*/ int32_t r1[6]; /* -1 */
/*040*/ int32_t cylinders;
/*044*/ int32_t sectors;
/*048*/ int32_t heads;
/*04c*/ int32_t interleave;
/*050*/ int32_t parkingZone;
/*054*/ int32_t r2[3]; /* 0 */
/*060*/ int32_t writePreComp;
/*064*/ int32_t reducedWrite;
/*068*/ int32_t stepRate;
/*06c*/ int32_t r3[5]; /* 0 */
/*080*/ int32_t rdbBlockLo;
/*084*/ int32_t rdbBlockHi;
/*088*/ int32_t loCylinder;
/*08c*/ int32_t hiCylinder;
/*090*/ int32_t cylBlocks;
/*094*/ int32_t autoParkSeconds;
/*098*/ int32_t highRDSKBlock;
/*09c*/ int32_t r4; /* 0 */
/*0a0*/ char diskVendor[8];
/*0a8*/ char diskProduct[16];
/*0b8*/ char diskRevision[4];
/*0bc*/ char controllerVendor[8];
/*0c4*/ char controllerProduct[16];
/*0d4*/ char controllerRevision[4];
/*0d8*/ int32_t r5[10]; /* 0 */
/*100*/
};
struct bBADBentry {
/*000*/ int32_t badBlock;
/*004*/ int32_t goodBlock;
};
struct bBADBblock {
/*000*/ char id[4]; /* BADB */
/*004*/ int32_t size; /* 128 int32_ts */
/*008*/ ULONG checksum;
/*00c*/ int32_t hostID; /* 7 */
/*010*/ int32_t next;
/*014*/ int32_t r1;
/*018*/ struct bBADBentry blockPairs[61];
};
struct bPARTblock {
/*000*/ char id[4]; /* PART */
/*004*/ int32_t size; /* 64 int32_ts */
/*008*/ ULONG checksum;
/*00c*/ int32_t hostID; /* 7 */
/*010*/ int32_t next;
/*014*/ int32_t flags;
/*018*/ int32_t r1[2];
/*020*/ int32_t devFlags;
/*024*/ char nameLen;
/*025*/ char name[31];
/*044*/ int32_t r2[15];
/*080*/ int32_t vectorSize; /* often 16 int32_ts */
/*084*/ int32_t blockSize; /* 128 int32_ts */
/*088*/ int32_t secOrg;
/*08c*/ int32_t surfaces;
/*090*/ int32_t sectorsPerBlock; /* == 1 */
/*094*/ int32_t blocksPerTrack;
/*098*/ int32_t dosReserved;
/*09c*/ int32_t dosPreAlloc;
/*0a0*/ int32_t interleave;
/*0a4*/ int32_t lowCyl;
/*0a8*/ int32_t highCyl;
/*0ac*/ int32_t numBuffer;
/*0b0*/ int32_t bufMemType;
/*0b4*/ int32_t maxTransfer;
/*0b8*/ int32_t mask;
/*0bc*/ int32_t bootPri;
/*0c0*/ char dosType[4];
/*0c4*/ int32_t r3[15];
};
struct bLSEGblock {
/*000*/ char id[4]; /* LSEG */
/*004*/ int32_t size; /* 128 int32_ts */
/*008*/ ULONG checksum;
/*00c*/ int32_t hostID; /* 7 */
/*010*/ int32_t next;
/*014*/ char loadData[123*4];
};
struct bFSHDblock {
/*000*/ char id[4]; /* FSHD */
/*004*/ int32_t size; /* 64 */
/*008*/ ULONG checksum;
/*00c*/ int32_t hostID; /* 7 */
/*010*/ int32_t next;
/*014*/ int32_t flags;
/*018*/ int32_t r1[2];
/*020*/ char dosType[4];
/*024*/ short majVersion;
/*026*/ short minVersion;
/*028*/ int32_t patchFlags;
/*02c*/ int32_t type;
/*030*/ int32_t task;
/*034*/ int32_t lock;
/*038*/ int32_t handler;
/*03c*/ int32_t stackSize;
/*040*/ int32_t priority;
/*044*/ int32_t startup;
/*048*/ int32_t segListBlock;
/*04c*/ int32_t globalVec;
/*050*/ int32_t r2[23];
/*0ac*/ int32_t r3[21];
};
#endif /* _HD_BLK_H */
/*##########################################################################*/

36
src/prefix.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef _PREFIX_H
#define _PREFIX_H 1
/*
* prefix.h
*
* $Id$
*
* adds symbol export directive under windows
* does nothing under Linux
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef WIN32DLL
#define PREFIX __declspec(dllexport)
#else
#define PREFIX
#endif /* WIN32DLL */
#endif /* _PREFIX_H */

141
src/win32/adf_nativ.c Normal file
View File

@@ -0,0 +1,141 @@
/* Win32/adf_nativ.c - Win32 specific drive-access routines for ADFLib
*
* Modified for Win32 by Dan Sutherland <dan@chromerhino.demon.co.uk>
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/* Modified 29/8/00 by Gary Harris.
** - Added a third, Boolean argument to Win32InitDevice() to avoid a compilation warning
** caused by the mismatch with the number of arguments in ADFLib's adfInitDevice().
*/
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include "../adf_str.h"
#include "../adf_err.h"
#include "adf_nativ.h"
#include "nt4_dev.h"
extern struct Env adfEnv;
RETCODE Win32InitDevice(struct Device* dev, char* lpstrName, BOOL ro)
{
struct nativeDevice* nDev;
char strTempName[3];
nDev = (struct nativeDevice*)dev->nativeDev;
nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
if (!nDev) {
(*adfEnv.eFct)("Win32InitDevice : malloc");
return RC_ERROR; /* BV */
}
/* convert device name to something usable by Win32 functions */
if (strlen(lpstrName) != 3) {
(*adfEnv.eFct)("Win32InitDevice : invalid drive specifier");
return RC_ERROR; /* BV */
}
strTempName[0] = lpstrName[1];
strTempName[1] = lpstrName[2];
strTempName[2] = '\0';
nDev->hDrv = NT4OpenDrive(strTempName);
if (nDev->hDrv == NULL) {
(*adfEnv.eFct)("Win32InitDevice : NT4OpenDrive");
return RC_ERROR; /* BV */
}
dev->size = NT4GetDriveSize(nDev->hDrv);
dev->nativeDev = nDev;
return RC_OK;
}
RETCODE Win32ReadSector(struct Device *dev, long n, int size, unsigned char* buf)
{
struct nativeDevice* tDev;
tDev = (struct nativeDevice*)dev->nativeDev;
if (! NT4ReadSector(tDev->hDrv, n, size, buf)) {
(*adfEnv.eFct)("Win32InitDevice : NT4ReadSector");
return RC_ERROR; /* BV */
}
return RC_OK;
}
RETCODE Win32WriteSector(struct Device *dev, long n, int size, unsigned char* buf)
{
struct nativeDevice* tDev;
tDev = (struct nativeDevice*)dev->nativeDev;
if (! NT4WriteSector(tDev->hDrv, n, size, buf)) {
(*adfEnv.eFct)("Win32InitDevice : NT4WriteSector");
return RC_ERROR; /* BV */
}
return RC_OK;
}
RETCODE Win32ReleaseDevice(struct Device *dev)
{
struct nativeDevice* nDev;
nDev = (struct nativeDevice*)dev->nativeDev;
if (! NT4CloseDrive(nDev->hDrv))
return RC_ERROR; /* BV */
free(nDev);
return RC_OK;
}
void adfInitNativeFct()
{
struct nativeFunctions *nFct;
nFct = (struct nativeFunctions*)adfEnv.nativeFct;
nFct->adfInitDevice = Win32InitDevice;
nFct->adfNativeReadSector = Win32ReadSector;
nFct->adfNativeWriteSector = Win32WriteSector;
nFct->adfReleaseDevice = Win32ReleaseDevice;
nFct->adfIsDevNative = Win32IsDevNative;
}
BOOL Win32IsDevNative(char *devName)
{
return devName[0] == '|';
}

61
src/win32/adf_nativ.h Normal file
View File

@@ -0,0 +1,61 @@
/* Win32/adf_nativ.h
*
* Win32 specific drive access routines for ADFLib
* Copyright 1999 by Dan Sutherland <dan@chromerhino.demon.co.uk>
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
*/
#ifndef ADF_NATIV_H
#define ADF_NATIV_H
#include "../adf_str.h"
#define NATIVE_FILE 8001
#ifndef BOOL
#define BOOL int
#endif
#ifndef RETCODE
#define RETCODE long
#endif
struct nativeDevice{
FILE *fd; /* needed by adf_dump.c */
void *hDrv;
};
struct nativeFunctions{
RETCODE (*adfInitDevice)(struct Device*, char*, BOOL);
RETCODE (*adfNativeReadSector)(struct Device*, long, int, unsigned char*);
RETCODE (*adfNativeWriteSector)(struct Device*, long, int, unsigned char*);
BOOL (*adfIsDevNative)(char*);
RETCODE (*adfReleaseDevice)();
};
void adfInitNativeFct();
RETCODE Win32ReadSector(struct Device *dev, long n, int size, unsigned char* buf);
RETCODE Win32WriteSector(struct Device *dev, long n, int size, unsigned char* buf);
RETCODE Win32InitDevice(struct Device *dev, char* name, BOOL ro);
RETCODE Win32ReleaseDevice(struct Device *dev);
BOOL Win32IsDevNative(char*);
#endif /* ndef ADF_NATIV_H */

104
src/win32/adfvolinfo.c Normal file
View File

@@ -0,0 +1,104 @@
/* An ADFLib function for Windows which displays a dialogue box containing details about
** the current disk file.
** Converted from adfVolumeInfo(), part of ADFLib by Laurent Clevy.
**
** Gary Harris
** 30/8/00
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include "../ADF_raw.h"
#include "../ADF_Util.h"
void adfVolumeInfoWin(HWND hWnd, struct Volume *vol)
/* Windows version of adfVolumeInfo().
** Input: Receives a handle to the window on which to display the dialogue and a pointer
** to a ADFLib Volume structure.
** Output: Nil. Displays a windows dialogue containing the disk file data.
*/
{
char szTemp[50], szAdfInfo[500]; /* Info string. */
struct bRootBlock root;
char diskName[35];
int days,month,year;
if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK)
return;
memset(diskName, 0, 35);
memcpy(diskName, root.diskName, root.nameLen);
sprintf(szAdfInfo, "Name : %-30s\n", vol->volName);
strcat(szAdfInfo, "Type : ");
switch(vol->dev->devType) {
case DEVTYPE_FLOPDD:
strcat(szAdfInfo, "Floppy Double Density : 880 KBytes\n");
break;
case DEVTYPE_FLOPHD:
strcat(szAdfInfo, "Floppy High Density : 1760 KBytes\n");
break;
case DEVTYPE_HARDDISK:
sprintf(szTemp, "Hard Disk partition : %3.1f KBytes\n",
(vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
strcat(szAdfInfo, szTemp);
break;
case DEVTYPE_HARDFILE:
sprintf(szTemp, "HardFile : %3.1f KBytes\n",
(vol->lastBlock - vol->firstBlock +1) * 512.0/1024.0);
strcat(szAdfInfo, szTemp);
break;
default:
strcat(szAdfInfo, "Unknown devType!\n");
}
strcat(szAdfInfo, "Filesystem : ");
sprintf(szTemp, "%s ",isFFS(vol->dosType) ? "FFS" : "OFS");
strcat(szAdfInfo, szTemp);
if (isINTL(vol->dosType))
strcat(szAdfInfo, "INTL ");
if (isDIRCACHE(vol->dosType))
strcat(szAdfInfo, "DIRCACHE ");
strcat(szAdfInfo, "\n");
sprintf(szTemp, "Free blocks = %ld\n", adfCountFreeBlocks(vol));
strcat(szAdfInfo, szTemp);
if (vol->readOnly)
strcat(szAdfInfo, "Read only\n");
else
strcat(szAdfInfo, "Read/Write\n");
/* created */
adfDays2Date(root.coDays, &year, &month, &days);
sprintf(szTemp, "created %d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
root.coMins/60,root.coMins%60,root.coTicks/50);
strcat(szAdfInfo, szTemp);
adfDays2Date(root.days, &year, &month, &days);
sprintf(szTemp, "last access %d/%02d/%02d %ld:%02ld:%02ld, ",days,month,year,
root.mins/60,root.mins%60,root.ticks/50);
strcat(szAdfInfo, szTemp);
adfDays2Date(root.cDays, &year, &month, &days);
sprintf(szTemp, "%d/%02d/%02d %ld:%02ld:%02ld\n",days,month,year,
root.cMins/60,root.cMins%60,root.cTicks/50);
strcat(szAdfInfo, szTemp);
MessageBox(hWnd, szAdfInfo, "Adf Info", MB_OK);
}

31
src/win32/defendian.h Normal file
View File

@@ -0,0 +1,31 @@
#ifndef DEFENDIAN_H
#define DEFENDIAN_H
#define LITT_ENDIAN 1
/*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifdef _MSC_VER
#undef printf
#define printf
#undef putchar
#define putchar
#endif
#endif /* DEFENDIAN_H */

140
src/win32/nt4_dev.c Normal file
View File

@@ -0,0 +1,140 @@
/* nt4_dev.c - routines for direct drive access in Windows NT 4.0
*
* Copyright 1999 by Dan Sutherland <dan@chromerhino.demon.co.uk>
*
* These routines only currently work with drives <2GB and 512 bytes per sector
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <windows.h>
#include <winioctl.h>
#include <stdio.h>
#include "nt4_dev.h"
HANDLE NT4OpenDrive(char *lpstrDrive)
{
char strDriveFile[40];
HANDLE hDrv;
DWORD dwRet;
switch (lpstrDrive[0]) {
case 'H':
sprintf(strDriveFile, "\\\\.\\PhysicalDrive%c", lpstrDrive[1]);
break;
/* add support for other device types here */
default:
return NULL;
}
hDrv = CreateFile(strDriveFile, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
0, NULL);
if (hDrv == INVALID_HANDLE_VALUE)
return NULL;
if (! DeviceIoControl(hDrv, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0,
&dwRet, NULL))
return NULL;
return hDrv;
}
BOOL NT4CloseDrive(HANDLE hDrv)
{
DWORD dwRet;
if( hDrv==NULL ) return TRUE; /* BV */
if (! DeviceIoControl(hDrv, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0,
&dwRet, NULL))
return FALSE;
if (! CloseHandle(hDrv))
return FALSE;
return TRUE;
}
BOOL NT4ReadSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf)
{
void *lpvoidTempBuf;
DWORD dwActual;
lpvoidTempBuf = VirtualAlloc(NULL, 512, MEM_COMMIT, PAGE_READWRITE);
if (SetFilePointer(hDrv, iSect * 512, NULL, FILE_BEGIN) == 0xFFFFFFFF) {
VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
return FALSE;
}
if (! ReadFile(hDrv, lpvoidTempBuf, 512, &dwActual, NULL)) {
VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
return FALSE;
}
memcpy(lpvoidBuf, lpvoidTempBuf, iSize);
VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
return TRUE;
}
BOOL NT4WriteSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf)
{
void *lpvoidTempBuf;
DWORD dwActual;
if (iSize != 512)
return FALSE;
lpvoidTempBuf = VirtualAlloc(NULL, 512, MEM_COMMIT, PAGE_READWRITE);
if (SetFilePointer(hDrv, iSect * 512, NULL, FILE_BEGIN) == 0xFFFFFFFF) {
VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
return FALSE;
}
memcpy(lpvoidTempBuf, lpvoidBuf, iSize);
if (! WriteFile(hDrv, lpvoidTempBuf, 512, &dwActual, NULL)) {
VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
return FALSE;
}
VirtualFree(lpvoidTempBuf, 0, MEM_RELEASE);
return TRUE;
}
ULONG NT4GetDriveSize(HANDLE hDrv)
{
DWORD dwActual;
DISK_GEOMETRY dgGeom;
long size;
DeviceIoControl(hDrv, IOCTL_DISK_GET_DRIVE_GEOMETRY, NULL, 0,
&dgGeom, sizeof(DISK_GEOMETRY), &dwActual, NULL);
size = dgGeom.Cylinders.LowPart * dgGeom.TracksPerCylinder *
dgGeom.SectorsPerTrack * dgGeom.BytesPerSector;
/* BV */
/* printf("Total sectors: %i\n", dgGeom.Cylinders.LowPart * dgGeom.TracksPerCylinder * dgGeom.SectorsPerTrack);
** printf("Byte size: %i\n", size);
*/
return size;
}

26
src/win32/nt4_dev.h Normal file
View File

@@ -0,0 +1,26 @@
/* nt4_dev.h - prototypes for NT4 direct drive access functions
*
* Copyright 1999 by Dan Sutherland
*
* This file is part of ADFLib.
*
* ADFLib is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* ADFLib is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
HANDLE NT4OpenDrive(char *strDrive);
BOOL NT4CloseDrive(HANDLE hDrv);
BOOL NT4ReadSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf);
BOOL NT4WriteSector(HANDLE hDrv, long iSect, int iSize, void *lpvoidBuf);
ULONG NT4GetDriveSize(HANDLE hDrv);

View File

@@ -0,0 +1,40 @@
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>
<body bgcolor="#FFFFFF">
<h1>Readme file for ADFLib on Win32</h1>
<p>
<p>This file contains additional information on using ADFLib under 32-bit Windows.
See the main library documentation for more general info.
<h2>Compiling the library on Win32 platforms</h2>
<p>The ADFLib distribution contains a two makefiles for nmake:
<p><b>Win32Lib.mak</b><br>
Compiles the ADFLib as a static library. To use it, simply link your program
with adflib.lib and #include adflibusr.h.
<p><b>Win32DLL.mak</b><br>
Compiles ADFLib as a DLL. This will produce the files ADFLib.dll, ADFLib.lib
(the import library to link with your
<p>Both makefiles contain debug and release targets. To specify which one to use,
use a command line like this:
<pre>NMAKE /f "ADFLib.mak" CFG="ADFLib - Win32 Release"</pre>
<p>The makefiles will produce a debug version of the library by default if no
configuration is specified.
<h2>The Win32 native functions</h2>
<p>When ADFLib is compiled under Win32, the Win32 native functions will be linked,
allowing you to access Amiga harddisks directly in Windows. Current only Windows
NT is supported - support for Windows 95 and 98 is in the pipeline.
<p>For the direct drive access routines to work under Windows NT, you need administrative
priviledges. This is a security feature of Windows NT and there is no way around
it.
<p>To open a physical device, simply use the following format as the filname:
<pre>|Hx</pre>
<p>Where x is the ID of the drive to mount. Example:
<pre>hd = adfMountDev(&quot;|H1&quot;);</pre>
<p>Your system boot device always has an ID of 0. Attempting to mount it is not
a good idea!
<p>&nbsp;
</body>
</html>