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

270
doc/API.txt Normal file
View File

@@ -0,0 +1,270 @@
The ADFlib API quick overview
*****************************
outdated ! But may be useful anyway...
Always read ADFlib structures, never change a value directly, the
behaviour of the library could then become unforeseeable.
Minimal C program with ADFlib
-----------------------------
#include<stdio.h> /* for puts() */
#include"adflib.h"
ENV_DECLARATION;
int main(int argc, char *argv[])
{
adfEnvInitDefault();
puts("hello world");
adfEnvCleanUp();
}
Device
------
struct Device {
int devType; /* see adf_str.h */
BOOL readOnly;
long size; /* in bytes */
int nVol; /* partitions */
struct Volume** volList;
long cylinders; /* geometry */
long heads;
long sectors;
BOOL isNativeDev;
void *nativeDev;
};
struct Device* adfMountDev(char* name)
mounts and allocates a device (real or dump)
void adfDeviceInfo(struct Device* dev)
prints device info to stdout : must be rewritten for another GUI
void adfUnMountDev(struct Device* dev)
void adfCreateHd(struct Device* dev, int nbPartitions, struct Partition** part)
create a filesystem for harddisk with one or several partition
(see hd_test2.c)
void adfCreateFlop(struct Device* dev, char* name, int flags)
flags are for ffs, dircache or international (see fl_test.c)
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;
int datablockSize; /* 488 or 512 */
char *volName;
long bitmapSize; /* in blocks */
SECTNUM *bitmapBlocks; /* bitmap blocks pointers */
struct bBitmapBlock **bitmapTable;
BOOL *bitmapBlocksChg;
SECTNUM curDirPtr;
};
struct Volume* adfMount(struct Device* dev, int partition, BOOL readOnly)
The first partition is #0
To be called after adfCreateFlop(), adfCreateHd() or adfMountDev().
void adfVolumeInfo(vol)
Display volume info to stdout, must be rewritten for another GUI
void adfUnMount(struct Volume *vol)
Dump device (.ADF)
------------------
struct adfCreateDumpDevice(char*, int cyl, int heads, int sectors)
To be used in place of adfMountDev(). Create a filename of the right size,
nothing else
File
----
struct File* adfOpenFile(struct Volume *volume, char* filename, char* mode)
mode = "r" or "w"
void adfCloseFile(struct File* file)
long adfReadFile(struct File* file, long length, unsigned char* buffer)
returns the number of bytes read
long adfWriteFile(struct File* file, long length, unsigned char* buffer)
returns the number of bytes written
BOOL adfEndOfFile(struct File* file)
Directory
---------
struct List* adfGetDirEnt(struct Volume* vol, SECTNUM nSect)
Returns a linked list with the directory entries. Each cell content of the list
must be freed with adfFreeEntry()
void adfFreeEntry(struct Entry *entry)
SECTNUM adfChangeDir(struct Volume* vol, char* dirname)
change current directory
void adfParentDir(struct Volume* vol)
change current directory
void printEntry(struct Entry* entry)
print the cell content to stdout
void CreateDir(struct Volume* vol, SECTNUM parentSect, char* name)
Callbacks mechanism
-------------------
* The library environment : 'struct Env adfEnv'
This variable is the only global variable of the library. It contains
callbacks for error and notification messages, and global variables.
By default, adfEnvInitDefault() initialize adfEnv functions that display
messages to stderr. You must use adfSetEnv() to use your own defined
functions.
The environment must be clean up with adfEnvCleanUp().
Four functions are available :
- (*adfEnv.eFct)(char*), called by ADFlib for a fatal error. It STOPS
the library : you must redefine yourself a more friendly to handle
this kind of error.
- (adfEnv.wFct)(char*), called for warnings. It is called when something wrong
happens, but processing can continue.
- (adfEnv.vFct)(char*), called to display verbose messages.
- (*adfEnv.notifyEnv)(SECTNUM p, int t), called to tell that
the volume structure has changed. The value p give where the change appeared,
t the type of the value (ST_DIR,ST_FILE,...).
The environment also contains access to nativeFunctions.
* Native device and functions
By default, the library is compiled to manage .ADF files (dump files) and
real devices like harddisk and removable disks (called native devives)
on ONE defined plateform (WinNT/Intel or Linux/68k...)
To add a new plateform to be supported by ADFlib, you must write your
own files adf_nativ.h and adf_nativ.c.
. data types
adf_nativ.h defines two structures :
- 'struct nativeDev'. It contains all the variable necessary for
the native device management. You can add here whatever you what to
be able to manage your real device on your plateform !
- 'struct nativeFunctions'. It defines the minimal API between ADFlib and
the specific native part. The functions names and prototypes must not be
changed, since they are called by the library. It is possible to add
other functions.
The type device 'struct Device' contains one variable 'void* nativeDev'.
It is allocated within adf_nativ.c by adfInitDevice().
Another variable 'BOOL isNativeDev' tells if the ADFlib is working with
a dump file (.ADF) or a real device.
'adfEnv' contains one variable 'void *nativeFct'. adfEnvInitDefault()
allocates it by calling the function adfInitNativeFct().
. callback functions :
The structure 'struct nativeFunctions' must have at least :
BOOL (*adfInitDevice)(struct Device*, char*)
BOOL (*adfNativeReadSector)(struct Device*, long, int, unsigned char*)
BOOL (*adfNativeWriteSector)(struct Device*, long, int, unsigned char*)
BOOL (*adfIsDevNative)(char*)
void (*adfReleaseDevice)()
For example, adfMountDev() calls adfInitDevice() this way :
struct nativeFunctions *nFct;
... /* struct Device* dev allocation */
nFct = adfEnv.nativeFct; /* was of type void* */
/* only once ! */
dev->isNativeDev = (*nFct->adfIsDevNative)(filename);
/* choose between dump or a real device */
if (dev->isNativeDev)
(*nFct->adfInitDevice)(dev, filename);
else
adfInitDumpDevice(dev, filename);
You must define one function to initialize a device, for example :
BOOL myInitDevice(struct Device *dev, char* name)
{
/* allocate and initailize dev->nativeDev */
/* return TRUE if everything happens right */
}
or
BOOL myIsDevNative(char* name)
{
/* for a Unix like platform */
return( strncmp("/dev/",name,5)==0 );
}
And so on to read, write a 512 bytes block, and release the native device.
The function 'adfInitNativeFct()', also defined in adf_nativ.c (and .h),
makes the names and the ADFlib native API :
void adfInitNativeFct()
{
struct nativeFunctions *nFct;
nFct = (struct nativeFunctions*)adfEnv.nativeFct;
nFct->adfInitDevice = myInitDevice ;
nFct->adfNativeReadSector = myReadSector ;
...
}
But the prototypes must stay the same !

