Source file: /~heha/argon/multimed.zip/SNDBLST/INITC.C

/****************************************************************************
 *
 *   initc.c
 *
 *   Copyright (c) 1991-1992 Microsoft Corporation.  All Rights Reserved.
 *
 ***************************************************************************/

#include <windows.h>
#include <mmsystem.h>
#include <mmddk.h>
#define NOSTR  /* to avoid redefining strings */
#include "sndblst.h"

#define DEF_MIDIINPERSISTENCE   50      /* default MIDI in persistence factor */

/*****************************************************************************

    internal function prototypes

 ****************************************************************************/ 

static WORD NEAR PASCAL GetProfileHex(LPSTR szApp, LPSTR szEntry, WORD wDef);

/****************************************************************************

    strings

    most strings are only accessed at init time, so they will be placed
    in the _INIT code segment.

 ***************************************************************************/

#define BCODE _based(_segname("_CODE"))
#define BDATA _based(_segname("_DATA"))

/* non-localized strings */
char BCODE STR_PORT[]           = "port";
char BCODE STR_INT[]            = "int";
char BCODE STR_DRIVERNAME[]     = "sndblst.drv";
char BCODE STR_INIFILE[]        = "system.ini";
char BCODE STR_PRODUCTNAME[]    = "Sound Blaster";
static char BCODE STR_NULL[]        = "";
static char BCODE STR_DMACHANNEL[]  = "dmachannel";
static char BCODE STR_PERSISTENCE[] = "midiinpersistence";
static char BCODE STR_NOWARNING[]   = "nowarning";
static char BCODE STR_VERIFYINT[]   = "verifyint";
static char BCODE STR_EVILTWIN[]    = "SNDBLST1";

#ifdef DEBUG
    static char BCODE STR_SNDBLST[] = "sndblst";
    static char BCODE STR_MMDEBUG[] = "mmdebug";

    /* these strings are accessed at interrupt time, so they must be in */
    /* the fixed DS */
    char BDATA STR_CRLF[]       = "\r\nSNDBLST: ";
    char BDATA STR_SPACE[]      = " ";
#endif

/****************************************************************************

    public data

 ***************************************************************************/

HANDLE  ghModule        = NULL;         /* our module handle */
WORD    gwErrorStringId = 0;            /* if initialization fails, string id */
BYTE    gfVerifyInt     = FALSE;

#ifdef DEBUG
WORD    wDebugLevel = 0;        /* debug level */
#endif

/***************************************************************************
 * @doc INTERNAL
 *
 * @api WORD | GetProfileHex | Get a profile hex value.
 *
 * @parm LPSTR | szAppName | The app name.
 *
 * @parm LPSTR | szEntry | The entry name.
 *
 * @parm WORD | wDefault | The default value.
 *
 * @rdesc Returns the profile value or the default if none is present.
 ***************************************************************************/
static WORD NEAR PASCAL GetProfileHex(LPSTR szApp, LPSTR szEntry, WORD wDef)
{
BYTE  buf[20];
WORD  n;
BYTE  b;
int   i;

    n = GetPrivateProfileString(szApp, szEntry, STR_NULL, buf, sizeof(buf), STR_INIFILE);
    if (n < 1) return wDef;

    for (n = 0, i = 0; b = buf[i]; i++) {
        if (b > 'Z') b -= 'a' - 'A';
        b -= '0';
        if (b > 9) b -= 7;
        if (b > 15)
            break;
        n = n * 16 + b;
    }
    return n;
}

/***************************************************************************
 * @doc INTERNAL
 *
 * @api WORD | ConfigGetPortBase |
 *
 * @rdesc Returns the port base from SYSTEM.INI
 ***************************************************************************/
WORD NEAR PASCAL ConfigGetPortBase(void)
{
WORD    wPort;

    /* read szIniFile and get the board configuration information. */

    wPort = GetProfileHex(STR_DRIVERNAME, STR_PORT, -1);
    switch (wPort) {
        case 0x200:
        case 0x210:
        case 0x220:
        case 0x230:
        case 0x240:
        case 0x250:
        case 0x260:
        case 0x270:
            break;

        default:
            wPort = -1;
            D1("driver PORT not configured");
    }

    return (wPort);
}


/***************************************************************************
 * @doc INTERNAL
 *
 * @api WORD | ConfigGetIRQ |
 *
 * @rdesc Returns the IRQ ('int') from SYSTEM.INI
 ***************************************************************************/
BYTE NEAR PASCAL ConfigGetIRQ(void)
{
BYTE    bInt;

    bInt = (BYTE)GetPrivateProfileInt(STR_DRIVERNAME, STR_INT, -1, STR_INIFILE);

    switch (bInt) {
        case 3:
        case 5:
        case 7:
        case 9:
        case 10:
            break;

        case 2:
            bInt = 9;
            break;

        default:
            bInt = -1;
            D1("driver INT not configured");
            break;
    }

    return (bInt);
}


/***************************************************************************
 * @doc INTERNAL
 *
 * @api WORD | ConfigGetDMAChannel |
 *
 * @rdesc Returns the DMA channel from SYSTEM.INI
 ***************************************************************************/
