PORT.C
#include <windows.h> 
#include <string.h> 
#include <stdlib.h> 
#include "portpriv.h" 
#include "port.h" 
 
// redefine dbcs versions of common string functions 
#ifdef strnicmp 
#undef strnicmp 
#endif 
#define strnicmp    My_mbsnicmp 
#define strncmp     My_mbsncmp 
#define strncpy     My_mbsncpy 
#define strtok      My_mbstok 
 
/* globals for this module */ 
HANDLE  hMMFile = 0; 
HANDLE  hDLL; 
BOOL  bInit = FALSE; 
 
/* function prototypes for private module functions */ 
void WINAPI FreePortData (); 
int  WINAPI GetFirstToken (LPPORT *); 
int  WINAPI GetNextToken (LPPORT *); 
void WINAPI IgnoreToken (char *, LPPORT); 
BOOL WINAPI LoadSection (char *, char *, DWORD, int *, char *); 
BOOL WINAPI GetIniFile (HANDLE, char *, char *); 
 
/**************************************************************************** 
    My_mbschr:  strchr() DBCS version 
****************************************************************************/ 
unsigned char * _CRTAPI1 My_mbschr( 
    unsigned char *psz, unsigned short uiSep) 
{ 
    while (*psz != '\0' && *psz != uiSep) { 
        psz = CharNext(psz); 
    } 
    if (*psz == '\0' && uiSep != '\0') { 
        return NULL; 
    } else { 
        return psz; 
    } 
} 
/**************************************************************************** 
    My_mbstok:  strtok() DBCS version 
****************************************************************************/ 
unsigned char * _CRTAPI1 My_mbstok( 
    unsigned char *pszSrc, unsigned char *pszSep) 
{ 
    static char *pszSave = NULL; 
    char *pszHead; 
    char *psz; 
 
    if (pszSrc == NULL) { 
        if (pszSave == NULL) { 
            return NULL; 
        } else { 
            psz = pszSave; 
        } 
    } else { 
        psz = pszSrc; 
    } 
 
    /*********************************************/ 
    /* Skip delimiters to find a head of a token */ 
    /*********************************************/ 
    while (*psz) { 
        if (IsDBCSLeadByte(*psz)) { 
            break; 
        } else if (NULL == My_mbschr(pszSep, *psz)) { 
            break; 
        } 
        psz++; 
    } 
    if (*psz == '\0') { 
        //No more token 
        return (pszSave = NULL); 
    } 
    pszHead = psz; 
 
    /******************************/ 
    /* Search a Tail of the token */ 
    /******************************/ 
    while (*psz) { 
        if (IsDBCSLeadByte(*psz)) { 
            psz += 2; 
            continue; 
        } else if (NULL != My_mbschr(pszSep, *psz)) { 
            break; 
        } 
        psz++; 
    } 
    if (*psz == '\0') { 
        pszSave = NULL; 
    } else { 
        //Found next delimiter 
        pszSave = psz + 1; 
        *psz = '\0'; 
    } 
    return pszHead; 
} 
/**************************************************************************** 
    My_mbsnicmp:strnicmp() DBCS version 
                If 'nLen' splits a DBC, this function compares 
                the DBC's 2nd byte also. 
****************************************************************************/ 
int _CRTAPI1 My_mbsnicmp( 
    const unsigned char *psz1, const unsigned char *psz2, size_t Length) 
{ 
    int nLen = (int)Length; 
 
    while (0 < nLen) { 
        if ('\0' == *psz1 || '\0' == *psz2) { 
            return *psz1 - *psz2; 
        } 
        if (IsDBCSLeadByte(*psz1) || IsDBCSLeadByte(*psz2)) { 
            if (*psz1 != *psz2 || *(psz1+1) != *(psz2+1)) { 
                return *psz1 - *psz2; 
            } 
            psz1 += 2; 
            psz2 += 2; 
            nLen -= 2; 
        } else { 
            if((BYTE)CharUpper((LPSTR)*psz1) != (BYTE)CharUpper((LPSTR)*psz2)){ 
                return *psz1 - *psz2; 
            } 
            psz1++; 
            psz2++; 
            nLen--; 
        } 
    } 
    return 0; 
} 
/**************************************************************************** 
    My_mbsncmp: strncmp() DBCS version 
                If 'nLen' splits a DBC, this function compares 
                the DBC's 2nd byte also. 
****************************************************************************/ 
int _CRTAPI1 My_mbsncmp( 
    const unsigned char *psz1, const unsigned char *psz2, size_t Length) 
{ 
    int nLen = (int)Length; 
 
    while (0 < nLen) { 
        if ('\0' == *psz1 || '\0' == *psz2) { 
            return *psz1 - *psz2; 
        } 
        if (IsDBCSLeadByte(*psz1) || IsDBCSLeadByte(*psz2)) { 
            if (*psz1 != *psz2 || *(psz1+1) != *(psz2+1)) { 
                return *psz1 - *psz2; 
            } 
            psz1 += 2; 
            psz2 += 2; 
            nLen -= 2; 
        } else { 
            if (*psz1 != *psz2) { 
                return *psz1 - *psz2; 
            } 
            psz1++; 
            psz2++; 
            nLen--; 
        } 
    } 
    return 0; 
} 
/**************************************************************************** 
    My_mbsncpy: 
****************************************************************************/ 
unsigned char * _CRTAPI1 My_mbsncpy( 
    unsigned char *psz1, const unsigned char *psz2, size_t Length) 
{ 
    int nLen = (int)Length; 
    unsigned char *pszSv = psz1; 
 
    while (0 < nLen) { 
        if (*psz2 == '\0') { 
            *psz1++ = '\0'; 
            nLen--; 
        } else if (IsDBCSLeadByte(*psz2)) { 
            if (nLen == 1) { 
                *psz1 = '\0'; 
            } else { 
                *psz1++ = *psz2++; 
                *psz1++ = *psz2++; 
            } 
            nLen -= 2; 
        } else { 
            *psz1++ = *psz2++; 
            nLen--; 
        } 
    } 
    return pszSv; 
} 
 
