# the Device API

# Use cases

- Mounting volume of a existing device (ADF dump or real one) :
  1. adfMountDev()
  2. adfMount()
  3. adfUnMount()
  4. adfUnMountDev()

- Creating an ADF dump of a floppy :
  1. adfCreateDumpDevice()
  2. adfCreateFlop()
  3. adfMount()
  4. adfUnMount()
  5. adfUnMountDev()

- Creating an ADF dump of a harddisk :
  1. adfCreateDumpDevice()
  2. adfCreateHd()
  3. adfMount()
  4. adfUnMount()
  5. adfUnMountDev()

- Creating an new filesystem for an harddisk on a real device :
  1. adfMountDev()
  2. adfCreateHd()
  3. adfMount()
  4. adfUnMount()
  5. adfUnMountDev()

# Data structures

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.

The dynamic memory allocation/releasing is done by the library (i hope :).

    struct AdfDevice {
        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 adfVolume ** volList;     /* volumes */

        long                cylinders,   /* device geometry */
                            heads,
                            sectors;

        BOOL                isNativeDev;
        void *              nativeDev;   /* native specific and private structure */
    }

The Partition structure is used with adfCreateHd().

    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 characteristics : use the flags FSMASK_FFS,
                                FSMASK_INTL and FSMASK_DIRCACHE                     */

    }

adfMountDev()

## Syntax

struct adfDevice* adfMountDev( char* name)

## Description

Mounts a device. The name could be a filename for an ADF image ("dump"), or a real device name like "|F:" for the Win32 F: partition or "/dev/sdf1" for a Linux partition.
The real device name is platform dependent.

## Return values

NULL if an error occurs, an AdfDevice structure pointer otherwise.

## Internals

1. Allocation of struct AdfDevice *dev
2. Calls adfIsNativeDev() to determine if the name point out a ADF dump or a real (native) device. The field dev->isNativeDev is filled.
3. Initialize the (real or dump) device. The field dev->size is filled.
4. dev->devType is filled.
5. The device is mounted : dev->nVol, dev->volList[], dev->cylinders, dev->heads, dev->sectors are filled.
6. dev is returned

Warning, in each dev->volList[i] volumes (vol), only vol->volName (might be NULL), vol->firstBlock, vol->lastBlock and vol->rootBlock are filled !

## See also

struct AdfDevice, real (native) devices

## Files

Real devices allocation : adf_nativ.c, adf_nativ.h
ADF allocation : adf_dump.c, adf_dump.h

adfUnMountDev()

## Syntax

void adfUnMountDev( struct AdfDevice* dev)

## Description

Releases a Device and frees related resources.

## Internals

1. Frees dev->volList[]
2. Releases the ADF dump or real (native) device : call the suited function.

adfCreateHd()

## Syntax

RETCODE adfCreateHd(struct AdfDevice* dev, int nPart, struct Partition* *partList )

## Description

Create the filesystem of a device which will be used as an Harddisk. AdfMount() must be used after to mount a volume (partition).

In case of a new ADF dump, adfCreateDumpDevice() must be called before to create an empty media of the right size.

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.

## Return values

RC_OK, or Something different in case of error.

## Examples

Creation of an ADF Zip disk dump :

    struct Partition part1;
    struct Partition **partList;

    /* Env init */

    /* cyl = 2891, heads = 1, sectors = 68 */
    struct AdfDevice * 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 */
    RETCODE 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 */

## Internals

1. Creates and fill dev->volList[]
2. Creates the Harddisk header structures on the media. It uses usually the 2 first cylinders of the device.

adfCreateFlop()

## Syntax

RETCODE adfCreateFlop(struct AdfDevice* dev, char* volName, int volType )

## Description

Creates the filesystem of a DD or HD floppy. AdfMount() must be used after to mount the only volume.

In case of a new ADF dump, adfCreateDumpDevice() must be called before to create an empty media of the right size.

An Harddisk ADF dump created with ADFlib -can be- used back by the AmigaDOS.

## Return values

RC_OK, or Something different in case of error.

## Examples

    struct AdfDevice *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 */

## Internals

1. Allocation of dev->volList[]. It contains one volume.
2. Creation of the volume

ADF only : adfCreateDumpDevice()

## Syntax

struct AdfDevice* adfCreateDumpDevice(char* filename, long cyl, long heads, long sect)

## Description

Create a file of the right size, and fills some fields of the Device structure. Must be followed by adfCreateFlop() and adfCreateHd().

## Return values

the AdfDevice, NULL in case of error.

## Examples

See adfCreateFlop() and adfCreateHd() examples.

## Internals

1. Allocate struct AdfDevice* dev
2. Allocate dev->nativeDev
3. Create an empty file with a size equals to : cyl*heads*sect*512.
4. Open this file with "rb+" mode
5. Fills dev->cylinders, dev->heads, dev->sectors, dev->size, dev->devType, and dev->nVol = 0.
6. Returns dev