BYTE NEAR PASCAL ConfigGetDMAChannel(void)
{
BYTE    bDMAChannel;

    /* get the DMA channel that the card is using... */
    bDMAChannel = (BYTE)GetPrivateProfileInt(STR_DRIVERNAME, STR_DMACHANNEL,
                                -1, STR_INIFILE);

    switch (bDMAChannel) {
        case 0:
        case 1:
        case 3:
            break;

        default:
            bDMAChannel = 1;
    }

    return (bDMAChannel);
}

/***************************************************************************/

static WORD NEAR PASCAL GetWindowsVersionCorrectly()
{
WORD w;

    w = LOWORD(GetVersion());

    return (w << 8) | (w >> 8);
}

/***************************************************************************/

static void NEAR PASCAL HardErrorMsgBox(WORD wStringId)
{
char szErrorBuffer[MAX_ERR_STRING]; /* buffer for error messages */

    /*  Starting with Windows 3.1, it is ok to bring up a _hard system modal_ */
    /*  message box during LibInit.  In Windows 3.0, this will not work! */
    if (GetWindowsVersionCorrectly() >= 0x30A) {
        LoadString(ghModule, wStringId, szErrorBuffer, sizeof(szErrorBuffer));
        MessageBox(NULL, szErrorBuffer, STR_PRODUCTNAME, MB_OK|MB_SYSTEMMODAL|MB_ICONHAND);
    }
}

BOOL FAR PASCAL InitDisplayConfigErrors(void)
{
char szErrorBuffer[MAX_ERR_STRING]; /* buffer for error messages */

    if (gwErrorStringId) {
        LoadString(ghModule, gwErrorStringId, szErrorBuffer, sizeof(szErrorBuffer));
        MessageBox(NULL, szErrorBuffer, STR_PRODUCTNAME, MB_OK|MB_SYSTEMMODAL|MB_ICONHAND);
        gwErrorStringId = 0;
    }

    return TRUE;
}

/****************************************************************************
 * @doc INTERNAL
 *
 * @api int | LibMain | Library initialization code.
 *
 * @parm HANDLE | hModule | Our module handle.
 *
 * @parm WORD | wHeapSize | The heap size from the .def file.
 *
 * @parm LPSTR | lpCmdLine | The command line.
 *
 * @rdesc Returns 1 if the initialization was successful and 0 otherwise.
 ***************************************************************************/
int NEAR PASCAL LibMain(HANDLE hModule, WORD wHeapSize, LPSTR lpCmdLine)
{
WORD    wPort;
BYTE    bInt;
BYTE    bDMAChannel;
WORD    wMidiInPersistence;
WORD    wError;
DWORD   dw;

#ifdef DEBUG
    /* get debug level - default is 0 */
    wDebugLevel = GetProfileInt(STR_MMDEBUG, STR_SNDBLST, 0);
#endif

    D1("LibMain");

    /* save our module handle */
    ghModule = hModule;

    /* we have a good chance of hanging if two sound blaster drivers are */
    /* enabled */
    if (GetModuleHandle(STR_EVILTWIN)) {
        D1("EVIL TWIN SNDBLST1 LOCATED!!  WE WILL NOT ENABLE!!!");
        wError = IDS_ERRTWODRIVERS;
        goto libmain_Severe_Error;
    }

    /* do preliminary stuff--and check for hardware problems... */
    if (wError = InitPreliminary())
        goto libmain_Severe_Error;


    /* get the DMA channel that the card is using... */
    wPort = ConfigGetPortBase();
    bInt = ConfigGetIRQ();
    bDMAChannel = ConfigGetDMAChannel();

    /* over-ride switch in case someone has problems... */
    gfVerifyInt = (BYTE)GetPrivateProfileInt(STR_DRIVERNAME, STR_VERIFYINT, 1, STR_INIFILE);


    /* verify port, IRQ, DMA channel and DSP version
     *
     *  The return value is:
     *      LOWORD() =  error code. it is 0 if no error, otherwise it is
     *                  the IDS_xxxxxx error define (and hi-word will be
     *                  zero).
     *      HIWORD() =  DSP version.
     */
    dw = InitVerifyConfiguration(wPort, bInt, bDMAChannel);

    /* was there an error? */
    if (LOWORD(dw)) {
        /*  display error, but allow load to succeed.  we will NOT enable,
         *  but we need to allow someone to configure us in the drivers applet.
         */
        gwErrorStringId = IDS_ERRBADCONFIG;
        return 1;
    }

    /*  iff the DSP version is too old, then do NOT load driver! otherwise */
    /*  let it be loaded so it can be configured (but not enabled). */
    wError = HIWORD(dw);
    if (wError < DSP_VERSION_REQD) {
        wError = IDS_ERRBADVERSION;

libmain_Severe_Error:

        /* display error and FAIL to load... */
        HardErrorMsgBox(wError);
        return 0;
    }

    /* get MIDI input persistence... */
    wMidiInPersistence = GetPrivateProfileInt(STR_DRIVERNAME, STR_PERSISTENCE,
                                DEF_MIDIINPERSISTENCE, STR_INIFILE);

    /* set the configuration */
    InitSetConfiguration(wPort, bInt, bDMAChannel, wMidiInPersistence);

    /* load driver (but maybe not enable if configuration is wrong). */
    return 1;
}
Detected encoding: ASCII (7 bit)2