95 _In_ HANDLE FileHandle,
96 _In_ BOOLEAN ReadOnly,
102 LARGE_INTEGER fileSize;
105 HANDLE sectionHandle;
117 Parameters = &localParameters;
136 status = STATUS_BAD_FILE_TYPE;
154 !ReadOnly ? PAGE_READWRITE : PAGE_READONLY,
186 status = STATUS_BAD_FILE_TYPE;
268 _In_ BOOLEAN ReadOnly,
269 _In_ ULONG ShareAccess,
270 _In_ ULONG CreateDisposition,
282 !ReadOnly ? (FILE_GENERIC_READ | FILE_GENERIC_WRITE | DELETE) : FILE_GENERIC_READ,
283 FILE_ATTRIBUTE_NORMAL,
331 for (i = 0; i < Pool->ByIndexSize; i++)
333 if (head = Pool->ByIndexBuckets[i])
340 entry = entry->Flink;
343 }
while (entry != head);
347 if (Pool->ByIndexBuckets)
348 PhFree(Pool->ByIndexBuckets);
352 if (Pool->SectionHandle)
353 NtClose(Pool->SectionHandle);
354 if (Pool->FileHandle)
355 NtClose(Pool->FileHandle);
370 NTSTATUS status = STATUS_SUCCESS;
374 if (Parameters->SegmentShift < 16)
376 Parameters->SegmentShift = 16;
377 status = STATUS_SOME_NOT_MAPPED;
380 if (Parameters->SegmentShift > 28)
382 Parameters->SegmentShift = 28;
383 status = STATUS_SOME_NOT_MAPPED;
399 Parameters->SegmentShift = 18;
400 Parameters->MaximumInactiveViews = 128;
426 ULONG numberOfBlocks;
432 ULONG nextSegmentIndex;
433 ULONG newFreeListIndex;
436 numberOfBlocks = (FIELD_OFFSET(
PH_FP_BLOCK_HEADER, Body) + Size + Pool->BlockSize - 1) >> Pool->BlockShift;
448 for (freeListIndex = 0; freeListIndex <= freeListLimit; freeListIndex++)
450 segmentIndex = Pool->Header->FreeLists[freeListIndex];
452 while (segmentIndex != -1)
460 nextSegmentIndex = segmentHeader->
FreeFlink;
468 segmentIndex = nextSegmentIndex;
495 if (newFreeListIndex != freeListIndex)
506 return &blockHeader->
Body;
519 _In_ ULONG SegmentIndex,
525 ULONG oldFreeListIndex;
526 ULONG newFreeListIndex;
534 if (newFreeListIndex != oldFreeListIndex)
562 firstBlock = view->
Base;
592 PhpFreeFilePool(Pool, segmentIndex, firstBlock, (PCHAR)firstBlock + offset);
655 return (PCHAR)firstBlock + offset;
718 _Out_ PULONGLONG Context
721 *Context = Pool->Header->UserContext;
732 _In_ PULONGLONG Context
735 Pool->Header->UserContext = *Context;
749 LARGE_INTEGER newSectionSize;
751 newSectionSize.QuadPart = NewSize;
773 LARGE_INTEGER sectionOffset;
777 sectionOffset.QuadPart = Offset;
790 !Pool->ReadOnly ? PAGE_READWRITE : PAGE_READONLY
825 _In_ ULONG AdditionalBlocksUsed
831 BlockOfSegmentHeader->Span = Pool->SegmentHeaderBlockSpan;
835 RtlSetBits(&bitmap, 0, Pool->SegmentHeaderBlockSpan + AdditionalBlocksUsed);
852 _Out_ PULONG NewSegmentIndex
860 newSize = (Pool->Header->SegmentCount + 1) << Pool->SegmentShift;
865 segmentIndex = Pool->Header->SegmentCount++;
872 *NewSegmentIndex = segmentIndex;
888 if (FirstBlock != Pool->FirstBlockOfFirstSegment)
907 index = View->SegmentIndex & (Pool->ByIndexSize - 1);
908 head = Pool->ByIndexBuckets[index];
917 Pool->ByIndexBuckets[index] = &View->ByIndexListEntry;
929 index = View->SegmentIndex & (Pool->ByIndexSize - 1);
930 head = Pool->ByIndexBuckets[index];
936 if (&View->ByIndexListEntry == head)
945 Pool->ByIndexBuckets[index] = NULL;
947 Pool->ByIndexBuckets[index] = head->Flink;
962 _In_ ULONG SegmentIndex
970 index = SegmentIndex & (Pool->ByIndexSize - 1);
971 head = Pool->ByIndexBuckets[index];
985 entry = entry->Flink;
986 }
while (entry != head);
1040 lookupView.
Base = Base;
1051 else if (result < 0)
1069 if ((ULONG_PTR)Base >= (ULONG_PTR)view->
Base && (ULONG_PTR)Base < (ULONG_PTR)view->
Base + Pool->SegmentSize)
1077 _In_ ULONG SegmentIndex
1120 Pool->NumberOfInactiveViews--;
1128 InsertHeadList(&Pool->InactiveViewsListHead, &View->InactiveViewsListEntry);
1129 Pool->NumberOfInactiveViews++;
1132 while (Pool->NumberOfInactiveViews > Pool->MaximumInactiveViews)
1134 PLIST_ENTRY lruEntry;
1138 Pool->NumberOfInactiveViews--;
1140 assert(lruEntry != &Pool->InactiveViewsListHead);
1141 lruView = CONTAINING_RECORD(lruEntry,
PH_FILE_POOL_VIEW, InactiveViewsListEntry);
1151 if (View->RefCount == 0)
1165 if (--View->RefCount == 0)
1167 if (View->SegmentIndex == 0)
1176 _In_ ULONG SegmentIndex
1182 if (SegmentIndex != 0 && SegmentIndex >= Pool->Header->SegmentCount)
1208 _In_ ULONG SegmentIndex
1266 _In_ ULONG NumberOfBlocks
1274 if (FirstBlock != Pool->FirstBlockOfFirstSegment)
1275 hintIndex = Pool->SegmentHeaderBlockSpan;
1277 hintIndex = Pool->SegmentHeaderBlockSpan + Pool->FileHeaderBlockSpan;
1282 foundIndex = RtlFindClearBitsAndSet(&bitmap, NumberOfBlocks, hintIndex);
1284 if (foundIndex == -1)
1290 SegmentHeader->FreeBlocks -= NumberOfBlocks;
1292 blockHeader = (
PPH_FP_BLOCK_HEADER)((PCHAR)FirstBlock + (foundIndex << Pool->BlockShift));
1293 blockHeader->
Flags = 0;
1294 blockHeader->
Span = NumberOfBlocks;
1321 startIndex = (ULONG)((PCHAR)BlockHeader - (PCHAR)FirstBlock) >> Pool->BlockShift;
1322 blockSpan = BlockHeader->Span;
1324 SegmentHeader->FreeBlocks += blockSpan;
1335 _In_ ULONG NumberOfBlocks
1359 if (NumberOfBlocks >= 4)
1368 if (NumberOfBlocks >= 1)
1386 _In_ ULONG FreeListIndex,
1387 _In_ ULONG SegmentIndex,
1391 ULONG oldSegmentIndex;
1395 oldSegmentIndex = Pool->Header->FreeLists[FreeListIndex];
1399 if (oldSegmentIndex != -1)
1403 if (!oldSegmentFirstBlock)
1409 SegmentHeader->FreeBlink = -1;
1410 SegmentHeader->FreeFlink = oldSegmentIndex;
1411 Pool->Header->FreeLists[FreeListIndex] = SegmentIndex;
1413 if (oldSegmentIndex != -1)
1416 oldSegmentHeader->
FreeBlink = SegmentIndex;
1433 _In_ ULONG FreeListIndex,
1434 _In_ ULONG SegmentIndex,
1438 ULONG flinkSegmentIndex;
1441 ULONG blinkSegmentIndex;
1445 flinkSegmentIndex = SegmentHeader->
FreeFlink;
1446 blinkSegmentIndex = SegmentHeader->FreeBlink;
1450 if (flinkSegmentIndex != -1)
1454 if (!flinkSegmentFirstBlock)
1458 if (blinkSegmentIndex != -1)
1462 if (!blinkSegmentFirstBlock)
1464 if (flinkSegmentIndex != -1)
1473 if (flinkSegmentIndex != -1)
1476 flinkSegmentHeader->
FreeBlink = blinkSegmentIndex;
1480 if (blinkSegmentIndex != -1)
1483 blinkSegmentHeader->
FreeFlink = flinkSegmentIndex;
1489 Pool->Header->FreeLists[FreeListIndex] = flinkSegmentIndex;
1519 _In_ ULONG SegmentIndex,
1524 return (SegmentIndex << Pool->SegmentShift) + (ULONG)((PCHAR)Address - (PCHAR)FirstBlock);
1540 _Out_ PULONG SegmentIndex
1545 segmentIndex = Rva >> Pool->SegmentShift;
1547 if (segmentIndex >= Pool->Header->SegmentCount)
1550 *SegmentIndex = segmentIndex;
1552 return Rva & (Pool->SegmentSize - 1);