cominfo.c
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:16k
源码类别:
操作系统开发
开发平台:
Visual C++
- /*********************************************************************
- * Microsoft Diagnostics Version 2.0
- *
- * A diagnostic utility to detect as much useful information about a
- * customer's computer system as is possible.
- *
- * Microsoft Diagnostics: We detect the World.
- *
- * COMINFO.C - Source file for serial port detection code.
- ********************************************************************/
- /* Include Files */
- #include "msd.h"
- /*********************************************************************
- * GetComInfo - Gets the COM port information.
- *
- * Returns: TRUE if an error occured.
- *********************************************************************/
- BOOL GetComInfo (COM_STRUCT *pCom, BOOL fMinimumInfo)
- {
- WORD i, wWait; /* Looping variables */
- WORD wIndex; /* Index for strings */
- WORD wPort; /* COM port address */
- WORD wLCR; /* Line Control Register value */
- WORD wMSR; /* Modem Status Register value */
- WORD wNewIID; /* Used to store changed IID value */
- DWORD dwBaudRateDivisor; /* Used to calculate the baud rate */
- BOOL fArcnetCard; /* True if the 02E0-02EF range should */
- /* be avoided */
- /* 40:0 is the port address of the first valid COM port */
- WORD FAR * fwPortAddress = (WORD FAR *) 0x00400000;
- /* Determine if an Arcnet card is present at 02E0 */
- fArcnetCard = ArcnetCardPresent();
- /* Set the values in the structure for each port */
- /* Zero out the count of COM ports */
- pCom->wNmbrComPorts = 0;
- for (i = 0; i < MAX_COM_PORTS; ++i)
- {
- {
- /* Load the port address from the DOS Device table, if it exists */
- pCom->ComxInfo[i].wPortAddress = *(fwPortAddress++);
- wPort = pCom->ComxInfo[i].wPortAddress;
- /* Determine if the port exists in the right range */
- if (wPort >= 0x220 && wPort <= 0x3FF)
- {
- ++(pCom->wNmbrComPorts);
- pCom->ComxInfo[i].fComPortDetected = TRUE;
- }
- else
- pCom->ComxInfo[i].fComPortDetected = FALSE;
- /* If the Arcnet card is present, disable COM4 testing */
- if (fArcnetCard && wPort >= 0x2E0 && wPort <= 0x2FF)
- pCom->ComxInfo[i].fComPortDetected = FALSE;
- if (fMinimumInfo || !(pCom->ComxInfo[i].fComPortDetected))
- continue;
- }
- {
- /* Read the Line Control Register Port */
- wLCR = inp (wPort + 3);
- /* If the DLAB bit (bit 7) is 1, we can obtain the Baud Rate */
- /* Divisor from *fwPortAddress (LSB) and *fwPortAddress + 1 */
- /* (MSB) */
- /* If the DLAB bit is not set, set it, then read the Baud Rate */
- /* Divisor */
- if (!(0x80 & wLCR))
- outp (wPort + 3, 0x80 | wLCR);
- /* Pause briefly for the port to respond */
- for (wWait = 0; wWait < 25; ++wWait)
- ;
- dwBaudRateDivisor = (WORD) (inp (wPort)) +
- (WORD) (inp (wPort + 1) << 8);
- /* Pause briefly for the port to respond */
- for (wWait = 0; wWait < 25; ++wWait)
- ;
- /* If the DLAB bit was not set originally, put it back to it's */
- /* original state. */
- if (!(0x80 & wLCR))
- outp (wPort + 3, wLCR);
- }
- {
- /* Calculate the BAUD rate */
- if (dwBaudRateDivisor == 0)
- pCom->ComxInfo[i].dwBaudRate = 0;
- else
- pCom->ComxInfo[i].dwBaudRate = 115200L / dwBaudRateDivisor;
- }
- {
- /* Parity - If bit 3 of the LCR register is off, parity is none. */
- /* none. If bit 3 is on, bits 4 and 5 come into play */
- /* like this: */
- /* */
- /* Bits: 5 4 */
- /* 0 0 - Odd parity */
- /* 0 1 - Even parity */
- /* 1 0 - Mark parity */
- /* 1 1 - Space parity */
- if ((wLCR & 0x08) == 0)
- pCom->ComxInfo[i].wParity = 0;
- else
- pCom->ComxInfo[i].wParity = ((wLCR & 0x30) >> 4) + 1;
- memset (pCom->ComxInfo[i].szParity, ' ', MAX_PARITY);
- wIndex = pCom->ComxInfo[i].wParity;
- strcpy (pCom->ComxInfo[i].szParity, paszParityDesc[wIndex]);
- }
- {
- /* Data Bits - Stored in the LCR in bits 0 and 1: */
- /* */
- /* Bits: 1 0 */
- /* 0 0 - 5 data bits */
- /* 0 1 - 6 data bits */
- /* 1 0 - 7 data bits */
- /* 1 1 - 8 data bits */
- pCom->ComxInfo[i].wDataBits = (wLCR & 0x03) + 5;
- }
- {
- /* Stop Bits - Stored in the LCR in bit 2. Off is 1 stop bit, */
- /* On is two stop bits. */
- /* Note: If data bits is 5 and LCR bit 2 is on, */
- /* stop bits = 1.5. */
- pCom->ComxInfo[i].wStopBits = (wLCR & 0x04) ? 2 : 1;
- if (pCom->ComxInfo[i].wDataBits == 5 &&
- pCom->ComxInfo[i].wStopBits == 2)
- pCom->ComxInfo[i].wStopBits = 3;
- }
- {
- /* Read the Modem Status Register values */
- wMSR = inp (wPort + 6);
- }
- {
- /* Carrier Detect is bit 7 of the MSR */
- pCom->ComxInfo[i].fCarrierDetect = (wMSR & 0x80) ? TRUE : FALSE;
- }
- {
- /* Ring Indicator is bit 6 of the MSR */
- pCom->ComxInfo[i].fRingIndicator = (wMSR & 0x40) ? TRUE : FALSE;
- }
- {
- /* Data Set Ready (DSR) is bit 5 of the MSR */
- pCom->ComxInfo[i].fDataSetReady = (wMSR & 0x20) ? TRUE : FALSE;
- }
- {
- /* Clear to Send is bit 4 of the MSR */
- pCom->ComxInfo[i].fClearToSend = (wMSR & 0x10) ? TRUE : FALSE;
- }
- {
- /* Determine the UART chip type. This is accomplished by */
- /* outputing 11000001 to the FIFO Control Register (FCR). */
- /* Then, bits 6 and 7 are checked to see if they are on. The */
- /* list below shows how the chip type is determined: */
- /* */
- /* Bits: 7 6 */
- /* 0 0 - INS8250 UART */
- /* 0 1 - Unknown */
- /* 1 0 - NS16550 UART */
- /* 1 1 - NS16550AN UART */
- /* */
- /* This may cause problems with TSR communications programs and */
- /* COM programs running in OS/2 or Windows while MSD runs, */
- /* because in order to determine the chip type, I must modify */
- /* the behavior of the UART chip. */
- /* Turn on bits 6 and 7 */
- outp (wPort + 2, 0xC1);
- /* Pause for a moment to allow the port to take the change. */
- for (wWait = 0; wWait < 25; ++wWait)
- ;
- /* Read the changed value */
- wNewIID = inp (wPort + 2);
- /* Set the chip type, based on bits 6 and 7 */
- wIndex = pCom->ComxInfo[i].wUartChip = wNewIID >> 6;
- memset (pCom->ComxInfo[i].szUartChip, ' ', MAX_UART_CHIP);
- strcpy (pCom->ComxInfo[i].szUartChip, paszUartChips[wIndex]);
- }
- }
- return (FALSE);
- }
- /*********************************************************************
- * SprintComInfo - Put Com port information into a set of strings to
- * be printed or displayed.
- *
- * Returns: NULL if an error occured.
- *********************************************************************/
- QSZ * SprintComInfo (COM_STRUCT *pCom,
- CHAR szSumStrings[][MAX_SUMM_INFO + 5])
- {
- WORD wNmbrStrings; /* Number of strings */
- WORD wNmbrChars; /* Number of characters in the strings */
- WORD wComIndex; /* Index to the structure of COM data */
- WORD i; /* Looping variables */
- QSZ *pqszStrings = NULL; /* Location for storing string pointers */
- /* Summary information */
- if (szSumStrings != NULL)
- {
- sprintf (szSumStrings[0], "%d", pCom->wNmbrComPorts);
- return (NULL);
- }
- /* Calculate the amount of space required for the strings */
- wNmbrChars = (MAX_COM_TITLES + 3) * (MAX_COM_INFO_LINE + 1);
- wNmbrStrings = MAX_COM_TITLES + 3;
- /* Allocate space for the pointer area and string area */
- pqszStrings = AllocStringSpace (wNmbrStrings, wNmbrChars);
- if (pqszStrings == NULL)
- return (NULL);
- /* Put the first two strings in place */
- Qmemset (pqszStrings[0], ' ', COM_TITLE_WIDTH + COM_INFO_COL_WIDTH - 5);
- Qstrcpy (&pqszStrings[0][COM_TITLE_WIDTH + COM_INFO_COL_WIDTH - 5],
- pszComHeader);
- pqszStrings[1] = pqszStrings[0] + Qstrlen (pqszStrings[0]) + 1;
- Qmemset (pqszStrings[1], ' ', COM_TITLE_WIDTH + COM_INFO_COL_WIDTH - 5);
- Qstrcpy (&pqszStrings[1][COM_TITLE_WIDTH + COM_INFO_COL_WIDTH - 5],
- pszComUnderline);
- pqszStrings[2] = pqszStrings[1] + Qstrlen (pqszStrings[1]) + 1;
- /* Put the COM port information in place */
- for (i = 2, wComIndex = 0; wComIndex < MAX_COM_TITLES;
- ++i, ++wComIndex)
- {
- WORD wPort; /* Port number for each display line */
- WORD wLength; /* Current length of string */
- WORD wInfoColumn; /* Column to place the information */
- CHAR chBuffer[80]; /* Buffer for string data */
- PSZ pszString = NULL; /* String pointer */
- /* Clear out the string */
- Qmemset (pqszStrings[i], ' ', MAX_COM_INFO_LINE);
- pqszStrings[i][MAX_COM_INFO_LINE] = ' ';
- /* Put on the title */
- Qstrncpy (pqszStrings[i], paszComTitles[wComIndex],
- strlen (paszComTitles[wComIndex]));
- for (wPort = 0; wPort < MAX_COM_PORTS; ++wPort)
- {
- wInfoColumn = wPort * COM_INFO_COL_WIDTH + COM_TITLE_WIDTH;
- /* Put the N/A under the Port Address for ports that don't exist */
- if (wComIndex == COM_PORT_ADDRESS &&
- pCom->ComxInfo[wPort].fComPortDetected == FALSE)
- {
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], pszNA,
- strlen (pszNA), COM_INFO_COL_WIDTH);
- }
- /* Add the strings only if the COM port exists */
- if (pCom->ComxInfo[wPort].fComPortDetected)
- {
- switch (wComIndex)
- {
- case COM_PORT_ADDRESS:
- {
- sprintf (chBuffer, "%04XH",
- pCom->ComxInfo[wPort].wPortAddress);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], chBuffer,
- strlen (chBuffer), COM_INFO_COL_WIDTH);
- break;
- }
- case COM_BAUD_RATE:
- {
- sprintf (chBuffer, "%Lu",
- pCom->ComxInfo[wPort].dwBaudRate);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], chBuffer,
- strlen (chBuffer), COM_INFO_COL_WIDTH);
- break;
- }
- case COM_PARITY:
- {
- wLength = strlen (pCom->ComxInfo[wPort].szParity);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn],
- pCom->ComxInfo[wPort].szParity,
- wLength, COM_INFO_COL_WIDTH);
- break;
- }
- case COM_DATA_BITS:
- {
- sprintf (chBuffer, "%d",
- pCom->ComxInfo[wPort].wDataBits);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], chBuffer,
- strlen (chBuffer), COM_INFO_COL_WIDTH);
- break;
- }
- case COM_STOP_BITS:
- {
- if (pCom->ComxInfo[wPort].wStopBits < 3)
- {
- sprintf (chBuffer, "%d",
- pCom->ComxInfo[wPort].wStopBits);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn],
- chBuffer,
- strlen (chBuffer),
- COM_INFO_COL_WIDTH);
- }
- else
- {
- wLength = strlen (psz1point5);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn],
- psz1point5,
- wLength,
- COM_INFO_COL_WIDTH);
- }
- break;
- }
- case COM_CARRIER_DETECT:
- {
- pszString = (pCom->ComxInfo[wPort].fCarrierDetect) ?
- pszYes : pszNo;
- wLength = strlen (pszString);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], pszString,
- wLength, COM_INFO_COL_WIDTH);
- break;
- }
- case COM_RING_INDICATOR:
- {
- pszString = (pCom->ComxInfo[wPort].fRingIndicator) ?
- pszYes : pszNo;
- wLength = strlen (pszString);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], pszString,
- wLength, COM_INFO_COL_WIDTH);
- break;
- }
- case COM_DATA_SET_READY:
- {
- pszString = (pCom->ComxInfo[wPort].fDataSetReady) ?
- pszYes : pszNo;
- wLength = strlen (pszString);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], pszString,
- wLength, COM_INFO_COL_WIDTH);
- break;
- }
- case COM_CLEAR_TO_SEND:
- {
- pszString = (pCom->ComxInfo[wPort].fClearToSend) ?
- pszYes : pszNo;
- wLength = strlen (pszString);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn], pszString,
- wLength, COM_INFO_COL_WIDTH);
- break;
- }
- case COM_UART_CHIP:
- {
- wLength = strlen (pCom->ComxInfo[wPort].szUartChip);
- QstrncpyAlign (&pqszStrings[i][wInfoColumn],
- pCom->ComxInfo[wPort].szUartChip,
- wLength, COM_INFO_COL_WIDTH);
- break;
- }
- }
- }
- }
- PrepNextString (pqszStrings, i);
- }
- /* Set the last pointer to a NULL */
- pqszStrings[i] = NULL;
- /* Return the pointer to pqszStrings */
- return (pqszStrings);
- }