/* entry point for DLL loading and unloading */ 
BOOL WINAPI DllMain ( 
    HANDLE    hModule, 
    DWORD     dwFunction, 
    LPVOID    lpNot) 
{ 
#ifdef DEBUG 
DebugBreak (); 
#endif 
 
    switch (dwFunction) 
{ 
case DLL_PROCESS_ATTACH: 
hDLL = hModule; 
    break; 
 
case DLL_PROCESS_DETACH: 
    FreePortData (); 
default: 
    break; 
} 
 
    return TRUE; 
} 
 
 
 
/* function initializes port structures */ 
BOOL WINAPI InitPortData ( 
char  *szIniFileName 
) 
{ 
    charszSection[MAX_PATH]; 
    charszIniFilePath[MAX_PATH]; 
    charszMapFileName[MAX_PATH]; 
    OFSTRUCTof; 
    HANDLEhFile; 
    DWORDnFileSize; 
    int nOffset = 0; 
    char*lpMMFile; 
 
/* Initialize Flag off */ 
bInit = FALSE; 
 
    /* load name for global file mapping */ 
    LoadString (hDLL, IDS_MAPFILENAME, szMapFileName, MAX_PATH); 
 
    /* after first process initializes port data */ 
    if ((hMMFile = OpenFileMapping (FILE_MAP_WRITE, FALSE, szMapFileName))) 
/* exit now since initialization was already performed by another process */ 
return TRUE; 
 
    /* retrive path and file for ini file */ 
if (!GetIniFile (hDLL, szIniFileName, szIniFilePath)) 
return FALSE; 
 
    /* test for ini file existance and get length of file */ 
    if ((int)(hFile = (HANDLE)OpenFile (szIniFilePath, &of, OF_READ)) == -1) 
return FALSE; 
    else 
{ 
nFileSize = GetFileSize (hFile, NULL); 
CloseHandle (hFile); 
} 
 
    /* allocate a segment of the swap file for shared memory 2*Size of ini file */ 
    if (!(hMMFile = CreateFileMapping ((HANDLE)0xffffffff, 
   NULL, 
   PAGE_READWRITE, 
   0, 
   nFileSize * 2, 
   szMapFileName))) 
return FALSE; 
 
    /* map a view of this file for writing */ 
    lpMMFile = (char *)MapViewOfFile (hMMFile, FILE_MAP_WRITE, 0, 0, 0); 
 
    /* load tokens for APIS section */ 
    LoadString (hDLL, IDS_PORTAPIS, szSection, MAX_PATH); 
    if (!LoadSection (szIniFilePath, szSection, PT_APIS, &nOffset, lpMMFile)) 
{ 
/* clean up memory mapped file */ 
UnmapViewOfFile (lpMMFile); 
CloseHandle (hMMFile); 
return FALSE; 
} 
 
    /* load tokens for MESSAGES section */ 
    LoadString (hDLL, IDS_PORTMESSAGES, szSection, MAX_PATH); 
    if (!LoadSection (szIniFilePath, szSection, PT_MESSAGES, &nOffset, lpMMFile)) 
{ 
/* clean up memory mapped file */ 
UnmapViewOfFile (lpMMFile); 
CloseHandle (hMMFile); 
return FALSE; 
} 
 
    /* load tokens for STRUCTURES section */ 
    LoadString (hDLL, IDS_PORTSTRUCTURES, szSection, MAX_PATH); 
    if (!LoadSection (szIniFilePath, szSection, PT_STRUCTURES, &nOffset, lpMMFile)) 
{ 
/* clean up memory mapped file */ 
UnmapViewOfFile (lpMMFile); 
CloseHandle (hMMFile); 
return FALSE; 
} 
 
    /* load tokens for TYPES section */ 
    LoadString (hDLL, IDS_PORTTYPES, szSection, MAX_PATH); 
    if (!LoadSection (szIniFilePath, szSection, PT_TYPES, &nOffset, lpMMFile)) 
{ 
/* clean up memory mapped file */ 
UnmapViewOfFile (lpMMFile); 
CloseHandle (hMMFile); 
return FALSE; 
} 
 
    /* load tokens for MACROS section */ 
    LoadString (hDLL, IDS_PORTMACROS, szSection, MAX_PATH); 
    if (!LoadSection (szIniFilePath, szSection, PT_MACROS, &nOffset, lpMMFile)) 
{ 
/* clean up memory mapped file */ 
UnmapViewOfFile (lpMMFile); 
CloseHandle (hMMFile); 
return FALSE; 
} 
 
    /* load tokens for CONSTANTS section */ 
    LoadString (hDLL, IDS_PORTCONSTANTS, szSection, MAX_PATH); 
    if (!LoadSection (szIniFilePath, szSection, PT_CONSTANTS, &nOffset, lpMMFile)) 
{ 
/* clean up memory mapped file */ 
UnmapViewOfFile (lpMMFile); 
CloseHandle (hMMFile); 
return FALSE; 
} 
 
    /* load tokens for CUSTOM section */ 
    LoadString (hDLL, IDS_PORTCUSTOM, szSection, MAX_PATH); 
    if (!LoadSection (szIniFilePath, szSection, PT_CUSTOM, &nOffset, lpMMFile)) 
{ 
/* clean up memory mapped file */ 
UnmapViewOfFile (lpMMFile); 
CloseHandle (hMMFile); 
return FALSE; 
} 
 
    /* release WRITE view of memory mapped file */ 
    UnmapViewOfFile (lpMMFile); 
 
/* success */ 
bInit = TRUE; 
    return TRUE; 
} 
 
 
 
