/***********************************************************************/
/*                  Scanner Driver ToolKit                             */
/*                   C Driver Program                                  */
/***********************************************************************/

#include <dos.h>
#include "scandrv.h"

/* Hand Held Scanner driver function code define */
#define  GetParameters    0x00
#define  SetParameters    0x01
#define  StartScan        0x02
#define  StopScan         0x03

/* Note: Microsoft C Complier User 
   Structure are word aligned; structures of odd size are padded to an
   even number of bytes in default setting.
   So use the /Zp complier option to specify the same packing size */

typedef struct
{
    char function;
    LPSTR lpParamPacket;
    LPSTR lpDataPacket;
} CB;
typedef CB	 *PCB;
typedef CB near *NPCB;
typedef CB far	*LPCB;

/* DOS constants */
#define OPENFILE     0x3D
#define CLOSEFILE    0x3E
#define IOCTL        0x44
#define SYSCALL      0x21
#define NULLF        0L

/* Local Function Proto Type */
LOCAL short ScanIOCTL(void);

LOCAL CB cbParameter = { '\0', NULLF, NULLF };
LOCAL unsigned short wDrvHandle = 0;

short ScanOpen()
{
    union REGS inregs, outregs;
    struct SREGS segregs;
    LPSTR lpTmp;
    LOCAL char *szDrvName = "PRO$SCAN";
    
    lpTmp = (LPSTR)szDrvName;
    
    inregs.h.ah = OPENFILE;
    inregs.h.al = 2;			/* read & write */
    inregs.x.dx = FP_OFF (lpTmp);
    segregs.ds	= FP_SEG (lpTmp);
    int86x (SYSCALL, &inregs, &outregs, &segregs);
    wDrvHandle = outregs.x.ax;
    return (!outregs.x.cflag);
}

short ScanClose()
{
    union REGS inregs, outregs; 

    inregs.h.ah = CLOSEFILE;
    inregs.x.bx = wDrvHandle;
    int86 ( SYSCALL, &inregs, &outregs );
    return ( !outregs.x.cflag );
}

short ScanGetParameters( LPGETPB lpgetpbParameters )
{
    cbParameter.function = GetParameters;
    cbParameter.lpParamPacket = NULLF;
    cbParameter.lpDataPacket  = (LPSTR)lpgetpbParameters;
    return (ScanIOCTL());
}

short ScanSetParameters( LPSETPB lpsetpbParameters )
{
    cbParameter.function = SetParameters;
    cbParameter.lpParamPacket = (LPSTR)lpsetpbParameters;
    cbParameter.lpDataPacket  = NULLF;
    return (ScanIOCTL());
}

short ScanStart ( LPSS lpssScanBuf, LPSP far *lplpspScanPos)
{    
    cbParameter.function = StartScan;
    cbParameter.lpParamPacket = (LPSTR)lpssScanBuf;
    cbParameter.lpDataPacket  = (LPSTR)lplpspScanPos;
    return (ScanIOCTL());
}    

short ScanStop ()
{    
    cbParameter.function = StopScan;
    cbParameter.lpParamPacket = NULLF;
    cbParameter.lpDataPacket  =  NULLF;
    return (ScanIOCTL());
}    

LOCAL short ScanIOCTL()
{
    union REGS inregs, outregs;
    struct SREGS segregs;
    LPSTR lpTmp;
    
    lpTmp = (LPSTR) &cbParameter;
    
    inregs.h.ah = IOCTL;
    inregs.h.al = 3;		/* SEND CONTROL DATA */
    inregs.x.bx = wDrvHandle;
    inregs.x.cx = sizeof(CB);
    inregs.x.dx = FP_OFF (lpTmp);
    segregs.ds  = FP_SEG (lpTmp);
    int86x (SYSCALL, &inregs, &outregs, &segregs);
    return (!outregs.x.cflag);
}

