ReactOS 0.4.16-dev-87-g3dfbe52
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;
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 */
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 */
386 }
387
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 */
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;
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}
#define PAGED_CODE()
unsigned char BOOLEAN
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1307
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
_In_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING LongName
Definition: fsrtlfuncs.h:338
_In_ ULONGLONG DirectoryKey
Definition: fsrtlfuncs.h:336
_In_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING _In_ BOOLEAN KeyByShortName
Definition: fsrtlfuncs.h:339
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
long LONG
Definition: pedump.c:60
Definition: fatfs.h:173
Definition: tunnel.c:16
LARGE_INTEGER Time
Definition: tunnel.c:19
RTL_SPLAY_LINKS SplayInfo
Definition: tunnel.c:17
ULONG DataLength
Definition: tunnel.c:25
LIST_ENTRY TimerQueueEntry
Definition: tunnel.c:18
ULONGLONG DirectoryKey
Definition: tunnel.c:20
ULONG Flags
Definition: tunnel.c:21
UNICODE_STRING LongName
Definition: tunnel.c:22
UNICODE_STRING ShortName
Definition: tunnel.c:23
PVOID Data
Definition: tunnel.c:24
Definition: typedefs.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
VOID FsRtlEmptyFreePoolList(IN PLIST_ENTRY PoolList)
Definition: tunnel.c:290
#define DEFAULT_ENTRY_SIZE
Definition: tunnel.c:33
ULONG TunnelMaxEntries
Definition: tunnel.c:28
VOID FsRtlPruneTunnelCache(IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
Definition: tunnel.c:86
#define TUNNEL_FLAG_POOL
Definition: tunnel.c:35
#define TUNNEL_FLAG_KEY_SHORT_NAME
Definition: tunnel.c:36
VOID FsRtlFreeTunnelNode(IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList OPTIONAL)
Definition: tunnel.c:39
PAGED_LOOKASIDE_LIST TunnelLookasideList
Definition: tunnel.c:30
LONG FsRtlCompareNodeAndKey(IN PTUNNEL_NODE_ENTRY CurEntry, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING KeyString)
Definition: tunnel.c:254
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint32_t ULONG
Definition: typedefs.h:59
_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:409
#define POOL_COLD_ALLOCATION
#define RtlParent(Links)
#define RtlInsertAsRightChild(ParentLinks, ChildLinks)
#define RtlIsLeftChild(Links)
#define RtlInitializeSplayLinks(Links)
#define RtlInsertAsLeftChild(ParentLinks, ChildLinks)
WCHAR * LPWSTR
Definition: xmlstorage.h:184

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}
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

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 FsRtlRemoveNodeFromTunnel(IN PTUNNEL Cache, IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList, OUT PBOOLEAN Rebalance)
Definition: tunnel.c:57
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Must_inspect_result_ NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlRealSuccessor(_In_ PRTL_SPLAY_LINKS Links)

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 */
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}
base of all file and directory entries
Definition: entries.h:83

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}
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964

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 {
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;
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}
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
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}
#define InsertHeadList(ListHead, Entry)
#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;
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 */
192
193 /* close key */
194 ZwClose(hKey);
195}
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: cdrom.h:961
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
@ KeyValueFullInformation
Definition: nt_native.h:1181
#define KEY_READ
Definition: nt_native.h:1023
#define L(x)
Definition: ntvdm.h:50
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
root entry for file system trees
Definition: entries.h:148
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413

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 */
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}
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274

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 */
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 */
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
ULONG TunnelMaxAge
Definition: tunnel.c:29
VOID FsRtlGetTunnelParameterValue(IN PUNICODE_STRING ParameterName, OUT PULONG Value)
Definition: tunnel.c:135

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 ASSERT(a)
Definition: mode.c:44
LONGLONG QuadPart
Definition: typedefs.h:114

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 PRTL_SPLAY_LINKS NTAPI RtlDelete(_In_ PRTL_SPLAY_LINKS Links)
NTSYSAPI VOID NTAPI RtlDeleteNoSplay(_In_ PRTL_SPLAY_LINKS Links, _Inout_ PRTL_SPLAY_LINKS *Root)

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