ReactOS  0.4.15-dev-1201-gb2cf5a4
gdidbg.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS win32 kernel mode subsystem
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: win32ss/gdi/ntgdi/gdidbg.c
5  * PURPOSE: Special debugging functions for GDI
6  * PROGRAMMERS: Timo Kreuzer
7  */
8 
11 #if DBG
12 #include <win32k.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 extern ULONG gulFirstFree;
17 extern ULONG gulFirstUnused;
18 extern PENTRY gpentHmgr;
19 
20 ULONG gulLogUnique = 0;
21 
22 /* Note: the following values need to be sorted */
23 DBG_CHANNEL DbgChannels[DbgChCount] = {
24  {L"EngBlt", DbgChEngBlt},
25  {L"EngBrush", DbgChEngBrush},
26  {L"EngClip", DbgChEngClip},
27  {L"EngCursor", DbgChEngCursor},
28  {L"EngDev", DbgChEngDev},
29  {L"EngErr", DbgChEngErr},
30  {L"EngEvent", DbgChEngEvent},
31  {L"EngGrad", DbgChEngGrad},
32  {L"EngLDev", DbgChEngLDev},
33  {L"EngLine", DbgChEngLine},
34  {L"EngMapping", DbgChEngMapping},
35  {L"EngPDev", DbgChEngPDev},
36  {L"EngSurface", DbgChEngSurface},
37  {L"EngWnd", DbgChEngWnd},
38  {L"EngXlate", DbgChEngXlate},
39  {L"GdiBitmap", DbgChGdiBitmap},
40  {L"GdiBlt", DbgChGdiBlt},
41  {L"GdiBrush", DbgChGdiBrush},
42  {L"GdiClipRgn", DbgChGdiClipRgn},
43  {L"GdiCoord", DbgChGdiCoord},
44  {L"GdiDC", DbgChGdiDC},
45  {L"GdiDCAttr", DbgChGdiDCAttr},
46  {L"GdiDCState", DbgChGdiDCState},
47  {L"GdiDev", DbgChGdiDev},
48  {L"GdiDib", DbgChGdiDib},
49  {L"GdiFont", DbgChGdiFont},
50  {L"GdiLine", DbgChGdiLine},
51  {L"GdiObj", DbgChGdiObj},
52  {L"GdiPalette", DbgChGdiPalette},
53  {L"GdiPath", DbgChGdiPath},
54  {L"GdiPen", DbgChGdiPen},
55  {L"GdiPool", DbgChGdiPool},
56  {L"GdiRgn", DbgChGdiRgn},
57  {L"GdiText", DbgChGdiText},
58  {L"GdiXFormObj", DbgChGdiXFormObj},
59  {L"UserAccel", DbgChUserAccel},
60  {L"UserCallback", DbgChUserCallback},
61  {L"UserCallProc", DbgChUserCallProc},
62  {L"UserCaret", DbgChUserCaret},
63  {L"UserClass", DbgChUserClass},
64  {L"UserClipbrd", DbgChUserClipbrd},
65  {L"UserCsr", DbgChUserCsr},
66  {L"UserDce", DbgChUserDce},
67  {L"UserDefwnd", DbgChUserDefwnd},
68  {L"UserDesktop", DbgChUserDesktop},
69  {L"UserDisplay",DbgChUserDisplay},
70  {L"UserEvent", DbgChUserEvent},
71  {L"UserFocus", DbgChUserFocus},
72  {L"UserHook", DbgChUserHook},
73  {L"UserHotkey", DbgChUserHotkey},
74  {L"UserIcon", DbgChUserIcon},
75  {L"UserInput", DbgChUserInput},
76  {L"UserKbd", DbgChUserKbd},
77  {L"UserKbdLayout", DbgChUserKbdLayout},
78  {L"UserMenu", DbgChUserMenu},
79  {L"UserMetric", DbgChUserMetric},
80  {L"UserMisc", DbgChUserMisc},
81  {L"UserMonitor", DbgChUserMonitor},
82  {L"UserMsg", DbgChUserMsg},
83  {L"UserMsgQ", DbgChUserMsgQ},
84  {L"UserObj", DbgChUserObj},
85  {L"UserPainting", DbgChUserPainting},
86  {L"UserProcess", DbgChUserProcess},
87  {L"UserProp", DbgChUserProp},
88  {L"UserScrollbar", DbgChUserScrollbar},
89  {L"UserShutdown", DbgChUserShutdown},
90  {L"UserSysparams", DbgChUserSysparams},
91  {L"UserTimer", DbgChUserTimer},
92  {L"UserThread", DbgChUserThread},
93  {L"UserWinpos", DbgChUserWinpos},
94  {L"UserWinsta", DbgChUserWinsta},
95  {L"UserWnd", DbgChUserWnd}
96 };
97 
98 ULONG
99 NTAPI
101  _Out_writes_(cFramesToCapture) PVOID* ppvFrames,
102  _In_ ULONG cFramesToSkip,
103  _In_ ULONG cFramesToCapture)
104 {
105  ULONG cFrameCount;
106  PVOID apvTemp[30];
107  NT_ASSERT(cFramesToCapture <= _countof(apvTemp));
108 
109  /* Zero it out */
110  RtlZeroMemory(ppvFrames, cFramesToCapture * sizeof(PVOID));
111 
112  /* Capture kernel stack */
113  cFrameCount = RtlWalkFrameChain(apvTemp, _countof(apvTemp), 0);
114 
115  /* If we should skip more than we have, we are done */
116  if (cFramesToSkip > cFrameCount)
117  return 0;
118 
119  /* Copy, but skip frames */
120  cFrameCount -= cFramesToSkip;
121  cFrameCount = min(cFrameCount, cFramesToCapture);
122  RtlCopyMemory(ppvFrames, &apvTemp[cFramesToSkip], cFrameCount * sizeof(PVOID));
123 
124  /* Check if there is still space left */
125  if (cFrameCount < cFramesToCapture)
126  {
127  /* Capture user stack */
128  cFrameCount += RtlWalkFrameChain(&ppvFrames[cFrameCount],
129  cFramesToCapture - cFrameCount,
130  1);
131  }
132 
133  return cFrameCount;
134 }
135 
136 #if DBG_ENABLE_GDIOBJ_BACKTRACES
137 
138 static
139 BOOL
140 CompareBacktraces(
141  USHORT idx1,
142  USHORT idx2)
143 {
144  POBJ pobj1, pobj2;
145  ULONG iLevel;
146 
147  /* Get the objects */
148  pobj1 = gpentHmgr[idx1].einfo.pobj;
149  pobj2 = gpentHmgr[idx2].einfo.pobj;
150 
151  /* Loop all stack levels */
152  for (iLevel = 0; iLevel < GDI_OBJECT_STACK_LEVELS; iLevel++)
153  {
154  /* If one level doesn't match we are done */
155  if (pobj1->apvBackTrace[iLevel] != pobj2->apvBackTrace[iLevel])
156  {
157  return FALSE;
158  }
159  }
160 
161  return TRUE;
162 }
163 
164 typedef struct
165 {
166  USHORT idx;
167  USHORT iCount;
168 } GDI_DBG_HANDLE_BT;
169 
170 VOID
171 NTAPI
172 DbgDumpGdiHandleTableWithBT(void)
173 {
174  static BOOL bLeakReported = FALSE;
175  ULONG idx, j;
176  BOOL bAlreadyPresent;
177  GDI_DBG_HANDLE_BT aBacktraceTable[GDI_DBG_MAX_BTS];
178  USHORT iCount;
179  KIRQL OldIrql;
180  POBJ pobj;
181  ULONG iLevel, ulObj;
182 
183  /* Only report once */
184  if (bLeakReported)
185  {
186  DPRINT1("GDI handle abusers already reported!\n");
187  return;
188  }
189 
190  bLeakReported = TRUE;
191  DPRINT1("Reporting GDI handle abusers:\n");
192 
193  /* Zero out the table */
194  RtlZeroMemory(aBacktraceTable, sizeof(aBacktraceTable));
195 
196  /* We've got serious business to do */
198 
199  /* Step through GDI handle table and find out who our culprit is... */
201  {
202  /* If the handle is free, continue */
203  if (gpentHmgr[idx].einfo.pobj == 0) continue;
204 
205  /* Check if this backtrace is already covered */
206  bAlreadyPresent = FALSE;
207  for (j = RESERVE_ENTRIES_COUNT; j < idx; j++)
208  {
209  if (CompareBacktraces(idx, j))
210  {
211  bAlreadyPresent = TRUE;
212  break;
213  }
214  }
215 
216  if (bAlreadyPresent) continue;
217 
218  /* We don't have this BT yet, count how often it is present */
219  iCount = 1;
220  for (j = idx + 1; j < GDI_HANDLE_COUNT; j++)
221  {
222  if (CompareBacktraces(idx, j))
223  {
224  iCount++;
225  }
226  }
227 
228  /* Now add this backtrace */
229  for (j = 0; j < GDI_DBG_MAX_BTS; j++)
230  {
231  /* Insert it below the next smaller count */
232  if (aBacktraceTable[j].iCount < iCount)
233  {
234  /* Check if there are entries above */
235  if (j < GDI_DBG_MAX_BTS - 1)
236  {
237  /* Move the following entries up by 1 */
238  RtlMoveMemory(&aBacktraceTable[j],
239  &aBacktraceTable[j + 1],
240  GDI_DBG_MAX_BTS - j - 1);
241  }
242 
243  /* Set this entry */
244  aBacktraceTable[j].idx = idx;
245  aBacktraceTable[j].iCount = iCount;
246 
247  /* We are done here */
248  break;
249  }
250  }
251  }
252 
253  /* Print the worst offenders... */
254  DbgPrint("Count Handle Backtrace\n");
255  DbgPrint("------------------------------------------------\n");
256  for (j = 0; j < GDI_DBG_MAX_BTS; j++)
257  {
258  idx = aBacktraceTable[j].idx;
259  if (idx == 0)
260  break;
261 
262  ulObj = ((ULONG)gpentHmgr[idx].FullUnique << 16) | idx;
263  pobj = gpentHmgr[idx].einfo.pobj;
264 
265  DbgPrint("%5d %08lx ", aBacktraceTable[j].iCount, ulObj);
266  for (iLevel = 0; iLevel < GDI_OBJECT_STACK_LEVELS; iLevel++)
267  {
268  DbgPrint("%p,", pobj->apvBackTrace[iLevel]);
269  }
270  DbgPrint("\n");
271  }
272 
273  __debugbreak();
274 
276 }
277 
278 #endif /* DBG_ENABLE_GDIOBJ_BACKTRACES */
279 
280 #if DBG
281 
282 BOOL
283 NTAPI
285 {
286  ULONG i, nDeleted = 0, nFree = 0, nUsed = 0;
287  PGDI_TABLE_ENTRY pEntry;
288  BOOL r = 1;
289 
291 
292  /* FIXME: Check reserved entries */
293 
294  /* Now go through the deleted objects */
295  i = gulFirstFree & 0xffff;
296  while (i)
297  {
298  pEntry = &GdiHandleTable->Entries[i];
299  if (i >= GDI_HANDLE_COUNT)
300  {
301  DPRINT1("nDeleted=%lu\n", nDeleted);
302  ASSERT(FALSE);
303  }
304 
305  nDeleted++;
306 
307  /* Check the entry */
308  if ((pEntry->Type & GDI_ENTRY_BASETYPE_MASK) != 0)
309  {
310  r = 0;
311  DPRINT1("Deleted Entry has a type != 0\n");
312  }
313  if ((ULONG_PTR)pEntry->KernelData >= GDI_HANDLE_COUNT)
314  {
315  r = 0;
316  DPRINT1("Deleted entries KernelPointer too big\n");
317  }
318  if (pEntry->UserData != NULL)
319  {
320  r = 0;
321  DPRINT1("Deleted entry has UserData != 0\n");
322  }
323  if (pEntry->ProcessId != 0)
324  {
325  r = 0;
326  DPRINT1("Deleted entry has ProcessId != 0\n");
327  }
328 
329  i = (ULONG_PTR)pEntry->KernelData & 0xffff;
330  };
331 
332  for (i = gulFirstUnused;
334  i++)
335  {
336  pEntry = &GdiHandleTable->Entries[i];
337 
338  if ((pEntry->Type) != 0)
339  {
340  r = 0;
341  DPRINT1("Free Entry has a type != 0\n");
342  }
343  if ((ULONG_PTR)pEntry->KernelData != 0)
344  {
345  r = 0;
346  DPRINT1("Free entries KernelPointer != 0\n");
347  }
348  if (pEntry->UserData != NULL)
349  {
350  r = 0;
351  DPRINT1("Free entry has UserData != 0\n");
352  }
353  if (pEntry->ProcessId != 0)
354  {
355  r = 0;
356  DPRINT1("Free entry has ProcessId != 0\n");
357  }
358  nFree++;
359  }
360 
362  {
363  HGDIOBJ Handle;
364  ULONG Type;
365 
366  pEntry = &GdiHandleTable->Entries[i];
367  Type = pEntry->Type;
369 
371  {
372  if (pEntry->KernelData == NULL)
373  {
374  r = 0;
375  DPRINT1("Used entry has KernelData == 0\n");
376  }
377  else if (pEntry->KernelData <= MmHighestUserAddress)
378  {
379  r = 0;
380  DPRINT1("Used entry invalid KernelData\n");
381  }
382  else if (((POBJ)(pEntry->KernelData))->hHmgr != Handle)
383  {
384  r = 0;
385  DPRINT1("Used entry %lu, has invalid hHmg %p (expected: %p)\n",
386  i, ((POBJ)(pEntry->KernelData))->hHmgr, Handle);
387  }
388  nUsed++;
389  }
390  }
391 
392  if (RESERVE_ENTRIES_COUNT + nDeleted + nFree + nUsed != GDI_HANDLE_COUNT)
393  {
394  r = 0;
395  DPRINT1("Number of all entries incorrect: RESERVE_ENTRIES_COUNT = %lu, nDeleted = %lu, nFree = %lu, nUsed = %lu\n",
396  RESERVE_ENTRIES_COUNT, nDeleted, nFree, nUsed);
397  }
398 
400 
401  return r;
402 }
403 
404 #endif /* DBG */
405 
406 
407 #if DBG_ENABLE_EVENT_LOGGING
408 
409 VOID
410 NTAPI
411 DbgLogEvent(PSLIST_HEADER pslh, LOG_EVENT_TYPE nEventType, LPARAM lParam)
412 {
413  PLOGENTRY pLogEntry;
414 
415  /* Log a maximum of 100 events */
416  if (QueryDepthSList(pslh) >= 1000) return;
417 
418  /* Allocate a logentry */
419  pLogEntry = EngAllocMem(0, sizeof(LOGENTRY), 'golG');
420  if (!pLogEntry) return;
421 
422  /* Set type */
423  pLogEntry->nEventType = nEventType;
424  pLogEntry->ulUnique = InterlockedIncrement((LONG*)&gulLogUnique);
425  pLogEntry->dwProcessId = HandleToUlong(PsGetCurrentProcessId());
426  pLogEntry->dwThreadId = HandleToUlong(PsGetCurrentThreadId());
427  pLogEntry->lParam = lParam;
428 
429  /* Capture a backtrace */
430  DbgCaptureStackBackTace(pLogEntry->apvBackTrace, 1, 20);
431 
432  switch (nEventType)
433  {
434  case EVENT_ALLOCATE:
435  case EVENT_CREATE_HANDLE:
436  case EVENT_REFERENCE:
437  case EVENT_DEREFERENCE:
438  case EVENT_LOCK:
439  case EVENT_UNLOCK:
440  case EVENT_DELETE:
441  case EVENT_FREE:
442  case EVENT_SET_OWNER:
443  default:
444  break;
445  }
446 
447  /* Push it on the list */
448  InterlockedPushEntrySList(pslh, &pLogEntry->sleLink);
449 }
450 
451 #define REL_ADDR(va) ((ULONG_PTR)va - (ULONG_PTR)&__ImageBase)
452 
453 VOID
454 NTAPI
455 DbgPrintEvent(PLOGENTRY pLogEntry)
456 {
457  PSTR pstr;
458 
459  switch (pLogEntry->nEventType)
460  {
461  case EVENT_ALLOCATE: pstr = "Allocate"; break;
462  case EVENT_CREATE_HANDLE: pstr = "CreatHdl"; break;
463  case EVENT_REFERENCE: pstr = "Ref"; break;
464  case EVENT_DEREFERENCE: pstr = "Deref"; break;
465  case EVENT_LOCK: pstr = "Lock"; break;
466  case EVENT_UNLOCK: pstr = "Unlock"; break;
467  case EVENT_DELETE: pstr = "Delete"; break;
468  case EVENT_FREE: pstr = "Free"; break;
469  case EVENT_SET_OWNER: pstr = "SetOwner"; break;
470  default: pstr = "Unknown"; break;
471  }
472 
473  DbgPrint("[%lu] %03x:%03x %.8s val=%p <%lx,%lx,%lx,%lx>\n",
474  pLogEntry->ulUnique,
475  pLogEntry->dwProcessId,
476  pLogEntry->dwThreadId,
477  pstr,
478  (PVOID)pLogEntry->lParam,
479  REL_ADDR(pLogEntry->apvBackTrace[2]),
480  REL_ADDR(pLogEntry->apvBackTrace[3]),
481  REL_ADDR(pLogEntry->apvBackTrace[4]),
482  REL_ADDR(pLogEntry->apvBackTrace[5]));
483 }
484 
485 VOID
486 NTAPI
487 DbgDumpEventList(PSLIST_HEADER pslh)
488 {
489  PSLIST_ENTRY psle;
490  PLOGENTRY pLogEntry;
491 
492  while ((psle = InterlockedPopEntrySList(pslh)))
493  {
494  pLogEntry = CONTAINING_RECORD(psle, LOGENTRY, sleLink);
495  DbgPrintEvent(pLogEntry);
496  }
497 }
498 
499 VOID
500 NTAPI
501 DbgCleanupEventList(PSLIST_HEADER pslh)
502 {
503  PSLIST_ENTRY psle;
504  PLOGENTRY pLogEntry;
505 
506  while ((psle = InterlockedPopEntrySList(pslh)))
507  {
508  pLogEntry = CONTAINING_RECORD(psle, LOGENTRY, sleLink);
509  EngFreeMem(pLogEntry);
510  }
511 }
512 
513 #endif /* DBG_ENABLE_EVENT_LOGGING */
514 
515 #if 1 || DBG_ENABLE_SERVICE_HOOKS
516 
517 VOID
518 NTAPI
520 {
521  ULONG i;
522 
524  {
525  PENTRY pentry = &gpentHmgr[i];
526 
527  if (pentry->Objt)
528  {
529  POBJ pobj = pentry->einfo.pobj;
530  if (pobj->cExclusiveLock > 0)
531  {
532  DPRINT1("Locked object: %lx, type = %lx. allocated from:\n",
533  i, pentry->Objt);
534  DBG_DUMP_EVENT_LIST(&pobj->slhLog);
535  }
536  }
537  }
538 }
539 
540 void
541 NTAPI
542 GdiDbgPreServiceHook(ULONG ulSyscallId, PULONG_PTR pulArguments)
543 {
545  if (pti && pti->cExclusiveLocks != 0)
546  {
547  DbgPrint("FATAL: Win32DbgPreServiceHook(0x%lx): There are %lu exclusive locks!\n",
548  ulSyscallId, pti->cExclusiveLocks);
550  ASSERT(FALSE);
551  }
552 
553 }
554 
555 ULONG_PTR
556 NTAPI
557 GdiDbgPostServiceHook(ULONG ulSyscallId, ULONG_PTR ulResult)
558 {
560  if (pti && pti->cExclusiveLocks != 0)
561  {
562  DbgPrint("FATAL: Win32DbgPostServiceHook(0x%lx): There are %lu exclusive locks!\n",
563  ulSyscallId, pti->cExclusiveLocks);
565  ASSERT(FALSE);
566  }
567  return ulResult;
568 }
569 
570 #endif /* DBG_ENABLE_SERVICE_HOOKS */
571 
572 
574 QueryEnvironmentVariable(PUNICODE_STRING Name,
576 {
578  PWSTR wcs;
580  PWSTR val;
581  PPEB Peb;
583 
584  /* Ugly HACK for ReactOS system threads */
585  if(!NtCurrentTeb())
586  {
588  }
589 
590  Peb = NtCurrentPeb();
591 
592  if (Peb == NULL)
593  {
595  }
596 
598 
599  if (Environment == NULL)
600  {
602  }
603 
604  Value->Length = 0;
605 
606  wcs = Environment;
607  while (*wcs)
608  {
609  var.Buffer = wcs++;
610  wcs = wcschr(wcs, L'=');
611  if (wcs == NULL)
612  {
613  wcs = var.Buffer + wcslen(var.Buffer);
614  }
615  if (*wcs)
616  {
617  var.Length = var.MaximumLength = (wcs - var.Buffer) * sizeof(WCHAR);
618  val = ++wcs;
619  wcs += wcslen(wcs);
620 
622  {
623  Value->Length = (wcs - val) * sizeof(WCHAR);
624  if (Value->Length <= Value->MaximumLength)
625  {
626  memcpy(Value->Buffer, val,
627  min(Value->Length + sizeof(WCHAR), Value->MaximumLength));
629  }
630  else
631  {
633  }
634 
635  return(Status);
636  }
637  }
638  wcs++;
639  }
640 
642 }
643 
644 static int __cdecl
645 DbgCompareChannels(const void * a, const void * b)
646 {
647  return wcscmp((WCHAR*)a, ((DBG_CHANNEL*)b)->Name);
648 }
649 
650 static BOOL
651 DbgAddDebugChannel(PPROCESSINFO ppi, WCHAR* channel, WCHAR* level, WCHAR op)
652 {
653  DBG_CHANNEL *ChannelEntry;
654  UINT iLevel, iChannel;
655 
656  /* Special treatment for the "all" channel */
657  if (wcscmp(channel, L"all") == 0)
658  {
659  for (iChannel = 0; iChannel < DbgChCount; iChannel++)
660  {
661  DbgAddDebugChannel(ppi, DbgChannels[iChannel].Name, level, op);
662  }
663  return TRUE;
664  }
665 
666  ChannelEntry = (DBG_CHANNEL*)bsearch(channel,
667  DbgChannels,
668  DbgChCount,
669  sizeof(DBG_CHANNEL),
670  DbgCompareChannels);
671  if(ChannelEntry == NULL)
672  {
673  return FALSE;
674  }
675 
676  iChannel = ChannelEntry->Id;
677  ASSERT(iChannel < DbgChCount);
678 
679  if(level == NULL || *level == L'\0' ||wcslen(level) == 0 )
680  iLevel = MAX_LEVEL;
681  else if(wcsncmp(level, L"err", 3) == 0)
682  iLevel = ERR_LEVEL;
683  else if(wcsncmp(level, L"fixme", 5) == 0)
684  iLevel = FIXME_LEVEL;
685  else if(wcsncmp(level, L"warn", 4) == 0)
686  iLevel = WARN_LEVEL;
687  else if (wcsncmp(level, L"trace", 4) == 0)
688  iLevel = TRACE_LEVEL;
689  else
690  return FALSE;
691 
692  if(op==L'+')
693  {
694  DBG_ENABLE_CHANNEL(ppi, iChannel, iLevel);
695  }
696  else
697  {
698  DBG_DISABLE_CHANNEL(ppi, iChannel, iLevel);
699  }
700 
701  return TRUE;
702 }
703 
704 static BOOL
706 {
707  WCHAR *str, *separator, *c, op;
708 
709  str = Value->Buffer;
710 
711  do
712  {
713  separator = wcschr(str, L',');
714  if(separator != NULL)
715  *separator = L'\0';
716 
717  c = wcschr(str, L'+');
718  if(c == NULL)
719  c = wcschr(str, L'-');
720 
721  if(c != NULL)
722  {
723  op = *c;
724  *c = L'\0';
725  c++;
726 
727  DbgAddDebugChannel(ppi, c, str, op);
728  }
729 
730  str = separator + 1;
731  }while(separator != NULL);
732 
733  return TRUE;
734 }
735 
737 {
738  WCHAR valBuffer[100];
740  UNICODE_STRING Name = RTL_CONSTANT_STRING(L"DEBUGCHANNEL");
742  PPROCESSINFO ppi;
743  BOOL ret;
744 
745  /* Initialize all channels to ERROR */
747  RtlFillMemory( ppi->DbgChannelLevel,
748  sizeof(ppi->DbgChannelLevel),
749  ERR_LEVEL);
750 
751  /* Find DEBUGCHANNEL env var */
752  Value.Buffer = valBuffer;
753  Value.Length = 0;
754  Value.MaximumLength = sizeof(valBuffer);
755  Status = QueryEnvironmentVariable(&Name, &Value);
756 
757  /* It does not exist */
759  {
760  /* There is nothing more to do */
761  return TRUE;
762  }
763 
764  /* If the buffer in the stack is not enough allocate it */
766  {
767  Value.Buffer = ExAllocatePool(PagedPool, Value.MaximumLength);
768  if(Value.Buffer == NULL)
769  {
770  return FALSE;
771  }
772 
773  /* Get the env var again */
774  Status = QueryEnvironmentVariable(&Name, &Value);
775  }
776 
777  /* Check for error */
778  if(!NT_SUCCESS(Status))
779  {
780  if(Value.Buffer != valBuffer)
781  {
782  ExFreePool(Value.Buffer);
783  }
784 
785  return FALSE;
786  }
787 
788  /* Parse the variable */
790 
791  /* Clean up */
792  if(Value.Buffer != valBuffer)
793  {
794  ExFreePool(Value.Buffer);
795  }
796 
797  return ret;
798 }
799 
800 
801 #endif // DBG
802 
803 /* EOF */
const char * var
Definition: shader.c:5666
ULONG NTAPI DbgCaptureStackBackTace(_Out_writes_(cFramesToCapture) PVOID *ppvFrames, _In_ ULONG cFramesToSkip, _In_ ULONG cFramesToCapture)
#define MAX_LEVEL
Definition: cdmake.c:83
GLint level
Definition: gl.h:1546
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:45
PVOID UserData
Definition: gdi.h:6
#define KeRaiseIrql(irql, oldIrql)
Definition: env_spec_w32.h:597
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define KeLowerIrql(oldIrql)
Definition: env_spec_w32.h:602
PPEB Peb
Definition: dllmain.c:27
static const WCHAR separator[]
Definition: asmname.c:65
Type
Definition: Type.h:6
#define DbgParseDebugChannels(val)
Definition: debug.h:120
#define __cdecl
Definition: accygwin.h:79
wchar_t wcs[5]
#define DbgPrint
Definition: loader.c:25
#define TRUE
Definition: types.h:120
#define EngFreeMem
Definition: polytest.cpp:56
uint16_t * PWSTR
Definition: typedefs.h:56
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
UCHAR Objt
Definition: ntgdihdl.h:249
PVOID NTAPI PsGetCurrentThreadWin32Thread(VOID)
Definition: thread.c:805
LONG NTSTATUS
Definition: precomp.h:26
#define HandleToUlong(h)
Definition: basetsd.h:79
struct _BASEOBJECT * pobj
Definition: ntgdihdl.h:234
USHORT cExclusiveLock
Definition: gdiobj.h:45
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1959
HANDLE ProcessId
Definition: gdi.h:4
volatile ULONG gulFirstFree
Definition: gdiobj.c:151
#define QueryDepthSList(SListHead)
Definition: rtlfuncs.h:3402
void __cdecl __debugbreak(void)
Definition: intrin_ppc.h:698
PENTRY gpentHmgr
Definition: gdiobj.c:149
#define DBG_ENABLE_CHANNEL(ppi, ch, level)
Definition: win32kdebug.h:162
PSLIST_ENTRY WINAPI InterlockedPopEntrySList(PSLIST_HEADER ListHead)
Definition: interlocked.c:55
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
IN UCHAR Value
Definition: halp.h:394
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
union _ENTRY::_EINFO einfo
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define _Out_writes_(size)
Definition: no_sal2.h:367
UCHAR KIRQL
Definition: env_spec_w32.h:591
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG cExclusiveLocks
Definition: win32.h:153
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL NTAPI DbgGdiHTIntegrityCheck(VOID)
long LONG
Definition: pedump.c:60
VOID NTAPI DbgDumpLockedGdiHandles(VOID)
#define GDI_ENTRY_BASETYPE_MASK
Definition: ntgdihdl.h:34
unsigned int idx
Definition: utils.c:41
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
LONG_PTR LPARAM
Definition: windef.h:208
PsGetCurrentThreadId
Definition: CrNtStubs.h:7
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
GLuint GLfloat * val
Definition: glext.h:7180
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_In_ HANDLE Handle
Definition: extypes.h:390
#define GdiHandleTable
Definition: win32nt.h:35
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
struct _THREADINFO * PTHREADINFO
Definition: ntwin32.h:6
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RtlFillMemory(Dest, Length, Fill)
Definition: winternl.h:593
#define _countof(array)
Definition: sndvol32.h:68
const GLubyte * c
Definition: glext.h:8905
LONG Type
Definition: gdi.h:5
UINT op
Definition: effect.c:224
#define PSLIST_ENTRY
Definition: rtltypes.h:134
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
void * EngAllocMem(int zero, unsigned long size, int tag=0)
Definition: polytest.cpp:70
BOOL DbgInitDebugChannels()
int ret
#define DBG_DUMP_EVENT_LIST(pslh)
Definition: gdidebug.h:111
Status
Definition: gdiplustypes.h:24
#define STATUS_VARIABLE_NOT_FOUND
Definition: ntstatus.h:492
static const WCHAR L[]
Definition: oid.c:1250
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:790
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
NTKERNELAPI PSLIST_ENTRY FASTCALL InterlockedPushEntrySList(IN PSLIST_HEADER ListHead, IN PSLIST_ENTRY ListEntry)
Definition: interlocked.c:82
#define DBG_DISABLE_CHANNEL(ppi, ch, level)
Definition: win32kdebug.h:163
#define GDI_OBJECT_STACK_LEVELS
Definition: gdiobj.h:8
static const unsigned RESERVE_ENTRIES_COUNT
Definition: gdiobj.h:11
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
#define _In_
Definition: no_sal2.h:204
void * HGDIOBJ
Definition: windef.h:252
Definition: gdi.h:1
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define InterlockedIncrement
Definition: armddk.h:53
FORCEINLINE struct _TEB * NtCurrentTeb(VOID)
Definition: psfuncs.h:420
#define NtCurrentPeb()
Definition: FLS.c:20
unsigned short USHORT
Definition: pedump.c:61
ULONG NTAPI RtlWalkFrameChain(OUT PVOID *Callers, IN ULONG Count, IN ULONG Flags)
Definition: libsupp.c:227
#define GDI_HANDLE_COUNT
Definition: gdi.h:12
signed char * PSTR
Definition: retypes.h:7
ULONG gulFirstUnused
Definition: gdiobj.c:152
#define min(a, b)
Definition: monoChain.cc:55
#define GDI_ENTRY_UPPER_SHIFT
Definition: ntgdihdl.h:35
HANDLE NTAPI PsGetCurrentProcessId(VOID)
Definition: process.c:1123
PVOID KernelData
Definition: gdi.h:3
unsigned int UINT
Definition: ndis.h:50
PVOID MmHighestUserAddress
Definition: rtlcompat.c:29
PVOID NTAPI PsGetCurrentProcessWin32Process(VOID)
Definition: process.c:1183
#define GDI_DBG_MAX_BTS
Definition: gdidebug.h:3
#define DPRINT1
Definition: precomp.h:8
#define c
Definition: ke_i.h:80
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define ULONG_PTR
Definition: config.h:101
uint32_t * PULONG_PTR
Definition: typedefs.h:65
Definition: ntgdihdl.h:230
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
return STATUS_SUCCESS
Definition: btrfs.c:3014
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
LPARAM lParam
Definition: combotst.c:139
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NT_ASSERT
Definition: rtlfuncs.h:3312
#define bsearch