/* release memory mapped file view */ 
void WINAPI FreePortData () 
{ 
if ( ! bInit ) 
return; 
 
    /* release memory mapped file */ 
    CloseHandle (hMMFile); 
    } 
 
 
 
/* external function to check a string for porting issues */ 
BOOL WINAPI CheckString ( 
    char*lpszSrc, 
    DWORDdwSearch, 
    LPRESULTlprIssue) 
{ 
    BOOL      bRet = FALSE; 
    LPPORT    lpToken; 
    char      *lpStr = lpszSrc; 
    int       nSrcLen = strlen (lpszSrc); 
    int       nTokLen; 
    char      *lpMMFile = (char *)MapViewOfFile (hMMFile, FILE_MAP_WRITE, 0, 0, 0); 
 
 
if ( ! bInit ) 
   return FALSE; 
 
/* if view of file failed */ 
    if (!lpMMFile) 
return FALSE; 
 
    /* if ignore token */ 
    if (dwSearch & PT_IGNORETOKEN) 
/* flag token as ignored */ 
IgnoreToken (lpszSrc, (LPPORT)lpMMFile); 
 
    else 
/* loop through all characters in string */ 
while ((lpStr-lpszSrc) < nSrcLen) 
    { 
    /* initialize lpToken to beginning of list */ 
    lpToken = (LPPORT)lpMMFile; 
 
        /* loop thru all tokens */ 
    if (nTokLen = GetFirstToken (&lpToken)) 
    do 
        { 
        /* filter tokens for search criteria */ 
        if (!(lpToken->dwType & PT_IGNORED) && 
            !(dwSearch & lpToken->dwType) && 
            ((dwSearch & PT_IGNORECASE && 
              !strnicmp ((char *)lpToken+lpToken->nPosToken, lpStr, nTokLen)) || 
             !strncmp ((char *)lpToken+lpToken->nPosToken, lpStr, nTokLen))) 
            { 
            /* token found in line, return ISSUE struct */ 
            strncpy (lprIssue->lpszToken, 
                 (char *)lpToken+lpToken->nPosToken, 
                 *(WORD *)lprIssue->lpszToken); 
            strncpy (lprIssue->lpszHelpStr, 
                 (char *)lpToken+lpToken->nPosHelpStr, 
                 *(WORD *)lprIssue->lpszHelpStr); 
            strncpy (lprIssue->lpszIssue, 
                 (char *)lpToken+lpToken->nPosIssue, 
                 *(WORD *)lprIssue->lpszIssue); 
            strncpy (lprIssue->lpszSuggest, 
                 (char *)lpToken+lpToken->nPosSuggest, 
                 *(WORD *)lprIssue->lpszSuggest); 
            lprIssue->nPosToken = (int)(lpStr - lpszSrc); 
 
    bRet = TRUE; 
    goto DONE; 
    } 
} 
    while ((nTokLen = GetNextToken (&lpToken))); 
 
        lpStr = CharNext(lpStr); 
        } 
 
DONE: 
 
    /* unmap view of memory mapped file */ 
    UnmapViewOfFile (lpMMFile); 
 
    return bRet; 
} 
 
 
 
