ReactOS  0.4.15-dev-985-gd905dd5
lock.c
Go to the documentation of this file.
1 /*++
2 
3 Copyright (C) Microsoft Corporation, 1990 - 1998
4 
5 Module Name:
6 
7  lock.c
8 
9 Abstract:
10 
11  This is the NT SCSI port driver.
12 
13 Environment:
14 
15  kernel mode only
16 
17 Notes:
18 
19  This module is a driver dll for scsi miniports.
20 
21 Revision History:
22 
23 --*/
24 
25 #include "classp.h"
26 #include "debug.h"
27 
28 #ifdef DEBUG_USE_WPP
29 #include "lock.tmh"
30 #endif
31 
32 
36 
37 //
38 // Structure used for tracking remove lock allocations in checked builds
39 //
40 typedef struct _REMOVE_TRACKING_BLOCK {
46 
47 /*++////////////////////////////////////////////////////////////////////////////
48 
49 Classpnp RemoveLockRundown
50 
51 RemoveLockRundown is a cacheaware rundown protection for the classpnp device object. While this
52 rundown protection is held successfully, the caller can assume that no pending pnp REMOVE
53 requests will be completed.
54 
55 The RemoveLockRundown is a replacement of the original RemoveLock to improve the scalability.
56 For backward compatibility, we still keep the RemoveLock field in the device common extension structure.
57 However, the old RemoveLock is only being used in the DBG build.
58 
59 The usage of the RemoveLockRundown is slightly different from the normal rundown protection usage.
60 The RemoveLockRundown is acquired via ClassAcquireRemoveLockEx() function
61 and released via ClassReleaseRemoveLock() function. Usually, we bail out when the acquisition
62 of rundown protection fails (calls to ExAcquireRundownProtectionCacheAware returns FALSE) and
63 will not release the rundown protection in acquisition failure. For the RemoveLockRundown,
64 the caller will always call ClassAcquireRemoveLockEx() and ClassReleaseRemoveLock() in a pair no
65 matter the return value of ClassAcquireRemoveLockEx(). Therefore, a thread may still call
66 ClassReleaseRemoveLock() even the previous acquisition RemoveLockRundown protection failed.
67 
68 To deal with the previous acquisition failure case, we introduced a new field RemoveLockFailAcquire
69 as a counter for rundown acquisition failures. In the ClassReleaseRemoveLock() function, we only
70 release the rundown protection when this counter is decremented to zero. Since the change of RemoveLockFailAcquire
71 and release rundown protection is not protected by a lock as an atomic operation, we use a while loop over
72 InterlockedCompareExchange operation to make sure when we release the rundown protection, this counter is
73 actually zero.
74 
75 --*/
76 
77 /*++////////////////////////////////////////////////////////////////////////////
78 
79 ClassAcquireRemoveLockEx()
80 
81 Routine Description:
82 
83  This routine is called to acquire the remove lock on the device object.
84  While the lock is held, the caller can assume that no pending pnp REMOVE
85  requests will be completed.
86 
87  The lock should be acquired immediately upon entering a dispatch routine.
88  It should also be acquired before creating any new reference to the
89  device object if there's a chance of releasing the reference before the
90  new one is done.
91 
92  This routine will return TRUE if the lock was successfully acquired or
93  FALSE if it cannot be because the device object has already been removed.
94 
95 Arguments:
96 
97  DeviceObject - the device object to lock
98 
99  Tag - Used for tracking lock allocation and release. If an irp is
100  specified when acquiring the lock then the same Tag must be
101  used to release the lock before the Tag is completed.
102 
103 Return Value:
104 
105  The value of the IsRemoved flag in the device extension. If this is
106  non-zero then the device object has received a Remove irp and non-cleanup
107  IRP's should fail.
108 
109  If the value is REMOVE_COMPLETE, the caller should not even release the
110  lock.
111 
112 --*/
113 ULONG
114 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
117  _In_ PVOID Tag,
118  _In_ PCSTR File,
119  _In_ ULONG Line
120  )
121 // This function implements the acquisition of Tag
122 #ifdef _MSC_VER
123 #pragma warning(suppress:28104)
124 #endif
125 {
127  BOOLEAN rundownAcquired;
128  PEX_RUNDOWN_REF_CACHE_AWARE removeLockRundown = NULL;
129 
130  //
131  // Grab the remove lock
132  //
133 
134  #if DBG
135 
136  LONG lockValue;
137 
138  lockValue = InterlockedIncrement(&commonExtension->RemoveLock);
139 
140 
141  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_LOCK, "ClassAcquireRemoveLock: "
142  "Acquired for Object %p & irp %p - count is %d\n",
143  DeviceObject, Tag, lockValue));
144 
145  NT_ASSERTMSG("ClassAcquireRemoveLock - lock value was negative : ",
146  (lockValue > 0));
147 
148  NT_ASSERTMSG("RemoveLock increased to meet LockHighWatermark",
149  ((LockHighWatermark == 0) ||
150  (lockValue != LockHighWatermark)));
151 
152  if (commonExtension->IsRemoved != REMOVE_COMPLETE) {
153  PRTL_GENERIC_TABLE removeTrackingList = NULL;
154  REMOVE_TRACKING_BLOCK trackingBlock;
155  PREMOVE_TRACKING_BLOCK insertedTrackingBlock = NULL;
156  BOOLEAN newElement = FALSE;
157 
158  KIRQL oldIrql;
159 
160  trackingBlock.Tag = Tag;
161 
162  trackingBlock.File = File;
163  trackingBlock.Line = Line;
164 
165  KeQueryTickCount((&trackingBlock.TimeLocked));
166 
167  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
168  &oldIrql);
169 
170  removeTrackingList = commonExtension->RemoveTrackingList;
171 
172  if (removeTrackingList != NULL) {
173  insertedTrackingBlock = RtlInsertElementGenericTable(removeTrackingList,
174  &trackingBlock,
175  sizeof(REMOVE_TRACKING_BLOCK),
176  &newElement);
177  }
178 
179  if (insertedTrackingBlock != NULL) {
180  if (!newElement) {
181  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassAcquireRemoveLock: "
182  "already tracking Tag %p\n", Tag));
183  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassAcquireRemoveLock: "
184  "acquired in file %s on line %d\n",
185  insertedTrackingBlock->File, insertedTrackingBlock->Line));
186 // NT_ASSERT(FALSE);
187 
188  }
189  } else {
190  commonExtension->RemoveTrackingUntrackedCount++;
191 
192  TracePrint((TRACE_LEVEL_WARNING, TRACE_FLAG_LOCK, ">>>>>ClassAcquireRemoveLock: "
193  "Cannot track Tag %p - currently %d untracked requsts\n",
194  Tag, commonExtension->RemoveTrackingUntrackedCount));
195  }
196 
197  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock, oldIrql);
198  }
199  #else
200 
204 
205  #endif
206 
207  removeLockRundown = (PEX_RUNDOWN_REF_CACHE_AWARE)
208  ((PCHAR)commonExtension->PrivateCommonData + sizeof(CLASS_PRIVATE_COMMON_DATA));
209  rundownAcquired = ExAcquireRundownProtectionCacheAware(removeLockRundown);
210  if (!rundownAcquired) {
211  InterlockedIncrement((volatile LONG*) &(commonExtension->PrivateCommonData->RemoveLockFailAcquire));
212  TracePrint((TRACE_LEVEL_VERBOSE,
213  TRACE_FLAG_LOCK,
214  "ClassAcquireRemoveLockEx: RemoveLockRundown acquisition failed"
215  "RemoveLockFailAcquire = %d\n",
216  commonExtension->PrivateCommonData->RemoveLockFailAcquire));
217  }
218 
219  return (commonExtension->IsRemoved);
220 }
221 
222 /*++////////////////////////////////////////////////////////////////////////////
223 
224 ClassReleaseRemoveLock()
225 
226 Routine Description:
227 
228  This routine is called to release the remove lock on the device object. It
229  must be called when finished using a previously locked reference to the
230  device object. If an Tag was specified when acquiring the lock then the
231  same Tag must be specified when releasing the lock.
232 
233  When the lock count reduces to zero, this routine will signal the waiting
234  remove Tag to delete the device object. As a result the DeviceObject
235  pointer should not be used again once the lock has been released.
236 
237 Arguments:
238 
239  DeviceObject - the device object to lock
240 
241  Tag - The irp (if any) specified when acquiring the lock. This is used
242  for lock tracking purposes
243 
244 Return Value:
245 
246  none
247 
248 --*/
249 VOID
250 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
254  )
255 // This function implements the release of Tag
256 #ifdef _MSC_VER
257 #pragma warning(suppress:28103)
258 #endif
259 {
261  LONG lockValue;
262  LONG oldValue;
263  PEX_RUNDOWN_REF_CACHE_AWARE removeLockRundown = NULL;
264 
265  #if DBG
266  PRTL_GENERIC_TABLE removeTrackingList = NULL;
267  REMOVE_TRACKING_BLOCK searchDataBlock;
268 
269  BOOLEAN found = FALSE;
270 
271  BOOLEAN isRemoved = (commonExtension->IsRemoved == REMOVE_COMPLETE);
272 
273  KIRQL oldIrql;
274 
275  if (isRemoved) {
276  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_LOCK, "ClassReleaseRemoveLock: REMOVE_COMPLETE set; this should never happen"));
277  InterlockedDecrement(&(commonExtension->RemoveLock));
278  return;
279  }
280 
281  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock,
282  &oldIrql);
283 
284  removeTrackingList = commonExtension->RemoveTrackingList;
285 
286  if (removeTrackingList != NULL) {
287  searchDataBlock.Tag = Tag;
288  found = RtlDeleteElementGenericTable(removeTrackingList, &searchDataBlock);
289  }
290 
291  if (!found) {
292  if(commonExtension->RemoveTrackingUntrackedCount == 0) {
293  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassReleaseRemoveLock: "
294  "Couldn't find Tag %p in the lock tracking list\n", Tag));
295  //
296  // This might happen if the device is being removed and the tracking list
297  // has already been freed. Don't assert if that is the case.
298  //
299  NT_ASSERT((removeTrackingList == NULL) && (commonExtension->IsRemoved != NO_REMOVE));
300  } else {
301  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassReleaseRemoveLock: "
302  "Couldn't find Tag %p in the lock tracking list - "
303  "may be one of the %d untracked requests still outstanding\n",
304  Tag, commonExtension->RemoveTrackingUntrackedCount));
305 
306  commonExtension->RemoveTrackingUntrackedCount--;
307  NT_ASSERT(commonExtension->RemoveTrackingUntrackedCount >= 0);
308  }
309  }
310 
311  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock,
312  oldIrql);
313 
314  lockValue = InterlockedDecrement(&commonExtension->RemoveLock);
315 
316  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_LOCK, "ClassReleaseRemoveLock: "
317  "Released for Object %p & irp %p - count is %d\n",
318  DeviceObject, Tag, lockValue));
319 
320  NT_ASSERT(lockValue >= 0);
321 
322  NT_ASSERTMSG("RemoveLock decreased to meet LockLowWatermark",
323  ((LockLowWatermark == 0) || !(lockValue == LockLowWatermark)));
324 
325  if (lockValue == 0) {
326 
327  NT_ASSERT(commonExtension->IsRemoved);
328 
329  //
330  // The device needs to be removed. Signal the remove event
331  // that it's safe to go ahead.
332  //
333 
334  TracePrint((TRACE_LEVEL_VERBOSE, TRACE_FLAG_LOCK, "ClassReleaseRemoveLock: "
335  "Release for object %p & irp %p caused lock to go to zero\n",
336  DeviceObject, Tag));
337 
338  }
339 
340  #else
341 
343 
344  #endif
345 
346  //
347  // Decrement the RemoveLockFailAcquire by 1 when RemoveLockFailAcquire is non-zero.
348  // Release the RemoveLockRundown only when RemoveLockFailAcquire is zero.
349  //
350 
351  oldValue = 1;
352  lockValue = commonExtension->PrivateCommonData->RemoveLockFailAcquire;
353  while (lockValue != 0) {
354  oldValue =
356  lockValue - 1,
357  lockValue);
358 
359  if (oldValue == lockValue) {
360  break;
361  }
362 
363  lockValue = oldValue;
364  }
365 
366  if (lockValue == 0) {
367  removeLockRundown = (PEX_RUNDOWN_REF_CACHE_AWARE)
368  ((PCHAR)commonExtension->PrivateCommonData + sizeof(CLASS_PRIVATE_COMMON_DATA));
369  ExReleaseRundownProtectionCacheAware(removeLockRundown);
370  }
371 
372  return;
373 }
374 
375 /*++////////////////////////////////////////////////////////////////////////////
376 
377 ClassCompleteRequest()
378 
379 Routine Description:
380 
381  This routine is a wrapper around (and should be used instead of)
382  IoCompleteRequest. It is used primarily for debugging purposes.
383  The routine will assert if the Irp being completed is still holding
384  the release lock.
385 
386 Arguments:
387 
388  DeviceObject - the device object that was handling this request
389 
390  Irp - the irp to be completed by IoCompleteRequest
391 
392  PriorityBoost - the priority boost to pass to IoCompleteRequest
393 
394 Return Value:
395 
396  none
397 
398 --*/
399 VOID
400 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
403  _In_ PIRP Irp,
405  )
406 {
407  #if DBG
409 
410  PRTL_GENERIC_TABLE removeTrackingList = NULL;
411  REMOVE_TRACKING_BLOCK searchDataBlock;
412  PREMOVE_TRACKING_BLOCK foundTrackingBlock;
413 
414  KIRQL oldIrql;
415 
416  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock, &oldIrql);
417 
418  removeTrackingList = commonExtension->RemoveTrackingList;
419 
420  if (removeTrackingList != NULL)
421  {
422  searchDataBlock.Tag = Irp;
423 
424  foundTrackingBlock = RtlLookupElementGenericTable(removeTrackingList, &searchDataBlock);
425 
426  if(foundTrackingBlock != NULL) {
427 
428  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassCompleteRequest: "
429  "Irp %p completed while still holding the remove lock\n", Irp));
430  TracePrint((TRACE_LEVEL_ERROR, TRACE_FLAG_LOCK, ">>>>>ClassCompleteRequest: "
431  "Lock acquired in file %s on line %d\n",
432  foundTrackingBlock->File, foundTrackingBlock->Line));
433  NT_ASSERT(FALSE);
434  }
435  }
436 
437  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock, oldIrql);
438  #endif
439 
440 
442 
444  return;
445 } // end ClassCompleteRequest()
446 
447 
449 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
454  )
455 {
456  PVOID tag1, tag2;
457 
459 
460  tag1 = ((PREMOVE_TRACKING_BLOCK)FirstStruct)->Tag;
461  tag2 = ((PREMOVE_TRACKING_BLOCK)SecondStruct)->Tag;
462 
463  if (tag1 < tag2)
464  {
465  return GenericLessThan;
466  }
467  else if (tag1 > tag2)
468  {
469  return GenericGreaterThan;
470  }
471 
472  return GenericEqual;
473 }
474 
475 PVOID
476 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
480  )
481 {
483 
484  return ExAllocatePoolWithTag(NonPagedPoolNx, ByteSize, CLASS_TAG_LOCK_TRACKING);
485 }
486 
487 VOID
488 NTAPI /* ReactOS Change: GCC Does not support STDCALL by default */
491  PVOID Buffer
492  )
493 {
495 
496  FREE_POOL(Buffer);
497 }
498 
499 VOID
502  )
503 {
505 
506  #if DBG
507  KeInitializeSpinLock(&commonExtension->RemoveTrackingSpinlock);
508 
509  commonExtension->RemoveTrackingList = ExAllocatePoolWithTag(NonPagedPoolNx, sizeof(RTL_GENERIC_TABLE), CLASS_TAG_LOCK_TRACKING);
510 
511  if (commonExtension->RemoveTrackingList != NULL)
512  {
517  NULL);
518  }
519  #else
520 
522 
523  commonExtension->RemoveTrackingSpinlock = (ULONG_PTR) -1;
524  commonExtension->RemoveTrackingList = NULL;
525  #endif
526 }
527 
528 VOID
531  )
532 {
533  #if DBG
535  PRTL_GENERIC_TABLE removeTrackingList = commonExtension->RemoveTrackingList;
536 
537  ASSERTMSG("Removing the device while still holding remove locks",
538  commonExtension->RemoveTrackingUntrackedCount == 0 &&
539  removeTrackingList != NULL ? RtlNumberGenericTableElements(removeTrackingList) == 0 : TRUE);
540 
541  if (removeTrackingList != NULL)
542  {
543  KIRQL oldIrql;
544  KeAcquireSpinLock(&commonExtension->RemoveTrackingSpinlock, &oldIrql);
545 
546  FREE_POOL(removeTrackingList);
547  commonExtension->RemoveTrackingList = NULL;
548 
549  KeReleaseSpinLock(&commonExtension->RemoveTrackingSpinlock, oldIrql);
550  }
551 
552  #else
553 
555  #endif
556 }
557 
558 
559 
560 
signed char * PCHAR
Definition: retypes.h:7
#define NT_ASSERTMSG
Definition: rtlfuncs.h:3313
ASMGENDATA Table[]
Definition: genincdata.c:61
VOID ClasspInitializeRemoveTracking(_In_ PDEVICE_OBJECT DeviceObject)
Definition: lock.c:500
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElements(_In_ PRTL_GENERIC_TABLE Table)
#define REMOVE_COMPLETE
Definition: classpnp.h:98
struct _EX_RUNDOWN_REF_CACHE_AWARE * PEX_RUNDOWN_REF_CACHE_AWARE
Definition: extypes.h:186
_In_ PIRP Irp
Definition: csq.h:116
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG MaxLockedMinutes
Definition: lock.c:35
LONG LockHighWatermark
Definition: lock.c:33
struct _REMOVE_TRACKING_BLOCK * PREMOVE_TRACKING_BLOCK
#define InterlockedCompareExchange
Definition: interlocked.h:104
struct _CLASS_PRIVATE_COMMON_DATA CLASS_PRIVATE_COMMON_DATA
Definition: classpnp.h:285
VOID NTAPI RemoveTrackingFreeRoutine(PRTL_GENERIC_TABLE Table, PVOID Buffer)
Definition: lock.c:489
VOID NTAPI RtlInitializeGenericTable(IN PRTL_GENERIC_TABLE Table, IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine, IN PVOID TableContext)
Definition: generictable.c:100
#define _In_opt_
Definition: no_sal2.h:213
UCHAR KIRQL
Definition: env_spec_w32.h:591
ULONG CLONG
Definition: umtypes.h:126
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define TRACE_LEVEL_VERBOSE
Definition: storswtr.h:30
long LONG
Definition: pedump.c:60
#define ASSERTMSG(msg, exp)
Definition: nt_native.h:431
_In_opt_ PVOID _In_ PCSTR File
Definition: iofuncs.h:615
_In_ CCHAR PriorityBoost
Definition: iofuncs.h:763
ULONG NTAPI ClassAcquireRemoveLockEx(_In_ PDEVICE_OBJECT DeviceObject, _In_ PVOID Tag, _In_ PCSTR File, _In_ ULONG Line)
Definition: lock.c:115
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:238
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
VOID NTAPI ClassReleaseRemoveLock(_In_ PDEVICE_OBJECT DeviceObject, _In_opt_ PIRP Tag)
Definition: lock.c:251
smooth NULL
Definition: ftsmooth.c:416
LONG LockLowWatermark
Definition: lock.c:34
#define IoCompleteRequest
Definition: irp.c:1240
Definition: bufpool.h:45
VOID NTAPI KeQueryTickCount(IN PLARGE_INTEGER TickCount)
Definition: clock.c:165
RTL_GENERIC_COMPARE_RESULTS NTAPI RemoveTrackingCompareRoutine(PRTL_GENERIC_TABLE Table, PVOID FirstStruct, PVOID SecondStruct)
Definition: lock.c:450
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ PVOID Buffer)
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:383
char CCHAR
Definition: typedefs.h:51
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
struct _REMOVE_TRACKING_BLOCK REMOVE_TRACKING_BLOCK
LARGE_INTEGER TimeLocked
Definition: lock.c:42
Definition: ncftp.h:79
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define NO_REMOVE
Definition: classpnp.h:96
#define InterlockedDecrement
Definition: armddk.h:52
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:383
#define FREE_POOL(_PoolPtr)
Definition: classpnp.h:63
NTKERNELAPI VOID FASTCALL ExReleaseRundownProtectionCacheAware(_Inout_ PEX_RUNDOWN_REF_CACHE_AWARE RunRefCacheAware)
#define TRACE_LEVEL_ERROR
Definition: storswtr.h:27
#define TRACE_LEVEL_WARNING
Definition: storswtr.h:28
#define _In_
Definition: no_sal2.h:204
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ PVOID Buffer)
#define InterlockedIncrement
Definition: armddk.h:53
PCLASS_PRIVATE_COMMON_DATA PrivateCommonData
Definition: classpnp.h:633
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
IN ULONG IN ULONG Tag
Definition: evtlib.h:159
unsigned int ULONG
Definition: retypes.h:1
#define ULONG_PTR
Definition: config.h:101
const char * PCSTR
Definition: typedefs.h:52
Definition: File.h:15
KSPIN_LOCK RemoveTrackingSpinlock
Definition: classpnp.h:603
#define CLASS_TAG_LOCK_TRACKING
Definition: classpnp.h:88
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)
VOID NTAPI ClassCompleteRequest(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ CCHAR PriorityBoost)
Definition: lock.c:401
PVOID NTAPI RemoveTrackingAllocateRoutine(PRTL_GENERIC_TABLE Table, CLONG ByteSize)
Definition: lock.c:477
struct Line Line
VOID ClasspUninitializeRemoveTracking(_In_ PDEVICE_OBJECT DeviceObject)
Definition: lock.c:529
#define NT_ASSERT
Definition: rtlfuncs.h:3312