ReactOS  0.4.15-dev-2774-gc8ce0cc
tunnel.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
Include dependency graph for tunnel.c:

Go to the source code of this file.

Classes

struct  TUNNEL_NODE_ENTRY
 

Macros

#define NDEBUG
 
#define DEFAULT_EXTRA_SIZE   (72)
 
#define DEFAULT_ENTRY_SIZE   (sizeof(TUNNEL_NODE_ENTRY) + DEFAULT_EXTRA_SIZE)
 
#define TUNNEL_FLAG_POOL   0x2
 
#define TUNNEL_FLAG_KEY_SHORT_NAME   0x1
 

Typedefs

typedef struct TUNNEL_NODE_ENTRYPTUNNEL_NODE_ENTRY
 

Functions

VOID FsRtlFreeTunnelNode (IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList OPTIONAL)
 
VOID FsRtlRemoveNodeFromTunnel (IN PTUNNEL Cache, IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList, OUT PBOOLEAN Rebalance)
 
VOID FsRtlPruneTunnelCache (IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
 
VOID FsRtlGetTunnelParameterValue (IN PUNICODE_STRING ParameterName, OUT PULONG Value)
 
VOID NTAPI FsRtlInitializeTunnels (VOID)
 
LONG FsRtlCompareNodeAndKey (IN PTUNNEL_NODE_ENTRY CurEntry, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING KeyString)
 
VOID FsRtlEmptyFreePoolList (IN PLIST_ENTRY PoolList)
 
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)
 
VOID NTAPI FsRtlDeleteKeyFromTunnelCache (IN PTUNNEL Cache, IN ULONGLONG DirectoryKey)
 
VOID NTAPI FsRtlDeleteTunnelCache (IN PTUNNEL Cache)
 
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)
 
VOID NTAPI FsRtlInitializeTunnelCache (IN PTUNNEL Cache)
 

Variables

ULONG TunnelMaxEntries = 256
 
ULONG TunnelMaxAge = 15
 
PAGED_LOOKASIDE_LIST TunnelLookasideList
 

Macro Definition Documentation

◆ DEFAULT_ENTRY_SIZE

#define DEFAULT_ENTRY_SIZE   (sizeof(TUNNEL_NODE_ENTRY) + DEFAULT_EXTRA_SIZE)

Definition at line 33 of file tunnel.c.

◆ DEFAULT_EXTRA_SIZE

#define DEFAULT_EXTRA_SIZE   (72)

Definition at line 32 of file tunnel.c.

◆ NDEBUG

#define NDEBUG

Definition at line 13 of file tunnel.c.

◆ TUNNEL_FLAG_KEY_SHORT_NAME

#define TUNNEL_FLAG_KEY_SHORT_NAME   0x1

Definition at line 36 of file tunnel.c.

◆ TUNNEL_FLAG_POOL

#define TUNNEL_FLAG_POOL   0x2

Definition at line 35 of file tunnel.c.

Typedef Documentation

◆ PTUNNEL_NODE_ENTRY

Function Documentation

◆ FsRtlAddToTunnelCache()

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 at line 342 of file tunnel.c.

