/* ------------------------------------------------------------------------ */
/*  @@ Usage                                           *** C Version ***    */
/*                                                                          */
/*  Copyright (c) Creative Technology Ltd, 1993. All rights reserved.       */
/*                                                                          */
/*   char far * sbkLoadDriver (char *szDrvName, WORD wEmbedBuffer,          */
/*                             char FAR ** lpOrigin)                        */
/*                                                                          */
/*   DESCRIPTION:                                                           */
/*       Loads driver into memory with the driver name specified. The       */
/*       driver is always loaded into the offset 0 of a segement.           */
/*                                                                          */
/*   ENTRY:                                                                 */
/*       szDrvName      - Driver name to be loaded.                         */
/*       wEmbedBuffer   - zero     : UNUSED or load the driver with         */
/*                                   embedded DMA buffer.                   */
/*                        non-zero : to load the actual size of the driver  */
/*                                   (without embedded DMA buffer).         */
/*                                                                          */
/*                        Note that this argument only applicable to        */
/*                        Creative Voice drivers CTVDSK.DRV and             */
/*                        CT-VOICE.DRV.                                     */
/*                                                                          */
/*       lpOringin      - Original memory pointer before segment            */
/*                        adjustment. This pointer is stored for freeing    */
/*                        driver buffer.                                    */
/*                                                                          */
/*   EXIT:                                                                  */
/*       Pointer to the loaded driver if successful, else returns NULL      */
/*                                                                          */
/* ------------------------------------------------------------------------ */

#include  <dos.h>
#include  <stdio.h>
#include  <stdlib.h>
#include  <fcntl.h>
#include  <string.h>
#include  <io.h>
#include  <errno.h>

#include  "ctstddef.h"
#include  "sbkvoice.h"
#include  "sbkmacro.h"
#include  "sbkx.h"


/* function prototype */
char FAR * sbkLoadDriver (char *szDrvName,WORD wEmbedBuffer, char FAR ** lpRelease);


char FAR * sbkLoadDriver (char *szDrvName,WORD wEmbedBuffer, char FAR ** lpRelease)
{
    char    FAR *lpPtr, FAR *lpDrvPtr = 0 ;
    char    szDrvFile[100] ;
    char    *pPtr ;
    int     Handle = 1, fExit ;
    WORD    wTemp ;
    DWORD   dwDrvSize ;


#if _MSC_VER
    struct find_t   stFile ;
#elif __TURBOC__
    struct ffblk    stFile ;
#endif


    /* locate driver through environment parameter */
    if ((pPtr = getenv("SOUND")) != NULL)
    {
        strcat(strcpy(szDrvFile,pPtr),"\\DRV\\") ;
        strcat(szDrvFile,szDrvName);

        /* handle set to 0, if found */
        Handle = sbkFindFirst(szDrvFile,&stFile) ;
    }

    /* locate driver in current directory */
    if (Handle != 0)
    {
        strcpy(szDrvFile,szDrvName) ;

        /* handle set to 0, if found */
        Handle = sbkFindFirst(szDrvFile,&stFile) ;
    }

    if (Handle != 0)
        printf("\nDriver file %s does not exist.",szDrvName) ;
    else
    {
        if ((Handle = sbkDosOpen(szDrvFile)) == -1)
            printf("Open %s error.\n",szDrvFile) ;
        else
        {
            dwDrvSize = filelength(Handle) ;

            fExit = 0 ;

            while (!fExit)
            {
                if ((lpDrvPtr = sbkAllocMem((DWORD)(dwDrvSize + 15l))) != NULL)
                {
                    /* store the original allocated buffer */
                    *lpRelease = lpDrvPtr ;

                    FPSEG(lpDrvPtr) += ((FPOFF(lpDrvPtr) + 15) >> 4) ;
                    FPOFF(lpDrvPtr) = 0 ;

                    lpPtr = lpDrvPtr;

                    if (sbkDosRead(Handle,lpPtr,(WORD)dwDrvSize,(WORD FAR *)&wTemp))
                    {
                        lpDrvPtr = 0 ;
                        wEmbedBuffer = UNUSED ;
                    }

                    if (wEmbedBuffer)
                    {
                        lseek(Handle,0L,SEEK_SET) ;
                        strupr(szDrvName) ;

                        if (!strcmp(szDrvName,"CT-VOICE.DRV"))
                        {
                            /* init CT-VOICE driver entry point */
                            voice_drv = lpDrvPtr ;
                            /* get actual driver size */
                            if (ctvmGetParam(CTVOC_DRIVERSIZE,
                                    (DWORD FAR *)&dwDrvSize))
                            {
                                printf("\nError retrieving driver size.") ;
                                fExit = 1 ;
                            }
                        }
                        else if (!strcmp(szDrvName,"CTVDSK.DRV"))
                        {
                            /* init CTVDSK.DRV driver entry point */
                            ctvdsk_drv = lpDrvPtr;
                            /* get actual driver size */
                            if (ctvdGetParam(CTVOC_DRIVERSIZE,
                                    (DWORD FAR *)&dwDrvSize))
                            {
                                printf("\nError retrieving driver size.") ;
                                fExit = 1 ;
                            }
                        }
                        else
                            break ;

                        /* free pre-loaded driver */
                        sbkFreeMem(*lpRelease) ;
                        lpDrvPtr = 0 ;
                        wEmbedBuffer = UNUSED ;
                    }
                    else
                    {
                        /* free pre-loaded driver */
                        if (lpDrvPtr == 0)
                            sbkFreeMem(*lpRelease) ;
                        fExit = 1 ;
                    }
                }
                else
                {
                    printf("Memory allocation error\n");
                    fExit = 1 ;
                }
            }
            sbkDosClose(Handle) ;
        }
    }
    return(lpDrvPtr) ;
}
/* End of file */
