ReactOS 0.4.16-dev-340-g0540c21
tunnel.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Kernel
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: ntoskrnl/fsrtl/tunnel.c
5 * PURPOSE: Provides the Tunnel Cache implementation for file system drivers.
6 * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
7 * Pierre Schweitzer (pierre@reactos.org)
8 */
9
10/* INCLUDES ******************************************************************/
11
12#include <ntoskrnl.h>
13#define NDEBUG
14#include <debug.h>
15
16typedef struct {
27
31
32#define DEFAULT_EXTRA_SIZE (72)
33#define DEFAULT_ENTRY_SIZE (sizeof(TUNNEL_NODE_ENTRY) + DEFAULT_EXTRA_SIZE)
34
35#define TUNNEL_FLAG_POOL 0x2
36#define TUNNEL_FLAG_KEY_SHORT_NAME 0x1
37
38VOID
40 IN PTUNNEL_NODE_ENTRY CurEntry,
41 IN PLIST_ENTRY PoolList OPTIONAL)
42{
43 if (PoolList)
44 {
45 /* divert the linked list entry, it's not required anymore, but we need it */
46 InsertHeadList(PoolList, &CurEntry->TimerQueueEntry);
47 return;
48 }
49
50 if (CurEntry->Flags & TUNNEL_FLAG_POOL)
51 ExFreePool(CurEntry);
52 else
53 ExFreeToPagedLookasideList(&TunnelLookasideList, CurEntry);
54}
55
56VOID
59 IN PTUNNEL_NODE_ENTRY CurEntry,
60 IN PLIST_ENTRY PoolList,
61 OUT PBOOLEAN Rebalance)
62{
63 /* delete entry and rebalance if required */
64 if (Rebalance && *Rebalance)
65 {
66 Cache->Cache = RtlDelete(&CurEntry->SplayInfo);
67 /* reset */
68 *Rebalance = FALSE;
69 }
70 else
71 {
72 RtlDeleteNoSplay(&CurEntry->SplayInfo, &Cache->Cache);
73 }
74
75 /* remove entry */
76 RemoveEntryList(&CurEntry->TimerQueueEntry);
77
78 /* free node entry */
79 FsRtlFreeTunnelNode(CurEntry, PoolList);
80
81 /* decrement node count */
82 Cache->NumEntries--;
83}
84
85VOID
88 IN PLIST_ENTRY PoolList)
89{
90 PLIST_ENTRY Entry, NextEntry;
91 PTUNNEL_NODE_ENTRY CurEntry;
92 LARGE_INTEGER CurTime, OldTime;
93 BOOLEAN Rebalance = TRUE;
94 PAGED_CODE();
95
96 /* query time */
97 KeQuerySystemTime(&CurTime);
98
99 /* subtract maximum node age */
100 OldTime.QuadPart = CurTime.QuadPart - TunnelMaxAge;
101
102 /* free all entries */
103 Entry = Cache->TimerQueue.Flink;
104
105 while(Entry != &Cache->TimerQueue)
106 {
107 /* get node entry */
108 CurEntry = CONTAINING_RECORD(Entry, TUNNEL_NODE_ENTRY, TimerQueueEntry);
109
110 /* get next entry */
111 NextEntry = Entry->Flink;
112
113 /* prune if expired OR if in advance in time */
114 if (CurEntry->Time.QuadPart < OldTime.QuadPart ||
115 CurEntry->Time.QuadPart > CurTime.QuadPart)
116 {
117 FsRtlRemoveNodeFromTunnel(Cache, CurEntry, PoolList, &Rebalance);
118 }
119
120 /* move to next entry */
121 Entry = NextEntry;
122 }
123
124 /* If we have too many entries */
125 while (Cache->NumEntries > TunnelMaxEntries)
126 {
127 ASSERT(!IsListEmpty(&Cache->TimerQueue));
128 CurEntry = CONTAINING_RECORD(Cache->TimerQueue.Flink, TUNNEL_NODE_ENTRY, TimerQueueEntry);
129 FsRtlRemoveNodeFromTunnel(Cache, CurEntry, PoolList, &Rebalance);
130 }
131}
132
133CODE_SEG("INIT")
134VOID
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}
196
197CODE_SEG("INIT")
198VOID
199NTAPI
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}
252
253LONG
255 IN PTUNNEL_NODE_ENTRY CurEntry,
257 IN PUNICODE_STRING KeyString)
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}
288
289VOID
291 IN PLIST_ENTRY PoolList)
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}
305
306/* PUBLIC FUNCTIONS **********************************************************/
307
308/*++
309 * @name FsRtlAddToTunnelCache
310 * @implemented
311 *
312 * FILLME
313 *
314 * @param Cache
315 * FILLME
316 *
317 * @param DirectoryKey
318 * FILLME
319 *
320 * @param ShortName
321 * FILLME
322 *
323 * @param LongName
324 * FILLME
325 *
326 * @param KeyByShortName
327 * FILLME
328 *
329 * @param DataLength
330 * FILLME
331 *
332 * @param Data
333 * FILLME
334 *
335 * @return None
336 *
337 * @remarks None
338 *
339 *--*/
340VOID
341NTAPI
348 IN PVOID Data)
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}
569
570/*++
571 * @name FsRtlDeleteKeyFromTunnelCache
572 * @implemented
573 *
574 * FILLME
575 *
576 * @param Cache
577 * FILLME
578 *
579 * @param DirectoryKey
580 * FILLME
581 *
582 * @return None
583 *
584 * @remarks None
585 *
586 *--*/
587VOID
588NTAPI
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}
674
675/*++
676 * @name FsRtlDeleteTunnelCache
677 * @implemented
678 *
679 * FILLME
680 *
681 * @param Cache
682 * FILLME
683 *
684 * @return None
685 *
686 * @remarks None
687 *
688 *--*/
689VOID
690NTAPI
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}
731
732/*++
733 * @name FsRtlFindInTunnelCache
734 * @implemented
735 *
736 * FILLME
737 *
738 * @param Cache
739 * FILLME
740 *
741 * @param DirectoryKey
742 * FILLME
743 *
744 * @param ShortName
745 * FILLME
746 *
747 * @param LongName
748 * FILLME
749 *
750 * @param KeyByShortName
751 * FILLME
752 *
753 * @param DataLength
754 * FILLME
755 *
756 * @param Data
757 * FILLME
758 *
759 * @return None
760 *
761 * @remarks None
762 *
763 *--*/
765NTAPI
772 OUT PVOID Data)
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}
875
876/*++
877 * @name FsRtlInitializeTunnelCache
878 * @implemented
879 *
880 * FILLME
881 *
882 * @param Cache
883 * FILLME
884 *
885 * @return None
886 *
887 * @remarks None
888 *
889 *--*/
890VOID
891NTAPI
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}
908
909/* EOF */
#define PAGED_CODE()
#define CODE_SEG(...)
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
_In_opt_ PWSTR _In_ PWSTR ParameterName
Definition: cdrom.h:961
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
#define KeQuerySystemTime(t)
Definition: env_spec_w32.h:570
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#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
FxAutoRegKey hKey
Status
Definition: gdiplustypes.h:25
VOID FASTCALL ExAcquireFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:23
VOID FASTCALL ExReleaseFastMutex(IN PFAST_MUTEX FastMutex)
Definition: fmutex.c:31
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
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
#define ASSERT(a)
Definition: mode.c:44
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
@ KeyValueFullInformation
Definition: nt_native.h:1181
#define KEY_READ
Definition: nt_native.h:1023
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
Definition: fatfs.h:173
base of all file and directory entries
Definition: entries.h:83
root entry for file system trees
Definition: entries.h:148
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
struct TUNNEL_NODE_ENTRY * PTUNNEL_NODE_ENTRY
VOID FsRtlPruneTunnelCache(IN PTUNNEL Cache, IN PLIST_ENTRY PoolList)
Definition: tunnel.c:86
VOID NTAPI FsRtlInitializeTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:892
ULONG TunnelMaxAge
Definition: tunnel.c:29
VOID FsRtlGetTunnelParameterValue(IN PUNICODE_STRING ParameterName, OUT PULONG Value)
Definition: tunnel.c:135
#define TUNNEL_FLAG_POOL
Definition: tunnel.c:35
VOID FsRtlRemoveNodeFromTunnel(IN PTUNNEL Cache, IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList, OUT PBOOLEAN Rebalance)
Definition: tunnel.c:57
#define TUNNEL_FLAG_KEY_SHORT_NAME
Definition: tunnel.c:36
VOID NTAPI FsRtlInitializeTunnels(VOID)
Definition: tunnel.c:200
VOID NTAPI FsRtlAddToTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING ShortName, IN PUNICODE_STRING LongName, IN BOOLEAN KeyByShortName, IN ULONG DataLength, IN PVOID Data)
Definition: tunnel.c:342
VOID FsRtlFreeTunnelNode(IN PTUNNEL_NODE_ENTRY CurEntry, IN PLIST_ENTRY PoolList OPTIONAL)
Definition: tunnel.c:39
PAGED_LOOKASIDE_LIST TunnelLookasideList
Definition: tunnel.c:30
BOOLEAN NTAPI FsRtlFindInTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING Name, OUT PUNICODE_STRING ShortName, OUT PUNICODE_STRING LongName, IN OUT PULONG DataLength, OUT PVOID Data)
Definition: tunnel.c:766
LONG FsRtlCompareNodeAndKey(IN PTUNNEL_NODE_ENTRY CurEntry, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING KeyString)
Definition: tunnel.c:254
VOID NTAPI FsRtlDeleteTunnelCache(IN PTUNNEL Cache)
Definition: tunnel.c:691
VOID NTAPI FsRtlDeleteKeyFromTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey)
Definition: tunnel.c:589
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define OUT
Definition: typedefs.h:40
LONGLONG QuadPart
Definition: typedefs.h:114
_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_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_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
FORCEINLINE VOID ExInitializeFastMutex(_Out_ PFAST_MUTEX FastMutex)
Definition: exfuncs.h:274
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
#define POOL_COLD_ALLOCATION
#define RtlParent(Links)
#define RtlInsertAsRightChild(ParentLinks, ChildLinks)
#define RtlIsLeftChild(Links)
NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlDelete(_In_ PRTL_SPLAY_LINKS Links)
#define RtlInitializeSplayLinks(Links)
#define RtlInsertAsLeftChild(ParentLinks, ChildLinks)
NTSYSAPI VOID NTAPI RtlDeleteNoSplay(_In_ PRTL_SPLAY_LINKS Links, _Inout_ PRTL_SPLAY_LINKS *Root)
_Must_inspect_result_ NTSYSAPI PRTL_SPLAY_LINKS NTAPI RtlRealSuccessor(_In_ PRTL_SPLAY_LINKS Links)
WCHAR * LPWSTR
Definition: xmlstorage.h:184