2410
doc/FAQ/adf_info.html Normal file

File diff suppressed because it is too large Load Diff

2121
doc/FAQ/adf_info.txt Normal file

File diff suppressed because it is too large Load Diff

1134
doc/FAQ/adf_info_V0_9.txt Normal file

File diff suppressed because it is too large Load Diff

BIN
doc/FAQ/image/adf_dir.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
doc/FAQ/image/adf_file.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

24
doc/Makefile.am Normal file
View File

@@ -0,0 +1,24 @@
doc_DATA = $(top_srcdir)/README \
$(top_srcdir)/AUTHORS \
$(top_srcdir)/COPYING \
$(top_srcdir)/ChangeLog \
$(top_srcdir)/NEWS
nobase_doc_DATA = FAQ/image/adf_dir.gif \
FAQ/image/adf_file.gif \
FAQ/adf_info.html \
FAQ/adf_info.txt \
FAQ/adf_info_V0_9.txt \
api_device.html \
api_dir.html \
api_env.html \
api_file.html \
api_index.html \
api_native.html \
api_salv.html \
api_volume.html \
API.txt \
version0.7.9d_gary.txt
EXTRA_DIST = doc_DATA nobase_doc_DATA

334
doc/api_device.html Normal file
View File

@@ -0,0 +1,334 @@
<HTML>
<HEAD>
<TITLE>Device</TITLE>
</HEAD>
<BODY>
<H1 ALIGN=CENTER>the Device API</H1>
<HR>
<H1>Use cases</H1>
<UL>
<P>
<LI>Mounting volume of a existing device (ADF dump or real one) :
<OL>
<LI>adfMountDev()
<LI>adfMount()
<LI>adfUnMount()
<LI>adfUnMountDev()
</OL>
<P>
<LI>Creating an ADF dump of a floppy :
<OL>
<LI>adfCreateDumpDevice()
<LI>adfCreateFlop()
<LI>adfMount()
<LI>adfUnMount()
<LI>adfUnMountDev()
</OL>
<P>
<LI>Creating an ADF dump of a harddisk :
<OL>
<LI>adfCreateDumpDevice()
<LI>adfCreateHd()
<LI>adfMount()
<LI>adfUnMount()
<LI>adfUnMountDev()
</OL>
<P>
<LI>Creating an new filesystem for an harddisk on a real device :
<OL>
<LI>adfMountDev()
<LI>adfCreateHd()
<LI>adfMount()
<LI>adfUnMount()
<LI>adfUnMountDev()
</OL>
</UL>
<HR>
<H1>Data structures</H1>
<P>
<B>
Warning ! None of the fields of the structure below must be modified directly. In this case,
i can not tell how will behave the library. Unless specified, read access
is of course allowed.
</B>
<P>
The dynamic memory allocation/releasing is done by the library (i hope :).
<P>
<PRE>
struct Device {
int devType; /* DEVTYPE_FLOPDD, DEVTYPE_FLOPHD or DEVTYPE_HARDDISK */
long size; /* size in bytes of the media. ADFlib is limited to 4Gb */
int nVol; /* number of partitions (volumes) */
struct Volume* *volList; /* volumes */
long cylinders, heads, sectors; /* device geometry */
BOOL isNativeDev;
void *nativeDev; /* native specific and private structure */
}
</PRE>
<P>
The Partition structure is used with adfCreateHd().
<PRE>
struct Partition{
long startCyl; /* starting cylinder of the usable space : should be 2 */
long lenCyl; /* length of this area, in cylinders */
char* volName; /* name of the volume, if any. Instead filled with 0. */
int volType; /* filesystem caracteristics : use the flags FSMASK_FFS,
FSMASK_INTL and FSMASK_DIRCACHE */
}
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfMountDev() </FONT></P>
<H2>Syntax</H2>
<B>struct Device*</B> adfMountDev( <B>char*</B> name)
<H2>Description</H2>
Mounts a device. The name could be a filename for an ADF dump, or a
real device name like "|F:" for the Win32 F: partition. <BR>
The real device name is plateform dependent.
<H2>Return values</H2>
NULL if an error occurs, a Device structure pointer instead.
<H2>Internals</H2>
<OL>
<LI>Allocation of <I>struct Device *dev</I>
<LI>Calls <I>adfIsNativeDev()</I> to determine if the name point out
a ADF dump or a real (native) device. The field <I>dev->isNativeDev</I> is filled.
<LI>Initialize the (real or dump) device. The field <I>dev->size</I> is filled.
<LI><I>dev->devType</I> is filled.
<LI>The device is mounted : <I>dev->nVol, dev->volList[], dev->cylinders,
dev->heads, dev->sectors</I> are filled.
<LI><I>dev</I> is returned
</OL>
Warning, in each <I>dev->volList[i]</I> volumes (vol),
only <I>vol->volName</I> (might be NULL), <I>vol->firstBlock, vol->lastBlock</I>
and <I>vol->rootBlock</I> are filled !
<H2>See also</H2>
struct Device, real (native) devices
<H2>Files</H2>
Real devices allocation : adf_nativ.c, adf_nativ.h <BR>
ADF allocation : adf_dump.c, adf_dump.h
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfUnMountDev() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfUnMountDev( <B>struct Device*</B> dev)
<H2>Description</H2>
Releases a Device and frees related resources.
<H2>Internals</H2>
<OL>
<LI>Frees <I>dev->volList[]</I>
<LI>Releases the ADF dump or real (native) device : call the suited function.
</OL>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfCreateHd() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfCreateHd(<B>struct Device*</B> dev, <B>int</B> nPart,
<B>struct Partition*</B> *partList )
<H2>Description</H2>
Create the filesystem of a device which will be used as an Harddisk.
<I>AdfMount()</I> must be used after to mount
a volume (partition).
<P>
In case of a new ADF dump, <I>adfCreateDumpDevice()</I> must be called before to
create an empty media of the right size.
<P>
An Harddisk ADF dump created with ADFlib -can not be- used back by the AmigaDOS,
since some fields of the header structures are missing : they can not be
automatically determined.
<H2>Return values</H2>
RC_OK, or Something different in case of error.
<H2>Examples</H2>
Creation of an ADF Zip disk dump : <BR>
<PRE>
struct Partition part1;
struct Partition **partList;
struct Device *hd;
RETCODE rc;
/* Env init */
/* cyl = 2891, heads = 1, sectors = 68 */
hd = adfCreateDumpDevice("newdev",2891,1,68);
if (!hd) { /* cleanup and exit */ }
/* allocation of partlist[] */
/* the filesystem definition : size, FFS with DIRCACHE */
part1.startCyl = 2;
part1.lenCyl = 2889;
part1.volName = strdup("zip");
part1.volType = FSMASK_FFS|FSMASK_DIRCACHE;
partList[0] = &part1;
/* creates the filesystem */
rc = adfCreateHd(hd,1,partList);
if (rc!=RC_OK) { /* something wrong, cleaning up and exit */ }
/* freeing of partList[] and part1.volName */
/* device usage */
adfUnMountDev(hd);
/* Env cleanup */
</PRE>
<H2>Internals</H2>
<OL>
<LI>Creates and fill <I>dev->volList[]</I>
<LI>Creates the Harddisk header structures on the media. It uses usually the
2 first cylinders of the device.
</OL>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfCreateFlop() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfCreateFlop(<B>struct Device*</B> dev,
<B>char*</B> volName, <B>int</B> volType )
<H2>Description</H2>
Creates the filesystem of a DD or HD floppy.
<I>AdfMount()</I> must be used after to mount the only volume.
<P>
In case of a new ADF dump, <I>adfCreateDumpDevice()</I> must be called before to
create an empty media of the right size.
<P>
An Harddisk ADF dump created with ADFlib -can be- used back by the AmigaDOS.
<H2>Return values</H2>
RC_OK, or Something different in case of error.
<H2>Examples</H2>
<PRE>
struct Device *flop;
/* Env init */
/* creates a DD floppy empty dump */
/* cyl = 80, heads = 2, sectors = 11. HD floppies has 22 sectors */
flop = adfCreateDumpDevice("newdev", 80, 2, 11);
if (!flop) { /* cleanup and exit */ }
/* create the filesystem : OFS with DIRCACHE */
rc = adfCreateFlop( flop, "empty", FSMASK_DIRCACHE );
if (rc!=RC_OK) { /* error : cleanup and exit() */
/* device usage */
adfUnMountDev(flop);
/* Env cleanup */
</PRE>
<H2>Internals</H2>
<OL>
<LI>Allocation of dev->volList[]. It contains one volume.
<LI>Creation of the volume
</OL>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> ADF only : adfCreateDumpDevice() </FONT></P>
<H2>Syntax</H2>
<B>struct Device*</B> adfCreateDumpDevice(<B>char*</B> filename,
<B>long</B> cyl, <B>long</B> heads, <B>long</B> sect)
<H2>Description</H2>
Create a file of the right size, and fills some fields of the Device
structure. Must be followed by adfCreateFlop() and adfCreateHd().
<H2>Return values</H2>
the Device, NULL in case of error.
<H2>Examples</H2>
See adfCreateFlop() and adfCreateHd() examples.
<H2>Internals</H2>
<OL>
<LI>Allocate <I>struct Device* dev</I>
<LI>Allocate <I>dev->nativeDev</I>
<LI>Create an empty file with a size equals to : cyl*heads*sect*512.
<LI>Open this file with "rb+" mode
<LI>Fills <I>dev->cylinders, dev->heads, dev->sectors, dev->size,
dev->devType</I>, and <I>dev->nVol</I> = 0.
<LI>Returns <I>dev</I>
</OL>
</BODY>
</HTML>

274
doc/api_dir.html Normal file
View File

@@ -0,0 +1,274 @@
<HTML>
<HEAD><TITLE> Directory </TITLE></HEAD>
<BODY>
<H1 ALIGN=CENTER>the Directory API</H1>
<HR>
<H1>Data structures</H1>
<PRE>
/* entry types */
#define ST_DIR 2
#define ST_FILE -3
struct Entry{
int type; /* type of the entry */
char *name; /* name */
SECTNUM sector; /* sector pointer */
char *comment; /* optional comment */
unsigned long size; /* file size, 0 for a directory */
long access; /* RWEDAPSH access rights */
int year, month, day; /* date */
int hour, min, sec; /* hour */
}
/* general purpose list used to stored directory entries */
struct List{
void *content; /* Filled with struct Entry* type */
struct List *subdir; /* If the cell content is a dir, its entries list */
/* is stored here, else filled with NULL */
struct List *next; /* Next cell */
}
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfGetDirEnt() </FONT></P>
<H2>Syntax</H2>
<B>struct List*</B> adfGetDirEnt(<B>struct Volume*</B> vol, <B>SECTNUM</B> dir )<BR>
equivalent to <BR>
<B>struct List*</B> adfGetRDirEnt(<B>struct Volume*</B> vol, <B>SECTNUM</B> dir, FALSE )<BR>
<H2>Description</H2>
Returns a linked list which contains the entries of one directory.
<H2>Return values</H2>
The list, NULL in case of error.
<H2>Examples</H2>
<PRE>
struct List *list, *cell;
struct Entry *entry;
/* saves the head of the list */
cell = list = adfGetDirEnt(vol,vol->curDirPtr);
/* while cell->next is NULL, the last cell */
while(cell) {
entry = (struct Entry*)cell->content;
printf("%s %ld\n", entry->name, entry->sector);
cell = cell->next;
}
/* frees the list and the content */
adfFreeDirList(list);
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfGetRDirEnt() </FONT></P>
<H2>Syntax</H2>
<B>struct List*</B> adfGetRDirEnt(<B>struct Volume*</B> vol, <B>SECTNUM</B> dir, <B>BOOL</B> recursive )<BR>
<H2>Description</H2>
Returns a linked list which contains the entries of one directory.
<H2>Return values</H2>
The list, NULL in case of error.
<H2>Examples</H2>
<PRE>
#define TRUE 1
int main()
{
struct List *list, *cell;
struct Entry *entry;
...
/* saves the head of the list */
cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE);
/* prints the tree */
printTree(cell);
/* frees the list and the content */
adfFreeDirList(list);
...
}
/* print the directories tree. recursive */
printTree(struct List* tree)
{
while(tree) {
entry = (struct Entry*)cell->content;
printf("%s %ld\n", entry->name, entry->sector);
if (tree->subdir!=NULL)
printTree(tree->subdir)
tree = tree->next;
}
}
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfChangeDir() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfChangeDir(<B>struct Volume*</B> vol, <B>char *</B>dirName)
<H2>Description</H2>
Change the current working directory to the new one (dirName).
<H2>Return values</H2>
RC_OK, something different in case of error.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfParentDir() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfParentDir(<B>struct Volume*</B> vol)
<H2>Description</H2>
Change the current working directory to its parent directory. If the current
directory is the root of the filesystem ('/'), nothing happens.
<H2>Return values</H2>
RC_OK, something different in case of error.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfCreateDir() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfCreateDir(<B>struct Volume*</B> vol,
<B>SECTNUM</B> parent, <B>char*</B> dirName)
<H2>Description</H2>
Creates a new directory (dirName) into the specified directory (parent).
<H2>Return values</H2>
RC_OK, something different in case of error.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfRemoveEntry() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfRemoveEntry(<B>struct Volume *</B>vol,
<B>SECTNUM</B> parent, <B>char *</B>name)
<H2>Description</H2>
Removes a entry (a file or an empty directory) from one directory (parent).
<H2>Return values</H2>
RC_OK, something different in case of error.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfFreeDirList() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfFreeDirList(<B>struct List*</B> list)
<H2>Description</H2>
Frees a linked list or a tree of directory entries.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfAccess2String() </FONT></P>
<H2>Syntax</H2>
<B>char*</B> adfAccess2String(<B>long</B> access)
<H2>Description</H2>
Converts the access rights from <I>long</I> to <I>char*</I>.
<H2>Return values</H2>
A C string which represents the access rights.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfRenameEntry() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfRenameEntry(<B>struct Volume*</B> vol, <B>SECTNUM</B> oldDir, <B>char*</B> old, <B>SECTNUM</B> newDir, <B>char*</B> new)
<H2>Description</H2>
Changes the name of the entry <I>old</I> located in the <I>oldDir</I> into
the name <I>new</I>, located into the <I>newDir</I> directory.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> printEntry() </FONT></P>
<H2>Syntax</H2>
<B>void</B> printEntry(<B>struct Entry*</B> entry)
<H2>Description</H2>
Do no use this function (not an adf one), but you can use its code to learn
how to display a directory entry (in adf_dir.c).
<P>
<HR>
</BODY>
</HTML>