/* function get's the first token in the list */ 
int WINAPI GetFirstToken ( 
    LPPORT    *lpToken) 
{ 
    /* increment to next non-ignored token in list */ 
    while (((((LPPORT)*lpToken)->dwType) == PT_IGNORED) && 
   ((((LPPORT)*lpToken)->nSize) != 0)) 
(char *)*lpToken += ((LPPORT)*lpToken)->nSize; 
 
    /* if at end of list, reset list to null */ 
    if ((((LPPORT)*lpToken)->nSize) == 0) 
{ 
*lpToken = 0; 
return 0; 
} 
 
    /* return length of token */ 
    return (strlen ((char *)*lpToken + ((LPPORT)*lpToken)->nPosToken)); 
} 
 
 
/* function get's the next token in the list */ 
int WINAPI GetNextToken ( 
    LPPORT    *lpToken) 
{ 
    /* increment to next non-ignored token in list */ 
    do 
(char *)*lpToken += ((LPPORT)*lpToken)->nSize; 
    while (((((LPPORT)*lpToken)->dwType) == PT_IGNORED) && 
   ((((LPPORT)*lpToken)->nSize) != 0)); 
 
    /* if at end of list, reset list to null */ 
    if ((((LPPORT)*lpToken)->nSize) == 0) 
{ 
*lpToken = 0; 
return 0; 
} 
 
    /* return length of token */ 
    return (strlen ((char *)*lpToken + ((LPPORT)*lpToken)->nPosToken)); 
} 
 
 
 
