BytesRead = ReadAttribute(Vcb, IndexAllocationContext, 0, (PCHAR)Buffer, BufferSize);
- ASSERT(BytesRead = BufferSize);
+ ASSERT(BytesRead == BufferSize);
CurrentNode = Buffer;
* @returns
* STATUS_SUCCESS in case of success.
* STATUS_NOT_IMPLEMENTED if there's no $I30 bitmap attribute in the file record.
-*
+*
* @remarks
* AllocateIndexNode() doesn't write any data to the index record it creates. Called by UpdateIndexNode().
* Don't call PrintAllVCNs() or NtfsDumpFileRecord() after calling AllocateIndexNode() before UpdateIndexNode() finishes.
// Windows seems to allocate the bitmap in 8-byte chunks to keep any bytes from being wasted on padding
BytesNeeded = ALIGN_UP(BytesNeeded, ATTR_RECORD_ALIGNMENT);
- // Allocate memory for the bitmap, including some padding; RtlInitializeBitmap() wants a pointer
+ // Allocate memory for the bitmap, including some padding; RtlInitializeBitmap() wants a pointer
// that's ULONG-aligned, and it wants the size of the memory allocated for it to be a ULONG-multiple.
BitmapMem = ExAllocatePoolWithTag(NonPagedPool, BytesNeeded + sizeof(ULONG), TAG_NTFS);
if (!BitmapMem)
// Set the bit for the new index record
RtlSetBits(&Bitmap, NextNodeNumber, 1);
-
+
// Write the new bitmap attribute
Status = WriteAttribute(DeviceExt,
BitmapCtx,
}
RtlZeroMemory(NewIndexEntry, EntrySize);
-
+
if (HasChildNode)
{
NewIndexEntry->Flags = NTFS_INDEX_ENTRY_NODE | NTFS_INDEX_ENTRY_END;
{
// Truncate KeyName2 to be the same length as KeyName1
Key2Name.Length = Key1Name.Length;
-
+
// Compare the names of the same length
Comparison = RtlCompareUnicodeString(&Key1Name, &Key2Name, !CaseSensitive);
/**
* @name CountBTreeKeys
* @implemented
-*
+*
* Counts the number of linked B-Tree keys, starting with FirstKey.
*
* @param FirstKey
* Pointer to a B_TREE_KEY that will be the first key to be counted.
-*
+*
* @return
* The number of keys in a linked-list, including FirstKey and the final dummy key.
*/
{
ULONG Count = 0;
PB_TREE_KEY Current = FirstKey;
-
+
while (Current != NULL)
{
Count++;
* @returns
* STATUS_SUCCESS on success.
* STATUS_INSUFFICIENT_RESOURCES if an allocation fails.
-*
+*
* @remarks
* Allocates memory for the entire tree. Caller is responsible for destroying the tree with DestroyBTree().
*/
PNTFS_ATTR_CONTEXT IndexAllocationContext = NULL;
NTSTATUS Status;
- DPRINT1("CreateBTreeFromIndex(%p, %p)\n", IndexRoot, NewTree);
+ DPRINT("CreateBTreeFromIndex(%p, %p)\n", IndexRoot, NewTree);
if (!Tree || !RootNode || !CurrentKey)
{
PB_TREE_KEY CurrentKey = Node->FirstKey;
ULONG i;
for (i = 0; i < Node->KeyCount; i++)
- {
+ {
ASSERT(CurrentKey->IndexEntry->Length != 0);
// Add the length of the current node
* STATUS_SUCCESS on success.
* STATUS_INSUFFICIENT_RESOURCES if an allocation fails.
* STATUS_NOT_IMPLEMENTED if the new index can't fit within MaxIndexSize.
-*
+*
* @remarks
* If the function succeeds, it's the caller's responsibility to free IndexRoot with ExFreePoolWithTag().
*/
DeviceExt->NtfsInfo.BytesPerFileRecord,
TAG_NTFS);
- DPRINT1("CreateIndexRootFromBTree(%p, %p, 0x%lx, %p, %p)\n", DeviceExt, Tree, MaxIndexSize, IndexRoot, Length);
+ DPRINT("CreateIndexRootFromBTree(%p, %p, 0x%lx, %p, %p)\n", DeviceExt, Tree, MaxIndexSize, IndexRoot, Length);
#ifndef NDEBUG
DumpBTree(Tree);
// Setup each Node Entry
CurrentKey = Tree->RootNode->FirstKey;
- CurrentNodeEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)NewIndexRoot
+ CurrentNodeEntry = (PINDEX_ENTRY_ATTRIBUTE)((ULONG_PTR)NewIndexRoot
+ FIELD_OFFSET(INDEX_ROOT_ATTRIBUTE, Header)
+ NewIndexRoot->Header.FirstEntryOffset);
for (i = 0; i < Tree->RootNode->KeyCount; i++)
// Windows seems to alternate between using 0x28 and 0x40 for the first entry offset of each index buffer.
// Interestingly, neither Windows nor chkdsk seem to mind if we just use 0x28 for every index record.
- IndexBuffer->Header.FirstEntryOffset = 0x28;
+ IndexBuffer->Header.FirstEntryOffset = 0x28;
IndexBuffer->Header.AllocatedSize = BufferSize - FIELD_OFFSET(INDEX_BUFFER, Header);
// Start summing the total size of this node's entries
PB_TREE_FILENAME_NODE NewSubNode, NewIndexRoot;
PB_TREE_KEY DummyKey;
- DPRINT1("Collapsing Index Root into sub-node.\n");
+ DPRINT("Collapsing Index Root into sub-node.\n");
#ifndef NDEBUG
DumpBTree(Tree);
ULONG i;
ULONG IndexAllocationOffset;
- DPRINT1("UpdateIndexAllocation() called.\n");
+ DPRINT("UpdateIndexAllocation() called.\n");
Status = FindAttribute(DeviceExt, FileRecord, AttributeIndexAllocation, L"$I30", 4, &IndexAllocationContext, &IndexAllocationOffset);
if (NT_SUCCESS(Status))
return Status;
}
- // Advance end marker
+ // Advance end marker
EndMarker = (PNTFS_ATTR_RECORD)((ULONG_PTR)EndMarker + EndMarker->Length);
// Add index bitmap to the very end of the file record
DPRINT1("ERROR: Failed to update child node!\n");
return Status;
}
-
+
// Is the Index Entry large enough to store the VCN?
if (!BooleanFlagOn(CurrentKey->IndexEntry->Flags, NTFS_INDEX_ENTRY_NODE))
{
*MedianKey = NULL;
*NewRightHandSibling = NULL;
- DPRINT1("NtfsInsertKey(%p, 0x%I64x, %p, %p, %s, %lu, %lu, %p, %p)\n",
- Tree,
- FileReference,
- FileNameAttribute,
- Node,
- CaseSensitive ? "TRUE" : "FALSE",
- MaxIndexRootSize,
- IndexRecordSize,
- MedianKey,
- NewRightHandSibling);
+ DPRINT("NtfsInsertKey(%p, 0x%I64x, %p, %p, %s, %lu, %lu, %p, %p)\n",
+ Tree,
+ FileReference,
+ FileNameAttribute,
+ Node,
+ CaseSensitive ? "TRUE" : "FALSE",
+ MaxIndexRootSize,
+ IndexRecordSize,
+ MedianKey,
+ NewRightHandSibling);
// Create the key for the filename attribute
NewKey = CreateBTreeKeyFromFilename(FileReference, FileNameAttribute);
CaseSensitive,
MaxIndexRootSize,
IndexRecordSize,
- &NewLeftKey,
+ &NewLeftKey,
&NewChild);
if (!NT_SUCCESS(Status))
{
// Calculate maximum size of index entries without any headers
AllocatedNodeSize = IndexRecordSize - FIELD_OFFSET(INDEX_BUFFER, Header);
- // TODO: Replace magic with math
+ // TODO: Replace magic with math
MaxNodeSizeWithoutHeader = AllocatedNodeSize - 0x28;
-
+
// Has the node grown larger than its allocated size?
if (NodeSize > MaxNodeSizeWithoutHeader)
{
* @param CaseSensitive
* Boolean indicating if the function should operate in case-sensitive mode. This will be TRUE
* if an application created the file with the FILE_FLAG_POSIX_SEMANTICS flag.
-*
+*
* @return
* STATUS_SUCCESS on success.
* STATUS_INSUFFICIENT_RESOURCES if an allocation fails.
ULONG SizeSum;
ULONG i;
- DPRINT1("SplitBTreeNode(%p, %p, %p, %p, %s) called\n",
+ DPRINT("SplitBTreeNode(%p, %p, %p, %p, %s) called\n",
Tree,
Node,
MedianKey,
WCHAR FullPath[MAX_PATH];
ULONG WritePosition = MAX_PATH - 1;
- DPRINT1("NtfsMoonWalkID(%p, %I64x, %p)\n", DeviceExt, Id, OutPath);
+ DPRINT("NtfsMoonWalkID(%p, %I64x, %p)\n", DeviceExt, Id, OutPath);
RtlZeroMemory(FullPath, sizeof(FullPath));
MftRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
PNTFS_FCB FCB;
PFILE_RECORD_HEADER MftRecord;
- DPRINT1("NtfsOpenFileById(%p, %p, %I64x, %p)\n", DeviceExt, FileObject, MftId, FoundFCB);
+ DPRINT("NtfsOpenFileById(%p, %p, %I64x, %p)\n", DeviceExt, FileObject, MftId, FoundFCB);
ASSERT(MftId < NTFS_FILE_FIRST_USER_FILE);
if (MftId > 0xb) /* No entries are used yet beyond this */
NTSTATUS Status;
PWSTR AbsFileName = NULL;
- DPRINT1("NtfsOpenFile(%p, %p, %S, %s, %p)\n",
+ DPRINT("NtfsOpenFile(%p, %p, %S, %s, %p)\n",
DeviceExt,
FileObject,
FileName,
UNICODE_STRING FullPath;
PIRP Irp = IrpContext->Irp;
- DPRINT1("NtfsCreateFile(%p, %p) called\n", DeviceObject, IrpContext);
+ DPRINT("NtfsCreateFile(%p, %p) called\n", DeviceObject, IrpContext);
DeviceExt = DeviceObject->DeviceExtension;
ASSERT(DeviceExt);
}
// TODO: check for appropriate access
-
+
ExAcquireResourceExclusiveLite(&(Fcb->MainResource), TRUE);
fileRecord = ExAllocateFromNPagedLookasideList(&Fcb->Vcb->FileRecLookasideList);
else
{
Status = STATUS_NO_MEMORY;
- }
-
+ }
+
DoneOverwriting:
if (fileRecord)
ExFreeToNPagedLookasideList(&Fcb->Vcb->FileRecLookasideList, fileRecord);
{
NtfsCloseFile(DeviceExt, FileObject);
return Status;
- }
+ }
if (RequestedDisposition == FILE_SUPERSEDE)
{
ULONG MaxIndexRootSize;
ULONG RootLength;
- DPRINT1("NtfsCreateFileRecord(%p, %p, %s, %s)\n",
+ DPRINT("NtfsCreateFileRecord(%p, %p, %s, %s)\n",
DeviceExt,
FileObject,
CaseSensitive ? "TRUE" : "FALSE",
}
// Calculate maximum size of index root
- MaxIndexRootSize = DeviceExt->NtfsInfo.BytesPerFileRecord
+ MaxIndexRootSize = DeviceExt->NtfsInfo.BytesPerFileRecord
- ((ULONG_PTR)NextAttribute - (ULONG_PTR)FileRecord)
- sizeof(ULONG) * 2;
*
* @param DeviceExt
* Pointer to the DEVICE_EXTENSION of the target volume the file record will be stored on.
-*
+*
* @return
* A pointer to the newly-created FILE_RECORD_HEADER if the function succeeds, NULL otherwise.
*/
PFILE_RECORD_HEADER FileRecord;
PNTFS_ATTR_RECORD NextAttribute;
- DPRINT1("NtfsCreateEmptyFileRecord(%p)\n", DeviceExt);
+ DPRINT("NtfsCreateEmptyFileRecord(%p)\n", DeviceExt);
// allocate memory for file record
FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
* @param CanWait
* Boolean indicating if the function is allowed to wait for exclusive access to the master file table.
* This will only be relevant if the MFT doesn't have any free file records and needs to be enlarged.
-*
+*
* @return
-* STATUS_SUCCESS on success.
+* STATUS_SUCCESS on success.
* STATUS_INSUFFICIENT_RESOURCES if unable to allocate memory for the file record.
-* STATUS_CANT_WAIT if CanWait was FALSE and the function needed to resize the MFT but
+* STATUS_CANT_WAIT if CanWait was FALSE and the function needed to resize the MFT but
* couldn't get immediate, exclusive access to it.
*/
NTSTATUS
ULONGLONG ParentMftIndex;
ULONGLONG FileMftIndex;
- DPRINT1("NtfsCreateFileRecord(%p, %p, %s, %s)\n",
+ DPRINT("NtfsCreateFileRecord(%p, %p, %s, %s)\n",
DeviceExt,
FileObject,
CaseSensitive ? "TRUE" : "FALSE",
UNICODE_STRING Pattern;
ULONG Written;
- DPRINT1("NtfsQueryDirectory() called\n");
+ DPRINT("NtfsQueryDirectory() called\n");
ASSERT(IrpContext);
Irp = IrpContext->Irp;
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
- DPRINT1("NtfsDirectoryControl() called\n");
+ DPRINT("NtfsDirectoryControl() called\n");
switch (IrpContext->MinorFunction)
{
BOOLEAN
NtfsFCBIsCompressed(PNTFS_FCB Fcb)
{
- return ((Fcb->Entry.FileAttributes & NTFS_FILE_TYPE_COMPRESSED) == NTFS_FILE_TYPE_COMPRESSED);
+ return ((Fcb->Entry.FileAttributes & NTFS_FILE_TYPE_COMPRESSED) == NTFS_FILE_TYPE_COMPRESSED);
}
BOOLEAN
PNTFS_FCB rcFCB;
ULONGLONG Size, AllocatedSize;
- DPRINT1("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p, %p)\n", Vcb, DirectoryFCB, Name, Stream, Record, fileFCB);
+ DPRINT("NtfsMakeFCBFromDirEntry(%p, %p, %wZ, %p, %p, %p)\n", Vcb, DirectoryFCB, Name, Stream, Record, fileFCB);
FileName = GetBestFileNameFromRecord(Vcb, Record);
if (!FileName)
PNTFS_ATTR_CONTEXT DataContext;
USHORT Length = 0;
- DPRINT1("NtfsDirFindFile(%p, %p, %S, %s, %p)\n",
- Vcb,
- DirectoryFcb,
- FileToFind,
- CaseSensitive ? "TRUE" : "FALSE",
- FoundFCB);
+ DPRINT("NtfsDirFindFile(%p, %p, %S, %s, %p)\n",
+ Vcb,
+ DirectoryFcb,
+ FileToFind,
+ CaseSensitive ? "TRUE" : "FALSE",
+ FoundFCB);
*FoundFCB = NULL;
RtlInitUnicodeString(&File, FileToFind);
NTSTATUS
NtfsReadFCBAttribute(PNTFS_VCB Vcb,
PNTFS_FCB pFCB,
- ULONG Type,
+ ULONG Type,
PCWSTR Name,
ULONG NameLength,
PVOID * Data)
{
UNREFERENCED_PARAMETER(DeviceObject);
- DPRINT1("NtfsGetStandardInformation(%p, %p, %p, %p)\n", Fcb, DeviceObject, StandardInfo, BufferLength);
+ DPRINT("NtfsGetStandardInformation(%p, %p, %p, %p)\n", Fcb, DeviceObject, StandardInfo, BufferLength);
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
return STATUS_BUFFER_TOO_SMALL;
{
PFILENAME_ATTRIBUTE FileName = &Fcb->Entry;
- DPRINT1("NtfsGetBasicInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, BasicInfo, BufferLength);
+ DPRINT("NtfsGetBasicInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, BasicInfo, BufferLength);
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
return STATUS_BUFFER_TOO_SMALL;
UNREFERENCED_PARAMETER(FileObject);
UNREFERENCED_PARAMETER(DeviceObject);
- DPRINT1("NtfsGetNameInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, NameInfo, BufferLength);
+ DPRINT("NtfsGetNameInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, NameInfo, BufferLength);
ASSERT(NameInfo != NULL);
ASSERT(Fcb != NULL);
{
PFILENAME_ATTRIBUTE FileName = &Fcb->Entry;
- DPRINT1("NtfsGetNetworkOpenInformation(%p, %p, %p, %p)\n", Fcb, DeviceExt, NetworkInfo, BufferLength);
+ DPRINT("NtfsGetNetworkOpenInformation(%p, %p, %p, %p)\n", Fcb, DeviceExt, NetworkInfo, BufferLength);
if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
return STATUS_BUFFER_TOO_SMALL;
* STATUS_INSUFFICIENT_RESOURCES if an allocation failed,
* STATUS_ACCESS_DENIED if target file is a volume or if paging is involved.
*
-* @remarks As this function sets the size of a file at the file-level
-* (and not at the attribute level) it's not recommended to use this
+* @remarks As this function sets the size of a file at the file-level
+* (and not at the attribute level) it's not recommended to use this
* function alongside functions that operate on the data attribute directly.
*
*/
*
* @remarks Called by NtfsDispatch() in response to an IRP_MJ_SET_INFORMATION request.
* Only the FileEndOfFileInformation InformationClass is fully implemented. FileAllocationInformation
-* is a hack and not a true implementation, but it's enough to make SetEndOfFile() work.
+* is a hack and not a true implementation, but it's enough to make SetEndOfFile() work.
* All other information classes are TODO.
*
*/
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
- DPRINT1("NtfsSetInformation(%p)\n", IrpContext);
+ DPRINT("NtfsSetInformation(%p)\n", IrpContext);
Irp = IrpContext->Irp;
Stack = IrpContext->Stack;
{
PFILE_END_OF_FILE_INFORMATION EndOfFileInfo;
- /* TODO: Allocation size is not actually the same as file end for NTFS,
+ /* TODO: Allocation size is not actually the same as file end for NTFS,
however, few applications are likely to make the distinction. */
- case FileAllocationInformation:
+ case FileAllocationInformation:
DPRINT1("FIXME: Using hacky method of setting FileAllocationInformation.\n");
case FileEndOfFileInformation:
EndOfFileInfo = (PFILE_END_OF_FILE_INFORMATION)SystemBuffer;
BooleanFlagOn(Stack->Flags, SL_CASE_SENSITIVE),
&EndOfFileInfo->EndOfFile);
break;
-
+
// TODO: all other information classes
default:
* PURPOSE: NTFS filesystem driver
* PROGRAMMER: Eric Kohl
* Valentin Verkhovsky
- * Pierre Schweitzer
+ * Pierre Schweitzer
*/
/* INCLUDES *****************************************************************/
PBOOT_SECTOR BootSector;
NTSTATUS Status;
- DPRINT1("NtfsHasFileSystem() called\n");
+ DPRINT("NtfsHasFileSystem() called\n");
Size = sizeof(DISK_GEOMETRY);
Status = NtfsDeviceIoControl(DeviceToMount,
/* Check cluster size */
ClusterSize = BootSector->BPB.BytesPerSector * BootSector->BPB.SectorsPerCluster;
- if (ClusterSize != 512 && ClusterSize != 1024 &&
+ if (ClusterSize != 512 && ClusterSize != 1024 &&
ClusterSize != 2048 && ClusterSize != 4096 &&
ClusterSize != 8192 && ClusterSize != 16384 &&
ClusterSize != 32768 && ClusterSize != 65536)
NTSTATUS Status;
BOOLEAN Lookaside = FALSE;
- DPRINT1("NtfsMountVolume() called\n");
+ DPRINT("NtfsMountVolume() called\n");
if (DeviceObject != NtfsGlobalData->DeviceObject)
{
ULONGLONG ToCopy;
BOOLEAN Overflow = FALSE;
- DPRINT1("GetVolumeBitmap(%p, %p)\n", DeviceExt, Irp);
+ DPRINT("GetVolumeBitmap(%p, %p)\n", DeviceExt, Irp);
Stack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION Stack;
PDEVICE_EXTENSION DeviceExt;
- DPRINT1("NtfsUserFsRequest(%p, %p)\n", DeviceObject, Irp);
+ DPRINT("NtfsUserFsRequest(%p, %p)\n", DeviceObject, Irp);
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceExt = DeviceObject->DeviceExtension;
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
- DPRINT1("NtfsFileSystemControl() called\n");
+ DPRINT("NtfsFileSystemControl() called\n");
DeviceObject = IrpContext->DeviceObject;
Irp = IrpContext->Irp;
PCHAR ReadBuffer = (PCHAR)Buffer;
ULONGLONG StreamSize;
- DPRINT1("NtfsReadFile(%p, %p, %p, %lu, %lu, %lx, %p)\n", DeviceExt, FileObject, Buffer, Length, ReadOffset, IrpFlags, LengthRead);
+ DPRINT("NtfsReadFile(%p, %p, %p, %lu, %lu, %lx, %p)\n", DeviceExt, FileObject, Buffer, Length, ReadOffset, IrpFlags, LengthRead);
*LengthRead = 0;
* @implemented
*
* Writes a file to the disk. It presently borrows a lot of code from NtfsReadFile() and
-* VFatWriteFileData(). It needs some more work before it will be complete; it won't handle
+* VFatWriteFileData(). It needs some more work before it will be complete; it won't handle
* page files, asnyc io, cached writes, etc.
*
* @param DeviceExt
ULONG Read = 0;
RTL_BITMAP Bitmap;
- DPRINT1("NtfsGetFreeClusters(%p)\n", DeviceExt);
+ DPRINT("NtfsGetFreeClusters(%p)\n", DeviceExt);
BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
if (BitmapRecord == NULL)
return FreeClusters;
}
-/**
-* NtfsAllocateClusters
+/**
+* NtfsAllocateClusters
* Allocates a run of clusters. The run allocated might be smaller than DesiredClusters.
*/
NTSTATUS
NtfsAllocateClusters(PDEVICE_EXTENSION DeviceExt,
ULONG FirstDesiredCluster,
- ULONG DesiredClusters,
- PULONG FirstAssignedCluster,
+ ULONG DesiredClusters,
+ PULONG FirstAssignedCluster,
PULONG AssignedClusters)
{
NTSTATUS Status;
ULONG AssignedRun;
ULONG LengthWritten;
- DPRINT1("NtfsAllocateClusters(%p, %lu, %lu, %p, %p)\n", DeviceExt, FirstDesiredCluster, DesiredClusters, FirstAssignedCluster, AssignedClusters);
+ DPRINT("NtfsAllocateClusters(%p, %lu, %lu, %p, %p)\n", DeviceExt, FirstDesiredCluster, DesiredClusters, FirstAssignedCluster, AssignedClusters);
BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
if (BitmapRecord == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
}
- DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
- DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
- DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);
+ DPRINT("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
+ DPRINT("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
+ DPRINT("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);
ReadAttribute(DeviceExt, DataContext, 0, (PCHAR)BitmapData, (ULONG)BitmapDataSize);
ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
return STATUS_DISK_FULL;
}
-
+
// TODO: Observe MFT reservation zone
// Can we get one contiguous run?
{
// we can't get one contiguous run
*AssignedClusters = RtlFindNextForwardRunClear(&Bitmap, FirstDesiredCluster, FirstAssignedCluster);
-
+
if (*AssignedClusters == 0)
{
// we couldn't find any runs starting at DesiredFirstCluster
*AssignedClusters = RtlFindLongestRunClear(&Bitmap, FirstAssignedCluster);
}
-
+
}
-
+
Status = WriteAttribute(DeviceExt, DataContext, 0, BitmapData, (ULONG)BitmapDataSize, &LengthWritten, BitmapRecord);
-
+
ReleaseAttributeContext(DataContext);
ExFreePoolWithTag(BitmapData, TAG_NTFS);