187
doc/api_env.html Normal file
View File

@@ -0,0 +1,187 @@
<HTML>
<HEAD><TITLE> Environment </TITLE></HEAD>
<BODY>
<H1 ALIGN=CENTER>the Environment API</H1>
<HR>
<H1>Typical usage</H1>
<PRE>
#include"adflib.h"
void MyVer(char *msg)
{
fprintf(stderr,"Verbose [%s]\n",msg);
}
int main()
{
BOOL boolPr = TRUE;
adfEnvInitDefault();
/* to use the dir cache blocks, default is FALSE */
adfChgEnvProp(PR_USEDIRC, (void*)&boolPr); // optional
/* to override the verbose callback */
adfChgEnvProp(PR_VFCT, MyVer); // optional
adfEnvCleanUp();
}
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfEnvInitDefault() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfEnvInitDefault()
<H2>Description</H2>
Initialise the library data structures and default values.
Must be done before any other call to the library.
<P>
There is 4 callback functions which can be (and must be) overridden,
the library must not write anything to the console.
<UL>
<LI>The verbose messages redirection,
<LI>the warning messages redirection,
<LI>the error messages redirection (must stop the library)
<LI>The notification callback : when the current directory has changed.
<LI>The progress bar : this function is called with an int first set to 0.
Then the value increases up to 100. It can be used to display a progress bar.
</UL>
By default, those functions write a message to stderr.
<P>
Another environment property is the ability to use or not the dir cache
blocks to get the content of a directory. By default, it is not used.
<P>
See <B>adfChgEnvProp()</B> to learn how to change those properties.
<H2>Internals</H2>
<OL>
<LI>Set the default values
<LI>Prints the library version with the verbose callback.
<LI>Allocate the native functions structure
<LI>Calls adfInitNativeFct()
</OL>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfChgEnvProp() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfChgEnvProp(<B>int</B> propertyName, <B>void*</B> new value)
<H2>Description</H2>
Change the default or lastest value of one of the environment property.
The new value has the <B>void*</B>, this is the only way to transmit it
for several types. A cast is made depending of the property name inside
adfChgEnvProp().
<P>
Here's the list of the properties, and their types :
<UL>
<LI>PR_VFCT, displays verbose messages, (void(*)(char*))
<LI>PR_WFCT, displays warning messages, (void(*)(char*))
<LI>PR_EFCT, displays error messages, (void(*)(char*))
</UL>
<UL>
<LI>PR_NOTFCT, directory object change notification, (void(*)(SECTNUM,int))
<LI>PR_USE_NOTFCT, toggle on/off (default=off=false), BOOL
</UL>
<UL>
<LI>PR_PROGBAR, progress bar, (void(*)(int))
<LI>PR_USE_PROGBAR, use progress bar (default=off), BOOL<BR>
The functions that support 'progress bar' are : adfCreateFlop(),
adfCreateHd(), adfCreateHdFile().
</UL>
<UL>
<LI>PR_RWACCESS, read (BOOL=false) or write (BOOL=true) operation, logical block and physical sector accessed, (void(*)(SECTNUM,SECTNUM,BOOL))
<LI>PR_USE_RWACCESS, use rwaccess (default=off), BOOL
</UL>
<UL>
<LI>PR_USEDIRC, use dircache blocks, BOOL (default=off).
</UL>
For the non pointer types (int with PR_USEDIRC), you have to use a temporary variable.
To override successfully a function, the easiest is to reuse the default function
located in adf_env.c, and to change it for your needs.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfEnvCleanUp() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfEnvCleanUp()
<H2>Description</H2>
Cleans up the environment.
<H2>Internals</H2>
Frees the native functions structure.
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfEnvCleanUp() : Obsolete </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfSetEnvFct( <B>void(*eFct)(char*)</B> error, <B>void(*wFct)(char*)</B> warning, <B>void(*vFct)(char*)</B> verbose, <B>void(*notFct)(SECTNUM,int)</B> notify )
<P>
Obsolete : use adfChgEnvProp() instead.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfGetVersionNumber() </FONT></P>
<H2>Syntax</H2>
<B>char*</B> adfGetVersionNumber()
<H2>Description</H2>
Returns the current numeric ADFlib version.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfGetVersionDate() </FONT></P>
<H2>Syntax</H2>
<B>char*</B> adfGetVersionDate()
<H2>Description</H2>
Returns the date of the ADFlib current version.
<P>
</BODY>
</HTML>

