Windows NT 4.0 source code leak
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.

2456 lines
82 KiB

4 years ago
  1. /*
  2. ** LOGGER - DLL to control logging of API trace information
  3. */
  4. #define NOGDICAPMASKS
  5. #define NOVIRTUALKEYCODES
  6. #define NOWINSTYLES
  7. #define NOSYSMETRICS
  8. #define NOICONS
  9. #define NOKEYSTATES
  10. #define NOSYSCOMMANDS
  11. #define NORASTEROPS
  12. #define NOSHOWWINDOW
  13. #define NOATOM
  14. #define NOCLIPBOARD
  15. #define NOCOLOR
  16. #define NODRAWTEXT
  17. #define NOMB
  18. #define NOMEMMGR
  19. #define NOMETAFILE
  20. #define NOMINMAX
  21. #define NOMSG
  22. #define NOSCROLL
  23. #define NOSOUND
  24. #define NOTEXTMETRIC
  25. #define NOWINOFFSETS
  26. #define NOCOMM
  27. #define NOKANJI
  28. #define NOHELP
  29. #define NOPROFILER
  30. #define NODEFERWINDOWPOS
  31. #include <windows.h>
  32. #include <stdlib.h>
  33. #include <stdarg.h>
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <math.h>
  37. #include <memory.h>
  38. #if !defined(WIN32)
  39. #define INT21H
  40. #include <dos.h>
  41. #endif
  42. #include "logger.h"
  43. #include "lintern.h"
  44. #include "saverest.h"
  45. #include "timing.h"
  46. //
  47. // by default OUTPUT.LOG is created in the current working directory unless:
  48. // there is any file ALT_LOG_FLAG(log.on) located in the ALTERNATE_PATH
  49. //
  50. #define OUTPUT_LOG "OUTPUT.LOG"
  51. #define OUTPUT_DAT "OUTPUT.DAT"
  52. #define ALT_LOG_DIR "x:\\log" // alt. dir to put log file in
  53. #define ALT_FLAG_FILE "log.on" // a flag to indicate "write output.log to al
  54. #ifdef LOGFILE_PATH
  55. #define ALTERNATE_PATH LOGFILE_PATH "\\"
  56. #define ALTERNATE_TEST ALTERNATE_PATH ALT_FLAG_FILE
  57. #else
  58. #define ALTERNATE_PATH ALT_LOG_DIR "\\"
  59. #define ALTERNATE_TEST ALTERNATE_PATH ALT_FLAG_FILE
  60. #endif // LOGFILE_PATH
  61. #define TIMING_ON_FLAG "time.on" // set timing on
  62. #define TIMING_ON_TEST ALTERNATE_PATH TIMING_ON_FLAG
  63. #if !defined( WIN32 )
  64. int FAR PASCAL LibMain(HANDLE, WORD, WORD, LPSTR);
  65. DWORD far GetSetKernelDOSProc (DWORD);
  66. extern void _far __export _pascal _Int21_Handler (void);
  67. void DoInt21Init(void);
  68. void _loadds LogInt21Calls (
  69. WORD wFlags, WORD wBP, WORD wSS,
  70. WORD wES, WORD wDS, WORD wSI, WORD wDI,
  71. WORD wDX, WORD wCX, WORD wBX,
  72. WORD wAX, WORD Dummy1, WORD Dummy2,
  73. WORD Dummy3, WORD Dummy4, WORD wIP, WORD wCS);
  74. void _loadds LogOut21Calls (
  75. WORD wFlags, WORD wDS, WORD wES, WORD wSI, WORD wDI,
  76. WORD wDX, WORD wCX, WORD wBX, WORD wAX,
  77. WORD wIP, WORD wCS);
  78. DWORD dwTemp;
  79. UINT wSelData, uSel;
  80. UINT RegAX = 0;
  81. unsigned int cLogInInt21 = 0;
  82. // the above var. is required for the following reason:
  83. // it is possible that an API calls another API before
  84. // returning. So, before calling LogOut, another LogIn
  85. // might be called. If in the meanwhile, the write buffer
  86. // gets filled up, an Int21 will be issued (via a write
  87. // request. So, we log Int21s only when this var. is zero.
  88. // A counter is incremented and decremented at the beginning
  89. // & end of this function.
  90. unsigned int cInt21CallsByApp = 0;
  91. unsigned int cAllInt21Calls = 0;
  92. LPDWORD lpOrig;
  93. BOOL fLogIn = FALSE;
  94. // the above is a flag that is used for Int21 logging. This flag
  95. // is just set before exiting LogIn since this means that the app
  96. // has already made the first Windows API call. We use this to begin
  97. // counting the Int21 calls.
  98. // HTASK hTask;
  99. // STACKTRACEENTRY StackTrace;
  100. // MODULEENTRY ModuleEntry;
  101. #endif
  102. #define REST 0x99
  103. #define MAX_INST_TABLE 30
  104. #ifdef SHARED_MEM
  105. typedef struct _shared_mem_t
  106. {
  107. /*
  108. ** Global static variables
  109. */
  110. int nLogIndent ;
  111. char achCurrentDirectory[_MAX_PATH];
  112. int cDbg ;
  113. BOOL fLogInit ;
  114. BOOL cDbgPort ;
  115. BOOL fTiming ;
  116. BOOL fNotes ;
  117. BOOL fWOW ;
  118. BOOL fLogObjects ;
  119. BOOL fINT21H ;
  120. BOOL fAPIOnly ;
  121. BOOL fLogSync ;
  122. BOOL fDrvLog ;
  123. BOOL fElapsedTimes ;
  124. char szLogFileName[_MAX_PATH]; // output log file name
  125. char szDatFileName[_MAX_PATH]; // output dat file name
  126. } SHARED_MEMORY, *PSHARED_MEM;
  127. PSHARED_MEM pVars ;
  128. #define SHMEMSIZE sizeof(struct _shared_mem_t)
  129. #define ACCESS(varname) (pVars->varname)
  130. HANDLE hMapObject ;
  131. #else
  132. /*
  133. ** Global static variables
  134. */
  135. int nLogIndent = 1;
  136. char achCurrentDirectory[_MAX_PATH];
  137. int cDbg = REST;
  138. BOOL fLogInit = FALSE ;
  139. BOOL cDbgPort = FALSE ;
  140. BOOL fTiming = FALSE ;
  141. BOOL fNotes = FALSE ;
  142. BOOL fWOW = FALSE ;
  143. BOOL fLogObjects = FALSE ;
  144. BOOL fINT21H = FALSE ;
  145. BOOL fAPIOnly = FALSE ;
  146. BOOL fLogSync = FALSE ;
  147. BOOL fDrvLog = FALSE ;
  148. BOOL fElapsedTimes = TRUE ; // DEAFULT to elapsed times.
  149. static char szLogFileName[_MAX_PATH]; // output log file name
  150. static char szDatFileName[_MAX_PATH]; // output dat file name
  151. #define ACCESS(varname) varname
  152. #endif
  153. /*
  154. ** "Local" Global Data
  155. */
  156. int WindowsVerRunning = 0;
  157. int hLogFile, hDataFile;
  158. int nLineLen = 0;
  159. long nLogLine = 0L;
  160. long nLogSpot = 0L;
  161. BOOL fInputHook;
  162. HHOOK hOldHook;
  163. FARPROC fpOldHook;
  164. FARPROC fpNewHook;
  165. #define MAX_BUFFER 1024
  166. char chBuffer[MAX_BUFFER];
  167. #define MAX_PATH_NAME_LEN _MAX_PATH
  168. /*
  169. ** For timing info
  170. ** Time only if compiled with this flag
  171. */
  172. short TimerHandle [MAX_BUFFER];
  173. BOOL fTimerCalibrated = FALSE;
  174. unsigned long ulOverhead = 0L;
  175. void CalibrateTimer (void);
  176. BOOL fDos3Call = FALSE;
  177. BOOL fAlias = FALSE ;
  178. /*
  179. ** Special HACK addresses so that we can determine whether there is
  180. ** a pending mouse movement message.
  181. */
  182. int FAR *lpfMouseMoved = NULL;
  183. HANDLE hLibInstance = NULL;
  184. // for DialogBoxIndirectParam playback
  185. WORD hInstanceTable[MAX_INST_TABLE];
  186. WORD hInstOfCaller = 0;
  187. #ifdef WIN32
  188. BOOLEAN
  189. NtQueryPerformanceCounter (
  190. PLARGE_INTEGER PerformanceCounter,
  191. PLARGE_INTEGER PerformanceFrequency
  192. );
  193. #else
  194. typedef DWORD ULONG;
  195. typedef DWORD BOOLEAN;
  196. typedef struct large_integer {
  197. ULONG LowPart;
  198. LONG HighPart;
  199. } LARGE_INTEGER, FAR *PLARGE_INTEGER;
  200. #endif
  201. // This stuff can and will be local
  202. TYPEIO *typehash[256] = { NULL };
  203. TYPEIO IoTypes[] = {
  204. #if defined( WIN32)
  205. // DRVLOG types - at the top so we don't slow down DDI anymore than necc.
  206. "PSURFOBJ", PrtPSURFOBJ, NULL,
  207. "PCLIPOBJ", PrtPCLIPOBJ, NULL,
  208. "PXLATEOBJ", PrtPXLATEOBJ, NULL,
  209. "PRECTL", PrtPRECTL, NULL,
  210. "PPOINTL", PrtPPOINTL, NULL,
  211. "POINTS", PrtPOINTS, NULL,
  212. "COORD", PrtPOINTS, NULL,
  213. "PBRUSHOBJ", PrtPBRUSHOBJ, NULL,
  214. "ROP4", PrtROP4, NULL,
  215. "FLONG", PrtLong, NULL,
  216. "PHSURF", PrtPHSURF, NULL,
  217. "HSURF", PrtHSURF, NULL,
  218. "DHSURF", PrtHSURF, NULL,
  219. "PIFIMETRICS", PrtPIFIMETRICS, NULL,
  220. "PDEVMODEW", PrtPDEVMODEW, NULL,
  221. "PDRVENABLEDATA", PrtPDRVENABLEDATA, NULL,
  222. "PDEVINFO", PrtPDEVINFO, NULL,
  223. "DHPDEV", PrtDHPDEV, NULL,
  224. "HDEV", PrtHDEV, NULL,
  225. "PSTROBJ", PrtPSTROBJ, NULL,
  226. "PFONTOBJ", PrtPFONTOBJ, NULL,
  227. "MIX", PrtMIX, NULL,
  228. "SIZE", PrtSIZE, NULL,
  229. "SIZEL", PrtSIZE, NULL,
  230. "LPWORD", PrtLPWORD, NULL,
  231. "PHANDLER_ROUTINE", PrtFARPROC, NULL,
  232. "PSMALL_RECT", PrtPSMALL_RECT, NULL,
  233. // Not implemented
  234. "PCONSOLE_SCREEN_BUFFER_INFO", PrtLong, NULL,
  235. "PCONSOLE_CURSOR_INFO", PrtLong, NULL,
  236. "PCHAR_INFO", PrtLong, NULL,
  237. "PINPUT_RECORD", PrtLong, NULL,
  238. "LPCPINFO", PrtLong, NULL,
  239. "LPSYSTEM_INFO", PrtLong, NULL,
  240. "LPKERNINGPAIR", PrtLong, NULL,
  241. #endif
  242. "UINT", PrtInt, NULL,
  243. "INT", PrtInt, NULL,
  244. "INT*", PrtLPINT, NULL,
  245. "const INT*", PrtLPINT, NULL,
  246. "INT *", PrtLPINT, NULL,
  247. "const INT *", PrtLPINT, NULL,
  248. "HDWP", PrtInt, NULL,
  249. "int", PrtInt, NULL,
  250. "HDWP", PrtHMEM, NULL,
  251. "short", PrtShort, NULL,
  252. "SHORT", PrtShort, NULL,
  253. "char", PrtInt, NULL,
  254. "CHAR", PrtInt, NULL,
  255. "BYTE", PrtInt, NULL,
  256. "long", PrtLong, NULL,
  257. "BOOL", PrtBool, NULL,
  258. "BOOL far*", PrtLPINT, NULL,
  259. "WORD", PrtInt, NULL,
  260. "WPARAM", PrtInt, NULL,
  261. "DWORD", PrtLong, NULL,
  262. "ULONG", PrtLong, NULL,
  263. "POINT", PrtLong, NULL,
  264. "LONG", PrtLong, NULL,
  265. "LPARAM", PrtLong, NULL,
  266. "LPVOID", PrtLong, NULL,
  267. "va_list", PrtLong, NULL,
  268. #ifdef WIN32
  269. "PVOID", PrtLong, NULL,
  270. "const void*", PrtLong, NULL,
  271. "HSZ", PrtLong, NULL,
  272. "HDDEDATA", PrtLong, NULL,
  273. "HCONVLIST", PrtLong, NULL,
  274. "HCONV", PrtLong, NULL,
  275. "LCID", PrtLong, NULL,
  276. "PLCID", PrtLPDWORD, NULL,
  277. "LPLCID", PrtLPDWORD, NULL,
  278. "LCID *", PrtLPDWORD, NULL,
  279. "LCTYPE", PrtLong, NULL,
  280. "LPLCID", PrtLPDWORD, NULL,
  281. "LPCVOID", PrtLong, NULL,
  282. "REGSAM", PrtLong, NULL,
  283. "ACCESS_MASK", PrtLong, NULL,
  284. "PACCESS_MASK", PrtLPDWORD, NULL,
  285. "LPBYTE", PrtLPBYTE, NULL,
  286. "LANGID", PrtShort, NULL,
  287. "LPTHREAD_START_ROUTINE", PrtLong, NULL,
  288. "PTHREAD_START_ROUTINE", PrtLong, NULL,
  289. "LPWINDOWPLACEMENT", PrtLPWINDOWPLACEMENT, NULL,
  290. "PWINDOWPLACEMENT", PrtLPWINDOWPLACEMENT, NULL,
  291. "WINDOWPLACEMENT*", PrtLPWINDOWPLACEMENT, NULL,
  292. "const WINDOWPLACEMENT*", PrtLPWINDOWPLACEMENT, NULL,
  293. "LPCONVCONTEXT", PrtLPCONVCONTEXT, NULL,
  294. "PCONVCONTEXT", PrtLPCONVCONTEXT, NULL,
  295. "const CONVCONTEXT*", PrtLPCONVCONTEXT, NULL,
  296. "CONVCONTEXT*", PrtLPCONVCONTEXT, NULL,
  297. #endif
  298. "const BYTE*", PrtLong, NULL,
  299. "LRESULT", PrtLong, NULL,
  300. "COLORREF", PrtLong, NULL,
  301. "ATOM", PrtATOM, NULL,
  302. "LPINT", PrtLPINT, NULL,
  303. "int far*", PrtLPINT, NULL,
  304. "LPDWORD", PrtLPDWORD, NULL,
  305. "LPLONG", PrtLPDWORD, NULL,
  306. "LPBOOL", PrtLPDWORD, NULL,
  307. "const DWORD *", PrtLPDWORD, NULL,
  308. "const DWORD*", PrtLPDWORD, NULL,
  309. "DWORD *", PrtLPDWORD, NULL,
  310. "DWORD*", PrtLPDWORD, NULL,
  311. "PULONG", PrtLPDWORD, NULL,
  312. "PLONG", PrtLPDWORD, NULL, // Do we need to differentiate the sign?
  313. "ARRAYINT", PrtARRAYINT, NULL,
  314. "LPSTR", PrtLPSTR, NULL,
  315. "LPSTR*", PrtLPDWORD, NULL,
  316. "LPCSTR", PrtLPSTR, NULL,
  317. // Default these to pointers so we can see what is going on....mjr
  318. "HANDLETABLE far*", PrtLPINT, NULL,
  319. "METARECORD far*", PrtLPINT, NULL,
  320. #ifdef WIN32
  321. "LPWSTR*", PrtPLPWSTR, NULL,
  322. "LPWSTR", PrtLPWSTR, NULL,
  323. "PWSTR", PrtLPWSTR, NULL,
  324. "LPCWSTR", PrtLPWSTR, NULL,
  325. "wchar near*", PrtLPSTR, NULL,
  326. "wchar far*", PrtLPSTR, NULL,
  327. "const wchar_t*", PrtLPSTR, NULL,
  328. "void*", PrtLong, NULL,
  329. "const char*", PrtLPSTR, NULL,
  330. "size_t", PrtInt, NULL,
  331. #endif
  332. "char near*", PrtLPSTR, NULL,
  333. "char far*", PrtLPSTR, NULL,
  334. "void far*", PrtLong, NULL,
  335. "const void far*", PrtLong, NULL,
  336. "const void *", PrtLong, NULL,
  337. "FixedString", PrtFixedString, NULL,
  338. "FineString", PrtFineString, NULL,
  339. "HMETAFILE", PrtHMETA, NULL,
  340. "const HANDLE*", PrtPHANDLE, NULL,
  341. "LPHANDLE", PrtPHANDLE, NULL,
  342. "HANDLE", PrtHMEM, NULL,
  343. "HLOCAL", PrtHMEM, NULL,
  344. "HINSTANCE", PrtHMEM, NULL,
  345. "HMODULE", PrtHMEM, NULL,
  346. "HGLOBAL", PrtHMEM, NULL,
  347. "HFILE", PrtHFILE, NULL,
  348. "HRSRC", PrtHRES, NULL,
  349. "HWND", PrtHWND, NULL,
  350. "HICON", PrtHICON, NULL,
  351. "HBITMAP", PrtHBITMAP, NULL,
  352. "HCURSOR", PrtHCURSOR, NULL,
  353. "HPEN", PrtHPEN, NULL,
  354. "HDC", PrtHDC, NULL,
  355. "HBRUSH", PrtHBRUSH, NULL,
  356. "HFONT", PrtHFONT, NULL,
  357. "HTASK", PrtHTASK, NULL,
  358. "HACCEL", PrtHACCEL, NULL,
  359. "HMENU", PrtHMENU, NULL,
  360. "HRGN", PrtHRGN, NULL,
  361. "HGDIOBJ", PrtHMEM, NULL,
  362. "HPALETTE", PrtHPALETTE, NULL,
  363. "LPLOGBRUSH", PrtLPLOGBRUSH, NULL,
  364. "LOGBRUSH *", PrtLPLOGBRUSH, NULL,
  365. "LOGBRUSH*", PrtLPLOGBRUSH, NULL,
  366. "const LOGBRUSH *", PrtLPLOGBRUSH, NULL,
  367. "const LOGBRUSH*", PrtLPLOGBRUSH, NULL,
  368. "LOGBRUSH far*", PrtLPLOGBRUSH, NULL,
  369. "LPDEVMODE", PrtLPDEVMODE, NULL,
  370. "DEVMODE far*", PrtLPDEVMODE, NULL,
  371. #ifdef WIN32
  372. "LPLOGFONTA", PrtLPLOGFONTA, NULL,
  373. "LOGFONTA *", PrtLPLOGFONTA, NULL,
  374. "LOGFONTA*", PrtLPLOGFONTA, NULL,
  375. "const LOGFONTA *", PrtLPLOGFONTA, NULL,
  376. "const LOGFONTA*", PrtLPLOGFONTA, NULL,
  377. "LOGFONTA far*", PrtLPLOGFONTA, NULL,
  378. "const LOGFONTA*", PrtLPLOGFONTA, NULL,
  379. "LPLOGFONTW", PrtLPLOGFONTW, NULL,
  380. "LOGFONTW *", PrtLPLOGFONTW, NULL,
  381. "LOGFONTW*", PrtLPLOGFONTW, NULL,
  382. "const LOGFONTW *", PrtLPLOGFONTW, NULL,
  383. "const LOGFONTW*", PrtLPLOGFONTW, NULL,
  384. "LOGFONTW far*", PrtLPLOGFONTW, NULL,
  385. "const LOGFONTW*", PrtLPLOGFONTW, NULL,
  386. #else
  387. "LPLOGFONT", PrtLPLOGFONT, NULL,
  388. "LOGFONT *", PrtLPLOGFONT, NULL,
  389. "LOGFONT*", PrtLPLOGFONT, NULL,
  390. "const LOGFONT *", PrtLPLOGFONT, NULL,
  391. "const LOGFONT*", PrtLPLOGFONT, NULL,
  392. "LOGFONT far*", PrtLPLOGFONT, NULL,
  393. "const LOGFONTA*", PrtLPLOGFONT, NULL,
  394. #endif
  395. "LPLOGPEN", PrtLPLOGPEN, NULL,
  396. "LOGPEN far*", PrtLPLOGPEN, NULL,
  397. "LPLOGPALETTE", PrtLPLOGPALETTE, NULL,
  398. "LOGPALETTE far*", PrtLPLOGPALETTE, NULL,
  399. "LOGPALETTE*", PrtLPLOGPALETTE, NULL,
  400. "const LOGPALETTE*", PrtLPLOGPALETTE, NULL,
  401. "PALETTEENTRY far *", PrtLPPALETTEENTRY, NULL,
  402. "PALETTEENTRY far*", PrtLPPALETTEENTRY, NULL,
  403. "LPPALETTEENTRY", PrtLPPALETTEENTRY, NULL,
  404. "LPMSG", PrtLPMSG, NULL,
  405. "MSG far*", PrtLPMSG, NULL,
  406. "const MSG*", PrtLPMSG, NULL,
  407. "LPOFSTRUCT", PrtLPOFSTRUCT, NULL,
  408. "OFSTRUCT far*", PrtLPOFSTRUCT, NULL,
  409. "LPPOINT", PrtLPPOINT, NULL,
  410. "POINT far*", PrtLPPOINT, NULL,
  411. "const POINT *", PrtLPPOINT, NULL,
  412. "const POINT*", PrtLPPOINT, NULL,
  413. "POINT *", PrtLPPOINT, NULL,
  414. "POINT*", PrtLPPOINT, NULL,
  415. "LPSIZE", PrtLPPOINT, NULL,
  416. "LPRECT", PrtLPRECT, NULL,
  417. "LPTR", PrtLPTR, NULL,
  418. "RECT far*", PrtLPRECT, NULL,
  419. "const RECT*", PrtLPRECT, NULL,
  420. "LPPAINTSTRUCT", PrtLPPAINTSTRUCT, NULL,
  421. "PAINTSTRUCT far*", PrtLPPAINTSTRUCT, NULL,
  422. "const PAINTSTRUCT*", PrtLPPAINTSTRUCT, NULL,
  423. #ifdef WIN32
  424. "LPWNDCLASSA", PrtLPWNDCLASSA, NULL,
  425. "WNDCLASSA far*", PrtLPWNDCLASSA, NULL,
  426. "const WNDCLASSA *", PrtLPWNDCLASSA, NULL,
  427. "LPWNDCLASSW", PrtLPWNDCLASSW, NULL,
  428. "WNDCLASSW far*", PrtLPWNDCLASSW, NULL,
  429. "const WNDCLASSW *", PrtLPWNDCLASSW, NULL,
  430. #else
  431. "LPWNDCLASS", PrtLPWNDCLASS, NULL,
  432. "WNDCLASS far*", PrtLPWNDCLASS, NULL,
  433. #endif
  434. "LPBITMAP", PrtLPBITMAP, NULL,
  435. "const BITMAP*", PrtLPBITMAP, NULL,
  436. "LPBITMAPINFOHEADER", PrtLPBMIH, NULL,
  437. "BITMAPINFOHEADER far*", PrtLPBMIH, NULL,
  438. "LPBITMAPINFO", PrtLPBMI, NULL,
  439. "BITMAPINFO far*", PrtLPBMI, NULL,
  440. "BITMAP far *", PrtLPBITMAP, NULL,
  441. "BITMAP far*", PrtLPBITMAP, NULL,
  442. "FARPROC far *", PrtLPFARPROC, NULL,
  443. "FARPROC far*", PrtLPFARPROC, NULL,
  444. "HOOKPROC", PrtFARPROC, NULL,
  445. "HOOKPROC far*", PrtLPFARPROC, NULL,
  446. "LNOTIFYPROC", PrtFARPROC, NULL,
  447. "DLGPROC", PrtFARPROC, NULL,
  448. "TIMERPROC", PrtFARPROC, NULL,
  449. "PROPENUMPROC", PrtFARPROC, NULL,
  450. "WNDENUMPROC", PrtFARPROC, NULL,
  451. "ABORTPROC", PrtFARPROC, NULL,
  452. "MFENUMPROC", PrtFARPROC, NULL,
  453. "FONTENUMPROC", PrtFARPROC, NULL,
  454. "GRAYSTRINGPROC", PrtFARPROC, NULL,
  455. "LINEDDAPROC", PrtFARPROC, NULL,
  456. "GOBJENUMPROC", PrtFARPROC, NULL,
  457. "RSRCHDLRPROC", PrtFARPROC, NULL,
  458. "GNOTIFYPROC", PrtFARPROC, NULL,
  459. "FARPROC", PrtFARPROC, NULL,
  460. "WNDPROC", PrtFARPROC, NULL,
  461. "PFNCALLBACK", PrtFARPROC, NULL,
  462. "HHOOK", PrtHHOOK, NULL,
  463. #ifdef WIN32
  464. "LPTEXTMETRICA", PrtLPTEXTMETRICA, NULL,
  465. "TEXTMETRICA far*", PrtLPTEXTMETRICA, NULL,
  466. "TEXTMETRICA *", PrtLPTEXTMETRICA, NULL,
  467. "TEXTMETRICA*", PrtLPTEXTMETRICA, NULL,
  468. "LPTEXTMETRICW", PrtLPTEXTMETRICW, NULL,
  469. "TEXTMETRICW far*", PrtLPTEXTMETRICW, NULL,
  470. "TEXTMETRICW *", PrtLPTEXTMETRICW, NULL,
  471. "TEXTMETRICW*", PrtLPTEXTMETRICW, NULL,
  472. #else
  473. "LPTEXTMETRIC", PrtLPTEXTMETRIC, NULL,
  474. "TEXTMETRIC far*", PrtLPTEXTMETRIC, NULL,
  475. #endif
  476. "LPEVENTMSG", PrtLPEVENTMSG, NULL,
  477. "COMSTAT far*", PrtLPCOMSTAT, NULL,
  478. #if (WINVER >= 0x30a)
  479. #ifdef WIN32
  480. "LPOUTLINETEXTMETRICA", PrtLPOUTLINETEXTMETRICA, NULL,
  481. "LPOUTLINETEXTMETRICW", PrtLPOUTLINETEXTMETRICW, NULL,
  482. #else
  483. "LPOUTLINETEXTMETRIC", PrtLPOUTLINETEXTMETRIC, NULL,
  484. #endif
  485. "LPGLYPHMETRICS", PrtLPGLYPHMETRICS, NULL,
  486. "LPMAT2", PrtLPMAT2, NULL,
  487. #endif
  488. #ifdef WIN32
  489. "LPSTARTUPINFOA", PrtLPSTARTUPINFOA, NULL,
  490. "LPSTARTUPINFOW", PrtLPSTARTUPINFOW, NULL,
  491. "LPOVERLAPPED", PrtLPOVERLAPPED, NULL,
  492. "LPSECURITY_ATTRIBUTES", PrtLPSECURITY_ATTRIBUTES,NULL,
  493. "LPCRITICAL_SECTION", PrtLPCRITICAL_SECTION, NULL,
  494. "HEVENT", PrtHEVENT, NULL,
  495. "HKEY", PrtHKEY, NULL,
  496. "PHKEY", PrtPHKEY, NULL,
  497. "PMEMORY_BASIC_INFORMATION",PrtPMEMORY_BASIC_INFORMATION,NULL,
  498. "LPFILETIME", PrtLPFILETIME, NULL,
  499. "PFILETIME", PrtLPFILETIME, NULL,
  500. "const FILETIME *", PrtLPFILETIME, NULL,
  501. "const FILETIME*", PrtLPFILETIME, NULL,
  502. "LPSYSTEMTIME", PrtLPSYSTEMTIME, NULL,
  503. "PSYSTEMTIME", PrtLPSYSTEMTIME, NULL,
  504. "const SYSTEMTIME *", PrtLPSYSTEMTIME, NULL,
  505. "const SYSTEMTIME*", PrtLPSYSTEMTIME, NULL,
  506. "LPWIN32_FIND_DATAA", PrtLPWIN32_FIND_DATAA, NULL,
  507. "PWIN32_FIND_DATAA", PrtLPWIN32_FIND_DATAA, NULL,
  508. "LPWIN32_FIND_DATAW", PrtLPWIN32_FIND_DATAW, NULL,
  509. "PWIN32_FIND_DATAW", PrtLPWIN32_FIND_DATAW, NULL,
  510. "LPCDLGTEMPLATEA", PrtLPDLGTEMPLATEA, NULL,
  511. "LPCDLGTEMPLATEW", PrtLPDLGTEMPLATEW, NULL,
  512. "LPDLGTEMPLATEA", PrtLPDLGTEMPLATEA, NULL,
  513. "LPDLGTEMPLATEW", PrtLPDLGTEMPLATEW, NULL,
  514. "LPDLGITEMTEMPLATEA", PrtLPDLGITEMTEMPLATEA, NULL,
  515. "LPDLGITEMTEMPLATEW", PrtLPDLGITEMTEMPLATEW, NULL,
  516. #endif
  517. "LPNCB", PrtLPNCB, NULL
  518. };
  519. int nIoTypes = sizeof(IoTypes)/sizeof(IoTypes[0]);
  520. SPECIAL SpecialCases[] =
  521. {
  522. #ifdef WIN32
  523. "AppendMenuA", DoAppendMenu,
  524. "AppendMenuW", DoAppendMenuW,
  525. "ChangeMenuA", DoChangeMenu,
  526. "ChangeMenuW", DoChangeMenuW,
  527. "ModifyMenuA", DoModifyMenu,
  528. "ModifyMenuW", DoModifyMenuW,
  529. "SearchPathA", DoSearchPathA,
  530. "SearchPathW", DoSearchPathW,
  531. "GetStartupInfoA", DoGetStartupInfoA,
  532. "GetStartupInfoW", DoGetStartupInfoW,
  533. "CreateWindowExA", DoCreateWindow,
  534. "CreateWindowExW", DoCreateWindowW,
  535. "DefWindowProcA", DoMessageA,
  536. "DefWindowProcW", DoMessageW,
  537. "DefMDIChildProcA", DoMessageA,
  538. "DefMDIChildProcW", DoMessageW,
  539. "DefDlgProcA", DoMessageA,
  540. "DefDlgProcW", DoMessageW,
  541. "GetMessageA", DoGetMessage,
  542. "GetMessageW", DoGetMessage,
  543. "PeekMessageA", DoCallPeek,
  544. "PeekMessageW", DoCallPeek,
  545. "PostAppMessageA", DoMessageA,
  546. "PostAppMessageW", DoMessageW,
  547. "PostMessageA", DoMessageA,
  548. "PostMessageW", DoMessageW,
  549. "SendMessageA", DoMessageA,
  550. "SendMessageW", DoMessageW,
  551. "SendDlgItemMessageA", DoMessageA,
  552. "SendDlgItemMessageW", DoMessageW,
  553. "CallWindowProcA", DoMessageA,
  554. "CallWindowProcW", DoMessageW,
  555. "TextOutA", DoTextOut,
  556. "TextOutW", DoTextOutW,
  557. "GetTextExtentA", DoGetTextExtent,
  558. "GetTextExtentW", DoGetTextExtentW,
  559. #else
  560. "AppendMenu", DoAppendMenu,
  561. "ChangeMenu", DoChangeMenu,
  562. "ModifyMenu", DoModifyMenu,
  563. "CreateWindow", DoCreateWindow,
  564. "CreateWindowEx", DoCreateWindow,
  565. "DefWindowProc", DoMessage,
  566. "DefMDIChildProc", DoMessage,
  567. "DefDlgProc", DoMessage,
  568. "GetMessage", DoGetMessage,
  569. "PeekMessage", DoCallPeek,
  570. "PostAppMessage", DoMessage,
  571. "PostMessage", DoMessage,
  572. "SendMessage", DoMessage,
  573. "SendDlgItemMessage", DoMessage,
  574. "CallWindowProc", DoMessage,
  575. "TextOut", DoTextOut,
  576. "GetTextExtent", DoGetTextExtent,
  577. "CreateDialogIndirect", DoCreateDialogIndirect,
  578. #endif
  579. "DPtoLP", DoHDC_LPPOINT_int,
  580. "LPtoDP", DoHDC_LPPOINT_int,
  581. "Polygon", DoHDC_LPPOINT_int,
  582. "Polyline", DoHDC_LPPOINT_int,
  583. "_lread", Do_lreadwrite,
  584. "_lwrite", Do_lreadwrite,
  585. "SetKeyboardState", DoGetSetKeyboardState,
  586. "Escape", DoEscape,
  587. "CreateBitmap", DoCreateBitmap,
  588. "CreateDIBitmap", DoCreateDIBitmap,
  589. "SetBitmapBits", DoSetBitmapBits,
  590. "LoadModule", DoLoadModule,
  591. "CreatePolygonRgn", DoCreatePolygonRgn,
  592. "SetPaletteEntries", DoSetPaletteEntries,
  593. "SetClipboardData", DoSetClipboardData,
  594. } ;
  595. int nSpecialCases = sizeof(SpecialCases)/sizeof(SpecialCases[0]) ;
  596. SPECIAL RetSpecialCases[] =
  597. {
  598. #ifdef WIN32
  599. "CreateWindowExA", DoCreateWindowRet,
  600. "CreateWindowExW", DoCreateWindowRet,
  601. "GetMessageA", DoGetMessageRet,
  602. "GetMessageW", DoGetMessageRet,
  603. "PeekMessageA", DoRetPeek,
  604. "PeekMessageW", DoRetPeek,
  605. #else
  606. "CreateWindow", DoCreateWindowRet,
  607. "CreateWindowEx", DoCreateWindowRet,
  608. "GetMessage", DoGetMessageRet,
  609. "PeekMessage", DoRetPeek,
  610. #endif
  611. "GlobalLock", DoRetSimpleLPSTR,
  612. "GlobalWire", DoRetSimpleLPSTR,
  613. "_lread", DoRet_lread,
  614. "GetKeyboardState", DoGetSetKeyboardState,
  615. "LockResource", DoRetSimpleLPSTR,
  616. "Escape", DoRetEscape,
  617. "GetPaletteEntries", DoRetPalettes,
  618. "GlobalHandle", DoRetGlobalHandle,
  619. "GetClipboardData", DoRetGetClipboardData,
  620. "GetSystemPaletteEntries", DoRetPalettes
  621. } ;
  622. int nRetSpecialCases = sizeof(RetSpecialCases)/sizeof(RetSpecialCases[0]) ;
  623. unsigned int nLogBuff = LOG_BUFF ;
  624. char LogBuffer[LOG_BUFF+1] = {0};
  625. LPSTR LogPtr = (LPSTR)LogBuffer;
  626. unsigned int nLogSize;
  627. char far *SCP;
  628. WORD far *WCP;
  629. OFSTRUCT ofFileData, ofDataFile;
  630. BOOL fFlushed = FALSE;
  631. void CheckEntryForInstTable (WORD hInstanceCaller);
  632. VOID FAR LogInstanceIn(LPSTR lpstrFormat, ...);
  633. VOID FAR LogInstanceOut(LPSTR lpstrFormat,...);
  634. #ifdef WIN32
  635. BOOL WINAPI Logger32SetType( DWORD dwFlags )
  636. {
  637. if( dwFlags & LOGGER_DRVLOG )
  638. {
  639. ACCESS(fDrvLog) = TRUE ;
  640. ACCESS(fLogSync) = TRUE ;
  641. }
  642. if( dwFlags & LOGGER_ENGLOG )
  643. {
  644. ACCESS(fDrvLog) = TRUE ;
  645. ACCESS(fLogSync) = TRUE ;
  646. }
  647. return TRUE ; ;
  648. }
  649. #endif
  650. void FlushBuff( void )
  651. {
  652. HANDLE hLogFile;
  653. fFlushed = TRUE;
  654. if ( nLogSize != 0 ) {
  655. switch( ACCESS(cDbgPort) ) {
  656. case TRUE:
  657. *LogPtr = '\0';
  658. LogPtr = (LPSTR)LogBuffer;
  659. OutputDebugString(LogPtr);
  660. break;
  661. case FALSE:
  662. LogPtr = (LPSTR)LogBuffer;
  663. hLogFile = OpenFile( ACCESS(szLogFileName),
  664. (LPOFSTRUCT)&ofFileData,
  665. OF_READWRITE | OF_REOPEN | OF_SHARE_DENY_NONE );
  666. if( hLogFile )
  667. {
  668. _llseek( hLogFile, 0L, 2 );
  669. nLogSize = _lwrite( hLogFile, LogPtr, nLogSize );
  670. _lclose( hLogFile );
  671. }
  672. break;
  673. case 2:
  674. LogPtr = (LPSTR)LogBuffer;
  675. break;
  676. }
  677. nLogSize = 0;
  678. }
  679. }
  680. void WriteBuff( LPSTR lpText )
  681. {
  682. char ch;
  683. while ( (ch = *lpText++) != '\0' ) {
  684. if ( nLogSize == nLogBuff ) {
  685. FlushBuff();
  686. }
  687. *LogPtr++ = ch;
  688. nLogSize++;
  689. nLogSpot++;
  690. }
  691. }
  692. void EndLineBuff( void )
  693. {
  694. WriteBuff( (LPSTR)"\r\n" );
  695. if ( !ACCESS(fTiming) ) {
  696. switch( ACCESS(cDbgPort) ) {
  697. case 2:
  698. case TRUE:
  699. FlushBuff();
  700. break;
  701. case FALSE:
  702. break;
  703. }
  704. }
  705. else
  706. {
  707. if( ACCESS(fLogSync) )
  708. FlushBuff() ; // Sync'd logs mean EOL flushes
  709. }
  710. }
  711. HWND WhereWindow( HWND hWnd, POINT pt, BOOL *lpfInClient )
  712. {
  713. HWND hWndChild;
  714. RECT rect;
  715. POINT ptCoord;
  716. /*
  717. ** Search through the list of children of the passed in window
  718. ** If found a child that it is in, then recurse, otherwise return window
  719. */
  720. hWndChild = GetWindow( hWnd, GW_CHILD );
  721. while ( hWndChild ) {
  722. GetWindowRect( hWndChild, &rect );
  723. if ( PtInRect(&rect, pt) ) {
  724. return( WhereWindow(hWndChild,pt,lpfInClient) );
  725. }
  726. hWndChild = GetWindow( hWndChild, GW_HWNDNEXT );
  727. }
  728. GetClientRect( hWnd, &rect );
  729. ptCoord.x = rect.left;
  730. ptCoord.y = rect.top;
  731. ClientToScreen( hWnd, &ptCoord );
  732. rect.left = ptCoord.x;
  733. rect.top = ptCoord.y;
  734. ptCoord.x = rect.right;
  735. ptCoord.y = rect.bottom;
  736. ClientToScreen( hWnd, &ptCoord );
  737. rect.right = ptCoord.x;
  738. rect.bottom = ptCoord.y;
  739. *lpfInClient = PtInRect(&rect,pt);
  740. return( hWnd );
  741. }
  742. void FAR PASCAL filterfunc( int nCode, WORD wParam, DWORD lParam )
  743. {
  744. LPEVENTMSG msg;
  745. HWND hwndCapture;
  746. msg = (LPEVENTMSG)lParam;
  747. if ( msg != NULL ) {
  748. switch( msg->message )
  749. {
  750. default:
  751. hwndCapture = GetCapture();
  752. if( hwndCapture == NULL )
  753. hwndCapture = GetFocus() ;
  754. break ;
  755. case WM_MOUSEMOVE:
  756. {
  757. POINT pt ;
  758. BOOL f;
  759. pt.x = msg->paramL ;
  760. pt.y = msg->paramH ;
  761. hwndCapture = WhereWindow( GetDesktopWindow(), pt, &f );
  762. }
  763. break ;
  764. }
  765. wsprintf( chBuffer,
  766. "++|INPUT:x {%04X %04X %04X %08lX} %04X",
  767. msg->message,
  768. msg->paramL,
  769. msg->paramH,
  770. msg->time,
  771. hwndCapture );
  772. WriteBuff( chBuffer );
  773. EndLineBuff();
  774. }
  775. if ( nCode < 0 ) {
  776. DefHookProc( nCode, wParam, lParam, &hOldHook );
  777. }
  778. }
  779. void FAR PASCAL EvtLogHook( int nCode, WORD wParam, DWORD lParam )
  780. {
  781. LPEVENTMSG msg;
  782. HWND hwndCapture;
  783. msg = (LPEVENTMSG)lParam;
  784. if ( msg != NULL ) {
  785. hwndCapture = GetCapture();
  786. wsprintf( chBuffer,
  787. "++|INPUT:x {%04X %04X %04X %08lX} %04X ",
  788. msg->message,
  789. msg->paramL,
  790. msg->paramH,
  791. msg->time,
  792. hwndCapture );
  793. WriteBuff( chBuffer );
  794. EndLineBuff();
  795. }
  796. }
  797. /*
  798. ** This function will be called by MS-TEST/WINPLAY tools if running
  799. */
  800. BOOL fAutoDrive = FALSE ;
  801. DWORD FAR PASCAL InitLogger( void )
  802. {
  803. DWORD dwRet ;
  804. fAutoDrive = TRUE ;
  805. dwRet = (DWORD)EvtLogHook ;
  806. return dwRet ;
  807. }
  808. void GlobalInitLib( BOOL fInit )
  809. {
  810. char text[100];
  811. if( fInit )
  812. {
  813. /*
  814. ** Get Controlling information from the .INI file
  815. */
  816. ACCESS(cDbgPort) = GetProfileInt( "Logger", "DbgPort", FALSE );
  817. ACCESS(fTiming) = GetProfileInt( "Logger", "Timing", FALSE );
  818. ACCESS(fNotes) = GetProfileInt( "Logger", "Notes", TRUE );
  819. ACCESS(fINT21H) = GetProfileInt( "Logger", "Int21h", ACCESS(fINT21H) ) ;
  820. ACCESS(fAPIOnly) = GetProfileInt( "Logger", "APIOnly", FALSE ) ;
  821. ACCESS(fLogSync) = GetProfileInt( "Logger", "LogSync", FALSE ) ;
  822. ACCESS(fElapsedTimes)= GetProfileInt( "Logger", "TimerTicks", FALSE ) ?
  823. FALSE : TRUE ;
  824. #ifdef WIN32
  825. if( !ACCESS(fLogSync) )
  826. {
  827. GetProfileString( "LOGGER", "LogFile", "OUTPUT32.LOG",
  828. ACCESS(szLogFileName), sizeof(ACCESS(szLogFileName)) );
  829. GetProfileString( "LOGGER", "DatFile", "OUTPUT32.DAT",
  830. ACCESS(szDatFileName), sizeof(ACCESS(szDatFileName)) );
  831. }
  832. else
  833. #endif
  834. {
  835. GetProfileString( "LOGGER", "LogFile", "OUTPUT.LOG",
  836. ACCESS(szLogFileName), sizeof(ACCESS(szLogFileName)) );
  837. GetProfileString( "LOGGER", "DatFile", "OUTPUT.DAT",
  838. ACCESS(szDatFileName), sizeof(ACCESS(szDatFileName)) );
  839. }
  840. if ( ACCESS(fTiming) )
  841. {
  842. ACCESS(fLogObjects) = GetProfileInt( "LOGGER", "LogObjects", FALSE );
  843. }
  844. else
  845. {
  846. ACCESS(fLogObjects) = GetProfileInt( "LOGGER", "LogObjects", TRUE );
  847. }
  848. ACCESS(nLogIndent) = 1;
  849. ACCESS(fLogInit) = TRUE;
  850. // Create/Truncate the the files
  851. #if !defined(WIN32)
  852. // Since Logger32 would be loaded first make sure that 16 bit Logger doesn't truncate
  853. // the log that Logger32 has already written to.
  854. if( ACCESS(fLogSync) )
  855. {
  856. HANDLE hLogFile, hDataFile;
  857. hLogFile = OpenFile( ACCESS(szLogFileName),
  858. (LPOFSTRUCT)&ofFileData,
  859. OF_WRITE | OF_SHARE_DENY_NONE );
  860. _lclose( hLogFile );
  861. hDataFile = OpenFile( ACCESS(szDatFileName),
  862. (LPOFSTRUCT)&ofDataFile,
  863. OF_WRITE | OF_SHARE_DENY_NONE );
  864. _lclose( hDataFile );
  865. }
  866. else
  867. #endif
  868. {
  869. HANDLE hLogFile, hDataFile;
  870. hLogFile = OpenFile( ACCESS(szLogFileName),
  871. (LPOFSTRUCT)&ofFileData,
  872. OF_CREATE | OF_WRITE | OF_SHARE_DENY_NONE );
  873. _lclose( hLogFile );
  874. hDataFile = OpenFile( ACCESS(szDatFileName),
  875. (LPOFSTRUCT)&ofDataFile,
  876. OF_CREATE | OF_WRITE | OF_SHARE_DENY_NONE );
  877. _lclose( hDataFile );
  878. }
  879. // Do Header Info
  880. /*
  881. ** Determine the current directory
  882. */
  883. #if !defined(WIN32)
  884. if( !ACCESS(fLogSync) )
  885. #endif
  886. {
  887. int hTempFile;
  888. OFSTRUCT ofTemp;
  889. char *pch;
  890. char *pchLastDelimiter;
  891. hTempFile = OpenFile( "LOGGER.TMP",
  892. (LPOFSTRUCT)&ofTemp,
  893. OF_CREATE | OF_WRITE | OF_SHARE_DENY_NONE );
  894. _lclose( hTempFile );
  895. pch = ofTemp.szPathName;
  896. while ( *pch ) {
  897. if ( *pch == '\\' || *pch == '/' ) {
  898. pchLastDelimiter = pch;
  899. }
  900. pch++;
  901. }
  902. strcpy( ACCESS(achCurrentDirectory), ofTemp.szPathName );
  903. ACCESS(achCurrentDirectory)[pchLastDelimiter - ofTemp.szPathName] = '\0';
  904. wsprintf( text, "++|Current directory is [%s]", (LPSTR)ACCESS(achCurrentDirectory) );
  905. WriteBuff( text );
  906. EndLineBuff();
  907. }
  908. #if !defined(WIN32)
  909. if( !ACCESS(fLogSync) )
  910. #endif
  911. if ( fAlias )
  912. {
  913. WriteBuff("++|Aliasing Enabled");
  914. EndLineBuff();
  915. }
  916. if ( ACCESS(fTiming) )
  917. #if !defined(WIN32)
  918. if( !ACCESS(fLogSync) )
  919. #endif
  920. {
  921. // Show that we think we are timing
  922. if( ACCESS(fElapsedTimes) )
  923. {
  924. wsprintf( text,"++|Timing (Elapsed) Enabled" ) ;
  925. }
  926. else
  927. {
  928. wsprintf( text,"++|Timing (Ticks) Enabled" ) ;
  929. }
  930. WriteBuff(text);
  931. EndLineBuff();
  932. }
  933. }
  934. else
  935. {
  936. // Logger is being inited for the second time.
  937. // Flush the current instance's buffers and go into LogSync mode.
  938. FlushBuff() ;
  939. ACCESS(fLogSync) = TRUE ;
  940. }
  941. }
  942. void LocalInitLib( void )
  943. {
  944. int count;
  945. unsigned char hashvalue;
  946. DWORD version;
  947. WORD SpecialDS;
  948. BOOL fMouseHack;
  949. /*
  950. ** Determine which system we are on
  951. */
  952. WindowsVerRunning = (int)GetVersion();
  953. nLogBuff = GetProfileInt( "Logger", "FlushAfter", nLogBuff ) ;
  954. fAlias = GetProfileInt( "LOGGER", "Alias", FALSE );
  955. /*
  956. ** Under WOW, default to no mousehack
  957. ** On Win 3.1, default to yes mousehack
  958. */
  959. fMouseHack = GetProfileInt( "LOGGER", "MouseHack", !ACCESS(fWOW) );
  960. /*
  961. ** Initialize the logging variables
  962. */
  963. LogPtr = (LPSTR)LogBuffer;
  964. nLogSize = 0;
  965. /*
  966. ** Install a journal recording hook (input queue hook) so that
  967. ** we can watch the app being fed.
  968. */
  969. fInputHook = GetProfileInt( "LOGGER", "InputHook", FALSE );
  970. if ( fInputHook ) {
  971. fpNewHook = MakeProcInstance((FARPROC)filterfunc,hLibInstance);
  972. hOldHook = (HHOOK)SetWindowsHook( WH_JOURNALRECORD, (HOOKPROC)fpNewHook );
  973. }
  974. /*
  975. ** Also initialize the type I/O hash table
  976. */
  977. for ( count = 0; count < nIoTypes; count++ ) {
  978. /*
  979. ** Process this IoRtn
  980. */
  981. hashvalue = (char)HASH_FUNC(IoTypes[count].name);
  982. IoTypes[count].next = typehash[hashvalue];
  983. typehash[hashvalue] = &IoTypes[count];
  984. }
  985. if ( fMouseHack ) {
  986. /*
  987. ** Initialize the special hack variables
  988. */
  989. SCP = (char FAR *)SetCursorPos + 9;
  990. WCP = (WORD FAR *)SCP;
  991. version = GetVersion();
  992. if ( version == 0x003 ) {
  993. SpecialDS = *WCP;
  994. lpfMouseMoved = (int FAR *)MAKELONG(0x0004,SpecialDS);
  995. }
  996. SCP += 5;
  997. WCP = (WORD far *)SCP;
  998. if ( version == 0xA03 ) {
  999. SpecialDS = *WCP;
  1000. lpfMouseMoved = (int FAR *)MAKELONG(0x0002,SpecialDS);
  1001. }
  1002. }
  1003. SetupCorrespondenceTables();
  1004. if( ACCESS(fTiming) && !ACCESS(fElapsedTimes) )
  1005. {
  1006. // Open and init the global timer
  1007. TimerOpen ((short far *)&TimerHandle[0], MICROSECONDS);
  1008. TimerInit (TimerHandle[0]);
  1009. CalibrateTimer() ;
  1010. fTimerCalibrated = TRUE ;
  1011. }
  1012. }
  1013. void InitLib( BOOL bInit )
  1014. {
  1015. GlobalInitLib(bInit) ;
  1016. LocalInitLib() ;
  1017. }
  1018. /*--------------------------------------------------------------------------
  1019. ** WEP() - Called when the DLL is unloaded.
  1020. ** This routine closes the log file.
  1021. **--------------------------------------------------------------------------
  1022. */
  1023. VOID FAR PASCAL WEP(
  1024. int bSystemExit
  1025. ) {
  1026. // char lpText[60];
  1027. /*
  1028. ** Unhook the journal recording hook
  1029. */
  1030. if( fInputHook )
  1031. {
  1032. UnhookWindowsHook( WH_JOURNALRECORD, (HOOKPROC)fpNewHook );
  1033. }
  1034. /*
  1035. ** Close the log file
  1036. */
  1037. FlushBuff();
  1038. // Notify MS-TEST/WINPLAY that we are being unloaded
  1039. if( fAutoDrive )
  1040. {
  1041. void (FAR WINAPI *fp)( DWORD );
  1042. HANDLE hMod ;
  1043. hMod = GetModuleHandle( "TESTEVNT.DLL" ) ;
  1044. if( hMod == NULL )
  1045. {
  1046. hMod = GetModuleHandle( "WATTEVNT.DLL" ) ;
  1047. }
  1048. if( hMod )
  1049. {
  1050. fp = (void (FAR WINAPI *)(DWORD))GetProcAddress( hMod, "RegisterLogger" ) ;
  1051. if( fp )
  1052. {
  1053. (*fp)( (DWORD)NULL ) ;
  1054. }
  1055. }
  1056. }
  1057. #ifdef WIN32
  1058. #else
  1059. // set the int21 handler to be handled by the original handler.
  1060. if( fINT21H )
  1061. GetSetKernelDOSProc ((DWORD)OrigHandler);
  1062. #endif
  1063. return;
  1064. }
  1065. #ifdef WIN32
  1066. /*-----------------------------------------------------------------------------
  1067. ** NT needs this to know when the DLL is going away (when to call the WEP).
  1068. **-----------------------------------------------------------------------------
  1069. */
  1070. BOOL APIENTRY LibMain(HANDLE hModule, DWORD fdwReason, PCONTEXT pContext)
  1071. {
  1072. BOOL fInit = TRUE ;
  1073. #ifdef SHARED_MEM
  1074. BOOL fIgnore;
  1075. PSECURITY_DESCRIPTOR psd ;
  1076. DWORD dwErr ;
  1077. #endif
  1078. /*
  1079. ** We're just going to set them equal for now. This removes compiler
  1080. ** warnings under NT.
  1081. */
  1082. pContext = pContext;
  1083. hModule = hModule;
  1084. switch ( fdwReason )
  1085. {
  1086. case DLL_PROCESS_ATTACH:
  1087. #ifdef SHARED_MEM
  1088. // Need a Security Descriptor to make sure ALL processes can get
  1089. // to the shared memory
  1090. psd = (PSECURITY_DESCRIPTOR)LocalAlloc( LPTR,
  1091. SECURITY_DESCRIPTOR_MIN_LENGTH ) ;
  1092. if( !psd )
  1093. {
  1094. OutputDebugString( "LOGGER32:LocalAlloc failed for security descriptor\n" ) ;
  1095. return FALSE ;
  1096. }
  1097. if( !InitializeSecurityDescriptor(psd, SECURITY_DESCRIPTOR_REVISION) )
  1098. {
  1099. OutputDebugString( "LOGGER32:Failed to init security descriptor\n" ) ;
  1100. }
  1101. if( !SetSecurityDescriptorDacl( psd, TRUE, (PACL)NULL, FALSE ) )
  1102. {
  1103. OutputDebugString( "LOGGER32:Set DACL failed!\n" ) ;
  1104. }
  1105. hMapObject = CreateFileMapping(
  1106. (HANDLE) 0xFFFFFFFF, /* use paging file */
  1107. psd, /* security attr. */
  1108. PAGE_READWRITE, /* read/write access */
  1109. 0, /* size: high 32-bits */
  1110. SHMEMSIZE, /* size: low 32-bits */
  1111. "LOGGER32MemoryMap"); /* name of map object */
  1112. dwErr = GetLastError() ;
  1113. if (hMapObject == NULL)
  1114. {
  1115. OutputDebugString( "LOGGER32:CreateFileMapping Failed!\n" ) ;
  1116. return FALSE;
  1117. }
  1118. /* The first process to attach initializes memory. */
  1119. fInit = (dwErr != ERROR_ALREADY_EXISTS);
  1120. /* Get a pointer to file mapped shared memory. */
  1121. pVars = MapViewOfFile(
  1122. hMapObject, /* object to map view of */
  1123. FILE_MAP_WRITE, /* read/write access */
  1124. 0, /* high offset: map from */
  1125. 0, /* low offset: beginning */
  1126. 0); /* default: map entire file */
  1127. if (pVars == NULL)
  1128. {
  1129. OutputDebugString( "LOGGER32:MapViewOfFile failed!\n" ) ;
  1130. return FALSE;
  1131. }
  1132. /* Initialize memory if this is the first process. */
  1133. if (fInit)
  1134. {
  1135. if( !SetKernelObjectSecurity( hMapObject, DACL_SECURITY_INFORMATION,
  1136. psd ) )
  1137. {
  1138. OutputDebugString("LOGGER32:FAILED to set KernelObjSecurity\n" ) ;
  1139. }
  1140. }
  1141. #endif
  1142. InitLib(fInit) ;
  1143. #ifdef SHARED_MEM
  1144. if( psd )
  1145. LocalFree( (HLOCAL)psd ) ;
  1146. #endif
  1147. break;
  1148. case DLL_PROCESS_DETACH:
  1149. WEP(0) ;
  1150. #ifdef SHARED_MEM
  1151. /* Unmap shared memory from process' address space. */
  1152. fIgnore = UnmapViewOfFile(pVars);
  1153. /* Close the process' handle to the file-mapping object. */
  1154. fIgnore = CloseHandle(hMapObject);
  1155. #endif
  1156. break;
  1157. }
  1158. return TRUE ;
  1159. }
  1160. #endif
  1161. /*-----------------------------------------------------------------------------
  1162. ** lpartial_strcpy() - Called to copy only part of a string.
  1163. ** This routine copies an entire string, or the string up until some specified
  1164. ** character into a destination string. This is used to help parse the format
  1165. ** string passed to LogStuff().
  1166. **-----------------------------------------------------------------------------
  1167. */
  1168. LPSTR lpartial_strcpy(
  1169. LPSTR lpstrDest,
  1170. LPSTR lpstrSource,
  1171. char ch,
  1172. int nMaxLen
  1173. ) {
  1174. char chOther;
  1175. while ( (chOther=*lpstrSource) != '\0' ) {
  1176. lpstrSource++;
  1177. if ( chOther == ch ) {
  1178. *lpstrDest = '\0';
  1179. return(lpstrSource);
  1180. }
  1181. *lpstrDest++ = chOther;
  1182. --nMaxLen;
  1183. if ( nMaxLen == 0 ) {
  1184. *lpstrDest = '\0';
  1185. return(lpstrSource);
  1186. }
  1187. }
  1188. return( lpstrSource );
  1189. }
  1190. /*-----------------------------------------------------------------------------
  1191. ** LogStuff() - Called when something needs to be logged.
  1192. ** This routine logs the parameters (based on type) into the log file.
  1193. **-----------------------------------------------------------------------------
  1194. */
  1195. VOID LogStuff(
  1196. LPSTR lpstrFormat,
  1197. unsigned long ulTime,
  1198. va_list marker
  1199. ) {
  1200. char chType[9] ;
  1201. char chApi[MAX_BUFF+1];
  1202. char chBuff[MAX_BUFF+1];
  1203. LPSTR lpDest;
  1204. int nLen;
  1205. LPSTR lpSpot;
  1206. LPSTR lpNext;
  1207. short s;
  1208. unsigned char hashvalue;
  1209. TYPEIO *typeio;
  1210. int count;
  1211. nLogLine++;
  1212. nLineLen = 0;
  1213. /*
  1214. ** Log the information
  1215. */
  1216. lpDest = (LPSTR)chBuff;
  1217. #ifdef WIN32
  1218. wsprintf( lpDest, (LPSTR)"%02X!", ACCESS(nLogIndent) );
  1219. #else
  1220. wsprintf( lpDest, (LPSTR)"%02X|", ACCESS(nLogIndent) );
  1221. #endif
  1222. WriteBuff( lpDest );
  1223. nLineLen += 3;
  1224. if( ACCESS(fTiming) )
  1225. {
  1226. wsprintf( lpDest, (LPSTR)" %08lX|", ulTime );
  1227. WriteBuff( (LPSTR)lpDest );
  1228. nLineLen += 10;
  1229. }
  1230. /* pull off the identifier */
  1231. lpSpot = lpartial_strcpy( chType, lpstrFormat, ':', MAX_BUFF );
  1232. WriteBuff( (LPSTR)chType ) ;
  1233. WriteBuff( (LPSTR)":" ) ;
  1234. nLineLen += lstrlen(chType) + 1;
  1235. if ( chType[0] != 'M' )
  1236. {
  1237. /* pull off API name */
  1238. lpDest = (LPSTR)chApi;
  1239. lpSpot = lpartial_strcpy( lpDest, lpSpot, ' ', MAX_BUFF );
  1240. WriteBuff( lpDest );
  1241. if ( ACCESS(fTiming) == 2 || ACCESS(fAPIOnly) ) {
  1242. EndLineBuff();
  1243. return;
  1244. }
  1245. // have to save and restore di & si registers while calling Dos3Call.
  1246. // This is currently not done in the z Dlls.
  1247. if (chApi[3] == '3')
  1248. fDos3Call = TRUE;
  1249. //
  1250. WriteBuff( (LPSTR)" " );
  1251. nLineLen += lstrlen(lpDest) + 1;
  1252. }
  1253. else
  1254. {
  1255. if( ACCESS(fAPIOnly) )
  1256. {
  1257. EndLineBuff() ;
  1258. return ;
  1259. }
  1260. if ( ACCESS(fTiming) == 2 )
  1261. {
  1262. WriteBuff( (LPSTR)"?" );
  1263. EndLineBuff();
  1264. return;
  1265. }
  1266. /* special MSGCALL/RET routine */
  1267. #ifdef WIN32
  1268. DoMessageA( (LPSTR)chType, lpSpot, marker ) ;
  1269. #else
  1270. DoMessage( (LPSTR)chType, lpSpot, marker ) ;
  1271. #endif
  1272. EndLineBuff() ;
  1273. return ;
  1274. }
  1275. /* Do we need to call a special case ?? */
  1276. if ( chType[3] == 'C' ) /* CALL special cases */
  1277. {
  1278. for( count = 0; count < nSpecialCases; count++ )
  1279. {
  1280. if( lstrcmp( (LPSTR)chApi, (LPSTR)SpecialCases[count].name) == 0 )
  1281. {
  1282. /* call special case and return */
  1283. (*SpecialCases[count].rtn)( (LPSTR)chApi, lpSpot, marker ) ;
  1284. EndLineBuff() ;
  1285. return ;
  1286. }
  1287. }
  1288. }
  1289. else
  1290. { /* RET special cases */
  1291. for( count = 0; count < nRetSpecialCases; count++ )
  1292. {
  1293. if( lstrcmp( (LPSTR)chApi, (LPSTR)RetSpecialCases[count].name) == 0 )
  1294. {
  1295. /* call special case and return */
  1296. (*RetSpecialCases[count].rtn)( (LPSTR)chApi, lpSpot, marker ) ;
  1297. EndLineBuff() ;
  1298. return ;
  1299. }
  1300. }
  1301. }
  1302. lpDest = (LPSTR)chBuff;
  1303. while ( TRUE ) {
  1304. lpNext = lpartial_strcpy( lpDest, lpSpot, '+', MAX_BUFF );
  1305. if ( lpNext == lpSpot ) {
  1306. break;
  1307. }
  1308. nLen = lstrlen( lpDest );
  1309. if ( nLen == 0 ) {
  1310. /*
  1311. ** Default is an unprintable short (really a 0)
  1312. */
  1313. s = va_arg( marker, short );
  1314. lpSpot = lpNext;
  1315. continue ;
  1316. } else {
  1317. hashvalue = HASH_FUNC( lpDest );
  1318. typeio = typehash[hashvalue];
  1319. while ( typeio ) {
  1320. if ( lstrcmp(lpDest,(LPSTR)typeio->name) == 0 ) {
  1321. marker = (* typeio->rtn)( (LPSTR)chApi, marker );
  1322. break;
  1323. }
  1324. typeio = typeio->next;
  1325. }
  1326. if ( typeio == NULL ) {
  1327. for ( count = 0; count < nIoTypes; count++ ) {
  1328. if ( lstrcmp(lpDest,(LPSTR)IoTypes[count].name) == 0 ) {
  1329. WriteBuff( (LPSTR)"$Internal Logging Data Corrupted$" );
  1330. marker = (* IoTypes[count].rtn)( (LPSTR)chApi, marker );
  1331. typeio = &IoTypes[count];
  1332. break;
  1333. }
  1334. }
  1335. }
  1336. if ( typeio == NULL ) {
  1337. /*
  1338. ** These IFDEFs should be removed at some point. After we have most of the
  1339. ** 32-bit structures being dumped.
  1340. */
  1341. WriteBuff("\nUNKNOWN IOType:" ) ; //*** MJR MJR
  1342. WriteBuff( lpDest );
  1343. WriteBuff("!!!!!\n" ) ; //*** MJR MJR
  1344. FlushBuff() ; // Force write incase we fault
  1345. nLineLen += lstrlen(lpDest);
  1346. }
  1347. }
  1348. WriteBuff( (LPSTR)" " );
  1349. nLineLen++;
  1350. lpSpot = lpNext;
  1351. }
  1352. EndLineBuff();
  1353. }
  1354. /*-----------------------------------------------------------------------------
  1355. ** LogIn() - Called when an API is about to be called with Input parameters
  1356. ** This routine logs the input parameters to the log file.
  1357. **-----------------------------------------------------------------------------
  1358. */
  1359. VOID FAR LogIn( LPSTR lpstrFormat, ... )
  1360. {
  1361. va_list marker; // NTWINT had moved this outside LogIn
  1362. ULONG ulTime = 0 ;
  1363. #ifdef WIN32
  1364. DWORD dwError = GetLastError() ;
  1365. #endif
  1366. #ifdef INT21H
  1367. if( fINT21H )
  1368. {
  1369. fLogIn = TRUE;
  1370. ++cLogInInt21;
  1371. }
  1372. #endif
  1373. if ( !ACCESS(fLogInit) ) {
  1374. InitLib( TRUE );
  1375. }
  1376. if( ACCESS(fTiming) && !ACCESS(fElapsedTimes) )
  1377. {
  1378. ulTime = TimerRead(TimerHandle[0]) ;
  1379. }
  1380. switch( ACCESS(cDbg) ) {
  1381. case REST:
  1382. break;
  1383. case 0:
  1384. case 1:
  1385. case 2:
  1386. FlushBuff();
  1387. ACCESS(cDbgPort) = ACCESS(cDbg);
  1388. ACCESS(cDbg) = REST;
  1389. break;
  1390. }
  1391. switch( ACCESS(cDbgPort) ) {
  1392. case 2:
  1393. break;
  1394. case TRUE:
  1395. case FALSE:
  1396. va_start( marker, lpstrFormat );
  1397. LogStuff( lpstrFormat, ulTime, marker );
  1398. va_end( marker );
  1399. break;
  1400. }
  1401. ACCESS(nLogIndent)++;
  1402. #ifdef INT21H
  1403. if( fINT21H )
  1404. --cLogInInt21;
  1405. #endif
  1406. if( ACCESS(fTiming) && ACCESS(fElapsedTimes) )
  1407. {
  1408. // Time all calls, API, MSG etc.
  1409. TimerOpen((short far *)&TimerHandle[ACCESS(nLogIndent)-1], MICROSECONDS);
  1410. TimerInit(TimerHandle[ACCESS(nLogIndent)-1]);
  1411. }
  1412. #ifdef WIN32
  1413. SetLastError(dwError) ;
  1414. #endif
  1415. }
  1416. /*-----------------------------------------------------------------------------
  1417. ** LogData() - Called when someone wants to output some data.
  1418. **---------------------------------------------------------------------------
  1419. */
  1420. VOID FAR LogData(
  1421. LPSTR lpstrFormat,
  1422. ...
  1423. ) {
  1424. va_list marker;
  1425. if ( !ACCESS(fLogInit) ) {
  1426. InitLib( TRUE );
  1427. }
  1428. switch( ACCESS(cDbg) ) {
  1429. case REST:
  1430. break;
  1431. case 0:
  1432. case 1:
  1433. case 2:
  1434. FlushBuff();
  1435. ACCESS(cDbgPort) = ACCESS(cDbg) ;
  1436. ACCESS(cDbg) = REST;
  1437. break;
  1438. }
  1439. switch( ACCESS(cDbgPort) ) {
  1440. case 2:
  1441. break;
  1442. case TRUE:
  1443. case FALSE:
  1444. va_start( marker, lpstrFormat );
  1445. LogStuff( lpstrFormat, 0, marker );
  1446. va_end( marker );
  1447. break;
  1448. }
  1449. }
  1450. /*-----------------------------------------------------------------------------
  1451. ** LogOut() - Called when an API has just returned with Output parameters and
  1452. ** return code. This routine logs the output parameters to the log file.
  1453. **-----------------------------------------------------------------------------
  1454. */
  1455. // logging timing info
  1456. char chType[9] ;
  1457. char chIdent[9] ;
  1458. char chApi[MAX_BUFF+1];
  1459. char chBuff[MAX_BUFF+1];
  1460. LPSTR lpDest, lpDestString, lpNew;
  1461. int nLen;
  1462. LPSTR lpSpot;
  1463. unsigned long ulElapsedTime = 0L;
  1464. VOID FAR LogOut(
  1465. LPSTR lpstrFormat,
  1466. ...
  1467. ) {
  1468. va_list marker; // Commented out in NTWINT version
  1469. #ifdef WIN32
  1470. DWORD dwError = GetLastError() ;
  1471. #endif
  1472. if ( !ACCESS(fLogInit) ) {
  1473. InitLib( TRUE );
  1474. }
  1475. if( ACCESS(fTiming) )
  1476. {
  1477. // get the time for the API, MSG etc. call
  1478. // Dos3Call uses si and di. These two are not saved and
  1479. // restored by the z dll's. Until that is done, we can have
  1480. // fix in. - vaidy, June 8, 1992.
  1481. //#if !defined(WIN32)
  1482. // if (fDos3Call) {
  1483. // _asm {
  1484. // push di
  1485. // push si
  1486. // push es
  1487. // push ds
  1488. // push dx
  1489. // push cx
  1490. // push bx
  1491. // push ax
  1492. // };
  1493. // }
  1494. //#endif
  1495. if( ACCESS(fElapsedTimes) )
  1496. {
  1497. ulElapsedTime = TimerRead (TimerHandle[ACCESS(nLogIndent) - 1]);
  1498. }
  1499. else
  1500. {
  1501. ulElapsedTime = TimerRead(TimerHandle[0]);
  1502. }
  1503. //#if !defined(WIN32)
  1504. // if (fDos3Call) {
  1505. // _asm {
  1506. // pop ax
  1507. // pop bx
  1508. // pop cx
  1509. // pop dx
  1510. // pop ds
  1511. // pop es
  1512. // pop si
  1513. // pop di
  1514. // };
  1515. //
  1516. // fDos3Call = FALSE; // reset to FALSE.
  1517. // }
  1518. //#endif
  1519. #ifdef INT21H
  1520. if( fINT21H )
  1521. ++cLogInInt21;
  1522. #endif
  1523. // calibrate the timer for overhead if not already done
  1524. if (!fTimerCalibrated) {
  1525. CalibrateTimer ();
  1526. fTimerCalibrated = TRUE;
  1527. }
  1528. if( ACCESS(fElapsedTimes) )
  1529. {
  1530. TimerClose (TimerHandle[ACCESS(nLogIndent)-1]);
  1531. }
  1532. } // fTiming
  1533. --ACCESS(nLogIndent);
  1534. switch( ACCESS(cDbgPort) ) {
  1535. case 2:
  1536. break;
  1537. case TRUE:
  1538. case FALSE:
  1539. va_start( marker, lpstrFormat );
  1540. LogStuff( lpstrFormat, (unsigned long)(ulElapsedTime - ulOverhead),marker );
  1541. va_end( marker );
  1542. break;
  1543. }
  1544. switch( ACCESS(cDbg) ) {
  1545. case REST:
  1546. break;
  1547. case 0:
  1548. case 1:
  1549. case 2:
  1550. FlushBuff();
  1551. ACCESS(cDbgPort) = ACCESS(cDbg) ;
  1552. ACCESS(cDbg) = REST;
  1553. break;
  1554. }
  1555. #ifdef INT21H
  1556. if( fINT21H )
  1557. --cLogInInt21;
  1558. #endif
  1559. #ifdef WIN32
  1560. // restore last error
  1561. SetLastError(dwError) ;
  1562. #endif
  1563. }
  1564. DWORD StoreData( LPCSTR lpstrData, DWORD dwCount)
  1565. {
  1566. DWORD dwEnd;
  1567. HANDLE hDataFile;
  1568. hDataFile = OpenFile( ACCESS(szDatFileName), (LPOFSTRUCT)&ofDataFile,
  1569. OF_READWRITE | OF_REOPEN | OF_SHARE_DENY_NONE );
  1570. dwEnd = (DWORD) _llseek( hDataFile, 0L, 2 );
  1571. _lwrite( hDataFile, (LPSTR)&dwCount, sizeof(DWORD));
  1572. _lwrite( hDataFile, lpstrData, (int) dwCount);
  1573. _lclose( hDataFile );
  1574. return dwEnd;
  1575. }
  1576. UINT FAR PASCAL GetLogInfo(
  1577. UINT iInfoType
  1578. ) {
  1579. switch( iInfoType ) {
  1580. case LOG_OBJECTS:
  1581. return( (UINT)ACCESS(fLogObjects) );
  1582. default:
  1583. return( (UINT)0 );
  1584. }
  1585. }
  1586. /*----------------------------------------------------------------------------
  1587. ** CalibrateTimer() - Calibrates the timer for overhead in saving and
  1588. ** restoring registers.
  1589. **----------------------------------------------------------------------------
  1590. */
  1591. #define MAX_REPEAT_FOR_CALIBRATION 250
  1592. unsigned long ulRepetitions = 0L;
  1593. unsigned long ulLogIn [MAX_REPEAT_FOR_CALIBRATION];
  1594. unsigned long ulLogOut [MAX_REPEAT_FOR_CALIBRATION];
  1595. void CalibrateTimer(void) {
  1596. short CalibrationHandle;
  1597. unsigned long ulMinLogIn = 2000000L, ulMinLogOut = 2000000L;
  1598. TimerOpen ((short far *) &CalibrationHandle, MICROSECONDS);
  1599. while (ulRepetitions < MAX_REPEAT_FOR_CALIBRATION) {
  1600. #if !defined(WIN32)
  1601. SaveRegs(); // do not time this
  1602. #endif
  1603. TimerInit (CalibrationHandle);
  1604. #if !defined(WIN32)
  1605. RestoreRegs();
  1606. GrovelDS();
  1607. #endif
  1608. ulLogIn[ulRepetitions] = TimerRead (CalibrationHandle);
  1609. // login overhead done. Calibrate LogOut.
  1610. TimerInit (CalibrationHandle);
  1611. #if !defined(WIN32)
  1612. UnGrovelDS();
  1613. SaveRegs();
  1614. #endif
  1615. ulLogOut[ulRepetitions++] = TimerRead (CalibrationHandle);
  1616. // do not time
  1617. #if !defined(WIN32)
  1618. RestoreRegs();
  1619. #endif
  1620. } // end of while
  1621. // grab the minimum of LogIn and LogOut overheads and sum them
  1622. // for overall overhead.
  1623. for (ulRepetitions = 0L; ulRepetitions < MAX_REPEAT_FOR_CALIBRATION;
  1624. ulRepetitions++) {
  1625. if (ulLogIn[ulRepetitions] < ulMinLogIn)
  1626. ulMinLogIn = ulLogIn[ulRepetitions];
  1627. if (ulLogOut[ulRepetitions] < ulMinLogOut)
  1628. ulMinLogOut = ulLogOut[ulRepetitions];
  1629. }
  1630. ulOverhead = ulMinLogIn + ulMinLogOut;
  1631. return;
  1632. }
  1633. #if !defined(WIN32)
  1634. /*********************************************************************
  1635. PURPOSE: Contains library routines for the logger
  1636. FUNCTION: LibMain (HANDLE, WORD, WORD, LPSTR)
  1637. PURPOSE: Is called by LibEntry. LibEntry is called by Windows when
  1638. the DLL is loaded. The LibEntry routine is provided in
  1639. the LIBENTRY.OBJ in the SDK Link Libraries disk. (The
  1640. source LIBENTRY.ASM is also provided.)
  1641. LibEntry initializes the DLL's heap, if a HEAPSIZE value is
  1642. specified in the DLL's DEF file. Then LibEntry calls
  1643. LibMain. The LibMain function below satisfies that call.
  1644. The LibMain function should perform additional initialization
  1645. tasks required by the DLL.
  1646. LibMain should return a value of 1 if
  1647. the initialization is successful.
  1648. */
  1649. /*********************************************************************/
  1650. int FAR PASCAL LibMain(hModule, wDataSeg, cbHeapSize, lpszCmdLine)
  1651. HANDLE hModule;
  1652. WORD wDataSeg;
  1653. WORD cbHeapSize;
  1654. LPSTR lpszCmdLine;
  1655. {
  1656. #ifdef INT21H
  1657. if( fINT21H )
  1658. DoInt21Init();
  1659. #endif
  1660. return(1);
  1661. }
  1662. #endif
  1663. #ifdef INT21H
  1664. UINT WINAPI PrestoChangoSelector(UINT sourceSel, UINT destSel);
  1665. UINT WINAPI AllocSelector(UINT);
  1666. /*
  1667. * DoInt21Init() - called by LibMain to install the new Int21 Handler
  1668. *
  1669. * Accepts and returns nothing
  1670. */
  1671. void DoInt21Init () {
  1672. // get the original handler and replace with the address of
  1673. // the private handler.
  1674. // lpOrig points to OrigHandler.
  1675. lpOrig = &OrigHandler;
  1676. uSel = AllocSelector (HIWORD(lpOrig));
  1677. // change the CS to a DS selector. This way, we can write
  1678. // to OrigHandler. If we do not go thru' this, we will get
  1679. // a GP fault when we try to get the original Int21 handler
  1680. // & try to store it.
  1681. wSelData = PrestoChangoSelector ((UINT)HIWORD(lpOrig), uSel);
  1682. // we need to retain the LOWORD of lpOrig but get the
  1683. // new DS selector into the HIWORD of lpOrig.
  1684. dwTemp = wSelData;
  1685. dwTemp <<= 16;
  1686. lpOrig = (LPDWORD)((DWORD)lpOrig & 0xFFFF);
  1687. lpOrig = (LPDWORD) (dwTemp | (DWORD)lpOrig);
  1688. // call the kernel API to return the address of the
  1689. // original Int21 Handler.
  1690. *lpOrig = GetSetKernelDOSProc ((DWORD) _Int21_Handler);
  1691. }
  1692. #pragma pack (1) // pack on byte boundary for the MYFCB struct.
  1693. /*
  1694. * LogInt21Calls - gets called from the Int21 handler (handler.asm)
  1695. *
  1696. * Purpose is to log the params of the Int 21 calls
  1697. *
  1698. * Accepts - a whole bunch of regs and flags, returns - nothing
  1699. */
  1700. char chType[9] ;
  1701. char chBuff[MAX_BUFF+1];
  1702. LPSTR lpDest;
  1703. char Dummy[50];
  1704. BOOL fTimeInt21 = FALSE;
  1705. short hTimerInt21 = 0;
  1706. typedef struct _myfcb _MYFCB;
  1707. struct _myfcb {
  1708. char char1;
  1709. char Reserved [5];
  1710. char Attrib;
  1711. char DriveID;
  1712. char FileName[8];
  1713. char Extension[3];
  1714. int CurrentBlock;
  1715. int RecordSize;
  1716. long FileSize;
  1717. int Date;
  1718. int Time;
  1719. char LongReserved[8];
  1720. char CurrentRecord;
  1721. long RelativeRecord;
  1722. } ;
  1723. _MYFCB FAR * pmyFCB;
  1724. typedef struct _fn17hfcb _FN17HFCB;
  1725. struct _fn17hfcb {
  1726. char DriveID;
  1727. char OldFileName[8];
  1728. char OldExtension[3];
  1729. char Reserved[5];
  1730. char NewFileName[8];
  1731. char NewExtension[3];
  1732. char Zeroed[9];
  1733. };
  1734. _FN17HFCB FAR * pfn17FCB;
  1735. int iCount = 0;
  1736. char szFileName [9];
  1737. char szExtension [4];
  1738. char szNewFileName [9];
  1739. char szNewExtension [4];
  1740. char szPathName [MAX_PATH_NAME_LEN];
  1741. LPSTR pPathName;
  1742. WORD Int21Function = 0;
  1743. void _loadds LogInt21Calls (
  1744. WORD wFlags, WORD wBP, WORD wSS,
  1745. WORD wES, WORD wDS, WORD wSI, WORD wDI,
  1746. WORD wDX, WORD wCX, WORD wBX,
  1747. WORD wAX, WORD Dummy1, WORD Dummy2,
  1748. WORD Dummy3, WORD Dummy4, WORD wIP, WORD wCS
  1749. ) {
  1750. if (!cLogInInt21) { // makes sure that we are not logging spurious disk
  1751. // I/O.
  1752. // log only if at an odd level & log only if logger has logged
  1753. // one Windows API.
  1754. if (((nLogIndent) & 1) && fLogIn) {
  1755. // set the int21 handler to be handled by the original handler.
  1756. // We need to log the Int21 call, right?
  1757. GetSetKernelDOSProc ((DWORD)OrigHandler);
  1758. // print & count only if the call is not from
  1759. // the KERNEL, GDI or USER.
  1760. // if ((lstrcmp (ModuleEntry.szModule, "KERNEL") != 0) &&
  1761. // (lstrcmp (ModuleEntry.szModule, "USER") != 0) &&
  1762. // (lstrcmp (ModuleEntry.szModule, "GDI") != 0)) {
  1763. // for the present just add up all Int21 calls made by app
  1764. cInt21CallsByApp++;
  1765. lpDest = (LPSTR)chBuff;
  1766. // filter out all Int 21 Function 50 calls
  1767. if (HIBYTE(wAX) != 0x50) {
  1768. wsprintf( lpDest,
  1769. (LPSTR)"%02X|APICALL: Int21h %x", nLogIndent,
  1770. HIBYTE(wAX));
  1771. WriteBuff( lpDest );
  1772. nLineLen += 3;
  1773. }
  1774. memset (szPathName, '\0', MAX_PATH_NAME_LEN);
  1775. switch (HIBYTE(wAX)) {
  1776. case 0x0E: // Select Disk
  1777. case 0x1C: // Get Drive Data
  1778. case 0x36: // Get Disk free Space
  1779. wsprintf( lpDest, (LPSTR)"%x ", LOBYTE(wDX));
  1780. WriteBuff( (LPSTR)lpDest ) ;
  1781. break;
  1782. // FCB based File operations
  1783. /* case 0x0F: // OpenFile with FCB
  1784. case 0x10: // CloseFile with FCB
  1785. case 0x11: // Find First File
  1786. case 0x12: // Find Next File
  1787. case 0x13: // Delete File
  1788. case 0x14: // Sequential Read
  1789. case 0x15: // Sequential Write
  1790. case 0x16: // Create File with FCB
  1791. case 0x21: // Random Read with FCB
  1792. case 0x22: // Random Write with FCB
  1793. case 0x23: // Get File Size with FCB
  1794. case 0x24: // Set Relative Record with FCB
  1795. case 0x27: // Random Block Read with FCB
  1796. case 0x28: // Random Block Write with FCB
  1797. // make a long pointer out if DS:DX for the FCB.
  1798. pmyFCB = MAKELP (wDS, wDX);
  1799. // make strings out of the FileName & Extension
  1800. while (iCount < 8) {
  1801. szFileName[iCount] = pmyFCB->FileName[iCount++];
  1802. }
  1803. szFileName[iCount] = '\0';
  1804. iCount = 0;
  1805. while (iCount < 3) {
  1806. szExtension[iCount] = pmyFCB->Extension[iCount++];
  1807. }
  1808. szExtension[iCount] = '\0';
  1809. wsprintf (lpDest, "GARBAGE");
  1810. WriteBuff((LPSTR)lpDest);
  1811. wsprintf (lpDest, "%x %d %s %s %d %d %l %d %d %d %l ",
  1812. pmyFCB->Attrib, pmyFCB->DriveID,
  1813. szFileName, szExtension,
  1814. pmyFCB->CurrentBlock, pmyFCB->RecordSize,
  1815. pmyFCB->FileSize, pmyFCB->Date,
  1816. pmyFCB->Time, pmyFCB->CurrentRecord,
  1817. pmyFCB->RelativeRecord);
  1818. // write 'em all out.
  1819. WriteBuff( (LPSTR)lpDest ) ;
  1820. // if Block I/O, dump # records
  1821. if ((wAX == 0x27) || (wAX == 0x28)) {
  1822. wsprintf (lpDest, "%x ", wCX);
  1823. WriteBuff ((LPSTR) lpDest);
  1824. }
  1825. break;
  1826. case 0x17: // Rename File with FCB
  1827. // uses a special FCB
  1828. pfn17FCB = MAKELP (wDS, wDX);
  1829. iCount = 0;
  1830. // make strings out of the FileNames & Extensions
  1831. while (iCount < 8) {
  1832. szFileName[iCount] =
  1833. pfn17FCB->OldFileName[iCount];
  1834. szNewFileName[iCount] =
  1835. pfn17FCB->OldFileName[iCount++];
  1836. }
  1837. szFileName[iCount] = '\0';
  1838. szNewFileName[iCount] = '\0';
  1839. iCount = 0;
  1840. while (iCount < 3) {
  1841. szExtension[iCount] =
  1842. pfn17FCB->OldExtension[iCount];
  1843. szNewExtension[iCount] =
  1844. pfn17FCB->NewExtension[iCount++];
  1845. }
  1846. szExtension[iCount] = '\0';
  1847. szNewExtension[iCount] = '\0';
  1848. wsprintf (lpDest, "%d %s %s %s %s ",
  1849. pfn17FCB->DriveID,
  1850. szFileName, szExtension,
  1851. szNewFileName, szNewExtension);
  1852. // write 'em all out.
  1853. WriteBuff( (LPSTR)lpDest ) ;
  1854. break;
  1855. */
  1856. case 0x1A: // Set DTA Address
  1857. wsprintf( lpDest, (LPSTR)"%x:%x ", wDS, wDX);
  1858. WriteBuff( (LPSTR)lpDest ) ;
  1859. break;
  1860. case 0x3C: // Create File with Handle
  1861. case 0x3D: // Open File with Handle
  1862. case 0x41: // Delete File
  1863. case 0x4E: // Find First File
  1864. case 0x5B: // Create New File
  1865. // get the attribute for Create File/FindFirst/
  1866. // Create New File
  1867. if ((HIBYTE (wAX) == 0x3C) || (HIBYTE (wAX) == 0x4E)
  1868. ||(HIBYTE (wAX) == 0x5B) ) {
  1869. wsprintf( lpDest, (LPSTR)"%x ", wCX);
  1870. WriteBuff( (LPSTR)lpDest ) ;
  1871. }
  1872. // get the access code if Open File call
  1873. else if (HIBYTE (wAX) == 0x3D) {
  1874. wsprintf( lpDest, (LPSTR)"%x ", LOBYTE(wAX));
  1875. WriteBuff( (LPSTR)lpDest ) ;
  1876. }
  1877. // get the path name
  1878. pPathName = MAKELP (wDS, wDX);
  1879. iCount = 0;
  1880. while (*pPathName != '\0') {
  1881. szPathName[iCount++] = *pPathName;
  1882. pPathName++;
  1883. }
  1884. wsprintf (lpDest, "%s ", szPathName);
  1885. WriteBuff( (LPSTR) szPathName);
  1886. break;
  1887. case 0x3E: // Close File with Handle, BX contains handle
  1888. wsprintf (lpDest, "%x ", wBX);
  1889. WriteBuff( (LPSTR) lpDest);
  1890. break;
  1891. case 0x3F: // Read File thru' Handle
  1892. case 0x40: // Write File thru' Handle
  1893. // dump the handle and the # bytes read/written
  1894. wsprintf (lpDest, "%x %x ", wBX, wCX);
  1895. WriteBuff( (LPSTR) lpDest);
  1896. break;
  1897. case 0x42: // move file pointer
  1898. wsprintf (lpDest, "%x %x %x %x ", LOBYTE(wAX),
  1899. wBX, wCX, wDX);
  1900. WriteBuff( (LPSTR) lpDest);
  1901. break;
  1902. case 0x43: // Get/Set File Attributes
  1903. wsprintf (lpDest, "%x ", LOBYTE (wAX));
  1904. WriteBuff( (LPSTR) lpDest);
  1905. // get attributes to set
  1906. if (LOBYTE(wAX) == 0) {
  1907. wsprintf (lpDest, "%x ", wCX);
  1908. WriteBuff( (LPSTR) lpDest);
  1909. }
  1910. // get the path name
  1911. pPathName = MAKELP (wDS, wDX);
  1912. iCount = 0;
  1913. while (*pPathName != '\0') {
  1914. szPathName[iCount++] = *pPathName;
  1915. pPathName++;
  1916. }
  1917. wsprintf (lpDest, "%s ", szPathName);
  1918. WriteBuff( (LPSTR) szPathName);
  1919. break;
  1920. case 0x45: // duplicate file handle
  1921. case 0x46: // force duplicate file handle
  1922. wsprintf (lpDest, "%x ", wBX);
  1923. WriteBuff( (LPSTR) lpDest);
  1924. if (HIBYTE(wAX) == 0x46) {
  1925. wsprintf (lpDest, "%x ", wCX);
  1926. WriteBuff( (LPSTR) lpDest);
  1927. }
  1928. break;
  1929. case 0x44: // IOCTL calls. Just record the
  1930. // sub-function
  1931. wsprintf (lpDest, "%x ", LOBYTE(wAX));
  1932. WriteBuff( (LPSTR) lpDest);
  1933. break;
  1934. default:
  1935. break;
  1936. } // end of switch (HIBYTE(wAX))
  1937. // at the time of returning, AX may not contain
  1938. // the name of the Int21 Function. So, in the
  1939. // routine where we log output params, in order to
  1940. // know the Function, we need to save it in a global.
  1941. Int21Function = HIBYTE(wAX);
  1942. // you don't want to End line for Function 50 calls.
  1943. if (Int21Function != 0x50)
  1944. EndLineBuff();
  1945. fTimeInt21 = TRUE;
  1946. *lpOrig = GetSetKernelDOSProc ((DWORD) _Int21_Handler);
  1947. }
  1948. }
  1949. ++ nLogIndent; // let us bump up the log level. We need only odd
  1950. // level Int21s. These will be those called by the
  1951. // application.
  1952. // add up all the Int21 calls made (app or otherwise)
  1953. ++cAllInt21Calls;
  1954. if( ACCESS(fTiming) && ACCESS(fElapsedTimes) )
  1955. {
  1956. // Time all Int21s
  1957. TimerOpen ((short far *)&TimerHandle[nLogIndent-1], MICROSECONDS);
  1958. TimerInit (TimerHandle[nLogIndent-1]);
  1959. }
  1960. return;
  1961. }
  1962. void _loadds LogOut21Calls (
  1963. WORD wFlags, WORD wDS, WORD wES,
  1964. WORD wSI, WORD wDI,
  1965. WORD wDX, WORD wCX, WORD wBX, WORD wAX,
  1966. WORD wIP, WORD wCS
  1967. ) {
  1968. --nLogIndent;
  1969. // Time int21s if it is the right call.
  1970. if (fTimeInt21) {
  1971. if( fTiming )
  1972. {
  1973. ulElapsedTime = TimerRead (TimerHandle[nLogIndent]);
  1974. if( ACCESS(fElapsedTimes) )
  1975. {
  1976. TimerClose (TimerHandle[nLogIndent]);
  1977. }
  1978. }
  1979. // set the int21 handler to be handled by the original handler.
  1980. // more disk writing to do. I don't want this to go into
  1981. // an infinite loop.
  1982. GetSetKernelDOSProc ((DWORD)OrigHandler);
  1983. // discard Int21 Function 50 calls
  1984. if (Int21Function != 0x50) {
  1985. lpDest = (LPSTR)&chBuff[0];
  1986. wsprintf( lpDest, (LPSTR)"%02X|APIRET:Int21h ", nLogIndent );
  1987. WriteBuff( lpDest );
  1988. nLineLen += 3;
  1989. wsprintf( lpDest, (LPSTR)"%x %x ", wFlags, wAX);
  1990. WriteBuff( (LPSTR)lpDest ) ;
  1991. }
  1992. switch (Int21Function) {
  1993. /* case 0x1B: // get default drive data
  1994. case 0x1C: // get drive data
  1995. // FCB based File operations
  1996. case 0x0F: // OpenFile with FCB
  1997. case 0x10: // CloseFile with FCB
  1998. case 0x11: // Find First File
  1999. case 0x12: // Find Next File
  2000. case 0x13: // Delete File
  2001. case 0x14: // Sequential Read
  2002. case 0x15: // Sequential Write
  2003. case 0x16: // Create File with FCB
  2004. case 0x21: // Random Read with FCB
  2005. case 0x22: // Random Write with FCB
  2006. case 0x23: // Get File Size with FCB
  2007. case 0x24: // Set Relative Record with FCB
  2008. case 0x27: // Random Block Read with FCB
  2009. case 0x28: // Random Block Write with FCB
  2010. // print out the return value.
  2011. wsprintf( lpDest, (LPSTR)"%x ", LOBYTE(wAX));
  2012. WriteBuff( (LPSTR)lpDest ) ;
  2013. pmyFCB = MAKELP (wDS, wDX);
  2014. wsprintf (lpDest, "%x %d %s %s %d %d %l %d %d %d %l ",
  2015. pmyFCB->Attrib, pmyFCB->DriveID,
  2016. szFileName, szExtension,
  2017. pmyFCB->CurrentBlock, pmyFCB->RecordSize,
  2018. pmyFCB->FileSize, pmyFCB->Date,
  2019. pmyFCB->Time, pmyFCB->CurrentRecord,
  2020. pmyFCB->RelativeRecord);
  2021. WriteBuff( (LPSTR)lpDest ) ;
  2022. break;
  2023. case 0x17: // Rename File with FCB
  2024. // print out the return value.
  2025. wsprintf( lpDest, (LPSTR)"%x", LOBYTE(wAX));
  2026. WriteBuff( (LPSTR)lpDest ) ;
  2027. // uses a special FCB
  2028. pfn17FCB = MAKELP (wDS, wDX);
  2029. iCount = 0;
  2030. // make strings out of the FileNames & Extensions
  2031. while (iCount < 8) {
  2032. szFileName[iCount] =
  2033. pfn17FCB->OldFileName[iCount];
  2034. szNewFileName[iCount] =
  2035. pfn17FCB->OldFileName[iCount++];
  2036. }
  2037. szFileName[iCount] = '\0';
  2038. szNewFileName[iCount] = '\0';
  2039. iCount = 0;
  2040. while (iCount < 3) {
  2041. szExtension[iCount] =
  2042. pfn17FCB->OldExtension[iCount];
  2043. szNewExtension[iCount] =
  2044. pfn17FCB->NewExtension[iCount++];
  2045. }
  2046. szExtension[iCount] = '\0';
  2047. szNewExtension[iCount] = '\0';
  2048. wsprintf (lpDest, "%d %s %s %s %s",
  2049. pfn17FCB->DriveID,
  2050. szFileName, szExtension,
  2051. szNewFileName, szNewExtension);
  2052. // write 'em all out.
  2053. WriteBuff( (LPSTR)lpDest ) ;
  2054. break;
  2055. */
  2056. case 0x36: // Get Disk Free Space
  2057. wsprintf (lpDest, "%x %x %x %x ", wAX, wBX, wCX, wDX);
  2058. WriteBuff( (LPSTR) lpDest);
  2059. break;
  2060. case 0x3C: // Create File with Handle
  2061. case 0x3D: // Open File with Handle
  2062. case 0x3E: // Close File with Handle
  2063. case 0x3F: // Read File thru' Handle
  2064. case 0x40: // Write File thru' Handle
  2065. case 0x41: // Delete File
  2066. case 0x4E: // Find First File
  2067. case 0x5B: // Create New File
  2068. break;
  2069. case 0x42: // move file pointer
  2070. wsprintf (lpDest, "%x ", wDX);
  2071. WriteBuff( (LPSTR) lpDest);
  2072. break;
  2073. case 0x43: // Get / Set File Attributes
  2074. wsprintf (lpDest, "%x ", wCX);
  2075. WriteBuff( (LPSTR) lpDest);
  2076. break;
  2077. default:
  2078. break;
  2079. } // end of switch (HIBYTE(wAX))
  2080. if (Int21Function != 0x50)
  2081. EndLineBuff();
  2082. if( fTiming )
  2083. {
  2084. if (Int21Function != 0x50) {
  2085. lpDest = (LPSTR)&chBuff[0];
  2086. wsprintf( lpDest, (LPSTR)"%02X|APITIME:Int21h ", nLogIndent );
  2087. WriteBuff( lpDest );
  2088. wsprintf( lpDest, (LPSTR)"%lu ", ulElapsedTime);
  2089. WriteBuff( (LPSTR)lpDest ) ;
  2090. EndLineBuff();
  2091. }
  2092. }
  2093. fTimeInt21 = FALSE;
  2094. // set it back to our Int21 handler
  2095. *lpOrig = GetSetKernelDOSProc ((DWORD) _Int21_Handler);
  2096. }
  2097. }
  2098. #pragma pack() // default packing
  2099. #else // Dummy for conditional compiles without -DINT21H
  2100. #if !defined(WIN32)
  2101. void _loadds LogInt21Calls (
  2102. WORD wFlags, WORD wBP, WORD wSS,
  2103. WORD wES, WORD wDS, WORD wSI, WORD wDI,
  2104. WORD wDX, WORD wCX, WORD wBX,
  2105. WORD wAX, WORD Dummy1, WORD Dummy2,
  2106. WORD Dummy3, WORD Dummy4, WORD wIP, WORD wCS
  2107. ) {
  2108. }
  2109. void _loadds LogOut21Calls (
  2110. WORD wFlags, WORD wDS, WORD wES,
  2111. WORD wSI, WORD wDI,
  2112. WORD wDX, WORD wCX, WORD wBX, WORD wAX,
  2113. WORD wIP, WORD wCS
  2114. ) {
  2115. }
  2116. #endif
  2117. #endif