home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / sdktools / porttool / port.c < prev    next >
C/C++ Source or Header  |  1995-10-28  |  20KB  |  732 lines

  1. #include <windows.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include "portpriv.h"
  5. #include "port.h"
  6.  
  7. // redefine dbcs versions of common string functions
  8. #ifdef strnicmp
  9. #undef strnicmp
  10. #endif
  11. #define strnicmp    My_mbsnicmp
  12. #define strncmp     My_mbsncmp
  13. #define strncpy     My_mbsncpy
  14. #define strtok      My_mbstok
  15.  
  16. /* globals for this module */
  17. HANDLE      hMMFile = 0;
  18. HANDLE      hDLL;
  19. BOOL      bInit = FALSE;
  20.  
  21. /* function prototypes for private module functions */
  22. void WINAPI FreePortData ();
  23. int  WINAPI GetFirstToken (LPPORT *);
  24. int  WINAPI GetNextToken (LPPORT *);
  25. void WINAPI IgnoreToken (char *, LPPORT);
  26. BOOL WINAPI LoadSection (char *, char *, DWORD, int *, char *);
  27. BOOL WINAPI GetIniFile (HANDLE, char *, char *);
  28.  
  29. /****************************************************************************
  30.     My_mbschr:  strchr() DBCS version
  31. ****************************************************************************/
  32. unsigned char * _CRTAPI1 My_mbschr(
  33.     unsigned char *psz, unsigned short uiSep)
  34. {
  35.     while (*psz != '\0' && *psz != uiSep) {
  36.         psz = CharNext(psz);
  37.     }
  38.     if (*psz == '\0' && uiSep != '\0') {
  39.         return NULL;
  40.     } else {
  41.         return psz;
  42.     }
  43. }
  44. /****************************************************************************
  45.     My_mbstok:  strtok() DBCS version
  46. ****************************************************************************/
  47. unsigned char * _CRTAPI1 My_mbstok(
  48.     unsigned char *pszSrc, unsigned char *pszSep)
  49. {
  50.     static char *pszSave = NULL;
  51.     char *pszHead;
  52.     char *psz;
  53.  
  54.     if (pszSrc == NULL) {
  55.         if (pszSave == NULL) {
  56.             return NULL;
  57.         } else {
  58.             psz = pszSave;
  59.         }
  60.     } else {
  61.         psz = pszSrc;
  62.     }
  63.  
  64.     /*********************************************/
  65.     /* Skip delimiters to find a head of a token */
  66.     /*********************************************/
  67.     while (*psz) {
  68.         if (IsDBCSLeadByte(*psz)) {
  69.             break;
  70.         } else if (NULL == My_mbschr(pszSep, *psz)) {
  71.             break;
  72.         }
  73.         psz++;
  74.     }
  75.     if (*psz == '\0') {
  76.         //No more token
  77.         return (pszSave = NULL);
  78.     }
  79.     pszHead = psz;
  80.  
  81.     /******************************/
  82.     /* Search a Tail of the token */
  83.     /******************************/
  84.     while (*psz) {
  85.         if (IsDBCSLeadByte(*psz)) {
  86.             psz += 2;
  87.             continue;
  88.         } else if (NULL != My_mbschr(pszSep, *psz)) {
  89.             break;
  90.         }
  91.         psz++;
  92.     }
  93.     if (*psz == '\0') {
  94.         pszSave = NULL;
  95.     } else {
  96.         //Found next delimiter
  97.         pszSave = psz + 1;
  98.         *psz = '\0';
  99.     }
  100.     return pszHead;
  101. }
  102. /****************************************************************************
  103.     My_mbsnicmp:strnicmp() DBCS version
  104.                 If 'nLen' splits a DBC, this function compares
  105.                 the DBC's 2nd byte also.
  106. ****************************************************************************/
  107. int _CRTAPI1 My_mbsnicmp(
  108.     const unsigned char *psz1, const unsigned char *psz2, size_t Length)
  109. {
  110.     int nLen = (int)Length;
  111.  
  112.     while (0 < nLen) {
  113.         if ('\0' == *psz1 || '\0' == *psz2) {
  114.             return *psz1 - *psz2;
  115.         }
  116.         if (IsDBCSLeadByte(*psz1) || IsDBCSLeadByte(*psz2)) {
  117.             if (*psz1 != *psz2 || *(psz1+1) != *(psz2+1)) {
  118.                 return *psz1 - *psz2;
  119.             }
  120.             psz1 += 2;
  121.             psz2 += 2;
  122.             nLen -= 2;
  123.         } else {
  124.             if((BYTE)CharUpper((LPSTR)*psz1) != (BYTE)CharUpper((LPSTR)*psz2)){
  125.                 return *psz1 - *psz2;
  126.             }
  127.             psz1++;
  128.             psz2++;
  129.             nLen--;
  130.         }
  131.     }
  132.     return 0;
  133. }
  134. /****************************************************************************
  135.     My_mbsncmp: strncmp() DBCS version
  136.                 If 'nLen' splits a DBC, this function compares
  137.                 the DBC's 2nd byte also.
  138. ****************************************************************************/
  139. int _CRTAPI1 My_mbsncmp(
  140.     const unsigned char *psz1, const unsigned char *psz2, size_t Length)
  141. {
  142.     int nLen = (int)Length;
  143.  
  144.     while (0 < nLen) {
  145.         if ('\0' == *psz1 || '\0' == *psz2) {
  146.             return *psz1 - *psz2;
  147.         }
  148.         if (IsDBCSLeadByte(*psz1) || IsDBCSLeadByte(*psz2)) {
  149.             if (*psz1 != *psz2 || *(psz1+1) != *(psz2+1)) {
  150.                 return *psz1 - *psz2;
  151.             }
  152.             psz1 += 2;
  153.             psz2 += 2;
  154.             nLen -= 2;
  155.         } else {
  156.             if (*psz1 != *psz2) {
  157.                 return *psz1 - *psz2;
  158.             }
  159.             psz1++;
  160.             psz2++;
  161.             nLen--;
  162.         }
  163.     }
  164.     return 0;
  165. }
  166. /****************************************************************************
  167.     My_mbsncpy:
  168. ****************************************************************************/
  169. unsigned char * _CRTAPI1 My_mbsncpy(
  170.     unsigned char *psz1, const unsigned char *psz2, size_t Length)
  171. {
  172.     int nLen = (int)Length;
  173.     unsigned char *pszSv = psz1;
  174.  
  175.     while (0 < nLen) {
  176.         if (*psz2 == '\0') {
  177.             *psz1++ = '\0';
  178.             nLen--;
  179.         } else if (IsDBCSLeadByte(*psz2)) {
  180.             if (nLen == 1) {
  181.                 *psz1 = '\0';
  182.             } else {
  183.                 *psz1++ = *psz2++;
  184.                 *psz1++ = *psz2++;
  185.             }
  186.             nLen -= 2;
  187.         } else {
  188.             *psz1++ = *psz2++;
  189.             nLen--;
  190.         }
  191.     }
  192.     return pszSv;
  193. }
  194.  
  195. /* entry point for DLL loading and unloading */
  196. BOOL WINAPI DllMain (
  197.     HANDLE    hModule,
  198.     DWORD     dwFunction,
  199.     LPVOID    lpNot)
  200. {
  201. #ifdef DEBUG
  202. DebugBreak ();
  203. #endif
  204.  
  205.     switch (dwFunction)
  206.     {
  207.     case DLL_PROCESS_ATTACH:
  208.         hDLL = hModule;
  209.         break;
  210.  
  211.     case DLL_PROCESS_DETACH:
  212.         FreePortData ();
  213.     default:
  214.         break;
  215.     }
  216.  
  217.     return TRUE;
  218. }
  219.  
  220.  
  221.  
  222. /* function initializes port structures */
  223. BOOL WINAPI InitPortData (
  224.     char      *szIniFileName
  225.     )
  226. {
  227.     char    szSection[MAX_PATH];
  228.     char    szIniFilePath[MAX_PATH];
  229.     char    szMapFileName[MAX_PATH];
  230.     OFSTRUCT    of;
  231.     HANDLE    hFile;
  232.     DWORD    nFileSize;
  233.     int     nOffset = 0;
  234.     char    *lpMMFile;
  235.  
  236.     /* Initialize Flag off */
  237.     bInit = FALSE;
  238.  
  239.     /* load name for global file mapping */
  240.     LoadString (hDLL, IDS_MAPFILENAME, szMapFileName, MAX_PATH);
  241.  
  242.     /* after first process initializes port data */
  243.     if ((hMMFile = OpenFileMapping (FILE_MAP_WRITE, FALSE, szMapFileName)))
  244.     /* exit now since initialization was already performed by another process */
  245.     return TRUE;
  246.  
  247.     /* retrive path and file for ini file */
  248.     if (!GetIniFile (hDLL, szIniFileName, szIniFilePath))
  249.     return FALSE;
  250.  
  251.     /* test for ini file existance and get length of file */
  252.     if ((int)(hFile = (HANDLE)OpenFile (szIniFilePath, &of, OF_READ)) == -1)
  253.     return FALSE;
  254.     else
  255.     {
  256.     nFileSize = GetFileSize (hFile, NULL);
  257.     CloseHandle (hFile);
  258.     }
  259.  
  260.     /* allocate a segment of the swap file for shared memory 2*Size of ini file */
  261.     if (!(hMMFile = CreateFileMapping ((HANDLE)0xffffffff,
  262.                    NULL,
  263.                    PAGE_READWRITE,
  264.                    0,
  265.                    nFileSize * 2,
  266.                    szMapFileName)))
  267.     return FALSE;
  268.  
  269.     /* map a view of this file for writing */
  270.     lpMMFile = (char *)MapViewOfFile (hMMFile, FILE_MAP_WRITE, 0, 0, 0);
  271.  
  272.     /* load tokens for APIS section */
  273.     LoadString (hDLL, IDS_PORTAPIS, szSection, MAX_PATH);
  274.     if (!LoadSection (szIniFilePath, szSection, PT_APIS, &nOffset, lpMMFile))
  275.     {
  276.     /* clean up memory mapped file */
  277.     UnmapViewOfFile (lpMMFile);
  278.     CloseHandle (hMMFile);
  279.     return FALSE;
  280.     }
  281.  
  282.     /* load tokens for MESSAGES section */
  283.     LoadString (hDLL, IDS_PORTMESSAGES, szSection, MAX_PATH);
  284.     if (!LoadSection (szIniFilePath, szSection, PT_MESSAGES, &nOffset, lpMMFile))
  285.     {
  286.     /* clean up memory mapped file */
  287.     UnmapViewOfFile (lpMMFile);
  288.     CloseHandle (hMMFile);
  289.     return FALSE;
  290.     }
  291.  
  292.     /* load tokens for STRUCTURES section */
  293.     LoadString (hDLL, IDS_PORTSTRUCTURES, szSection, MAX_PATH);
  294.     if (!LoadSection (szIniFilePath, szSection, PT_STRUCTURES, &nOffset, lpMMFile))
  295.     {
  296.     /* clean up memory mapped file */
  297.     UnmapViewOfFile (lpMMFile);
  298.     CloseHandle (hMMFile);
  299.     return FALSE;
  300.     }
  301.  
  302.     /* load tokens for TYPES section */
  303.     LoadString (hDLL, IDS_PORTTYPES, szSection, MAX_PATH);
  304.     if (!LoadSection (szIniFilePath, szSection, PT_TYPES, &nOffset, lpMMFile))
  305.     {
  306.     /* clean up memory mapped file */
  307.     UnmapViewOfFile (lpMMFile);
  308.     CloseHandle (hMMFile);
  309.     return FALSE;
  310.     }
  311.  
  312.     /* load tokens for MACROS section */
  313.     LoadString (hDLL, IDS_PORTMACROS, szSection, MAX_PATH);
  314.     if (!LoadSection (szIniFilePath, szSection, PT_MACROS, &nOffset, lpMMFile))
  315.     {
  316.     /* clean up memory mapped file */
  317.     UnmapViewOfFile (lpMMFile);
  318.     CloseHandle (hMMFile);
  319.     return FALSE;
  320.     }
  321.  
  322.     /* load tokens for CONSTANTS section */
  323.     LoadString (hDLL, IDS_PORTCONSTANTS, szSection, MAX_PATH);
  324.     if (!LoadSection (szIniFilePath, szSection, PT_CONSTANTS, &nOffset, lpMMFile))
  325.     {
  326.     /* clean up memory mapped file */
  327.     UnmapViewOfFile (lpMMFile);
  328.     CloseHandle (hMMFile);
  329.     return FALSE;
  330.     }
  331.  
  332.     /* load tokens for CUSTOM section */
  333.     LoadString (hDLL, IDS_PORTCUSTOM, szSection, MAX_PATH);
  334.     if (!LoadSection (szIniFilePath, szSection, PT_CUSTOM, &nOffset, lpMMFile))
  335.     {
  336.     /* clean up memory mapped file */
  337.     UnmapViewOfFile (lpMMFile);
  338.     CloseHandle (hMMFile);
  339.     return FALSE;
  340.     }
  341.  
  342.     /* release WRITE view of memory mapped file */
  343.     UnmapViewOfFile (lpMMFile);
  344.  
  345.     /* success */
  346.     bInit = TRUE;
  347.     return TRUE;
  348. }
  349.  
  350.  
  351.  
  352. /* release memory mapped file view */
  353. void WINAPI FreePortData ()
  354.     {
  355.     if ( ! bInit )
  356.         return;
  357.  
  358.     /* release memory mapped file */
  359.     CloseHandle (hMMFile);
  360.     }
  361.  
  362.  
  363.  
  364. /* external function to check a string for porting issues */
  365. BOOL WINAPI CheckString (
  366.     char    *lpszSrc,
  367.     DWORD    dwSearch,
  368.     LPRESULT    lprIssue)
  369. {
  370.     BOOL      bRet = FALSE;
  371.     LPPORT    lpToken;
  372.     char      *lpStr = lpszSrc;
  373.     int       nSrcLen = strlen (lpszSrc);
  374.     int       nTokLen;
  375.     char      *lpMMFile = (char *)MapViewOfFile (hMMFile, FILE_MAP_WRITE, 0, 0, 0);
  376.  
  377.  
  378.     if ( ! bInit )
  379.        return FALSE;
  380.  
  381.     /* if view of file failed */
  382.     if (!lpMMFile)
  383.     return FALSE;
  384.  
  385.     /* if ignore token */
  386.     if (dwSearch & PT_IGNORETOKEN)
  387.     /* flag token as ignored */
  388.     IgnoreToken (lpszSrc, (LPPORT)lpMMFile);
  389.  
  390.     else
  391.     /* loop through all characters in string */
  392.     while ((lpStr-lpszSrc) < nSrcLen)
  393.         {
  394.         /* initialize lpToken to beginning of list */
  395.         lpToken = (LPPORT)lpMMFile;
  396.  
  397.         /* loop thru all tokens */
  398.         if (nTokLen = GetFirstToken (&lpToken))
  399.         do
  400.         {
  401.         /* filter tokens for search criteria */
  402.         if (!(lpToken->dwType & PT_IGNORED) &&
  403.             !(dwSearch & lpToken->dwType) &&
  404.             ((dwSearch & PT_IGNORECASE &&
  405.               !strnicmp ((char *)lpToken+lpToken->nPosToken, lpStr, nTokLen)) ||
  406.              !strncmp ((char *)lpToken+lpToken->nPosToken, lpStr, nTokLen)))
  407.             {
  408.             /* token found in line, return ISSUE struct */
  409.             strncpy (lprIssue->lpszToken,
  410.                  (char *)lpToken+lpToken->nPosToken,
  411.                  *(WORD *)lprIssue->lpszToken);
  412.             strncpy (lprIssue->lpszHelpStr,
  413.                  (char *)lpToken+lpToken->nPosHelpStr,
  414.                  *(WORD *)lprIssue->lpszHelpStr);
  415.             strncpy (lprIssue->lpszIssue,
  416.                  (char *)lpToken+lpToken->nPosIssue,
  417.                  *(WORD *)lprIssue->lpszIssue);
  418.             strncpy (lprIssue->lpszSuggest,
  419.                  (char *)lpToken+lpToken->nPosSuggest,
  420.                  *(WORD *)lprIssue->lpszSuggest);
  421.             lprIssue->nPosToken = (int)(lpStr - lpszSrc);
  422.  
  423.             bRet = TRUE;
  424.             goto DONE;
  425.             }
  426.         }
  427.         while ((nTokLen = GetNextToken (&lpToken)));
  428.  
  429.         lpStr = CharNext(lpStr);
  430.         }
  431.  
  432. DONE:
  433.  
  434.     /* unmap view of memory mapped file */
  435.     UnmapViewOfFile (lpMMFile);
  436.  
  437.     return bRet;
  438. }
  439.  
  440.  
  441.  
  442. /* function get's the first token in the list */
  443. int WINAPI GetFirstToken (
  444.     LPPORT    *lpToken)
  445. {
  446.     /* increment to next non-ignored token in list */
  447.     while (((((LPPORT)*lpToken)->dwType) == PT_IGNORED) &&
  448.        ((((LPPORT)*lpToken)->nSize) != 0))
  449.     (char *)*lpToken += ((LPPORT)*lpToken)->nSize;
  450.  
  451.     /* if at end of list, reset list to null */
  452.     if ((((LPPORT)*lpToken)->nSize) == 0)
  453.     {
  454.     *lpToken = 0;
  455.     return 0;
  456.     }
  457.  
  458.     /* return length of token */
  459.     return (strlen ((char *)*lpToken + ((LPPORT)*lpToken)->nPosToken));
  460. }
  461.  
  462.  
  463. /* function get's the next token in the list */
  464. int WINAPI GetNextToken (
  465.     LPPORT    *lpToken)
  466. {
  467.     /* increment to next non-ignored token in list */
  468.     do
  469.     (char *)*lpToken += ((LPPORT)*lpToken)->nSize;
  470.     while (((((LPPORT)*lpToken)->dwType) == PT_IGNORED) &&
  471.        ((((LPPORT)*lpToken)->nSize) != 0));
  472.  
  473.     /* if at end of list, reset list to null */
  474.     if ((((LPPORT)*lpToken)->nSize) == 0)
  475.     {
  476.     *lpToken = 0;
  477.     return 0;
  478.     }
  479.  
  480.     /* return length of token */
  481.     return (strlen ((char *)*lpToken + ((LPPORT)*lpToken)->nPosToken));
  482. }
  483.  
  484.  
  485.  
  486. /* function sets the ignore flag on the specified token */
  487. void WINAPI IgnoreToken (
  488.     char    *lpszToken,
  489.     LPPORT  lpToken)
  490. {
  491.     /* search for token in list */
  492.     while (lpToken->nSize != 0)
  493.     /* if same token */
  494.     if (!strcmp ((char *)((char *)lpToken + lpToken->nPosToken), lpszToken))
  495.         {
  496.         lpToken->dwType |= PT_IGNORED;
  497.         break;
  498.         }
  499.     /* increment to  next token */
  500.     else
  501.         (char *)lpToken += lpToken->nSize;
  502. }
  503.  
  504.  
  505.  
  506.  
  507. /* load tokens from a section of ini file */
  508. BOOL WINAPI LoadSection (
  509.     char    *lpszIniFile,
  510.     char    *lpszSection,
  511.     DWORD   dwType,
  512.     int     *nOffset,
  513.     char    *lpMMFile)
  514. {
  515.     char    *lpszKeyNames;
  516.     char    *lpKey;
  517.     char    *lpszValue;
  518.     char    *lpVal;
  519.     char    *lpszToken;
  520.     char    lpszDefault[] = "Default";
  521.     char    *lpMem = lpMMFile + *nOffset;
  522.     int     nList;
  523.  
  524.  
  525.     /* allocate lots of memory off heap to save calling applications' stack */
  526.     if (!(lpszKeyNames = (char *)LocalAlloc (LPTR, FIFTY_K_LINE)))
  527.     return FALSE;
  528.     if (!(lpszValue = (char *)LocalAlloc (LPTR, TWO_K_LINE)))
  529.     {
  530.     LocalFree ((HLOCAL)lpszKeyNames);
  531.     return FALSE;
  532.     }
  533.     if (!(lpszToken = (char *)LocalAlloc (LPTR, MAXTOKENLEN)))
  534.     {
  535.     LocalFree ((HLOCAL)lpszKeyNames);
  536.     LocalFree ((HLOCAL)lpszValue);
  537.     return FALSE;
  538.     }
  539.  
  540.     /* get all keynames in section */
  541.     if (((nList = GetPrivateProfileString (lpszSection,
  542.                        NULL,
  543.                        lpszDefault,
  544.                        lpszKeyNames,
  545.                        FIFTY_K_LINE,
  546.                        lpszIniFile)) == (int)(strlen (lpszDefault))) &&
  547.     !strcmp (lpszDefault, lpszKeyNames))
  548.     {
  549.     LocalFree ((HLOCAL)lpszKeyNames);
  550.     LocalFree ((HLOCAL)lpszValue);
  551.     LocalFree ((HLOCAL)lpszToken);
  552.     return FALSE;
  553.     }
  554.  
  555.     /* initialize token pointer and first token */
  556.     lpKey = lpszKeyNames;
  557.  
  558.     /* loop through all keynames */
  559.     while (TRUE)
  560.     {
  561.     /* get next token */
  562.     strcpy (lpszToken, lpKey);
  563.  
  564.     /* get value for token */
  565.     if ((GetPrivateProfileString (lpszSection,
  566.                      lpszToken,
  567.                      lpszDefault,
  568.                      lpszValue,
  569.                      TWO_K_LINE,
  570.                      lpszIniFile) == strlen (lpszDefault)) &&
  571.         !strcmp (lpszDefault, lpszValue))
  572.         {
  573.         LocalFree ((HLOCAL)lpszKeyNames);
  574.         LocalFree ((HLOCAL)lpszValue);
  575.         LocalFree ((HLOCAL)lpszToken);
  576.         return FALSE;
  577.         }
  578.     else
  579.         {
  580.         /* break line up into components */
  581.         ((LPPORT)lpMem)->nPosToken = sizeof (PORT);
  582.         strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosToken), lpszToken);
  583.  
  584.         ((LPPORT)lpMem)->nPosHelpStr =
  585.             ((LPPORT)lpMem)->nPosToken + strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosToken)) + 1;
  586.         if (lpVal = strtok (lpszValue, ";"))
  587.         strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosHelpStr), lpVal);
  588.         else
  589.         *(lpMem + ((LPPORT)lpMem)->nPosHelpStr) = 0;
  590.  
  591.         ((LPPORT)lpMem)->nPosIssue =
  592.             ((LPPORT)lpMem)->nPosHelpStr + strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosHelpStr)) + 1;
  593.         if (lpVal = strtok (NULL, ";"))
  594.         strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosIssue), lpVal);
  595.         else
  596.         *(lpMem + ((LPPORT)lpMem)->nPosIssue) = 0;
  597.  
  598.         ((LPPORT)lpMem)->nPosSuggest =
  599.             ((LPPORT)lpMem)->nPosIssue + strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosIssue)) + 1;
  600.         if (lpVal = strtok (NULL, ";"))
  601.         strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosSuggest), lpVal);
  602.         else
  603.         *(lpMem + ((LPPORT)lpMem)->nPosSuggest) = 0;
  604.  
  605.         /* set size of dynamic token structure */
  606.         ((LPPORT)lpMem)->nSize = (((LPPORT)lpMem)->nPosSuggest +
  607.          strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosSuggest)) + 1);
  608.  
  609.         /* adjust nSize for DWORD alignment */
  610.             ((LPPORT)lpMem)->nSize = ((((LPPORT)lpMem)->nSize) + 3) & ~3;
  611.  
  612.         /* set token type */
  613.         ((LPPORT)lpMem)->dwType = dwType;
  614.  
  615.         /* adjust list pointer to point beginning of next list element */
  616.         lpMem += ((LPPORT)lpMem)->nSize;
  617.         }
  618.  
  619.     /* increment token pointer and test for end of list */
  620.     if (((lpKey += strlen (lpszToken) + 1) - lpszKeyNames) >= (nList - 1))
  621.         {
  622.         /* indicate end of list by setting size of next element to 0 */
  623.         ((LPPORT)lpMem)->nSize = 0;
  624.         break;
  625.         }
  626.     }
  627.  
  628.     /* got to end of section, clean up and go away */
  629.     LocalFree ((HLOCAL)lpszKeyNames);
  630.     LocalFree ((HLOCAL)lpszValue);
  631.     LocalFree ((HLOCAL)lpszToken);
  632.  
  633.     /* recalculate offset */
  634.     *nOffset = lpMem - lpMMFile;
  635.  
  636.     /* return successful load */
  637.     return TRUE;
  638. }
  639.  
  640.  
  641. /* retrieve ini file and path */
  642. BOOL WINAPI GetIniFile (
  643.     HANDLE    hDLL,
  644.     char    *lpszFileName,
  645.     char    *lpszFile)
  646. {
  647.     char    lpszPath[MAX_PATH];
  648.     char    *lpPath;
  649.     // char     lpszFileName[MAX_PATH];
  650.     OFSTRUCT    of;
  651.  
  652.     // Is this a full path ? If so there must be a : or \ in there somewhere.
  653.     lpPath = lpszFileName;
  654.     while ( *lpPath )
  655.     {
  656.        if ( *lpPath == '\\' || *lpPath == ':' )
  657.        {
  658.           if ((OpenFile (lpszFileName, &of, OF_EXIST)))
  659.           {
  660.              // Name passed in is OK.
  661.              strcpy (lpszFile, lpszFileName);
  662.              return TRUE;
  663.           }
  664.  
  665.        }
  666.        lpPath = CharNext(lpPath);
  667.     }
  668.  
  669.     // OK, not a full path, we must build one
  670.  
  671.     /* get module directory and path */
  672.     GetModuleFileName (hDLL, lpszPath, MAX_PATH);
  673.     lpPath = lpszPath + strlen (lpszPath);
  674.  
  675.     /* find end of path by searching backwards from end to first '\' or ':' */
  676.     while (lpPath > lpszPath)
  677.     {
  678.     if (*lpPath == '\\' ||
  679.         *lpPath == ':')
  680.         {
  681.         lpPath++;
  682.         break;
  683.         }
  684.     lpPath = CharPrev(lpszPath, lpPath);
  685.     }
  686.  
  687.     /* terminate at end of path */
  688.     *lpPath = 0;
  689.  
  690.     /* append ini filename to path */
  691.     strcat (lpPath, lpszFileName);
  692.  
  693.     // check for an extension ( look for '.' before '\' )
  694.     lpPath = lpszPath+strlen(lpszPath);
  695.     while ( lpPath > lpszPath && 
  696.             *lpPath != '\\' && 
  697.             *lpPath != ':')
  698.     {
  699.        if ( *lpPath == '.')
  700.           break;
  701.        lpPath = CharPrev(lpszPath, lpPath);
  702.     }
  703.  
  704.     if ( *lpPath != '.' )
  705.     {
  706.        // No extension, supply one
  707.        strcat (lpszPath, ".INI");
  708.     }
  709.  
  710.  
  711.     /* test for existance */
  712.     if (!(OpenFile (lpszPath, &of, OF_EXIST)))
  713.     {
  714.     GetWindowsDirectory (lpszPath, MAX_PATH);
  715.     strcat (lpszPath, lpszFileName);
  716.     if (!(OpenFile (lpszPath, &of, OF_EXIST)))
  717.     {
  718.         return FALSE;
  719.     }
  720.     else
  721.         {
  722.         strcpy (lpszFile, lpszPath);
  723.         return TRUE;
  724.         }
  725.     }
  726.     else
  727.     {
  728.     strcpy (lpszFile, lpszPath);
  729.     return TRUE;
  730.     }
  731. }
  732.