ReactOS  0.4.14-dev-608-gd495a4f
tunnel.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: ntoskrnl/fsrtl/tunnel.c
5  * PURPOSE: Provides the Tunnel Cache implementation for file system drivers.
6  * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
7  * Pierre Schweitzer (pierre@reactos.org)
8  */
9 
10 /* INCLUDES ******************************************************************/
11 
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 typedef struct {
27 
31 
32 #define DEFAULT_EXTRA_SIZE (72)
33 #define DEFAULT_ENTRY_SIZE (sizeof(TUNNEL_NODE_ENTRY) + DEFAULT_EXTRA_SIZE)
34 
35 #define TUNNEL_FLAG_POOL 0x2
36 #define TUNNEL_FLAG_KEY_SHORT_NAME 0x1
37 
38 VOID
40  IN PTUNNEL_NODE_ENTRY CurEntry,
41  IN PLIST_ENTRY PoolList OPTIONAL)
42 {
43  if (PoolList)
44  {
45  /* divert the linked list entry, it's not required anymore, but we need it */
46  InsertHeadList(PoolList, &CurEntry->TimerQueueEntry);
47  return;
48  }
49 
50  if (CurEntry->Flags & TUNNEL_FLAG_POOL)
51  ExFreePool(CurEntry);
52  else
53  ExFreeToPagedLookasideList(&TunnelLookasideList, CurEntry);
54 }
55 
56 VOID
59  IN PTUNNEL_NODE_ENTRY CurEntry,
60  IN PLIST_ENTRY PoolList,
61  OUT PBOOLEAN Rebalance)
62 {
63  /* delete entry and rebalance if required */
64  if (Rebalance && *Rebalance)
65  {
66  Cache->Cache = RtlDelete(&CurEntry->SplayInfo);
67  /* reset */
68  *Rebalance = FALSE;
69  }
70  else
71  {
72  RtlDeleteNoSplay(&CurEntry->SplayInfo, &Cache->Cache);
73  }
74 
75  /* remove entry */
76  RemoveEntryList(&CurEntry->TimerQueueEntry);
77 
78  /* free node entry */
79  FsRtlFreeTunnelNode(CurEntry, PoolList);
80 
81  /* decrement node count */
82  Cache->NumEntries--;
83 }
84 
85 VOID
88  IN PLIST_ENTRY PoolList)
89 {
90  PLIST_ENTRY Entry, NextEntry;
91  PTUNNEL_NODE_ENTRY CurEntry;
92  LARGE_INTEGER CurTime, OldTime;
93  BOOLEAN Rebalance = TRUE;
94  PAGED_CODE();
95 
96  /* query time */
97  KeQuerySystemTime(&CurTime);
98 
99  /* subtract maximum node age */
100  OldTime.QuadPart = CurTime.QuadPart - TunnelMaxAge;
101 
102  /* free all entries */
103  Entry = Cache->TimerQueue.Flink;
104 
105  while(Entry != &Cache->TimerQueue)
106  {
107  /* get node entry */
108  CurEntry = CONTAINING_RECORD(Entry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
109 
110  /* get next entry */
111  NextEntry = Entry->Flink;
112 
113  /* prune if expired OR if in advance in time */
114  if (CurEntry->Time.QuadPart < OldTime.QuadPart ||
115  CurEntry->Time.QuadPart > CurTime.QuadPart)
116  {
117  FsRtlRemoveNodeFromTunnel(Cache, CurEntry, PoolList, &Rebalance);
118  }
119 
120  /* move to next entry */
121  Entry = NextEntry;
122  }
123 
124  /* If we have too many entries */
125  while (Cache->NumEntries > TunnelMaxEntries)
126  {
127  CurEntry = CONTAINING_RECORD(Entry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
128  FsRtlRemoveNodeFromTunnel(Cache, CurEntry, PoolList, &Rebalance);
129  }
130 }
131 
132 INIT_FUNCTION
133 VOID
136  OUT PULONG Value)
137 {
138  UNICODE_STRING Root = RTL_CONSTANT_STRING(L"Registry\\Machine\\System\\CurrentControlSet\\Control\\FileSystem");
140  HANDLE hKey;
142  ULONG Length;
144 
145  /* initialize object attributes */
147 
148  /* open registry key */
149  Status = ZwOpenKey(&hKey, KEY_READ, &ObjectAttributes);
150 
151  if (!NT_SUCCESS(Status))
152  {
153  /* failed to open key */
154  return;
155  }
156 
157  /* query value size */
158  Status = ZwQueryValueKey(hKey, ParameterName, KeyValueFullInformation, NULL, 0, &Length);
159 
161  {
162  /* failed to query size */
163  ZwClose(hKey);
164  return;
165  }
166 
167  /* allocate buffer */
169 
170  if (!Info)
171  {
172  /* out of memory */
173  ZwClose(hKey);
174  return;
175  }
176 
177  /* query value */
178  Status = ZwQueryValueKey(hKey, ParameterName, KeyValueFullInformation, NULL, 0, &Length);
179 
180  if (NT_SUCCESS(Status))
181  {
182  if (Info->DataLength)
183  {
184  /* store result */
185  *Value = (ULONG)((ULONG_PTR)Info + Info->DataOffset);
186  }
187  }
188 
189  /* free buffer */
190  ExFreePool(Info);
191 
192  /* close key */
193  ZwClose(hKey);
194 }
195 
196 INIT_FUNCTION
197 VOID
198 NTAPI
200 {
201  ULONG TunnelEntries;
202  UNICODE_STRING MaximumTunnelEntryAgeInSeconds = RTL_CONSTANT_STRING(L"MaximumTunnelEntryAgeInSeconds");
203  UNICODE_STRING MaximumTunnelEntries = RTL_CONSTANT_STRING( L"MaximumTunnelEntries");
204 
205  /* check for nt */
206  if (MmIsThisAnNtAsSystem())
207  {
208  /* default */
209  TunnelMaxEntries = 1024;
210  }
211 
212  /* check for custom override of max entries*/
213  FsRtlGetTunnelParameterValue(&MaximumTunnelEntries, &TunnelMaxEntries);
214 
215  /* check for custom override of age*/
216  FsRtlGetTunnelParameterValue(&MaximumTunnelEntryAgeInSeconds, &TunnelMaxAge);
217 
218  if (!TunnelMaxAge)
219  {
220  /* no age means no entries */
221  TunnelMaxEntries = 0;
222  }
223 
224  /* get max entries */
225  TunnelEntries = TunnelMaxEntries;
226 
227  /* convert to ticks */
228  TunnelMaxAge *= 10000000;
229 
230  if(TunnelMaxEntries <= 65535)
231  {
232  /* use max 256 entries */
233  TunnelEntries = TunnelMaxEntries / 16;
234  }
235 
236  if(!TunnelEntries && TunnelMaxEntries )
237  {
238  /* max tunnel entries was too small */
239  TunnelEntries = TunnelMaxEntries + 1;
240  }
241 
242  if (TunnelEntries > 0xFFFF)
243  {
244  /* max entries is 256 */
245  TunnelEntries = 256;
246  }
247 
248  /* initialize look aside list */
250 }
251 
252 LONG
254  IN PTUNNEL_NODE_ENTRY CurEntry,
256  IN PUNICODE_STRING KeyString)
257 {
259  LONG Ret;
260 
261  if (DirectoryKey > CurEntry->DirectoryKey)
262  {
263  Ret = 1;
264  }
265  else if (DirectoryKey < CurEntry->DirectoryKey)
266  {
267  Ret = -1;
268  }
269  else
270  {
271  if (CurEntry->Flags & TUNNEL_FLAG_KEY_SHORT_NAME)
272  {
273  /* use short name as key */
274  String = &CurEntry->ShortName;
275  }
276  else
277  {
278  /* use long name as key */
279  String = &CurEntry->LongName;
280  }
281 
282  Ret = RtlCompareUnicodeString(KeyString, String, TRUE);
283  }
284 
285  return Ret;
286 }
287 
288 VOID
290  IN PLIST_ENTRY PoolList)
291 {
292  PLIST_ENTRY CurEntry;
293  PTUNNEL_NODE_ENTRY CurNode;
294 
295  /* loop over all the entry */
296  while (!IsListEmpty(PoolList))
297  {
298  /* and free them, one by one */
299  CurEntry = RemoveHeadList(PoolList);
300  CurNode = CONTAINING_RECORD(CurEntry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
301  FsRtlFreeTunnelNode(CurNode, 0);
302  }
303 }
304 
305 /* PUBLIC FUNCTIONS **********************************************************/
306 
307 /*++
308  * @name FsRtlAddToTunnelCache
309  * @implemented
310  *
311  * FILLME
312  *
313  * @param Cache
314  * FILLME
315  *
316  * @param DirectoryKey
317  * FILLME
318  *
319  * @param ShortName
320  * FILLME
321  *
322  * @param LongName
323  * FILLME
324  *
325  * @param KeyByShortName
326  * FILLME
327  *
328  * @param DataLength
329  * FILLME
330  *
331  * @param Data
332  * FILLME
333  *
334  * @return None
335  *
336  * @remarks None
337  *
338  *--*/
339 VOID
340 NTAPI
347  IN PVOID Data)
348 {
349  PTUNNEL_NODE_ENTRY NodeEntry = NULL;
350  PRTL_SPLAY_LINKS CurEntry, LastEntry;
351  ULONG Length;
352  LONG Result = 0;
353  BOOLEAN AllocatedFromPool = FALSE;
354  PUNICODE_STRING KeyString;
355  LIST_ENTRY PoolList;
356 
357  PAGED_CODE();
358 
359  /* check if tunnel cache is enabled */
360  if (!TunnelMaxEntries)
361  {
362  /* entries are disabled */
363  return;
364  }
365 
366  /* initialize free pool list */
367  InitializeListHead(&PoolList);
368 
369  /* calculate node length */
370  Length = sizeof(TUNNEL_NODE_ENTRY);
371 
372  /* add data size */
373  Length += DataLength;
374 
375  if (ShortName)
376  {
377  /* add short name length */
378  Length += ShortName->Length;
379  }
380 
381  if (LongName)
382  {
383  /* add short name length */
384  Length += LongName->Length;
385  }
386 
387  if (Length <= DEFAULT_ENTRY_SIZE)
388  {
389  /* get standard entry */
390  NodeEntry = ExAllocateFromPagedLookasideList(&TunnelLookasideList);
391  }
392 
393  if (NodeEntry == NULL)
394  {
395  /* bigger than default entry or allocation failed */
397  /* check for success */
398  if (NodeEntry == NULL)
399  {
400  /* out of memory */
401  return;
402  }
403 
404  AllocatedFromPool = TRUE;
405  }
406 
407  /* acquire lock */
408  ExAcquireFastMutex(&Cache->Mutex);
409 
410  /* now search cache for existing entries */
411  CurEntry = Cache->Cache;
412 
413  /* check which key should be used for search */
414  KeyString = (KeyByShortName ? ShortName : LongName);
415 
416  /* initialize last entry */
417  LastEntry = NULL;
418 
419  while(CurEntry)
420  {
421  /* compare current node */
423 
424  /* backup last entry */
425  LastEntry = CurEntry;
426 
427  if (Result > 0)
428  {
429  /* current directory key is bigger */
430  CurEntry = CurEntry->LeftChild;
431  }
432  else
433  {
434  if (Result == 0)
435  {
436  /* found equal entry */
437  break;
438  }
439 
440  /* current directory key is smaller */
441  CurEntry = CurEntry->RightChild;
442  }
443  }
444 
445  /* initialize node entry */
446  RtlInitializeSplayLinks(&NodeEntry->SplayInfo);
447 
448  if (CurEntry != NULL)
449  {
450  /* found existing item */
451  if (CurEntry->LeftChild)
452  {
453  /* update parent */
454  RtlInsertAsLeftChild(NodeEntry, CurEntry->LeftChild);
455  }
456 
457  if (CurEntry->RightChild)
458  {
459  /* update parent */
460  RtlInsertAsRightChild(NodeEntry, CurEntry->RightChild);
461  }
462 
463  if (CurEntry->Parent == CurEntry)
464  {
465  /* cur entry was root */
466  Cache->Cache = (struct _RTL_SPLAY_LINKS*)NodeEntry;
467  }
468  else
469  {
470  /* update parent node */
471  if (RtlIsLeftChild(CurEntry))
472  {
473  RtlInsertAsLeftChild(RtlParent(CurEntry), NodeEntry);
474  }
475  else
476  {
477  RtlInsertAsRightChild(RtlParent(CurEntry), NodeEntry);
478  }
479  }
480 
481  /* remove entry */
482  RemoveEntryList(&((PTUNNEL_NODE_ENTRY)CurEntry)->TimerQueueEntry);
483 
484  /* free node entry */
485  FsRtlFreeTunnelNode((PTUNNEL_NODE_ENTRY)CurEntry, &PoolList);
486 
487  /* decrement node count */
488  Cache->NumEntries--;
489  }
490  else
491  {
492  if (LastEntry == NULL)
493  {
494  /* first entry in tunnel cache */
495  Cache->Cache = (struct _RTL_SPLAY_LINKS*)NodeEntry;
496  }
497  else
498  {
499  if (Result > 0)
500  {
501  /* new left node */
502  RtlInsertAsLeftChild(LastEntry, NodeEntry);
503  }
504  else
505  {
506  /* new right node */
507  RtlInsertAsRightChild(LastEntry, NodeEntry);
508  }
509  }
510  }
511 
512  /* initialize entry */
513  KeQuerySystemTime(&NodeEntry->Time);
514 
515  NodeEntry->DirectoryKey = DirectoryKey;
516  NodeEntry->Flags = (AllocatedFromPool ? TUNNEL_FLAG_POOL : 0x0);
517  NodeEntry->Flags |= (KeyByShortName ? TUNNEL_FLAG_KEY_SHORT_NAME : 0x0);
518 
519  if (ShortName)
520  {
521  /* copy short name */
522  NodeEntry->ShortName.Length = ShortName->Length;
523  NodeEntry->ShortName.MaximumLength = ShortName->Length;
524  NodeEntry->ShortName.Buffer = (LPWSTR)((ULONG_PTR)NodeEntry + sizeof(TUNNEL_NODE_ENTRY));
525 
526  RtlMoveMemory(NodeEntry->ShortName.Buffer, ShortName->Buffer, ShortName->Length);
527  }
528  else
529  {
530  NodeEntry->ShortName.Length = NodeEntry->ShortName.MaximumLength = 0;
531  NodeEntry->ShortName.Buffer = NULL;
532  }
533 
534  if (LongName)
535  {
536  /* copy long name */
537  NodeEntry->LongName.Length = LongName->Length;
538  NodeEntry->LongName.MaximumLength = LongName->Length;
539  NodeEntry->LongName.Buffer = (LPWSTR)((ULONG_PTR)NodeEntry + sizeof(TUNNEL_NODE_ENTRY) + NodeEntry->ShortName.Length);
540 
542  }
543  else
544  {
545  NodeEntry->LongName.Length = NodeEntry->LongName.MaximumLength = 0;
546  NodeEntry->LongName.Buffer = NULL;
547  }
548 
549  NodeEntry->DataLength = DataLength;
550  NodeEntry->Data = (PVOID)((ULONG_PTR)NodeEntry + sizeof(TUNNEL_NODE_ENTRY) + NodeEntry->ShortName.Length + NodeEntry->LongName.Length);
551  RtlMoveMemory(NodeEntry->Data, Data, DataLength);
552 
553  /* increment node count */
554  Cache->NumEntries++;
555 
556  /* insert into list */
557  InsertTailList(&Cache->TimerQueue, &NodeEntry->TimerQueueEntry);
558 
559  /* prune cache */
560  FsRtlPruneTunnelCache(Cache, &PoolList);
561 
562  /* release lock */
563  ExReleaseFastMutex(&Cache->Mutex);
564 
565  /* free pool list */
566  FsRtlEmptyFreePoolList(&PoolList);
567 }
568 
569 /*++
570  * @name FsRtlDeleteKeyFromTunnelCache
571  * @implemented
572  *
573  * FILLME
574  *
575  * @param Cache
576  * FILLME
577  *
578  * @param DirectoryKey
579  * FILLME
580  *
581  * @return None
582  *
583  * @remarks None
584  *
585  *--*/
586 VOID
587 NTAPI
590 {
591  BOOLEAN Rebalance = TRUE;
592  LIST_ENTRY PoolList;
593  PTUNNEL_NODE_ENTRY CurNode;
594  PRTL_SPLAY_LINKS CurEntry, LastEntry = NULL, Successors;
595 
596  PAGED_CODE();
597 
598  /* check if tunnel cache is enabled */
599  if (!TunnelMaxEntries)
600  {
601  /* entries are disabled */
602  return;
603  }
604 
605  /* initialize free pool list */
606  InitializeListHead(&PoolList);
607 
608  /* acquire lock */
609  ExAcquireFastMutex(&Cache->Mutex);
610 
611  /* Look for the entry */
612  CurEntry = Cache->Cache;
613  while (CurEntry)
614  {
615  CurNode = CONTAINING_RECORD(CurEntry, TUNNEL_NODE_ENTRY, SplayInfo);
616 
617  if (CurNode->DirectoryKey > DirectoryKey)
618  {
619  /* current directory key is bigger */
620  CurEntry = CurEntry->LeftChild;
621  }
622  else if (CurNode->DirectoryKey < DirectoryKey)
623  {
624  /* if we have already found one suitable, break */
625  if (LastEntry != NULL)
626  {
627  break;
628  }
629 
630  /* current directory key is smaller */
631  CurEntry = CurEntry->RightChild;
632  }
633  else
634  {
635  /* save and look for another */
636  LastEntry = CurEntry;
637  CurEntry = CurEntry->LeftChild;
638  }
639  }
640 
641  /* was it found? */
642  if (LastEntry == NULL)
643  {
644  /* release tunnel lock */
645  ExReleaseFastMutex(&Cache->Mutex);
646 
647  return;
648  }
649 
650  /* delete any matching key */
651  do
652  {
653  CurNode = CONTAINING_RECORD(LastEntry, TUNNEL_NODE_ENTRY, SplayInfo);
654 
655  Successors = RtlRealSuccessor(LastEntry);
656  if (CurNode->DirectoryKey != DirectoryKey)
657  {
658  break;
659  }
660 
661  /* remove from tunnel */
662  FsRtlRemoveNodeFromTunnel(Cache, CurNode, &PoolList, &Rebalance);
663  LastEntry = Successors;
664  }
665  while (LastEntry != NULL);
666 
667  /* release tunnel lock */
668  ExReleaseFastMutex(&Cache->Mutex);
669 
670  /* free pool */
671  FsRtlEmptyFreePoolList(&PoolList);
672 }
673 
674 /*++
675  * @name FsRtlDeleteTunnelCache
676  * @implemented
677  *
678  * FILLME
679  *
680  * @param Cache
681  * FILLME
682  *
683  * @return None
684  *
685  * @remarks None
686  *
687  *--*/
688 VOID
689 NTAPI
691 {
692  PLIST_ENTRY Entry, NextEntry;
693  PTUNNEL_NODE_ENTRY CurEntry;
694 
695  PAGED_CODE();
696 
697  /* check if tunnel cache is enabled */
698  if (!TunnelMaxEntries)
699  {
700  /* entries are disabled */
701  return;
702  }
703 
704  /* free all entries */
705  Entry = Cache->TimerQueue.Flink;
706 
707  while(Entry != &Cache->TimerQueue)
708  {
709  /* get node entry */
710  CurEntry = CONTAINING_RECORD(Entry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
711 
712  /* get next entry */
713  NextEntry = Entry->Flink;
714 
715  /* remove entry from list */
716  RemoveEntryList(&CurEntry->TimerQueueEntry);
717 
718  /* free entry */
719  FsRtlFreeTunnelNode(CurEntry, NULL);
720 
721  /* move to next entry */
722  Entry = NextEntry;
723  }
724 
725  /* reset object */
726  Cache->Cache = NULL;
727  Cache->NumEntries = 0;
728  InitializeListHead(&Cache->TimerQueue);
729 }
730 
731 /*++
732  * @name FsRtlFindInTunnelCache
733  * @implemented
734  *
735  * FILLME
736  *
737  * @param Cache
738  * FILLME
739  *
740  * @param DirectoryKey
741  * FILLME
742  *
743  * @param ShortName
744  * FILLME
745  *
746  * @param LongName
747  * FILLME
748  *
749  * @param KeyByShortName
750  * FILLME
751  *
752  * @param DataLength
753  * FILLME
754  *
755  * @param Data
756  * FILLME
757  *
758  * @return None
759  *
760  * @remarks None
761  *
762  *--*/
763 BOOLEAN
764 NTAPI
771  OUT PVOID Data)
772 {
773  BOOLEAN Ret = FALSE;
774  PTUNNEL_NODE_ENTRY CurEntry;
775  LIST_ENTRY PoolList;
776  //NTSTATUS Status;
777  LONG Result;
778 
779  PAGED_CODE();
780 
781  /* check if tunnel cache is enabled */
782  if (!TunnelMaxEntries)
783  {
784  /* entries are disabled */
785  return FALSE;
786  }
787 
788  /* initialize free pool list */
789  InitializeListHead(&PoolList);
790 
791  /* acquire tunnel lock */
792  ExAcquireFastMutex(&Cache->Mutex);
793 
794  /* prune old entries */
795  FsRtlPruneTunnelCache(Cache, &PoolList);
796 
797  /* now search cache for existing entries */
798  CurEntry = (PTUNNEL_NODE_ENTRY)Cache->Cache;
799 
800  while(CurEntry)
801  {
802  /* compare current node */
804 
805  if (Result > 0)
806  {
807  /* current directory key is bigger */
808  CurEntry = (PTUNNEL_NODE_ENTRY)CurEntry->SplayInfo.LeftChild;
809  }
810  else
811  {
812  if (Result == 0)
813  {
814  /* found equal entry */
815  break;
816  }
817 
818  /* current directory key is smaller */
819  CurEntry = (PTUNNEL_NODE_ENTRY)CurEntry->SplayInfo.RightChild;
820  }
821  }
822 
823  if (CurEntry != NULL)
824  {
825  _SEH2_TRY
826  {
827  /* copy short name */
829 
830  /* check size */
831  if (LongName->MaximumLength < CurEntry->LongName.Length)
832  {
833  /* buffer is too small */
835  if (LongName->Buffer)
836  {
837  LongName->Length = CurEntry->LongName.Length;
839  RtlMoveMemory(LongName->Buffer, CurEntry->LongName.Buffer, CurEntry->LongName.Length);
840  }
841  }
842  else
843  {
844  /* buffer is big enough */
846  }
847 
848  /* copy data */
849  RtlMoveMemory(Data, CurEntry->Data, CurEntry->DataLength);
850 
851  /* store size */
852  *DataLength = CurEntry->DataLength;
853 
854  /* done */
855  Ret = TRUE;
856  }
858  {
859  /* Get the status */
860  //Status = _SEH2_GetExceptionCode();
861  }
862  _SEH2_END;
863 
864  }
865 
866  /* release tunnel lock */
867  ExReleaseFastMutex(&Cache->Mutex);
868 
869  /* free pool */
870  FsRtlEmptyFreePoolList(&PoolList);
871 
872  return Ret;
873 }
874 
875 /*++
876  * @name FsRtlInitializeTunnelCache
877  * @implemented
878  *
879  * FILLME
880  *
881  * @param Cache
882  * FILLME
883  *
884  * @return None
885  *
886  * @remarks None
887  *
888  *--*/
889 VOID
890 NTAPI
892 {
893  PAGED_CODE();
894 
895  /* initialize mutex */
896  ExInitializeFastMutex(&Cache->Mutex);
897 
898  /* initialize node tree */
899  Cache->Cache = NULL;
900 
901  /* initialize timer list */
902  InitializeListHead(&Cache->TimerQueue);
903 
904  /* initialize node count */
905  Cache->NumEntries = 0;
906 }
907 
908 /* EOF */
VOID FsRtlEmptyFreePoolList(IN PLIST_ENTRY PoolList)
Definition: tunnel.c:289
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1294
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
VOID FsRtlPruneTunnelCache(IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
Definition: tunnel.c:86
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlDeleteNoSplay(_In_ PRTL_SPLAY_LINKS Links, _Inout_ PRTL_SPLAY_LINKS *Root)
VOID NTAPI ExInitializePagedLookasideList(IN PPAGED_LOOKASIDE_LIST Lookaside, IN PALLOCATE_FUNCTION Allocate OPTIONAL, IN PFREE_FUNCTION Free OPTIONAL, IN ULONG Flags, IN SIZE_T Size, IN ULONG Tag, IN USHORT Depth)
Definition: lookas.c:274
PVOID Data
Definition: tunnel.c:24
struct _Entry Entry
Definition: kefuncs.h:640
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG Flags
Definition: tunnel.c:21
Definition: fatfs.h:173
#define KEY_READ
Definition: nt_native.h:1023
LARGE_INTEGER Time
Definition: tunnel.c:19
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define RtlInsertAsRightChild(ParentLinks, ChildLinks)
LONG NTSTATUS
Definition: precomp.h:26
VOID NTAPI FsRtlDeleteKeyFromTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey)
Definition: tunnel.c:588
LIST_ENTRY TimerQueueEntry
Definition: tunnel.c:18
#define POOL_COLD_ALLOCATION
static WCHAR String[]
Definition: stringtable.c:55
#define InsertTailList(ListHead, Entry)
LONG FsRtlCompareNodeAndKey(IN PTUNNEL_NODE_ENTRY CurEntry, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING KeyString)
Definition: tunnel.c:253
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
struct TraceInfo Info
#define PAGED_CODE()
Definition: video.h:57
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
_SEH2_TRY
Definition: create.c:4250
#define RtlInsertAsLeftChild(ParentLinks, ChildLinks)
uint32_t ULONG_PTR
Definition: typedefs.h:63
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
RTL_SPLAY_LINKS SplayInfo
Definition: tunnel.c:17
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
VOID NTAPI FsRtlAddToTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING ShortName, IN PUNICODE_STRING LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN PVOID Data)
Definition: tunnel.c:341
BOOLEAN NTAPI FsRtlFindInTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING Name, OUT PUNICODE_STRING ShortName, OUT PUNICODE_STRING LongName, IN OUT PULONG DataLength, OUT PVOID Data)
Definition: tunnel.c:765
long LONG
Definition: pedump.c:60
#define RtlIsLeftChild(Links)
VOID FsRtlFreeTunnelNode(IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList OPTIONAL)
Definition: tunnel.c:39
#define RtlInitializeSplayLinks(Links)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
void * PVOID
Definition: retypes.h:9
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
_In_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING _In_ BOOLEAN KeyByShortName
Definition: fsrtlfuncs.h:336
root entry for file system trees
Definition: entries.h:148
ULONG DataLength
Definition: tunnel.c:25
BOOLEAN NTAPI MmIsThisAnNtAsSystem(VOID)
Definition: mmsup.c:246
#define RtlParent(Links)
NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlDelete(_In_ PRTL_SPLAY_LINKS Links)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
VOID NTAPI FsRtlInitializeTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:891
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_In_ ULONGLONG DirectoryKey
Definition: fsrtlfuncs.h:336
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
char * PBOOLEAN
Definition: retypes.h:11
#define TUNNEL_FLAG_KEY_SHORT_NAME
Definition: tunnel.c:36
VOID FsRtlRemoveNodeFromTunnel(IN PTUNNEL Cache, IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList, OUT PBOOLEAN Rebalance)
Definition: tunnel.c:57
static const WCHAR L[]
Definition: oid.c:1250
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
ULONGLONG DirectoryKey
Definition: tunnel.c:20
#define TUNNEL_FLAG_POOL
Definition: tunnel.c:35
Definition: typedefs.h:117
PAGED_LOOKASIDE_LIST TunnelLookasideList
Definition: tunnel.c:30
Status
Definition: gdiplustypes.h:24
INIT_FUNCTION VOID FsRtlGetTunnelParameterValue(IN PUNICODE_STRING ParameterName, OUT PULONG Value)
Definition: tunnel.c:134
INIT_FUNCTION VOID NTAPI FsRtlInitializeTunnels(VOID)
Definition: tunnel.c:199
_SEH2_END
Definition: create.c:4424
#define DEFAULT_ENTRY_SIZE
Definition: tunnel.c:33
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
UNICODE_STRING ShortName
Definition: tunnel.c:23
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: classpnp.h:1209
_In_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING LongName
Definition: fsrtlfuncs.h:336
UNICODE_STRING LongName
Definition: tunnel.c:22
unsigned int * PULONG
Definition: retypes.h:1
#define OUT
Definition: typedefs.h:39
ULONG TunnelMaxEntries
Definition: tunnel.c:28
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
_Must_inspect_result_ NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlRealSuccessor(_In_ PRTL_SPLAY_LINKS Links)
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
ULONG TunnelMaxAge
Definition: tunnel.c:29
VOID NTAPI FsRtlDeleteTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:690
Definition: tunnel.c:16
base of all file and directory entries
Definition: entries.h:82
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
struct TUNNEL_NODE_ENTRY * PTUNNEL_NODE_ENTRY
LONGLONG QuadPart
Definition: typedefs.h:112
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68