home *** CD-ROM | disk | FTP | other *** search
/ IBM Presents OS/2 Software Hits 1995 / OS-2_SW_HITS_2ND_EDITION_1995.ISO / i17 / ur423841.dsk / CSDX.DFI / DFIEXALF.C < prev    next >
C/C++ Source or Header  |  1993-06-24  |  28KB  |  584 lines

  1. /**:DOC***********************************************************************/
  2. /*                                                                           */
  3. /* Part Name:        DFIEXALF C                                              */
  4. /*                                                                           */
  5. /* Descriptive Name: Alert filter exit.                                      */
  6. /*                                                                           */
  7. /* Copyright:        None                                                    */
  8. /*                                                                           */
  9. /* Status:           LAN Network Manager 1.0                                 */
  10. /*                                                                           */
  11. /* Function:         User customized alert filtering.                        */
  12. /*                                                                           */
  13. /* Entry Points:                                                             */
  14. /*   AdapterFilter   Uses NMVT information to determine whether to pass an   */
  15. /*                   alert to NetView or block it.                           */
  16. /*                                                                           */
  17. /*                                                                           */
  18. /* 06/24/93 P5154 PRK Initialization for the char arrays are not done        */
  19. /**:EDOC**********************************************************************/
  20.  
  21. #define         INCL_DOSSEMAPHORES
  22. #define         PASS      0
  23. #define         BLOCK     1
  24. #define         MAX_SUBFIELD_LEN 512
  25.  
  26. #include        <os2.h>
  27. #include        <string.h>
  28. #include        <stdlib.h>
  29.  
  30. PCHAR Ebcdic2Ascii(PCHAR, PCHAR, USHORT);
  31. PCHAR Ascii2Ebcdic(PCHAR, PCHAR, USHORT);
  32. VOID AddrFromHex(PBYTE, PCHAR);
  33.  
  34. CHAR achAdapterAddress[13]; /* Adapter address to pass through filter */
  35.  
  36. /*****************************************************************************/
  37. /* The variables declared in this area are all set in the filter routine to
  38.    contain information parsed from the NMVT alert vector.  They represent much
  39.    of the information contained in the alert vector, but not all of it.  An
  40.    attempt was made to incude the data the user would be most likely to want
  41.    to use to filter alerts.  Since this sample routine filters by adapter
  42.    address, only those variables containing addresses are used in the filtering
  43.    comparison.  The other variables are provided to allow filtering using
  44.    different criteria. */
  45.  
  46. /* Data from subvector 0x05: hierarchy/resource list */
  47.  
  48. BYTE bResType;        /* One byte hex codepoint indicating resource type */
  49. CHAR achResName[9];   /* Resource name */
  50.  
  51. /* Data from subvector 0x51: LAN link connection subsystem data */
  52.  
  53. CHAR achLanId[255];       /* LAN identifier */
  54. BYTE bSegNumber[2];       /* Two byte ring or segment number */
  55. CHAR achLocAddr[13],      /* Local individual MAC address */
  56.      achRemAddr[13];      /* Remote individual MAC address */
  57. BYTE bRoutingInfo[18];    /* LAN routing information - up to 18 bytes */
  58. BYTE bBeaconData;         /* Specifies type of beaconing detected */
  59. CHAR achUpAddr[13] ,       /* Upstream adapter MAC address */
  60.      achDownAddr[13],     /* Downstream adapter MAC address */
  61.      achSingAddr[13];     /* Single MAC address */
  62. BYTE bDownWeight[2],      /* Binary severity weight for downstream MAC element*/
  63.      bUpWeight[2],        /* Binary severity weight for upstream MAC element*/
  64.      bBridgeId[4];        /* Bridge Identifier */
  65. CHAR achLocName[16],      /* Local individual MAC name */
  66.      achRemName[16],      /* Remote individual MAC name */
  67.      achDownName[16],     /* Downstream MAC element ring fault domain name */
  68.      achUpName[16],       /* Upstream MAC element ring fault domain name */
  69.      achSingName[16];     /* Single MAC name */
  70.  
  71. /* Data from subvector 0x52: Link connection subsystem configuration data */
  72.  
  73. BYTE bPortAddr[2],        /* Port address of the link connection */
  74.      bRemDevAddr,         /* DLC address of the remote link station */
  75.      bLcsTopology,        /* LPDA-2 modem LCS topology */
  76.      bLocDevAddr,         /* Address of the local link station */
  77.      bLcsCorrNum[2],      /* Modem LCS correlation number */
  78.      bLinkStatAttr[2],    /* Modem LCS link station attributes */
  79.      bLinkConnAttr[4],    /* Modem LCS link connection attributes */
  80.      bLslDesc;            /* LPDA fault link segment descriptor */
  81.  
  82. /* Data from subvector 0x92: Generic alert data */
  83.  
  84. BYTE bAlertType,          /* One byte codepoint indicating alert type */
  85.      bAlertDesc[2];       /* Two byte codepoint indicating alert description */
  86.  
  87. /* Data from subvector 0x93: Probable causes */
  88.  
  89. BYTE bProbCauses[10][2];  /* Array of two byte probable cause codepoints */
  90.  
  91. /* Data from subvector 0x94: User causes */
  92.  
  93. BYTE bUserCauses[10][2],  /* Array of two byte user cause codepoints */
  94.      bUserActions[10][2]; /* Array of two byte recommended actions codepoints */
  95.                           /* for user causes */
  96. CHAR achUserAddr[13];     /* Address from user causes detailed data */
  97.  
  98. /* Data from subvector 0x95: Installation causes */
  99.  
  100. BYTE bInstCauses[10][2],  /* Array of two byte installation cause codepoints */
  101.      bInstActions[10][2]; /* Array of two byte recommended actions codepoints */
  102.                           /* for installation causes */
  103. CHAR achFailAddr[13],     /* Address from failure causes detailed data */
  104.      achInstAddr[13];     /* Address from install causes detailed data */
  105.  
  106. /* Data from subvector 0x96: Failure causes */
  107.  
  108. BYTE bFailCauses[10][2],  /* Array of two byte failure cause codepoints */
  109.      bFailActions[10][2]; /* Array of two byte recommended actions codepoints */
  110.                           /* for failure causes */
  111. CHAR achInstAddr[13];     /* Address from install causes detailed data */
  112.  
  113. /*****************************************************************************/
  114.  
  115. BYTE bSvLen,   /* Subvector length */
  116.      bSvId,    /* Subvector ID */
  117.      bSfLen,   /* Subvector subfield length */
  118.      bSfId,    /* Subvector subfield ID */
  119.      bLength;  /* Misc. length variable */
  120.  
  121. CHAR *pNmvtPtr,  /* Pointer to NMVT alert vector */
  122.      *pSubField, /* Pointer to NMVT alert subfield */
  123.      achAscii[MAX_SUBFIELD_LEN];   /* Holds strings converted from EBCDIC */
  124.  
  125. USHORT usCounter, usCount, usMvLen ; /* Counter for loops, and MvLength */
  126.  
  127. /**:DOC***********************************************************************/
  128. /*                                                                           */
  129. /* Entry Point: AdapterFilter                                                */
  130. /*                                                                           */
  131. /* Purpose:                                                                  */
  132. /*   This function filters alerts by adapter address, allowing only alerts   */
  133. /*   with the specified address to be passed to NetView.                     */
  134. /*                                                                           */
  135. /* Parameters:                                                               */
  136. /*   pNmvt         INPUT  - PBYTE      - Pointer to NMVT.                    */
  137. /*                                                                           */
  138. /* Linkage:                                                                  */
  139. /*   AdapterFilter(PBYTE pNmvt);                                             */
  140. /*                                                                           */
  141. /* Error Indicators:                                                         */
  142. /*   None.                                                                   */
  143. /*                                                                           */
  144. /* Msgid's Processed:  None.                                                 */
  145. /*                                                                           */
  146. /* Special Instructions to Caller:                                           */
  147. /*    Because this function is declared as a PASCAL function, the compiler   */
  148. /* translates the routine's name to uppercase. LAN Network Manager forces    */
  149. /* the routine name to uppercase when it is typed in on the Alert Filters    */
  150. /* window. The programmer should be aware of this fact, but does not need to */
  151. /* make any extra effort to work around it.                                  */
  152. /*                                                                           */
  153. /**:EDOC**********************************************************************/
  154.  
  155. USHORT far PASCAL AdapterFilter(PBYTE pNmvtPtr)
  156. {
  157.   BYTE abTemp[2], bRc;
  158.  
  159. /* Set address string to desired adapter address to pass */
  160. strcpy(achAdapterAddress, "101010101010");
  161. //VIBMPRAK PTR 5154 
  162. achLocAddr[0] ='\0';
  163. achRemAddr[0] ='\0';
  164. achSingAddr[0] ='\0';
  165. achUpAddr[0] ='\0';
  166. achDownAddr[0] ='\0';
  167. achUserAddr[0] ='\0';
  168. achFailAddr[0] ='\0';
  169. achInstAddr[0] ='\0';
  170.  
  171. /* Advance pointer past Nmvt header */
  172. pNmvtPtr += 8;
  173.  
  174. usCount = 4;
  175. abTemp[1]  = *pNmvtPtr;
  176. abTemp[0]  = *(pNmvtPtr+1);
  177. usMvLen  = *((USHORT *)abTemp);
  178.  
  179. pNmvtPtr += 4;   /* Advance the pointer to 1st subvector field */
  180.  
  181. /* Parse alert vector */
  182. while (usCount < usMvLen)
  183.    {
  184.    bSvLen = *pNmvtPtr;     /* Subvector length and ID are first 2 bytes */
  185.    bSvId = *(pNmvtPtr+1);
  186.    switch (bSvId)
  187.       {
  188.       case 0x05: /* Heirarchy-resource list */
  189.          /* This subvector (x'05') contains the resource name and type */
  190.          pSubField = pNmvtPtr + 5;
  191.          while (pSubField < (pNmvtPtr + bSvLen))
  192.             {
  193.             /* Frame text fields are in EBCDIC so... */
  194.             Ebcdic2Ascii((pSubField+1), (PCHAR)achAscii, (USHORT)(*pSubField));
  195.             if (!(bRc = (BYTE)memcmp(achResName, achAscii, (USHORT)(*pSubField))))
  196.                break;
  197.             pSubField += (CHAR) *pSubField;  /* jump to end of resource name */
  198.             pSubField++;                     /* step over 'flags' byte */
  199.             bResType = (BYTE) *pSubField;
  200.             pSubField++;                     /* point to next field length */
  201.             }
  202.          break;
  203.  
  204.       case 0x51: /* LAN link connection subsystem data */
  205.          /* This subvector (0x51) contains data on the elements of the LAN
  206.             link connection */
  207.          pSubField = pNmvtPtr+2;
  208.          while((BYTE)(pSubField - pNmvtPtr) < bSvLen)
  209.             {
  210.             bSfLen = *pSubField;
  211.             bSfId = *(pSubField+1);
  212.             switch(bSfId)
  213.                {
  214.                case 0x01: /* Lan identifier */
  215.                   memcpy(achLanId, pSubField+2, bSfLen-2);
  216.                   break;
  217.                case 0x02: /* Ring/segment identifier */
  218.                   memcpy(bSegNumber, pSubField+2, 2);
  219.                   break;
  220.                case 0x03: /* Local individual MAC address */
  221.                   AddrFromHex(pSubField+2,achLocAddr);
  222.                   break;
  223.                case 0x04: /* Remote individual MAC address */
  224.                   AddrFromHex(pSubField+2,achRemAddr);
  225.                   break;
  226.                case 0x05: /* LAN routing information used by link */
  227.                   memcpy(bRoutingInfo, pSubField+2, bSfLen-2);
  228.                   break;
  229.                case 0x06: /* Ring fault domain description */
  230.                   AddrFromHex(pSubField+2,achDownAddr);
  231.                   AddrFromHex(pSubField+8,achUpAddr);
  232.                   break;
  233.                case 0x07: /* Beaconing data */
  234.                   memcpy(&bBeaconData,pSubField+2, 1);
  235.                   break;
  236.                case 0x08: /* Single MAC address */
  237.                   AddrFromHex(pSubField+2,achSingAddr);
  238.                   break;
  239.                case 0x09: /* Fault domain error weight pair */
  240.                   memcpy(bDownWeight, pSubField+2, 2);
  241.                   memcpy(bUpWeight, pSubField+4, 2);
  242.                   break;
  243.                case 0x0A: /* Bridge identifier */
  244.                   memcpy(bBridgeId, pSubField+2, 4);
  245.                   break;
  246.                case 0x23: /* Local individual MAC name */
  247.                   memcpy(achLocName, pSubField+2, bSfLen-2);
  248.                   break;
  249.                case 0x24: /* Remote individual MAC name */
  250.                   memcpy(achRemName, pSubField+2, bSfLen-2);
  251.                   break;
  252.                case 0x26: /* Fault domain names */
  253.                   bLength = *(pSubField+2);
  254.                   memcpy(achDownName, pSubField+3, bLength-1);
  255.                   bLength = *(pSubField+2+bLength);
  256.                   memcpy(achUpName, pSubField+3+bLength, bLength-1);
  257.                   break;
  258.                case 0x28: /* Single MAC name */
  259.                   memcpy(achSingName, pSubField+2, bSfLen-2);
  260.                   break;
  261.                default:  /* Unrecognized subfield id */
  262.                   break;
  263.                } /* end switch */
  264.             pSubField += bSfLen; /* Advance pointer to next subfield */
  265.             } /* end while */
  266.          break;
  267.       case 0x52: /* Link connection subsystem configuration data */
  268.          /* This subvector (x'52') contains data for link connections with LAN
  269.             or LPDA-2 modems*/
  270.          pSubField = pNmvtPtr+2;
  271.          while((BYTE)(pSubField - pNmvtPtr) < bSvLen)
  272.             {
  273.             bSfLen = *pSubField;
  274.             bSfId = *(pSubField+1);
  275.             switch(bSfId)
  276.                {
  277.                case 0x01: /* Port address */
  278.                   memcpy(bPortAddr, pSubField+2, 2);
  279.                   break;
  280.                case 0x02: /* Remote device address */
  281.                   memcpy(&bRemDevAddr, pSubField+2, 1);
  282.                   break;
  283.                case 0x03: /* Modem LCS topology */
  284.                   memcpy(&bLcsTopology, pSubField+2, 1);
  285.                   break;
  286.                case 0x04: /* Local device address */
  287.                   memcpy(&bLocDevAddr, pSubField+2, 1);
  288.                   break;
  289.                case 0x05: /* Modem LCS correlation number */
  290.                   memcpy(bLcsCorrNum, pSubField+2, 2);
  291.                   break;
  292.                case 0x06: /* Modem LCS link station attributes */
  293.                   memcpy(bLinkStatAttr, pSubField+2, 2);
  294.                   break;
  295.                case 0x07: /* Modem LCS link attributes*/
  296.                   memcpy(bLinkConnAttr, pSubField+2, 4);
  297.                   break;
  298.                case 0x08: /* LPDA fault link segment descriptor */
  299.                   memcpy(&bLslDesc, pSubField+2, 1);
  300.                   break;
  301.                default:  /* Unrecognized subfield id */
  302.                   break;
  303.                } /* end switch */
  304.             pSubField += bSfLen; /* Advance pointer to next subfield */
  305.             } /* end while */
  306.          break;
  307.       case 0x92: /* Generic alert data */
  308.          pSubField = pNmvtPtr+4;
  309.          memcpy(&bAlertType, pSubField, 1);
  310.          memcpy(bAlertDesc, pSubField+1, 2);
  311.          break;
  312.       case 0x93: /* Probable causes */
  313.          usCounter = 0;
  314.          pSubField = pNmvtPtr+2;
  315.          while((BYTE)(pSubField - pNmvtPtr) < bSvLen)
  316.             {
  317.             memcpy(bProbCauses[usCounter], pSubField, 2);
  318.             pSubField+=2;
  319.             ++usCounter;
  320.             } /* end while */
  321.          break;
  322.       case 0x94: /* User causes */
  323.          pSubField = pNmvtPtr+2;
  324.          while((BYTE)(pSubField - pNmvtPtr) < bSvLen)
  325.             {
  326.             bSfLen = *pSubField;
  327.             bSfId = *(pSubField+1);
  328.             switch(bSfId)
  329.                {
  330.                case 0x01: /* User Causes */
  331.                   usCounter=0;
  332.                   while(usCounter*2 < bSfLen)
  333.                      {
  334.                      /* Load all user cause codepoints into array */
  335.                      memcpy(bUserCauses[usCounter],
  336.                             pSubField+(usCounter+1)*2, 2);
  337.                      usCounter++ ;
  338.                      }
  339.                   break;
  340.                case 0x81: /* Recommended actions */
  341.                   usCounter=0;
  342.                   while(usCounter*2 < bSfLen)
  343.                      {
  344.                      /*Load all user recommended action codepoints into array */
  345.                      memcpy(bUserActions[usCounter],
  346.                             pSubField+(usCounter+1)*2, 2);
  347.                      usCounter++ ;
  348.                      }
  349.                   break;
  350.                case 0x82: /* Detailed data */
  351.                   /* if subfield length is 2, no detailed data is present */
  352.                   if (bSfLen == 2)
  353.                      break;
  354.                   /* if detailed data type is 0x61 detailed data is address */
  355.                   if ( (BYTE)*(pSubField+3) == 0x61 )
  356.                      AddrFromHex(pSubField+5,achUserAddr);
  357.                   break;
  358.                case 0x83: /* Product set ID index */
  359.                   break;
  360.                default:  /* Unrecognized subfield id */
  361.                   break;
  362.                } /* end switch */
  363.             pSubField += bSfLen;
  364.             } /* end while */
  365.          break;
  366.       case 0x95: /* Install causes */
  367.          pSubField = pNmvtPtr+2;
  368.          while((BYTE)(pSubField - pNmvtPtr) < bSvLen)
  369.             {
  370.             bSfLen = *pSubField;
  371.             bSfId = *(pSubField+1);
  372.             switch(bSfId)
  373.                {
  374.                case 0x01: /* Install Causes */
  375.                   usCounter=0;
  376.                   while(usCounter*2 < bSfLen)
  377.                      {
  378.                      /* Load all installation cause codepoints into array */
  379.                      memcpy(bInstCauses[usCounter],
  380.                             pSubField+(usCounter+1)*2, 2);
  381.                      usCounter++ ;
  382.                      }
  383.                   break;
  384.                case 0x81: /* Recommended actions */
  385.                   usCounter=0;
  386.                   while(usCounter*2 < bSfLen)
  387.                      {
  388.                      /* Load all installation recommended action codepoints */
  389.                      /* into array */
  390.                      memcpy(bInstActions[usCounter],
  391.                             pSubField+(usCounter+1)*2, 2);
  392.                      usCounter++ ;
  393.                      }
  394.                   break;
  395.                case 0x82: /* Detailed data */
  396.                   /* if subfield length is 2, no detailed data is present */
  397.                   if (bSfLen == 2)
  398.                      break;
  399.                   /* if detailed data type is 0x61 detailed data is address */
  400.                   if ( (BYTE)*(pSubField+3) == 0x61 )
  401.                      AddrFromHex(pSubField+5,achInstAddr);
  402.                   break;
  403.                case 0x83: /* Product set ID index */
  404.                   break;
  405.                default:  /* Unrecognized subfield id */
  406.                   break;
  407.                } /* end switch */
  408.             pSubField += bSfLen;
  409.             } /* end while */
  410.          break;
  411.       case 0x96: /* Failure causes */
  412.          pSubField = pNmvtPtr+2;
  413.          while((BYTE)(pSubField - pNmvtPtr) < bSvLen)
  414.             {
  415.             bSfLen = *pSubField;
  416.             bSfId = *(pSubField+1);
  417.             switch(bSfId)
  418.                {
  419.                case 0x01: /* Failure Causes */
  420.                   usCounter=0;
  421.                   while(usCounter*2 < bSfLen)
  422.                      {
  423.                      /* Load all failure cause codepoints into array */
  424.                      memcpy(bFailCauses[usCounter],
  425.                             pSubField+(usCounter+1)*2, 2);
  426.                      usCounter++ ;
  427.                      }
  428.                   break;
  429.                case 0x81: /* Recommended actions */
  430.                   usCounter=0;
  431.                   while(usCounter*2 < bSfLen)
  432.                      {
  433.                      /* Load all failure recommended action codepoints */
  434.                      /* into array */
  435.                      memcpy(bFailActions[usCounter],
  436.                             pSubField+(usCounter+1)*2, 2);
  437.                      usCounter++ ;
  438.                      }
  439.                   break;
  440.                case 0x82: /* Detailed data */
  441.                   /* if subfield length is 2, no detailed data is present */
  442.                   if (bSfLen == 2)
  443.                      break;
  444.                   /* if detailed data type is 0x61 detailed data is address */
  445.                   if ( (BYTE)*(pSubField+3) == 0x61 )
  446.                      AddrFromHex(pSubField+5,achFailAddr);
  447.                   break;
  448.                case 0x83: /* Product set ID index */
  449.                   break;
  450.                default:  /* Unrecognized subfield id */
  451.                   break;
  452.                } /* end switch */
  453.             pSubField += bSfLen;
  454.             } /* end while */
  455.          break;
  456.       default:
  457.          break;
  458.       } /* end switch */
  459.    pNmvtPtr+=bSvLen; /* Advance pointer and counter to next subvector */
  460.    usCount += bSvLen ;
  461.    } /* end while */
  462.  
  463. /* Compare address fields from NMVT alert vector with address of adapter
  464.    whose alerts are to be passed to NetView.  Return BLOCK or PASS to the
  465.    LAN Network Manager alert filter */
  466.  
  467. if ( !(strcmp(achAdapterAddress, achLocAddr )) ||
  468.      !(strcmp(achAdapterAddress, achRemAddr )) ||
  469.      !(strcmp(achAdapterAddress, achSingAddr)) ||
  470.      !(strcmp(achAdapterAddress, achUpAddr  )) ||
  471.      !(strcmp(achAdapterAddress, achDownAddr)) ||
  472.      !(strcmp(achAdapterAddress, achUserAddr)) ||
  473.      !(strcmp(achAdapterAddress, achFailAddr)) ||
  474.      !(strcmp(achAdapterAddress, achInstAddr)) ||
  475.      !bRc )
  476.    return(PASS);
  477. else
  478.    return(BLOCK);
  479. }
  480.  
  481. /***************************************************************************/
  482. /* This function converts a six byte numeric address to 12 hex characters  */
  483. /***************************************************************************/
  484.  
  485. VOID AddrFromHex(PBYTE pHexBytes, PCHAR pCharArray)
  486.  
  487. /* pHexBytes must point to the first byte of the six byte address */
  488. /* pCharArray must point to a 13 character array to store the hex address */
  489.  
  490. {
  491. CHAR achStr[3]; /* String to store result of itoa function */
  492. USHORT usCtr;   /* loop counter */
  493.  
  494. for (usCtr=0; usCtr < 6; usCtr++)
  495.    {
  496.    itoa( (USHORT)*(pHexBytes+usCtr), achStr, 16);
  497.    if(achStr[1] == '\0')
  498.       {
  499.       achStr[1] = achStr[0];
  500.       achStr[0] = '0';
  501.       }
  502.    if(achStr[0] >= 'a' && achStr[0] <= 'f') achStr[0] -= 32;
  503.    if(achStr[1] >= 'a' && achStr[1] <= 'f') achStr[1] -= 32;
  504.    *(pCharArray + 2*usCtr) = achStr[0];
  505.    *(pCharArray + 2*usCtr+1) = achStr[1];
  506.    }
  507. *(pCharArray+12) = '\0'; /* Add null terminator */
  508. }
  509.  
  510. /***************************************************************************/
  511. /* Converts an EBCDIC string to ASCII, returning a pointer to the NULL     */
  512. /* terminated ASCII string. The ASCII string must be big enough to hold    */
  513. /* usLen+1 bytes.                                                          */
  514. /***************************************************************************/
  515.  
  516. PCHAR Ebcdic2Ascii(PCHAR pEbcdic, PCHAR pAscii, USHORT usLen)
  517. {
  518.           CHAR *pReturnMe = pAscii;
  519.    static BYTE XlatTable[] =
  520.       {
  521. /*         _0    _1    _2    _3    _4    _5    _6    _7    _8    _9    _A    _B    _C    _D    _E    _F */
  522. /* 0_ */ 0x00, 0x01, 0x02, 0x03, 0xCF, 0x09, 0xD3, 0x7F, 0xD4, 0xD5, 0xC3, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  523.          0x10, 0x11, 0x12, 0x13, 0xC7, 0xB4, 0x08, 0xC9, 0x18, 0x19, 0xCC, 0xCD, 0x83, 0x1D, 0xD2, 0x1F,
  524.          0x81, 0x82, 0x1C, 0x84, 0x86, 0x0A, 0x17, 0x1B, 0x89, 0x91, 0x92, 0x95, 0xA2, 0x05, 0x06, 0x07,
  525.          0xE0, 0xEE, 0x16, 0xE5, 0xD0, 0x1E, 0xEA, 0x04, 0x8A, 0xF6, 0xC6, 0xC2, 0x14, 0x15, 0xC1, 0x1A,
  526.          0x20, 0xA6, 0xE1, 0x80, 0xEB, 0x90, 0x9F, 0xE2, 0xAB, 0x8B, 0x9B, 0x2E, 0x3C, 0x28, 0x2B, 0x7C,
  527. /* 5_ */ 0x26, 0xA9, 0xAA, 0x9C, 0xDB, 0xA5, 0x99, 0xE3, 0xA8, 0x9E, 0x21, 0x24, 0x2A, 0x29, 0x3B, 0x5E,
  528.          0x2D, 0x2F, 0xDF, 0xDC, 0x9A, 0xDD, 0xDE, 0x98, 0x9D, 0xAC, 0xBA, 0x2C, 0x25, 0x5F, 0x3E, 0x3F,
  529.          0xD7, 0x88, 0x94, 0xB0, 0xB1, 0xB2, 0xFC, 0xD6, 0xFB, 0x60, 0x3A, 0x23, 0x40, 0x27, 0x3D, 0x22,
  530.          0xF8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x96, 0xA4, 0xF3, 0xAF, 0xAE, 0xC5,
  531.          0x8C, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x97, 0x87, 0xCE, 0x93, 0xF1, 0xFE,
  532. /* A_ */ 0xC8, 0x7E, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0xEF, 0xC0, 0xDA, 0x5B, 0xF2, 0xF9,
  533.          0xB5, 0xB6, 0xFD, 0xB7, 0xB8, 0xB9, 0xE6, 0xBB, 0xBC, 0xBD, 0x8D, 0xD9, 0xBF, 0x5D, 0xD8, 0xC4,
  534.          0x7B, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0xCB, 0xCA, 0xBE, 0xE8, 0xEC, 0xED,
  535.          0x7D, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0xA1, 0xAD, 0xF5, 0xF4, 0xA3, 0x8F,
  536.          0x5C, 0xE7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0xA0, 0x85, 0x8E, 0xE9, 0xE4, 0xD1,
  537. /* F_ */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0xB3, 0xF7, 0xF0, 0xFA, 0xA7, 0xFF
  538.       };
  539.  
  540.    while (usLen--)
  541.       *pAscii++ = (CHAR) XlatTable[*((UCHAR *)pEbcdic++)];
  542.    *pAscii = (CHAR) NULL;
  543.  
  544.    return pReturnMe;
  545. }
  546.  
  547. /***************************************************************************/
  548. /* Converts an ASCII string to EBCDIC, returning a pointer to the NULL     */
  549. /* terminated EBCDIC string. The EBCDIC string must be big enough to hold  */
  550. /* usLen+1 bytes.                                                          */
  551. /***************************************************************************/
  552.  
  553. PCHAR Ascii2Ebcdic(PCHAR pAscii, PCHAR pEbcdic, USHORT usLen)
  554. {
  555.           CHAR *pReturnMe = pEbcdic;
  556.    static BYTE XlatTable[] =
  557.       {
  558. /*         _0    _1    _2    _3    _4    _5    _6    _7    _8    _9    _A    _B    _C    _D    _E    _F */
  559. /* 0_ */ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F, 0x16, 0x05, 0x25, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  560.          0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26, 0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x35, 0x1F,
  561.          0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D, 0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
  562.          0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
  563.          0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
  564. /* 5_ */ 0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xAD, 0xE0, 0xBD, 0x5F, 0x6D,
  565.          0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
  566.          0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
  567.          0x43, 0x20, 0x21, 0x1C, 0x23, 0xEB, 0x24, 0x9B, 0x71, 0x28, 0x38, 0x49, 0x90, 0xBA, 0xEC, 0xDF,
  568.          0x45, 0x29, 0x2A, 0x9D, 0x72, 0x2B, 0x8A, 0x9A, 0x67, 0x56, 0x64, 0x4A, 0x53, 0x68, 0x59, 0x46,
  569. /* A_ */ 0xEA, 0xDA, 0x2C, 0xDE, 0x8B, 0x55, 0x41, 0xFE, 0x58, 0x51, 0x52, 0x48, 0x69, 0xDB, 0x8E, 0x8D,
  570.          0x73, 0x74, 0x75, 0xFA, 0x15, 0xB0, 0xB1, 0xB3, 0xB4, 0xB5, 0x6A, 0xB7, 0xB8, 0xB9, 0xCC, 0xBC,
  571.          0xAB, 0x3E, 0x3B, 0x0A, 0xBF, 0x8F, 0x3A, 0x14, 0xA0, 0x17, 0xCB, 0xCA, 0x1A, 0x1B, 0x9C, 0x04,
  572.          0x34, 0xEF, 0x1E, 0x06, 0x08, 0x09, 0x77, 0x70, 0xBE, 0xBB, 0xAC, 0x54, 0x63, 0x65, 0x66, 0x62,
  573.          0x30, 0x42, 0x47, 0x57, 0xEE, 0x33, 0xB6, 0xE1, 0xCD, 0xED, 0x36, 0x44, 0xCE, 0xCF, 0x31, 0xAA,
  574. /* F_ */ 0xFC, 0x9E, 0xAE, 0x8C, 0xDD, 0xDC, 0x39, 0xFB, 0x80, 0xAF, 0xFD, 0x78, 0x76, 0xB2, 0x9F, 0xFF
  575.  
  576.       };
  577.  
  578.    while (usLen--)
  579.       *pEbcdic++ = (CHAR) XlatTable[*((UCHAR *)pAscii++)];
  580.    *pEbcdic = (CHAR) NULL;
  581.  
  582.    return pReturnMe;
  583. }
  584.