246
doc/api_file.html Normal file
View File

@@ -0,0 +1,246 @@
<HTML>
<HEAD>
<TITLE>File</TITLE>
</HEAD>
<BODY>
<H1 ALIGN=CENTER>the File API</H1>
<H1>Data structures</H1>
<P>
<B>
Warning ! None of the fields of the structure below must be modified directly. In this case,
i can not tell how will behave the library. Unless specified, read access
is of course allowed.
</B>
<P>
The dynamic memory allocation/releasing is done by the library (i hope :).
<P>
<PRE>
struct File {
struct Volume *volume; // pointer to the volume
struct bFileHeaderBlock* fileHdr; // the header block
void *currentData; // current data block
struct bFileExtBlock* currentExt; // current data extension block
long nDataBlock; // number of current data blocks
SECTNUM curDataPtr; // pointer to the current data block
unsigned long pos; // file pos
int posInDataBlk; // index in a datablock
int posInExtBlk; // index in a file header or file extension block
BOOL eof; // TRUE is the last byte has been read, use adfendOfFile()
BOOL writeMode; // if the adfOpenFile() mode is "w"
};
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfOpenFile() </FONT></P>
<H2>Syntax</H2>
<B>struct File*</B> adfOpenFile(<B>struct Volume*</B> vol, <B>char*</B> name, <B>char*</B> mode);
<H2>Description</H2>
Opens the file with the name <I>name</I> which is located in the current
working directory of the <I>vol</I> volume.<BR>
The allowed <I>mode</I> are <I>"r"</I> and <I>"w"</I>. If the mode is <I>"w"</I>, the file
mustn't already exists, otherwise an error occurs.
<P>
Some basic access permissions are just checked for now.
<H2>Return values</H2>
The File structure, ready to be read or wrote.<BR>
NULL if an error occurs : file not found with "r", or file already exists with "w".
<H2>Internals</H2>
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfFlushFile() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfFlushFile(<B>struct File*</B> file);
<H2>Description</H2>
Flushes the datablocks on disk.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfCloseFile() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfCloseFile(<B>struct File*</B> file)
<H2>Description</H2>
Calls adfFlushFile() and frees the file structure.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfFileRealSize() </FONT></P>
<H2>Syntax</H2>
<B>long</B> adfFileRealSize(<B>unsigned long</B> size, <B>int</B> blockSize, <B>long*</B> dataN, <B>long*</B> extN);
<H2>Description</H2>
Returns the real size in blocks of a file which the given size. It does not
taking into account the new dircache that -may- be allocated.
<P>
The <I>blockSize</I> must be 488 or 512. This information is located in the
<B>datablockSize</B> of the Volume structure.
<P>
If the pointers <I>dataN</I> and <I>extN</I> aren't NULL, the number of
data blocks and file extension blocks are returned.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfReadFile() </FONT></P>
<H2>Syntax</H2>
<B>long</B> adfReadFile(<B>struct File*</B> file, <B>long</B> n, <B>unsigned char*</B> buffer)
<H2>Description</H2>
Read <I>n</I> bytes from the given <I>file</I> into the buffer <I>buffer</I>.
<P>
Use adfEndOfFile() to check if the end of the file is reached or not.
<H2>Example</H2>
<PRE>
#include"adflib.h"
struct File* file;
FILE* out;
long n;
unsigned char buf[600];
/* a device and a volume 'vol' has been successfully mounted */
/* opens the Amiga file */
file = adfOpenFile(vol, "mod.and.distantcall","r");
if (!file) { /* frees resources and exits */ };
/* opens the output classic file */
out = fopen("mod.distant","wb");
if (!out) { adfCloseFile(file); /* ... */ };
/* copy the Amiga file into the standard file, 600 bytes per 600 bytes */
len = 600;
n = adfReadFile(file, len, buf);
while(!adfEndOfFile(file)) {
fwrite(buf, sizeof(unsigned char), n, out);
n = adfReadFile(file, len, buf);
}
/* even if the EOF is reached, some bytes may need to be written */
if (n>0)
fwrite(buf, sizeof(unsigned char), n, out);
/* closes the standard file */
fclose(out);
/* closes the Amiga file */
adfCloseFile(file);
</PRE>
<H2>Returned values</H2>
The number of bytes really read.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfEndOfFile() </FONT></P>
<H2>Syntax</H2>
<B>BOOL</B> adfEndOfFile(<B>struct File*</B> file)
<H2>Description</H2>
TRUE if the end of the file <I>file</I> is reached.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfWriteFile() </FONT></P>
<H2>Syntax</H2>
<B>long</B> adfWriteFile(<B>struct File*</B> file, <B>long</B> n, <B>unsigned char*</B> buffer)
<H2>Description</H2>
Writes <I>n</I> bytes from the given <I>buffer</I> into the file <I>file</I>.
<P>
<H2>Example</H2>
<PRE>
#include"adflib.h"
struct File* file;
FILE* in;
/* a device and a volume 'vol' has been successfully mounted */
file = adfOpenFile(vol, "moon_gif", "w");
if (!file) { /* error handling */ };
in = fopen( argv[2],"rb");
if (!out) { adfCloseFile(file); /* error handling */ };
len = 600;
n = fread(buf,sizeof(unsigned char),len,out);
while(!feof(out)) {
adfWriteFile(file, n, buf);
n = fread(buf,sizeof(unsigned char),len,out);
}
if (n>0)
adfWriteFile(file, n, buf);
fclose(out);
adfCloseFile(file);
</PRE>
<H2>Returned values</H2>
The number of bytes really wrote.
<P>
<HR>
</BODY>
</HTML>