349 {
350  PTUNNEL_NODE_ENTRY NodeEntry = NULL;
351  PRTL_SPLAY_LINKS CurEntry, LastEntry;
352  ULONG Length;
353  LONG Result = 0;
354  BOOLEAN AllocatedFromPool = FALSE;
355  PUNICODE_STRING KeyString;
356  LIST_ENTRY PoolList;
357 
358  PAGED_CODE();
359 
360  /* check if tunnel cache is enabled */
361  if (!TunnelMaxEntries)
362  {
363  /* entries are disabled */
364  return;
365  }
366 
367  /* initialize free pool list */
368  InitializeListHead(&PoolList);
369 
370  /* calculate node length */
371  Length = sizeof(TUNNEL_NODE_ENTRY);
372 
373  /* add data size */
374  Length += DataLength;
375 
376  if (ShortName)
377  {
378  /* add short name length */
379  Length += ShortName->Length;
380  }
381 
382  if (LongName)
383  {
384  /* add short name length */
385  Length += LongName->Length;
386  }
387 
388  if (Length <= DEFAULT_ENTRY_SIZE)
389  {
390  /* get standard entry */
391  NodeEntry = ExAllocateFromPagedLookasideList(&TunnelLookasideList);
392  }
393 
394  if (NodeEntry == NULL)
395  {
396  /* bigger than default entry or allocation failed */
398  /* check for success */
399  if (NodeEntry == NULL)
400  {
401  /* out of memory */
402  return;
403  }
404 
405  AllocatedFromPool = TRUE;
406  }
407 
408  /* acquire lock */
409  ExAcquireFastMutex(&Cache->Mutex);
410 
411  /* now search cache for existing entries */
412  CurEntry = Cache->Cache;
413 
414  /* check which key should be used for search */
415  KeyString = (KeyByShortName ? ShortName : LongName);
416 
417  /* initialize last entry */
418  LastEntry = NULL;
419 
420  while(CurEntry)
421  {
422  /* compare current node */
424 
425  /* backup last entry */
426  LastEntry = CurEntry;
427 
428  if (Result > 0)
429  {
430  /* current directory key is bigger */
431  CurEntry = CurEntry->LeftChild;
432  }
433  else
434  {
435  if (Result == 0)
436  {
437  /* found equal entry */
438  break;
439  }
440 
441  /* current directory key is smaller */
442  CurEntry = CurEntry->RightChild;
443  }
444  }
445 
446  /* initialize node entry */
447  RtlInitializeSplayLinks(&NodeEntry->SplayInfo);
448 
449  if (CurEntry != NULL)
450  {
451  /* found existing item */
452  if (CurEntry->LeftChild)
453  {
454  /* update parent */
455  RtlInsertAsLeftChild(NodeEntry, CurEntry->LeftChild);
456  }
457 
458  if (CurEntry->RightChild)
459  {
460  /* update parent */
461  RtlInsertAsRightChild(NodeEntry, CurEntry->RightChild);
462  }
463 
464  if (CurEntry->Parent == CurEntry)
465  {
466  /* cur entry was root */
467  Cache->Cache = (struct _RTL_SPLAY_LINKS*)NodeEntry;
468  }
469  else
470  {
471  /* update parent node */
472  if (RtlIsLeftChild(CurEntry))
473  {
474  RtlInsertAsLeftChild(RtlParent(CurEntry), NodeEntry);
475  }
476  else
477  {
478  RtlInsertAsRightChild(RtlParent(CurEntry), NodeEntry);
479  }
480  }
481 
482  /* remove entry */
483  RemoveEntryList(&((PTUNNEL_NODE_ENTRY)CurEntry)->TimerQueueEntry);
484 
485  /* free node entry */
486  FsRtlFreeTunnelNode((PTUNNEL_NODE_ENTRY)CurEntry, &PoolList);
487 
488  /* decrement node count */
489  Cache->NumEntries--;
490  }
491  else
492  {
493  if (LastEntry == NULL)
494  {
495  /* first entry in tunnel cache */
496  Cache->Cache = (struct _RTL_SPLAY_LINKS*)NodeEntry;
497  }
498  else
499  {
500  if (Result > 0)
501  {
502  /* new left node */
503  RtlInsertAsLeftChild(LastEntry, NodeEntry);
504  }
505  else
506  {
507  /* new right node */
508  RtlInsertAsRightChild(LastEntry, NodeEntry);
509  }
510  }
511  }
512 
513  /* initialize entry */
514  KeQuerySystemTime(&NodeEntry->Time);
515 
516  NodeEntry->DirectoryKey = DirectoryKey;
517  NodeEntry->Flags = (AllocatedFromPool ? TUNNEL_FLAG_POOL : 0x0);
518  NodeEntry->Flags |= (KeyByShortName ? TUNNEL_FLAG_KEY_SHORT_NAME : 0x0);
519 
520  if (ShortName)
521  {
522  /* copy short name */
523  NodeEntry->ShortName.Length = ShortName->Length;
524  NodeEntry->ShortName.MaximumLength = ShortName->Length;
525  NodeEntry->ShortName.Buffer = (LPWSTR)((ULONG_PTR)NodeEntry + sizeof(TUNNEL_NODE_ENTRY));
526 
527  RtlMoveMemory(NodeEntry->ShortName.Buffer, ShortName->Buffer, ShortName->Length);
528  }
529  else
530  {
531  NodeEntry->ShortName.Length = NodeEntry->ShortName.MaximumLength = 0;
532  NodeEntry->ShortName.Buffer = NULL;
533  }
534 
535  if (LongName)
536  {
537  /* copy long name */
538  NodeEntry->LongName.Length = LongName->Length;
539  NodeEntry->LongName.MaximumLength = LongName->Length;
540  NodeEntry->LongName.Buffer = (LPWSTR)((ULONG_PTR)NodeEntry + sizeof(TUNNEL_NODE_ENTRY) + NodeEntry->ShortName.Length);
541 
543  }
544  else
545  {
546  NodeEntry->LongName.Length = NodeEntry->LongName.MaximumLength = 0;
547  NodeEntry->LongName.Buffer = NULL;
548  }
549 
550  NodeEntry->DataLength = DataLength;
551  NodeEntry->Data = (PVOID)((ULONG_PTR)NodeEntry + sizeof(TUNNEL_NODE_ENTRY) + NodeEntry->ShortName.Length + NodeEntry->LongName.Length);
552  RtlMoveMemory(NodeEntry->Data, Data, DataLength);
553 
554  /* increment node count */
555  Cache->NumEntries++;
556 
557  /* insert into list */
558  InsertTailList(&Cache->TimerQueue, &NodeEntry->TimerQueueEntry);
559 
560  /* prune cache */
561  FsRtlPruneTunnelCache(Cache, &PoolList);
562 
563  /* release lock */
564  ExReleaseFastMutex(&Cache->Mutex);
565 
566  /* free pool list */
567  FsRtlEmptyFreePoolList(&PoolList);
568 }
VOID FsRtlEmptyFreePoolList(IN PLIST_ENTRY PoolList)
Definition: tunnel.c:290
#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:1303
VOID FsRtlPruneTunnelCache(IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
Definition: tunnel.c:86
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
PVOID Data
Definition: tunnel.c:24
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG Flags
Definition: tunnel.c:21
Definition: fatfs.h:173
#define TRUE
Definition: types.h:120
LARGE_INTEGER Time
Definition: tunnel.c:19
#define RtlInsertAsRightChild(ParentLinks, ChildLinks)
LIST_ENTRY TimerQueueEntry
Definition: tunnel.c:18
#define POOL_COLD_ALLOCATION
#define InsertTailList(ListHead, Entry)
LONG FsRtlCompareNodeAndKey(IN PTUNNEL_NODE_ENTRY CurEntry, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING KeyString)
Definition: tunnel.c:254
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define RtlInsertAsLeftChild(ParentLinks, ChildLinks)
uint32_t ULONG_PTR
Definition: typedefs.h:65
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
RTL_SPLAY_LINKS SplayInfo
Definition: tunnel.c:17
#define FALSE
Definition: types.h:117
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)
unsigned char BOOLEAN
_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
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1437
void * PVOID
Definition: retypes.h:9
_In_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING _In_ BOOLEAN KeyByShortName
Definition: fsrtlfuncs.h:336
ULONG DataLength
Definition: tunnel.c:25
#define RtlParent(Links)
_In_ ULONGLONG DirectoryKey
Definition: fsrtlfuncs.h:336
#define TUNNEL_FLAG_KEY_SHORT_NAME
Definition: tunnel.c:36
#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:119
PAGED_LOOKASIDE_LIST TunnelLookasideList
Definition: tunnel.c:30
#define DEFAULT_ENTRY_SIZE
Definition: tunnel.c:33
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_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING LongName
Definition: fsrtlfuncs.h:336
UNICODE_STRING LongName
Definition: tunnel.c:22
#define NULL
Definition: types.h:112
ULONG TunnelMaxEntries
Definition: tunnel.c:28
unsigned int ULONG
Definition: retypes.h:1
WCHAR * LPWSTR
Definition: xmlstorage.h:184
Definition: tunnel.c:16
#define PAGED_CODE()

