ReactOS  0.4.15-dev-2979-gfd8baca
largemcb.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: GPL v2 - See COPYING in the top level directory
4  * FILE: ntoskrnl/fsrtl/largemcb.c
5  * PURPOSE: Large Mapped Control Block (MCB) support for File System Drivers
6  * PROGRAMMERS: Aleksey Bragin <aleksey@reactos.org>
7  * Jan Kratochvil <project-captive@jankratochvil.net>
8  * Trevor Thompson
9  */
10 
11 /* INCLUDES ******************************************************************/
12 
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 #define MIN(x,y) (((x)<(y))?(x):(y))
18 #define MAX(x,y) (((x)>(y))?(x):(y))
19 
20 /* GLOBALS *******************************************************************/
21 
24 
25 /* We use only real 'mapping' runs; we do not store 'holes' to our GTree. */
26 typedef struct _LARGE_MCB_MAPPING_ENTRY // run
27 {
29  LARGE_INTEGER RunEndVbn; /* RunStartVbn+SectorCount; that means +1 after the last sector */
30  LARGE_INTEGER StartingLbn; /* Lbn of 'RunStartVbn' */
32 
33 typedef struct _LARGE_MCB_MAPPING // mcb_priv
34 {
37 
38 typedef struct _BASE_MCB_INTERNAL {
45 
46 /*
47 static LARGE_MCB_MAPPING_ENTRY StaticRunBelow0 = {
48  {{-1}}, // ignored
49  {{0}},
50  {{-1}}, // ignored
51 };
52 */
53 
55 {
56  PVOID Result;
57  PBASE_MCB Mcb = (PBASE_MCB)Table->TableContext;
58  Result = ExAllocatePoolWithTag(Mcb->PoolType, Bytes, 'BCML');
59  DPRINT("McbMappingAllocate(%lu) => %p\n", Bytes, Result);
60  return Result;
61 }
62 
64 {
65  DPRINT("McbMappingFree(%p)\n", Buffer);
66  ExFreePoolWithTag(Buffer, 'BCML');
67 }
68 
69 static
71 NTAPI
73  PVOID PtrA,
74  PVOID PtrB)
75 {
76  PLARGE_MCB_MAPPING_ENTRY A = PtrA, B = PtrB;
78 
79  ASSERT(A);
80  ASSERT(B);
81 
82  if (A->RunStartVbn.QuadPart == B->RunStartVbn.QuadPart && A->RunEndVbn.QuadPart == B->RunEndVbn.QuadPart)
83  Res = GenericEqual;
84  else if (A->RunEndVbn.QuadPart <= B->RunStartVbn.QuadPart)
85  Res = GenericLessThan;
86  else if (A->RunEndVbn.QuadPart >= B->RunStartVbn.QuadPart)
87  Res = GenericGreaterThan;
88  else
89  {
90  ASSERT(FALSE);
91  Res = GenericEqual;
92  }
93 
94  return Res;
95 }
96 
98 {
99  PLARGE_MCB_MAPPING_ENTRY A = PtrA, B = PtrB;
101 
102  if (A->RunStartVbn.QuadPart <= B->RunStartVbn.QuadPart && A->RunEndVbn.QuadPart > B->RunStartVbn.QuadPart)
103  Res = GenericEqual;
104  else if (A->RunStartVbn.QuadPart >= B->RunStartVbn.QuadPart && B->RunEndVbn.QuadPart > A->RunStartVbn.QuadPart)
105  Res = GenericEqual;
106  else if (A->RunStartVbn.QuadPart < B->RunStartVbn.QuadPart)
107  Res = GenericLessThan;
108  else if (A->RunStartVbn.QuadPart > B->RunStartVbn.QuadPart)
109  Res = GenericGreaterThan;
110  else
111  Res = GenericEqual;
112 
113  return Res;
114 }
115 
116 
117 /* PUBLIC FUNCTIONS **********************************************************/
118 
119 /*
120  * @implemented
121  * @Mcb: #PLARGE_MCB initialized by FsRtlInitializeLargeMcb().
122  * %NULL value is forbidden.
123  * @Vbn: Starting virtual block number of the wished range.
124  * @Lbn: Starting logical block number of the wished range.
125  * @SectorCount: Length of the wished range.
126  * Value less or equal to %0 is forbidden; FIXME: Is the reject of %0 W32 compliant?
127  *
128  * Adds the specified range @Vbn ... @Vbn+@SectorCount-1 to @Mcb.
129  * Any mappings previously in this range are deleted first.
130  *
131  * Returns: %TRUE if successful.
132  */
133 BOOLEAN
134 NTAPI
136  IN LONGLONG Vbn,
137  IN LONGLONG Lbn,
139 {
140  BOOLEAN Result = TRUE;
141  BOOLEAN IntResult;
143  LARGE_MCB_MAPPING_ENTRY Node, NeedleRun;
144  PLARGE_MCB_MAPPING_ENTRY LowerRun, HigherRun;
145  BOOLEAN NewElement;
146  LONGLONG IntLbn, IntSectorCount;
147 
148  DPRINT("FsRtlAddBaseMcbEntry(%p, %I64d, %I64d, %I64d)\n", OpaqueMcb, Vbn, Lbn, SectorCount);
149 
150  if (Vbn < 0)
151  {
152  Result = FALSE;
153  goto quit;
154  }
155 
156  if (SectorCount <= 0)
157  {
158  Result = FALSE;
159  goto quit;
160  }
161 
162  IntResult = FsRtlLookupBaseMcbEntry(OpaqueMcb, Vbn, &IntLbn, &IntSectorCount, NULL, NULL, NULL);
163  if (IntResult)
164  {
165  if (IntLbn != -1 && IntLbn != Lbn)
166  {
167  Result = FALSE;
168  goto quit;
169  }
170 
171  if ((IntLbn != -1) && (IntSectorCount >= SectorCount))
172  {
173  /* This is a no-op */
174  goto quit;
175  }
176  }
177 
178  /* clean any possible previous entries in our range */
180 
181  // We need to map [Vbn, Vbn+SectorCount) to [Lbn, Lbn+SectorCount),
182  // taking in account the fact that we need to merge these runs if
183  // they are adjacent or overlap, but fail if new run fully fits into another run
184 
185  /* initially we think we will be inserted as a separate run */
186  Node.RunStartVbn.QuadPart = Vbn;
187  Node.RunEndVbn.QuadPart = Vbn + SectorCount;
188  Node.StartingLbn.QuadPart = Lbn;
189 
190  /* optionally merge with lower run */
191  NeedleRun.RunStartVbn.QuadPart = Node.RunStartVbn.QuadPart - 1;
192  NeedleRun.RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart + 1;
193  NeedleRun.StartingLbn.QuadPart = ~0ULL;
194  Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
195  if ((LowerRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun)) &&
196  (LowerRun->StartingLbn.QuadPart + (LowerRun->RunEndVbn.QuadPart - LowerRun->RunStartVbn.QuadPart) == Node.StartingLbn.QuadPart))
197  {
198  ASSERT(LowerRun->RunEndVbn.QuadPart == Node.RunStartVbn.QuadPart);
199  Node.RunStartVbn.QuadPart = LowerRun->RunStartVbn.QuadPart;
200  Node.StartingLbn.QuadPart = LowerRun->StartingLbn.QuadPart;
201  Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
202  RtlDeleteElementGenericTable(&Mcb->Mapping->Table, LowerRun);
203  --Mcb->PairCount;
204  DPRINT("Intersecting lower run found (%I64d,%I64d) Lbn: %I64d\n", LowerRun->RunStartVbn.QuadPart, LowerRun->RunEndVbn.QuadPart, LowerRun->StartingLbn.QuadPart);
205  }
206 
207  /* optionally merge with higher run */
208  NeedleRun.RunStartVbn.QuadPart = Node.RunEndVbn.QuadPart;
209  NeedleRun.RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart + 1;
210  Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
211  if ((HigherRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun)) &&
212  (Node.StartingLbn.QuadPart <= HigherRun->StartingLbn.QuadPart))
213  {
214  ASSERT(HigherRun->RunStartVbn.QuadPart == Node.RunEndVbn.QuadPart);
215  Node.RunEndVbn.QuadPart = HigherRun->RunEndVbn.QuadPart;
216  Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
217  RtlDeleteElementGenericTable(&Mcb->Mapping->Table, HigherRun);
218  --Mcb->PairCount;
219  DPRINT("Intersecting higher run found (%I64d,%I64d) Lbn: %I64d\n", HigherRun->RunStartVbn.QuadPart, HigherRun->RunEndVbn.QuadPart, HigherRun->StartingLbn.QuadPart);
220  }
221  Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
222 
223  /* finally insert the resulting run */
224  RtlInsertElementGenericTable(&Mcb->Mapping->Table, &Node, sizeof(Node), &NewElement);
225  ++Mcb->PairCount;
226  ASSERT(NewElement);
227 
228  // NB: Two consecutive runs can only be merged, if actual LBNs also match!
229 
230  /* 1.
231  Existing->RunStartVbn
232  |
233  |///////|
234  |/////////////|
235  |
236  Node->RunStartVbn
237 
238  2.
239  Existing->RunStartVbn
240  |
241  |///////|
242  |//////|
243  |
244  Node->RunStartVbn
245 
246  3.
247  Existing->RunStartVbn
248  |
249  |///////|
250  |///|
251  |
252  Node->RunStartVbn
253 
254  4.
255  Existing->RunStartVbn
256  |
257  |///////|
258  |///////////////|
259  |
260  Node->RunStartVbn
261 
262 
263  Situation with holes:
264  1. Holes at both ends
265  2. Hole at the right, new run merged with the previous run
266  3. Hole at the right, new run is not merged with the previous run
267  4. Hole at the left, new run merged with the next run
268  5. Hole at the left, new run is not merged with the next run
269  6. No holes, exact fit to merge with both previous and next runs
270  7. No holes, merges only with the next run
271  8. No holes, merges only with the previous run
272  9. No holes, does not merge with next or prev runs
273 
274 
275  Overwriting existing mapping is not possible and results in FALSE being returned
276  */
277 
278 quit:
279  DPRINT("FsRtlAddBaseMcbEntry(%p, %I64d, %I64d, %I64d) = %d\n", Mcb, Vbn, Lbn, SectorCount, Result);
280  return Result;
281 }
282 
283 /*
284  * @implemented
285  */
286 BOOLEAN
287 NTAPI
289  IN LONGLONG Vbn,
290  IN LONGLONG Lbn,
292 {
293  BOOLEAN Result;
294 
295  DPRINT("FsRtlAddLargeMcbEntry(%p, %I64d, %I64d, %I64d)\n", Mcb, Vbn, Lbn, SectorCount);
296 
297  KeAcquireGuardedMutex(Mcb->GuardedMutex);
298  Result = FsRtlAddBaseMcbEntry(&(Mcb->BaseMcb),
299  Vbn,
300  Lbn,
301  SectorCount);
302  KeReleaseGuardedMutex(Mcb->GuardedMutex);
303 
304  DPRINT("FsRtlAddLargeMcbEntry(%p, %I64d, %I64d, %I64d) = %d\n", Mcb, Vbn, Lbn, SectorCount, Result);
305 
306  return Result;
307 }
308 
309 /*
310  * @implemented
311  * @Mcb: #PLARGE_MCB initialized by FsRtlInitializeLargeMcb().
312  * %NULL value is forbidden.
313  * @RunIndex: Requested range index to retrieve.
314  * @Vbn: Returns the starting virtual block number of the wished range.
315  * %NULL pointer is forbidden.
316  * @Lbn: Returns the starting logical block number of the wished range (or -1 if it is a hole).
317  * %NULL pointer is forbidden.
318  * @SectorCount: Returns the length of the wished range.
319  * %NULL pointer is forbidden.
320  * Value less or equal to %0 is forbidden; FIXME: Is the reject of %0 W32 compliant?
321  *
322  * Retrieves the parameters of the specified run with index @RunIndex.
323  *
324  * Mapping %0 always starts at virtual block %0, either as 'hole' or as 'real' mapping.
325  * libcaptive does not store 'hole' information to its #GTree.
326  * Last run is always a 'real' run. 'hole' runs appear as mapping to constant @Lbn value %-1.
327  *
328  * Returns: %TRUE if successful.
329  */
330 BOOLEAN
331 NTAPI
333  IN ULONG RunIndex,
334  OUT PLONGLONG Vbn,
335  OUT PLONGLONG Lbn,
337 {
338  BOOLEAN Result = FALSE;
341  ULONG CurrentIndex = 0;
342  ULONGLONG LastVbn = 0;
343  ULONGLONG LastSectorCount = 0;
344 
345  // Traverse the tree
346  for (Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE);
347  Run;
349  {
350  // is the current index a hole?
351  if (Run->RunStartVbn.QuadPart > (LastVbn + LastSectorCount))
352  {
353  // Is this the index we're looking for?
354  if (RunIndex == CurrentIndex)
355  {
356  *Vbn = LastVbn + LastSectorCount;
357  *Lbn = -1;
358  *SectorCount = Run->RunStartVbn.QuadPart - *Vbn;
359 
360  Result = TRUE;
361  goto quit;
362  }
363 
364  CurrentIndex++;
365  }
366 
367  if (RunIndex == CurrentIndex)
368  {
369  *Vbn = Run->RunStartVbn.QuadPart;
370  *Lbn = Run->StartingLbn.QuadPart;
371  *SectorCount = Run->RunEndVbn.QuadPart - Run->RunStartVbn.QuadPart;
372 
373  Result = TRUE;
374  goto quit;
375  }
376 
377  CurrentIndex++;
378  LastVbn = Run->RunStartVbn.QuadPart;
379  LastSectorCount = Run->RunEndVbn.QuadPart - Run->RunStartVbn.QuadPart;
380  }
381 
382 quit:
383  DPRINT("FsRtlGetNextBaseMcbEntry(%p, %d, %p, %p, %p) = %d (%I64d, %I64d, %I64d)\n", Mcb, RunIndex, Vbn, Lbn, SectorCount, Result, *Vbn, *Lbn, *SectorCount);
384  return Result;
385 }
386 
387 /*
388  * @implemented
389  */
390 BOOLEAN
391 NTAPI
393  IN ULONG RunIndex,
394  OUT PLONGLONG Vbn,
395  OUT PLONGLONG Lbn,
397 {
398  BOOLEAN Result;
399 
400  DPRINT("FsRtlGetNextLargeMcbEntry(%p, %d, %p, %p, %p)\n", Mcb, RunIndex, Vbn, Lbn, SectorCount);
401 
402  KeAcquireGuardedMutex(Mcb->GuardedMutex);
403  Result = FsRtlGetNextBaseMcbEntry(&(Mcb->BaseMcb),
404  RunIndex,
405  Vbn,
406  Lbn,
407  SectorCount);
408  KeReleaseGuardedMutex(Mcb->GuardedMutex);
409 
410  DPRINT("FsRtlGetNextLargeMcbEntry(%p, %d, %p, %p, %p) = %d (%I64d, %I64d, %I64d)\n", Mcb, RunIndex, Vbn, Lbn, SectorCount, Result, *Vbn, *Lbn, *SectorCount);
411 
412  return Result;
413 }
414 
415 /*
416  * @implemented
417  */
418 VOID
419 NTAPI
422 {
424 
425  if (PoolType == PagedPool)
426  {
427  Mcb->Mapping = ExAllocateFromPagedLookasideList(&FsRtlFirstMappingLookasideList);
428  }
429  else
430  {
432  sizeof(LARGE_MCB_MAPPING),
433  'CBSF');
434  }
435 
436  Mcb->PoolType = PoolType;
437  Mcb->PairCount = 0;
438  Mcb->MaximumPairCount = MAXIMUM_PAIR_COUNT;
439  RtlInitializeGenericTable(&Mcb->Mapping->Table,
443  Mcb);
444 }
445 
446 /*
447  * @implemented
448  */
449 VOID
450 NTAPI
453 {
454  DPRINT("FsRtlInitializeLargeMcb(%p, %d)\n", Mcb, PoolType);
455 
456  Mcb->GuardedMutex = ExAllocateFromNPagedLookasideList(&FsRtlFastMutexLookasideList);
457 
458  KeInitializeGuardedMutex(Mcb->GuardedMutex);
459 
460  _SEH2_TRY
461  {
462  FsRtlInitializeBaseMcb(&(Mcb->BaseMcb), PoolType);
463  }
465  {
466  ExFreeToNPagedLookasideList(&FsRtlFastMutexLookasideList,
467  Mcb->GuardedMutex);
468  Mcb->GuardedMutex = NULL;
469  }
470  _SEH2_END;
471 }
472 
473 /*
474  * @implemented
475  */
476 CODE_SEG("INIT")
477 VOID
478 NTAPI
480 {
481  /* Initialize the list for the MCB */
483  NULL,
484  NULL,
486  sizeof(LARGE_MCB_MAPPING),
487  IFS_POOL_TAG,
488  0); /* FIXME: Should be 4 */
489 
490  /* Initialize the list for the guarded mutex */
492  NULL,
493  NULL,
495  sizeof(KGUARDED_MUTEX),
496  IFS_POOL_TAG,
497  0); /* FIXME: Should be 32 */
498 }
499 
500 /*
501  * @implemented
502  */
503 BOOLEAN
504 NTAPI
506  IN LONGLONG Vbn,
512 {
513  BOOLEAN Result = FALSE;
514  ULONG i;
515  LONGLONG LastVbn = 0, LastLbn = 0, Count = 0; // the last values we've found during traversal
516 
517  DPRINT("FsRtlLookupBaseMcbEntry(%p, %I64d, %p, %p, %p, %p, %p)\n", OpaqueMcb, Vbn, Lbn, SectorCountFromLbn, StartingLbn, SectorCountFromStartingLbn, Index);
518 
519  for (i = 0; FsRtlGetNextBaseMcbEntry(OpaqueMcb, i, &LastVbn, &LastLbn, &Count); i++)
520  {
521  // have we reached the target mapping?
522  if (Vbn < LastVbn + Count)
523  {
524  if (Lbn)
525  {
526  if (LastLbn == -1)
527  *Lbn = -1;
528  else
529  *Lbn = LastLbn + (Vbn - LastVbn);
530  }
531 
532  if (SectorCountFromLbn)
533  *SectorCountFromLbn = LastVbn + Count - Vbn;
534  if (StartingLbn)
535  *StartingLbn = LastLbn;
537  *SectorCountFromStartingLbn = LastVbn + Count - LastVbn;
538  if (Index)
539  *Index = i;
540 
541  Result = TRUE;
542  goto quit;
543  }
544  }
545 
546 quit:
547  DPRINT("FsRtlLookupBaseMcbEntry(%p, %I64d, %p, %p, %p, %p, %p) = %d (%I64d, %I64d, %I64d, %I64d, %d)\n",
551 
552  return Result;
553 }
554 
555 /*
556  * @implemented
557  */
558 BOOLEAN
559 NTAPI
561  IN LONGLONG Vbn,
567 {
568  BOOLEAN Result;
569 
570  DPRINT("FsRtlLookupLargeMcbEntry(%p, %I64d, %p, %p, %p, %p, %p)\n", Mcb, Vbn, Lbn, SectorCountFromLbn, StartingLbn, SectorCountFromStartingLbn, Index);
571 
572  KeAcquireGuardedMutex(Mcb->GuardedMutex);
573  Result = FsRtlLookupBaseMcbEntry(&(Mcb->BaseMcb),
574  Vbn,
575  Lbn,
577  StartingLbn,
579  Index);
580  KeReleaseGuardedMutex(Mcb->GuardedMutex);
581 
582  DPRINT("FsRtlLookupLargeMcbEntry(%p, %I64d, %p, %p, %p, %p, %p) = %d (%I64d, %I64d, %I64d, %I64d, %d)\n",
586 
587  return Result;
588 }
589 
590 static BOOLEAN
591 NTAPI
593  OUT PLONGLONG Vbn,
594  OUT PLONGLONG Lbn,
596 {
597  ULONG RunIndex = 0;
598  PLARGE_MCB_MAPPING_ENTRY Run, RunFound = NULL;
599  LONGLONG LastVbn = 0;
600 
601  for (Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE);
602  Run;
604  {
605  /* Take care when we must emulate missing 'hole' runs. */
606  if (Run->RunStartVbn.QuadPart > LastVbn)
607  {
608  RunIndex++;
609  }
610  LastVbn = Run->RunEndVbn.QuadPart;
611  RunIndex++;
612  RunFound = Run;
613  }
614 
615  if (!RunFound)
616  {
617  return FALSE;
618  }
619 
620  if (Vbn)
621  {
622  *Vbn = RunFound->RunEndVbn.QuadPart - 1;
623  }
624  if (Lbn)
625  {
626  if (1)
627  {
628  *Lbn = RunFound->StartingLbn.QuadPart + (RunFound->RunEndVbn.QuadPart - RunFound->RunStartVbn.QuadPart) - 1;
629  }
630  else
631  {
632  *Lbn = ~0ULL;
633  }
634  }
635  if (Index)
636  {
637  *Index = RunIndex - 1;
638  }
639 
640  return TRUE;
641 }
642 
643 
644 /*
645  * @implemented
646  */
647 BOOLEAN
648 NTAPI
652  IN OUT PULONG Index)
653 {
654  BOOLEAN Result;
656 
657  DPRINT("FsRtlLookupLastBaseMcbEntryAndIndex(%p, %p, %p, %p)\n", OpaqueMcb, LargeVbn, LargeLbn, Index);
658 
660 
661  DPRINT("FsRtlLookupLastBaseMcbEntryAndIndex(%p, %p, %p, %p) = %d (%I64d, %I64d, %d)\n", OpaqueMcb, LargeVbn, LargeLbn, Index, Result, *LargeVbn, *LargeLbn, *Index);
662 
663  return Result;
664 }
665 
666 /*
667  * @implemented
668  */
669 BOOLEAN
670 NTAPI
674  OUT PULONG Index)
675 {
676  BOOLEAN Result;
677 
678  DPRINT("FsRtlLookupLastLargeMcbEntryAndIndex(%p, %p, %p, %p)\n", OpaqueMcb, LargeVbn, LargeLbn, Index);
679 
680  KeAcquireGuardedMutex(OpaqueMcb->GuardedMutex);
681  Result = FsRtlLookupLastBaseMcbEntryAndIndex(&(OpaqueMcb->BaseMcb),
682  LargeVbn,
683  LargeLbn,
684  Index);
685  KeReleaseGuardedMutex(OpaqueMcb->GuardedMutex);
686 
687  DPRINT("FsRtlLookupLastLargeMcbEntryAndIndex(%p, %p, %p, %p) = %d (%I64d, %I64d, %d)\n", OpaqueMcb, LargeVbn, LargeLbn, Index, Result, *LargeVbn, *LargeLbn, *Index);
688 
689  return Result;
690 }
691 
692 /*
693  * @unimplemented
694  */
695 BOOLEAN
696 NTAPI
698  OUT PLONGLONG Vbn,
699  OUT PLONGLONG Lbn)
700 {
701  BOOLEAN Result;
703 
704  DPRINT("FsRtlLookupLastBaseMcbEntry(%p, %p, %p)\n", OpaqueMcb, Vbn, Lbn);
705 
707 
708  DPRINT("FsRtlLookupLastBaseMcbEntry(%p, %p, %p) = %d (%I64d, %I64d)\n", Mcb, Vbn, Lbn, Result, *Vbn, *Lbn);
709 
710  return Result;
711 }
712 
713 /*
714  * @implemented
715  */
716 BOOLEAN
717 NTAPI
719  OUT PLONGLONG Vbn,
720  OUT PLONGLONG Lbn)
721 {
722  BOOLEAN Result;
723 
724  DPRINT("FsRtlLookupLastLargeMcbEntry(%p, %p, %p)\n", Mcb, Vbn, Lbn);
725 
726  KeAcquireGuardedMutex(Mcb->GuardedMutex);
727  Result = FsRtlLookupLastBaseMcbEntry(&(Mcb->BaseMcb),
728  Vbn,
729  Lbn);
730  KeReleaseGuardedMutex(Mcb->GuardedMutex);
731 
732  DPRINT("FsRtlLookupLastLargeMcbEntry(%p, %p, %p) = %d (%I64d, %I64d)\n", Mcb, Vbn, Lbn, Result, *Vbn, *Lbn);
733 
734  return Result;
735 }
736 
737 /*
738  * @implemented
739  */
740 ULONG
741 NTAPI
743 {
744  ULONG NumberOfRuns = 0;
745  LONGLONG Vbn, Lbn, Count;
746  int i;
747 
748  DPRINT("FsRtlNumberOfRunsInBaseMcb(%p)\n", OpaqueMcb);
749 
750  // Count how many Mcb entries there are
751  for (i = 0; FsRtlGetNextBaseMcbEntry(OpaqueMcb, i, &Vbn, &Lbn, &Count); i++)
752  {
753  NumberOfRuns++;
754  }
755 
756  DPRINT("FsRtlNumberOfRunsInBaseMcb(%p) = %d\n", OpaqueMcb, NumberOfRuns);
757  return NumberOfRuns;
758 }
759 
760 /*
761  * @implemented
762  */
763 ULONG
764 NTAPI
766 {
767  ULONG NumberOfRuns;
768 
769  DPRINT("FsRtlNumberOfRunsInLargeMcb(%p)\n", Mcb);
770 
771  /* Read the number of runs while holding the MCB lock */
772  KeAcquireGuardedMutex(Mcb->GuardedMutex);
773  NumberOfRuns = FsRtlNumberOfRunsInBaseMcb(&(Mcb->BaseMcb));
774  KeReleaseGuardedMutex(Mcb->GuardedMutex);
775 
776  DPRINT("FsRtlNumberOfRunsInLargeMcb(%p) = %d\n", Mcb, NumberOfRuns);
777 
778  /* Return the count */
779  return NumberOfRuns;
780 }
781 
782 /*
783  * @implemented
784  * @Mcb: #PLARGE_MCB initialized by FsRtlInitializeLargeMcb().
785  * %NULL value is forbidden.
786  * @Vbn: Starting virtual block number to specify the range to delete.
787  * @SectorCount: Length of the range to delete.
788  * Value less or equal to %0 is forbidden; FIXME: Is the reject of %0 W32 compliant?
789  *
790  * Deletes any possible @Mcb mappings in the given range @Vbn ... @Vbn+@SectorCount-1.
791  * This call has no problems if no mappings exist there yet.
792  */
793 BOOLEAN
794 NTAPI
796  IN LONGLONG Vbn,
798 {
800  LARGE_MCB_MAPPING_ENTRY NeedleRun;
801  PLARGE_MCB_MAPPING_ENTRY HaystackRun;
802  BOOLEAN Result = TRUE;
803 
804  DPRINT("FsRtlRemoveBaseMcbEntry(%p, %I64d, %I64d)\n", OpaqueMcb, Vbn, SectorCount);
805 
806  if (Vbn < 0 || SectorCount <= 0)
807  {
808  Result = FALSE;
809  goto quit;
810  }
811 
812  if (Vbn + SectorCount <= Vbn)
813  {
814  Result = FALSE;
815  goto quit;
816  }
817 
818  NeedleRun.RunStartVbn.QuadPart = Vbn;
819  NeedleRun.RunEndVbn.QuadPart = Vbn + SectorCount;
820  NeedleRun.StartingLbn.QuadPart = -1;
821 
822  /* adjust/destroy all intersecting ranges */
823  Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
824  while ((HaystackRun = RtlLookupElementGenericTable(&Mcb->Mapping->Table, &NeedleRun)))
825  {
826  if (HaystackRun->RunStartVbn.QuadPart < NeedleRun.RunStartVbn.QuadPart)
827  {
828  LONGLONG HaystackRunEnd = HaystackRun->RunEndVbn.QuadPart;
829  ASSERT(HaystackRun->RunEndVbn.QuadPart > NeedleRun.RunStartVbn.QuadPart);
830 
831  HaystackRun->RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart;
832 
833  if (HaystackRunEnd > NeedleRun.RunEndVbn.QuadPart)
834  {
835  /* The run we are deleting is included in the run we just truncated.
836  * Add the tail back. */
837  LARGE_MCB_MAPPING_ENTRY TailRun;
838  BOOLEAN NewElement;
839 
840  TailRun.RunStartVbn.QuadPart = NeedleRun.RunEndVbn.QuadPart;
841  TailRun.RunEndVbn.QuadPart = HaystackRunEnd;
842  TailRun.StartingLbn.QuadPart = HaystackRun->StartingLbn.QuadPart + (NeedleRun.RunEndVbn.QuadPart - HaystackRun->RunStartVbn.QuadPart);
843 
844  Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
845 
846  RtlInsertElementGenericTable(&Mcb->Mapping->Table, &TailRun, sizeof(TailRun), &NewElement);
847  ++Mcb->PairCount;
848  ASSERT(NewElement);
849 
850  Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
851  }
852  }
853  else if (HaystackRun->RunEndVbn.QuadPart > NeedleRun.RunEndVbn.QuadPart)
854  {
855  LONGLONG HaystackRunStart = HaystackRun->RunStartVbn.QuadPart;
856  LONGLONG HaystackStartingLbn = HaystackRun->StartingLbn.QuadPart;
857 
858  ASSERT(HaystackRun->RunStartVbn.QuadPart < NeedleRun.RunEndVbn.QuadPart);
859  HaystackRun->RunStartVbn.QuadPart = NeedleRun.RunEndVbn.QuadPart;
860  /* Adjust the starting LBN */
861  HaystackRun->StartingLbn.QuadPart += NeedleRun.RunEndVbn.QuadPart - HaystackRunStart;
862 
863  if (HaystackRunStart < NeedleRun.RunStartVbn.QuadPart)
864  {
865  /* The run we are deleting is included in the run we just truncated.
866  * Add the head back. */
867  LARGE_MCB_MAPPING_ENTRY HeadRun;
868  BOOLEAN NewElement;
869 
870  HeadRun.RunStartVbn.QuadPart = HaystackRunStart;
871  HeadRun.RunEndVbn.QuadPart = NeedleRun.RunStartVbn.QuadPart;
872  HeadRun.StartingLbn.QuadPart = HaystackStartingLbn;
873 
874  Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
875 
876  RtlInsertElementGenericTable(&Mcb->Mapping->Table, &HeadRun, sizeof(HeadRun), &NewElement);
877  ++Mcb->PairCount;
878  ASSERT(NewElement);
879 
880  Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
881  }
882  }
883  else
884  {
885  //ASSERT(NeedleRun.RunStartVbn.QuadPart >= HaystackRun->RunStartVbn.QuadPart);
886  //ASSERT(NeedleRun.RunEndVbn.QuadPart <= HaystackRun->RunEndVbn.QuadPart);
887  Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
888  RtlDeleteElementGenericTable(&Mcb->Mapping->Table, HaystackRun);
889  --Mcb->PairCount;
890  Mcb->Mapping->Table.CompareRoutine = McbMappingIntersectCompare;
891  }
892  }
893  Mcb->Mapping->Table.CompareRoutine = McbMappingCompare;
894 
895 quit:
896  DPRINT("FsRtlRemoveBaseMcbEntry(%p, %I64d, %I64d) = %d\n", OpaqueMcb, Vbn, SectorCount, Result);
897  return Result;
898 }
899 
900 /*
901  * @implemented
902  */
903 VOID
904 NTAPI
906  IN LONGLONG Vbn,
908 {
909  DPRINT("FsRtlRemoveLargeMcbEntry(%p, %I64d, %I64d)\n", Mcb, Vbn, SectorCount);
910 
911  KeAcquireGuardedMutex(Mcb->GuardedMutex);
913  KeReleaseGuardedMutex(Mcb->GuardedMutex);
914 }
915 
916 /*
917  * @implemented
918  */
919 VOID
920 NTAPI
922 {
924  PLARGE_MCB_MAPPING_ENTRY Element;
925 
926  DPRINT("FsRtlResetBaseMcb(%p)\n", OpaqueMcb);
927 
928  while (RtlNumberGenericTableElements(&Mcb->Mapping->Table) &&
929  (Element = (PLARGE_MCB_MAPPING_ENTRY)RtlGetElementGenericTable(&Mcb->Mapping->Table, 0)))
930  {
931  RtlDeleteElementGenericTable(&Mcb->Mapping->Table, Element);
932  }
933 
934  Mcb->PairCount = 0;
935  Mcb->MaximumPairCount = 0;
936 }
937 
938 /*
939  * @implemented
940  */
941 VOID
942 NTAPI
945 {
946  DPRINT("FsRtlResetLargeMcb(%p, %d)\n", Mcb, SelfSynchronized);
947 
948  if (!SelfSynchronized)
949  KeAcquireGuardedMutex(Mcb->GuardedMutex);
950 
951  FsRtlResetBaseMcb(&Mcb->BaseMcb);
952 
953  if (!SelfSynchronized)
954  KeReleaseGuardedMutex(Mcb->GuardedMutex);
955 }
956 
957 /*
958  * @unimplemented
959  */
960 BOOLEAN
961 NTAPI
963  IN LONGLONG Vbn,
965 {
967  PLARGE_MCB_MAPPING_ENTRY Run, InsertLowerRun = NULL, ExistingRun = NULL;
968  BOOLEAN NewElement;
969 
970  DPRINT("FsRtlSplitBaseMcb(%p, %I64d, %I64d)\n", OpaqueMcb, Vbn, Amount);
971 
972  /* Traverse the tree */
973  for (Run = (PLARGE_MCB_MAPPING_ENTRY)RtlEnumerateGenericTable(&Mcb->Mapping->Table, TRUE);
974  Run;
976  {
977  /* unaffected run? */
978  /* FIXME: performance: effective skip of all 'lower' runs without traversing them */
979  if (Vbn >= Run->RunEndVbn.QuadPart) { DPRINT("Skipping it\n"); continue; }
980 
981  /* crossing run to be split?
982  * 'lower_run' is created on the original place; just shortened.
983  * current 'run' is shifted up later
984  */
985  if (Vbn < Run->RunEndVbn.QuadPart)
986  {
987  /* FIXME: shift 'run->Lbn_start' ? */
988  Run->RunStartVbn.QuadPart = Vbn;
989 
990  InsertLowerRun = NULL;
991  }
992 
993  /* Shift the current 'run'.
994  * Ordering is not changed in Generic Tree so I hope I do not need to reinsert it.
995  */
996  Run->RunStartVbn.QuadPart += Amount;
997  ASSERT(Run->RunEndVbn.QuadPart + Amount > Run->RunEndVbn.QuadPart); /* overflow? */
998  Run->RunEndVbn.QuadPart += Amount;
999  /* FIXME: shift 'run->Lbn_start' ? */
1000 
1001  /* continue the traversal */
1002  }
1003 
1004  if (InsertLowerRun)
1005  {
1006  ExistingRun = RtlInsertElementGenericTable(&Mcb->Mapping->Table, InsertLowerRun, sizeof(*InsertLowerRun), &NewElement);
1007  ++Mcb->PairCount;
1008  }
1009 
1010  ASSERT(ExistingRun == NULL);
1011 
1012  DPRINT("FsRtlSplitBaseMcb(%p, %I64d, %I64d) = %d\n", OpaqueMcb, Vbn, Amount, TRUE);
1013 
1014  return TRUE;
1015 }
1016 
1017 /*
1018  * @implemented
1019  */
1020 BOOLEAN
1021 NTAPI
1023  IN LONGLONG Vbn,
1024  IN LONGLONG Amount)
1025 {
1026  BOOLEAN Result;
1027 
1028  DPRINT("FsRtlSplitLargeMcb(%p, %I64d, %I64d)\n", Mcb, Vbn, Amount);
1029 
1030  KeAcquireGuardedMutex(Mcb->GuardedMutex);
1031  Result = FsRtlSplitBaseMcb(&(Mcb->BaseMcb),
1032  Vbn,
1033  Amount);
1034  KeReleaseGuardedMutex(Mcb->GuardedMutex);
1035 
1036  DPRINT("FsRtlSplitLargeMcb(%p, %I64d, %I64d) = %d\n", Mcb, Vbn, Amount, Result);
1037 
1038  return Result;
1039 }
1040 
1041 /*
1042  * @unimplemented
1043  */
1044 VOID
1045 NTAPI
1047  IN LONGLONG Vbn)
1048 {
1049  DPRINT("FsRtlTruncateBaseMcb(%p, %I64d)\n", OpaqueMcb, Vbn);
1050 
1051  FsRtlRemoveBaseMcbEntry(OpaqueMcb, Vbn, MAXLONG - Vbn + 1);
1052 }
1053 
1054 /*
1055  * @implemented
1056  */
1057 VOID
1058 NTAPI
1060  IN LONGLONG Vbn)
1061 {
1062  DPRINT("FsRtlTruncateLargeMcb(%p, %I64d)\n", Mcb, Vbn);
1063 
1064  KeAcquireGuardedMutex(Mcb->GuardedMutex);
1065  FsRtlTruncateBaseMcb(&(Mcb->BaseMcb), Vbn);
1066  KeReleaseGuardedMutex(Mcb->GuardedMutex);
1067 }
1068 
1069 /*
1070  * @implemented
1071  */
1072 VOID
1073 NTAPI
1075 {
1076  DPRINT("FsRtlUninitializeBaseMcb(%p)\n", Mcb);
1077 
1079 
1080  if ((Mcb->PoolType == PagedPool)/* && (Mcb->MaximumPairCount == MAXIMUM_PAIR_COUNT)*/)
1081  {
1082  ExFreeToPagedLookasideList(&FsRtlFirstMappingLookasideList,
1083  Mcb->Mapping);
1084  }
1085  else
1086  {
1087  ExFreePoolWithTag(Mcb->Mapping, 'CBSF');
1088  }
1089 }
1090 
1091 /*
1092  * @implemented
1093  */
1094 VOID
1095 NTAPI
1097 {
1098  DPRINT("FsRtlUninitializeLargeMcb(%p)\n", Mcb);
1099 
1100  if (Mcb->GuardedMutex)
1101  {
1102  ExFreeToNPagedLookasideList(&FsRtlFastMutexLookasideList,
1103  Mcb->GuardedMutex);
1104  FsRtlUninitializeBaseMcb(&(Mcb->BaseMcb));
1105  }
1106 }
Definition: bidi.c:433
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ LONGLONG _In_ LONGLONG Amount
Definition: fsrtlfuncs.h:550
ASMGENDATA Table[]
Definition: genincdata.c:61
Definition: ehthrow.cxx:53
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
struct LOOKASIDE_ALIGN _NPAGED_LOOKASIDE_LIST NPAGED_LOOKASIDE_LIST
BOOLEAN NTAPI FsRtlLookupLastBaseMcbEntry(IN PBASE_MCB OpaqueMcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn)
Definition: largemcb.c:697
_In_ BOOLEAN SelfSynchronized
Definition: fsrtlfuncs.h:462
#define MAXLONG
Definition: umtypes.h:116
VOID FASTCALL KeAcquireGuardedMutex(IN PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:42
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElements(_In_ PRTL_GENERIC_TABLE Table)
PLARGE_MCB_MAPPING Mapping
Definition: largemcb.c:43
#define TRUE
Definition: types.h:120
VOID NTAPI FsRtlRemoveLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG SectorCount)
Definition: largemcb.c:905
void quit(int argc, const char *argv[])
Definition: cmds.c:1606
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ BOOLEAN Restart)
BOOLEAN NTAPI FsRtlSplitBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, IN LONGLONG Amount)
Definition: largemcb.c:962
_In_ UINT Bytes
Definition: mmcopy.h:9
_In_ LONGLONG _Out_opt_ PLONGLONG _Out_opt_ PLONGLONG SectorCountFromLbn
Definition: fsrtlfuncs.h:498
_Must_inspect_result_ _In_ LONGLONG _In_ LONGLONG Lbn
Definition: fsrtlfuncs.h:479
VOID NTAPI FsRtlInitializeLargeMcbs(VOID)
Definition: largemcb.c:479
Definition: largemcb.c:26
PAGED_LOOKASIDE_LIST FsRtlFirstMappingLookasideList
Definition: largemcb.c:22
struct _LARGE_MCB_MAPPING_ENTRY LARGE_MCB_MAPPING_ENTRY
_Out_ PLONGLONG LargeVbn
Definition: fsrtlfuncs.h:520
ULONG NTAPI FsRtlNumberOfRunsInLargeMcb(IN PLARGE_MCB Mcb)
Definition: largemcb.c:765
Definition: ehthrow.cxx:92
VOID NTAPI RtlInitializeGenericTable(IN PRTL_GENERIC_TABLE Table, IN PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine, IN PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine, IN PRTL_GENERIC_FREE_ROUTINE FreeRoutine, IN PVOID TableContext)
Definition: generictable.c:100
LARGE_INTEGER StartingLbn
Definition: largemcb.c:30
VOID NTAPI FsRtlTruncateLargeMcb(IN PLARGE_MCB Mcb, IN LONGLONG Vbn)
Definition: largemcb.c:1059
struct _BASE_MCB_INTERNAL * PBASE_MCB_INTERNAL
ULONG MaximumPairCount
Definition: largemcb.c:39
_Must_inspect_result_ _In_ ULONG RunIndex
Definition: fsrtlfuncs.h:538
_SEH2_TRY
Definition: create.c:4226
BOOLEAN NTAPI FsRtlLookupBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn OPTIONAL, OUT PLONGLONG SectorCountFromLbn OPTIONAL, OUT PLONGLONG StartingLbn OPTIONAL, OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, OUT PULONG Index OPTIONAL)
Definition: largemcb.c:505
BOOLEAN NTAPI FsRtlGetNextLargeMcbEntry(IN PLARGE_MCB Mcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount)
Definition: largemcb.c:392
struct _LARGE_MCB_MAPPING * PLARGE_MCB_MAPPING
__GNU_EXTENSION typedef __int64 * PLONGLONG
Definition: ntbasedef.h:382
ULONG CLONG
Definition: umtypes.h:126
VOID NTAPI FsRtlInitializeBaseMcb(IN PBASE_MCB OpaqueMcb, IN POOL_TYPE PoolType)
Definition: largemcb.c:420
static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingCompare(PRTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB)
Definition: largemcb.c:72
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
union node Node
Definition: types.h:1255
struct _BASE_MCB * PBASE_MCB
static VOID NTAPI McbMappingFree(PRTL_GENERIC_TABLE Table, PVOID Buffer)
Definition: largemcb.c:63
VOID NTAPI FsRtlInitializeLargeMcb(IN PLARGE_MCB Mcb, IN POOL_TYPE PoolType)
Definition: largemcb.c:451
BOOLEAN NTAPI FsRtlLookupLastLargeMcbEntry(IN PLARGE_MCB Mcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn)
Definition: largemcb.c:718
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
struct tagRun Run
VOID NTAPI FsRtlUninitializeBaseMcb(IN PBASE_MCB Mcb)
Definition: largemcb.c:1074
Definition: bufpool.h:45
#define ULL(a, b)
Definition: format_msg.c:27
_In_ LONGLONG _Out_opt_ PLONGLONG _Out_opt_ PLONGLONG _Out_opt_ PLONGLONG StartingLbn
Definition: fsrtlfuncs.h:498
#define IFS_POOL_TAG
Definition: tag.h:52
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ PVOID Buffer)
int64_t LONGLONG
Definition: typedefs.h:68
VOID NTAPI FsRtlResetBaseMcb(IN PBASE_MCB OpaqueMcb)
Definition: largemcb.c:921
int Count
Definition: noreturn.cpp:7
VOID NTAPI ExInitializeNPagedLookasideList(IN PNPAGED_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:218
#define ASSERT(a)
Definition: mode.c:44
BOOLEAN NTAPI FsRtlAddBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount)
Definition: largemcb.c:135
INT POOL_TYPE
Definition: typedefs.h:78
_In_ WDFCOLLECTION _In_ ULONG Index
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
uint64_t ULONGLONG
Definition: typedefs.h:67
struct _BASE_MCB_INTERNAL BASE_MCB_INTERNAL
LARGE_INTEGER RunStartVbn
Definition: largemcb.c:28
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlGetElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ ULONG I)
BOOLEAN NTAPI FsRtlGetNextBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN ULONG RunIndex, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PLONGLONG SectorCount)
Definition: largemcb.c:332
BOOLEAN NTAPI FsRtlRemoveBaseMcbEntry(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn, IN LONGLONG SectorCount)
Definition: largemcb.c:795
BOOLEAN NTAPI FsRtlLookupLastBaseMcbEntryAndIndex(IN PBASE_MCB OpaqueMcb, IN OUT PLONGLONG LargeVbn, IN OUT PLONGLONG LargeLbn, IN OUT PULONG Index)
Definition: largemcb.c:649
struct _LARGE_MCB_MAPPING LARGE_MCB_MAPPING
NPAGED_LOOKASIDE_LIST FsRtlFastMutexLookasideList
Definition: largemcb.c:23
BOOLEAN NTAPI FsRtlAddLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Lbn, IN LONGLONG SectorCount)
Definition: largemcb.c:288
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG SectorCount
Definition: part_xbox.c:31
BOOLEAN NTAPI FsRtlLookupLastLargeMcbEntryAndIndex(IN PLARGE_MCB OpaqueMcb, OUT PLONGLONG LargeVbn, OUT PLONGLONG LargeLbn, OUT PULONG Index)
Definition: largemcb.c:671
static BOOLEAN NTAPI FsRtlLookupLastLargeMcbEntryAndIndex_internal(IN PBASE_MCB_INTERNAL Mcb, OUT PLONGLONG Vbn, OUT PLONGLONG Lbn, OUT PULONG Index OPTIONAL)
Definition: largemcb.c:592
_In_ LONGLONG _Out_opt_ PLONGLONG _Out_opt_ PLONGLONG _Out_opt_ PLONGLONG _Out_opt_ PLONGLONG SectorCountFromStartingLbn
Definition: fsrtlfuncs.h:498
static RTL_GENERIC_COMPARE_RESULTS NTAPI McbMappingIntersectCompare(PRTL_GENERIC_TABLE Table, PVOID PtrA, PVOID PtrB)
Definition: largemcb.c:97
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_ PVOID Buffer)
BOOLEAN NTAPI FsRtlLookupLargeMcbEntry(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, OUT PLONGLONG Lbn OPTIONAL, OUT PLONGLONG SectorCountFromLbn OPTIONAL, OUT PLONGLONG StartingLbn OPTIONAL, OUT PLONGLONG SectorCountFromStartingLbn OPTIONAL, OUT PULONG Index OPTIONAL)
Definition: largemcb.c:560
_SEH2_END
Definition: create.c:4400
VOID FASTCALL KeInitializeGuardedMutex(OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:31
VOID NTAPI FsRtlTruncateBaseMcb(IN PBASE_MCB OpaqueMcb, IN LONGLONG Vbn)
Definition: largemcb.c:1046
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
struct LOOKASIDE_ALIGN _PAGED_LOOKASIDE_LIST PAGED_LOOKASIDE_LIST
unsigned short USHORT
Definition: pedump.c:61
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:343
VOID NTAPI FsRtlUninitializeLargeMcb(IN PLARGE_MCB Mcb)
Definition: largemcb.c:1096
unsigned int * PULONG
Definition: retypes.h:1
#define NULL
Definition: types.h:112
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
VOID FASTCALL KeReleaseGuardedMutex(IN OUT PKGUARDED_MUTEX GuardedMutex)
Definition: gmutex.c:53
struct _LARGE_MCB_MAPPING_ENTRY * PLARGE_MCB_MAPPING_ENTRY
_In_ LONGLONG Vbn
Definition: fsrtlfuncs.h:470
#define OUT
Definition: typedefs.h:40
VOID NTAPI FsRtlResetLargeMcb(IN PLARGE_MCB Mcb, IN BOOLEAN SelfSynchronized)
Definition: largemcb.c:943
static PVOID NTAPI McbMappingAllocate(PRTL_GENERIC_TABLE Table, CLONG Bytes)
Definition: largemcb.c:54
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ _Strict_type_match_ POOL_TYPE PoolType
Definition: wdfdevice.h:3810
unsigned int ULONG
Definition: retypes.h:1
RTL_GENERIC_TABLE Table
Definition: largemcb.c:35
_Out_ PLONGLONG _Out_ PLONGLONG LargeLbn
Definition: fsrtlfuncs.h:520
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define POOL_RAISE_IF_ALLOCATION_FAILURE
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define DPRINT
Definition: sndvol32.h:71
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTable(_In_ PRTL_GENERIC_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)
LARGE_INTEGER RunEndVbn
Definition: largemcb.c:29
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
ULONG NTAPI FsRtlNumberOfRunsInBaseMcb(IN PBASE_MCB OpaqueMcb)
Definition: largemcb.c:742
BOOLEAN NTAPI FsRtlSplitLargeMcb(IN PLARGE_MCB Mcb, IN LONGLONG Vbn, IN LONGLONG Amount)
Definition: largemcb.c:1022
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: dlist.c:348
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
#define MAXIMUM_PAIR_COUNT
Definition: fsrtl.h:50