/* function sets the ignore flag on the specified token */ 
void WINAPI IgnoreToken ( 
    char    *lpszToken, 
    LPPORT  lpToken) 
{ 
    /* search for token in list */ 
    while (lpToken->nSize != 0) 
/* if same token */ 
if (!strcmp ((char *)((char *)lpToken + lpToken->nPosToken), lpszToken)) 
    { 
    lpToken->dwType |= PT_IGNORED; 
    break; 
    } 
/* increment to  next token */ 
else 
    (char *)lpToken += lpToken->nSize; 
} 
 
 
 
 
/* load tokens from a section of ini file */ 
BOOL WINAPI LoadSection ( 
    char    *lpszIniFile, 
    char    *lpszSection, 
    DWORD   dwType, 
    int     *nOffset, 
    char    *lpMMFile) 
{ 
    char    *lpszKeyNames; 
    char    *lpKey; 
    char    *lpszValue; 
    char    *lpVal; 
    char    *lpszToken; 
    char    lpszDefault[] = "Default"; 
    char    *lpMem = lpMMFile + *nOffset; 
    int     nList; 
 
 
    /* allocate lots of memory off heap to save calling applications' stack */ 
    if (!(lpszKeyNames = (char *)LocalAlloc (LPTR, FIFTY_K_LINE))) 
return FALSE; 
    if (!(lpszValue = (char *)LocalAlloc (LPTR, TWO_K_LINE))) 
{ 
LocalFree ((HLOCAL)lpszKeyNames); 
return FALSE; 
} 
    if (!(lpszToken = (char *)LocalAlloc (LPTR, MAXTOKENLEN))) 
{ 
LocalFree ((HLOCAL)lpszKeyNames); 
LocalFree ((HLOCAL)lpszValue); 
return FALSE; 
} 
 
    /* get all keynames in section */ 
    if (((nList = GetPrivateProfileString (lpszSection, 
   NULL, 
   lpszDefault, 
   lpszKeyNames, 
   FIFTY_K_LINE, 
   lpszIniFile)) == (int)(strlen (lpszDefault))) && 
!strcmp (lpszDefault, lpszKeyNames)) 
{ 
LocalFree ((HLOCAL)lpszKeyNames); 
LocalFree ((HLOCAL)lpszValue); 
LocalFree ((HLOCAL)lpszToken); 
return FALSE; 
} 
 
    /* initialize token pointer and first token */ 
    lpKey = lpszKeyNames; 
 
    /* loop through all keynames */ 
    while (TRUE) 
{ 
/* get next token */ 
strcpy (lpszToken, lpKey); 
 
/* get value for token */ 
if ((GetPrivateProfileString (lpszSection, 
     lpszToken, 
     lpszDefault, 
     lpszValue, 
     TWO_K_LINE, 
     lpszIniFile) == strlen (lpszDefault)) && 
    !strcmp (lpszDefault, lpszValue)) 
    { 
    LocalFree ((HLOCAL)lpszKeyNames); 
    LocalFree ((HLOCAL)lpszValue); 
    LocalFree ((HLOCAL)lpszToken); 
    return FALSE; 
    } 
else 
    { 
    /* break line up into components */ 
    ((LPPORT)lpMem)->nPosToken = sizeof (PORT); 
    strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosToken), lpszToken); 
 
    ((LPPORT)lpMem)->nPosHelpStr = 
    ((LPPORT)lpMem)->nPosToken + strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosToken)) + 1; 
    if (lpVal = strtok (lpszValue, ";")) 
strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosHelpStr), lpVal); 
    else 
*(lpMem + ((LPPORT)lpMem)->nPosHelpStr) = 0; 
 
    ((LPPORT)lpMem)->nPosIssue = 
    ((LPPORT)lpMem)->nPosHelpStr + strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosHelpStr)) + 1; 
    if (lpVal = strtok (NULL, ";")) 
strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosIssue), lpVal); 
    else 
*(lpMem + ((LPPORT)lpMem)->nPosIssue) = 0; 
 
    ((LPPORT)lpMem)->nPosSuggest = 
    ((LPPORT)lpMem)->nPosIssue + strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosIssue)) + 1; 
    if (lpVal = strtok (NULL, ";")) 
strcpy ((char *)(lpMem + ((LPPORT)lpMem)->nPosSuggest), lpVal); 
    else 