Referenced by DuplicatesTest(), FatTunnelFcbOrDcb(), and TestFsRtlAddToTunnelCache().

◆ FsRtlCompareNodeAndKey()

LONG FsRtlCompareNodeAndKey ( IN PTUNNEL_NODE_ENTRY  CurEntry,
IN ULONGLONG  DirectoryKey,
IN PUNICODE_STRING  KeyString 
)

Definition at line 254 of file tunnel.c.

258 {
260  LONG Ret;
261 
262  if (DirectoryKey > CurEntry->DirectoryKey)
263  {
264  Ret = 1;
265  }
266  else if (DirectoryKey < CurEntry->DirectoryKey)
267  {
268  Ret = -1;
269  }
270  else
271  {
272  if (CurEntry->Flags & TUNNEL_FLAG_KEY_SHORT_NAME)
273  {
274  /* use short name as key */
275  String = &CurEntry->ShortName;
276  }
277  else
278  {
279  /* use long name as key */
280  String = &CurEntry->LongName;
281  }
282 
283  Ret = RtlCompareUnicodeString(KeyString, String, TRUE);
284  }
285 
286  return Ret;
287 }
#define TRUE
Definition: types.h:120
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
long LONG
Definition: pedump.c:60
_In_ ULONGLONG DirectoryKey
Definition: fsrtlfuncs.h:336
#define TUNNEL_FLAG_KEY_SHORT_NAME
Definition: tunnel.c:36
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31

