ReactOS  0.4.14-dev-599-g2d4d3f5
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)
 
INIT_FUNCTION VOID FsRtlGetTunnelParameterValue (IN PUNICODE_STRING ParameterName, OUT PULONG Value)
 
INIT_FUNCTION 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 341 of file tunnel.c.

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 }
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
VOID FsRtlPruneTunnelCache(IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
Definition: tunnel.c:86
#define TRUE
Definition: types.h:120
PVOID Data
Definition: tunnel.c:24
USHORT MaximumLength
Definition: env_spec_w32.h:370
ULONG Flags
Definition: tunnel.c:21
Definition: fatfs.h:173
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:253
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define PAGED_CODE()
Definition: video.h:57
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#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
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
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
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_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_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:117
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
ULONG TunnelMaxEntries
Definition: tunnel.c:28
unsigned int ULONG
Definition: retypes.h:1
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
Definition: tunnel.c:16

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

◆ FsRtlCompareNodeAndKey()

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

Definition at line 253 of file tunnel.c.

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 }
#define TRUE
Definition: types.h:120
static WCHAR String[]
Definition: stringtable.c:55
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 588 of file tunnel.c.

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 }
VOID FsRtlEmptyFreePoolList(IN PLIST_ENTRY PoolList)
Definition: tunnel.c:289
#define TRUE
Definition: types.h:120
Definition: fatfs.h:173
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define PAGED_CODE()
Definition: video.h:57
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
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:117
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG TunnelMaxEntries
Definition: tunnel.c:28
_Must_inspect_result_ NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlRealSuccessor(_In_ PRTL_SPLAY_LINKS Links)
Definition: tunnel.c:16

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

◆ FsRtlDeleteTunnelCache()

VOID NTAPI FsRtlDeleteTunnelCache ( IN PTUNNEL  Cache)

Definition at line 690 of file tunnel.c.

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 }
struct _Entry Entry
Definition: kefuncs.h:640
Definition: fatfs.h:173
LIST_ENTRY TimerQueueEntry
Definition: tunnel.c:18
#define PAGED_CODE()
Definition: video.h:57
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
smooth NULL
Definition: ftsmooth.c:416
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:117
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
ULONG TunnelMaxEntries
Definition: tunnel.c:28
Definition: tunnel.c:16
base of all file and directory entries
Definition: entries.h:82

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

◆ FsRtlEmptyFreePoolList()

VOID FsRtlEmptyFreePoolList ( IN PLIST_ENTRY  PoolList)

Definition at line 289 of file tunnel.c.

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 }
_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:117
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 765 of file tunnel.c.

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 }
VOID FsRtlEmptyFreePoolList(IN PLIST_ENTRY PoolList)
Definition: tunnel.c:289
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1294
VOID FsRtlPruneTunnelCache(IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
Definition: tunnel.c:86
#define TRUE
Definition: types.h:120
PVOID Data
Definition: tunnel.c:24
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: fatfs.h:173
LONG FsRtlCompareNodeAndKey(IN PTUNNEL_NODE_ENTRY CurEntry, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING KeyString)
Definition: tunnel.c:253
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#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)
_SEH2_TRY
Definition: create.c:4250
RTL_SPLAY_LINKS SplayInfo
Definition: tunnel.c:17
long LONG
Definition: pedump.c:60
#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
ULONG DataLength
Definition: tunnel.c:25
_In_ ULONGLONG DirectoryKey
Definition: fsrtlfuncs.h:336
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Definition: typedefs.h:117
_SEH2_END
Definition: create.c:4424
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
ULONG TunnelMaxEntries
Definition: tunnel.c:28
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
Definition: tunnel.c:16
struct TUNNEL_NODE_ENTRY * PTUNNEL_NODE_ENTRY

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()

INIT_FUNCTION VOID FsRtlGetTunnelParameterValue ( IN PUNICODE_STRING  ParameterName,
OUT PULONG  Value 
)

Definition at line 134 of file tunnel.c.

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 }
_In_opt_ ULONG _Out_ PULONG Value
Definition: rtlfuncs.h:2343
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
struct TraceInfo Info
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
uint32_t ULONG_PTR
Definition: typedefs.h:63
smooth NULL
Definition: ftsmooth.c:416
root entry for file system trees
Definition: entries.h:148
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
Status
Definition: gdiplustypes.h:24
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: classpnp.h:1209
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 891 of file tunnel.c.

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 }
Definition: fatfs.h:173
#define PAGED_CODE()
Definition: video.h:57
smooth NULL
Definition: ftsmooth.c:416
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944

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

◆ FsRtlInitializeTunnels()

INIT_FUNCTION VOID NTAPI FsRtlInitializeTunnels ( VOID  )

Definition at line 199 of file tunnel.c.

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 }
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
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN NTAPI MmIsThisAnNtAsSystem(VOID)
Definition: mmsup.c:246
static const WCHAR L[]
Definition: oid.c:1250
PAGED_LOOKASIDE_LIST TunnelLookasideList
Definition: tunnel.c:30
INIT_FUNCTION VOID FsRtlGetTunnelParameterValue(IN PUNICODE_STRING ParameterName, OUT PULONG Value)
Definition: tunnel.c:134
#define DEFAULT_ENTRY_SIZE
Definition: tunnel.c:33
ULONG TunnelMaxEntries
Definition: tunnel.c:28
unsigned int ULONG
Definition: retypes.h:1
ULONG TunnelMaxAge
Definition: tunnel.c:29
#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  CurEntry = CONTAINING_RECORD(Entry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
128  FsRtlRemoveNodeFromTunnel(Cache, CurEntry, PoolList, &Rebalance);
129  }
130 }
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define TRUE
Definition: types.h:120
struct _Entry Entry
Definition: kefuncs.h:640
Definition: fatfs.h:173
LARGE_INTEGER Time
Definition: tunnel.c:19
#define PAGED_CODE()
Definition: video.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
VOID FsRtlRemoveNodeFromTunnel(IN PTUNNEL Cache, IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList, OUT PBOOLEAN Rebalance)
Definition: tunnel.c:57
Definition: typedefs.h:117
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:112

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
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