/// <param name="offset">Within the PST file</param> public static void FreeAllocation(PSTFile file, long offset, int allocationLength) { int numberOfPages = file.Header.root.NumberOfAllocationMapPages; if (offset < AllocationMapPage.FirstPageOffset) { throw new ArgumentException("Allocation offset to free cannot be before the first AMAP"); } int pageIndex = (int)((offset - AllocationMapPage.FirstPageOffset) / AllocationMapPage.MapppedLength); if (pageIndex >= numberOfPages) { throw new ArgumentException("Allocation offset to free cannot be after the area mapped by the last AMAP"); } AllocationMapPage page = AllocationMapPage.ReadAllocationMapPage(file, pageIndex); int pageStartOffset = (int)((offset - AllocationMapPage.FirstPageOffset) % AllocationMapPage.MapppedLength); if (pageStartOffset < AllocationMapPage.Length) { throw new ArgumentException("Allocation offset to free cannot be within the AMAP page"); } page.FreeAllocatedSpace(pageStartOffset, allocationLength); page.WriteAllocationMapPage(file, pageIndex); UpdateFMap(file, page, pageIndex); file.Header.root.cbAMapFree += (uint)allocationLength; }
/// <returns>Offset of space allocated</returns> private static long AllocateSpace(PSTFile file, int allocationLength, bool pageAligned) { if (allocationLength > MaxAllocationLength) { throw new Exception("Invalid allocation length requested"); } int numberOfPages = file.Header.root.NumberOfAllocationMapPages; AllocationMapPage targetPage = null; int targetPageIndex = 0; for (int index = 0; index < numberOfPages; index++) { AllocationMapPage page = AllocationMapPage.ReadAllocationMapPage(file, index); int startOffset = page.FindContiguousSpace(allocationLength, pageAligned); if (startOffset > 0) // 0 is allocated to the AMAP itself and is not a valid value { targetPage = page; targetPageIndex = index; break; } } if (targetPage == null) { // no space was found within existing pages targetPageIndex = numberOfPages; targetPage = GrowPST(file, targetPageIndex); } int targetPageStartOffset = targetPage.FindContiguousSpace(allocationLength, pageAligned); targetPage.AllocateSpace(targetPageStartOffset, allocationLength); targetPage.WriteAllocationMapPage(file, targetPageIndex); UpdateFMap(file, targetPage, targetPageIndex); file.Header.root.cbAMapFree -= (uint)allocationLength; //InvalidatePMap(file); //InvalidateDList(file); return(AllocationMapPage.FirstPageOffset + (long)targetPageIndex * AllocationMapPage.MapppedLength + targetPageStartOffset); }