Referenced by FsRtlAddToTunnelCache(), and FsRtlFindInTunnelCache().

◆ FsRtlDeleteKeyFromTunnelCache()

VOID NTAPI FsRtlDeleteKeyFromTunnelCache ( IN PTUNNEL  Cache,
IN ULONGLONG  DirectoryKey 
)

Definition at line 589 of file tunnel.c.

591 {
592  BOOLEAN Rebalance = TRUE;
593  LIST_ENTRY PoolList;
594  PTUNNEL_NODE_ENTRY CurNode;
595  PRTL_SPLAY_LINKS CurEntry, LastEntry = NULL, Successors;
596 
597  PAGED_CODE();
598 
599  /* check if tunnel cache is enabled */
600  if (!TunnelMaxEntries)
601  {
602  /* entries are disabled */
603  return;
604  }
605 
606  /* initialize free pool list */
607  InitializeListHead(&PoolList);
608 
609  /* acquire lock */
610  ExAcquireFastMutex(&Cache->Mutex);
611 
612  /* Look for the entry */
613  CurEntry = Cache->Cache;
614  while (CurEntry)
615  {
616  CurNode = CONTAINING_RECORD(CurEntry, TUNNEL_NODE_ENTRY, SplayInfo);
617 
618  if (CurNode->DirectoryKey > DirectoryKey)
619  {
620  /* current directory key is bigger */
621  CurEntry = CurEntry->LeftChild;
622  }
623  else if (CurNode->DirectoryKey < DirectoryKey)
624  {
625  /* if we have already found one suitable, break */
626  if (LastEntry != NULL)
627  {
628  break;
629  }
630 
631  /* current directory key is smaller */
632  CurEntry = CurEntry->RightChild;
633  }
634  else
635  {
636  /* save and look for another */
637  LastEntry = CurEntry;
638  CurEntry = CurEntry->LeftChild;
639  }
640  }
641 
642  /* was it found? */
643  if (LastEntry == NULL)
644  {
645  /* release tunnel lock */
646  ExReleaseFastMutex(&Cache->Mutex);
647 
648  return;
649  }
650 
651  /* delete any matching key */
652  do
653  {
654  CurNode = CONTAINING_RECORD(LastEntry, TUNNEL_NODE_ENTRY, SplayInfo);
655 
656  Successors = RtlRealSuccessor(LastEntry);
657  if (CurNode->DirectoryKey != DirectoryKey)
658  {
659  break;
660  }
661 
662  /* remove from tunnel */
663  FsRtlRemoveNodeFromTunnel(Cache, CurNode, &PoolList, &Rebalance);
664  LastEntry = Successors;
665  }
666  while (LastEntry != NULL);
667 
668  /* release tunnel lock */
669  ExReleaseFastMutex(&Cache->Mutex);
670 
671  /* free pool */
672  FsRtlEmptyFreePoolList(&PoolList);
673 }
VOID FsRtlEmptyFreePoolList(IN PLIST_ENTRY PoolList)
Definition: tunnel.c:290
Definition: fatfs.h:173
#define TRUE
Definition: types.h:120
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
unsigned char BOOLEAN
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 DirectoryKey
Definition: fsrtlfuncs.h:336
VOID FsRtlRemoveNodeFromTunnel(IN PTUNNEL Cache, IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList, OUT PBOOLEAN Rebalance)
Definition: tunnel.c:57
ULONGLONG DirectoryKey
Definition: tunnel.c:20
Definition: typedefs.h:119
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
ULONG TunnelMaxEntries
Definition: tunnel.c:28
_Must_inspect_result_ NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlRealSuccessor(_In_ PRTL_SPLAY_LINKS Links)
Definition: tunnel.c:16
#define PAGED_CODE()

