/*-
 * getdevinfo.c - get filesystem information about a disk device
 *
 * DiskChecker 1.0 Copyright 1989 C. Harald Koch. All Rights Reserved.
 *
-*/

#include	"libraries/dos.h"
#include	"libraries/dosextens.h"
#include	"libraries/filehandler.h"
#include	<exec/memory.h>

#include	<ctype.h>
#include	<stdio.h>

#include	"devinfo.h"

extern struct DosLibrary *DOSBase;
extern void    *AllocMem();

#define CTOB(x) (void *)(((long)(x))>>2)	/* BCPL conversion */
#define BTOC(x) (void *)(((long)(x))<<2)

touppers(s)
char           *s;
{
    while (*s) {
	*s = (islower(*s)) ? toupper(*s) : *s;
	s++;
    }
}

void
BtoCStr(cstr, bstr)
char           *cstr;
BPTR            bstr;
{
    char           *bstr2;
    int             i;

    bstr2 = BTOC(bstr);
    for (i = 0; i < bstr2[0]; i++) {
	cstr[i] = bstr2[i + 1];
    }
    cstr[i] = '\0';
}


struct MyDevInfo *
getDevInfo(name)
char           *name;
{
    struct RootNode *root;
    struct DosInfo *info;
    struct DeviceNode *dnode;
    struct FileSysStartupMsg *fsmsg;
    struct DosEnvec *env;
    long            unit;
    char            dosname[20];
    char            execname[256];
    long            flags;
    struct MyDevInfo *mdi;
    root = (struct RootNode *) DOSBase->dl_Root;
    info = (struct DosInfo *) BTOC(root->rn_Info);
    dnode = (struct DeviceNode *) BTOC(info->di_DevInfo);

    for (; dnode != NULL;) {
	if (dnode->dn_Type == DLT_DEVICE) {
	    BtoCStr(dosname, dnode->dn_Name);
	    if (strcmp(name, dosname) == 0) {
		/* found it! */
		fsmsg = (struct FileSysStartupMsg *) BTOC(dnode->dn_Startup);
		if (fsmsg != NULL) {
		    char           *bcplname;
		    long            namelen;

		    mdi = AllocMem(sizeof(*mdi), MEMF_CLEAR);
		    bcplname = BTOC(fsmsg->fssm_Device);
		    namelen = bcplname[0] + 1;
		    mdi->DeviceName = AllocMem(namelen, 0L);
		    BtoCStr(mdi->DeviceName, fsmsg->fssm_Device);
		    mdi->Unit = fsmsg->fssm_Unit;
		    mdi->DeviceFlags = fsmsg->fssm_Flags;
		    env = BTOC(fsmsg->fssm_Environ);
		    mdi->BlockSize = env->de_SizeBlock * 4;
		    mdi->Surfaces = env->de_Surfaces;
		    mdi->BlocksPerTrack = env->de_BlocksPerTrack;
		    mdi->Reserved = env->de_Reserved;
		    mdi->PreAlloc = env->de_PreAlloc;
		    mdi->LowCyl = env->de_LowCyl;
		    mdi->HighCyl = env->de_HighCyl;
		    if (env->de_TableSize >= 12) {
			mdi->BufMemType = env->de_BufMemType;
		    }
		    else {
			mdi->BufMemType = MEMF_CHIP;
		    }
		    if (env->de_TableSize >= 16) {
			mdi->DosType = env->de_DosType;
		    }
		    else {
			mdi->DosType = 0x444f5300;
		    }

		    return mdi;
		}
	    }
	}
	dnode = (struct DeviceNode *) BTOC(dnode->dn_Next);
    }
    return NULL;
}
