# the Native API

# Introduction

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).
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.

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.

The templates for those files are in Generic/.

The native API consists of :

1. The natives functions :

- RETCODE adfInitDevice(struct Device*, char*)
- RETCODE adfReleaseDevice(struct Device*)
- RETCODE adfNativeReadSector(struct Device*, long, int, unsigned char*)
- RETCODE adfNativeWriteSector(struct Device*, long, int, unsigned char*)
- BOOL adfIsDevNative(char*)
- void adfInitNativeFct()

2. And two data structures devoted to native devices management :

- struct nativeFunctions stored in the library environment,
- struct nativeDevice stored in the struct Device structure.

The author of the driver defines the nativeDevice structure and writes the expected functions below, with the expected parameters and the expected behaviours.

At the environment initialisation, a pointer of each function is stored in the nativeFunctions structure with adfInitNativeFct().

Here's how, for example, adfMountDev() call a native function : adfInitDevice() :

    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);

    ...

# Data structures

    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 */
    };

adfInitDevice()

## Syntax

RETCODE adfInitDevice(struct Device* device, char* name)

You can choose another name, but the same parameters types and number, and the same return type.

## Description

Initialise the native device.

## Return values

RC_OK if everything went alright, something else otherwise.

## Template

    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;
    }

adfNativeReadSector()

## Syntax

RETCODE adfNativeReadSector(struct Device* device, long n, int size, unsigned char* buf)

You can choose another name, but the same parameters types and number, and the same return type.

## Description

Move to 512*n bytes from the beginning of the media, and read size bytes into the buf buffer.

adfNativeWriteSector()

## Syntax

RETCODE adfNativeWriteSector(struct Device* device, long n, int size, unsigned char* buf)

You can choose another name, but the same parameters types and number, and the same return type.

## Description

Move to 512*n bytes from the beginning of the media, and write size bytes into the buf buffer.

adfReleaseDevice()

## Syntax

RETCODE adfReleaseDevice(struct Device* device)

You can choose another name, but the same parameters types and number, and the same return type.

## Description

Release the device.

adfIsDevNative()

## Syntax

RETCODE adfIsDevNative(char* name)

You can choose another name, but the same parameters types and number, and the same return type.

## Description

TRUE is the name points out a native device, FALSE otherwise.

adfInitDevice()

## Syntax

RETCODE adfInitDevice(struct Device* device, char* name)

You can choose another name, but the same parameters types and number, and the same return type.

## Description

Initialise the nativeFunctions structure with the native functions addresses.