Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

467 lines
18 KiB

  1. ;/*
  2. ; * Microsoft Confidential
  3. ; * Copyright (C) Microsoft Corporation 1988 - 1991
  4. ; * All Rights Reserved.
  5. ; */
  6. /*----------------------------------------------------------------------+
  7. | |
  8. | |
  9. | Title: MEM |
  10. | |
  11. | Syntax: |
  12. | |
  13. | From the DOS command line: |
  14. | |
  15. | MEM |
  16. | - Used to display DOS memory map summary. |
  17. | |
  18. | MEM /PROGRAM |
  19. | - Used to display DOS memory map. |
  20. | |
  21. | MEM /DEBUG |
  22. | - Used to display a detailed DOS memory map. |
  23. | |
  24. | AN001 - PTM P2914 -> This PTM relates to MEM's ability to report|
  25. | the accurate total byte count for EM |
  26. | memory. |
  27. | |
  28. | AN002 - PTM P3477 -> MEM was displaying erroneous base memory |
  29. | information for "Total" and "Available" |
  30. | memory. This was due to incorrect logic |
  31. | for RAM carving. |
  32. | |
  33. | AN003 - PTM P3912 -> MEM messages do not conform to spec. |
  34. | PTM P3989 |
  35. | |
  36. | Date: 1/28/88 |
  37. | |
  38. | AN004 - PTM P4510 -> MEM does not give correct DOS size. |
  39. | |
  40. | Date: 4/27/88 |
  41. | |
  42. | AN005 - PTM P4957 -> MEM does not give correct DOS size for |
  43. | programs loaded into high memory. |
  44. | |
  45. | Date: 6/07/88 |
  46. | |
  47. | Revision History |
  48. | ================ |
  49. | |
  50. | M000 SR 8/27/90 Added new Ctrl-C handler to delink UMBs |
  51. | |
  52. | M003 NSM 12/28/90 Added a New switch /Classify which |
  53. | groups programs in conv and UMB and gives sizes |
  54. | in decimal and hex. |
  55. | |
  56. +----------------------------------------------------------------------*/
  57. /*���������������������������������������������������������������������������*/
  58. #include "ctype.h"
  59. #include "conio.h" /* need for kbhit prototype */
  60. #include "stdio.h"
  61. #include "dos.h"
  62. #include "string.h"
  63. #include "stdlib.h"
  64. #include "msgdef.h"
  65. #include "parse.h"
  66. #include "version.h" /* MSKK02 07/18/89 */
  67. #include "mem.h"
  68. /*���������������������������������������������������������������������������*/
  69. /* All global declarations go here */
  70. char *SingleDrive = "%c:" ;
  71. char *MultipleDrives = "%c: - %c:" ;
  72. char *UnOwned = "----------" ;
  73. #if IBMCOPYRIGHT /*EGH*/
  74. char *Ibmbio = "IBMBIO" ; /*EGH*/
  75. char *Ibmdos = "IBMDOS" ; /*EGH*/
  76. #else /*EGH*/
  77. char *Ibmbio = "IO " ;
  78. char *Ibmdos = "MSDOS " ;
  79. #endif /*EGH*/
  80. char LinkedIn = 0; /* Flag set when mem links in UMBs :M000 */
  81. void (interrupt far *OldCtrlc)(); /* Old Ctrlc handler save vector :M000*/
  82. /*----------------------------------------------------------------------+
  83. | define structure used by parser |
  84. +----------------------------------------------------------------------*/
  85. struct p_parms p_p;
  86. struct p_parmsx p_px;
  87. struct p_control_blk p_con1;
  88. struct p_control_blk p_con2;
  89. struct p_control_blk p_con3;
  90. struct p_control_blk p_con4;
  91. struct p_result_blk p_result1;
  92. struct p_result_blk p_result2;
  93. struct p_result_blk p_result3;
  94. struct p_result_blk p_result4;
  95. struct p_value_blk p_noval;
  96. /*���������������������������������������������������������������������������*/
  97. struct sublistx sublist[5];
  98. unsigned far *ArenaHeadPtr;
  99. struct SYSIVAR far *SysVarsPtr;
  100. char OwnerName[128];
  101. char TypeText[128];
  102. char cmd_line[128];
  103. char far *cmdline;
  104. unsigned UMB_Head;
  105. unsigned LastPSP=0;
  106. char UseArgvZero = TRUE;
  107. char EMSInstalledFlag = (char) 2;
  108. union REGS InRegs;
  109. union REGS OutRegs;
  110. struct SREGS SegRegs;
  111. int DataLevel;
  112. int Classify; /* M003 */
  113. int i;
  114. int BlockDeviceNumber;
  115. char *Parse_Ptr; /* ;an003; dms; pointer to command */
  116. struct mem_classif mem_table[100]; /* M003 */
  117. int noof_progs = 0; /* no of entries in mem_table above */
  118. /*���������������������������������������������������������������������������*/
  119. void interrupt cdecl far MemCtrlc (unsigned es, unsigned ds,
  120. unsigned di, unsigned si, unsigned bp, unsigned sp,
  121. unsigned bx, unsigned dx, unsigned cx, unsigned ax );
  122. int main()
  123. {
  124. unsigned char UMB_Linkage;
  125. unsigned int rc=0; /* init to NO ERROR */
  126. sysloadmsg(&InRegs,&OutRegs);
  127. if ((OutRegs.x.cflag & CarryFlag) == CarryFlag)
  128. {
  129. sysdispmsg(&OutRegs,&OutRegs);
  130. exit(1);
  131. }
  132. InRegs.h.ah = (unsigned char) 0x62; /* an000; dms; get the PSP */
  133. intdosx(&InRegs, &InRegs, &SegRegs); /* an000; dms; invoke the INT 21 */
  134. FP_OFF(cmdline) = 0x81; /* an000; dms; offset of command line */
  135. FP_SEG(cmdline) = InRegs.x.bx; /* an000; dms; segment of command line */
  136. i = 0; /* an000; dms; init index */
  137. while ( *cmdline != (char) '\x0d' ) cmd_line[i++] = *cmdline++; /* an000; dms; while no CR */
  138. cmd_line[i++] = (char) '\x0d'; /* an000; dms; CR terminate string */
  139. cmd_line[i++] = (char) '\0'; /* an000; dms; null terminate string */
  140. DataLevel = Classify = 0; /* M003 */
  141. CSwitch_init(); /* M003: init data structures for */
  142. /* Classify */
  143. parse_init(); /* an000; dms; init for parser */
  144. InRegs.x.si = (unsigned)cmd_line; /* an000; dms; initialize to command ln.*/
  145. InRegs.x.cx = (unsigned)0; /* an000; dms; ordinal of 0 */
  146. InRegs.x.dx = (unsigned)0; /* an000; dms; init pointer */
  147. InRegs.x.di = (unsigned)&p_p; /* an000; dms; point to ctrl blocks */
  148. Parse_Ptr = cmd_line; /*;an003; dms; point to command */
  149. parse(&InRegs,&OutRegs); /* an000; dms; parse command line */
  150. while (OutRegs.x.ax == p_no_error) /* an000; dms; good parse loop */
  151. {
  152. if (p_result4.P_SYNONYM_Ptr == (unsigned int)p_con4.p_keyorsw)
  153. {
  154. for (i = MSG_OPTIONS_FIRST; i <= MSG_OPTIONS_LAST; i++)
  155. Sub0_Message(i, STDOUT, Utility_Msg_Class);
  156. return(0);
  157. }
  158. if (p_result1.P_SYNONYM_Ptr == (unsigned int)p_con1.p_keyorsw || /* DEBUG switch */
  159. p_result1.P_SYNONYM_Ptr == (unsigned int)p_con1.p_keyorsw +
  160. (strlen(p_con1.p_keyorsw)+1))
  161. DataLevel = 2; /* flag DEBUG switch */
  162. if (p_result2.P_SYNONYM_Ptr == (unsigned int)p_con2.p_keyorsw || /* PROGRAM switch */
  163. p_result2.P_SYNONYM_Ptr == (unsigned int)p_con2.p_keyorsw +
  164. (strlen(p_con2.p_keyorsw)+1))
  165. DataLevel = 1; /* flag PROGRAM switch */
  166. /* M003 BEGIN - parsing for switch /C */
  167. if (p_result3.P_SYNONYM_Ptr == (unsigned int)p_con3.p_keyorsw || /* Classify switch */
  168. p_result3.P_SYNONYM_Ptr == (unsigned int)p_con3.p_keyorsw +
  169. (strlen(p_con3.p_keyorsw)+1))
  170. {
  171. DataLevel = 1; /* treat this similar to /P switch */
  172. Classify = 1;
  173. }
  174. /* M003 END */
  175. Parse_Ptr = (char *) (OutRegs.x.si); /* point to next parm */
  176. parse(&OutRegs,&OutRegs); /* parse the line */
  177. if (OutRegs.x.ax == p_no_error) /* check for > 1 switch */
  178. OutRegs.x.ax = p_too_many; /* flag too many */
  179. }
  180. if (OutRegs.x.ax != p_rc_eol) /* parse error? */
  181. {
  182. Parse_Message(OutRegs.x.ax,STDERR,Parse_Err_Class,(char far *)Parse_Ptr); /* display parse error */
  183. exit(1); /* exit the program */
  184. }
  185. /* Store the current Ctrl-C handler and replace with our
  186. Ctrl-C handler :M000
  187. */
  188. OldCtrlc = _dos_getvect( 0x23 ); /* M000 */
  189. _dos_setvect( 0x23, MemCtrlc ); /* M000 */
  190. if (DataLevel > 0)
  191. {
  192. /* save current state of UMB linkage */
  193. InRegs.x.ax = GET_UMB_LINK_STATE;
  194. intdos(&InRegs, &OutRegs);
  195. if (!(UMB_Linkage = OutRegs.h.al))
  196. { /* UMBs not presently linked, so do it now */
  197. InRegs.x.ax = SET_UMB_LINK_STATE;
  198. InRegs.x.bx = LINK_UMBS;
  199. intdos(&InRegs, &OutRegs);
  200. LinkedIn++; /* Indicate that we have linked in UMBs :M000 */
  201. }
  202. rc = DisplayBaseDetail(); /* go show the memory state */
  203. /* restore original UMB link state */
  204. if (!UMB_Linkage) /* weren't linked originally */
  205. {
  206. InRegs.x.ax = SET_UMB_LINK_STATE;
  207. InRegs.x.bx = UNLINK_UMBS;
  208. intdos(&InRegs, &OutRegs); /* take 'em out again */
  209. LinkedIn--;
  210. }
  211. }
  212. if (!rc) { /* if no error in DisplayBaseDetail */
  213. /* go display other things and summary */
  214. Sub0_Message(NewLineMsg,STDOUT,Utility_Msg_Class);
  215. /* M003 BEGIN - Display summary acc. to option chosen */
  216. if (Classify)
  217. DisplayClassification();
  218. else
  219. DisplayBaseSummary(); /* display low memory totals */
  220. /* M003 END */
  221. if (EMSInstalled() && (DataLevel > 1))
  222. DisplayEMSDetail(); /* display EMS memory totals */
  223. if (EMSInstalled())
  224. DisplayEMSSummary(); /* display EMS memory totals */
  225. DisplayExtendedSummary(); /* display extended memory summary */
  226. /* NOTE: we don't display status of
  227. * HMA because to enquire about its
  228. * status can cause XMS to kick in
  229. *
  230. * If we didn't care about that, then
  231. * display HMA status here.
  232. */
  233. } /* end of if (!rc) */
  234. /* If user did not issue Ctrl-C till here, we just remove the handler */
  235. _dos_setvect( 0x23, OldCtrlc ); /* M000 */
  236. return(rc); /* end of MEM main routine */
  237. }
  238. /*���������������������������������������������������������������������������*/
  239. unsigned long AddressOf(Pointer)
  240. char far *Pointer;
  241. {
  242. unsigned long SegmentAddress,OffsetAddress;
  243. SegmentAddress = (unsigned long) (FP_SEG(Pointer)) * 16l;
  244. OffsetAddress = (unsigned long) (FP_OFF(Pointer));
  245. return( SegmentAddress + OffsetAddress);
  246. }
  247. /*----------------------------------------------------------------------+
  248. | |
  249. | SUBROUTINE NAME: PARSE_INIT |
  250. | |
  251. | SUBROUTINE FUNCTION: |
  252. | |
  253. | This routine is called by the FILESYS MAIN routine to initialize|
  254. | the parser data structures. |
  255. | |
  256. | INPUT: |
  257. | none |
  258. | |
  259. | OUTPUT: |
  260. | properly initialized parser control blocks |
  261. | |
  262. +----------------------------------------------------------------------*/
  263. void parse_init()
  264. {
  265. p_p.p_parmsx_address = &p_px; /* address of extended parm list */
  266. p_p.p_num_extra = 0;
  267. p_px.p_minp = 0;
  268. p_px.p_maxp = 0;
  269. p_px.p_maxswitch = 4;
  270. p_px.p_control[0] = &p_con1;
  271. p_px.p_control[1] = &p_con2;
  272. p_px.p_control[2] = &p_con3;
  273. p_px.p_control[3] = &p_con4;
  274. p_px.p_keyword = 0;
  275. p_con1.p_match_flag = p_none;
  276. p_con1.p_function_flag = p_cap_file;
  277. p_con1.p_result_buf = (unsigned int)&p_result1;
  278. p_con1.p_value_list = (unsigned int)&p_noval;
  279. p_con1.p_nid = 2;
  280. strcpy(p_con1.p_keyorsw,"/DEBUG"+NUL);
  281. strcpy(p_con1.p_keyorsw + (strlen(p_con1.p_keyorsw)+1),"/D"+NUL);
  282. p_con2.p_match_flag = p_none;
  283. p_con2.p_function_flag = p_cap_file;
  284. p_con2.p_result_buf = (unsigned int)&p_result2;
  285. p_con2.p_value_list = (unsigned int)&p_noval;
  286. p_con2.p_nid = 2;
  287. strcpy(p_con2.p_keyorsw,"/PROGRAM"+NUL);
  288. strcpy(p_con2.p_keyorsw + (strlen(p_con2.p_keyorsw)+1),"/P"+NUL);
  289. p_con3.p_match_flag = p_none;
  290. p_con3.p_function_flag = p_cap_file;
  291. p_con3.p_result_buf = (unsigned int)&p_result3;
  292. p_con3.p_value_list = (unsigned int)&p_noval;
  293. p_con3.p_nid = 2;
  294. strcpy(p_con3.p_keyorsw,"/CLASSIFY"+NUL);
  295. strcpy(p_con3.p_keyorsw + (strlen(p_con3.p_keyorsw)+1),"/C"+NUL);
  296. p_con4.p_match_flag = p_none;
  297. p_con4.p_function_flag = p_none;
  298. p_con4.p_result_buf = (unsigned int)&p_result4;
  299. p_con4.p_value_list = (unsigned int)&p_noval;
  300. p_con4.p_nid = 1;
  301. strcpy(p_con4.p_keyorsw,"/?"+NUL);
  302. p_noval.p_val_num = 0;
  303. p_result1.P_Type = 0;
  304. p_result1.P_Item_Tag = 0;
  305. p_result1.P_SYNONYM_Ptr = 0;
  306. p_result1.p_result_buff = 0;
  307. p_result2.P_Type = 0;
  308. p_result2.P_Item_Tag = 0;
  309. p_result2.P_SYNONYM_Ptr = 0;
  310. p_result2.p_result_buff = 0;
  311. p_result3.P_Type = 0;
  312. p_result3.P_Item_Tag = 0;
  313. p_result3.P_SYNONYM_Ptr = 0;
  314. p_result3.p_result_buff = 0;
  315. return;
  316. } /* end parse_init */
  317. /************************************************************************/
  318. /* Parse_Message - This routine will print only those */
  319. /* messages that require 1 replaceable */
  320. /* parm. */
  321. /* */
  322. /* Inputs : Msg_Num - number of applicable message */
  323. /* Handle - display type */
  324. /* Message_Type - type of message to display */
  325. /* Replace_Parm - pointer to parm to replace */
  326. /* */
  327. /* Outputs : message */
  328. /* */
  329. /************************************************************************/
  330. void Parse_Message(Msg_Num,Handle,Message_Type,parse_ptr)
  331. int Msg_Num;
  332. int Handle;
  333. unsigned char Message_Type;
  334. char far *parse_ptr;
  335. {
  336. if (parse_ptr) {
  337. sublist[1].value = (unsigned far *)parse_ptr;
  338. sublist[1].size = Sublist_Length;
  339. sublist[1].reserved = Reserved;
  340. sublist[1].id = 0;
  341. sublist[1].flags = Char_Field_ASCIIZ+Left_Align;
  342. sublist[1].max_width = 40;
  343. sublist[1].min_width = 01;
  344. sublist[1].pad_char = Blank;
  345. InRegs.x.cx = SubCnt1;
  346. }
  347. else
  348. InRegs.x.cx = 0;
  349. InRegs.x.ax = Msg_Num;
  350. InRegs.x.bx = Handle;
  351. InRegs.h.dl = No_Input;
  352. InRegs.h.dh = Message_Type;
  353. InRegs.x.si = (unsigned int)&sublist[1];
  354. sysdispmsg(&InRegs,&OutRegs);
  355. return;
  356. }
  357. /* M003 BEGIN */
  358. /*----------------------------------------------------------------------+
  359. | |
  360. | SUBROUTINE NAME: CSwitch_init |
  361. | |
  362. | SUBROUTINE FUNCTION: |
  363. | |
  364. | This routine is called by the FILESYS MAIN routine to initialize|
  365. | the C(lassify) switch related data structures. |
  366. | |
  367. | INPUT: |
  368. | none |
  369. | |
  370. | OUTPUT: |
  371. | properly initialized C switch related Data structures |
  372. | |
  373. +----------------------------------------------------------------------*/
  374. void CSwitch_init()
  375. {
  376. int i;
  377. int *ptr;
  378. ptr = (int *) (mem_table);
  379. for (i=sizeof(mem_table)/2;i>0;i--)
  380. *ptr++ = 0;
  381. noof_progs=0;
  382. }
  383. /* M003 END */
  384.