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.

1803 lines
46 KiB

  1. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. debug.cpp
  5. Abstract:
  6. Debug logging routines for W3spoof project.
  7. Author:
  8. Paul M Midgen (pmidge) 15-May-2000
  9. Revision History:
  10. 15-May-2000 pmidge
  11. Created
  12. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  13. #include "common.h"
  14. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  15. MapIIDToString()
  16. WHAT : maps an IID to its string id. if the IID is unknown we
  17. emit a '?'.
  18. ARGS : hr - the IID code to map
  19. RETURNS : pointer to the IID's string name
  20. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  21. LPSTR
  22. MapIIDToString(REFIID riid)
  23. {
  24. //
  25. // standard IIDs
  26. //
  27. CASE_IID(riid, IID_NULL);
  28. CASE_IID(riid, IID_IUnknown);
  29. CASE_IID(riid, IID_IClassFactory);
  30. CASE_IID(riid, IID_IDispatch);
  31. CASE_IID(riid, IID_IConnectionPointContainer);
  32. CASE_IID(riid, IID_IConnectionPoint);
  33. CASE_IID(riid, IID_IMarshal);
  34. CASE_IID(riid, IID_IStdMarshalInfo);
  35. CASE_IID(riid, IID_IExternalConnection);
  36. CASE_IID(riid, IID_IObjectWithSite);
  37. CASE_IID(riid, IID_IActiveScriptSite);
  38. CASE_IID(riid, IID_IProvideClassInfo);
  39. CASE_IID(riid, IID_IActiveScriptSiteInterruptPoll);
  40. CASE_IID(riid, IID_IActiveScriptSiteDebug);
  41. // CASE_IID(riid, IID_ICanHandleException); // dispex.h?
  42. // CASE_IID(riid, IID_IDispatchEx); // dispex.h?
  43. CASE_IID(riid, IID_IServiceProvider);
  44. //
  45. // app-defined IIDs
  46. //
  47. CASE_IID(riid, IID_IConfig);
  48. CASE_IID(riid, IID_IThreadPool);
  49. CASE_IID(riid, IID_IW3Spoof);
  50. CASE_IID(riid, IID_IW3SpoofClientSupport);
  51. CASE_IID(riid, IID_IW3SpoofEvents);
  52. CASE_IID(riid, IID_ISession);
  53. CASE_IID(riid, IID_ISocket);
  54. CASE_IID(riid, IID_IHeaders);
  55. CASE_IID(riid, IID_IEntity);
  56. CASE_IID(riid, IID_IUrl);
  57. CASE_IID(riid, IID_IRequest);
  58. CASE_IID(riid, IID_IResponse);
  59. CASE_IID(riid, IID_IW3SpoofRuntime);
  60. CASE_IID(riid, IID_IW3SpoofPropertyBag);
  61. CASE_IID(riid, IID_IW3SpoofFile);
  62. return "?";
  63. }
  64. LPSTR
  65. MapIOTYPEToString(IOTYPE iot)
  66. {
  67. switch(iot)
  68. {
  69. CASE_OF(IOCT_CONNECT);
  70. CASE_OF(IOCT_RECV);
  71. CASE_OF(IOCT_SEND);
  72. CASE_OF(IOCT_DUMMY);
  73. default : return "?";
  74. }
  75. }
  76. LPSTR
  77. MapScriptDispidToString(SCRIPTDISPID sd)
  78. {
  79. switch(sd)
  80. {
  81. CASE_OF(Global);
  82. CASE_OF(OnConnect);
  83. CASE_OF(OnDataAvailable);
  84. CASE_OF(OnRequest);
  85. CASE_OF(OnResponse);
  86. CASE_OF(OnClose);
  87. default : return "?";
  88. }
  89. }
  90. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  91. MapHResultToString()
  92. WHAT : maps an HRESULT to its string id. if the HRESULT is unknown we
  93. emit a '?'.
  94. ARGS : hr - the HRESULT code to map
  95. RETURNS : pointer to the HRESULT's string name
  96. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  97. LPSTR
  98. MapHResultToString(HRESULT hr)
  99. {
  100. switch(hr)
  101. {
  102. CASE_OF(S_OK);
  103. CASE_OF(E_NOINTERFACE);
  104. CASE_OF(E_POINTER);
  105. CASE_OF(E_UNEXPECTED);
  106. CASE_OF(E_INVALIDARG);
  107. CASE_OF(E_OUTOFMEMORY);
  108. CASE_OF(E_FAIL);
  109. CASE_OF(E_NOTIMPL);
  110. CASE_OF(E_PENDING);
  111. CASE_OF(E_ACCESSDENIED);
  112. CASE_OF(CLASS_E_NOAGGREGATION);
  113. CASE_OF(TYPE_E_IOERROR);
  114. CASE_OF(TYPE_E_REGISTRYACCESS);
  115. CASE_OF(TYPE_E_INVALIDSTATE);
  116. CASE_OF(TYPE_E_BUFFERTOOSMALL);
  117. CASE_OF(TYPE_E_FIELDNOTFOUND);
  118. CASE_OF(TYPE_E_ELEMENTNOTFOUND);
  119. CASE_OF(TYPE_E_AMBIGUOUSNAME);
  120. CASE_OF(TYPE_E_UNKNOWNLCID);
  121. CASE_OF(TYPE_E_BADMODULEKIND);
  122. CASE_OF(TYPE_E_CANTLOADLIBRARY);
  123. CASE_OF(TYPE_E_INCONSISTENTPROPFUNCS);
  124. CASE_OF(CONNECT_E_NOCONNECTION);
  125. CASE_OF(CONNECT_E_ADVISELIMIT);
  126. CASE_OF(CO_E_OBJNOTREG);
  127. CASE_OF(DISP_E_BADPARAMCOUNT);
  128. CASE_OF(DISP_E_BADVARTYPE);
  129. CASE_OF(DISP_E_EXCEPTION);
  130. CASE_OF(DISP_E_MEMBERNOTFOUND);
  131. CASE_OF(DISP_E_NONAMEDARGS);
  132. CASE_OF(DISP_E_OVERFLOW);
  133. CASE_OF(DISP_E_PARAMNOTFOUND);
  134. CASE_OF(DISP_E_TYPEMISMATCH);
  135. CASE_OF(DISP_E_UNKNOWNINTERFACE);
  136. CASE_OF(DISP_E_UNKNOWNLCID);
  137. CASE_OF(DISP_E_PARAMNOTOPTIONAL);
  138. CASE_OF(DISP_E_UNKNOWNNAME);
  139. default : return "?";
  140. }
  141. }
  142. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  143. MapStateToString()
  144. WHAT : maps a STATE value to a string. if the state is unknown we
  145. emit a '?'.
  146. ARGS : st - the STATE to map
  147. RETURNS : pointer to the STATE's string name
  148. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  149. LPSTR
  150. MapStateToString(STATE st)
  151. {
  152. switch(st)
  153. {
  154. CASE_OF(ST_CREATED);
  155. CASE_OF(ST_OPENING);
  156. CASE_OF(ST_OPEN);
  157. CASE_OF(ST_CLOSING);
  158. CASE_OF(ST_CLOSED);
  159. CASE_OF(ST_ERROR);
  160. default : return "?";
  161. }
  162. }
  163. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  164. MapIoStateToString()
  165. WHAT : maps a SERVERSTATE value to a string. if the state is unknown we
  166. emit a '?'.
  167. ARGS : st - the SERVERSTATE to map
  168. RETURNS : pointer to the SERVERSTATE's string name
  169. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  170. LPSTR
  171. MapStateToString(SERVERSTATE st)
  172. {
  173. switch(st)
  174. {
  175. CASE_OF(SS_START_STATE);
  176. CASE_OF(SS_SOCKET_CONNECTED);
  177. CASE_OF(SS_REQUEST_PENDING);
  178. CASE_OF(SS_REQUEST_COMPLETE);
  179. CASE_OF(SS_RESPONSE_PENDING);
  180. CASE_OF(SS_RESPONSE_COMPLETE);
  181. CASE_OF(SS_SOCKET_DISCONNECTED);
  182. default : return "?";
  183. }
  184. }
  185. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  186. MapStateToString()
  187. WHAT : maps a script engine state to a string for the log file.
  188. ARGS : st - the state
  189. RETURNS : string representation of the state
  190. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  191. LPSTR
  192. MapStateToString(SCRIPTSTATE st)
  193. {
  194. switch(st)
  195. {
  196. CASE_OF(SCRIPTSTATE_UNINITIALIZED);
  197. CASE_OF(SCRIPTSTATE_INITIALIZED);
  198. CASE_OF(SCRIPTSTATE_STARTED);
  199. CASE_OF(SCRIPTSTATE_CONNECTED);
  200. CASE_OF(SCRIPTSTATE_DISCONNECTED);
  201. CASE_OF(SCRIPTSTATE_CLOSED);
  202. default : return "?";
  203. }
  204. }
  205. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  206. MapTPOToString()
  207. WHAT : maps a TPO_* (thread pool option) value to a string. if the option
  208. is unknown we emit a '?'.
  209. ARGS : option - the option to map
  210. RETURNS : pointer to the options's string name
  211. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  212. LPSTR
  213. MapTPOToString(DWORD option)
  214. {
  215. switch(option)
  216. {
  217. CASE_OF(TPO_MAX_POOL_THREADS);
  218. CASE_OF(TPO_MAX_ACTIVE_THREADS);
  219. CASE_OF(TPO_SERVER_LISTEN_PORT);
  220. default : return "?";
  221. }
  222. }
  223. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  224. MapErrorToString()
  225. WHAT : maps an error code to its string id. if the error is unknown we
  226. emit a '?'.
  227. ARGS : error - the error code to map
  228. RETURNS : pointer to the error code's string name
  229. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  230. LPSTR
  231. MapErrorToString(int error)
  232. {
  233. switch(error)
  234. {
  235. CASE_OF(ERROR_SUCCESS);
  236. CASE_OF(ERROR_INVALID_FUNCTION);
  237. CASE_OF(ERROR_FILE_NOT_FOUND);
  238. CASE_OF(ERROR_PATH_NOT_FOUND);
  239. CASE_OF(ERROR_TOO_MANY_OPEN_FILES);
  240. CASE_OF(ERROR_ACCESS_DENIED);
  241. CASE_OF(ERROR_INVALID_HANDLE);
  242. CASE_OF(ERROR_ARENA_TRASHED);
  243. CASE_OF(ERROR_NOT_ENOUGH_MEMORY);
  244. CASE_OF(ERROR_INVALID_BLOCK);
  245. CASE_OF(ERROR_BAD_ENVIRONMENT);
  246. CASE_OF(ERROR_BAD_FORMAT);
  247. CASE_OF(ERROR_INVALID_ACCESS);
  248. CASE_OF(ERROR_INVALID_DATA);
  249. CASE_OF(ERROR_OUTOFMEMORY);
  250. CASE_OF(ERROR_INVALID_DRIVE);
  251. CASE_OF(ERROR_CURRENT_DIRECTORY);
  252. CASE_OF(ERROR_NOT_SAME_DEVICE);
  253. CASE_OF(ERROR_NO_MORE_FILES);
  254. CASE_OF(ERROR_WRITE_PROTECT);
  255. CASE_OF(ERROR_BAD_UNIT);
  256. CASE_OF(ERROR_NOT_READY);
  257. CASE_OF(ERROR_BAD_COMMAND);
  258. CASE_OF(ERROR_CRC);
  259. CASE_OF(ERROR_BAD_LENGTH);
  260. CASE_OF(ERROR_SEEK);
  261. CASE_OF(ERROR_NOT_DOS_DISK);
  262. CASE_OF(ERROR_SECTOR_NOT_FOUND);
  263. CASE_OF(ERROR_OUT_OF_PAPER);
  264. CASE_OF(ERROR_WRITE_FAULT);
  265. CASE_OF(ERROR_READ_FAULT);
  266. CASE_OF(ERROR_GEN_FAILURE);
  267. CASE_OF(ERROR_SHARING_VIOLATION);
  268. CASE_OF(ERROR_LOCK_VIOLATION);
  269. CASE_OF(ERROR_WRONG_DISK);
  270. CASE_OF(ERROR_SHARING_BUFFER_EXCEEDED);
  271. CASE_OF(ERROR_HANDLE_EOF);
  272. CASE_OF(ERROR_HANDLE_DISK_FULL);
  273. CASE_OF(ERROR_NOT_SUPPORTED);
  274. CASE_OF(ERROR_REM_NOT_LIST);
  275. CASE_OF(ERROR_DUP_NAME);
  276. CASE_OF(ERROR_BAD_NETPATH);
  277. CASE_OF(ERROR_NETWORK_BUSY);
  278. CASE_OF(ERROR_DEV_NOT_EXIST);
  279. CASE_OF(ERROR_TOO_MANY_CMDS);
  280. CASE_OF(ERROR_ADAP_HDW_ERR);
  281. CASE_OF(ERROR_BAD_NET_RESP);
  282. CASE_OF(ERROR_UNEXP_NET_ERR);
  283. CASE_OF(ERROR_BAD_REM_ADAP);
  284. CASE_OF(ERROR_PRINTQ_FULL);
  285. CASE_OF(ERROR_NO_SPOOL_SPACE);
  286. CASE_OF(ERROR_PRINT_CANCELLED);
  287. CASE_OF(ERROR_NETNAME_DELETED);
  288. CASE_OF(ERROR_NETWORK_ACCESS_DENIED);
  289. CASE_OF(ERROR_BAD_DEV_TYPE);
  290. CASE_OF(ERROR_BAD_NET_NAME);
  291. CASE_OF(ERROR_TOO_MANY_NAMES);
  292. CASE_OF(ERROR_TOO_MANY_SESS);
  293. CASE_OF(ERROR_SHARING_PAUSED);
  294. CASE_OF(ERROR_REQ_NOT_ACCEP);
  295. CASE_OF(ERROR_REDIR_PAUSED);
  296. CASE_OF(ERROR_FILE_EXISTS);
  297. CASE_OF(ERROR_CANNOT_MAKE);
  298. CASE_OF(ERROR_FAIL_I24);
  299. CASE_OF(ERROR_OUT_OF_STRUCTURES);
  300. CASE_OF(ERROR_ALREADY_ASSIGNED);
  301. CASE_OF(ERROR_INVALID_PASSWORD);
  302. CASE_OF(ERROR_INVALID_PARAMETER);
  303. CASE_OF(ERROR_NET_WRITE_FAULT);
  304. CASE_OF(ERROR_NO_PROC_SLOTS);
  305. CASE_OF(ERROR_TOO_MANY_SEMAPHORES);
  306. CASE_OF(ERROR_EXCL_SEM_ALREADY_OWNED);
  307. CASE_OF(ERROR_SEM_IS_SET);
  308. CASE_OF(ERROR_TOO_MANY_SEM_REQUESTS);
  309. CASE_OF(ERROR_INVALID_AT_INTERRUPT_TIME);
  310. CASE_OF(ERROR_SEM_OWNER_DIED);
  311. CASE_OF(ERROR_SEM_USER_LIMIT);
  312. CASE_OF(ERROR_DISK_CHANGE);
  313. CASE_OF(ERROR_DRIVE_LOCKED);
  314. CASE_OF(ERROR_BROKEN_PIPE);
  315. CASE_OF(ERROR_OPEN_FAILED);
  316. CASE_OF(ERROR_BUFFER_OVERFLOW);
  317. CASE_OF(ERROR_DISK_FULL);
  318. CASE_OF(ERROR_NO_MORE_SEARCH_HANDLES);
  319. CASE_OF(ERROR_INVALID_TARGET_HANDLE);
  320. CASE_OF(ERROR_INVALID_CATEGORY);
  321. CASE_OF(ERROR_INVALID_VERIFY_SWITCH);
  322. CASE_OF(ERROR_BAD_DRIVER_LEVEL);
  323. CASE_OF(ERROR_CALL_NOT_IMPLEMENTED);
  324. CASE_OF(ERROR_SEM_TIMEOUT);
  325. CASE_OF(ERROR_INSUFFICIENT_BUFFER);
  326. CASE_OF(ERROR_INVALID_NAME);
  327. CASE_OF(ERROR_INVALID_LEVEL);
  328. CASE_OF(ERROR_NO_VOLUME_LABEL);
  329. CASE_OF(ERROR_MOD_NOT_FOUND);
  330. CASE_OF(ERROR_PROC_NOT_FOUND);
  331. CASE_OF(ERROR_WAIT_NO_CHILDREN);
  332. CASE_OF(ERROR_CHILD_NOT_COMPLETE);
  333. CASE_OF(ERROR_DIRECT_ACCESS_HANDLE);
  334. CASE_OF(ERROR_NEGATIVE_SEEK);
  335. CASE_OF(ERROR_SEEK_ON_DEVICE);
  336. CASE_OF(ERROR_DIR_NOT_ROOT);
  337. CASE_OF(ERROR_DIR_NOT_EMPTY);
  338. CASE_OF(ERROR_PATH_BUSY);
  339. CASE_OF(ERROR_SYSTEM_TRACE);
  340. CASE_OF(ERROR_INVALID_EVENT_COUNT);
  341. CASE_OF(ERROR_TOO_MANY_MUXWAITERS);
  342. CASE_OF(ERROR_INVALID_LIST_FORMAT);
  343. CASE_OF(ERROR_BAD_ARGUMENTS);
  344. CASE_OF(ERROR_BAD_PATHNAME);
  345. CASE_OF(ERROR_BUSY);
  346. CASE_OF(ERROR_CANCEL_VIOLATION);
  347. CASE_OF(ERROR_ALREADY_EXISTS);
  348. CASE_OF(ERROR_FILENAME_EXCED_RANGE);
  349. CASE_OF(ERROR_LOCKED);
  350. CASE_OF(ERROR_NESTING_NOT_ALLOWED);
  351. CASE_OF(ERROR_BAD_PIPE);
  352. CASE_OF(ERROR_PIPE_BUSY);
  353. CASE_OF(ERROR_NO_DATA);
  354. CASE_OF(ERROR_PIPE_NOT_CONNECTED);
  355. CASE_OF(ERROR_MORE_DATA);
  356. CASE_OF(ERROR_NO_MORE_ITEMS);
  357. CASE_OF(ERROR_NOT_OWNER);
  358. CASE_OF(ERROR_PARTIAL_COPY);
  359. CASE_OF(ERROR_MR_MID_NOT_FOUND);
  360. CASE_OF(ERROR_INVALID_ADDRESS);
  361. CASE_OF(ERROR_PIPE_CONNECTED);
  362. CASE_OF(ERROR_PIPE_LISTENING);
  363. CASE_OF(ERROR_OPERATION_ABORTED);
  364. CASE_OF(ERROR_IO_INCOMPLETE);
  365. CASE_OF(ERROR_IO_PENDING);
  366. CASE_OF(ERROR_NOACCESS);
  367. CASE_OF(ERROR_STACK_OVERFLOW);
  368. CASE_OF(ERROR_INVALID_FLAGS);
  369. CASE_OF(ERROR_NO_TOKEN);
  370. CASE_OF(ERROR_BADDB);
  371. CASE_OF(ERROR_BADKEY);
  372. CASE_OF(ERROR_CANTOPEN);
  373. CASE_OF(ERROR_CANTREAD);
  374. CASE_OF(ERROR_CANTWRITE);
  375. CASE_OF(ERROR_REGISTRY_RECOVERED);
  376. CASE_OF(ERROR_REGISTRY_CORRUPT);
  377. CASE_OF(ERROR_REGISTRY_IO_FAILED);
  378. CASE_OF(ERROR_NOT_REGISTRY_FILE);
  379. CASE_OF(ERROR_KEY_DELETED);
  380. CASE_OF(ERROR_CIRCULAR_DEPENDENCY);
  381. CASE_OF(ERROR_SERVICE_NOT_ACTIVE);
  382. CASE_OF(ERROR_DLL_INIT_FAILED);
  383. CASE_OF(ERROR_CANCELLED);
  384. CASE_OF(ERROR_BAD_USERNAME);
  385. CASE_OF(ERROR_LOGON_FAILURE);
  386. CASE_OF(WAIT_FAILED);
  387. CASE_OF(WAIT_TIMEOUT);
  388. CASE_OF(WAIT_IO_COMPLETION);
  389. CASE_OF(RPC_S_INVALID_STRING_BINDING);
  390. CASE_OF(RPC_S_WRONG_KIND_OF_BINDING);
  391. CASE_OF(RPC_S_INVALID_BINDING);
  392. CASE_OF(RPC_S_PROTSEQ_NOT_SUPPORTED);
  393. CASE_OF(RPC_S_INVALID_RPC_PROTSEQ);
  394. CASE_OF(RPC_S_INVALID_STRING_UUID);
  395. CASE_OF(RPC_S_INVALID_ENDPOINT_FORMAT);
  396. CASE_OF(RPC_S_INVALID_NET_ADDR);
  397. CASE_OF(RPC_S_NO_ENDPOINT_FOUND);
  398. CASE_OF(RPC_S_INVALID_TIMEOUT);
  399. CASE_OF(RPC_S_OBJECT_NOT_FOUND);
  400. CASE_OF(RPC_S_ALREADY_REGISTERED);
  401. CASE_OF(RPC_S_TYPE_ALREADY_REGISTERED);
  402. CASE_OF(RPC_S_ALREADY_LISTENING);
  403. CASE_OF(RPC_S_NO_PROTSEQS_REGISTERED);
  404. CASE_OF(RPC_S_NOT_LISTENING);
  405. CASE_OF(RPC_S_UNKNOWN_MGR_TYPE);
  406. CASE_OF(RPC_S_UNKNOWN_IF);
  407. CASE_OF(RPC_S_NO_BINDINGS);
  408. CASE_OF(RPC_S_NO_PROTSEQS);
  409. CASE_OF(RPC_S_CANT_CREATE_ENDPOINT);
  410. CASE_OF(RPC_S_OUT_OF_RESOURCES);
  411. CASE_OF(RPC_S_SERVER_UNAVAILABLE);
  412. CASE_OF(RPC_S_SERVER_TOO_BUSY);
  413. CASE_OF(RPC_S_INVALID_NETWORK_OPTIONS);
  414. CASE_OF(RPC_S_NO_CALL_ACTIVE);
  415. CASE_OF(RPC_S_CALL_FAILED);
  416. CASE_OF(RPC_S_CALL_FAILED_DNE);
  417. CASE_OF(RPC_S_PROTOCOL_ERROR);
  418. CASE_OF(RPC_S_UNSUPPORTED_TRANS_SYN);
  419. CASE_OF(RPC_S_UNSUPPORTED_TYPE);
  420. CASE_OF(RPC_S_INVALID_TAG);
  421. CASE_OF(RPC_S_INVALID_BOUND);
  422. CASE_OF(RPC_S_NO_ENTRY_NAME);
  423. CASE_OF(RPC_S_INVALID_NAME_SYNTAX);
  424. CASE_OF(RPC_S_UNSUPPORTED_NAME_SYNTAX);
  425. CASE_OF(RPC_S_UUID_NO_ADDRESS);
  426. CASE_OF(RPC_S_DUPLICATE_ENDPOINT);
  427. CASE_OF(RPC_S_UNKNOWN_AUTHN_TYPE);
  428. CASE_OF(RPC_S_MAX_CALLS_TOO_SMALL);
  429. CASE_OF(RPC_S_STRING_TOO_LONG);
  430. CASE_OF(RPC_S_PROTSEQ_NOT_FOUND);
  431. CASE_OF(RPC_S_PROCNUM_OUT_OF_RANGE);
  432. CASE_OF(RPC_S_BINDING_HAS_NO_AUTH);
  433. CASE_OF(RPC_S_UNKNOWN_AUTHN_SERVICE);
  434. CASE_OF(RPC_S_UNKNOWN_AUTHN_LEVEL);
  435. CASE_OF(RPC_S_INVALID_AUTH_IDENTITY);
  436. CASE_OF(RPC_S_UNKNOWN_AUTHZ_SERVICE);
  437. CASE_OF(EPT_S_INVALID_ENTRY);
  438. CASE_OF(EPT_S_CANT_PERFORM_OP);
  439. CASE_OF(EPT_S_NOT_REGISTERED);
  440. CASE_OF(RPC_S_NOTHING_TO_EXPORT);
  441. CASE_OF(RPC_S_INCOMPLETE_NAME);
  442. CASE_OF(RPC_S_INVALID_VERS_OPTION);
  443. CASE_OF(RPC_S_NO_MORE_MEMBERS);
  444. CASE_OF(RPC_S_NOT_ALL_OBJS_UNEXPORTED);
  445. CASE_OF(RPC_S_INTERFACE_NOT_FOUND);
  446. CASE_OF(RPC_S_ENTRY_ALREADY_EXISTS);
  447. CASE_OF(RPC_S_ENTRY_NOT_FOUND);
  448. CASE_OF(RPC_S_NAME_SERVICE_UNAVAILABLE);
  449. CASE_OF(RPC_S_INVALID_NAF_ID);
  450. CASE_OF(RPC_S_CANNOT_SUPPORT);
  451. CASE_OF(RPC_S_NO_CONTEXT_AVAILABLE);
  452. CASE_OF(RPC_S_INTERNAL_ERROR);
  453. CASE_OF(RPC_S_ZERO_DIVIDE);
  454. CASE_OF(RPC_S_ADDRESS_ERROR);
  455. CASE_OF(RPC_S_FP_DIV_ZERO);
  456. CASE_OF(RPC_S_FP_UNDERFLOW);
  457. CASE_OF(RPC_S_FP_OVERFLOW);
  458. CASE_OF(RPC_X_NO_MORE_ENTRIES);
  459. CASE_OF(RPC_X_SS_CHAR_TRANS_OPEN_FAIL);
  460. CASE_OF(RPC_X_SS_CHAR_TRANS_SHORT_FILE);
  461. CASE_OF(RPC_X_SS_IN_NULL_CONTEXT);
  462. CASE_OF(RPC_X_SS_CONTEXT_DAMAGED);
  463. CASE_OF(RPC_X_SS_HANDLES_MISMATCH);
  464. CASE_OF(RPC_X_SS_CANNOT_GET_CALL_HANDLE);
  465. CASE_OF(RPC_X_NULL_REF_POINTER);
  466. CASE_OF(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
  467. CASE_OF(RPC_X_BYTE_COUNT_TOO_SMALL);
  468. CASE_OF(RPC_X_BAD_STUB_DATA);
  469. CASE_OF(WSAEINTR);
  470. CASE_OF(WSAEBADF);
  471. CASE_OF(WSAEACCES);
  472. CASE_OF(WSAEFAULT);
  473. CASE_OF(WSAEINVAL);
  474. CASE_OF(WSAEMFILE);
  475. CASE_OF(WSAEWOULDBLOCK);
  476. CASE_OF(WSAEINPROGRESS);
  477. CASE_OF(WSAEALREADY);
  478. CASE_OF(WSAENOTSOCK);
  479. CASE_OF(WSAEDESTADDRREQ);
  480. CASE_OF(WSAEMSGSIZE);
  481. CASE_OF(WSAEPROTOTYPE);
  482. CASE_OF(WSAENOPROTOOPT);
  483. CASE_OF(WSAEPROTONOSUPPORT);
  484. CASE_OF(WSAESOCKTNOSUPPORT);
  485. CASE_OF(WSAEOPNOTSUPP);
  486. CASE_OF(WSAEPFNOSUPPORT);
  487. CASE_OF(WSAEAFNOSUPPORT);
  488. CASE_OF(WSAEADDRINUSE);
  489. CASE_OF(WSAEADDRNOTAVAIL);
  490. CASE_OF(WSAENETDOWN);
  491. CASE_OF(WSAENETUNREACH);
  492. CASE_OF(WSAENETRESET);
  493. CASE_OF(WSAECONNABORTED);
  494. CASE_OF(WSAECONNRESET);
  495. CASE_OF(WSAENOBUFS);
  496. CASE_OF(WSAEISCONN);
  497. CASE_OF(WSAENOTCONN);
  498. CASE_OF(WSAESHUTDOWN);
  499. CASE_OF(WSAETOOMANYREFS);
  500. CASE_OF(WSAETIMEDOUT);
  501. CASE_OF(WSAECONNREFUSED);
  502. CASE_OF(WSAELOOP);
  503. CASE_OF(WSAENAMETOOLONG);
  504. CASE_OF(WSAEHOSTDOWN);
  505. CASE_OF(WSAEHOSTUNREACH);
  506. CASE_OF(WSAENOTEMPTY);
  507. CASE_OF(WSAEPROCLIM);
  508. CASE_OF(WSAEUSERS);
  509. CASE_OF(WSAEDQUOT);
  510. CASE_OF(WSAESTALE);
  511. CASE_OF(WSAEREMOTE);
  512. CASE_OF(WSAEDISCON);
  513. CASE_OF(WSASYSNOTREADY);
  514. CASE_OF(WSAVERNOTSUPPORTED);
  515. CASE_OF(WSANOTINITIALISED);
  516. CASE_OF(WSAHOST_NOT_FOUND);
  517. CASE_OF(WSATRY_AGAIN);
  518. CASE_OF(WSANO_RECOVERY);
  519. CASE_OF(WSANO_DATA);
  520. CASE_OF(ERROR_FAILURE);
  521. CASE_OF(ERROR_INVALID_STATE);
  522. default : return "?";
  523. }
  524. }
  525. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  526. MapDispidToString()
  527. WHAT : maps a dispid to a string for the log file.
  528. ARGS : dispid - the dispid
  529. RETURNS : string representation of the dispid
  530. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  531. LPSTR
  532. MapDispidToString(DISPID dispid)
  533. {
  534. switch(dispid)
  535. {
  536. // special dispids
  537. CASE_OF(DISPID_VALUE);
  538. CASE_OF(DISPID_NEWENUM);
  539. CASE_OF(DISPID_EVALUATE);
  540. CASE_OF(DISPID_PROPERTYPUT);
  541. CASE_OF(DISPID_CONSTRUCTOR);
  542. CASE_OF(DISPID_DESTRUCTOR);
  543. CASE_OF(DISPID_UNKNOWN);
  544. CASE_OF(DISPID_COLLECT);
  545. // internal OM dispids
  546. CASE_OF(DISPID_SESSION_SOCKET);
  547. CASE_OF(DISPID_SESSION_REQUEST);
  548. CASE_OF(DISPID_SESSION_RESPONSE);
  549. CASE_OF(DISPID_SESSION_GETPROPERTYBAG);
  550. CASE_OF(DISPID_SESSION_KEEPALIVE);
  551. CASE_OF(DISPID_SOCKET_PARENT);
  552. CASE_OF(DISPID_SOCKET_SEND);
  553. CASE_OF(DISPID_SOCKET_RECV);
  554. CASE_OF(DISPID_SOCKET_OPTION);
  555. CASE_OF(DISPID_SOCKET_CLOSE);
  556. CASE_OF(DISPID_SOCKET_RESOLVE);
  557. CASE_OF(DISPID_SOCKET_LOCALNAME);
  558. CASE_OF(DISPID_SOCKET_LOCALADDRESS);
  559. CASE_OF(DISPID_SOCKET_LOCALPORT);
  560. CASE_OF(DISPID_SOCKET_REMOTENAME);
  561. CASE_OF(DISPID_SOCKET_REMOTEADDRESS);
  562. CASE_OF(DISPID_SOCKET_REMOTEPORT);
  563. CASE_OF(DISPID_HEADERS_PARENT);
  564. CASE_OF(DISPID_HEADERS_GET);
  565. CASE_OF(DISPID_HEADERS_SET);
  566. CASE_OF(DISPID_HEADERS_GETHEADER);
  567. CASE_OF(DISPID_HEADERS_SETHEADER);
  568. CASE_OF(DISPID_ENTITY_PARENT);
  569. CASE_OF(DISPID_ENTITY_GET);
  570. CASE_OF(DISPID_ENTITY_SET);
  571. CASE_OF(DISPID_ENTITY_COMPRESS);
  572. CASE_OF(DISPID_ENTITY_DECOMPRESS);
  573. CASE_OF(DISPID_URL_PARENT);
  574. CASE_OF(DISPID_URL_ENCODING);
  575. CASE_OF(DISPID_URL_SCHEME);
  576. CASE_OF(DISPID_URL_SERVER);
  577. CASE_OF(DISPID_URL_PORT);
  578. CASE_OF(DISPID_URL_PATH);
  579. CASE_OF(DISPID_URL_RESOURCE);
  580. CASE_OF(DISPID_URL_QUERY);
  581. CASE_OF(DISPID_URL_FRAGMENT);
  582. CASE_OF(DISPID_URL_ESCAPE);
  583. CASE_OF(DISPID_URL_UNESCAPE);
  584. CASE_OF(DISPID_URL_SET);
  585. CASE_OF(DISPID_URL_GET);
  586. CASE_OF(DISPID_REQUEST_PARENT);
  587. CASE_OF(DISPID_REQUEST_HEADERS);
  588. CASE_OF(DISPID_REQUEST_ENTITY);
  589. CASE_OF(DISPID_REQUEST_URL);
  590. CASE_OF(DISPID_REQUEST_VERB);
  591. CASE_OF(DISPID_REQUEST_HTTPVERSION);
  592. CASE_OF(DISPID_RESPONSE_PARENT);
  593. CASE_OF(DISPID_RESPONSE_HEADERS);
  594. CASE_OF(DISPID_RESPONSE_ENTITY);
  595. CASE_OF(DISPID_RESPONSE_STATUSCODE);
  596. CASE_OF(DISPID_RESPONSE_STATUSTEXT);
  597. CASE_OF(DISPID_W3SPOOF_REGISTERCLIENT);
  598. CASE_OF(DISPID_W3SPOOF_REVOKECLIENT);
  599. // internal runtime dispids
  600. CASE_OF(DISPID_RUNTIME_GETFILE);
  601. CASE_OF(DISPID_FILE_OPEN);
  602. CASE_OF(DISPID_FILE_CLOSE);
  603. CASE_OF(DISPID_FILE_WRITE);
  604. CASE_OF(DISPID_FILE_WRITELINE);
  605. CASE_OF(DISPID_FILE_WRITEBLANKLINE);
  606. CASE_OF(DISPID_FILE_READ);
  607. CASE_OF(DISPID_FILE_READALL);
  608. CASE_OF(DISPID_FILE_ATTRIBUTES);
  609. CASE_OF(DISPID_FILE_SIZE);
  610. CASE_OF(DISPID_FILE_TYPE);
  611. CASE_OF(DISPID_FILE_DATELASTMODIFIED);
  612. CASE_OF(DISPID_PROPERTYBAG_GET);
  613. CASE_OF(DISPID_PROPERTYBAG_SET);
  614. CASE_OF(DISPID_PROPERTYBAG_EXPIRES);
  615. CASE_OF(DISPID_PROPERTYBAG_FLUSH);
  616. default : return "?";
  617. }
  618. }
  619. LPSTR
  620. MapVariantTypeToString(VARIANT* pvar)
  621. {
  622. if( pvar )
  623. {
  624. switch( V_VT(pvar) )
  625. {
  626. CASE_OF(VT_ARRAY | VT_UI1);
  627. CASE_OF(VT_EMPTY);
  628. CASE_OF(VT_NULL);
  629. CASE_OF(VT_I2);
  630. CASE_OF(VT_I4);
  631. CASE_OF(VT_R4);
  632. CASE_OF(VT_R8);
  633. CASE_OF(VT_CY);
  634. CASE_OF(VT_DATE);
  635. CASE_OF(VT_BSTR);
  636. CASE_OF(VT_DISPATCH);
  637. CASE_OF(VT_ERROR);
  638. CASE_OF(VT_BOOL);
  639. CASE_OF(VT_VARIANT);
  640. CASE_OF(VT_DECIMAL);
  641. CASE_OF(VT_RECORD);
  642. CASE_OF(VT_UNKNOWN);
  643. CASE_OF(VT_I1);
  644. CASE_OF(VT_UI1);
  645. CASE_OF(VT_UI2);
  646. CASE_OF(VT_UI4);
  647. CASE_OF(VT_INT);
  648. CASE_OF(VT_UINT);
  649. CASE_OF(VT_ARRAY);
  650. CASE_OF(VT_BYREF);
  651. default : return "?";
  652. }
  653. }
  654. else
  655. {
  656. return "?";
  657. }
  658. }
  659. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  660. MapInvokeFlagsToString()
  661. WHAT : maps invoke flags to a string for the log file.
  662. ARGS : flags - the invoke flags
  663. RETURNS : string representation of the flags
  664. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  665. LPSTR
  666. MapInvokeFlagsToString(WORD flags)
  667. {
  668. return "NOT_IMPLEMENTED";
  669. }
  670. #ifdef _DEBUG
  671. #define DEBUG_DEFAULT_DBGFILE L"W3SPOOF.LOG"
  672. #define DEBUG_LOGFILE_MUTEX L"W3Spoof_LogFile_Mutex"
  673. //
  674. // globals
  675. //
  676. DWORD g_dwTlsIndex = 0L;
  677. DWORD g_dwDebugFlags = DBG_NO_DEBUG;
  678. HANDLE g_hDebugLogFile = NULL;
  679. HANDLE g_mtxDebugLogFile = NULL;
  680. LPCWSTR g_wszDebugFlags = L"debugflags";
  681. MEMUSAGE g_memusage = {0};
  682. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  683. DebugInitialize()
  684. WHAT : initializes the debugging support for the application. allocates
  685. thread-local storage and opens a log file if necessary.
  686. on failure, the function sets the DBG_NO_DEBUG flag so other
  687. debug functions won't do anything to get us in trouble.
  688. ARGS : none
  689. RETURNS : nothing
  690. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  691. void
  692. DebugInitialize( void )
  693. {
  694. LPDWORD pdw = NULL;
  695. DebugMemInitialize();
  696. if( GetRegValue(g_wszDebugFlags, REG_DWORD, (void**) &pdw) )
  697. {
  698. g_dwDebugFlags = *pdw;
  699. delete pdw;
  700. }
  701. else
  702. {
  703. g_dwDebugFlags = DEBUG_DEFAULT_FLAGS;
  704. }
  705. if( DBG_THROWDBGALERT & g_dwDebugFlags )
  706. DebugThrowDbgAlert();
  707. if( !(g_dwDebugFlags & DBG_NO_DEBUG) )
  708. {
  709. //
  710. // allocate a TLS slot or else we can't
  711. // do call tracing
  712. //
  713. if( (g_dwTlsIndex = TlsAlloc()) == 0xFFFFFFFF )
  714. goto no_debug;
  715. //
  716. // if logging to file is enabled, open the log file
  717. // and create a mutex for log dumps, disable debug
  718. // logging on error
  719. //
  720. if( g_dwDebugFlags & DBG_TO_FILE )
  721. {
  722. if(
  723. !( _opendebugfile() &&
  724. (g_mtxDebugLogFile = CreateMutex(NULL, FALSE, DEBUG_LOGFILE_MUTEX))
  725. )
  726. )
  727. goto no_debug;
  728. }
  729. //
  730. // print the log banner
  731. //
  732. char* time = _gettimestamp();
  733. _debugout(
  734. NULL,
  735. TRUE,
  736. FALSE,
  737. "\r\nDebug W3SPOOF.EXE started at %s with flags: %x\r\n\r\n",
  738. time,
  739. g_dwDebugFlags
  740. );
  741. delete [] time;
  742. return;
  743. }
  744. else
  745. {
  746. DebugMemTerminate();
  747. }
  748. no_debug:
  749. g_dwDebugFlags = DBG_NO_DEBUG;
  750. }
  751. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  752. DebugTerminate()
  753. WHAT : terminates debugging support for the application.
  754. ARGS : none
  755. RETURNS : nothing.
  756. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  757. void
  758. DebugTerminate( void )
  759. {
  760. if( !(g_dwDebugFlags & DBG_NO_DEBUG) )
  761. {
  762. DebugMemTerminate();
  763. if( g_dwTlsIndex )
  764. TlsFree(g_dwTlsIndex);
  765. if( (g_dwDebugFlags & DBG_TO_FILE) && g_hDebugLogFile )
  766. {
  767. _closedebugfile();
  768. CloseHandle(g_mtxDebugLogFile);
  769. g_mtxDebugLogFile = NULL;
  770. }
  771. }
  772. }
  773. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  774. DebugMemInitialize()
  775. WHAT : Initializes memory allocation tracking for the app.
  776. ARGS : none.
  777. RETURNS : nothing.
  778. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  779. void
  780. DebugMemInitialize(void)
  781. {
  782. InitializeCriticalSection(&g_memusage.lock);
  783. g_memusage.total = 0;
  784. }
  785. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  786. DebugMemTerminate()
  787. WHAT : Terminates memory allocation tracking and prints the final line
  788. in the logfile indicating how many bytes of memory were unallocated
  789. at process termination.
  790. ARGS : none.
  791. RETURNS : nothing.
  792. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  793. void
  794. DebugMemTerminate(void)
  795. {
  796. if( g_dwDebugFlags & DBG_MEM )
  797. DebugTrace("*** unallocated memory: %d bytes", g_memusage.total);
  798. DeleteCriticalSection(&g_memusage.lock);
  799. }
  800. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  801. DebugMemAlloc()
  802. WHAT : Increments our allocation tracking value by the number of bytes
  803. a given allocation maps to on the process heap.
  804. ARGS : pv - pointer to allocated memory.
  805. RETURNS : nothing.
  806. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  807. void
  808. DebugMemAlloc(void* pv)
  809. {
  810. EnterCriticalSection(&g_memusage.lock);
  811. g_memusage.total += HeapSize(GetProcessHeap(), 0, pv);
  812. LeaveCriticalSection(&g_memusage.lock);
  813. }
  814. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  815. DebugMemFree()
  816. WHAT : Decrements our allocation tracking value by the number of bytes an
  817. allocation uses on the heap.
  818. ARGS : pv - pointer to allocated memory.
  819. RETURNS : nothing.
  820. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  821. void
  822. DebugMemFree(void* pv)
  823. {
  824. EnterCriticalSection(&g_memusage.lock);
  825. g_memusage.total -= HeapSize(GetProcessHeap(), 0, pv);
  826. LeaveCriticalSection(&g_memusage.lock);
  827. }
  828. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  829. DebugThrowDbgAlert()
  830. WHAT : Throws an alert dialog displaying the process PID so a debugger
  831. can be attached.
  832. ARGS : none.
  833. RETURNS : nothing.
  834. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  835. void
  836. DebugThrowDbgAlert(void)
  837. {
  838. char buf[256];
  839. wsprintfA(
  840. buf,
  841. "pid=%d",
  842. GetCurrentProcessId()
  843. );
  844. MessageBoxA(NULL, buf, "Attach Debugger!", MB_OK | MB_ICONSTOP | MB_SERVICE_NOTIFICATION);
  845. }
  846. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  847. DebugEnter()
  848. WHAT : called on api entry. prints a log entry resembling the following:
  849. CalledFunctionName(param1=value, etc.)
  850. ARGS : category - the debugging category for the logged function
  851. rt - lets us know what type the function returns
  852. function - the logged function's name
  853. format - user-supplied format string containing function args
  854. ... - optional parameter list
  855. RETURNS : nothing
  856. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  857. void
  858. DebugEnter(int category, RETTYPE rt, LPCSTR function, const char* format, ...)
  859. {
  860. LPTHREADINFO pti = NULL;
  861. LPCALLINFO pci = NULL;
  862. if( !(g_dwDebugFlags & DBG_NO_DEBUG) )
  863. {
  864. pti = GetThreadInfo();
  865. pci = SetCallInfo(pti, category, rt, function);
  866. if( g_dwDebugFlags & category )
  867. {
  868. char* buffer = new char[1024];
  869. va_list arg_list;
  870. pti->depth++;
  871. if( buffer )
  872. {
  873. //
  874. // if the user passed an arglist & some values,
  875. // we'll plug it in to the function entry listing
  876. // in the log. otherwise we just print empty parens
  877. //
  878. if( format )
  879. {
  880. va_start(arg_list, format);
  881. wvsprintfA(buffer, format, arg_list);
  882. _debugout(pti, FALSE, FALSE, "%s(%s)", function, buffer);
  883. va_end(arg_list);
  884. }
  885. else
  886. {
  887. _debugout(pti, FALSE, FALSE, "%s()", function);
  888. }
  889. delete [] buffer;
  890. }
  891. }
  892. }
  893. }
  894. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  895. DebugLeave()
  896. WHAT : prints a log entry for the logged function displaying the return
  897. value.
  898. ARGS : retval - the value the logged function will return
  899. RETURNS : nothing.
  900. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  901. void
  902. DebugLeave(int retval)
  903. {
  904. LPTHREADINFO pti = NULL;
  905. LPCALLINFO pci = NULL;
  906. if( !(g_dwDebugFlags & DBG_NO_DEBUG) )
  907. {
  908. pti = GetThreadInfo();
  909. pci = GetCallInfo(pti);
  910. if( g_dwDebugFlags & pci->category )
  911. {
  912. char* buffer = FormatCallReturnString(pci, retval);
  913. _debugout(pti, FALSE, FALSE, buffer);
  914. pti->depth--;
  915. delete [] buffer;
  916. }
  917. DeleteCallInfo(pci);
  918. }
  919. }
  920. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  921. DebugTrace()
  922. WHAT : prints a generic output line with the usual timestamp & thread id,
  923. etc.
  924. ARGS : format - user-supplied format string
  925. ... - optional parameter list
  926. RETURNS : nothing
  927. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  928. void
  929. DebugTrace(const char* format, ...)
  930. {
  931. va_list arg_list;
  932. char buf[1024];
  933. if( !(g_dwDebugFlags & DBG_NO_DEBUG) )
  934. {
  935. va_start(arg_list, format);
  936. wvsprintfA(buf, format, arg_list);
  937. _debugout(GetThreadInfo(), FALSE, TRUE, buf);
  938. va_end(arg_list);
  939. }
  940. }
  941. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  942. DebugAssert()
  943. WHAT : logs asserts to the selected outputs but doesn't break execution.
  944. ARGS : condition - the stringized failure condition.
  945. file - the file containing the assert
  946. line - the line of code that asserted
  947. RETURNS : nothing
  948. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  949. void
  950. DebugAssert(LPSTR condition, LPSTR file, int line)
  951. {
  952. LPTHREADINFO pti = GetThreadInfo();
  953. LPCALLINFO pci = NULL;
  954. _debugout(
  955. pti,
  956. TRUE,
  957. FALSE,
  958. "\r\n\r\n\t*******************************************\r\n" \
  959. "\t ASSERTION FAILED: \"%s\"\r\n" \
  960. "\t %s (line %d)\r\n",
  961. condition,
  962. file,
  963. line
  964. );
  965. for(pci = pti->stack; pci; pci = pci->next)
  966. {
  967. _debugout(pti, TRUE, FALSE, "\t %s", pci->fname);
  968. }
  969. _debugout(pti, TRUE, FALSE, "\r\n\t*******************************************\r\n");
  970. }
  971. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  972. DebugDataDump*()
  973. WHAT : functions to dump a data buffer to the log file.
  974. ARGS : title - a legend for the dump
  975. data - the buffer
  976. len - number of interesting bytes in the buffer
  977. RETURNS : nothing
  978. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  979. void
  980. DebugDataDump(LPSTR title, LPBYTE data, DWORD len)
  981. {
  982. DWORD n = 0L;
  983. DWORD offset = 0L;
  984. CHAR* buf = NULL;
  985. DebugTrace("%s (%#x bytes @ %#x)", title, len, data);
  986. buf = new CHAR[256];
  987. while( len )
  988. {
  989. n = DebugDataDumpFormat(buf, data, len);
  990. DebugTrace(buf);
  991. data += n;
  992. len -= n;
  993. }
  994. delete [] buf;
  995. }
  996. int
  997. DebugDataDumpFormat(LPSTR buffer, LPBYTE data, DWORD len)
  998. {
  999. //
  1000. // note - plagiarized from similar code in wininet.
  1001. //
  1002. static char spaces[] = " ";
  1003. DWORD n = 0L;
  1004. DWORD bytes = 0L;
  1005. DWORD offset = 0L;
  1006. DWORD byte = 0L;
  1007. CHAR ch;
  1008. bytes = min(len, 16);
  1009. offset = wsprintfA(buffer, "%08x ", data);
  1010. for(n=0; n<bytes; n++)
  1011. {
  1012. byte = data[n] & 0xFF;
  1013. offset += wsprintfA(
  1014. buffer+offset,
  1015. ((n & 15) == 7 ? "%02.2x-" : "%02.2x "),
  1016. byte
  1017. );
  1018. }
  1019. memcpy(buffer+offset, spaces, (16-bytes) * 3 + 2);
  1020. offset += (16-bytes) * 3 + 2;
  1021. for(n=0; n<bytes; n++)
  1022. {
  1023. ch = data[n];
  1024. buffer[offset + n] = (((ch < 32) || (ch > 127)) || ch == '%') ? '.' : ch;
  1025. }
  1026. buffer[offset + n] = '\0';
  1027. return bytes;
  1028. }
  1029. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1030. AcquireDebugFileLock()
  1031. WHAT : synchronizes access to the log file handle.
  1032. ARGS : none
  1033. RETURNS : nothing
  1034. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1035. void
  1036. AcquireDebugFileLock(void)
  1037. {
  1038. WaitForSingleObject(g_mtxDebugLogFile, INFINITE);
  1039. }
  1040. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1041. ReleaseDebugFileLock()
  1042. WHAT : releases a thread's lock on the log file handle
  1043. ARGS : none
  1044. RETURNS : nothing
  1045. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1046. void
  1047. ReleaseDebugFileLock(void)
  1048. {
  1049. ReleaseMutex(g_mtxDebugLogFile);
  1050. }
  1051. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1052. GetThreadInfo()
  1053. WHAT : extracts a THREADINFO struct from TLS. if one does not exist,
  1054. this function allocates one and returns it.
  1055. ARGS : none
  1056. RETURNS : pointer to a THREADINFO struct.
  1057. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1058. LPTHREADINFO
  1059. GetThreadInfo(void)
  1060. {
  1061. LPTHREADINFO pti = (LPTHREADINFO) TlsGetValue(g_dwTlsIndex);
  1062. if( !pti )
  1063. {
  1064. pti = new THREADINFO;
  1065. pti->threadid = GetCurrentThreadId();
  1066. pti->threadcat = 0;
  1067. pti->depth = 0;
  1068. pti->stack = NULL;
  1069. TlsSetValue(g_dwTlsIndex, (LPVOID) pti);
  1070. }
  1071. return pti;
  1072. }
  1073. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1074. SetCallInfo()
  1075. WHAT : allocates and pushes a CALLINFO struct onto the thread's internal
  1076. call list.
  1077. ARGS : pti - pointer to the thread's THREADINFO struct
  1078. category - the debug category associated with the logged function
  1079. rt - return type used by the logged function
  1080. function - the function name
  1081. RETURNS : pointer to a newly allocated CALLINFO struct
  1082. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1083. LPCALLINFO
  1084. SetCallInfo(LPTHREADINFO pti, DWORD category, RETTYPE rt, LPCSTR function)
  1085. {
  1086. LPCALLINFO pci = NULL;
  1087. LPCALLINFO plast = NULL;
  1088. //
  1089. // walk the call stack to the last item,
  1090. // store the next-to-last position
  1091. //
  1092. for( pci = pti->stack; pci; pci = pci->next )
  1093. {
  1094. plast = pci;
  1095. }
  1096. if( !pci )
  1097. {
  1098. pci = new CALLINFO;
  1099. //
  1100. // if this is the first call on this thread, set the thread
  1101. // category id. this makes logging more understandable by
  1102. // remembering where a thread was first created and what it
  1103. // was used for. the old method changed the caller id based
  1104. // on the function category, which was dumb.
  1105. //
  1106. if( !pti->threadcat )
  1107. pti->threadcat = category;
  1108. pci->category = category;
  1109. pci->fname = function;
  1110. pci->rettype = rt;
  1111. pci->last = plast;
  1112. pci->next = NULL;
  1113. //
  1114. // if this is the first element, insert it
  1115. // at the head of the list, otherwise
  1116. // link up with the last element
  1117. //
  1118. if( !pti->stack )
  1119. {
  1120. pti->stack = pci;
  1121. }
  1122. else
  1123. {
  1124. plast->next = pci;
  1125. }
  1126. }
  1127. return pci;
  1128. }
  1129. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1130. GetCallInfo()
  1131. WHAT : retrieves the last THREADINFO struct from the threads call trace
  1132. list.
  1133. ARGS : pti - pointer to the THREADINFO struct whose call list you want
  1134. RETURNS : pointer to a CALLINFO struct
  1135. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1136. LPCALLINFO
  1137. GetCallInfo(LPTHREADINFO pti)
  1138. {
  1139. LPCALLINFO pci = NULL;
  1140. if( pti->stack )
  1141. {
  1142. for( pci = pti->stack; pci->next; pci = pci->next );
  1143. }
  1144. return pci;
  1145. }
  1146. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1147. DeleteCallInfo()
  1148. WHAT : pops the specified CALLINFO struct off the thread's call list and
  1149. deletes it. if we just popped & deleted the last call record, then
  1150. delete the thread's THREADINFO struct.
  1151. ARGS : pci - the CALLINFO struct you wish to delete
  1152. RETURNS : nothing
  1153. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1154. void
  1155. DeleteCallInfo(LPCALLINFO pci)
  1156. {
  1157. LPTHREADINFO pti = GetThreadInfo();
  1158. //
  1159. // if the call record we're dealing with isn't the top of the stack
  1160. // then fix up the stack pointers
  1161. //
  1162. // if the current call record is the last then delete the THREADINFO
  1163. // for this thread and NULL the TLS value
  1164. //
  1165. if( pci->last )
  1166. {
  1167. pci->last->next = NULL;
  1168. }
  1169. else
  1170. {
  1171. delete pti;
  1172. TlsSetValue(g_dwTlsIndex, NULL);
  1173. }
  1174. //
  1175. // for all cases, free the call record
  1176. //
  1177. delete pci;
  1178. }
  1179. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1180. FormatCallReturnString()
  1181. WHAT : examines the returning function's return type and formats a string
  1182. containing the return value. in the case of known error codes, we
  1183. include a string representation of the error (e.g. ERROR_SUCCESS).
  1184. ARGS : pci - pointer to the CALLINFO struct for the returning function
  1185. retval - the function's return value
  1186. RETURNS : formatted character buffer
  1187. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1188. LPSTR
  1189. FormatCallReturnString(LPCALLINFO pci, int retval)
  1190. {
  1191. char* buffer = new char[256];
  1192. int offset = 0;
  1193. if( buffer )
  1194. {
  1195. offset = wsprintfA(
  1196. buffer,
  1197. "%s() returned ",
  1198. pci->fname
  1199. );
  1200. switch( pci->rettype )
  1201. {
  1202. case rt_void :
  1203. {
  1204. wsprintfA(buffer+offset, "<void>");
  1205. }
  1206. break;
  1207. case rt_bool :
  1208. {
  1209. wsprintfA(buffer+offset, "%s", (retval ? "TRUE" : "FALSE"));
  1210. }
  1211. break;
  1212. case rt_dword :
  1213. {
  1214. wsprintfA(buffer+offset, "%d [%s]", retval, MapErrorToString(retval));
  1215. }
  1216. break;
  1217. case rt_hresult :
  1218. {
  1219. wsprintfA(buffer+offset, "%x [%s]", retval, MapHResultToString(retval));
  1220. }
  1221. break;
  1222. case rt_string :
  1223. {
  1224. wsprintfA(buffer+offset, "%.16s", (LPSTR)retval);
  1225. }
  1226. break;
  1227. default:
  1228. {
  1229. wsprintfA(buffer+offset, "?");
  1230. }
  1231. }
  1232. }
  1233. return buffer;
  1234. }
  1235. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1236. MapCategoryToString()
  1237. WHAT : maps a debug category to a string for the log file.
  1238. ARGS : category - the category id
  1239. RETURNS : string representation of the category id
  1240. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1241. LPSTR
  1242. MapCategoryToString(int category)
  1243. {
  1244. switch(category)
  1245. {
  1246. case DBG_APP : return "app";
  1247. case DBG_WORKER : return "---";
  1248. default : return "???";
  1249. }
  1250. }
  1251. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1252. MapCompKeyToString()
  1253. WHAT : maps a completion key to a string for the log file.
  1254. ARGS : key - the completion key
  1255. RETURNS : string representation of the completion key
  1256. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1257. LPSTR
  1258. MapCompKeyToString(int key)
  1259. {
  1260. switch(key)
  1261. {
  1262. CASE_OF(CK_INVALID_KEY);
  1263. CASE_OF(CK_NEW_CONNECTION);
  1264. CASE_OF(CK_NORMAL);
  1265. CASE_OF(CK_CANCEL_IO);
  1266. CASE_OF(CK_TERMINATE_THREAD);
  1267. default :
  1268. {
  1269. return "*** WARNING: Unrecognized completion key!! ***";
  1270. }
  1271. }
  1272. }
  1273. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1274. _debugout()
  1275. WHAT : the debug output workhorse. sloppy as jello in the Texas sun and
  1276. i don't care.
  1277. ARGS : pti - THREADINFO pointer
  1278. fRaw - skip debug info formatting
  1279. fTrace - flag that causes us to do in-function indenting
  1280. format - printf format string
  1281. ... - arglist
  1282. RETURNS : nothing
  1283. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1284. void
  1285. _debugout(LPTHREADINFO pti, BOOL fRaw, BOOL fTrace, const char* format, ...)
  1286. {
  1287. int offset = 0;
  1288. char* buffer = new char[2048];
  1289. va_list arg_list;
  1290. if( !buffer )
  1291. goto quit;
  1292. //
  1293. // check if the user wants verbose debug info
  1294. //
  1295. if( !fRaw )
  1296. {
  1297. if( DBG_TIMESTAMP & g_dwDebugFlags )
  1298. {
  1299. char* timestamp = _gettimestamp();
  1300. offset = wsprintfA(buffer, "%s ", timestamp);
  1301. delete [] timestamp;
  1302. }
  1303. if( DBG_THREAD_INFO & g_dwDebugFlags )
  1304. {
  1305. offset += wsprintfA(buffer+offset, "%0.8x:%0.3d ", pti->threadid, pti->depth);
  1306. }
  1307. if( DBG_CALL_INFO & g_dwDebugFlags )
  1308. {
  1309. //
  1310. // 260500 pmidge
  1311. // changed this to use the thread category id instead of the caller's id.
  1312. //
  1313. offset += wsprintfA(buffer+offset, "<%s> ", MapCategoryToString(pti->threadcat));
  1314. }
  1315. if( DBG_NEST_CALLS & g_dwDebugFlags )
  1316. {
  1317. char* whitespace = _getwhitespace(
  1318. (fTrace ? pti->depth+1 : pti->depth)
  1319. );
  1320. offset += wsprintfA(buffer+offset, "%s", whitespace);
  1321. delete [] whitespace;
  1322. }
  1323. }
  1324. //
  1325. // plug in caller's goo if present
  1326. //
  1327. if( format )
  1328. {
  1329. va_start(arg_list, format);
  1330. offset += wvsprintfA(buffer+offset, format, arg_list);
  1331. wsprintfA(buffer+offset, "\r\n");
  1332. va_end(arg_list);
  1333. }
  1334. //
  1335. // dump to selected outputs
  1336. //
  1337. //
  1338. // BUGBUG: this app only runs on W2K, need to
  1339. // investigate WMI support
  1340. //
  1341. if( DBG_TO_FILE & g_dwDebugFlags )
  1342. {
  1343. DWORD dw = 0;
  1344. AcquireDebugFileLock();
  1345. WriteFile(
  1346. g_hDebugLogFile,
  1347. buffer,
  1348. strlen(buffer),
  1349. &dw,
  1350. NULL
  1351. );
  1352. ReleaseDebugFileLock();
  1353. }
  1354. if( DBG_TO_DEBUGGER & g_dwDebugFlags )
  1355. OutputDebugStringA(buffer);
  1356. quit:
  1357. delete [] buffer;
  1358. }
  1359. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1360. _gettimestamp( void )
  1361. WHAT : gets the current time, formats it, and returns it to the caller.
  1362. the caller MUST free the return value when done.
  1363. ARGS : none
  1364. RETURNS : pointer to formatted time string
  1365. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1366. char*
  1367. _gettimestamp( void )
  1368. {
  1369. SYSTEMTIME st;
  1370. char* buffer = new char[256];
  1371. if( buffer )
  1372. {
  1373. GetLocalTime(&st);
  1374. wsprintfA(
  1375. buffer,
  1376. "%0.2d:%0.2d:%0.2d.%0.3d",
  1377. st.wHour,
  1378. st.wMinute,
  1379. st.wSecond,
  1380. st.wMilliseconds
  1381. );
  1382. }
  1383. return buffer;
  1384. }
  1385. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1386. _getwhitespace( int spaces )
  1387. WHAT : used to insert a number of spaces for indenting. caller must
  1388. free return value.
  1389. ARGS : spaces - number of spaces to insert
  1390. RETURNS : pointer to character buffer filled with spaces
  1391. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1392. char*
  1393. _getwhitespace(int spaces)
  1394. {
  1395. char* buffer = new char[(spaces * 2) + 1];
  1396. if( buffer )
  1397. {
  1398. memset(buffer, ' ', (spaces * 2));
  1399. buffer[(spaces * 2)] = '\0';
  1400. }
  1401. return buffer;
  1402. }
  1403. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1404. _opendebugfile( void )
  1405. WHAT : opens the debug log file. will stomp previous logs instead of
  1406. appending.
  1407. ARGS : none
  1408. RETURNS : true or false based on whether the file was opened.
  1409. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1410. BOOL
  1411. _opendebugfile(void)
  1412. {
  1413. if( !g_hDebugLogFile )
  1414. {
  1415. g_hDebugLogFile = CreateFile(
  1416. DEBUG_DEFAULT_DBGFILE,
  1417. GENERIC_READ | GENERIC_WRITE,
  1418. FILE_SHARE_READ,
  1419. NULL,
  1420. CREATE_ALWAYS,
  1421. FILE_ATTRIBUTE_NORMAL,
  1422. NULL
  1423. );
  1424. }
  1425. return (g_hDebugLogFile ? TRUE : FALSE);
  1426. }
  1427. /*++=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
  1428. _closedebugfile( void )
  1429. WHAT : closes the debug log file.
  1430. ARGS : none
  1431. RETURNS : nothing
  1432. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--*/
  1433. void
  1434. _closedebugfile(void)
  1435. {
  1436. SAFECLOSE(g_hDebugLogFile);
  1437. }
  1438. #endif /* _DEBUG */