/********************** START OF SPECIFICATIONS *****************************/
/*                                                                          */
/* SOURCE FILE NAME: IOPRNLS.C                                              */
/*                                                                          */
/* DESCRIPTIVE NAME: IOproc National Language string retrieval              */
/*                                                                          */
/* COPYRIGHT:               IBM Confidential                                */
/*                  Copyright (c) IBM Corporation 1993                      */
/*                         All Rights Reserved                              */
/*                                                                          */
/* STATUS: OS/2 MM Release 1.10                                             */
/*                                                                          */
/* FUNCTION: This file produces a single .obj file that can be linked       */
/*           to application modules for access to the ioprnls.dll.          */
/*           The routines in this module look up NLS translated strings     */
/*           on behalf on the user module.  The strings are stored in the   */
/*           resource only DLL.  This file is not used to produce the DLL.  */
/*                                                                          */
/* NOTES:                                                                   */
/*    DEPENDENCIES: IOPRNLS.DLL must reside in DLL\ directory below that    */
/*                  pointed to by the MMBASE environment variable.          */
/*    RESTRICTIONS: Runs in protect mode only                               */
/*                                                                          */
/* MODIFICATION HISTORY:                                                    */
/* DATE      DEVELOPER        CHANGE DESCRIPTION                            */
/* 02-Feb-93 Joe Nord         Creation - feature 6090 common IOproc NLV     */
/* 15-Feb-93 Joe Nord         Added prototype for memcpy - defect 6799      */
/* 16-Feb-93 Joe Nord         Changed to use C language getenv function     */
/* 21-Feb-93 Joe Nord         Changed to _Optlink calling conventions       */
/* 29-Mar-93 Joe Nord         Eliminate DosFreeModule - defect 7700         */
/* 16-Aug-95 S.A.O'Loughlin   Workaround:  GetEnv on PPC not working, 15438 */
/************************ END OF SPECIFICATIONS *****************************/

/*
** Set up defines to include the necessary definitions from the OS/2
** include files.
*/

#include <stdlib.h>
#include <string.h>
#include <memory.h>

#define INCL_NOPMAPI                    // no PM include files required
#define INCL_DOSRESOURCES
#define INCL_DOSMODULEMGR               // DosLoadModule
#define INCL_DOSPROCESS                 // DosGetInfoBlocks
#include <os2.h>

#include <mmio.h>
#include "ioprnls.h"
#include <mmdsload.h>

/* Performance stub for pagetuned pragma header files */
#ifndef PERFSTUB
  #include "perfstub.h"
  #define  PERFSTUB
#endif

HMODULE hResourceDLLHandle = 0;

/*                                      --------------------- LoadResourceDLL -
** Load DLL that holds translated resources.  Returns handle
** to loaded module, or zero (invalid handle) if load failed.
*/

HMODULE LoadResourceDLL(VOID)
{

   CHAR       Failure[100];
   ULONG      ulRC;
   CHAR       szDllName [CCHMAXPATH];   // e.g. "c:\mmos2\dll\IOPRNLS.DLL"
   PSZ        pszTemp;
   ULONG      ulCharsFree;

   /*
   ** First version of this module did a Load/access/free sequence to pull
   ** the resource out of the DLL.  For performance, the free has been
   ** eliminated.  Subseqent calls to these routines are made faster if
   ** the DLL is left loaded (defect 7700).
   ** Negative effect is the resource dll is never released.  OS/2 frees
   ** the dll as part of exit list processing when using application terminates
   ** Using a semaphore to protect the retained variable isn't necessary as
   ** it doesn't matter if a second instance of the DLL is loaded.
   */

   if (hResourceDLLHandle != 0)                 // Already loaded?
      return (hResourceDLLHandle);              // yes, return handle

   #ifdef POWERPC                               // 15438
   strcpy(szDllName, "IOPRNLS");
   ulRC = MM_DosLoadModule((PSZ)Failure,
                           sizeof(Failure),
                           (PSZ)szDllName,
                           &hResourceDLLHandle);
   #else
   pszTemp = getenv ("MMBASE");                 // Otherwise load resource DLL

   if (pszTemp != NULL)
      {
      /*
      ** Build a string of the form d:\xxx\xxx\DLL\IOPRNLS.DLL
      */

      strncpy (szDllName, pszTemp, sizeof(szDllName) - 1);
      szDllName[sizeof(szDllName)-1] = '\0';    // Insure nul terminated

      pszTemp = strchr (szDllName, ';');        // Sometimes, MMBASE has a ';'
      if (pszTemp != NULL)                      // If it does, delete the ';'.
         *pszTemp = '\0';

      ulCharsFree = sizeof(szDllName) - strlen(szDllName) - 1;

      strncat (szDllName, "\\DLL\\IOPRNLS.DLL", ulCharsFree);

      ulRC = DosLoadModule
                ((PSZ)Failure,                  // Buffer to receive name of
                 sizeof(Failure),               // thing that caused failure
                 (PSZ)szDllName,                // DLL to load
                 &hResourceDLLHandle);          // Returned handle
      }
   #endif

   return (hResourceDLLHandle);                 // Module handle or zero
} /* LoadResourceDLL */



