Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

782 lines
26 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. RxLog.c
  5. Abstract:
  6. This module implements the logging system used by the Rx file system.
  7. Author:
  8. JoeLinn [JoeLinn] 1-Dec-94
  9. Revision History:
  10. Balan Sethu Raman [SethuR] 24-April-95
  11. Revised to conform to new log record layout.
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include "stdarg.h"
  16. #include "stdio.h"
  17. #include "stdlib.h"
  18. #include "string.h"
  19. #include "prefix.h"
  20. #ifdef ALLOC_PRAGMA
  21. #pragma alloc_text(PAGE, RxUninitializeLog)
  22. #pragma alloc_text(PAGE, RxInitializeLog)
  23. #pragma alloc_text(PAGE, RxPrintLog)
  24. #pragma alloc_text(PAGE, RxpTrackDereference)
  25. #endif
  26. #if !DBG
  27. #undef RDBSSTRACE
  28. #endif
  29. //
  30. // The debug trace level
  31. //
  32. #define Dbg (0)
  33. #define RDBSSHUGELOG
  34. #if DBG
  35. #define RX_LOG_BUFFER_SIZE 5000
  36. #else
  37. #if RDBSSLOG
  38. #define RX_LOG_BUFFER_SIZE 500
  39. #else
  40. #define RX_LOG_BUFFER_SIZE 0
  41. #endif
  42. #endif
  43. #define MAX_RX_LOG_BUFFER_ALLOC (256*1024)
  44. #define RX_LOG_MAX_MDLLIST_LENGTH 100
  45. RX_LOG s_RxLog = {0,RX_LOG_UNINITIALIZED,NULL,NULL,NULL,0,0,0,0};
  46. PUCHAR RxContxOperationNames[] = {
  47. RDBSSLOG_ASYNC_NAME_PREFIX "CREATE", //#define IRP_MJ_CREATE 0x00
  48. RDBSSLOG_ASYNC_NAME_PREFIX "CR_NMPIPE", //#define IRP_MJ_CREATE_NAMED_PIPE 0x01
  49. RDBSSLOG_ASYNC_NAME_PREFIX "CLOSE", //#define IRP_MJ_CLOSE 0x02
  50. RDBSSLOG_ASYNC_NAME_PREFIX "READ", //#define IRP_MJ_READ 0x03
  51. RDBSSLOG_ASYNC_NAME_PREFIX "WRITE", //#define IRP_MJ_WRITE 0x04
  52. RDBSSLOG_ASYNC_NAME_PREFIX "QUERYINFO", //#define IRP_MJ_QUERY_INFORMATION 0x05
  53. RDBSSLOG_ASYNC_NAME_PREFIX "SETINFO", //#define IRP_MJ_SET_INFORMATION 0x06
  54. RDBSSLOG_ASYNC_NAME_PREFIX "QUERYEA", //#define IRP_MJ_QUERY_EA 0x07
  55. RDBSSLOG_ASYNC_NAME_PREFIX "SETEA", //#define IRP_MJ_SET_EA 0x08
  56. RDBSSLOG_ASYNC_NAME_PREFIX "FLUSH", //#define IRP_MJ_FLUSH_BUFFERS 0x09
  57. RDBSSLOG_ASYNC_NAME_PREFIX "QUERYVOL", //#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0a
  58. RDBSSLOG_ASYNC_NAME_PREFIX "SETVOL", //#define IRP_MJ_SET_VOLUME_INFORMATION 0x0b
  59. RDBSSLOG_ASYNC_NAME_PREFIX "DIRCTRL", //#define IRP_MJ_DIRECTORY_CONTROL 0x0c
  60. RDBSSLOG_ASYNC_NAME_PREFIX "FSCTL", //#define IRP_MJ_FILE_SYSTEM_CONTROL 0x0d
  61. RDBSSLOG_ASYNC_NAME_PREFIX "IOCTL", //#define IRP_MJ_DEVICE_CONTROL 0x0e
  62. RDBSSLOG_ASYNC_NAME_PREFIX "xIOCTL", //#define IRP_MJ_INTERNAL_DEVICE_CONTROL 0x0f
  63. RDBSSLOG_ASYNC_NAME_PREFIX "SHUTDWN", //#define IRP_MJ_SHUTDOWN 0x10
  64. RDBSSLOG_ASYNC_NAME_PREFIX "LOCKCTRL", //#define IRP_MJ_LOCK_CONTROL 0x11
  65. RDBSSLOG_ASYNC_NAME_PREFIX "CLEANUP", //#define IRP_MJ_CLEANUP 0x12
  66. RDBSSLOG_ASYNC_NAME_PREFIX "CR_MLSLOT", //#define IRP_MJ_CREATE_MAILSLOT 0x13
  67. RDBSSLOG_ASYNC_NAME_PREFIX "QUERYSCRTY",//#define IRP_MJ_QUERY_SECURITY 0x14
  68. RDBSSLOG_ASYNC_NAME_PREFIX "SETSCRTY", //#define IRP_MJ_SET_SECURITY 0x15
  69. RDBSSLOG_ASYNC_NAME_PREFIX "QUERYPWR", //#define IRP_MJ_QUERY_POWER 0x16
  70. RDBSSLOG_ASYNC_NAME_PREFIX "NOTDEFND", //#define IRP_MJ_NOT_DEFINED 0x17
  71. RDBSSLOG_ASYNC_NAME_PREFIX "DVCHANGE", //#define IRP_MJ_DEVICE_CHANGE 0x18
  72. RDBSSLOG_ASYNC_NAME_PREFIX "QRYQUOTA", //#define IRP_MJ_QUERY_QUOTA 0x19
  73. RDBSSLOG_ASYNC_NAME_PREFIX "SETQUOTA", //#define IRP_MJ_SET_QUOTA 0x1a
  74. RDBSSLOG_ASYNC_NAME_PREFIX "PNPPOWER", //#define IRP_MJ_PNP_POWER 0x1b
  75. RDBSSLOG_ASYNC_NAME_PREFIX "********", //internal init 0x1c
  76. "XX"
  77. //#define IRP_MJ_MAXIMUM_FUNCTION 0x1b
  78. };
  79. PRX_LOG_ENTRY_HEADER
  80. RxGetNextLogEntry(void)
  81. {
  82. PRX_LOG_ENTRY_HEADER pEntry;
  83. // you have to hold the spinlock for this....
  84. pEntry = s_RxLog.CurrentEntry + 1;
  85. if (pEntry == s_RxLog.EntryLimit){
  86. s_RxLog.NumberOfLogWraps++;
  87. pEntry = s_RxLog.BaseEntry;
  88. }
  89. s_RxLog.CurrentEntry = pEntry;
  90. return pEntry;
  91. }
  92. VOID
  93. RxUninitializeLog ()
  94. {
  95. PRX_LOG_ENTRY_HEADER EntryLimit = s_RxLog.EntryLimit;
  96. PMDL *MdlList = (PMDL *)(EntryLimit+1);
  97. PAGED_CODE();
  98. //NOTE: none of this is happening under spinlock!
  99. //DbgPrint("UninitLog: mdllist=%08lx,*mdllist=%08lx\n",MdlList,*MdlList);
  100. //DbgBreakPoint();
  101. if ((s_RxLog.State == RX_LOG_UNINITIALIZED) ||
  102. (s_RxLog.State == RX_LOG_ERROR)) {
  103. return;
  104. }
  105. s_RxLog.State = RX_LOG_UNINITIALIZED;
  106. for (;;) {
  107. PMDL Mdl = *MdlList;
  108. PUCHAR Buffer;
  109. if (Mdl == NULL) break;
  110. Buffer = MmGetMdlVirtualAddress(Mdl);
  111. //DbgPrint("UninitLog: buffer=%08lx,mdl=%08lx\n",Buffer,Mdl);
  112. MmUnlockPages(Mdl);
  113. IoFreeMdl(Mdl);
  114. RxFreePool(Buffer);
  115. MdlList++;
  116. }
  117. RxFreePool(s_RxLog.BaseEntry);
  118. return;
  119. };
  120. NTSTATUS
  121. RxInitializeLog ()
  122. {
  123. ULONG NumEntries = RX_LOG_BUFFER_SIZE;
  124. ULONG NumEntriesLeft;
  125. ULONG LogSize = (NumEntries+1)*sizeof(RX_LOG_ENTRY_HEADER);
  126. PRX_LOG_ENTRY_HEADER BaseEntry=NULL,EntryLimit=NULL;
  127. PRX_LOG_ENTRY_HEADER p;
  128. PUCHAR NextBuffer;
  129. PMDL *MdlList;
  130. ULONG MdlListLength = RX_LOG_MAX_MDLLIST_LENGTH*sizeof(PMDL);
  131. ULONG MdlsLeft = RX_LOG_MAX_MDLLIST_LENGTH;
  132. ULONG SpaceLeft;
  133. PAGED_CODE();
  134. if (s_RxLog.State != RX_LOG_UNINITIALIZED) {
  135. return (STATUS_SUCCESS);
  136. }
  137. //only do this stuff once
  138. KeInitializeSpinLock( &s_RxLog.SpinLock );
  139. s_RxLog.LogBufferSizeInEntries = NumEntries;
  140. //first allocate the marginal index array
  141. BaseEntry = RxAllocatePoolWithTag(NonPagedPool,LogSize+MdlListLength,'xr');
  142. if (BaseEntry==NULL) {
  143. s_RxLog.State = RX_LOG_ERROR;
  144. DbgPrint("Couldn't initialize log1");
  145. return (STATUS_INSUFFICIENT_RESOURCES);
  146. }
  147. s_RxLog.BaseEntry = BaseEntry;
  148. EntryLimit = s_RxLog.EntryLimit = BaseEntry+NumEntries;
  149. MdlList = (PMDL *)(EntryLimit+1);
  150. *MdlList = 0;
  151. //DbgPrint("InitLog: mdllist=%08lx,*mdllist=%08lx\n",MdlList,*MdlList);
  152. //now allocate wspace for the actual buffers...since we may be asking for a lot
  153. // we allocate from pages pool and lock down.
  154. SpaceLeft = 0;
  155. for ( p=BaseEntry,NumEntriesLeft=NumEntries;
  156. NumEntriesLeft>0;
  157. p++,NumEntriesLeft-- ) {
  158. if (SpaceLeft<sizeof(RX_LOG_ENTRY_HEADER)) {
  159. PMDL Mdl = NULL;
  160. PUCHAR Buffer=NULL;
  161. NTSTATUS Status;
  162. ULONG AllocLength = min(MAX_RX_LOG_BUFFER_ALLOC,
  163. NumEntriesLeft*MAX_RX_LOG_ENTRY_SIZE);
  164. for (;;) {
  165. Buffer = RxAllocatePoolWithTag(PagedPool,AllocLength,'xr');
  166. if (Buffer) break;
  167. DbgPrint("InitLog: failed alloc at %08lx",AllocLength);
  168. if (AllocLength<PAGE_SIZE) break;
  169. AllocLength >>= 3;
  170. NumEntriesLeft = AllocLength / MAX_RX_LOG_ENTRY_SIZE;
  171. }
  172. if (Buffer==NULL) {
  173. s_RxLog.State = RX_LOG_ERROR;
  174. DbgPrint("Couldn't initialize log2");
  175. RxFreePool(BaseEntry);
  176. return (STATUS_INSUFFICIENT_RESOURCES);
  177. }
  178. if (MdlsLeft==0) {
  179. s_RxLog.State = RX_LOG_ERROR;
  180. DbgPrint("Couldn't initialize log3");
  181. RxFreePool(Buffer);
  182. RxFreePool(BaseEntry);
  183. return (STATUS_INSUFFICIENT_RESOURCES);
  184. }
  185. Mdl = RxAllocateMdl(Buffer,AllocLength);
  186. if (Mdl==NULL) {
  187. s_RxLog.State = RX_LOG_ERROR;
  188. DbgPrint("Couldn't initialize log4");
  189. RxFreePool(Buffer);
  190. RxFreePool(BaseEntry);
  191. return (STATUS_INSUFFICIENT_RESOURCES);
  192. }
  193. RxProbeAndLockPages(Mdl,KernelMode,IoModifyAccess,Status);
  194. if (Status!=(STATUS_SUCCESS)) {
  195. s_RxLog.State = RX_LOG_ERROR;
  196. DbgPrint("Couldn't initialize log5");
  197. RxFreePool(Mdl);
  198. RxFreePool(Buffer);
  199. RxFreePool(BaseEntry);
  200. return Status;
  201. }
  202. //DbgPrint("InitLog: newbuf=%08lx,mdl=%08lx,alloc=%08lx\n",Buffer,Mdl,AllocLength);
  203. MdlsLeft--;
  204. *MdlList = Mdl;
  205. MdlList++;
  206. *MdlList = NULL;
  207. NextBuffer = MmGetSystemAddressForMdlSafe(Mdl, LowPagePriority);
  208. if (NextBuffer == NULL) {
  209. s_RxLog.State = RX_LOG_ERROR;
  210. DbgPrint("Couldn't initialize log5");
  211. MmUnlockPages(Mdl);
  212. RxFreePool(Mdl);
  213. RxFreePool(Buffer);
  214. RxFreePool(BaseEntry);
  215. return STATUS_INSUFFICIENT_RESOURCES;
  216. }
  217. SpaceLeft = AllocLength;
  218. }
  219. p->Buffer = NextBuffer;
  220. *((PULONG)NextBuffer) = '###';
  221. NextBuffer += MAX_RX_LOG_ENTRY_SIZE;
  222. SpaceLeft -= MAX_RX_LOG_ENTRY_SIZE;
  223. }
  224. //DbgPrint("Init Log: numeleft,nummleft=%d,%d\n",NumEntriesLeft,MdlsLeft);
  225. p->Buffer = (PUCHAR)IntToPtr(0xf00df00d);
  226. s_RxLog.State = RX_LOG_ENABLED;
  227. s_RxLog.CurrentEntry = EntryLimit-1;
  228. //DbgPrint("Init Log: exit\n");
  229. return((STATUS_SUCCESS));
  230. }
  231. VOID
  232. _RxPauseLog ()
  233. {
  234. KIRQL oldIrql;
  235. KeAcquireSpinLock( &s_RxLog.SpinLock, &oldIrql );
  236. if (s_RxLog.State == RX_LOG_ENABLED) {
  237. s_RxLog.State = RX_LOG_DISABLED;
  238. }
  239. KeReleaseSpinLock( &s_RxLog.SpinLock, oldIrql );
  240. }
  241. VOID
  242. _RxResumeLog()
  243. {
  244. KIRQL oldIrql;
  245. KeAcquireSpinLock( &s_RxLog.SpinLock, &oldIrql );
  246. if (s_RxLog.State == RX_LOG_DISABLED) {
  247. s_RxLog.State = RX_LOG_ENABLED;
  248. }
  249. KeReleaseSpinLock( &s_RxLog.SpinLock, oldIrql );
  250. }
  251. VOID
  252. RxPrintLog (
  253. IN ULONG EntriesToPrint OPTIONAL
  254. )
  255. {
  256. //KIRQL oldIrql;
  257. PRX_LOG_ENTRY_HEADER LogEntry,EntryLimit;
  258. ULONG i=0;
  259. PAGED_CODE();
  260. RxPauseLog();
  261. if (EntriesToPrint==0) {
  262. EntriesToPrint = RX_LOG_BUFFER_SIZE;
  263. }
  264. DbgPrint("\n\n\nLog Print: Entries = %lu \n", EntriesToPrint);
  265. LogEntry = s_RxLog.CurrentEntry-1;
  266. EntryLimit = s_RxLog.EntryLimit;
  267. for (;EntriesToPrint>0;EntriesToPrint--) {
  268. LogEntry++;
  269. if (LogEntry>=EntryLimit) {
  270. LogEntry = s_RxLog.BaseEntry;
  271. }
  272. DbgPrint("%0ld: %s\n",i++,LogEntry->Buffer);
  273. }
  274. RxResumeLog();
  275. }
  276. VOID
  277. _RxLog(char *Format, ...)
  278. {
  279. va_list arglist;
  280. KIRQL oldIrql;
  281. CLONG LogEntryLength = 0;
  282. BOOLEAN fLogNewEntry = TRUE;
  283. PRX_LOG_ENTRY_HEADER LogEntry;
  284. CHAR EntryString[MAX_RX_LOG_ENTRY_SIZE];
  285. PCHAR pEntryString;
  286. CHAR FormatChar;
  287. CHAR FieldString[MAX_RX_LOG_ENTRY_SIZE];
  288. ULONG FieldLength;
  289. char *OriginalFormat = Format;
  290. ULONG BinaryArgs = 0;
  291. ULONG BinaryStringMask = 1; //the first arg is always a string!!!!
  292. //DbgPrint("RxLog: entry\n");
  293. if (s_RxLog.State != RX_LOG_ENABLED) {
  294. return;
  295. }
  296. pEntryString = EntryString;
  297. va_start(arglist, Format);
  298. //DbgBreakPoint();
  299. for (;;) {
  300. // Copy the format string
  301. while ((LogEntryLength < MAX_RX_LOG_ENTRY_SIZE) &&
  302. ((FormatChar = *Format++) != '\0') &&
  303. (FormatChar != '%')) {
  304. if (FormatChar != '\n'){
  305. pEntryString[LogEntryLength++] = FormatChar;
  306. }
  307. }
  308. if ((LogEntryLength < MAX_RX_LOG_ENTRY_SIZE) &&
  309. (FormatChar == '%')) {
  310. if ( (*Format == 'l') || (*Format == 'w') ) {
  311. Format++;
  312. }
  313. switch (*Format++) {
  314. case 'N': //binary placement -- don't try to make it foolproof
  315. {
  316. BinaryArgs++;
  317. *((PULONG)(&EntryString[sizeof(ULONG)])+BinaryArgs) = (ULONG)va_arg(arglist,ULONG);
  318. }
  319. break;
  320. case 'S': //binary placement -- don't try to make it foolproof
  321. {
  322. BinaryArgs++;
  323. BinaryStringMask |= 1<<(BinaryArgs-1);
  324. //DbgPrint("BSM %08lx\n",BinaryStringMask);
  325. *((PULONG)(&EntryString[sizeof(ULONG)])+BinaryArgs) = (ULONG)va_arg(arglist,ULONG);
  326. }
  327. break;
  328. case 'd':
  329. {
  330. // _itoa((LONG)va_arg(arglist,LONG),FieldString,10);
  331. // FieldLength = strlen(FieldString);// + 1;
  332. // if ((LogEntryLength + FieldLength) < MAX_RX_LOG_ENTRY_SIZE) {
  333. // strcpy(&pEntryString[LogEntryLength],FieldString);
  334. // LogEntryLength += FieldLength;
  335. // //pEntryString[LogEntryLength - 1] = ' ';
  336. // }
  337. LONG l = (LONG)va_arg(arglist,LONG);
  338. if ((LogEntryLength + 5) < MAX_RX_LOG_ENTRY_SIZE) {
  339. pEntryString[LogEntryLength++] = 0x5;
  340. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>0));
  341. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>8));
  342. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>16));
  343. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>24));
  344. }
  345. }
  346. break;
  347. case 'c':
  348. pEntryString[LogEntryLength++] = (CHAR)va_arg(arglist,char);
  349. break;
  350. case 'x':
  351. {
  352. // _itoa((LONG)va_arg(arglist,LONG),FieldString,16);
  353. // FieldLength = strlen(FieldString);// + 1;
  354. // if ((LogEntryLength + FieldLength) < MAX_RX_LOG_ENTRY_SIZE) {
  355. // strcpy(&pEntryString[LogEntryLength],FieldString);
  356. // LogEntryLength += FieldLength;
  357. // //pEntryString[LogEntryLength - 1] = ' ';
  358. // }
  359. LONG l = (LONG)va_arg(arglist,LONG);
  360. if ((LogEntryLength + 5) < MAX_RX_LOG_ENTRY_SIZE) {
  361. pEntryString[LogEntryLength++] = 0x4;
  362. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>0));
  363. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>8));
  364. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>16));
  365. pEntryString[LogEntryLength++] = (UCHAR)(0xff&(l>>24));
  366. }
  367. }
  368. break;
  369. case 's':
  370. {
  371. PCHAR pString = &pEntryString[LogEntryLength];
  372. PCHAR pArg = (PCHAR)va_arg(arglist, PCHAR);
  373. ASSERT(pArg!=NULL);
  374. FieldLength = strlen(pArg);// + 1;
  375. if ((LogEntryLength + FieldLength) < MAX_RX_LOG_ENTRY_SIZE) {
  376. strcpy(pString,pArg);
  377. LogEntryLength += FieldLength;
  378. //pEntryString[LogEntryLength - 1] = ' ';
  379. }
  380. }
  381. break;
  382. case 'Z':
  383. {
  384. PCHAR pString = &pEntryString[LogEntryLength];
  385. PUNICODE_STRING pArg = (PUNICODE_STRING)va_arg(arglist, PUNICODE_STRING);
  386. PWCHAR Buffer;
  387. ULONG Length;
  388. //this really only works for ascii strings in unicode......
  389. ASSERT(pArg!=NULL);
  390. Buffer = pArg->Buffer;
  391. Length = pArg->Length;
  392. //DbgPrint("yaya=%08lx,%08lx,%08lx\n",pArg,Buffer,Length);
  393. for (;Length>0;Length-=sizeof(WCHAR)) {
  394. if (LogEntryLength < MAX_RX_LOG_ENTRY_SIZE) {
  395. pEntryString[LogEntryLength++] = (UCHAR)(*Buffer++);
  396. } else {
  397. break;
  398. }
  399. }
  400. //DbgBreakPoint();
  401. }
  402. break;
  403. default:
  404. fLogNewEntry = FALSE;
  405. break;
  406. }
  407. } else {
  408. break;
  409. }
  410. }
  411. va_end(arglist);
  412. if (BinaryArgs) {
  413. EntryString[0] = '#';
  414. EntryString[1] = '>';
  415. EntryString[2] = '0'+(UCHAR)BinaryArgs;
  416. EntryString[3] = 0;
  417. *((PULONG)(&EntryString[sizeof(ULONG)])) = BinaryStringMask;
  418. LogEntryLength = MAX_RX_LOG_ENTRY_SIZE;
  419. }
  420. KeAcquireSpinLock( &s_RxLog.SpinLock, &oldIrql );
  421. if (fLogNewEntry) {
  422. s_RxLog.NumberOfLogWriteAttempts++;
  423. LogEntry = RxGetNextLogEntry();
  424. } else {
  425. s_RxLog.NumberOfEntriesIgnored++;
  426. DbgPrint("RxLog: Entry exceeds max size, not recorded <%s>\n",OriginalFormat);
  427. if (s_RxLog.NumberOfEntriesIgnored==1) {
  428. //DbgBreakPoint();
  429. }
  430. }
  431. KeReleaseSpinLock( &s_RxLog.SpinLock, oldIrql );
  432. if (fLogNewEntry) {
  433. BOOLEAN OutOfBounds = ((LogEntry<s_RxLog.BaseEntry) || (LogEntry>=s_RxLog.EntryLimit));
  434. if (OutOfBounds) {
  435. DbgPrint("RxLog: wrap logic has fail.....log disabled\n");
  436. s_RxLog.State = RX_LOG_DISABLED;
  437. } else {
  438. if (LogEntryLength >= MAX_RX_LOG_ENTRY_SIZE) {
  439. LogEntryLength = MAX_RX_LOG_ENTRY_SIZE;
  440. if (BinaryArgs == 0) {
  441. pEntryString[MAX_RX_LOG_ENTRY_SIZE-1] = 0;
  442. }
  443. } else {
  444. pEntryString[LogEntryLength++] = 0;
  445. }
  446. RtlCopyMemory(LogEntry->Buffer,pEntryString,LogEntryLength);
  447. }
  448. }
  449. }
  450. #define RxToUpper(CH) ((CH)&~('A'^'a'))
  451. #define RxIsLetter(CH) ((RxToUpper(CH)>='A') && (RxToUpper(CH)<='Z'))
  452. #define RxIsDigit(CH) (((CH)>='0')&&((CH)<='9'))
  453. VOID
  454. RxDebugControlCommand (
  455. IN char *ControlString
  456. )
  457. /*
  458. This routine manipulates the print and log levels and the breakpoint masks. the format is
  459. AAAAA+AAAAA+AAAAA+AAAAA.....
  460. where each AAAAA == <+-!>*<Letter>*<digit>*.
  461. <letter>* designates a control name.....only enuff to disambiguate is needed.
  462. any + turns on tracing globally
  463. any % turns on tracing globally RIGHT NOW!
  464. any - turns off tracing globally
  465. for 0 !s, it means: for the control <letter>*, set the printlevel to <digit>*
  466. for 1 !s, it means: for the control <letter>* set breakmask bit <digit>*. 0 means all bits
  467. for 2 !s, it means: for the control <letter>* clear breakmask bit <digit>*. 0 means all bits
  468. THIS STUFF (I.E. THE ! STUFF) IS ACTUALLY IMPLEMENTED IN RXTRACE.C
  469. @ means printlog
  470. @@ means pauselog
  471. @@@ means resumelog
  472. @@@@ means initialize
  473. @@@@@ means setup to debug by turning off printing
  474. more than @@@@@ means banner
  475. E.G. cle0+clo0+cre1000+!devf3 sets disables printing for cleanup and close, sets the printlevel
  476. for create to 1000, and enables the third bit of the breakmask for devfcb.
  477. the letter string is upcased automatically.
  478. There is usually one control for each file but some controls control stuff from multiple
  479. files (like dispatch)
  480. */
  481. {
  482. char namebuf[16], numbuf[16], *p, *q, *c;
  483. //long i;
  484. long level,pointcount,atsigncount;
  485. //DEBUG_TRACE_CONTROLS control;
  486. //ASSERTMSG("Here in debug command parser!\n",FALSE);
  487. RxDbgTrace( 0, (DEBUG_TRACE_ALWAYS), ("RxDebugTraceControl %s!!\n", ControlString));
  488. if (!ControlString)
  489. {
  490. return;
  491. }
  492. for (c = ControlString;;) {
  493. if (*c == 0) break;
  494. p=namebuf;q=numbuf; atsigncount=pointcount = 0;
  495. for (;(*c!=0)&&!RxIsLetter(*c)&&!RxIsDigit(*c); c++){ //skip to a letter or digit
  496. if (*c == '!') {
  497. pointcount++;
  498. }
  499. if (*c == '@') {
  500. atsigncount++;
  501. }
  502. #if RDBSSTRACE
  503. if (*c == '+') {
  504. RxNextGlobalTraceSuppress = FALSE;
  505. }
  506. if (*c == '%') {
  507. RxGlobalTraceSuppress = FALSE;
  508. }
  509. if (*c == '-') {
  510. RxNextGlobalTraceSuppress = TRUE;
  511. }
  512. #endif //RDBSSTRACE
  513. }
  514. for (p=namebuf;(*c!=0)&&RxIsLetter(*c); *p++=RxToUpper(*c++) ) ; //copy letters
  515. for (level=0,q=numbuf;(*c!=0)&&RxIsDigit(*c); *q++=*c++){ //copy digits
  516. level = 10*level+((*c)-'0');
  517. }
  518. *p = *q = (char)0;
  519. {if (atsigncount>0) {
  520. if (atsigncount==1) {
  521. RxPrintLog(level);
  522. } else if (atsigncount == 2) {
  523. RxPauseLog();
  524. } else if (atsigncount == 3) {
  525. RxResumeLog();
  526. } else if (atsigncount == 4) {
  527. RxInitializeLog();
  528. } else if (atsigncount == 5){
  529. #if RDBSSTRACE
  530. RxDebugTraceZeroAllPrintLevels();
  531. RxDbgTraceFindControlPoint((DEBUG_TRACE_UNWIND))->PrintLevel = 10000;
  532. RxDbgTraceFindControlPoint((DEBUG_TRACE_READ))->PrintLevel = 10000;
  533. RxDbgTraceFindControlPoint((DEBUG_TRACE_RXCONTX))->PrintLevel = 1000;
  534. RxDbgTraceFindControlPoint((DEBUG_TRACE_DISPATCH))->PrintLevel = 1000;
  535. RxDbgTraceFindControlPoint((DEBUG_TRACE_CREATE))->PrintLevel = 10000;
  536. RxDbgTraceFindControlPoint((DEBUG_TRACE_CLEANUP))->PrintLevel = 10000;
  537. RxDbgTraceFindControlPoint((DEBUG_TRACE_CLOSE))->PrintLevel = 10000;
  538. #endif
  539. } else {
  540. #if RDBSSTRACE
  541. RxDbgTrace(0, (DEBUG_TRACE_ALWAYS), ("\n\n\n\n\n %s %s\n\n\n\n\n", namebuf, numbuf));
  542. #endif
  543. }
  544. continue;
  545. }}
  546. #if RDBSSTRACE
  547. if (((*namebuf)==0||(*numbuf)==0)) {
  548. continue;
  549. }
  550. RxDebugTraceDebugCommand(namebuf,level,pointcount);
  551. #endif
  552. }
  553. return;
  554. }
  555. #ifdef DBG
  556. VOID
  557. RxpTrackReference(
  558. ULONG TraceType,
  559. PCHAR FileName,
  560. ULONG Line,
  561. PVOID pInstance)
  562. {
  563. if (REF_TRACING_ON(TraceType)) {
  564. ULONG RefCount;
  565. PCHAR pTypeName,pLogTypeName;
  566. switch (TraceType) {
  567. case RDBSS_REF_TRACK_SRVCALL :
  568. pTypeName = "SrvCall";
  569. pLogTypeName = "SC";
  570. RefCount = ((PSRV_CALL)pInstance)->NodeReferenceCount;
  571. RxWmiLog(SRVCALL,RxRefSrvcall,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  572. break;
  573. case RDBSS_REF_TRACK_NETROOT :
  574. pTypeName = "NetRoot";
  575. pLogTypeName = "NR";
  576. RefCount = ((PNET_ROOT)pInstance)->NodeReferenceCount;
  577. RxWmiLog(NETROOT,RxRefNetRoot,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  578. break;
  579. case RDBSS_REF_TRACK_VNETROOT:
  580. pTypeName = "VNetRoot";
  581. pLogTypeName = "VN";
  582. RefCount = ((PV_NET_ROOT)pInstance)->NodeReferenceCount;
  583. RxWmiLog(VNETROOT,RxRefVNetRoot,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  584. break;
  585. case RDBSS_REF_TRACK_NETFOBX :
  586. pTypeName = "NetFobx";
  587. pLogTypeName = "FO";
  588. RefCount = ((PFOBX)pInstance)->NodeReferenceCount;
  589. RxWmiLog(FOBX,RxRefFobx,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  590. break;
  591. case RDBSS_REF_TRACK_NETFCB :
  592. pTypeName = "NetFcb";
  593. pLogTypeName = "FC";
  594. RefCount = ((PFCB)pInstance)->NodeReferenceCount;
  595. RxWmiLog(FCB,RxRefFcb,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  596. break;
  597. case RDBSS_REF_TRACK_SRVOPEN :
  598. pTypeName = "SrvOpen";
  599. pLogTypeName = "SO";
  600. RefCount = ((PSRV_OPEN)pInstance)->NodeReferenceCount;
  601. RxWmiLog(SRVOPEN,RxRefSrvOpen,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  602. break;
  603. default:
  604. DbgPrint("Invalid Node Type for referencing\n");
  605. //DbgBreakPoint();
  606. return;
  607. }
  608. if (RdbssReferenceTracingValue & RX_LOG_REF_TRACKING) {
  609. RxLog(("Ref.%s %lx %ld %lx %ld->%ld",pLogTypeName,pInstance,Line,FileName,RefCount,RefCount+1));
  610. }
  611. if (RdbssReferenceTracingValue & RX_PRINT_REF_TRACKING) {
  612. DbgPrint("Reference %s %lx %ld %s\n",pTypeName,pInstance,Line,FileName);
  613. }
  614. }
  615. }
  616. BOOLEAN
  617. RxpTrackDereference(
  618. ULONG TraceType,
  619. PCHAR FileName,
  620. ULONG Line,
  621. PVOID pInstance)
  622. {
  623. PAGED_CODE();
  624. if (REF_TRACING_ON(TraceType)) {
  625. PCHAR pTypeName,pLogTypeName;
  626. ULONG RefCount;
  627. switch (TraceType) {
  628. case RDBSS_REF_TRACK_SRVCALL :
  629. pTypeName = "SrvCall";
  630. pLogTypeName = "SC";
  631. RefCount = ((PSRV_CALL)pInstance)->NodeReferenceCount;
  632. RxWmiLog(SRVCALL,RxDerefSrvcall,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  633. break;
  634. case RDBSS_REF_TRACK_NETROOT :
  635. pTypeName = "NetRoot";
  636. pLogTypeName = "NR";
  637. RefCount = ((PNET_ROOT)pInstance)->NodeReferenceCount;
  638. RxWmiLog(NETROOT,RxDerefNetRoot,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  639. break;
  640. case RDBSS_REF_TRACK_VNETROOT:
  641. pTypeName = "VNetRoot";
  642. pLogTypeName = "VN";
  643. RefCount = ((PV_NET_ROOT)pInstance)->NodeReferenceCount;
  644. RxWmiLog(VNETROOT,RxDerefVNetRoot,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  645. break;
  646. case RDBSS_REF_TRACK_NETFOBX :
  647. pTypeName = "NetFobx";
  648. pLogTypeName = "FO";
  649. RefCount = ((PFOBX)pInstance)->NodeReferenceCount;
  650. RxWmiLog(FOBX,RxDerefFobx,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  651. break;
  652. case RDBSS_REF_TRACK_NETFCB :
  653. pTypeName = "NetFcb";
  654. pLogTypeName = "FC";
  655. RefCount = ((PFCB)pInstance)->NodeReferenceCount;
  656. RxWmiLog(FCB,RxDerefFcb,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  657. break;
  658. case RDBSS_REF_TRACK_SRVOPEN :
  659. pTypeName = "SrvOpen";
  660. pLogTypeName = "SO";
  661. RefCount = ((PSRV_OPEN)pInstance)->NodeReferenceCount;
  662. RxWmiLog(SRVOPEN,RxDerefSrvOpen,LOGPTR(pInstance)LOGULONG(RefCount)LOGULONG(Line)LOGARSTR(FileName));
  663. break;
  664. default:
  665. DbgPrint("Invalid Node Type for referencing\n");
  666. //DbgBreakPoint();
  667. return TRUE;
  668. }
  669. if (RdbssReferenceTracingValue & RX_LOG_REF_TRACKING) {
  670. RxLog(("Deref.%s %lx %ld %lx %ld->%ld",pLogTypeName,pInstance,Line,FileName,RefCount,RefCount-1));
  671. }
  672. if (RdbssReferenceTracingValue & RX_PRINT_REF_TRACKING) {
  673. DbgPrint("Dereference %s %lx %ld %s\n",pTypeName,pInstance,Line,FileName);
  674. }
  675. }
  676. return TRUE;
  677. }
  678. #endif