Source code of Windows XP (NT5)
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.

399 lines
9.4 KiB

  1. /*
  2. * Module Name: WSFSLIB.C
  3. *
  4. * Library/DLL: Common library functions for handling working set tuner files.
  5. *
  6. *
  7. * Description:
  8. *
  9. * Library routines called by the working set tuner programs to open and
  10. * read working set tuner files. These functions may be useful to ISVs, etc.,
  11. *
  12. * This is an OS/2 2.x specific file
  13. *
  14. * IBM/Microsoft Confidential
  15. *
  16. * Copyright (c) IBM Corporation 1987, 1989
  17. * Copyright (c) Microsoft Corporation 1987, 1989
  18. *
  19. * All Rights Reserved
  20. *
  21. * Modification History:
  22. *
  23. * 03/26/90 - created
  24. *
  25. */
  26. #include <stdlib.h>
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <windows.h>
  30. #include <time.h>
  31. #include <wserror.h>
  32. #include <wsdata.h>
  33. #include <wsfslib.h>
  34. #define MAXLINE 128
  35. BOOL fWsIndicator = FALSE;
  36. /*
  37. * Function declarations and prototypes.
  38. */
  39. /*
  40. *
  41. ***EP WsWSPOpen
  42. *
  43. * Effects:
  44. *
  45. * Opens a WSP file, and reads and validates the file header.
  46. *
  47. * Returns:
  48. *
  49. * Returns 0. If an error is encountered, exits with ERROR via an
  50. * indirect call through pfnExit.
  51. */
  52. USHORT FAR PASCAL
  53. WsWSPOpen( PSZ pszFileName, FILE **phFile, PFN pfnExit, wsphdr_t *pWspHdr,
  54. INT iExitCode, INT iOpenPrintCode )
  55. {
  56. ULONG rc = NO_ERROR;
  57. INT iRet = 0;
  58. ULONG cbRead = 0;
  59. size_t stRead = 0;
  60. /* Open module's input WSP file. */
  61. if ((*phFile = fopen(pszFileName, "rb")) == NULL)
  62. {
  63. iRet = (*pfnExit)(iExitCode, iOpenPrintCode, MSG_FILE_OPEN, rc,
  64. pszFileName);
  65. return((USHORT)iRet);
  66. }
  67. /* Read WSP file header. */
  68. stRead = fread((PVOID) pWspHdr, (ULONG) sizeof(*pWspHdr),1, *phFile);
  69. if(!stRead)
  70. {
  71. iRet = (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_OPEN, rc,
  72. pszFileName);
  73. return((USHORT)iRet);
  74. }
  75. /* Read module pathname (directly follows file header). */
  76. #ifdef DEBUG
  77. printf("WspHdr (%s): ulTime 0x%lx, ulSnaps 0x%lx, OffBits 0x%lx\n",
  78. // szModPath, pWspHdr->wsphdr_ulTimeStamp,
  79. pszFileName, pWspHdr->wsphdr_ulTimeStamp, // mdg 4/98
  80. pWspHdr->wsphdr_ulSnaps, pWspHdr->wsphdr_ulOffBits);
  81. #endif /* DEBUG */
  82. /* Validate the WSP file header. */
  83. if (_strcmpi(pWspHdr->wsphdr_chSignature, "WSP"))
  84. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_BAD_HDR, (ULONG)-1, pszFileName);
  85. return(NO_ERROR);
  86. }
  87. /*
  88. *
  89. ***EP WsTMIOpen
  90. *
  91. * Effects:
  92. *
  93. * Opens a TMI file, and reads and validates the file header.
  94. *
  95. * Returns:
  96. *
  97. * Returns the number of records in the TMI file. If an error is
  98. * encountered, exits with ERROR via an indirect call through pfnExit.
  99. */
  100. ULONG FAR PASCAL
  101. WsTMIOpen( PSZ pszFileName, FILE **phFile, PFN pfnExit, USHORT usId, PCHAR pch)
  102. {
  103. //ULONG ulTmp;
  104. ULONG rc = NO_ERROR;
  105. ULONG cbRead = 0;
  106. ULONG cFxns = 0;
  107. CHAR szLineTMI[MAXLINE]; // Line from TMI file
  108. CHAR szTDFID[8]; // TDF Identifier string
  109. ULONG ulTDFID = 0; // TDF Identifier
  110. /* Open TMI file (contains function names, etc., in ASCII). */
  111. if ((*phFile = fopen(pszFileName, "rt")) == NULL)
  112. {
  113. (*pfnExit)(NOEXIT, PRINT_MSG, MSG_FILE_OPEN, rc,
  114. pszFileName);
  115. return(MSG_FILE_OPEN);
  116. }
  117. /* Validate TMI file. */
  118. if (fgets(szLineTMI, MAXLINE, *phFile) == NULL){
  119. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
  120. pszFileName);
  121. }
  122. // # fxns
  123. if (fgets(szLineTMI, MAXLINE, *phFile) == NULL){
  124. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
  125. pszFileName);
  126. }
  127. szLineTMI[strlen(szLineTMI) - 1] = '\0';
  128. if (sscanf(szLineTMI,"/* Total Symbols= %u */", &cFxns) != 1){
  129. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
  130. pszFileName);
  131. }
  132. // MODNAME
  133. if (fgets(szLineTMI, MAXLINE, *phFile) == NULL)
  134. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
  135. pszFileName);
  136. // MAJOR
  137. if (fgets(szLineTMI, MAXLINE, *phFile) == NULL)
  138. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
  139. pszFileName);
  140. // TDFID
  141. if (fgets(szLineTMI, MAXLINE, *phFile) == NULL)
  142. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
  143. pszFileName);
  144. if (sscanf(szLineTMI, "TDFID = %s", szTDFID) != 1)
  145. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc,
  146. pszFileName);
  147. ulTDFID = strtoul(szTDFID, (char **) 0, 0);
  148. /* Check identifier field */
  149. if (ulTDFID != (ULONG) usId)
  150. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_BAD_HDR, (ULONG)-1,
  151. pszFileName);
  152. return(cFxns);
  153. }
  154. /*
  155. *
  156. ***EP WsTMIReadRec
  157. *
  158. * Effects:
  159. *
  160. * Reads a record from a TMI file, including the variable length function
  161. * name.
  162. *
  163. * Returns:
  164. *
  165. * Function size, in bytes, from this record. If an error is
  166. * encountered, exits with ERROR via an indirect call through pfnExit.
  167. */
  168. ULONG FAR PASCAL
  169. WsTMIReadRec( PSZ *ppszFxnName, PULONG pulFxnIndex, PULONG pulFxnAddr,
  170. FILE *hFile, PFN pfnExit, PCHAR pch)
  171. {
  172. ULONG rc;
  173. ULONG cbFxn;
  174. UINT uiFxnAddrObj; // object portion of function address
  175. ULONG cbFxnName; // size in bytes of function name
  176. // Read in function name, etc.
  177. rc = fscanf(hFile, "%ld %x:%lx 0x%lx %ul", // mdg 98/4
  178. pulFxnIndex, &uiFxnAddrObj, pulFxnAddr, &cbFxn,
  179. &cbFxnName);
  180. if (rc != 5)
  181. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc, "TMI file");
  182. *ppszFxnName = malloc( 1 + cbFxnName ); // Allocate space for function name
  183. if (*ppszFxnName == NULL) // Abort if no mem
  184. (*pfnExit)(ERROR, PRINT_MSG, MSG_NO_MEM, 1 + cbFxnName, "TMI file");
  185. rc = fgetc( hFile ); // Skip leading blank space
  186. fgets( *ppszFxnName, cbFxnName + 1, hFile );
  187. rc = fgetc( hFile );
  188. if (rc != '\n' || strlen( *ppszFxnName ) != cbFxnName)
  189. (*pfnExit)(ERROR, PRINT_MSG, MSG_FILE_READ, rc, "TMI file");
  190. return(cbFxn);
  191. }
  192. LPVOID APIENTRY AllocAndLockMem(DWORD cbMem, HGLOBAL *hMem)
  193. {
  194. //
  195. // Changed to GHND from GMEM_MOVABLE
  196. //
  197. *hMem = GlobalAlloc(GHND, cbMem);
  198. if(!*hMem) {
  199. return(NULL);
  200. }
  201. return(GlobalLock(*hMem));
  202. }
  203. BOOL APIENTRY UnlockAndFreeMem(HGLOBAL hMem)
  204. {
  205. BOOL fRet;
  206. fRet = GlobalUnlock(hMem);
  207. if (fRet) {
  208. return(fRet);
  209. }
  210. if (!GlobalFree(hMem)) {
  211. return(FALSE);
  212. }
  213. return(TRUE);
  214. }
  215. void
  216. ConvertAppToOem( unsigned argc, char* argv[] )
  217. /*++
  218. Routine Description:
  219. Converts the command line from ANSI to OEM, and force the app
  220. to use OEM APIs
  221. Arguments:
  222. argc - Standard C argument count.
  223. argv - Standard C argument strings.
  224. Return Value:
  225. None.
  226. --*/
  227. {
  228. unsigned i;
  229. for( i=0; i<argc; i++ ) {
  230. CharToOem( argv[i], argv[i] );
  231. }
  232. SetFileApisToOEM();
  233. }
  234. /*
  235. *
  236. ***EP WsIndicator
  237. *
  238. * Effects:
  239. *
  240. * Displays a progress indicator on the console. Doesn't use stdout which may be
  241. * redirected.
  242. *
  243. * Parameters:
  244. *
  245. * eFunc Description nVal
  246. * WSINDF_NEW, Start new indicator Value of 100% limit
  247. * WSINDF_PROGRESS, Set progress of current indicator Value of progress toward limit
  248. * WSINDF_FINISH Mark indicator as finished -ignored-
  249. * -invalid- Do nothing
  250. *
  251. * In all valid cases, pszLabel sets string to display before indicator. If NULL,
  252. * uses last set string.
  253. *
  254. * Returns:
  255. *
  256. * Function size, in bytes, from this record. If an error is
  257. * encountered, exits with ERROR via an indirect call through pfnExit.
  258. */
  259. VOID FAR PASCAL
  260. WsProgress( WsIndicator_e eFunc, const char *pszLbl, unsigned long nVal )
  261. {
  262. static unsigned long
  263. nLimit = 0, nCurrent = 0;
  264. static const char *
  265. pszLabel = "";
  266. static unsigned nLabelLen = 0;
  267. static char bStarted = FALSE;
  268. static unsigned nLastLen = 0;
  269. static HANDLE hConsole = NULL;
  270. DWORD pnChars;
  271. switch (eFunc)
  272. {
  273. case WSINDF_NEW:
  274. if (bStarted)
  275. WsIndicator( WSINDF_FINISH, NULL, 0 );
  276. bStarted = TRUE;
  277. nLimit = nVal;
  278. nCurrent = 0;
  279. nLastLen = ~0; // Force redraw
  280. WsIndicator ( WSINDF_PROGRESS, pszLbl, 0 );
  281. break;
  282. case WSINDF_PROGRESS:
  283. if (!bStarted)
  284. break;
  285. if (pszLbl != NULL)
  286. {
  287. pszLabel = pszLbl;
  288. nLabelLen = strlen( pszLabel );
  289. }
  290. if (nVal > nCurrent) // Compare to current progress (ignore reverses)
  291. if (nVal <= nLimit)
  292. nCurrent = nVal;
  293. else
  294. nCurrent = nLimit;
  295. { // Calculate an indicator string and print it
  296. unsigned nLen = (unsigned) ((40.1 * (double)nCurrent) / nLimit);
  297. char * pszBuf;
  298. if (nLastLen == nLen) // Optimization - Don't redraw if result would be the same
  299. {
  300. if (pszLbl == NULL)
  301. break;
  302. }
  303. else
  304. nLastLen = nLen;
  305. if (hConsole == NULL)
  306. {
  307. hConsole = CreateFile( "CONOUT$", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
  308. if (hConsole == NULL) // Couldn't get the console for some reason?
  309. break;
  310. }
  311. WriteConsole( hConsole, "\r", 1, &pnChars, NULL );
  312. WriteConsole( hConsole, pszLabel, nLabelLen, &pnChars, NULL );
  313. WriteConsole( hConsole, " ", 1, &pnChars, NULL );
  314. pszBuf = malloc( nLen + 1 );
  315. if (pszBuf == NULL) // No memory? Oh, well...
  316. break;
  317. memset( pszBuf, '-', nLen );
  318. pszBuf[nLen] = '\0';
  319. WriteConsole( hConsole, pszBuf, nLen, &pnChars, NULL );
  320. free( pszBuf);
  321. }
  322. break;
  323. case WSINDF_FINISH:
  324. if (!bStarted)
  325. break;
  326. WsIndicator( WSINDF_PROGRESS, pszLbl, nLimit );
  327. if (hConsole != NULL)
  328. {
  329. WriteConsole( hConsole, "\n", 1, &pnChars, NULL );
  330. CloseHandle( hConsole );
  331. hConsole = NULL;
  332. }
  333. bStarted = FALSE;
  334. }
  335. }