/*                                      -------------- ioprnlsGetFormatString -
** This function returns the string associated with the given key.
** The search key is used to query a DLL resource, the data in the
** resource is assumed to be a translated ASCII-Z string.
** Support is included to query the length of the string without returning
** string data.
** The returned string length is the length of the string - NOT including
** the terminating nul character.
**
** ARGUMENTS:
**    lSearchId       - Table search key
**    pszFormatString - Address where to return string or NULL, if only
**                      querying string length.
**    ulBufSize       - Maximum number of bytes to place in user'd buffer.
**                      If psz parm is NULL, this parm is not used.
**
** RETURN:
**    Returns strlen of the referenced string or
**    zero to indicate the string look up failed (zero length string returned).
*/

ULONG _Optlink IOPRNLS_GetFormatString
                  (ULONG ulSearchId,      // Usually FourCC of IOproc
                   PSZ   pszFormatString, // NULL, or dest address
                   ULONG ulBufSize)       // Caller provided buffer size
{
   PSZ     pszTemp;
   LONG    ulStringLen;
   HMODULE hModHandle;
   ULONG   ulRC;

   hModHandle = LoadResourceDLL();

   /*
   ** Ask OS/2 to return a pointer to the indicated resource.
   ** This call will fail if asked to find a non-existant resource or
   ** if the module handle is incorrect.
   */
   ulRC = DosGetResource (hModHandle,
                          RT_RCDATA,
                          ulSearchId,
                          (PVOID)&pszTemp);
   if (ulRC != 0)
      {
      ulStringLen = 0;                          // Indicate string not found
      }
   else
      {
      ulStringLen = strlen (pszTemp);

      if (pszFormatString != NULL)              // Copy to caller's buffer?
         {
         if (ulBufSize > 0)                     // Only copy if have a buffer
            {
            if ((ulStringLen + 1) > ulBufSize)  // Truncate, if necessary
               ulStringLen = ulBufSize - 1;

            memcpy (pszFormatString, pszTemp, ulStringLen);
            pszFormatString[ulStringLen] = '\0';// nul terminate
            }
         else
            ulStringLen = 0;                    // Truncate length to zero
         } /* if */
      } /* else */

   DosFreeResource (pszTemp);                   // Free used resources
                                                // Don't free module
   return (ulStringLen);
}

/*                                      ------------------- ioprnlsGetNLSData -
** ARGUMENTS:
**     pulCodePage       - Address where to return the code page/country.
**     pulLanguage       - Address where to return the language/dialect.
**
** RETURN:
**    0          - Success
**    MMIO_ERROR - Failure
**
** DESCRIPTION:
**     This function will retrieve the NLS information for the
**     strings contained in the resource file.
*/

ULONG _Optlink IOPRNLS_GetNLSData
                  (PULONG pulCodePage,
                   PULONG pulCountryCode)
{
   PULONG  pulTemp;
   HMODULE hModHandle;

   hModHandle = LoadResourceDLL();

   if (DosGetResource (hModHandle,
                       RT_RCDATA,
                       IOPRNLS_CODEPAGE,
                       (PVOID)&pulTemp))
      {
       // See defect 11916 SJB.
       *pulCodePage = 0;
      } else {
       *pulCodePage    = *pulTemp;
       DosFreeResource (pulTemp);
      }

   if (DosGetResource (hModHandle,
                       RT_RCDATA,
                       IOPRNLS_COUNTRYCODE,
                       (PVOID)&pulTemp))
      {
        // See defect 11916 SJB.
        *pulCountryCode = 0;
      } else {
        *pulCountryCode = *pulTemp;
        DosFreeResource (pulTemp);                   // Free resource, not module
      }

   return (MMIO_SUCCESS);
}