*(lpMem + ((LPPORT)lpMem)->nPosSuggest) = 0; 
 
    /* set size of dynamic token structure */ 
    ((LPPORT)lpMem)->nSize = (((LPPORT)lpMem)->nPosSuggest + 
 strlen ((char *)(lpMem + ((LPPORT)lpMem)->nPosSuggest)) + 1); 
 
    /* adjust nSize for DWORD alignment */ 
            ((LPPORT)lpMem)->nSize = ((((LPPORT)lpMem)->nSize) + 3) & ~3; 
 
    /* set token type */ 
    ((LPPORT)lpMem)->dwType = dwType; 
 
    /* adjust list pointer to point beginning of next list element */ 
    lpMem += ((LPPORT)lpMem)->nSize; 
    } 
 
/* increment token pointer and test for end of list */ 
if (((lpKey += strlen (lpszToken) + 1) - lpszKeyNames) >= (nList - 1)) 
    { 
    /* indicate end of list by setting size of next element to 0 */ 
    ((LPPORT)lpMem)->nSize = 0; 
    break; 
    } 
} 
 
    /* got to end of section, clean up and go away */ 
    LocalFree ((HLOCAL)lpszKeyNames); 
    LocalFree ((HLOCAL)lpszValue); 
    LocalFree ((HLOCAL)lpszToken); 
 
    /* recalculate offset */ 
    *nOffset = lpMem - lpMMFile; 
 
    /* return successful load */ 
    return TRUE; 
} 
 
 
/* retrieve ini file and path */ 
BOOL WINAPI GetIniFile ( 
HANDLEhDLL, 
char*lpszFileName, 
    char    *lpszFile) 
{ 
    char    lpszPath[MAX_PATH]; 
    char    *lpPath; 
// char lpszFileName[MAX_PATH]; 
OFSTRUCTof; 
 
// Is this a full path ? If so there must be a : or \ in there somewhere. 
lpPath = lpszFileName; 
while ( *lpPath ) 
{ 
   if ( *lpPath == '\\' || *lpPath == ':' ) 
   { 
  if ((OpenFile (lpszFileName, &of, OF_EXIST))) 
  { 
 // Name passed in is OK. 
 strcpy (lpszFile, lpszFileName); 
 return TRUE; 
  } 
 
   } 
   lpPath = CharNext(lpPath); 
} 
 
// OK, not a full path, we must build one 
 
    /* get module directory and path */ 
    GetModuleFileName (hDLL, lpszPath, MAX_PATH); 
    lpPath = lpszPath + strlen (lpszPath); 
 
    /* find end of path by searching backwards from end to first '\' or ':' */ 
    while (lpPath > lpszPath) 
    { 
    if (*lpPath == '\\' || 
        *lpPath == ':') 
        { 
        lpPath++; 
        break; 
        } 
    lpPath = CharPrev(lpszPath, lpPath); 
    } 
 
    /* terminate at end of path */ 
    *lpPath = 0; 
 
    /* append ini filename to path */ 
strcat (lpPath, lpszFileName); 
 
// check for an extension ( look for '.' before '\' ) 
lpPath = lpszPath+strlen(lpszPath); 
while ( lpPath > lpszPath &&  
            *lpPath != '\\' &&  
            *lpPath != ':') 
{ 
   if ( *lpPath == '.') 
  break; 
   lpPath = CharPrev(lpszPath, lpPath); 
} 
 
if ( *lpPath != '.' ) 
{ 
   // No extension, supply one 
   strcat (lpszPath, ".INI"); 
} 
 
 
    /* test for existance */ 
    if (!(OpenFile (lpszPath, &of, OF_EXIST))) 
{ 
GetWindowsDirectory (lpszPath, MAX_PATH); 
strcat (lpszPath, lpszFileName); 
if (!(OpenFile (lpszPath, &of, OF_EXIST))) 
{ 
return FALSE; 
} 
else 
    { 
    strcpy (lpszFile, lpszPath); 
    return TRUE; 
    } 
} 
    else 
{ 
strcpy (lpszFile, lpszPath); 
return TRUE; 
} 
}