28
doc/api_index.html Normal file
View File

@@ -0,0 +1,28 @@
<HTML>
<HEAD>
<TITLE>The ADFlib Developpers documentation</TITLE>
</HEAD>
<BODY>
<H1 ALIGN=CENTER>the ADFlib API</H1>
<HR>
<UL>
<LI><A HREF="api_device.html">Device</A> : create and mount/unmount harddisk, floppydisk, .ADF, hardfiles,
<LI><A HREF="api_volume.html">Volume</A> : create and mout/unmount volumes
<LI><A HREF="api_dir.html">Directory</A> : list, create, change of directories,
<LI><A HREF="api_file.html">File</A> : create, read and write files,
<LI><A HREF="api_env.html">Environment</A> : initialize and shutdown the library, control its behaviour,
<LI><A HREF="api_salv.html">Salvage</A> : undeletion, recovery,
<LI><A HREF="api_native.html">Native API</A> : how to write real devices drivers on your OS,
</UL>
<HR>
</BODY>
</HTML>

231
doc/api_native.html Normal file
View File

@@ -0,0 +1,231 @@
<HTML>
<HEAD><TITLE> Native </TITLE></HEAD>
<BODY>
<H1 ALIGN=CENTER>the Native API</H1>
<HR>
<H1>Introduction</H1>
By default, the library is compiled to manage .ADF files (dump files) and
plateform specific real devices like harddisk or removable disks
(called native devices).<BR>
At compile time, you can choose between available platforms like Win32/Intel
for example. At run-time, it is possible to mount a dump device or a real device,
several times.
<P>
To add a new plateform support into ADFlib, you must write your
own files adf_nativ.h and adf_nativ.c for that platform. This driver is the link
between the native API of the library and the platform specific functions to
access the hardware.
<P>
The templates for those files are in Generic/.
<P>
The native API consists of :
<P>
1. The natives functions :
<UL>
<LI><B>RETCODE</B> adfInitDevice(<B>struct Device*</B>, <B>char*</B>)
<LI><B>RETCODE</B> adfReleaseDevice(<B>struct Device*</B>)
<LI><B>RETCODE</B> adfNativeReadSector(<B>struct Device*</B>, <B>long</B>, <B>int</B>, <B>unsigned char*</B>)
<LI><B>RETCODE</B> adfNativeWriteSector(<B>struct Device*</B>, <B>long</B>, <B>int</B>, <B>unsigned char*</B>)
<LI><B>BOOL</B> adfIsDevNative(<B>char*</B>)
<LI><B>void</B> adfInitNativeFct()
</UL>
2. And two data structures devoted to native devices management :
<UL>
<LI><B>struct nativeFunctions</B> stored in the library environment,
<LI><B>struct nativeDevice</B> stored in the <B>struct Device</B> structure.
</UL>
The author of the driver defines the <B>nativeDevice</B> structure
and writes the expected functions below, with the expected parameters and the expected behaviours.
<P>
At the environment initialisation, a pointer of each function is stored in the
<B>nativeFunctions</B> structure with adfInitNativeFct().
<P>
Here's how, for example, adfMountDev() call a native function : adfInitDevice() :
<PRE>
struct Device* adfMountDev(char* filename)
{
struct nativeFunctions *nFct;
struct Device* dev;
/* 'dev' memory allocation */
/* gets the native function pointers */
nFct = (struct nativeFunctions*)adfEnv.nativeFct; /* was of type void* */
/* only once ! */
dev->isNativeDev = (*nFct->adfIsDevNative)(filename);
/* choose dump or a real device initialisation */
if (dev->isNativeDev)
(*nFct->adfInitDevice)(dev, filename);
else
adfInitDumpDevice(dev, filename);
...
</PRE>
<HR>
<H1>Data structures</H1>
<PRE>
struct nativeFunctions{
/* function pointers */
RETCODE (*adfInitDevice)(struct Device*, char*);
RETCODE (*adfNativeReadSector)(struct Device*, long, int, unsigned char*);
RETCODE (*adfNativeWriteSector)(struct Device*, long, int, unsigned char*);
BOOL (*adfIsDevNative)(char*);
RETCODE (*adfReleaseDevice)();
};
Those functions are detailed above.
struct nativeDevice{
/* private to native functions, never used in the library, only in native functions */
/* for the dump devices, this structure contains one field : FILE *fd */
};
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfInitDevice() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfInitDevice(<B>struct Device*</B> device, <B>char*</B> name)
<P>
You can choose another name, but the same parameters types and number, and
the same return type.
<H2>Description</H2>
Initialise the native device.
<H2>Return values</H2>
RC_OK if everything went allright, something else otherwise.
<H2>Template</H2>
<PRE>
RETCODE adfInitDevice(struct Device* dev, char* name)
{
struct nativeDevice* nDev;
/* the type was 'void*' */
nDev = (struct nativeDevice*)dev->nativeDev;
nDev = (struct nativeDevice*)malloc(sizeof(struct nativeDevice));
if (!nDev) {
(*adfEnv.eFct)("myInitDevice : malloc");
return RC_ERROR;
}
dev->nativeDev = nDev;
/*
* specific device operations
*
* you MUST set the 'dev->size' field with the length in bytes of the physical media
*/
return RC_OK;
}
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfNativeReadSector() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfNativeReadSector(<B>struct Device*</B> device, <B>long</B> n, <B>int</B> size, <B>unsigned char*</B> buf)
<P>
You can choose another name, but the same parameters types and number, and
the same return type.
<H2>Description</H2>
Move to 512*<I>n</I> bytes from the beginning of the media,
and read <I>size</I> bytes into the <I>buf</I> buffer.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfNativeWriteSector() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfNativeWriteSector(<B>struct Device*</B> device, <B>long</B> n, <B>int</B> size, <B>unsigned char*</B> buf)
<P>
You can choose another name, but the same parameters types and number, and
the same return type.
<H2>Description</H2>
Move to 512*<I>n</I> bytes from the beginning of the media,
and write <I>size</I> bytes into the <I>buf</I> buffer.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfReleaseDevice() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfReleaseDevice(<B>struct Device*</B> device)
<P>
You can choose another name, but the same parameters types and number, and
the same return type.
<H2>Description</H2>
Release the device.
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfIsDevNative() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfIsDevNative(<B>char*</B> name)
<P>
You can choose another name, but the same parameters types and number, and
the same return type.
<H2>Description</H2>
TRUE is the name points out a native device, FALSE otherwise.
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfInitDevice() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfInitDevice(<B>struct Device*</B> device, <B>char*</B> name)
<P>
You can choose another name, but the same parameters types and number, and
the same return type.
<H2>Description</H2>
Initialise the nativeFunctions structure with the native functions addresses.
<HR>
</BODY>
</HTML>

119
doc/api_salv.html Normal file
View File

@@ -0,0 +1,119 @@
<HTML>
<HEAD><TITLE> Salvage </TITLE></HEAD>
<BODY>
<H1 ALIGN=CENTER>the Salvage API</H1>
<HR>
<H1>Typical usage</H1>
<PRE>
#include"adflib.h"
int main()
{
struct List *list, *cell;
/* initialization */
/* the device and volume are mounted */
cell = list = adfGetDelEnt(vol);
while(cell) {
block =(struct Block*) cell->content;
printf("%s %d %d %ld\n",block->name,block->type,block->secType,
block->sect);
cell = cell->next;
}
/* we noted the entry 883 and 885 */
adfFreeDelList(list);
/* 883 is a file */
if (adfCheckEntry(vol,883,0)==RC_OK)
adfUndelEntry(vol,vol->curDirPtr,883);
/* 885 is a directory */
if (adfCheckEntry(vol,885,0)==RC_OK)
adfUndelEntry(vol,vol->curDirPtr,885);
/* unmounts done */
/* cleanup */
}
</PRE>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfGetDelEnt() </FONT></P>
<H2>Syntax</H2>
<B>struct List*</B> adfGetDelEnt(<B>struct Volume *</B>vol)
<H2>Description</H2>
Returns the list of the files/directories that MIGHT be undeleted. The
entries must be checked before !
<P>
See <B>adfFreeDelList()</B> to free this list.<BR>
See <B>adfCheckEntry()</B> to check if the entry could be undeleted.
<H2>Internals</H2>
Scans all the blocks of the volume to find directory blocks
and file header blocks that are not allocated in the bitmap.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfCheckEntry() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfCheckEntry(<B>struct Volume*</B> vol, <B>SECTNUM</B> nSect, <B>int</B> level)
<H2>Description</H2>
Checks if an entry (directory or file) could be undeleted.
<P>
The 'level' argument is not used yet. Could be set to 0.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfUndelEntry()</FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfUndelEntry(<B>struct Volume*</B> vol, <B>SECTNUM</B> parent, <B>SECTNUM</B> nSect)
<H2>Description</H2>
Undelete a directory or a file. The parent directory of an entry must exist.
<H2>Internals</H2>
Add the entry first block pointer in the parent directory list and allocated
the related blocks in the bitmap.
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> void adfFreeDelList(struct List* list) </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfFreeDelList(<B>struct List*</B> list)
<H2>Description</H2>
Free the list of deleted entries.
<P>
</BODY>
</HTML>

171
doc/api_volume.html Normal file
View File

@@ -0,0 +1,171 @@
<HTML>
<HEAD><TITLE> Volume </TITLE></HEAD>
<BODY>
<H1 ALIGN=CENTER>the Volume API</H1>
<HR>
<H1>Use cases</H1>
<P>
See Device API use cases.
<P>
<HR>
<H1>Data structures</H1>
<PRE>
struct Volume{
struct Device *dev; /* the pointer of the Device structure of which the volume belongs to */
/* physical sector numbers */
SECTNUM firstBlock; /* first block of the data area (from the beginning of the media) */
SECTNUM lastBlock; /* last usable block (from the beginning of the media) */
/* logical sector number */
SECTNUM rootBlock; /* root block (from firstBlock) */
char dosType; /* FFS/OFS, DIRCACHE, INTERNATIONAL */
BOOL bootCode; /* TRUE if a floppy is bootable */
int dataBlockSize; /* 488 or 512 */
char* volName;
/* bitmap */
long bitmapSize; /* number of blocks used to store the bitmap
(excluding the bitmapExtension blocks) */
SECTNUM *bitmapBlocks; /* bitmap blocks pointers (excluding bitmap extensions blocks) */
struct bBitmapBlock* *bitmapTable; /* stores the bitmap blocks */
BOOL *bitmapBlocksChg; /* bitmapBlocksChg[i] is TRUE if bitmapTable[i} has changed,
and need to be written at bitmapBlocks[i] */
SECTNUM curDirPtr; /* number of the current working directory */
}
</PRE>
<P>
If <I>vol</I> is one Volume structure returned by adfMount() :
<UL>
<LI>The devType is <I>vol->dev->devType</I>.
<LI>The dosType is OFS or FFS (exclusive), and may have the DIRCACHE and INTERNATIONAL
modes enabled. Uses isFFS(vol->dosType), isOFS(), isINTL() and isDIRCACHE()
to determine it.
<BR>
<B>Warning ! Even if isINTL() returns FALSE, if isDIRCACHE()
is TRUE, the Volume is considered (like with AmigaDOS) as having the
international mode enabled !</B>
</UL>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfMount() </FONT></P>
<H2>Syntax</H2>
<B>struct Volume*</B> adfMount(<B>struct Device *</B>dev,
<B>int</B> nPart, <B>BOOL</B> readOnly)
<H2>Description</H2>
<P>
Mounts a designed volume (nPart) of the Device (dev), eventually with
read only access (readOnly). The first partition is #0.
<P>
The current working directory is the root block.
<H2>Return values</H2>
The Volume, NULL in case of error.
<H2>Internals</H2>
<OL>
<LI>Read the bootblock to determine <I>vol->dosType</I>
and <I>vol->datablockSize</I>.
<LI>Read the rootblock, fills <I>vol->curDirPtr</I>
<LI>Read and allocate the bitmap : <I>vol->bitmapBlocks[],
vol->bitmapTable[], vol->bitmapSize, vol->bitmapBlocksChg[]</I>.
</OL>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfUnMount() </FONT></P>
<H2>Syntax</H2>
<B>void</B> adfUnMount(<B>struct Volume *</B>vol)
<H2>Description</H2>
Release a Volume. Free the bitmap structures.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfCountFreeBlocks() </FONT></P>
<H2>Syntax</H2>
<B>long</B> adfCountFreeBlocks(<B>struct Volume *</B>vol)
<H2>Description</H2>
Counts the free blocks of a Volume.
<H2>Return values</H2>
The number of free blocks.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfInstallBootBlock() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfInstallBootBlock(<B>struct Volume*</B> vol, <B>unsigned char*</B> code)
<H2>Description</H2>
Install a bootblock on a floppy disk. Won't work on any other device.
<P>
You must provide the 1024 bytes large bootblock.<BR>
Doesn't modify the initial 'DOS' header and dosType. Recalculates the checksum.
<H2>Return values</H2>
RC_OK, something different in case of error.
<P>
<HR>
<P ALIGN=CENTER><FONT SIZE=+2> adfCreateHdFile() </FONT></P>
<H2>Syntax</H2>
<B>RETCODE</B> adfCreateHdFile(<B>struct Device*</B> dev, <B>char*</B> volName, <B>int</B> volType)
<H2>Description</H2>
Create an hardfile on a dump file. The size of this file must be larger
than 1802240 bytes, the size of an high density floppy dump.
<P>
Use adfCreateDumpDevice() the create the device passed to adfCreateHdFile().
<H2>Return values</H2>
RC_OK, something different in case of error.
<H2>Internals</H2>
The device is created with one volume, and <I>dev->devType if filled with
DEVTYPE_HARDFILE.
<P>
<HR>
</BODY>
</HTML>

View File

@@ -0,0 +1,70 @@
ADFLib changes - Wednesday 16/10/02
-----------------------------------
Background
----------
Bjark Viksoe changed ADFLib 0.7.9b in or before December 2001. Experimental
version sent to me by Laurent in December 2001, soon to be released as 0.7.9c.
Changes tried with ADFOpus then put aside due to difficulties compiling.
Successfully tried again in October 2002, having neither heard anything more
from Laurent nor seen a later version at the web site.
Bjark Viksoe's changes removed the dynamic projects and changed a number of
parameters such as where compiled files were stored. These were potentially not
portable and operated outside the compilation directory e.g. "..\..\AdfLib...",
"C:\Temp".
Laurent's original settings were slightly at odds with common VC++ practice i.e. Win32
and Debug directories used for compiled files rather than Release and Debug; Debug
executables used Release libs rather than debug versions.
Enter Gary with a shiny version of ADF Opus to release and a desire to release it with
a clean and equally shiny ADFLib 0.7.9c distribution.
Method
------
I started with a clean installation of ADFLib 0.7.9b. Loading this into VC++ 6 SP5
updated the project and workspace files to VC++ 6 versions. Next, I unpacked a clean
installation of the potential 0.7.9c version received from Laurent. I then used WinDiff
to determine exactly what changes Bjark had made and manually edited the 0.7.9b files
to match.
Changes
-------
-Reinstated dynlib, dynunadf and staticunadf by starting with V0.7.9b.
-Returned to original ADFLib compilation settings as above, then made some subtle changes.
-Release output files now go to Bin/Win32/Release, rather than Bin/Win32, for
symmetry and standardisation. Intermediate files still go to Release and Debug.
-Debug dynunadf and staticunadf now use the debug libs, not the release ones,
to allow full debugger access.
-Fixed a path setting problem which caused a failure to find adflibd.lib.
-Changed Bjark's setting of "C7 Compatible" back to "Program Database for Edit and Continue"
for consistency with the other projects.
-Annotated Bjark's changes with /* BV */ for easy identification.
-Removed C++ comment tags and replaced them with C tags across the board. ADFLib should
hopefully be pure C again now.
-Removed a change implemented for Opus which was inadvertantly left in during earlier updates
i.e. a string added to struct nativeDevice in adf_nativ.h.
-Updated Laurent's copyright on every page to include 2002.
-Updated the version and date strings to:
#define ADFLIB_VERSION "0.7.9c"
#define ADFLIB_DATE "16 October, 2002"
-Everything compiles cleanly with no warnings. :-)
-Bjark's changes appear to support non-standard FD ADFs up to 83 tracks. Can we confirm this?