
/*
 *@@sourcefile module.c:
 *      contains DLL management functions which are called when
 *      xfldr.dll is loaded and released. This is needed because
 *      XFolder needs the module handle and the full path of
 *      xfldr.dll all the time.
 *
 *      This file is all new with V0.81.
 *
 *      NOTE: I don't know if all compilers will accept this file.
 *      It does compile with VisualAge C++ 3.0.
 *      _DLL_InitModule is not a standard C function. I have found
 *      it in the EMX docs however, so it might work with EMX too.
 *
 *      The main thing is that the mod* functions at the bottom
 *      must return the module handle and the full path of the
 *      xfldr.dll file, or XFolder will not work. If you find any
 *      other way for this to work, that's fine too.
 *
 *@@include #define  INCL_DOSMODULEMGR
 *@@include #include <os2.h>
 *@@include #include "module.h"
 */

/*
 *      This code is based on the SAMPLE03 from VisualAge C++ 3.0.
 *      This file Copyright (C) 1997-99 Ulrich M”ller.
 *      This file is part of the XFolder source package.
 *      XFolder is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published
 *      by the Free Software Foundation, in version 2 as it comes in the
 *      "COPYING" file of the XFolder main distribution.
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 */

#define  INCL_DOSMODULEMGR
#define  INCL_DOSPROCESS
#include <os2.h>

#include <locale.h>

// Global variables:
char        szDLLFile[CCHMAXPATH];
HMODULE     hmodDLL;

// Declare prototypes, because there are no headers
// for these:

// _CRT_init is the C run-time environment initialization function.
// It will return 0 to indicate success and -1 to indicate failure.
int _CRT_init(void);

// _CRT_term is the C run-time environment termination function.
// It only needs to be called when the C run-time functions are statically
// linked, as is the case with XFolder.
void _CRT_term(void);

/*
 *@@ _DLL_InitTerm:
 *     this function gets called when the OS/2 DLL loader loads and frees
 *     this DLL. Since this is a SOM DLL for the WPS, this gets called
 *     right when the WPS is starting and when the WPS process ends, e.g.
 *     due to a WPS restart or trap. Since the WPS is the only process
 *     calling this DLL, we need not bother with details.
 *     Since OS/2 calls this function directly, it must have _System linkage.
 *     Note: You must then link using the /NOE option, because the VAC++ runtimes
 *     also contain a _DLL_Initterm, and the linker gets in trouble otherwise.
 *     The XFolder makefile takes care of this.
 *     This function returns 0 upon errors or 1 otherwise.
 */

unsigned long _System _DLL_InitTerm(unsigned long hModule,
                                    unsigned long ulFlag)
{
    APIRET rc;

    switch (ulFlag) {
        case 0 :
            // DLL being loaded:

            // store the DLL handle in the global variable so that
            // modQueryHandle() below can return it
            hmodDLL = hModule;

            // now initialize the C run-time environment before we
            // call any runtime functions
            if (_CRT_init() == -1)
               return (0);  // error

            // set the locale for the run-time environment. This
            // will affect string sorting, upper and lower case,
            // and much more, by reading in the LANG environment
            // variable, which OS/2 puts into CONFIG.SYS per default.
            setlocale(LC_ALL, "");

            if (rc = DosQueryModuleName(hModule, CCHMAXPATH, szDLLFile))
                    DosBeep(100, 100);
        break;

        case 1:
            // DLL being freed: cleanup runtime
            _CRT_term();
            break;

        default:
            // other code: beep for error
            DosBeep(100, 100);
            return (0);     // error
    }

    // a non-zero value must be returned to indicate success
    return (1);
}

/*
 *@@ modQueryHandle:
 *      this may be used to retrieve the DLL handle
 *      which was stored by _DLL_InitTerm.
 */

HMODULE modQueryHandle(VOID)
{
    return (hmodDLL);
}

/*
 *@@ modQueryFile:
 *      this may be used to retrieve the fully
 *      qualified file name of the DLL
 *      which was stored by _DLL_InitTerm.
 */

PSZ modQueryFile(VOID)
{
    return (szDLLFile);
}

