tsrlist.c
资源名称:DOS系统的源代码.rar [点击查看]
上传用户:xiaoan1112
上传日期:2013-04-11
资源大小:19621k
文件大小:29k
源码类别:
操作系统开发
开发平台:
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.
- *
- * TSRLIST.C - TSR Program detection routines.
- *********************************************************************/
- /* Include Files */
- #include "msd.h"
- /* Made global to this file. This prevents filling the structure with */
- /* more TSR info than was previously allocated (on the extremely odd */
- /* case of finding more TSRs when we actually get the driver info */
- /* than when we counted up how many there were. Under multitasking */
- /* systems, the addition of a new TSR installing while this program */
- /* is running is a rare, though potential, possibility. */
- WORD wTsrCount = 0; /* The number of TSRs installed in memory */
- /*********************************************************************
- * GetTsrInfoSize - Gets number of bytes required to store the data
- * about the TSRs installed in the system.
- *
- * Returns: The bytes required for the structure.
- *********************************************************************/
- WORD GetTsrInfoSize (VOID)
- {
- CHAR FAR * fpMcbHeader = NULL; /* Pointer to the MCB header */
- CHAR FAR * fpDeviceMemory = NULL; /* Pointer into device driver memory */
- DWORD dwNextDeviceMemory = 0; /* Pointer into next device driver */
- /* memory */
- DWORD dwNextMcbHeader = 0; /* Pointer to next MCB header */
- WORD FAR * fwWordPointer = NULL; /* WORD pointer to obtain WORD data */
- /* from the MCB. */
- WORD wMcbParagraphs = 0; /* Size of the MCB in paragraphs */
- BOOL fEndOfList = FALSE; /* TRUE when last MCB accounted for */
- /* Zero out the TSR count */
- wTsrCount = 0;
- /* Add the UMB chain to the DOS MCB chain */
- LinkUmbToDosChain (TRUE);
- /* Point to the first MCB */
- fpMcbHeader = FindFirstMcbHeader();
- /* Count MCBs until the MCB type is 'Z' */
- /* ('Z' signifies the end of the list) */
- while (fEndOfList == FALSE)
- {
- ++wTsrCount;
- /* Get the size of the MCB */
- fwWordPointer = (WORD FAR *) (fpMcbHeader + 1);
- wMcbParagraphs = fwWordPointer[1];
- /* Determine if this was the last MCB */
- if (*fpMcbHeader == 'Z')
- fEndOfList = TRUE;
- else
- {
- /* Determine if there are device drivers in this list */
- if (wDosMajor >= 4 && wDosMajor < 10 &&
- fpMcbHeader[8] == 'S' && fpMcbHeader[9] == 'D')
- {
- fpDeviceMemory = (CHAR FAR *)
- ((((DWORD) FP_SEG (fpMcbHeader) + 1) << 16) + 0);
- /* Is this a valid DOS data area subsegment control block */
- while (strchr ("DEIFXCBLS", fpDeviceMemory[0]))
- {
- /* If this is one we are interested in, */
- /* bump the TSR count */
- /* if (fpDeviceMemory[0] == 'D' || fpDeviceMemory[0] == 'I') */
- ++wTsrCount;
- /* Point to the next device */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- dwNextDeviceMemory = *fwWordPointer;
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- dwNextDeviceMemory += *fwWordPointer;
- fpDeviceMemory = (CHAR FAR *) (dwNextDeviceMemory << 16);
- }
- }
- /* Point to the next MCB */
- dwNextMcbHeader = (DWORD) fpMcbHeader +
- ((DWORD) (wMcbParagraphs + 1) << 16);
- fpMcbHeader = (CHAR FAR *) dwNextMcbHeader;
- }
- }
- /* Account for the zeroed out TSR record at the end of the struct */
- ++wTsrCount;
- /* Set the UMB/DOS MCB chain back to normal */
- LinkUmbToDosChain (FALSE);
- /* Return the number of bytes required to store the structure */
- return (wTsrCount * sizeof (TSR_PROGRAMS_STRUCT));
- }
- /*********************************************************************
- * GetTsrInfo - Fills the TSR_PROGRAMS_STRUCT with information about
- * the TSR programs installed in the system.
- *
- * Returns: The bytes required for the structure.
- *********************************************************************/
- BOOL GetTsrInfo (TSR_PROGRAMS_STRUCT *pTsrStruct, BOOL fMinimumInfo)
- {
- CHAR FAR * fpMcbHeader = NULL; /* Pointer to the MCB header */
- DWORD dwNextMcbHeader = 0; /* Pointer to next MCB header */
- CHAR FAR * fpPspAddress = NULL; /* Address of the MCB's PSP */
- CHAR FAR * fpParentPspAddress = NULL; /* Address of parent's PSP */
- CHAR FAR * fpTsrName = NULL; /* Points to TSR program's name */
- /* environment (for program name) */
- CHAR FAR * fpCommandLine = NULL; /* Command line parameters */
- WORD wMcbParagraphs = 0; /* Size of the MCB in paragraphs */
- CHAR FAR * fpDeviceMemory = NULL; /* Pointer into device driver subMCB */
- CHAR FAR * fpDeviceStruct = NULL; /* Pointer to device driver itself */
- DWORD dwNextDeviceMemory = 0; /* Pointer into next device driver */
- /* memory */
- WORD FAR * fwWordPointer = NULL; /* WORD pointer to obtain WORD data */
- /* from the MCB. */
- WORD i = 0; /* Looping variable */
- WORD wIndex; /* Index to structure */
- BOOL fEndOfList = FALSE; /* TRUE when last MCB accounted for */
- WORD wCharCount = 0; /* Number of characters in the */
- /* command line. */
- /* There is no minimum info to return from this routine */
- if (fMinimumInfo)
- return (FALSE);
- /* Add the UMB chain to the DOS MCB chain */
- LinkUmbToDosChain (TRUE);
- /* Point to the first MCB */
- fpMcbHeader = FindFirstMcbHeader();
- /* Count MCBs until the MCB type is 'Z' */
- /* ('Z' signifies the end of the list) */
- for (wIndex = 0; wIndex < wTsrCount - 1 && fEndOfList == FALSE; ++wIndex)
- {
- /* Store the address of the MCB */
- pTsrStruct[wIndex].wAddress = FP_SEG (fpMcbHeader);
- /* Get the size of the MCB */
- fwWordPointer = (WORD FAR *) (fpMcbHeader + 1);
- wMcbParagraphs = fwWordPointer[1];
- pTsrStruct[wIndex].dwBlockSize = (DWORD) wMcbParagraphs << 4;
- /* Caluclate PSP and parent's PSP */
- fpPspAddress = (CHAR FAR *) ((DWORD) fwWordPointer[0] << 16);
- fwWordPointer = (WORD FAR *) (fpPspAddress + 16);
- fpParentPspAddress = (CHAR FAR *) ((DWORD) *fwWordPointer << 16);
- /* Get the MCB's Owner's name */
- /* If the PSP Segment is 0000H it's free, */
- /* if it's 0008H, it's the DOS System Area. */
- if (FP_SEG (fpPspAddress) == 0x0000)
- {
- strcpy (pTsrStruct[wIndex].szTsrName, pszFreeMemory);
- pTsrStruct[wIndex].szParameters[0] = ' ';
- }
- else if (FP_SEG (fpPspAddress) == 0x0008)
- {
- /* Determine if it is the device driver area, etc */
- if (wDosMajor >= 4 && wDosMajor < 10)
- {
- /* "SC" is System Code / Locked out UMBs */
- if (wDosMajor >= 5 &&
- fpMcbHeader[8] == 'S' && fpMcbHeader[9] == 'C')
- {
- /* If the address + block size > A0000, it's */
- /* a locked out region. */
- if (((DWORD) (pTsrStruct[wIndex].wAddress) << 4) +
- pTsrStruct[wIndex].dwBlockSize > 0xA0000)
- strcpy (pTsrStruct[wIndex].szTsrName, pszExcludedUmbArea);
- else
- strcpy (pTsrStruct[wIndex].szTsrName, pszDosSystemCode);
- pTsrStruct[wIndex].szParameters[0] = ' ';
- }
- /* "SD" is System Data / Device Drivers, etc */
- else if (wDosMajor == 4 || (wDosMajor >= 5 &&
- fpMcbHeader[8] == 'S' && fpMcbHeader[9] == 'D'))
- {
- strcpy (pTsrStruct[wIndex].szTsrName, pszDosSystemData);
- pTsrStruct[wIndex].szParameters[0] = ' ';
- fpDeviceMemory = (CHAR FAR *)
- ((((DWORD) FP_SEG (fpMcbHeader) + 1) << 16) + 0);
- /* Is this a valid DOS data area subsegment control block */
- for (++wIndex;
- strchr ("DEIFXCBLS", fpDeviceMemory[0]) &&
- wIndex < wTsrCount - 1 && fEndOfList == FALSE;
- ++wIndex)
- {
- pTsrStruct[wIndex].szParameters[0] = ' ';
- switch (fpDeviceMemory[0])
- {
- case 'D':
- case 'I':
- /* If this is a device driver or installable */
- /* file system, put the device name and */
- /* device filename into the structure. */
- /* Address */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- pTsrStruct[wIndex].wAddress = *fwWordPointer;
- /* Point to the Device Name */
- fpDeviceStruct = (CHAR FAR *)
- (((DWORD) (*fwWordPointer)) << 16);
- /* Size */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- pTsrStruct[wIndex].dwBlockSize =
- ((DWORD) (*fwWordPointer)) << 4;
- /* Device Filename */
- pTsrStruct[wIndex].szTsrName[0] = ' ';
- pTsrStruct[wIndex].szTsrName[1] = ' ';
- _fmemcpy (&(pTsrStruct[wIndex].szTsrName[2]),
- &fpDeviceMemory[8], 8);
- pTsrStruct[wIndex].szTsrName[10] = ' ';
- /* Device Name */
- fwWordPointer = (WORD FAR *) (fpDeviceStruct + 4);
- if (*fwWordPointer & 0x8000)
- {
- /* Character Device */
- _fmemcpy (pTsrStruct[wIndex].szParameters,
- &fpDeviceStruct[10], 8);
- pTsrStruct[wIndex].szParameters[8] = ' ';
- }
- else
- {
- /* Block Device */
- strcpy (pTsrStruct[wIndex].szParameters,
- pszBlockDevice);
- }
- break;
- case 'E':
- strcpy (pTsrStruct[wIndex].szTsrName,
- pszDeviceAppenage);
- /* Address */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- pTsrStruct[wIndex].wAddress = *fwWordPointer;
- /* Size */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- pTsrStruct[wIndex].dwBlockSize =
- ((DWORD) (*fwWordPointer)) << 4;
- break;
- case 'F':
- strcpy (pTsrStruct[wIndex].szTsrName,
- pszFileHandles);
- /* Address */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- pTsrStruct[wIndex].wAddress = *fwWordPointer;
- /* Size */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- pTsrStruct[wIndex].dwBlockSize =
- ((DWORD) (*fwWordPointer)) << 4;
- break;
- case 'X':
- strcpy (pTsrStruct[wIndex].szTsrName,
- pszFCBS);
- /* Address */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- pTsrStruct[wIndex].wAddress = *fwWordPointer;
- /* Size */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- pTsrStruct[wIndex].dwBlockSize =
- ((DWORD) (*fwWordPointer)) << 4;
- break;
- case 'C':
- case 'B':
- strcpy (pTsrStruct[wIndex].szTsrName,
- pszBuffers);
- /* Address */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- pTsrStruct[wIndex].wAddress = *fwWordPointer;
- /* Size */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- pTsrStruct[wIndex].dwBlockSize =
- ((DWORD) (*fwWordPointer)) << 4;
- break;
- case 'L':
- strcpy (pTsrStruct[wIndex].szTsrName,
- pszDirectories);
- /* Address */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- pTsrStruct[wIndex].wAddress = *fwWordPointer;
- /* Size */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- pTsrStruct[wIndex].dwBlockSize =
- ((DWORD) (*fwWordPointer)) << 4;
- break;
- case 'S':
- strcpy (pTsrStruct[wIndex].szTsrName,
- pszStacksArea);
- /* Address */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- pTsrStruct[wIndex].wAddress = *fwWordPointer;
- /* Size */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- pTsrStruct[wIndex].dwBlockSize =
- ((DWORD) (*fwWordPointer)) << 4;
- break;
- }
- /* Point to the next device */
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 1);
- dwNextDeviceMemory = *fwWordPointer;
- fwWordPointer = (WORD FAR *) (fpDeviceMemory + 3);
- dwNextDeviceMemory += *fwWordPointer;
- fpDeviceMemory = (CHAR FAR *) (dwNextDeviceMemory << 16);
- }
- --wIndex;
- }
- /* We'll call this the DOS System Area, otherwise */
- else
- {
- strcpy (pTsrStruct[wIndex].szTsrName, pszDosSystemArea);
- pTsrStruct[wIndex].szParameters[0] = ' ';
- }
- }
- else
- {
- strcpy (pTsrStruct[wIndex].szTsrName, pszDosSystemArea);
- pTsrStruct[wIndex].szParameters[0] = ' ';
- }
- }
- else
- {
- /* If the PSP == the parent's PSP, it's COMMAND.COM */
- if (fpPspAddress == fpParentPspAddress)
- strcpy (pTsrStruct[wIndex].szTsrName, pszCommandCom);
- else
- {
- /* Otherwise, we have to find the name. First, search */
- /* in the environment area. */
- CHAR chEnvironName[80]; /* Buffer for storing what the */
- /* environment claims the is */
- /* the name of the TSR */
- fwWordPointer = (WORD FAR *) (fpPspAddress + 0x002C);
- fpTsrName = (CHAR FAR *) ((DWORD) *fwWordPointer << 16);
- /* The name of the program that owns this MCB is located */
- /* 2 bytes after 2 zero bytes and a word count. Loop */
- /* through the environment block until 2 back-to-back */
- /* zero bytes are located. */
- while (!(fpTsrName[0] == 0 && fpTsrName[1] == 0))
- ++fpTsrName;
- fpTsrName += 4;
- /* fpTsrName is now pointing to the fully qualified path */
- /* to the program name. Parse for just the program name. */
- for (i = 0; i < MAX_TSR_NAME - 1 &&
- *fpTsrName > ' ' &&
- *fpTsrName < 127; ++fpTsrName)
- {
- if (*fpTsrName == '\')
- i = 0;
- else
- chEnvironName[i++] = *fpTsrName;
- }
- /* If this was the real name, it should end with a zero */
- /* byte. If it was garbage, we should have dropped out */
- /* because fpTsrName pointed to something other than a */
- /* zero byte, or the length of the string is zero. */
- if (*fpTsrName == ' ')
- chEnvironName[i] = ' ';
- else
- chEnvironName[0] = ' ';
- /* The name from the environment is now ready. Next, */
- /* get the MCB owner (DOS 4.0 and above). If the MCB */
- /* owner is the same as the beginning of the name from */
- /* the environment, use chEnvironName. Otherwise, use */
- /* the MCB name. */
- if (wDosMajor < 4)
- {
- /* If there is no name, put in "???" */
- if (strlen (chEnvironName) == 0)
- strcpy (pTsrStruct[wIndex].szTsrName, "???");
- else
- strcpy (pTsrStruct[wIndex].szTsrName, chEnvironName);
- }
- else
- {
- /* Obtain the program name from the MCB */
- fpTsrName = fpMcbHeader + 8;
- for (i = 0; i < 8 &&
- *fpTsrName > ' ' &&
- *fpTsrName < 127 &&
- *fpTsrName == (CHAR) toupper (*fpTsrName);
- ++i, ++fpTsrName)
- {
- pTsrStruct[wIndex].szTsrName[i] = *fpTsrName;
- }
- pTsrStruct[wIndex].szTsrName[i] = ' ';
- /* Determine if this is a valid program name. If we */
- /* have not taken 8 characters from the MCB, we */
- /* should have run into a zero byte (the name is */
- /* null terminated if there are less than 8 */
- /* characters). */
- if (i < 8 && (*fpTsrName != ' ' ||
- pTsrStruct[wIndex].szTsrName[0] == ' '))
- {
- /* Use the environment name */
- strcpy (pTsrStruct[wIndex].szTsrName, chEnvironName);
- }
- /* The MCB contains a valid name. Check to see if the */
- /* environment contains a more complete name (ie, */
- /* the environment contains an extention, the MCB */
- /* does not. */
- else if (strnicmp (chEnvironName,
- pTsrStruct[wIndex].szTsrName,
- strlen (pTsrStruct[wIndex].szTsrName)) == 0)
- {
- strcpy (pTsrStruct[wIndex].szTsrName, chEnvironName);
- }
- if (strnicmp (pszCommand, pTsrStruct[wIndex].szTsrName,
- strlen (pszCommand)) == 0)
- {
- /* The word "command" was found, put COMMAND.COM */
- /* into the TSR Name field. */
- strcpy (pTsrStruct[wIndex].szTsrName, pszCommandCom);
- }
- if (pTsrStruct[wIndex].szTsrName[0] == ' ')
- {
- /* A valid program name could not be found */
- strcpy (pTsrStruct[wIndex].szTsrName, "???");
- }
- }
- }
- /* Get the command line parameters */
- fpCommandLine = fpPspAddress + 0x0080;
- /* The first byte is the number of characters in the */
- /* command line. */
- wCharCount = fpCommandLine[0];
- if (wCharCount > MAX_TSR_CMD_LINE - 1)
- wCharCount = MAX_TSR_CMD_LINE - 1;
- ++fpCommandLine;
- for (i = 0; i < wCharCount &&
- fpCommandLine[i] >= ' ' &&
- fpCommandLine[i] <= 127; ++i)
- pTsrStruct[wIndex].szParameters[i] = fpCommandLine[i];
- pTsrStruct[wIndex].szParameters[i] = ' ';
- }
- /* Determine if this was the last MCB */
- if (*fpMcbHeader == 'Z')
- fEndOfList = TRUE;
- else
- {
- /* Point to the next MCB */
- dwNextMcbHeader = (DWORD) fpMcbHeader +
- ((DWORD) (wMcbParagraphs + 1) << 16);
- fpMcbHeader = (CHAR FAR *) dwNextMcbHeader;
- }
- }
- /* Set the last record to zeroes */
- pTsrStruct[wIndex].wAddress = 0;
- pTsrStruct[wIndex].dwBlockSize = 0;
- pTsrStruct[wIndex].szTsrName[0] = ' ';
- pTsrStruct[wIndex].szParameters[0] = ' ';
- /* Set the UMB/DOS MCB chain back to normal */
- LinkUmbToDosChain (FALSE);
- return (FALSE);
- }
- /*********************************************************************
- * SprintTsrInfo - Put TSR program information into a set of strings
- * to be printed or displayed.
- * fIncludeParms - TRUE if command line parameters are to be included.
- *
- * Returns: NULL if an error occured.
- *********************************************************************/
- QSZ * SprintTsrInfo (TSR_PROGRAMS_STRUCT *pTsrStruct,
- BOOL fIncludeParms)
- {
- WORD wNmbrStrings; /* Number of strings */
- WORD wNmbrChars; /* Number of characters in the strings */
- WORD wUnderlineLength; /* Length of the underline string */
- WORD wIndex; /* Index to the structure of TSR data */
- WORD i; /* Looping variable */
- QSZ *pqszStrings = NULL; /* Location for storing string pointers */
- /* Calculate the amount of space required for the strings */
- wUnderlineLength = strlen (pszTsrUnderline);
- if (fIncludeParms)
- {
- wNmbrChars = strlen (pszTsrHeader) + 1 +
- wUnderlineLength + 1 +
- (wTsrCount * (wUnderlineLength + 1));
- if (wNmbrChars > _memmax() - 100)
- fIncludeParms = FALSE;
- }
- if (fIncludeParms == FALSE)
- wNmbrChars = strlen (pszTsrHeader) + 1 +
- wUnderlineLength + 1 +
- (wTsrCount * (TSR_CMD_LINE_COL + 1));
- /* The underline string is expected to be as long as a line of */
- /* TSR program info. */
- wNmbrStrings = wTsrCount + 3;
- /* "+ 3" is for the header line, the underline, and the NULL */
- /* pointer at the end of the array. */
- /* 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 */
- Qstrcpy (pqszStrings[0], pszTsrHeader);
- pqszStrings[1] = pqszStrings[0] + Qstrlen (pqszStrings[0]) + 1;
- Qstrcpy (pqszStrings[1], pszTsrUnderline);
- pqszStrings[2] = pqszStrings[1] + wUnderlineLength + 1;
- /* Put the TSR information in place */
- for (i = 2, wIndex = 0;
- !(pTsrStruct[wIndex].wAddress == 0 &&
- pTsrStruct[wIndex].dwBlockSize == 0);
- ++i, ++wIndex)
- {
- WORD wLength; /* Current length of string */
- CHAR chBuffer[80]; /* Buffer for string data */
- /* Fill the line with spaces */
- Qmemset (pqszStrings[i], ' ', wUnderlineLength);
- pqszStrings[i][wUnderlineLength] = ' ';
- /* TSR Name */
- Qstrcpy (pqszStrings[i], pTsrStruct[wIndex].szTsrName);
- wLength = Qstrlen (pqszStrings[i]);
- pqszStrings[i][wLength] = ' ';
- /* Size */
- wLength = sprintf (chBuffer, "%6lu",
- pTsrStruct[wIndex].dwBlockSize);
- Qstrcpy (&pqszStrings[i][TSR_SIZE_COL], chBuffer);
- pqszStrings[i][TSR_SIZE_COL + wLength] = ' ';
- /* Address */
- wLength = sprintf (chBuffer, "%04X", pTsrStruct[wIndex].wAddress);
- Qstrcpy (&pqszStrings[i][TSR_ADDRESS_COL], chBuffer);
- pqszStrings[i][TSR_ADDRESS_COL + wLength] = ' ';
- /* Command line parameters */
- if (fIncludeParms)
- Qstrcpy (&pqszStrings[i][TSR_CMD_LINE_COL],
- pTsrStruct[wIndex].szParameters);
- /* Set the next pointer */
- PrepNextString (pqszStrings, i);
- }
- /* Set the last pointer to NULL */
- pqszStrings[i] = NULL;
- /* Return the pointer to pqszStrings */
- return (pqszStrings);
- }
- /*********************************************************************
- * FindFirstMcbHeader - Finds the pointer to the first memory control
- * block (MCB).
- *
- * Returns: Far pointer to the first MCB.
- *********************************************************************/
- CHAR FAR * FindFirstMcbHeader (VOID)
- {
- union REGS regsIn, regsOut; /* Register structures for int86x call */
- struct SREGS sregs; /* Segment registers for int86x call */
- WORD wMcbSegment = 0; /* Segment of first MCB */
- WORD FAR *fwWordPointer = NULL; /* A far pointer to a WORD */
- /* Get the address of the start of DOS' list of lists (ES:BX) */
- regsIn.h.ah = 0x52;
- int86x (0x21, ®sIn, ®sOut, &sregs);
- /* Get first MCB Segment */
- fwWordPointer = (WORD FAR *)
- ((((long) (sregs.es) << 16) + (long) (regsOut.x.bx)) - 2);
- wMcbSegment = *fwWordPointer;
- /* Return pointer to the first MCB */
- return ((CHAR FAR *) ((DWORD) wMcbSegment << 16));
- }
- /*********************************************************************
- * LinkUmbToDosChain - Links or unlinks UMBs to the DOS memory control
- * block chain.
- * fLinkFlag - TRUE - Link UMBs to the DOS MCB chain.
- * FALSE - Set the chain back to the default.
- *********************************************************************/
- VOID LinkUmbToDosChain (BOOL fLinkFlag)
- {
- union REGS regsin, regsout; /* Register structs for int86 call */
- static BOOL fDefaultLink = 0xFFFF; /* Set to DOS Default of UMBs linked */
- /* or unlinked */
- /* Are we running under a valid version of DOS */
- if (wDosMajor >= 5 && wDosMajor < 10)
- {
- /* Set the default, if necessary */
- if (fDefaultLink == 0xFFFF)
- {
- regsin.x.ax = 0x5802;
- int86 (0x21, ®sin, ®sout);
- if (regsout.x.cflag == 0)
- fDefaultLink = (BOOL) regsout.h.al;
- else
- return;
- }
- /* Now, set the link as per the request */
- regsin.x.ax = 0x5803;
- if (fLinkFlag)
- {
- /* Link the UMB chain to the DOS MCB chain */
- regsin.x.bx = 0x0001;
- int86 (0x21, ®sin, ®sout);
- }
- else
- {
- /* Set the UMB chain link to the default state */
- regsin.x.bx = fDefaultLink;
- int86 (0x21, ®sin, ®sout);
- }
- }
- }