Referenced by DuplicatesTest(), FatTunnelFcbOrDcb(), and TestFsRtlDeleteKeyFromTunnelCache().

◆ FsRtlDeleteTunnelCache()

VOID NTAPI FsRtlDeleteTunnelCache ( IN PTUNNEL  Cache)

Definition at line 691 of file tunnel.c.

692 {
693  PLIST_ENTRY Entry, NextEntry;
694  PTUNNEL_NODE_ENTRY CurEntry;
695 
696  PAGED_CODE();
697 
698  /* check if tunnel cache is enabled */
699  if (!TunnelMaxEntries)
700  {
701  /* entries are disabled */
702  return;
703  }
704 
705  /* free all entries */
706  Entry = Cache->TimerQueue.Flink;
707 
708  while(Entry != &Cache->TimerQueue)
709  {
710  /* get node entry */
711  CurEntry = CONTAINING_RECORD(Entry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
712 
713  /* get next entry */
714  NextEntry = Entry->Flink;
715 
716  /* remove entry from list */
717  RemoveEntryList(&CurEntry->TimerQueueEntry);
718 
719  /* free entry */
720  FsRtlFreeTunnelNode(CurEntry, NULL);
721 
722  /* move to next entry */
723  Entry = NextEntry;
724  }
725 
726  /* reset object */
727  Cache->Cache = NULL;
728  Cache->NumEntries = 0;
729  InitializeListHead(&Cache->TimerQueue);
730 }
struct _Entry Entry
Definition: kefuncs.h:627
Definition: fatfs.h:173
LIST_ENTRY TimerQueueEntry
Definition: tunnel.c:18
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
VOID FsRtlFreeTunnelNode(IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList OPTIONAL)
Definition: tunnel.c:39
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
Definition: typedefs.h:119
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
ULONG TunnelMaxEntries
Definition: tunnel.c:28
Definition: tunnel.c:16
base of all file and directory entries
Definition: entries.h:82
#define PAGED_CODE()

Referenced by DuplicatesTest(), FatDeleteVcb(), and START_TEST().

◆ FsRtlEmptyFreePoolList()

VOID FsRtlEmptyFreePoolList ( IN PLIST_ENTRY  PoolList)

Definition at line 290 of file tunnel.c.

292 {
293  PLIST_ENTRY CurEntry;
294  PTUNNEL_NODE_ENTRY CurNode;
295 
296  /* loop over all the entry */
297  while (!IsListEmpty(PoolList))
298  {
299  /* and free them, one by one */
300  CurEntry = RemoveHeadList(PoolList);
301  CurNode = CONTAINING_RECORD(CurEntry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
302  FsRtlFreeTunnelNode(CurNode, 0);
303  }
304 }
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
VOID FsRtlFreeTunnelNode(IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList OPTIONAL)
Definition: tunnel.c:39
FORCEINLINE PLIST_ENTRY RemoveHeadList(_Inout_ PLIST_ENTRY ListHead)
Definition: rtlfuncs.h:128
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
Definition: typedefs.h:119
Definition: tunnel.c:16

Referenced by FsRtlAddToTunnelCache(), FsRtlDeleteKeyFromTunnelCache(), and FsRtlFindInTunnelCache().

◆ FsRtlFindInTunnelCache()

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 at line 766 of file tunnel.c.

773 {
774  BOOLEAN Ret = FALSE;
775  PTUNNEL_NODE_ENTRY CurEntry;
776  LIST_ENTRY PoolList;
777  //NTSTATUS Status;
778  LONG Result;
779 
780  PAGED_CODE();
781 
782  /* check if tunnel cache is enabled */
783  if (!TunnelMaxEntries)
784  {
785  /* entries are disabled */
786  return FALSE;
787  }
788 
789  /* initialize free pool list */
790  InitializeListHead(&PoolList);
791 
792  /* acquire tunnel lock */
793  ExAcquireFastMutex(&Cache->Mutex);
794 
795  /* prune old entries */
796  FsRtlPruneTunnelCache(Cache, &PoolList);
797 
798  /* now search cache for existing entries */
799  CurEntry = (PTUNNEL_NODE_ENTRY)Cache->Cache;
800 
801  while(CurEntry)
802  {
803  /* compare current node */
805 
806  if (Result > 0)
807  {
808  /* current directory key is bigger */
809  CurEntry = (PTUNNEL_NODE_ENTRY)CurEntry->SplayInfo.LeftChild;
810  }
811  else
812  {
813  if (Result == 0)
814  {
815  /* found equal entry */
816  break;
817  }
818 
819  /* current directory key is smaller */
820  CurEntry = (PTUNNEL_NODE_ENTRY)CurEntry->SplayInfo.RightChild;
821  }
822  }
823 
824  if (CurEntry != NULL)
825  {
826  _SEH2_TRY
827  {
828  /* copy short name */
830 
831  /* check size */
832  if (LongName->MaximumLength < CurEntry->LongName.Length)
833  {
834  /* buffer is too small */
836  if (LongName->Buffer)
837  {
838  LongName->Length = CurEntry->LongName.Length;
840  RtlMoveMemory(LongName->Buffer, CurEntry->LongName.Buffer, CurEntry->LongName.Length);
841  }
842  }
843  else
844  {
845  /* buffer is big enough */
847  }
848 
849  /* copy data */
850  RtlMoveMemory(Data, CurEntry->Data, CurEntry->DataLength);
851 
852  /* store size */
853  *DataLength = CurEntry->DataLength;
854 
855  /* done */
856  Ret = TRUE;
857  }
859  {
860  /* Get the status */
861  //Status = _SEH2_GetExceptionCode();
862  }
863  _SEH2_END;
864 
865  }
866 
867  /* release tunnel lock */
868  ExReleaseFastMutex(&Cache->Mutex);
869 
870  /* free pool */
871  FsRtlEmptyFreePoolList(&PoolList);
872 
873  return Ret;
874 }
VOID FsRtlEmptyFreePoolList(IN PLIST_ENTRY PoolList)
Definition: tunnel.c:290
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1303
VOID FsRtlPruneTunnelCache(IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
Definition: tunnel.c:86
PVOID Data
Definition: tunnel.c:24
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: fatfs.h:173
#define TRUE
Definition: types.h:120
LONG FsRtlCompareNodeAndKey(IN PTUNNEL_NODE_ENTRY CurEntry, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING KeyString)
Definition: tunnel.c:254
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
_SEH2_TRY
Definition: create.c:4226
RTL_SPLAY_LINKS SplayInfo
Definition: tunnel.c:17
#define FALSE
Definition: types.h:117
long LONG
Definition: pedump.c:60
unsigned char BOOLEAN
_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
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1437
ULONG DataLength
Definition: tunnel.c:25
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_In_ ULONGLONG DirectoryKey
Definition: fsrtlfuncs.h:336
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Definition: typedefs.h:119
_SEH2_END
Definition: create.c:4400
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_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING LongName
Definition: fsrtlfuncs.h:336
UNICODE_STRING LongName
Definition: tunnel.c:22
#define NULL
Definition: types.h:112
ULONG TunnelMaxEntries
Definition: tunnel.c:28
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
Definition: tunnel.c:16
struct TUNNEL_NODE_ENTRY * PTUNNEL_NODE_ENTRY
#define PAGED_CODE()

Referenced by DuplicatesTest(), FatSetRenameInfo(), and TestFsRtlFindInTunnelCache().

◆ FsRtlFreeTunnelNode()

VOID FsRtlFreeTunnelNode ( IN PTUNNEL_NODE_ENTRY  CurEntry,
IN PLIST_ENTRY PoolList  OPTIONAL 
)

Definition at line 39 of file tunnel.c.

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 }
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
#define TUNNEL_FLAG_POOL
Definition: tunnel.c:35
PAGED_LOOKASIDE_LIST TunnelLookasideList
Definition: tunnel.c:30
#define ExFreePool(addr)
Definition: env_spec_w32.h:352

Referenced by FsRtlAddToTunnelCache(), FsRtlDeleteTunnelCache(), FsRtlEmptyFreePoolList(), and FsRtlRemoveNodeFromTunnel().

◆ FsRtlGetTunnelParameterValue()

VOID FsRtlGetTunnelParameterValue ( IN PUNICODE_STRING  ParameterName,
OUT PULONG  Value 
)

Definition at line 135 of file tunnel.c.

138 {
139  UNICODE_STRING Root = RTL_CONSTANT_STRING(L"Registry\\Machine\\System\\CurrentControlSet\\Control\\FileSystem");
141  HANDLE hKey;
143  ULONG Length;
145 
146  /* initialize object attributes */
148 
149  /* open registry key */
150  Status = ZwOpenKey(&hKey, KEY_READ, &ObjectAttributes);
151 
152  if (!NT_SUCCESS(Status))
153  {
154  /* failed to open key */
155  return;
156  }
157 
158  /* query value size */
159  Status = ZwQueryValueKey(hKey, ParameterName, KeyValueFullInformation, NULL, 0, &Length);
160 
162  {
163  /* failed to query size */
164  ZwClose(hKey);
165  return;
166  }
167 
168  /* allocate buffer */
170 
171  if (!Info)
172  {
173  /* out of memory */
174  ZwClose(hKey);
175  return;
176  }
177 
178  /* query value */
179  Status = ZwQueryValueKey(hKey, ParameterName, KeyValueFullInformation, NULL, 0, &Length);
180 
181  if (NT_SUCCESS(Status))
182  {
183  if (Info->DataLength)
184  {
185  /* store result */
186  *Value = (ULONG)((ULONG_PTR)Info + Info->DataOffset);
187  }
188  }
189 
190  /* free buffer */
191  ExFreePool(Info);
192 
193  /* close key */
194  ZwClose(hKey);
195 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:65
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:683
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:406
Status
Definition: gdiplustypes.h:24
root entry for file system trees
Definition: entries.h:148
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: cdrom.h:960
FxAutoRegKey hKey
#define NULL
Definition: types.h:112
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by FsRtlInitializeTunnels().

◆ FsRtlInitializeTunnelCache()

VOID NTAPI FsRtlInitializeTunnelCache ( IN PTUNNEL  Cache)

Definition at line 892 of file tunnel.c.

893 {
894  PAGED_CODE();
895 
896  /* initialize mutex */
897  ExInitializeFastMutex(&Cache->Mutex);
898 
899  /* initialize node tree */
900  Cache->Cache = NULL;
901 
902  /* initialize timer list */
903  InitializeListHead(&Cache->TimerQueue);
904 
905  /* initialize node count */
906  Cache->NumEntries = 0;
907 }
Definition: fatfs.h:173
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define PAGED_CODE()

Referenced by _Requires_lock_held_(), DuplicatesTest(), and TestFsRtlInitializeTunnelCache().

◆ FsRtlInitializeTunnels()

VOID NTAPI FsRtlInitializeTunnels ( VOID  )

Definition at line 200 of file tunnel.c.

201 {
202  ULONG TunnelEntries;
203  UNICODE_STRING MaximumTunnelEntryAgeInSeconds = RTL_CONSTANT_STRING(L"MaximumTunnelEntryAgeInSeconds");
204  UNICODE_STRING MaximumTunnelEntries = RTL_CONSTANT_STRING( L"MaximumTunnelEntries");
205 
206  /* check for nt */
207  if (MmIsThisAnNtAsSystem())
208  {
209  /* default */
210  TunnelMaxEntries = 1024;
211  }
212 
213  /* check for custom override of max entries*/
214  FsRtlGetTunnelParameterValue(&MaximumTunnelEntries, &TunnelMaxEntries);
215 
216  /* check for custom override of age*/
217  FsRtlGetTunnelParameterValue(&MaximumTunnelEntryAgeInSeconds, &TunnelMaxAge);
218 
219  if (!TunnelMaxAge)
220  {
221  /* no age means no entries */
222  TunnelMaxEntries = 0;
223  }
224 
225  /* get max entries */
226  TunnelEntries = TunnelMaxEntries;
227 
228  /* convert to ticks */
229  TunnelMaxAge *= 10000000;
230 
231  if(TunnelMaxEntries <= 65535)
232  {
233  /* use max 256 entries */
234  TunnelEntries = TunnelMaxEntries / 16;
235  }
236 
237  if(!TunnelEntries && TunnelMaxEntries )
238  {
239  /* max tunnel entries was too small */
240  TunnelEntries = TunnelMaxEntries + 1;
241  }
242 
243  if (TunnelEntries > 0xFFFF)
244  {
245  /* max entries is 256 */
246  TunnelEntries = 256;
247  }
248 
249  /* initialize look aside list */
251 }
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:270
BOOLEAN NTAPI MmIsThisAnNtAsSystem(VOID)
Definition: mmsup.c:246
static const WCHAR L[]
Definition: oid.c:1250
PAGED_LOOKASIDE_LIST TunnelLookasideList
Definition: tunnel.c:30
#define DEFAULT_ENTRY_SIZE
Definition: tunnel.c:33
#define NULL
Definition: types.h:112
ULONG TunnelMaxEntries
Definition: tunnel.c:28
unsigned int ULONG
Definition: retypes.h:1
ULONG TunnelMaxAge
Definition: tunnel.c:29
VOID FsRtlGetTunnelParameterValue(IN PUNICODE_STRING ParameterName, OUT PULONG Value)
Definition: tunnel.c:135
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by FsRtlInitSystem().

◆ FsRtlPruneTunnelCache()

VOID FsRtlPruneTunnelCache ( IN PTUNNEL  Cache,
IN PLIST_ENTRY  PoolList 
)

Definition at line 86 of file tunnel.c.

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  ASSERT(!IsListEmpty(&Cache->TimerQueue));
128  CurEntry = CONTAINING_RECORD(Cache->TimerQueue.Flink, TUNNEL_NODE_ENTRY, TimerQueueEntry);
129  FsRtlRemoveNodeFromTunnel(Cache, CurEntry, PoolList, &Rebalance);
130  }
131 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
struct _Entry Entry
Definition: kefuncs.h:627
Definition: fatfs.h:173
#define TRUE
Definition: types.h:120
LARGE_INTEGER Time
Definition: tunnel.c:19
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
unsigned char BOOLEAN
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
#define ASSERT(a)
Definition: mode.c:44
VOID FsRtlRemoveNodeFromTunnel(IN PTUNNEL Cache, IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList, OUT PBOOLEAN Rebalance)
Definition: tunnel.c:57
Definition: typedefs.h:119
ULONG TunnelMaxEntries
Definition: tunnel.c:28
ULONG TunnelMaxAge
Definition: tunnel.c:29
Definition: tunnel.c:16
base of all file and directory entries
Definition: entries.h:82
LONGLONG QuadPart
Definition: typedefs.h:114
#define PAGED_CODE()

Referenced by FsRtlAddToTunnelCache(), and FsRtlFindInTunnelCache().

◆ FsRtlRemoveNodeFromTunnel()

VOID FsRtlRemoveNodeFromTunnel ( IN PTUNNEL  Cache,
IN PTUNNEL_NODE_ENTRY  CurEntry,
IN PLIST_ENTRY  PoolList,
OUT PBOOLEAN  Rebalance 
)

Definition at line 57 of file tunnel.c.

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 }
NTSYSAPI VOID NTAPI RtlDeleteNoSplay(_In_ PRTL_SPLAY_LINKS Links, _Inout_ PRTL_SPLAY_LINKS *Root)
Definition: fatfs.h:173
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FALSE
Definition: types.h:117
VOID FsRtlFreeTunnelNode(IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList OPTIONAL)
Definition: tunnel.c:39
NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlDelete(_In_ PRTL_SPLAY_LINKS Links)

Referenced by FsRtlDeleteKeyFromTunnelCache(), and FsRtlPruneTunnelCache().

Variable Documentation

◆ TunnelLookasideList

PAGED_LOOKASIDE_LIST TunnelLookasideList

Definition at line 30 of file tunnel.c.

Referenced by FsRtlAddToTunnelCache(), FsRtlFreeTunnelNode(), and FsRtlInitializeTunnels().

◆ TunnelMaxAge

ULONG TunnelMaxAge = 15

Definition at line 29 of file tunnel.c.

Referenced by FsRtlInitializeTunnels(), and FsRtlPruneTunnelCache().

◆ TunnelMaxEntries