Fix indentation and coding style. No code changes!!!

svn path=/trunk/; revision=59229
This commit is contained in:
Eric Kohl 2013-06-16 12:15:06 +00:00
parent 67115c45ed
commit 78a3d923b6
17 changed files with 2162 additions and 2065 deletions

View file

@ -16,7 +16,7 @@ list(APPEND SOURCE
rw.c
volinfo.c
ntfs.rc)
add_library(ntfs SHARED ${SOURCE})
set_module_type(ntfs kernelmodedriver)

View file

@ -36,252 +36,255 @@
/* FUNCTIONS ****************************************************************/
static ULONG
static
ULONG
RunLength(PUCHAR run)
{
return(*run & 0x0f) + ((*run >> 4) & 0x0f) + 1;
return(*run & 0x0f) + ((*run >> 4) & 0x0f) + 1;
}
static LONGLONG
static
LONGLONG
RunLCN(PUCHAR run)
{
UCHAR n1 = *run & 0x0f;
UCHAR n2 = (*run >> 4) & 0x0f;
LONGLONG lcn = (n2 == 0) ? 0 : (CHAR)(run[n1 + n2]);
LONG i = 0;
UCHAR n1 = *run & 0x0f;
UCHAR n2 = (*run >> 4) & 0x0f;
LONGLONG lcn = (n2 == 0) ? 0 : (CHAR)(run[n1 + n2]);
LONG i = 0;
for (i = n1 +n2 - 1; i > n1; i--)
lcn = (lcn << 8) + run[i];
return lcn;
for (i = n1 +n2 - 1; i > n1; i--)
lcn = (lcn << 8) + run[i];
return lcn;
}
static ULONGLONG
static
ULONGLONG
RunCount(PUCHAR run)
{
UCHAR n = *run & 0xf;
ULONGLONG count = 0;
ULONG i = 0;
UCHAR n = *run & 0xf;
ULONGLONG count = 0;
ULONG i = 0;
for (i = n; i > 0; i--)
count = (count << 8) + run[i];
return count;
for (i = n; i > 0; i--)
count = (count << 8) + run[i];
return count;
}
BOOLEAN
FindRun (PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
PULONGLONG lcn,
PULONGLONG count)
FindRun(PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
PULONGLONG lcn,
PULONGLONG count)
{
PUCHAR run;
PUCHAR run;
ULONGLONG base = NresAttr->StartVcn;
ULONGLONG base = NresAttr->StartVcn;
if (vcn < NresAttr->StartVcn || vcn > NresAttr->LastVcn)
return FALSE;
if (vcn < NresAttr->StartVcn || vcn > NresAttr->LastVcn)
return FALSE;
*lcn = 0;
*lcn = 0;
for (run = (PUCHAR)((ULONG_PTR)NresAttr + NresAttr->RunArrayOffset);
*run != 0; run += RunLength(run))
for (run = (PUCHAR)((ULONG_PTR)NresAttr + NresAttr->RunArrayOffset);
*run != 0; run += RunLength(run))
{
*lcn += RunLCN(run);
*count = RunCount(run);
*lcn += RunLCN(run);
*count = RunCount(run);
if (base <= vcn && vcn < base + *count)
{
*lcn = (RunLCN(run) == 0) ? 0 : *lcn + vcn - base;
*count -= (ULONG)(vcn - base);
if (base <= vcn && vcn < base + *count)
{
*lcn = (RunLCN(run) == 0) ? 0 : *lcn + vcn - base;
*count -= (ULONG)(vcn - base);
return TRUE;
}
else
{
base += *count;
}
return TRUE;
}
else
{
base += *count;
}
}
return FALSE;
return FALSE;
}
static VOID
static
VOID
NtfsDumpFileNameAttribute(PATTRIBUTE Attribute)
{
PRESIDENT_ATTRIBUTE ResAttr;
PFILENAME_ATTRIBUTE FileNameAttr;
PRESIDENT_ATTRIBUTE ResAttr;
PFILENAME_ATTRIBUTE FileNameAttr;
DbgPrint(" $FILE_NAME ");
DbgPrint(" $FILE_NAME ");
ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
FileNameAttr = (PFILENAME_ATTRIBUTE)((ULONG_PTR)ResAttr + ResAttr->ValueOffset);
DbgPrint(" '%.*S' ", FileNameAttr->NameLength, FileNameAttr->Name);
FileNameAttr = (PFILENAME_ATTRIBUTE)((ULONG_PTR)ResAttr + ResAttr->ValueOffset);
DbgPrint(" '%.*S' ", FileNameAttr->NameLength, FileNameAttr->Name);
}
static VOID
static
VOID
NtfsDumpVolumeNameAttribute(PATTRIBUTE Attribute)
{
PRESIDENT_ATTRIBUTE ResAttr;
PWCHAR VolumeName;
PRESIDENT_ATTRIBUTE ResAttr;
PWCHAR VolumeName;
DbgPrint(" $VOLUME_NAME ");
DbgPrint(" $VOLUME_NAME ");
ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
VolumeName = (PWCHAR)((ULONG_PTR)ResAttr + ResAttr->ValueOffset);
DbgPrint(" '%.*S' ", ResAttr->ValueLength / sizeof(WCHAR), VolumeName);
VolumeName = (PWCHAR)((ULONG_PTR)ResAttr + ResAttr->ValueOffset);
DbgPrint(" '%.*S' ", ResAttr->ValueLength / sizeof(WCHAR), VolumeName);
}
static VOID
static
VOID
NtfsDumpVolumeInformationAttribute(PATTRIBUTE Attribute)
{
PRESIDENT_ATTRIBUTE ResAttr;
PVOLINFO_ATTRIBUTE VolInfoAttr;
PRESIDENT_ATTRIBUTE ResAttr;
PVOLINFO_ATTRIBUTE VolInfoAttr;
DbgPrint(" $VOLUME_INFORMATION ");
DbgPrint(" $VOLUME_INFORMATION ");
ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
ResAttr = (PRESIDENT_ATTRIBUTE)Attribute;
// DbgPrint(" Length %lu Offset %hu ", ResAttr->ValueLength, ResAttr->ValueOffset);
VolInfoAttr = (PVOLINFO_ATTRIBUTE)((ULONG_PTR)ResAttr + ResAttr->ValueOffset);
DbgPrint(" NTFS Version %u.%u Flags 0x%04hx ",
VolInfoAttr->MajorVersion,
VolInfoAttr->MinorVersion,
VolInfoAttr->Flags);
VolInfoAttr = (PVOLINFO_ATTRIBUTE)((ULONG_PTR)ResAttr + ResAttr->ValueOffset);
DbgPrint(" NTFS Version %u.%u Flags 0x%04hx ",
VolInfoAttr->MajorVersion,
VolInfoAttr->MinorVersion,
VolInfoAttr->Flags);
}
static VOID
static
VOID
NtfsDumpAttribute (PATTRIBUTE Attribute)
{
PNONRESIDENT_ATTRIBUTE NresAttr;
UNICODE_STRING Name;
PNONRESIDENT_ATTRIBUTE NresAttr;
UNICODE_STRING Name;
ULONGLONG lcn = 0;
ULONGLONG runcount = 0;
ULONGLONG lcn = 0;
ULONGLONG runcount = 0;
switch (Attribute->AttributeType)
switch (Attribute->AttributeType)
{
case AttributeFileName:
NtfsDumpFileNameAttribute(Attribute);
break;
case AttributeFileName:
NtfsDumpFileNameAttribute(Attribute);
break;
case AttributeStandardInformation:
DbgPrint(" $STANDARD_INFORMATION ");
break;
case AttributeStandardInformation:
DbgPrint(" $STANDARD_INFORMATION ");
break;
case AttributeAttributeList:
DbgPrint(" $ATTRIBUTE_LIST ");
break;
case AttributeAttributeList:
DbgPrint(" $ATTRIBUTE_LIST ");
break;
case AttributeObjectId:
DbgPrint(" $OBJECT_ID ");
break;
case AttributeObjectId:
DbgPrint(" $OBJECT_ID ");
break;
case AttributeSecurityDescriptor:
DbgPrint(" $SECURITY_DESCRIPTOR ");
break;
case AttributeSecurityDescriptor:
DbgPrint(" $SECURITY_DESCRIPTOR ");
break;
case AttributeVolumeName:
NtfsDumpVolumeNameAttribute(Attribute);
break;
case AttributeVolumeName:
NtfsDumpVolumeNameAttribute(Attribute);
break;
case AttributeVolumeInformation:
NtfsDumpVolumeInformationAttribute(Attribute);
break;
case AttributeVolumeInformation:
NtfsDumpVolumeInformationAttribute(Attribute);
break;
case AttributeData:
DbgPrint(" $DATA ");
//DataBuf = ExAllocatePool(NonPagedPool,AttributeLengthAllocated(Attribute));
break;
case AttributeData:
DbgPrint(" $DATA ");
//DataBuf = ExAllocatePool(NonPagedPool,AttributeLengthAllocated(Attribute));
break;
case AttributeIndexRoot:
DbgPrint(" $INDEX_ROOT ");
break;
case AttributeIndexRoot:
DbgPrint(" $INDEX_ROOT ");
break;
case AttributeIndexAllocation:
DbgPrint(" $INDEX_ALLOCATION ");
break;
case AttributeIndexAllocation:
DbgPrint(" $INDEX_ALLOCATION ");
break;
case AttributeBitmap:
DbgPrint(" $BITMAP ");
break;
case AttributeBitmap:
DbgPrint(" $BITMAP ");
break;
case AttributeReparsePoint:
DbgPrint(" $REPARSE_POINT ");
break;
case AttributeReparsePoint:
DbgPrint(" $REPARSE_POINT ");
break;
case AttributeEAInformation:
DbgPrint(" $EA_INFORMATION ");
break;
case AttributeEAInformation:
DbgPrint(" $EA_INFORMATION ");
break;
case AttributeEA:
DbgPrint(" $EA ");
break;
case AttributeEA:
DbgPrint(" $EA ");
break;
case AttributePropertySet:
DbgPrint(" $PROPERTY_SET ");
break;
case AttributePropertySet:
DbgPrint(" $PROPERTY_SET ");
break;
case AttributeLoggedUtilityStream:
DbgPrint(" $LOGGED_UTILITY_STREAM ");
break;
case AttributeLoggedUtilityStream:
DbgPrint(" $LOGGED_UTILITY_STREAM ");
break;
default:
DbgPrint(" Attribute %lx ",
Attribute->AttributeType);
break;
default:
DbgPrint(" Attribute %lx ",
Attribute->AttributeType);
break;
}
if (Attribute->NameLength != 0)
if (Attribute->NameLength != 0)
{
Name.Length = Attribute->NameLength * sizeof(WCHAR);
Name.MaximumLength = Name.Length;
Name.Buffer = (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset);
Name.Length = Attribute->NameLength * sizeof(WCHAR);
Name.MaximumLength = Name.Length;
Name.Buffer = (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset);
DbgPrint("'%wZ' ", &Name);
DbgPrint("'%wZ' ", &Name);
}
DbgPrint("(%s)\n",
Attribute->Nonresident ? "non-resident" : "resident");
DbgPrint("(%s)\n",
Attribute->Nonresident ? "non-resident" : "resident");
if (Attribute->Nonresident)
if (Attribute->Nonresident)
{
NresAttr = (PNONRESIDENT_ATTRIBUTE)Attribute;
NresAttr = (PNONRESIDENT_ATTRIBUTE)Attribute;
FindRun (NresAttr,0,&lcn, &runcount);
FindRun(NresAttr,0,&lcn, &runcount);
DbgPrint (" AllocatedSize %I64u DataSize %I64u\n",
NresAttr->AllocatedSize, NresAttr->DataSize);
DbgPrint (" logical clusters: %I64u - %I64u\n",
lcn, lcn + runcount - 1);
DbgPrint(" AllocatedSize %I64u DataSize %I64u\n",
NresAttr->AllocatedSize, NresAttr->DataSize);
DbgPrint(" logical clusters: %I64u - %I64u\n",
lcn, lcn + runcount - 1);
}
}
VOID
NtfsDumpFileAttributes (PFILE_RECORD_HEADER FileRecord)
NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord)
{
PATTRIBUTE Attribute;
PATTRIBUTE Attribute;
Attribute = (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
while (Attribute < (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
Attribute->AttributeType != (ATTRIBUTE_TYPE)-1)
Attribute = (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
while (Attribute < (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
Attribute->AttributeType != (ATTRIBUTE_TYPE)-1)
{
NtfsDumpAttribute (Attribute);
NtfsDumpAttribute(Attribute);
Attribute = (PATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Length);
Attribute = (PATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Length);
}
}

View file

@ -37,124 +37,124 @@
NTSTATUS
NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN ULONG SectorSize,
IN OUT PUCHAR Buffer,
IN BOOLEAN Override)
IN ULONG DiskSector,
IN ULONG SectorCount,
IN ULONG SectorSize,
IN OUT PUCHAR Buffer,
IN BOOLEAN Override)
{
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER Offset;
ULONG BlockSize;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER Offset;
ULONG BlockSize;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
BlockSize = SectorCount * SectorSize;
Offset.QuadPart = (LONGLONG)DiskSector * (LONGLONG)SectorSize;
BlockSize = SectorCount * SectorSize;
DPRINT("NtfsReadSectors(DeviceObject %p, DiskSector %d, Buffer %p)\n",
DeviceObject, DiskSector, Buffer);
DPRINT("Offset %I64x BlockSize %ld\n",
Offset.QuadPart,
BlockSize);
DPRINT("NtfsReadSectors(DeviceObject %p, DiskSector %d, Buffer %p)\n",
DeviceObject, DiskSector, Buffer);
DPRINT("Offset %I64x BlockSize %ld\n",
Offset.QuadPart,
BlockSize);
DPRINT("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
Buffer,
BlockSize,
&Offset,
&Event,
&IoStatus);
if (Irp == NULL)
DPRINT("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
Buffer,
BlockSize,
&Offset,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildSynchronousFsdRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
DPRINT("IoBuildSynchronousFsdRequest failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Override)
if (Override)
{
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
}
DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
DPRINT("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING)
DPRINT("Waiting for IO Operation for %p\n", Irp);
if (Status == STATUS_PENDING)
{
DPRINT("Operation pending\n");
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT("Getting IO Status... for %p\n", Irp);
Status = IoStatus.Status;
DPRINT("Operation pending\n");
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT("Getting IO Status... for %p\n", Irp);
Status = IoStatus.Status;
}
DPRINT("NtfsReadSectors() done (Status %x)\n", Status);
DPRINT("NtfsReadSectors() done (Status %x)\n", Status);
return Status;
return Status;
}
NTSTATUS
NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
IN ULONG ControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer,
IN OUT PULONG OutputBufferSize,
IN BOOLEAN Override)
IN ULONG ControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer,
IN OUT PULONG OutputBufferSize,
IN BOOLEAN Override)
{
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
PIO_STACK_LOCATION Stack;
IO_STATUS_BLOCK IoStatus;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
KeInitializeEvent(&Event, NotificationEvent, FALSE);
KeInitializeEvent(&Event, NotificationEvent, FALSE);
DPRINT("Building device I/O control request ...\n");
Irp = IoBuildDeviceIoControlRequest(ControlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
(OutputBufferSize) ? *OutputBufferSize : 0,
FALSE,
&Event,
&IoStatus);
if (Irp == NULL)
DPRINT("Building device I/O control request ...\n");
Irp = IoBuildDeviceIoControlRequest(ControlCode,
DeviceObject,
InputBuffer,
InputBufferSize,
OutputBuffer,
(OutputBufferSize) ? *OutputBufferSize : 0,
FALSE,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildDeviceIoControlRequest() failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
DPRINT("IoBuildDeviceIoControlRequest() failed\n");
return STATUS_INSUFFICIENT_RESOURCES;
}
if (Override)
if (Override)
{
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
Stack = IoGetNextIrpStackLocation(Irp);
Stack->Flags |= SL_OVERRIDE_VERIFY_VOLUME;
}
DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
DPRINT("Calling IO Driver... with irp %p\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING)
{
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
Status = IoStatus.Status;
}
if (OutputBufferSize)
if (OutputBufferSize)
{
*OutputBufferSize = IoStatus.Information;
*OutputBufferSize = IoStatus.Information;
}
return Status;
return Status;
}
/* EOF */

View file

@ -36,75 +36,79 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS
NtfsCloseFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject)
/*
* FUNCTION: Closes a file
*/
static
NTSTATUS
NtfsCloseFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject)
{
PNTFS_CCB Ccb;
PNTFS_CCB Ccb;
DPRINT("NtfsCloseFile(DeviceExt %p, FileObject %p)\n",
DeviceExt,
FileObject);
DPRINT("NtfsCloseFile(DeviceExt %p, FileObject %p)\n",
DeviceExt,
FileObject);
Ccb = (PNTFS_CCB)(FileObject->FsContext2);
Ccb = (PNTFS_CCB)(FileObject->FsContext2);
DPRINT("Ccb %p\n", Ccb);
if (Ccb == NULL)
DPRINT("Ccb %p\n", Ccb);
if (Ccb == NULL)
{
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
FileObject->FsContext2 = NULL;
FileObject->FsContext2 = NULL;
if (FileObject->FileName.Buffer)
if (FileObject->FileName.Buffer)
{
// This a FO, that was created outside from FSD.
// Some FO's are created with IoCreateStreamFileObject() insid from FSD.
// This FO's don't have a FileName.
NtfsReleaseFCB(DeviceExt, FileObject->FsContext);
// This a FO, that was created outside from FSD.
// Some FO's are created with IoCreateStreamFileObject() insid from FSD.
// This FO's don't have a FileName.
NtfsReleaseFCB(DeviceExt, FileObject->FsContext);
}
if (Ccb->DirectorySearchPattern)
if (Ccb->DirectorySearchPattern)
{
ExFreePool(Ccb->DirectorySearchPattern);
ExFreePool(Ccb->DirectorySearchPattern);
}
ExFreePool(Ccb);
return(STATUS_SUCCESS);
ExFreePool(Ccb);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
NtfsFsdClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExtension;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
NTSTATUS Status;
DPRINT("NtfsClose() called\n");
DPRINT("NtfsClose() called\n");
if (DeviceObject == NtfsGlobalData->DeviceObject)
if (DeviceObject == NtfsGlobalData->DeviceObject)
{
DPRINT("Closing file system\n");
Status = STATUS_SUCCESS;
goto ByeBye;
DPRINT("Closing file system\n");
Status = STATUS_SUCCESS;
goto ByeBye;
}
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
DeviceExtension = DeviceObject->DeviceExtension;
Status = NtfsCloseFile(DeviceExtension,FileObject);
Status = NtfsCloseFile(DeviceExtension,FileObject);
ByeBye:
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
/* EOF */

View file

@ -35,143 +35,146 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS
static
NTSTATUS
NtfsMakeAbsoluteFilename(PFILE_OBJECT pFileObject,
PWSTR pRelativeFileName,
PWSTR *pAbsoluteFilename)
PWSTR pRelativeFileName,
PWSTR *pAbsoluteFilename)
{
PWSTR rcName;
PNTFS_FCB Fcb;
PWSTR rcName;
PNTFS_FCB Fcb;
DPRINT("try related for %S\n", pRelativeFileName);
Fcb = pFileObject->FsContext;
ASSERT(Fcb);
DPRINT("try related for %S\n", pRelativeFileName);
Fcb = pFileObject->FsContext;
ASSERT(Fcb);
/* verify related object is a directory and target name
don't start with \. */
if (NtfsFCBIsDirectory(Fcb) == FALSE ||
pRelativeFileName[0] == L'\\')
/* verify related object is a directory and target name
don't start with \. */
if (NtfsFCBIsDirectory(Fcb) == FALSE ||
pRelativeFileName[0] == L'\\')
{
return(STATUS_INVALID_PARAMETER);
return STATUS_INVALID_PARAMETER;
}
/* construct absolute path name */
ASSERT(wcslen (Fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1
<= MAX_PATH);
rcName = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH * sizeof(WCHAR), TAG_NTFS);
if (!rcName)
/* construct absolute path name */
ASSERT(wcslen (Fcb->PathName) + 1 + wcslen (pRelativeFileName) + 1 <= MAX_PATH);
rcName = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH * sizeof(WCHAR), TAG_NTFS);
if (!rcName)
{
return(STATUS_INSUFFICIENT_RESOURCES);
return STATUS_INSUFFICIENT_RESOURCES;
}
wcscpy(rcName, Fcb->PathName);
if (!NtfsFCBIsRoot(Fcb))
wcscat (rcName, L"\\");
wcscat (rcName, pRelativeFileName);
*pAbsoluteFilename = rcName;
wcscpy(rcName, Fcb->PathName);
if (!NtfsFCBIsRoot(Fcb))
wcscat (rcName, L"\\");
wcscat (rcName, pRelativeFileName);
*pAbsoluteFilename = rcName;
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS
/*
* FUNCTION: Opens a file
*/
static
NTSTATUS
NtfsOpenFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PWSTR FileName)
/*
* FUNCTION: Opens a file
*/
PFILE_OBJECT FileObject,
PWSTR FileName)
{
PNTFS_FCB ParentFcb;
PNTFS_FCB Fcb;
NTSTATUS Status;
PWSTR AbsFileName = NULL;
PNTFS_FCB ParentFcb;
PNTFS_FCB Fcb;
NTSTATUS Status;
PWSTR AbsFileName = NULL;
DPRINT("NtfsOpenFile(%p, %p, %S)\n", DeviceExt, FileObject, FileName);
DPRINT("NtfsOpenFile(%p, %p, %S)\n", DeviceExt, FileObject, FileName);
if (FileObject->RelatedFileObject)
if (FileObject->RelatedFileObject)
{
DPRINT("Converting relative filename to absolute filename\n");
DPRINT("Converting relative filename to absolute filename\n");
Status = NtfsMakeAbsoluteFilename(FileObject->RelatedFileObject,
FileName,
&AbsFileName);
FileName = AbsFileName;
if (!NT_SUCCESS(Status))
{
return(Status);
}
return(STATUS_UNSUCCESSFUL);
Status = NtfsMakeAbsoluteFilename(FileObject->RelatedFileObject,
FileName,
&AbsFileName);
FileName = AbsFileName;
if (!NT_SUCCESS(Status))
{
return Status;
}
return STATUS_UNSUCCESSFUL;
}
//FIXME: Get cannonical path name (remove .'s, ..'s and extra separators)
//FIXME: Get cannonical path name (remove .'s, ..'s and extra separators)
DPRINT("PathName to open: %S\n", FileName);
DPRINT("PathName to open: %S\n", FileName);
/* try first to find an existing FCB in memory */
DPRINT("Checking for existing FCB in memory\n");
Fcb = NtfsGrabFCBFromTable(DeviceExt,
FileName);
if (Fcb == NULL)
/* try first to find an existing FCB in memory */
DPRINT("Checking for existing FCB in memory\n");
Fcb = NtfsGrabFCBFromTable(DeviceExt,
FileName);
if (Fcb == NULL)
{
DPRINT("No existing FCB found, making a new one if file exists.\n");
Status = NtfsGetFCBForFile(DeviceExt,
&ParentFcb,
&Fcb,
FileName);
if (ParentFcb != NULL)
{
NtfsReleaseFCB(DeviceExt,
ParentFcb);
}
DPRINT("No existing FCB found, making a new one if file exists.\n");
Status = NtfsGetFCBForFile(DeviceExt,
&ParentFcb,
&Fcb,
FileName);
if (ParentFcb != NULL)
{
NtfsReleaseFCB(DeviceExt,
ParentFcb);
}
if (!NT_SUCCESS (Status))
{
DPRINT("Could not make a new FCB, status: %x\n", Status);
if (!NT_SUCCESS (Status))
{
DPRINT("Could not make a new FCB, status: %x\n", Status);
if (AbsFileName)
ExFreePool(AbsFileName);
if (AbsFileName)
ExFreePool(AbsFileName);
return(Status);
}
return Status;
}
}
DPRINT("Attaching FCB to fileObject\n");
Status = NtfsAttachFCBToFileObject(DeviceExt,
Fcb,
FileObject);
DPRINT("Attaching FCB to fileObject\n");
Status = NtfsAttachFCBToFileObject(DeviceExt,
Fcb,
FileObject);
if (AbsFileName)
ExFreePool (AbsFileName);
if (AbsFileName)
ExFreePool(AbsFileName);
return(Status);
return Status;
}
static NTSTATUS
NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Opens a file
*/
static
NTSTATUS
NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PDEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
ULONG RequestedDisposition;
// ULONG RequestedOptions;
// PFCB Fcb;
// PWSTR FileName;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
ULONG RequestedDisposition;
// ULONG RequestedOptions;
// PFCB Fcb;
// PWSTR FileName;
NTSTATUS Status;
DPRINT("NtfsCreateFile() called\n");
DPRINT("NtfsCreateFile() called\n");
DeviceExt = DeviceObject->DeviceExtension;
ASSERT(DeviceExt);
Stack = IoGetCurrentIrpStackLocation (Irp);
ASSERT(Stack);
DeviceExt = DeviceObject->DeviceExtension;
ASSERT(DeviceExt);
Stack = IoGetCurrentIrpStackLocation (Irp);
ASSERT(Stack);
RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
RequestedDisposition = ((Stack->Parameters.Create.Options >> 24) & 0xff);
// RequestedOptions =
// Stack->Parameters.Create.Options & FILE_VALID_OPTION_FLAGS;
// PagingFileCreate = (Stack->Flags & SL_OPEN_PAGING_FILE) ? TRUE : FALSE;
@ -179,62 +182,63 @@ NtfsCreateFile(PDEVICE_OBJECT DeviceObject,
// && RequestedDisposition == FILE_SUPERSEDE)
// return STATUS_INVALID_PARAMETER;
FileObject = Stack->FileObject;
FileObject = Stack->FileObject;
if (RequestedDisposition == FILE_CREATE ||
RequestedDisposition == FILE_OVERWRITE_IF ||
RequestedDisposition == FILE_SUPERSEDE)
if (RequestedDisposition == FILE_CREATE ||
RequestedDisposition == FILE_OVERWRITE_IF ||
RequestedDisposition == FILE_SUPERSEDE)
{
return(STATUS_ACCESS_DENIED);
return STATUS_ACCESS_DENIED;
}
Status = NtfsOpenFile(DeviceExt,
FileObject,
FileObject->FileName.Buffer);
Status = NtfsOpenFile(DeviceExt,
FileObject,
FileObject->FileName.Buffer);
/*
* If the directory containing the file to open doesn't exist then
* fail immediately
*/
Irp->IoStatus.Information = (NT_SUCCESS(Status)) ? FILE_OPENED : 0;
Irp->IoStatus.Status = Status;
/*
* If the directory containing the file to open doesn't exist then
* fail immediately
*/
Irp->IoStatus.Information = (NT_SUCCESS(Status)) ? FILE_OPENED : 0;
Irp->IoStatus.Status = Status;
return(Status);
return Status;
}
NTSTATUS NTAPI
NTSTATUS
NTAPI
NtfsFsdCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status;
if (DeviceObject == NtfsGlobalData->DeviceObject)
if (DeviceObject == NtfsGlobalData->DeviceObject)
{
/* DeviceObject represents FileSystem instead of logical volume */
DPRINT("Opening file system\n");
Irp->IoStatus.Information = FILE_OPENED;
Status = STATUS_SUCCESS;
goto ByeBye;
/* DeviceObject represents FileSystem instead of logical volume */
DPRINT("Opening file system\n");
Irp->IoStatus.Information = FILE_OPENED;
Status = STATUS_SUCCESS;
goto ByeBye;
}
DeviceExt = DeviceObject->DeviceExtension;
DeviceExt = DeviceObject->DeviceExtension;
FsRtlEnterFileSystem();
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
TRUE);
Status = NtfsCreateFile(DeviceObject,
Irp);
ExReleaseResourceLite(&DeviceExt->DirResource);
FsRtlExitFileSystem();
FsRtlEnterFileSystem();
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
TRUE);
Status = NtfsCreateFile(DeviceObject,
Irp);
ExReleaseResourceLite(&DeviceExt->DirResource);
FsRtlExitFileSystem();
ByeBye:
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp,
NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp,
NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
return(Status);
return Status;
}
/* EOF */

View file

@ -477,97 +477,102 @@ CdfsGetBothDirectoryInformation(PFCB Fcb,
}
#endif
NTSTATUS
NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
{
PIRP Irp;
//PDEVICE_OBJECT DeviceObject;
//PDEVICE_EXTENSION DeviceExtension;
//LONG BufferLength = 0;
PUNICODE_STRING SearchPattern = NULL;
//FILE_INFORMATION_CLASS FileInformationClass;
ULONG FileIndex = 0;
PUCHAR Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL;
//PNTFS_FCB Fcb;
PNTFS_CCB Ccb;
// FCB TempFcb;
BOOLEAN First = FALSE;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
//NTSTATUS Status = STATUS_SUCCESS;
PIRP Irp;
//PDEVICE_OBJECT DeviceObject;
//PDEVICE_EXTENSION DeviceExtension;
//LONG BufferLength = 0;
PUNICODE_STRING SearchPattern = NULL;
//FILE_INFORMATION_CLASS FileInformationClass;
ULONG FileIndex = 0;
PUCHAR Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL;
//PNTFS_FCB Fcb;
PNTFS_CCB Ccb;
// FCB TempFcb;
BOOLEAN First = FALSE;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
//NTSTATUS Status = STATUS_SUCCESS;
DPRINT1("NtfsQueryDirectory() called\n");
DPRINT1("NtfsQueryDirectory() called\n");
ASSERT(IrpContext);
Irp = IrpContext->Irp;
//DeviceObject = IrpContext->DeviceObject;
ASSERT(IrpContext);
Irp = IrpContext->Irp;
// DeviceObject = IrpContext->DeviceObject;
//DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
// DeviceExtension = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
Ccb = (PNTFS_CCB)FileObject->FsContext2;
//Fcb = (PNTFS_FCB)FileObject->FsContext;
Ccb = (PNTFS_CCB)FileObject->FsContext2;
// Fcb = (PNTFS_FCB)FileObject->FsContext;
/* Obtain the callers parameters */
//BufferLength = Stack->Parameters.QueryDirectory.Length;
SearchPattern = Stack->Parameters.QueryDirectory.FileName;
//FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
/* Obtain the callers parameters */
//BufferLength = Stack->Parameters.QueryDirectory.Length;
SearchPattern = Stack->Parameters.QueryDirectory.FileName;
//FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
if (SearchPattern != NULL)
{
if (!Ccb->DirectorySearchPattern)
if (SearchPattern != NULL)
{
First = TRUE;
Ccb->DirectorySearchPattern =
ExAllocatePoolWithTag(NonPagedPool, SearchPattern->Length + sizeof(WCHAR), TAG_NTFS);
if (!Ccb->DirectorySearchPattern)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
if (!Ccb->DirectorySearchPattern)
{
First = TRUE;
Ccb->DirectorySearchPattern =
ExAllocatePoolWithTag(NonPagedPool, SearchPattern->Length + sizeof(WCHAR), TAG_NTFS);
if (!Ccb->DirectorySearchPattern)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
memcpy(Ccb->DirectorySearchPattern,
SearchPattern->Buffer,
SearchPattern->Length);
Ccb->DirectorySearchPattern[SearchPattern->Length / sizeof(WCHAR)] = 0;
memcpy(Ccb->DirectorySearchPattern,
SearchPattern->Buffer,
SearchPattern->Length);
Ccb->DirectorySearchPattern[SearchPattern->Length / sizeof(WCHAR)] = 0;
}
}
}
else if (!Ccb->DirectorySearchPattern)
{
First = TRUE;
Ccb->DirectorySearchPattern = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), TAG_NTFS);
if (!Ccb->DirectorySearchPattern)
else if (!Ccb->DirectorySearchPattern)
{
return(STATUS_INSUFFICIENT_RESOURCES);
First = TRUE;
Ccb->DirectorySearchPattern = ExAllocatePoolWithTag(NonPagedPool, 2 * sizeof(WCHAR), TAG_NTFS);
if (!Ccb->DirectorySearchPattern)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
Ccb->DirectorySearchPattern[0] = L'*';
Ccb->DirectorySearchPattern[1] = 0;
}
Ccb->DirectorySearchPattern[0] = L'*';
Ccb->DirectorySearchPattern[1] = 0;
}
DPRINT("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
/* Determine directory index */
if (Stack->Flags & SL_INDEX_SPECIFIED)
{
Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
}
else if (First || (Stack->Flags & SL_RESTART_SCAN))
{
Ccb->Entry = 0;
}
DPRINT("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
/* Determine directory index */
if (Stack->Flags & SL_INDEX_SPECIFIED)
{
Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
}
else if (First || (Stack->Flags & SL_RESTART_SCAN))
{
Ccb->Entry = 0;
}
/* Determine Buffer for result */
if (Irp->MdlAddress)
{
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
}
else
{
Buffer = Irp->UserBuffer;
}
DPRINT("Buffer=%p tofind=%S\n", Buffer, Ccb->DirectorySearchPattern);
/* Determine Buffer for result */
if (Irp->MdlAddress)
{
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
}
else
{
Buffer = Irp->UserBuffer;
}
DPRINT("Buffer=%p tofind=%S\n", Buffer, Ccb->DirectorySearchPattern);
#if 0
TempFcb.ObjectName = TempFcb.PathName;
while (Status == STATUS_SUCCESS && BufferLength > 0)
@ -656,69 +661,69 @@ NtfsQueryDirectory(PNTFS_IRP_CONTEXT IrpContext)
}
#endif
if (Buffer0)
{
Buffer0->NextEntryOffset = 0;
}
if (Buffer0)
{
Buffer0->NextEntryOffset = 0;
}
if (FileIndex > 0)
{
//Status = STATUS_SUCCESS;
}
if (FileIndex > 0)
{
//Status = STATUS_SUCCESS;
}
// return(Status);
return(STATUS_NO_MORE_FILES);
// return Status;
return STATUS_NO_MORE_FILES;
}
NTSTATUS NTAPI
NTSTATUS
NTAPI
NtfsFsdDirectoryControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PNTFS_IRP_CONTEXT IrpContext = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
PNTFS_IRP_CONTEXT IrpContext = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
DPRINT1("NtfsDirectoryControl() called\n");
DPRINT1("NtfsDirectoryControl() called\n");
FsRtlEnterFileSystem();
ASSERT(DeviceObject);
ASSERT(Irp);
FsRtlEnterFileSystem();
ASSERT(DeviceObject);
ASSERT(Irp);
NtfsIsIrpTopLevel(Irp);
NtfsIsIrpTopLevel(Irp);
IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
if (IrpContext)
{
switch (IrpContext->MinorFunction)
IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
if (IrpContext)
{
case IRP_MN_QUERY_DIRECTORY:
Status = NtfsQueryDirectory(IrpContext);
break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
switch (IrpContext->MinorFunction)
{
case IRP_MN_QUERY_DIRECTORY:
Status = NtfsQueryDirectory(IrpContext);
break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
}
}
else
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (IrpContext)
ExFreePoolWithTag(IrpContext, 'PRIN');
IoSetTopLevelIrp(NULL);
FsRtlExitFileSystem();
return Status;
else
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (IrpContext)
ExFreePoolWithTag(IrpContext, 'PRIN');
IoSetTopLevelIrp(NULL);
FsRtlExitFileSystem();
return Status;
}
/* EOF */

View file

@ -43,48 +43,47 @@
* Irp = IRP to be passed to internal functions
* RETURNS: Status of I/O Request
*/
NTSTATUS NTAPI
NTSTATUS
NTAPI
NtfsFsdDispatch(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PNTFS_IRP_CONTEXT IrpContext = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
TRACE_(NTFS, "NtfsFsdDispatch()\n");
FsRtlEnterFileSystem();
ASSERT(DeviceObject);
ASSERT(Irp);
NtfsIsIrpTopLevel(Irp);
IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
if (IrpContext)
{
switch (IrpContext->MajorFunction)
PNTFS_IRP_CONTEXT IrpContext = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
TRACE_(NTFS, "NtfsFsdDispatch()\n");
FsRtlEnterFileSystem();
ASSERT(DeviceObject);
ASSERT(Irp);
NtfsIsIrpTopLevel(Irp);
IrpContext = NtfsAllocateIrpContext(DeviceObject, Irp);
if (IrpContext)
{
case IRP_MJ_QUERY_VOLUME_INFORMATION:
{
Status = NtfsQueryVolumeInformation(IrpContext);
break;
}
case IRP_MJ_SET_VOLUME_INFORMATION:
{
Status = NtfsSetVolumeInformation(IrpContext);
break;
}
switch (IrpContext->MajorFunction)
{
case IRP_MJ_QUERY_VOLUME_INFORMATION:
Status = NtfsQueryVolumeInformation(IrpContext);
break;
case IRP_MJ_SET_VOLUME_INFORMATION:
Status = NtfsSetVolumeInformation(IrpContext);
break;
}
}
}
else
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (IrpContext)
ExFreePoolWithTag(IrpContext, 'PRIN');
IoSetTopLevelIrp(NULL);
FsRtlExitFileSystem();
return Status;
else
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (IrpContext)
ExFreePoolWithTag(IrpContext, 'PRIN');
IoSetTopLevelIrp(NULL);
FsRtlExitFileSystem();
return Status;
}

View file

@ -20,7 +20,7 @@
* PROJECT: ReactOS kernel
* FILE: drivers/filesystem/ntfs/fastio.c
* PURPOSE: NTFS filesystem driver
* PROGRAMMER: Pierre Schweitzer
* PROGRAMMER: Pierre Schweitzer
*/
/* INCLUDES *****************************************************************/
@ -35,30 +35,39 @@
/* FUNCTIONS ****************************************************************/
BOOLEAN NTAPI
BOOLEAN
NTAPI
NtfsAcqLazyWrite(PVOID Context,
BOOLEAN Wait)
{
UNIMPLEMENTED;
return FALSE;
UNIMPLEMENTED;
return FALSE;
}
VOID NTAPI
VOID
NTAPI
NtfsRelLazyWrite(PVOID Context)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}
BOOLEAN NTAPI
BOOLEAN
NTAPI
NtfsAcqReadAhead(PVOID Context,
BOOLEAN Wait)
{
UNIMPLEMENTED;
return FALSE;
UNIMPLEMENTED;
return FALSE;
}
VOID NTAPI
VOID
NTAPI
NtfsRelReadAhead(PVOID Context)
{
UNIMPLEMENTED;
UNIMPLEMENTED;
}
/* EOF */

View file

@ -42,77 +42,82 @@
/* FUNCTIONS ****************************************************************/
static PWCHAR
static
PWCHAR
NtfsGetNextPathElement(PWCHAR FileName)
{
if (*FileName == L'\0')
{
return(NULL);
}
if (*FileName == L'\0')
{
return NULL;
}
while (*FileName != L'\0' && *FileName != L'\\')
{
FileName++;
}
while (*FileName != L'\0' && *FileName != L'\\')
{
FileName++;
}
return(FileName);
return FileName;
}
static VOID
NtfsWSubString(PWCHAR pTarget, const PWCHAR pSource, size_t pLength)
static
VOID
NtfsWSubString(PWCHAR pTarget,
const PWCHAR pSource,
size_t pLength)
{
wcsncpy (pTarget, pSource, pLength);
pTarget [pLength] = L'\0';
wcsncpy(pTarget, pSource, pLength);
pTarget[pLength] = L'\0';
}
PNTFS_FCB
NtfsCreateFCB(PCWSTR FileName, PNTFS_VCB Vcb)
NtfsCreateFCB(PCWSTR FileName,
PNTFS_VCB Vcb)
{
PNTFS_FCB Fcb;
PNTFS_FCB Fcb;
ASSERT(Vcb);
ASSERT(Vcb->Identifier.Type == NTFS_TYPE_VCB);
ASSERT(Vcb);
ASSERT(Vcb->Identifier.Type == NTFS_TYPE_VCB);
Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_FCB), TAG_FCB);
RtlZeroMemory(Fcb, sizeof(NTFS_FCB));
Fcb = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_FCB), TAG_FCB);
RtlZeroMemory(Fcb, sizeof(NTFS_FCB));
Fcb->Identifier.Type = NTFS_TYPE_FCB;
Fcb->Identifier.Size = sizeof(NTFS_TYPE_FCB);
Fcb->Vcb = Vcb;
Fcb->Identifier.Type = NTFS_TYPE_FCB;
Fcb->Identifier.Size = sizeof(NTFS_TYPE_FCB);
if (FileName)
{
wcscpy(Fcb->PathName, FileName);
if (wcsrchr(Fcb->PathName, '\\') != 0)
Fcb->Vcb = Vcb;
if (FileName)
{
Fcb->ObjectName = wcsrchr(Fcb->PathName, '\\');
wcscpy(Fcb->PathName, FileName);
if (wcsrchr(Fcb->PathName, '\\') != 0)
{
Fcb->ObjectName = wcsrchr(Fcb->PathName, '\\');
}
else
{
Fcb->ObjectName = Fcb->PathName;
}
}
else
{
Fcb->ObjectName = Fcb->PathName;
}
}
ExInitializeResourceLite(&Fcb->MainResource);
Fcb->RFCB.Resource = &(Fcb->MainResource);
ExInitializeResourceLite(&Fcb->MainResource);
return(Fcb);
Fcb->RFCB.Resource = &(Fcb->MainResource);
return Fcb;
}
VOID
NtfsDestroyFCB(PNTFS_FCB Fcb)
{
ASSERT(Fcb);
ASSERT(Fcb->Identifier.Type == NTFS_TYPE_FCB);
ASSERT(Fcb);
ASSERT(Fcb->Identifier.Type == NTFS_TYPE_FCB);
ExDeleteResourceLite(&Fcb->MainResource);
ExDeleteResourceLite(&Fcb->MainResource);
ExFreePool(Fcb);
ExFreePool(Fcb);
}
@ -121,14 +126,14 @@ NtfsFCBIsDirectory(PNTFS_FCB Fcb)
{
// return(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY);
// return(Fcb->Entry.FileFlags & 0x02);
return(TRUE);
return TRUE;
}
BOOLEAN
NtfsFCBIsRoot(PNTFS_FCB Fcb)
{
return(wcscmp(Fcb->PathName, L"\\") == 0);
return (wcscmp(Fcb->PathName, L"\\") == 0);
}
@ -136,16 +141,16 @@ VOID
NtfsGrabFCB(PNTFS_VCB Vcb,
PNTFS_FCB Fcb)
{
KIRQL oldIrql;
KIRQL oldIrql;
DPRINT("grabbing FCB at %p: %S, refCount:%d\n",
Fcb,
Fcb->PathName,
Fcb->RefCount);
DPRINT("grabbing FCB at %p: %S, refCount:%d\n",
Fcb,
Fcb->PathName,
Fcb->RefCount);
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
}
@ -153,22 +158,23 @@ VOID
NtfsReleaseFCB(PNTFS_VCB Vcb,
PNTFS_FCB Fcb)
{
KIRQL oldIrql;
KIRQL oldIrql;
DPRINT("releasing FCB at %p: %S, refCount:%d\n",
Fcb,
Fcb->PathName,
Fcb->RefCount);
DPRINT("releasing FCB at %p: %S, refCount:%d\n",
Fcb,
Fcb->PathName,
Fcb->RefCount);
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
Fcb->RefCount--;
if (Fcb->RefCount <= 0 && !NtfsFCBIsDirectory(Fcb))
{
RemoveEntryList(&Fcb->FcbListEntry);
CcUninitializeCacheMap(Fcb->FileObject, NULL, NULL);
NtfsDestroyFCB(Fcb);
}
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
Fcb->RefCount--;
if (Fcb->RefCount <= 0 && !NtfsFCBIsDirectory(Fcb))
{
RemoveEntryList(&Fcb->FcbListEntry);
CcUninitializeCacheMap(Fcb->FileObject, NULL, NULL);
NtfsDestroyFCB(Fcb);
}
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
}
@ -176,12 +182,12 @@ VOID
NtfsAddFCBToTable(PNTFS_VCB Vcb,
PNTFS_FCB Fcb)
{
KIRQL oldIrql;
KIRQL oldIrql;
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
Fcb->Vcb = Vcb;
InsertTailList(&Vcb->FcbListHead, &Fcb->FcbListEntry);
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
Fcb->Vcb = Vcb;
InsertTailList(&Vcb->FcbListHead, &Fcb->FcbListEntry);
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
}
@ -189,41 +195,42 @@ PNTFS_FCB
NtfsGrabFCBFromTable(PNTFS_VCB Vcb,
PCWSTR FileName)
{
KIRQL oldIrql;
PNTFS_FCB Fcb;
PLIST_ENTRY current_entry;
KIRQL oldIrql;
PNTFS_FCB Fcb;
PLIST_ENTRY current_entry;
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
KeAcquireSpinLock(&Vcb->FcbListLock, &oldIrql);
if (FileName == NULL || *FileName == 0)
{
DPRINT("Return FCB for stream file object\n");
Fcb = Vcb->StreamFileObject->FsContext;
Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
return(Fcb);
}
current_entry = Vcb->FcbListHead.Flink;
while (current_entry != &Vcb->FcbListHead)
{
Fcb = CONTAINING_RECORD(current_entry, NTFS_FCB, FcbListEntry);
DPRINT("Comparing '%S' and '%S'\n", FileName, Fcb->PathName);
if (_wcsicmp(FileName, Fcb->PathName) == 0)
if (FileName == NULL || *FileName == 0)
{
Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
return(Fcb);
DPRINT("Return FCB for stream file object\n");
Fcb = Vcb->StreamFileObject->FsContext;
Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
return Fcb;
}
//FIXME: need to compare against short name in FCB here
current_entry = Vcb->FcbListHead.Flink;
while (current_entry != &Vcb->FcbListHead)
{
Fcb = CONTAINING_RECORD(current_entry, NTFS_FCB, FcbListEntry);
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
DPRINT("Comparing '%S' and '%S'\n", FileName, Fcb->PathName);
if (_wcsicmp(FileName, Fcb->PathName) == 0)
{
Fcb->RefCount++;
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
return Fcb;
}
return(NULL);
//FIXME: need to compare against short name in FCB here
current_entry = current_entry->Flink;
}
KeReleaseSpinLock(&Vcb->FcbListLock, oldIrql);
return NULL;
}
@ -231,81 +238,82 @@ NTSTATUS
NtfsFCBInitializeCache(PNTFS_VCB Vcb,
PNTFS_FCB Fcb)
{
PFILE_OBJECT FileObject;
NTSTATUS Status;
PNTFS_CCB newCCB;
PFILE_OBJECT FileObject;
NTSTATUS Status;
PNTFS_CCB newCCB;
FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice);
FileObject = IoCreateStreamFileObject(NULL, Vcb->StorageDevice);
newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB);
if (newCCB == NULL)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(newCCB, sizeof(NTFS_CCB));
newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB);
if (newCCB == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
newCCB->Identifier.Type = NTFS_TYPE_CCB;
newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB);
RtlZeroMemory(newCCB, sizeof(NTFS_CCB));
FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
FileObject->FsContext = Fcb;
FileObject->FsContext2 = newCCB;
newCCB->PtrFileObject = FileObject;
Fcb->FileObject = FileObject;
Fcb->Vcb = Vcb;
newCCB->Identifier.Type = NTFS_TYPE_CCB;
newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB);
Status = STATUS_SUCCESS;
CcInitializeCacheMap(FileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
&(NtfsGlobalData->CacheMgrCallbacks),
Fcb);
FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
FileObject->FsContext = Fcb;
FileObject->FsContext2 = newCCB;
newCCB->PtrFileObject = FileObject;
Fcb->FileObject = FileObject;
Fcb->Vcb = Vcb;
ObDereferenceObject(FileObject);
Fcb->Flags |= FCB_CACHE_INITIALIZED;
Status = STATUS_SUCCESS;
CcInitializeCacheMap(FileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
&(NtfsGlobalData->CacheMgrCallbacks),
Fcb);
return(Status);
ObDereferenceObject(FileObject);
Fcb->Flags |= FCB_CACHE_INITIALIZED;
return Status;
}
PNTFS_FCB
NtfsMakeRootFCB(PNTFS_VCB Vcb)
{
PNTFS_FCB Fcb;
PNTFS_FCB Fcb;
Fcb = NtfsCreateFCB(L"\\", Vcb);
Fcb = NtfsCreateFCB(L"\\", Vcb);
// memset(Fcb->entry.Filename, ' ', 11);
// memset(Fcb->entry.Filename, ' ', 11);
// Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize;
// Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart;
// Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY;
Fcb->RefCount = 1;
Fcb->DirIndex = 0;
Fcb->RFCB.FileSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
Fcb->RFCB.ValidDataLength.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
Fcb->RFCB.AllocationSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
// Fcb->Entry.DataLengthL = Vcb->CdInfo.RootSize;
// Fcb->Entry.ExtentLocationL = Vcb->CdInfo.RootStart;
// Fcb->Entry.FileFlags = 0x02; // FILE_ATTRIBUTE_DIRECTORY;
Fcb->RefCount = 1;
Fcb->DirIndex = 0;
Fcb->RFCB.FileSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
Fcb->RFCB.ValidDataLength.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
Fcb->RFCB.AllocationSize.QuadPart = PAGE_SIZE;//Vcb->CdInfo.RootSize;
NtfsFCBInitializeCache(Vcb, Fcb);
NtfsAddFCBToTable(Vcb, Fcb);
NtfsGrabFCB(Vcb, Fcb);
NtfsFCBInitializeCache(Vcb, Fcb);
NtfsAddFCBToTable(Vcb, Fcb);
NtfsGrabFCB(Vcb, Fcb);
return(Fcb);
return Fcb;
}
PNTFS_FCB
NtfsOpenRootFCB(PNTFS_VCB Vcb)
{
PNTFS_FCB Fcb;
PNTFS_FCB Fcb;
Fcb = NtfsGrabFCBFromTable(Vcb, L"\\");
if (Fcb == NULL)
{
Fcb = NtfsMakeRootFCB(Vcb);
}
Fcb = NtfsGrabFCBFromTable(Vcb, L"\\");
if (Fcb == NULL)
{
Fcb = NtfsMakeRootFCB(Vcb);
}
return(Fcb);
return Fcb;
}
@ -405,38 +413,39 @@ NtfsAttachFCBToFileObject(PNTFS_VCB Vcb,
PNTFS_FCB Fcb,
PFILE_OBJECT FileObject)
{
PNTFS_CCB newCCB;
PNTFS_CCB newCCB;
newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB);
if (newCCB == NULL)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
RtlZeroMemory(newCCB, sizeof(NTFS_CCB));
newCCB = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_CCB), TAG_CCB);
if (newCCB == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
newCCB->Identifier.Type = NTFS_TYPE_CCB;
newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB);
RtlZeroMemory(newCCB, sizeof(NTFS_CCB));
FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
FileObject->FsContext = Fcb;
FileObject->FsContext2 = newCCB;
newCCB->PtrFileObject = FileObject;
Fcb->Vcb = Vcb;
newCCB->Identifier.Type = NTFS_TYPE_CCB;
newCCB->Identifier.Size = sizeof(NTFS_TYPE_CCB);
if (!(Fcb->Flags & FCB_CACHE_INITIALIZED))
{
CcInitializeCacheMap(FileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
NULL,
NULL);
FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
FileObject->FsContext = Fcb;
FileObject->FsContext2 = newCCB;
newCCB->PtrFileObject = FileObject;
Fcb->Vcb = Vcb;
Fcb->Flags |= FCB_CACHE_INITIALIZED;
}
if (!(Fcb->Flags & FCB_CACHE_INITIALIZED))
{
CcInitializeCacheMap(FileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
NULL,
NULL);
//DPRINT("file open: fcb:%x file size: %d\n", Fcb, Fcb->Entry.DataLengthL);
Fcb->Flags |= FCB_CACHE_INITIALIZED;
}
return(STATUS_SUCCESS);
//DPRINT("file open: fcb:%x file size: %d\n", Fcb, Fcb->Entry.DataLengthL);
return STATUS_SUCCESS;
}
@ -547,7 +556,7 @@ NtfsDirFindFile(PNTFS_VCB Vcb,
CcUnpinData(Context);
#endif
return(STATUS_OBJECT_NAME_NOT_FOUND);
return STATUS_OBJECT_NAME_NOT_FOUND;
}
@ -557,124 +566,127 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
PNTFS_FCB *pFCB,
const PWSTR pFileName)
{
NTSTATUS Status;
WCHAR pathName [MAX_PATH];
WCHAR elementName [MAX_PATH];
PWCHAR currentElement;
PNTFS_FCB FCB;
PNTFS_FCB parentFCB;
NTSTATUS Status;
WCHAR pathName [MAX_PATH];
WCHAR elementName [MAX_PATH];
PWCHAR currentElement;
PNTFS_FCB FCB;
PNTFS_FCB parentFCB;
DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S')\n",
Vcb,
pParentFCB,
pFCB,
pFileName);
DPRINT("NtfsGetFCBForFile(%p, %p, %p, '%S')\n",
Vcb,
pParentFCB,
pFCB,
pFileName);
/* Dummy code */
/* Dummy code */
// FCB = NtfsOpenRootFCB(Vcb);
// *pFCB = FCB;
// *pParentFCB = NULL;
#if 1
/* Trivial case, open of the root directory on volume */
if (pFileName [0] == L'\0' || wcscmp(pFileName, L"\\") == 0)
{
DPRINT("returning root FCB\n");
FCB = NtfsOpenRootFCB(Vcb);
*pFCB = FCB;
*pParentFCB = NULL;
return((FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND);
}
else
{
currentElement = pFileName + 1;
wcscpy (pathName, L"\\");
FCB = NtfsOpenRootFCB (Vcb);
}
parentFCB = NULL;
/* Parse filename and check each path element for existance and access */
while (NtfsGetNextPathElement(currentElement) != 0)
{
/* Skip blank directory levels */
if ((NtfsGetNextPathElement(currentElement) - currentElement) == 0)
/* Trivial case, open of the root directory on volume */
if (pFileName [0] == L'\0' || wcscmp(pFileName, L"\\") == 0)
{
currentElement++;
continue;
}
DPRINT("returning root FCB\n");
DPRINT("Parsing, currentElement:%S\n", currentElement);
DPRINT(" parentFCB:%p FCB:%p\n", parentFCB, FCB);
/* Descend to next directory level */
if (parentFCB)
{
NtfsReleaseFCB(Vcb, parentFCB);
parentFCB = NULL;
}
/* fail if element in FCB is not a directory */
if (!NtfsFCBIsDirectory(FCB))
{
DPRINT("Element in requested path is not a directory\n");
NtfsReleaseFCB(Vcb, FCB);
FCB = 0;
*pParentFCB = NULL;
*pFCB = NULL;
return(STATUS_OBJECT_PATH_NOT_FOUND);
}
parentFCB = FCB;
/* Extract next directory level into dirName */
NtfsWSubString(pathName,
pFileName,
NtfsGetNextPathElement(currentElement) - pFileName);
DPRINT(" pathName:%S\n", pathName);
FCB = NtfsGrabFCBFromTable(Vcb, pathName);
if (FCB == NULL)
{
NtfsWSubString(elementName,
currentElement,
NtfsGetNextPathElement(currentElement) - currentElement);
DPRINT(" elementName:%S\n", elementName);
Status = NtfsDirFindFile(Vcb, parentFCB, elementName, &FCB);
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
*pParentFCB = parentFCB;
*pFCB = NULL;
currentElement = NtfsGetNextPathElement(currentElement);
if (*currentElement == L'\0' || NtfsGetNextPathElement(currentElement + 1) == 0)
{
return(STATUS_OBJECT_NAME_NOT_FOUND);
}
else
{
return(STATUS_OBJECT_PATH_NOT_FOUND);
}
}
else if (!NT_SUCCESS(Status))
{
NtfsReleaseFCB(Vcb, parentFCB);
FCB = NtfsOpenRootFCB(Vcb);
*pFCB = FCB;
*pParentFCB = NULL;
*pFCB = NULL;
return(Status);
}
return (FCB != NULL) ? STATUS_SUCCESS : STATUS_OBJECT_PATH_NOT_FOUND;
}
else
{
currentElement = pFileName + 1;
wcscpy (pathName, L"\\");
FCB = NtfsOpenRootFCB (Vcb);
}
currentElement = NtfsGetNextPathElement(currentElement);
}
*pParentFCB = parentFCB;
*pFCB = FCB;
parentFCB = NULL;
/* Parse filename and check each path element for existance and access */
while (NtfsGetNextPathElement(currentElement) != 0)
{
/* Skip blank directory levels */
if ((NtfsGetNextPathElement(currentElement) - currentElement) == 0)
{
currentElement++;
continue;
}
DPRINT("Parsing, currentElement:%S\n", currentElement);
DPRINT(" parentFCB:%p FCB:%p\n", parentFCB, FCB);
/* Descend to next directory level */
if (parentFCB)
{
NtfsReleaseFCB(Vcb, parentFCB);
parentFCB = NULL;
}
/* fail if element in FCB is not a directory */
if (!NtfsFCBIsDirectory(FCB))
{
DPRINT("Element in requested path is not a directory\n");
NtfsReleaseFCB(Vcb, FCB);
FCB = 0;
*pParentFCB = NULL;
*pFCB = NULL;
return STATUS_OBJECT_PATH_NOT_FOUND;
}
parentFCB = FCB;
/* Extract next directory level into dirName */
NtfsWSubString(pathName,
pFileName,
NtfsGetNextPathElement(currentElement) - pFileName);
DPRINT(" pathName:%S\n", pathName);
FCB = NtfsGrabFCBFromTable(Vcb, pathName);
if (FCB == NULL)
{
NtfsWSubString(elementName,
currentElement,
NtfsGetNextPathElement(currentElement) - currentElement);
DPRINT(" elementName:%S\n", elementName);
Status = NtfsDirFindFile(Vcb, parentFCB, elementName, &FCB);
if (Status == STATUS_OBJECT_NAME_NOT_FOUND)
{
*pParentFCB = parentFCB;
*pFCB = NULL;
currentElement = NtfsGetNextPathElement(currentElement);
if (*currentElement == L'\0' || NtfsGetNextPathElement(currentElement + 1) == 0)
{
return STATUS_OBJECT_NAME_NOT_FOUND;
}
else
{
return STATUS_OBJECT_PATH_NOT_FOUND;
}
}
else if (!NT_SUCCESS(Status))
{
NtfsReleaseFCB(Vcb, parentFCB);
*pParentFCB = NULL;
*pFCB = NULL;
return Status;
}
}
currentElement = NtfsGetNextPathElement(currentElement);
}
*pParentFCB = parentFCB;
*pFCB = FCB;
#endif
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
/* EOF */

View file

@ -35,232 +35,238 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS
/*
* FUNCTION: Retrieve the standard file information
*/
static
NTSTATUS
NtfsGetStandardInformation(PNTFS_FCB Fcb,
PDEVICE_OBJECT DeviceObject,
PFILE_STANDARD_INFORMATION StandardInfo,
PULONG BufferLength)
/*
* FUNCTION: Retrieve the standard file information
*/
{
DPRINT("NtfsGetStandardInformation() called\n");
DPRINT("NtfsGetStandardInformation() called\n");
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
/* PRECONDITION */
ASSERT(StandardInfo != NULL);
ASSERT(Fcb != NULL);
/* PRECONDITION */
ASSERT(StandardInfo != NULL);
ASSERT(Fcb != NULL);
RtlZeroMemory(StandardInfo,
sizeof(FILE_STANDARD_INFORMATION));
RtlZeroMemory(StandardInfo,
sizeof(FILE_STANDARD_INFORMATION));
StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
StandardInfo->NumberOfLinks = 0;
StandardInfo->DeletePending = FALSE;
StandardInfo->Directory = NtfsFCBIsDirectory(Fcb);
StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
StandardInfo->NumberOfLinks = 0;
StandardInfo->DeletePending = FALSE;
StandardInfo->Directory = NtfsFCBIsDirectory(Fcb);
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
return(STATUS_SUCCESS);
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
return STATUS_SUCCESS;
}
static NTSTATUS
static
NTSTATUS
NtfsGetPositionInformation(PFILE_OBJECT FileObject,
PFILE_POSITION_INFORMATION PositionInfo,
PULONG BufferLength)
{
DPRINT("NtfsGetPositionInformation() called\n");
DPRINT("NtfsGetPositionInformation() called\n");
if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
PositionInfo->CurrentByteOffset.QuadPart =
0;
PositionInfo->CurrentByteOffset.QuadPart = 0;
// FileObject->CurrentByteOffset.QuadPart;
DPRINT("Getting position %I64x\n",
PositionInfo->CurrentByteOffset.QuadPart);
DPRINT("Getting position %I64x\n",
PositionInfo->CurrentByteOffset.QuadPart);
*BufferLength -= sizeof(FILE_POSITION_INFORMATION);
return(STATUS_SUCCESS);
*BufferLength -= sizeof(FILE_POSITION_INFORMATION);
return STATUS_SUCCESS;
}
static NTSTATUS
static
NTSTATUS
NtfsGetBasicInformation(PFILE_OBJECT FileObject,
PNTFS_FCB Fcb,
PDEVICE_OBJECT DeviceObject,
PFILE_BASIC_INFORMATION BasicInfo,
PULONG BufferLength)
{
DPRINT("NtfsGetBasicInformation() called\n");
DPRINT("NtfsGetBasicInformation() called\n");
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
#if 0
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->CreationTime);
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->LastAccessTime);
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->LastWriteTime);
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->ChangeTime);
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->CreationTime);
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->LastAccessTime);
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->LastWriteTime);
CdfsDateTimeToFileTime(Fcb,
&BasicInfo->ChangeTime);
CdfsFileFlagsToAttributes(Fcb,
&BasicInfo->FileAttributes);
CdfsFileFlagsToAttributes(Fcb,
&BasicInfo->FileAttributes);
#endif
*BufferLength -= sizeof(FILE_BASIC_INFORMATION);
*BufferLength -= sizeof(FILE_BASIC_INFORMATION);
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS
/*
* FUNCTION: Retrieve the file name information
*/
static
NTSTATUS
NtfsGetNameInformation(PFILE_OBJECT FileObject,
PNTFS_FCB Fcb,
PDEVICE_OBJECT DeviceObject,
PFILE_NAME_INFORMATION NameInfo,
PULONG BufferLength)
/*
* FUNCTION: Retrieve the file name information
*/
{
ULONG NameLength;
ULONG NameLength;
DPRINT("NtfsGetNameInformation() called\n");
DPRINT("NtfsGetNameInformation() called\n");
ASSERT(NameInfo != NULL);
ASSERT(Fcb != NULL);
ASSERT(NameInfo != NULL);
ASSERT(Fcb != NULL);
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
// NameLength = 2;
if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
return STATUS_BUFFER_OVERFLOW;
NameInfo->FileNameLength = NameLength;
memcpy(NameInfo->FileName,
Fcb->PathName,
NameLength + sizeof(WCHAR));
NameInfo->FileNameLength = NameLength;
memcpy(NameInfo->FileName,
Fcb->PathName,
NameLength + sizeof(WCHAR));
// wcscpy(NameInfo->FileName, L"\\");
*BufferLength -=
(sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
*BufferLength -= (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS
static
NTSTATUS
NtfsGetInternalInformation(PNTFS_FCB Fcb,
PFILE_INTERNAL_INFORMATION InternalInfo,
PULONG BufferLength)
{
DPRINT("NtfsGetInternalInformation() called\n");
DPRINT("NtfsGetInternalInformation() called\n");
ASSERT(InternalInfo);
ASSERT(Fcb);
ASSERT(InternalInfo);
ASSERT(Fcb);
if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
/* FIXME: get a real index, that can be used in a create operation */
InternalInfo->IndexNumber.QuadPart = 0;
/* FIXME: get a real index, that can be used in a create operation */
InternalInfo->IndexNumber.QuadPart = 0;
*BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
*BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
NTSTATUS NTAPI
NtfsFsdQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Retrieve the specified file information
*/
NTSTATUS
NTAPI
NtfsFsdQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
FILE_INFORMATION_CLASS FileInformationClass;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PNTFS_FCB Fcb;
PVOID SystemBuffer;
ULONG BufferLength;
FILE_INFORMATION_CLASS FileInformationClass;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PNTFS_FCB Fcb;
PVOID SystemBuffer;
ULONG BufferLength;
NTSTATUS Status = STATUS_SUCCESS;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtfsQueryInformation() called\n");
DPRINT("NtfsQueryInformation() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
FileObject = Stack->FileObject;
Fcb = FileObject->FsContext;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
FileObject = Stack->FileObject;
Fcb = FileObject->FsContext;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = Stack->Parameters.QueryFile.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = Stack->Parameters.QueryFile.Length;
switch (FileInformationClass)
{
case FileStandardInformation:
Status = NtfsGetStandardInformation(Fcb,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
switch (FileInformationClass)
{
case FileStandardInformation:
Status = NtfsGetStandardInformation(Fcb,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FilePositionInformation:
Status = NtfsGetPositionInformation(FileObject,
SystemBuffer,
&BufferLength);
break;
case FilePositionInformation:
Status = NtfsGetPositionInformation(FileObject,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
Status = NtfsGetBasicInformation(FileObject,
Fcb,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
Status = NtfsGetBasicInformation(FileObject,
Fcb,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileNameInformation:
Status = NtfsGetNameInformation(FileObject,
case FileNameInformation:
Status = NtfsGetNameInformation(FileObject,
Fcb,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
break;
case FileInternalInformation:
Status = NtfsGetInternalInformation(Fcb,
SystemBuffer,
&BufferLength);
break;
case FileInternalInformation:
Status = NtfsGetInternalInformation(Fcb,
SystemBuffer,
&BufferLength);
break;
case FileAlternateNameInformation:
case FileAllInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
case FileAlternateNameInformation:
case FileAllInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
default:
DPRINT("Unimplemented information class %u\n", FileInformationClass);
Status = STATUS_INVALID_PARAMETER;
}
default:
DPRINT("Unimplemented information class %u\n", FileInformationClass);
Status = STATUS_INVALID_PARAMETER;
}
Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status))
Irp->IoStatus.Information =
Stack->Parameters.QueryFile.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
if (NT_SUCCESS(Status))
Irp->IoStatus.Information =
Stack->Parameters.QueryFile.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
return(Status);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
/* EOF */

View file

@ -36,479 +36,502 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS
NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
/*
* FUNCTION: Tests if the device contains a filesystem that can be mounted
* by this fsd
* by this fsd.
*/
static
NTSTATUS
NtfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
{
PARTITION_INFORMATION PartitionInfo;
DISK_GEOMETRY DiskGeometry;
ULONG ClusterSize, Size, k;
PBOOT_SECTOR BootSector;
NTSTATUS Status;
PARTITION_INFORMATION PartitionInfo;
DISK_GEOMETRY DiskGeometry;
ULONG ClusterSize, Size, k;
PBOOT_SECTOR BootSector;
NTSTATUS Status;
DPRINT1("NtfsHasFileSystem() called\n");
DPRINT1("NtfsHasFileSystem() called\n");
Size = sizeof(DISK_GEOMETRY);
Status = NtfsDeviceIoControl(DeviceToMount,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
&Size,
TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
return(Status);
}
if (DiskGeometry.MediaType == FixedMedia)
{
/* We have found a hard disk */
Size = sizeof(PARTITION_INFORMATION);
Size = sizeof(DISK_GEOMETRY);
Status = NtfsDeviceIoControl(DeviceToMount,
IOCTL_DISK_GET_PARTITION_INFO,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&PartitionInfo,
&DiskGeometry,
&Size,
TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
return(Status);
DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
return Status;
}
if (PartitionInfo.PartitionType != PARTITION_IFS)
if (DiskGeometry.MediaType == FixedMedia)
{
DPRINT1("Invalid partition type\n");
return(STATUS_UNRECOGNIZED_VOLUME);
}
}
/* We have found a hard disk */
Size = sizeof(PARTITION_INFORMATION);
Status = NtfsDeviceIoControl(DeviceToMount,
IOCTL_DISK_GET_PARTITION_INFO,
NULL,
0,
&PartitionInfo,
&Size,
TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
return Status;
}
DPRINT1("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
BootSector = ExAllocatePoolWithTag(NonPagedPool,
DiskGeometry.BytesPerSector, TAG_NTFS);
if (BootSector == NULL)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
if (PartitionInfo.PartitionType != PARTITION_IFS)
{
DPRINT1("Invalid partition type\n");
return STATUS_UNRECOGNIZED_VOLUME;
}
}
Status = NtfsReadSectors (DeviceToMount,
0,
1,
DiskGeometry.BytesPerSector,
(PVOID)BootSector,
TRUE);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
/* Check values of different fields. If those fields have not expected
* values, we fail, to avoid mounting partitions that Windows won't mount.
*/
/* OEMID: this field must be NTFS */
if (RtlCompareMemory(BootSector->OEMID, "NTFS ", 8) != 8)
{
DPRINT1("Failed with NTFS-identifier: [%.8s]\n", BootSector->OEMID);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
/* Unused0: this field must be COMPLETELY null */
for (k=0; k<7; k++)
{
if (BootSector->BPB.Unused0[k] != 0)
DPRINT1("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
BootSector = ExAllocatePoolWithTag(NonPagedPool,
DiskGeometry.BytesPerSector,
TAG_NTFS);
if (BootSector == NULL)
{
DPRINT1("Failed in field Unused0: [%.7s]\n", BootSector->BPB.Unused0);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
return STATUS_INSUFFICIENT_RESOURCES;
}
}
/* Unused3: this field must be COMPLETELY null */
for (k=0; k<4; k++)
{
if (BootSector->BPB.Unused3[k] != 0)
Status = NtfsReadSectors(DeviceToMount,
0,
1,
DiskGeometry.BytesPerSector,
(PVOID)BootSector,
TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT1("Failed in field Unused3: [%.4s]\n", BootSector->BPB.Unused3);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
goto ByeBye;
}
/*
* Check values of different fields. If those fields have not expected
* values, we fail, to avoid mounting partitions that Windows won't mount.
*/
/* OEMID: this field must be NTFS */
if (RtlCompareMemory(BootSector->OEMID, "NTFS ", 8) != 8)
{
DPRINT1("Failed with NTFS-identifier: [%.8s]\n", BootSector->OEMID);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
/* Unused0: this field must be COMPLETELY null */
for (k = 0; k < 7; k++)
{
if (BootSector->BPB.Unused0[k] != 0)
{
DPRINT1("Failed in field Unused0: [%.7s]\n", BootSector->BPB.Unused0);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
}
/* Unused3: this field must be COMPLETELY null */
for (k = 0; k < 4; k++)
{
if (BootSector->BPB.Unused3[k] != 0)
{
DPRINT1("Failed in field Unused3: [%.4s]\n", BootSector->BPB.Unused3);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
}
/* Check cluster size */
ClusterSize = BootSector->BPB.BytesPerSector * BootSector->BPB.SectorsPerCluster;
if (ClusterSize != 512 && ClusterSize != 1024 &&
ClusterSize != 2048 && ClusterSize != 4096 &&
ClusterSize != 8192 && ClusterSize != 16384 &&
ClusterSize != 32768 && ClusterSize != 65536)
{
DPRINT1("Cluster size failed: %hu, %hu, %hu\n",
BootSector->BPB.BytesPerSector,
BootSector->BPB.SectorsPerCluster,
ClusterSize);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
}
/* Check cluster size */
ClusterSize = BootSector->BPB.BytesPerSector * BootSector->BPB.SectorsPerCluster;
if (ClusterSize != 512 && ClusterSize != 1024 &&
ClusterSize != 2048 && ClusterSize != 4096 &&
ClusterSize != 8192 && ClusterSize != 16384 &&
ClusterSize != 32768 && ClusterSize != 65536)
{
DPRINT1("Cluster size failed: %hu, %hu, %hu\n", BootSector->BPB.BytesPerSector,
BootSector->BPB.SectorsPerCluster,
ClusterSize);
Status = STATUS_UNRECOGNIZED_VOLUME;
goto ByeBye;
}
ByeBye:
ExFreePool(BootSector);
return Status;
ExFreePool(BootSector);
return Status;
}
static NTSTATUS
static
NTSTATUS
NtfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
PDEVICE_EXTENSION DeviceExt)
{
DISK_GEOMETRY DiskGeometry;
PFILE_RECORD_HEADER MftRecord;
PFILE_RECORD_HEADER VolumeRecord;
PVOLINFO_ATTRIBUTE VolumeInfo;
PBOOT_SECTOR BootSector;
PATTRIBUTE Attribute;
ULONG Size;
NTSTATUS Status;
PNTFS_INFO NtfsInfo = &DeviceExt->NtfsInfo;
DISK_GEOMETRY DiskGeometry;
PFILE_RECORD_HEADER MftRecord;
PFILE_RECORD_HEADER VolumeRecord;
PVOLINFO_ATTRIBUTE VolumeInfo;
PBOOT_SECTOR BootSector;
PATTRIBUTE Attribute;
ULONG Size;
PNTFS_INFO NtfsInfo = &DeviceExt->NtfsInfo;
NTSTATUS Status;
DPRINT("NtfsGetVolumeData() called\n");
DPRINT("NtfsGetVolumeData() called\n");
Size = sizeof(DISK_GEOMETRY);
Status = NtfsDeviceIoControl(DeviceObject,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
&Size,
TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
return(Status);
}
Size = sizeof(DISK_GEOMETRY);
Status = NtfsDeviceIoControl(DeviceObject,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&DiskGeometry,
&Size,
TRUE);
if (!NT_SUCCESS(Status))
{
DPRINT("NtfsDeviceIoControl() failed (Status %lx)\n", Status);
return Status;
}
DPRINT("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
BootSector = ExAllocatePoolWithTag(NonPagedPool,
DiskGeometry.BytesPerSector, TAG_NTFS);
if (BootSector == NULL)
{
return(STATUS_INSUFFICIENT_RESOURCES);
}
DPRINT("BytesPerSector: %lu\n", DiskGeometry.BytesPerSector);
BootSector = ExAllocatePoolWithTag(NonPagedPool,
DiskGeometry.BytesPerSector,
TAG_NTFS);
if (BootSector == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = NtfsReadSectors(DeviceObject,
0, /* Partition boot sector */
1,
DiskGeometry.BytesPerSector,
(PVOID)BootSector,
TRUE);
if (!NT_SUCCESS(Status))
{
ExFreePool(BootSector);
return Status;
}
/* Read data from the bootsector */
NtfsInfo->BytesPerSector = BootSector->BPB.BytesPerSector;
NtfsInfo->SectorsPerCluster = BootSector->BPB.SectorsPerCluster;
NtfsInfo->BytesPerCluster = BootSector->BPB.BytesPerSector * BootSector->BPB.SectorsPerCluster;
NtfsInfo->SectorCount = BootSector->EBPB.SectorCount;
NtfsInfo->MftStart.QuadPart = BootSector->EBPB.MftLocation;
NtfsInfo->MftMirrStart.QuadPart = BootSector->EBPB.MftMirrLocation;
NtfsInfo->SerialNumber = BootSector->EBPB.SerialNumber;
if (BootSector->EBPB.ClustersPerMftRecord > 0)
NtfsInfo->BytesPerFileRecord = BootSector->EBPB.ClustersPerMftRecord * NtfsInfo->BytesPerCluster;
else
NtfsInfo->BytesPerFileRecord = 1 << (-BootSector->EBPB.ClustersPerMftRecord);
DPRINT("Boot sector information:\n");
DPRINT(" BytesPerSector: %hu\n", BootSector->BPB.BytesPerSector);
DPRINT(" SectorsPerCluster: %hu\n", BootSector->BPB.SectorsPerCluster);
DPRINT(" SectorCount: %I64u\n", BootSector->EBPB.SectorCount);
DPRINT(" MftStart: %I64u\n", BootSector->EBPB.MftLocation);
DPRINT(" MftMirrStart: %I64u\n", BootSector->EBPB.MftMirrLocation);
DPRINT(" ClustersPerMftRecord: %lx\n", BootSector->EBPB.ClustersPerMftRecord);
DPRINT(" ClustersPerIndexRecord: %lx\n", BootSector->EBPB.ClustersPerIndexRecord);
DPRINT(" SerialNumber: %I64x\n", BootSector->EBPB.SerialNumber);
Status = NtfsReadSectors(DeviceObject,
0, /* Partition boot sector */
1,
DiskGeometry.BytesPerSector,
(PVOID)BootSector,
TRUE);
if (!NT_SUCCESS(Status))
{
ExFreePool(BootSector);
return Status;
}
/* Read data from the bootsector */
NtfsInfo->BytesPerSector = BootSector->BPB.BytesPerSector;
NtfsInfo->SectorsPerCluster = BootSector->BPB.SectorsPerCluster;
NtfsInfo->BytesPerCluster = BootSector->BPB.BytesPerSector * BootSector->BPB.SectorsPerCluster;
NtfsInfo->SectorCount = BootSector->EBPB.SectorCount;
MftRecord = ExAllocatePoolWithTag(NonPagedPool,
NtfsInfo->BytesPerFileRecord,
TAG_NTFS);
if (MftRecord == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
NtfsInfo->MftStart.QuadPart = BootSector->EBPB.MftLocation;
NtfsInfo->MftMirrStart.QuadPart = BootSector->EBPB.MftMirrLocation;
NtfsInfo->SerialNumber = BootSector->EBPB.SerialNumber;
if (BootSector->EBPB.ClustersPerMftRecord > 0)
NtfsInfo->BytesPerFileRecord = BootSector->EBPB.ClustersPerMftRecord * NtfsInfo->BytesPerCluster;
else
NtfsInfo->BytesPerFileRecord = 1 << (-BootSector->EBPB.ClustersPerMftRecord);
Status = NtfsReadSectors(DeviceObject,
NtfsInfo->MftStart.u.LowPart * NtfsInfo->SectorsPerCluster,
NtfsInfo->BytesPerFileRecord / NtfsInfo->BytesPerSector,
NtfsInfo->BytesPerSector,
(PVOID)MftRecord,
TRUE);
if (!NT_SUCCESS(Status))
{
ExFreePool(MftRecord);
return Status;
}
DPRINT("Boot sector information:\n");
DPRINT(" BytesPerSector: %hu\n", BootSector->BPB.BytesPerSector);
DPRINT(" SectorsPerCluster: %hu\n", BootSector->BPB.SectorsPerCluster);
DPRINT(" SectorCount: %I64u\n", BootSector->EBPB.SectorCount);
DPRINT(" MftStart: %I64u\n", BootSector->EBPB.MftLocation);
DPRINT(" MftMirrStart: %I64u\n", BootSector->EBPB.MftMirrLocation);
DPRINT(" ClustersPerMftRecord: %lx\n", BootSector->EBPB.ClustersPerMftRecord);
DPRINT(" ClustersPerIndexRecord: %lx\n", BootSector->EBPB.ClustersPerIndexRecord);
DPRINT(" SerialNumber: %I64x\n", BootSector->EBPB.SerialNumber);
VolumeRecord = ExAllocatePoolWithTag(NonPagedPool,
NtfsInfo->BytesPerFileRecord,
TAG_NTFS);
if (VolumeRecord == NULL)
{
ExFreePool(MftRecord);
return STATUS_INSUFFICIENT_RESOURCES;
}
ExFreePool(BootSector);
/* Read Volume File (MFT index 3) */
DeviceExt->StorageDevice = DeviceObject;
Status = ReadFileRecord(DeviceExt,
3,
VolumeRecord,
MftRecord);
if (!NT_SUCCESS(Status))
{
ExFreePool(MftRecord);
return Status;
}
MftRecord = ExAllocatePoolWithTag(NonPagedPool,
NtfsInfo->BytesPerFileRecord, TAG_NTFS);
if (MftRecord == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Enumerate attributes */
NtfsDumpFileAttributes (MftRecord);
/* Enumerate attributes */
NtfsDumpFileAttributes (VolumeRecord);
/* Get volume name */
Attribute = FindAttribute (VolumeRecord, AttributeVolumeName, NULL);
DPRINT("Attribute %p\n", Attribute);
if (Attribute != NULL && ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength != 0)
{
DPRINT("Data length %lu\n", AttributeDataLength (Attribute));
NtfsInfo->VolumeLabelLength =
min (((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength, MAXIMUM_VOLUME_LABEL_LENGTH);
RtlCopyMemory(NtfsInfo->VolumeLabel,
(PVOID)((ULONG_PTR)Attribute + ((PRESIDENT_ATTRIBUTE)Attribute)->ValueOffset),
NtfsInfo->VolumeLabelLength);
}
else
{
NtfsInfo->VolumeLabelLength = 0;
}
/* Get volume information */
Attribute = FindAttribute (VolumeRecord, AttributeVolumeInformation, NULL);
DPRINT("Attribute %p\n", Attribute);
if (Attribute != NULL && ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength != 0)
{
DPRINT("Data length %lu\n", AttributeDataLength (Attribute));
VolumeInfo = (PVOID)((ULONG_PTR)Attribute + ((PRESIDENT_ATTRIBUTE)Attribute)->ValueOffset);
NtfsInfo->MajorVersion = VolumeInfo->MajorVersion;
NtfsInfo->MinorVersion = VolumeInfo->MinorVersion;
NtfsInfo->Flags = VolumeInfo->Flags;
}
Status = NtfsReadSectors(DeviceObject,
NtfsInfo->MftStart.u.LowPart * NtfsInfo->SectorsPerCluster,
NtfsInfo->BytesPerFileRecord / NtfsInfo->BytesPerSector,
NtfsInfo->BytesPerSector,
(PVOID)MftRecord,
TRUE);
if (!NT_SUCCESS(Status))
{
ExFreePool(MftRecord);
ExFreePool(VolumeRecord);
return Status;
}
VolumeRecord = ExAllocatePoolWithTag(NonPagedPool, NtfsInfo->BytesPerFileRecord, TAG_NTFS);
if (VolumeRecord == NULL)
{
ExFreePool (MftRecord);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Read Volume File (MFT index 3) */
DeviceExt->StorageDevice = DeviceObject;
Status = ReadFileRecord(DeviceExt, 3, VolumeRecord, MftRecord);
if (!NT_SUCCESS(Status))
{
ExFreePool(MftRecord);
return Status;
}
/* Enumerate attributes */
NtfsDumpFileAttributes (MftRecord);
/* Enumerate attributes */
NtfsDumpFileAttributes (VolumeRecord);
/* Get volume name */
Attribute = FindAttribute (VolumeRecord, AttributeVolumeName, NULL);
DPRINT("Attribute %p\n", Attribute);
if (Attribute != NULL && ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength != 0)
{
DPRINT("Data length %lu\n", AttributeDataLength (Attribute));
NtfsInfo->VolumeLabelLength =
min (((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength, MAXIMUM_VOLUME_LABEL_LENGTH);
RtlCopyMemory (NtfsInfo->VolumeLabel,
(PVOID)((ULONG_PTR)Attribute + ((PRESIDENT_ATTRIBUTE)Attribute)->ValueOffset),
NtfsInfo->VolumeLabelLength);
}
else
{
NtfsInfo->VolumeLabelLength = 0;
}
/* Get volume information */
Attribute = FindAttribute (VolumeRecord, AttributeVolumeInformation, NULL);
DPRINT("Attribute %p\n", Attribute);
if (Attribute != NULL && ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength != 0)
{
DPRINT("Data length %lu\n", AttributeDataLength (Attribute));
VolumeInfo = (PVOID)((ULONG_PTR)Attribute + ((PRESIDENT_ATTRIBUTE)Attribute)->ValueOffset);
NtfsInfo->MajorVersion = VolumeInfo->MajorVersion;
NtfsInfo->MinorVersion = VolumeInfo->MinorVersion;
NtfsInfo->Flags = VolumeInfo->Flags;
}
ExFreePool(MftRecord);
ExFreePool(VolumeRecord);
return Status;
}
static NTSTATUS
static
NTSTATUS
NtfsMountVolume(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PDEVICE_OBJECT NewDeviceObject = NULL;
PDEVICE_OBJECT DeviceToMount;
PIO_STACK_LOCATION Stack;
PNTFS_FCB Fcb = NULL;
PNTFS_CCB Ccb = NULL;
PNTFS_VCB Vcb = NULL;
NTSTATUS Status;
PDEVICE_OBJECT NewDeviceObject = NULL;
PDEVICE_OBJECT DeviceToMount;
PIO_STACK_LOCATION Stack;
PNTFS_FCB Fcb = NULL;
PNTFS_CCB Ccb = NULL;
PNTFS_VCB Vcb = NULL;
NTSTATUS Status;
DPRINT1("NtfsMountVolume() called\n");
DPRINT1("NtfsMountVolume() called\n");
if (DeviceObject != NtfsGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
if (DeviceObject != NtfsGlobalData->DeviceObject)
{
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
Status = NtfsHasFileSystem(DeviceToMount);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
Status = NtfsHasFileSystem(DeviceToMount);
if (!NT_SUCCESS(Status))
{
goto ByeBye;
}
Status = IoCreateDevice(NtfsGlobalData->DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&NewDeviceObject);
if (!NT_SUCCESS(Status))
goto ByeBye;
Status = IoCreateDevice(NtfsGlobalData->DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&NewDeviceObject);
if (!NT_SUCCESS(Status))
goto ByeBye;
NewDeviceObject->Flags |= DO_DIRECT_IO;
Vcb = (PVOID)NewDeviceObject->DeviceExtension;
RtlZeroMemory(Vcb, sizeof(NTFS_VCB));
NewDeviceObject->Flags |= DO_DIRECT_IO;
Vcb = (PVOID)NewDeviceObject->DeviceExtension;
RtlZeroMemory(Vcb, sizeof(NTFS_VCB));
Vcb->Identifier.Type = NTFS_TYPE_VCB;
Vcb->Identifier.Size = sizeof(NTFS_TYPE_VCB);
Vcb->Identifier.Type = NTFS_TYPE_VCB;
Vcb->Identifier.Size = sizeof(NTFS_TYPE_VCB);
Status = NtfsGetVolumeData(DeviceToMount,
Vcb);
if (!NT_SUCCESS(Status))
goto ByeBye;
Status = NtfsGetVolumeData(DeviceToMount,
Vcb);
if (!NT_SUCCESS(Status))
goto ByeBye;
NewDeviceObject->Vpb = DeviceToMount->Vpb;
NewDeviceObject->Vpb = DeviceToMount->Vpb;
Vcb->StorageDevice = DeviceToMount;
Vcb->StorageDevice->Vpb->DeviceObject = NewDeviceObject;
Vcb->StorageDevice->Vpb->RealDevice = Vcb->StorageDevice;
Vcb->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
NewDeviceObject->StackSize = Vcb->StorageDevice->StackSize + 1;
NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
Vcb->StorageDevice = DeviceToMount;
Vcb->StorageDevice->Vpb->DeviceObject = NewDeviceObject;
Vcb->StorageDevice->Vpb->RealDevice = Vcb->StorageDevice;
Vcb->StorageDevice->Vpb->Flags |= VPB_MOUNTED;
NewDeviceObject->StackSize = Vcb->StorageDevice->StackSize + 1;
NewDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
Vcb->StreamFileObject = IoCreateStreamFileObject(NULL,
Vcb->StorageDevice);
Vcb->StreamFileObject = IoCreateStreamFileObject(NULL,
Vcb->StorageDevice);
InitializeListHead(&Vcb->FcbListHead);
InitializeListHead(&Vcb->FcbListHead);
Fcb = NtfsCreateFCB(NULL, Vcb);
if (Fcb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
Fcb = NtfsCreateFCB(NULL, Vcb);
if (Fcb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
Ccb = ExAllocatePoolWithTag(NonPagedPool,
sizeof(NTFS_CCB),
TAG_CCB);
if (Ccb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
RtlZeroMemory(Ccb, sizeof(NTFS_CCB));
Ccb = ExAllocatePoolWithTag(NonPagedPool,
sizeof(NTFS_CCB),
TAG_CCB);
if (Ccb == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
}
Ccb->Identifier.Type = NTFS_TYPE_CCB;
Ccb->Identifier.Size = sizeof(NTFS_TYPE_CCB);
RtlZeroMemory(Ccb, sizeof(NTFS_CCB));
Vcb->StreamFileObject->FsContext = Fcb;
Vcb->StreamFileObject->FsContext2 = Ccb;
Vcb->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
Vcb->StreamFileObject->PrivateCacheMap = NULL;
Vcb->StreamFileObject->Vpb = Vcb->Vpb;
Ccb->PtrFileObject = Vcb->StreamFileObject;
Fcb->FileObject = Vcb->StreamFileObject;
Fcb->Vcb = (PDEVICE_EXTENSION)Vcb->StorageDevice;
Ccb->Identifier.Type = NTFS_TYPE_CCB;
Ccb->Identifier.Size = sizeof(NTFS_TYPE_CCB);
Fcb->Flags = FCB_IS_VOLUME_STREAM;
Vcb->StreamFileObject->FsContext = Fcb;
Vcb->StreamFileObject->FsContext2 = Ccb;
Vcb->StreamFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
Vcb->StreamFileObject->PrivateCacheMap = NULL;
Vcb->StreamFileObject->Vpb = Vcb->Vpb;
Ccb->PtrFileObject = Vcb->StreamFileObject;
Fcb->FileObject = Vcb->StreamFileObject;
Fcb->Vcb = (PDEVICE_EXTENSION)Vcb->StorageDevice;
Fcb->RFCB.FileSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector;
Fcb->RFCB.ValidDataLength.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector;
Fcb->RFCB.AllocationSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; /* Correct? */
Fcb->Flags = FCB_IS_VOLUME_STREAM;
// Fcb->Entry.ExtentLocationL = 0;
// Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
Fcb->RFCB.FileSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector;
Fcb->RFCB.ValidDataLength.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector;
Fcb->RFCB.AllocationSize.QuadPart = Vcb->NtfsInfo.SectorCount * Vcb->NtfsInfo.BytesPerSector; /* Correct? */
CcInitializeCacheMap(Vcb->StreamFileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
&(NtfsGlobalData->CacheMgrCallbacks),
Fcb);
// Fcb->Entry.ExtentLocationL = 0;
// Fcb->Entry.DataLengthL = DeviceExt->CdInfo.VolumeSpaceSize * BLOCKSIZE;
ExInitializeResourceLite(&Vcb->DirResource);
CcInitializeCacheMap(Vcb->StreamFileObject,
(PCC_FILE_SIZES)(&Fcb->RFCB.AllocationSize),
FALSE,
&(NtfsGlobalData->CacheMgrCallbacks),
Fcb);
KeInitializeSpinLock(&Vcb->FcbListLock);
ExInitializeResourceLite(&Vcb->DirResource);
/* Get serial number */
NewDeviceObject->Vpb->SerialNumber = Vcb->NtfsInfo.SerialNumber;
KeInitializeSpinLock(&Vcb->FcbListLock);
/* Get volume label */
NewDeviceObject->Vpb->VolumeLabelLength = Vcb->NtfsInfo.VolumeLabelLength;
RtlCopyMemory(NewDeviceObject->Vpb->VolumeLabel,
Vcb->NtfsInfo.VolumeLabel,
Vcb->NtfsInfo.VolumeLabelLength);
/* Get serial number */
NewDeviceObject->Vpb->SerialNumber = Vcb->NtfsInfo.SerialNumber;
Status = STATUS_SUCCESS;
/* Get volume label */
NewDeviceObject->Vpb->VolumeLabelLength = Vcb->NtfsInfo.VolumeLabelLength;
RtlCopyMemory(NewDeviceObject->Vpb->VolumeLabel,
Vcb->NtfsInfo.VolumeLabel,
Vcb->NtfsInfo.VolumeLabelLength);
Status = STATUS_SUCCESS;
ByeBye:
if (!NT_SUCCESS(Status))
{
/* Cleanup */
if (Vcb && Vcb->StreamFileObject)
ObDereferenceObject(Vcb->StreamFileObject);
if (Fcb)
ExFreePool(Fcb);
if (Ccb)
ExFreePool(Ccb);
if (NewDeviceObject)
IoDeleteDevice(NewDeviceObject);
}
if (!NT_SUCCESS(Status))
{
/* Cleanup */
if (Vcb && Vcb->StreamFileObject)
ObDereferenceObject(Vcb->StreamFileObject);
DPRINT("NtfsMountVolume() done (Status: %lx)\n", Status);
if (Fcb)
ExFreePool(Fcb);
return Status;
if (Ccb)
ExFreePool(Ccb);
if (NewDeviceObject)
IoDeleteDevice(NewDeviceObject);
}
DPRINT("NtfsMountVolume() done (Status: %lx)\n", Status);
return Status;
}
static NTSTATUS
static
NTSTATUS
NtfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
DPRINT1("NtfsVerifyVolume() called\n");
return STATUS_WRONG_VOLUME;
DPRINT1("NtfsVerifyVolume() called\n");
return STATUS_WRONG_VOLUME;
}
NTSTATUS NTAPI
NTSTATUS
NTAPI
NtfsFsdFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
DPRINT1("NtfsFileSystemControl() called\n");
DPRINT1("NtfsFileSystemControl() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp);
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->MinorFunction)
{
case IRP_MN_KERNEL_CALL:
case IRP_MN_USER_FS_REQUEST:
DPRINT("NTFS: IRP_MN_USER_FS_REQUEST/IRP_MN_KERNEL_CALL\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
switch (Stack->MinorFunction)
{
case IRP_MN_KERNEL_CALL:
case IRP_MN_USER_FS_REQUEST:
DPRINT("NTFS: IRP_MN_USER_FS_REQUEST/IRP_MN_KERNEL_CALL\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
case IRP_MN_MOUNT_VOLUME:
DPRINT("NTFS: IRP_MN_MOUNT_VOLUME\n");
Status = NtfsMountVolume(DeviceObject, Irp);
break;
case IRP_MN_MOUNT_VOLUME:
DPRINT("NTFS: IRP_MN_MOUNT_VOLUME\n");
Status = NtfsMountVolume(DeviceObject, Irp);
break;
case IRP_MN_VERIFY_VOLUME:
DPRINT1("NTFS: IRP_MN_VERIFY_VOLUME\n");
Status = NtfsVerifyVolume(DeviceObject, Irp);
break;
case IRP_MN_VERIFY_VOLUME:
DPRINT1("NTFS: IRP_MN_VERIFY_VOLUME\n");
Status = NtfsVerifyVolume(DeviceObject, Irp);
break;
default:
DPRINT("NTFS FSC: MinorFunction %d\n", Stack->MinorFunction);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
default:
DPRINT("NTFS FSC: MinorFunction %d\n", Stack->MinorFunction);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
return Status;
}
/* EOF */

View file

@ -38,283 +38,288 @@
NTSTATUS
NtfsOpenMft (PDEVICE_EXTENSION Vcb)
NtfsOpenMft(PDEVICE_EXTENSION Vcb)
{
// PVOID Bitmap;
PFILE_RECORD_HEADER MftRecord;
PFILE_RECORD_HEADER FileRecord;
// PATTRIBUTE Attribute;
// PATTRIBUTE AttrData;
// PRESIDENT_ATTRIBUTE ResAttr;
// PVOID Bitmap;
PFILE_RECORD_HEADER MftRecord;
PFILE_RECORD_HEADER FileRecord;
// PATTRIBUTE Attribute;
// PATTRIBUTE AttrData;
// PRESIDENT_ATTRIBUTE ResAttr;
NTSTATUS Status;
ULONG BytesPerFileRecord;
ULONG n;
ULONG i;
NTSTATUS Status;
ULONG BytesPerFileRecord;
ULONG n;
ULONG i;
DPRINT1("NtfsOpenMft() called\n");
DPRINT1("NtfsOpenMft() called\n");
BytesPerFileRecord = Vcb->NtfsInfo.BytesPerFileRecord;
BytesPerFileRecord = Vcb->NtfsInfo.BytesPerFileRecord;
MftRecord = ExAllocatePoolWithTag(NonPagedPool,
BytesPerFileRecord, TAG_NTFS);
if (MftRecord == NULL)
MftRecord = ExAllocatePoolWithTag(NonPagedPool,
BytesPerFileRecord,
TAG_NTFS);
if (MftRecord == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
return STATUS_INSUFFICIENT_RESOURCES;
}
Status = NtfsReadSectors(Vcb->StorageDevice,
Vcb->NtfsInfo.MftStart.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster,
BytesPerFileRecord / Vcb->NtfsInfo.BytesPerSector,
Vcb->NtfsInfo.BytesPerSector,
(PVOID)MftRecord,
FALSE);
if (!NT_SUCCESS(Status))
Status = NtfsReadSectors(Vcb->StorageDevice,
Vcb->NtfsInfo.MftStart.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster,
BytesPerFileRecord / Vcb->NtfsInfo.BytesPerSector,
Vcb->NtfsInfo.BytesPerSector,
(PVOID)MftRecord,
FALSE);
if (!NT_SUCCESS(Status))
{
ExFreePool(MftRecord);
return Status;
ExFreePool(MftRecord);
return Status;
}
FixupUpdateSequenceArray(MftRecord);
FixupUpdateSequenceArray(MftRecord);
// Attribute = FindAttribute(MftRecord, AttributeBitmap, 0);
// Attribute = FindAttribute(MftRecord, AttributeBitmap, 0);
/* Get number of file records*/
n = AttributeDataLength(FindAttribute(MftRecord, AttributeData, 0)) / BytesPerFileRecord;
/* Get number of file records*/
n = AttributeDataLength (FindAttribute (MftRecord, AttributeData, 0))
/ BytesPerFileRecord;
FileRecord = ExAllocatePoolWithTag(NonPagedPool, BytesPerFileRecord, TAG_NTFS);
if (FileRecord == NULL)
FileRecord = ExAllocatePoolWithTag(NonPagedPool,
BytesPerFileRecord,
TAG_NTFS);
if (FileRecord == NULL)
{
ExFreePool(MftRecord);
return(STATUS_INSUFFICIENT_RESOURCES);
ExFreePool(MftRecord);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Enumerate MFT Records */
DPRINT("Enumerate MFT records\n");
for ( i=0; i < n; i++)
/* Enumerate MFT Records */
DPRINT("Enumerate MFT records\n");
for (i = 0; i < n; i++)
{
ReadFileRecord(Vcb, i, FileRecord, MftRecord);
ReadFileRecord(Vcb,
i,
FileRecord,
MftRecord);
if (FileRecord->Ntfs.Type == NRH_FILE_TYPE && (FileRecord->Flags & FRH_IN_USE))
{
DPRINT("\nFile %lu\n\n", i);
if (FileRecord->Ntfs.Type == NRH_FILE_TYPE &&
(FileRecord->Flags & FRH_IN_USE))
{
DPRINT("\nFile %lu\n\n", i);
/* Enumerate attributtes */
NtfsDumpFileAttributes (FileRecord);
DbgPrint("\n\n");
}
/* Enumerate attributtes */
NtfsDumpFileAttributes (FileRecord);
DbgPrint("\n\n");
}
}
ExFreePool(FileRecord);
ExFreePool(MftRecord);
ExFreePool(FileRecord);
ExFreePool(MftRecord);
return Status;
return Status;
}
PATTRIBUTE
FindAttribute (PFILE_RECORD_HEADER FileRecord,
ATTRIBUTE_TYPE Type,
PWSTR name)
FindAttribute(PFILE_RECORD_HEADER FileRecord,
ATTRIBUTE_TYPE Type,
PWSTR name)
{
PATTRIBUTE Attribute;
PATTRIBUTE Attribute;
Attribute = (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
while (Attribute < (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
Attribute->AttributeType != (ATTRIBUTE_TYPE)-1)
Attribute = (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
while (Attribute < (PATTRIBUTE)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
Attribute->AttributeType != (ATTRIBUTE_TYPE)-1)
{
if (Attribute->AttributeType == Type)
{
return Attribute;
}
if (Attribute->AttributeType == Type)
{
return Attribute;
}
Attribute = (PATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Length);
Attribute = (PATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Length);
}
return NULL;
return NULL;
}
ULONG
AttributeAllocatedLength (PATTRIBUTE Attribute)
AttributeAllocatedLength(PATTRIBUTE Attribute)
{
if (Attribute->Nonresident)
if (Attribute->Nonresident)
{
return ((PNONRESIDENT_ATTRIBUTE)Attribute)->AllocatedSize;
return ((PNONRESIDENT_ATTRIBUTE)Attribute)->AllocatedSize;
}
return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength;
return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength;
}
ULONG
AttributeDataLength (PATTRIBUTE Attribute)
AttributeDataLength(PATTRIBUTE Attribute)
{
if (Attribute->Nonresident)
if (Attribute->Nonresident)
{
return ((PNONRESIDENT_ATTRIBUTE)Attribute)->DataSize;
return ((PNONRESIDENT_ATTRIBUTE)Attribute)->DataSize;
}
return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength;
return ((PRESIDENT_ATTRIBUTE)Attribute)->ValueLength;
}
VOID
ReadAttribute (PATTRIBUTE attr,
PVOID buffer,
PDEVICE_EXTENSION Vcb,
PDEVICE_OBJECT DeviceObject)
ReadAttribute(PATTRIBUTE attr,
PVOID buffer,
PDEVICE_EXTENSION Vcb,
PDEVICE_OBJECT DeviceObject)
{
PNONRESIDENT_ATTRIBUTE NresAttr = (PNONRESIDENT_ATTRIBUTE)attr;
if (attr->Nonresident == FALSE)
PNONRESIDENT_ATTRIBUTE NresAttr = (PNONRESIDENT_ATTRIBUTE)attr;
if (attr->Nonresident == FALSE)
{
memcpy (buffer,
(PVOID)((ULONG_PTR)attr + ((PRESIDENT_ATTRIBUTE)attr)->ValueOffset),
((PRESIDENT_ATTRIBUTE)attr)->ValueLength);
memcpy(buffer,
(PVOID)((ULONG_PTR)attr + ((PRESIDENT_ATTRIBUTE)attr)->ValueOffset),
((PRESIDENT_ATTRIBUTE)attr)->ValueLength);
}
ReadExternalAttribute(Vcb, NresAttr, 0, (ULONG)(NresAttr->LastVcn) + 1,
buffer);
ReadExternalAttribute(Vcb,
NresAttr,
0,
(ULONG)(NresAttr->LastVcn) + 1,
buffer);
}
NTSTATUS
ReadFileRecord (PDEVICE_EXTENSION Vcb,
ULONG index,
PFILE_RECORD_HEADER file,
PFILE_RECORD_HEADER Mft)
ReadFileRecord(PDEVICE_EXTENSION Vcb,
ULONG index,
PFILE_RECORD_HEADER file,
PFILE_RECORD_HEADER Mft)
{
PVOID p;
ULONG BytesPerFileRecord = Vcb->NtfsInfo.BytesPerFileRecord;
ULONG clusters = max(BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster, 1);
ULONGLONG vcn = index * BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster;
LONG m = (Vcb->NtfsInfo.BytesPerCluster / BytesPerFileRecord) - 1;
ULONG n = m > 0 ? (index & m) : 0;
PVOID p;
ULONG BytesPerFileRecord = Vcb->NtfsInfo.BytesPerFileRecord;
ULONG clusters = max(BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster, 1);
ULONGLONG vcn = index * BytesPerFileRecord / Vcb->NtfsInfo.BytesPerCluster;
LONG m = (Vcb->NtfsInfo.BytesPerCluster / BytesPerFileRecord) - 1;
ULONG n = m > 0 ? (index & m) : 0;
p = ExAllocatePoolWithTag(NonPagedPool, clusters * Vcb->NtfsInfo.BytesPerCluster, TAG_NTFS);
p = ExAllocatePoolWithTag(NonPagedPool,
clusters * Vcb->NtfsInfo.BytesPerCluster,
TAG_NTFS);
ReadVCN (Vcb, Mft, AttributeData, vcn, clusters, p);
ReadVCN (Vcb, Mft, AttributeData, vcn, clusters, p);
memcpy(file, (PVOID)((ULONG_PTR)p + n * BytesPerFileRecord), BytesPerFileRecord);
memcpy(file,
(PVOID)((ULONG_PTR)p + n * BytesPerFileRecord),
BytesPerFileRecord);
ExFreePool(p);
ExFreePool(p);
FixupUpdateSequenceArray(file);
FixupUpdateSequenceArray(file);
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
VOID
ReadExternalAttribute (PDEVICE_EXTENSION Vcb,
PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
ULONG count,
PVOID buffer)
ReadExternalAttribute(PDEVICE_EXTENSION Vcb,
PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
ULONG count,
PVOID buffer)
{
ULONGLONG lcn;
ULONGLONG runcount;
ULONG readcount;
ULONG left;
ULONG n;
ULONGLONG lcn;
ULONGLONG runcount;
ULONG readcount;
ULONG left;
ULONG n;
PUCHAR bytes = (PUCHAR)buffer;
for (left = count; left>0; left -=readcount)
for (left = count; left > 0; left -= readcount)
{
FindRun(NresAttr, vcn, &lcn, &runcount);
FindRun(NresAttr, vcn, &lcn, &runcount);
// readcount = (ULONG)(__min(runcount, left));
readcount = (ULONG)min (runcount, left);
// readcount = (ULONG)(__min(runcount, left));
readcount = (ULONG)min(runcount, left);
n = readcount * Vcb->NtfsInfo.BytesPerCluster;
if (lcn == 0)
memset(bytes, 0, n);
else
ReadLCN(Vcb, lcn, readcount, bytes);
vcn += readcount;
bytes += n;
n = readcount * Vcb->NtfsInfo.BytesPerCluster;
if (lcn == 0)
memset(bytes, 0, n);
else
ReadLCN(Vcb, lcn, readcount, bytes);
vcn += readcount;
bytes += n;
}
}
VOID
ReadVCN (PDEVICE_EXTENSION Vcb,
PFILE_RECORD_HEADER file,
ATTRIBUTE_TYPE type,
ULONGLONG vcn,
ULONG count,
PVOID buffer)
ReadVCN(PDEVICE_EXTENSION Vcb,
PFILE_RECORD_HEADER file,
ATTRIBUTE_TYPE type,
ULONGLONG vcn,
ULONG count,
PVOID buffer)
{
PNONRESIDENT_ATTRIBUTE NresAttr;
PATTRIBUTE attr;
PNONRESIDENT_ATTRIBUTE NresAttr;
PATTRIBUTE attr;
attr = FindAttribute(file, type, 0);
attr = FindAttribute(file, type, 0);
NresAttr = (PNONRESIDENT_ATTRIBUTE) attr;
NresAttr = (PNONRESIDENT_ATTRIBUTE) attr;
if (NresAttr == 0 || (vcn < NresAttr->StartVcn ||vcn > NresAttr->LastVcn))
if (NresAttr == 0 || (vcn < NresAttr->StartVcn ||vcn > NresAttr->LastVcn))
{
// PATTRIBUTE attrList = FindAttribute(file,AttributeAttributeList,0);
DbgPrint("Exeption \n");
DbgPrint("Exeption \n");
// KeDebugCheck(0);
}
ReadExternalAttribute(Vcb, NresAttr, vcn, count, buffer);
ReadExternalAttribute(Vcb, NresAttr, vcn, count, buffer);
}
#if 0
BOOL bitset(PUCHAR bitmap, ULONG i)
{
return (bitmap[i>>3] & (1 << (i & 7))) !=0;
return (bitmap[i>>3] & (1 << (i & 7))) !=0;
}
#endif
VOID FixupUpdateSequenceArray(PFILE_RECORD_HEADER file)
VOID
FixupUpdateSequenceArray(PFILE_RECORD_HEADER file)
{
PUSHORT usa = (PUSHORT)((ULONG_PTR)file + file->Ntfs.UsaOffset);
PUSHORT sector = (PUSHORT)file;
PUSHORT usa = (PUSHORT)((ULONG_PTR)file + file->Ntfs.UsaOffset);
PUSHORT sector = (PUSHORT)file;
ULONG i;
for( i =1; i < file->Ntfs.UsaCount; i++)
{
sector[255] = usa[i];
sector += 256;
}
for (i = 1; i < file->Ntfs.UsaCount; i++)
{
sector[255] = usa[i];
sector += 256;
}
}
NTSTATUS
ReadLCN (PDEVICE_EXTENSION Vcb,
ULONGLONG lcn,
ULONG count,
PVOID buffer)
ReadLCN(PDEVICE_EXTENSION Vcb,
ULONGLONG lcn,
ULONG count,
PVOID buffer)
{
LARGE_INTEGER DiskSector;
LARGE_INTEGER DiskSector;
DiskSector.QuadPart = lcn;
DiskSector.QuadPart = lcn;
return NtfsReadSectors (Vcb->StorageDevice,
DiskSector.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster,
count * Vcb->NtfsInfo.SectorsPerCluster,
Vcb->NtfsInfo.BytesPerSector,
buffer,
FALSE);
return NtfsReadSectors(Vcb->StorageDevice,
DiskSector.u.LowPart * Vcb->NtfsInfo.SectorsPerCluster,
count * Vcb->NtfsInfo.SectorsPerCluster,
Vcb->NtfsInfo.BytesPerSector,
buffer,
FALSE);
}
/* EOF */

View file

@ -45,17 +45,17 @@
BOOLEAN
NtfsIsIrpTopLevel(PIRP Irp)
{
BOOLEAN ReturnCode = FALSE;
TRACE_(NTFS, "NtfsIsIrpTopLevel()\n");
BOOLEAN ReturnCode = FALSE;
if (IoGetTopLevelIrp() == NULL)
{
IoSetTopLevelIrp(Irp);
ReturnCode = TRUE;
}
TRACE_(NTFS, "NtfsIsIrpTopLevel()\n");
return ReturnCode;
if (IoGetTopLevelIrp() == NULL)
{
IoSetTopLevelIrp(Irp);
ReturnCode = TRUE;
}
return ReturnCode;
}
/*
@ -69,29 +69,35 @@ PNTFS_IRP_CONTEXT
NtfsAllocateIrpContext(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PNTFS_IRP_CONTEXT IrpContext;
PIO_STACK_LOCATION IoStackLocation;
TRACE_(NTFS, "NtfsAllocateIrpContext()\n");
IrpContext = (PNTFS_IRP_CONTEXT)ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_IRP_CONTEXT), 'PRIN');
if (IrpContext == NULL)
return NULL;
RtlZeroMemory(IrpContext, sizeof(NTFS_IRP_CONTEXT));
PNTFS_IRP_CONTEXT IrpContext;
PIO_STACK_LOCATION IoStackLocation;
IrpContext->Identifier.Type = NTFS_TYPE_IRP_CONTEST;
IrpContext->Identifier.Size = sizeof(NTFS_IRP_CONTEXT);
IrpContext->Irp = Irp;
IrpContext->DeviceObject = DeviceObject;
if (Irp)
{
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IoStackLocation);
TRACE_(NTFS, "NtfsAllocateIrpContext()\n");
IrpContext->MajorFunction = IoStackLocation->MajorFunction;
IrpContext->MinorFunction = IoStackLocation->MinorFunction;
IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
}
return IrpContext;
IrpContext = (PNTFS_IRP_CONTEXT)ExAllocatePoolWithTag(NonPagedPool,
sizeof(NTFS_IRP_CONTEXT),
'PRIN');
if (IrpContext == NULL)
return NULL;
RtlZeroMemory(IrpContext, sizeof(NTFS_IRP_CONTEXT));
IrpContext->Identifier.Type = NTFS_TYPE_IRP_CONTEST;
IrpContext->Identifier.Size = sizeof(NTFS_IRP_CONTEXT);
IrpContext->Irp = Irp;
IrpContext->DeviceObject = DeviceObject;
if (Irp)
{
IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
ASSERT(IoStackLocation);
IrpContext->MajorFunction = IoStackLocation->MajorFunction;
IrpContext->MinorFunction = IoStackLocation->MinorFunction;
IrpContext->IsTopLevel = (IoGetTopLevelIrp() == Irp);
}
return IrpContext;
}
/* EOF */

View file

@ -38,9 +38,6 @@ PNTFS_GLOBAL_DATA NtfsGlobalData = NULL;
/* FUNCTIONS ****************************************************************/
NTSTATUS NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initialize the driver
* ARGUMENTS:
@ -48,91 +45,99 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
NTSTATUS
NTAPI
DriverEntry(PDRIVER_OBJECT DriverObject,
PUNICODE_STRING RegistryPath)
{
NTSTATUS Status;
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
NTSTATUS Status;
TRACE_(NTFS, "DriverEntry(%p, '%wZ')\n", DriverObject, RegistryPath);
TRACE_(NTFS, "DriverEntry(%p, '%wZ')\n", DriverObject, RegistryPath);
/* Initialize global data */
NtfsGlobalData = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_GLOBAL_DATA), 'GRDN');
if (!NtfsGlobalData)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorEnd;
}
RtlZeroMemory(NtfsGlobalData, sizeof(NTFS_GLOBAL_DATA));
NtfsGlobalData->Identifier.Type = NTFS_TYPE_GLOBAL_DATA;
NtfsGlobalData->Identifier.Size = sizeof(NTFS_GLOBAL_DATA);
ExInitializeResourceLite(&NtfsGlobalData->Resource);
/* Initialize global data */
NtfsGlobalData = ExAllocatePoolWithTag(NonPagedPool, sizeof(NTFS_GLOBAL_DATA), 'GRDN');
if (!NtfsGlobalData)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto ErrorEnd;
}
/* Keep trace of Driver Object */
NtfsGlobalData->DriverObject = DriverObject;
RtlZeroMemory(NtfsGlobalData, sizeof(NTFS_GLOBAL_DATA));
NtfsGlobalData->Identifier.Type = NTFS_TYPE_GLOBAL_DATA;
NtfsGlobalData->Identifier.Size = sizeof(NTFS_GLOBAL_DATA);
/* Initialize IRP functions array */
NtfsInitializeFunctionPointers(DriverObject);
/* Initialize CC functions array */
NtfsGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = NtfsAcqLazyWrite;
NtfsGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = NtfsRelLazyWrite;
NtfsGlobalData->CacheMgrCallbacks.AcquireForReadAhead = NtfsAcqReadAhead;
NtfsGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = NtfsRelReadAhead;
ExInitializeResourceLite(&NtfsGlobalData->Resource);
/* Driver can't be unloaded */
DriverObject->DriverUnload = NULL;
/* Keep trace of Driver Object */
NtfsGlobalData->DriverObject = DriverObject;
Status = IoCreateDevice(DriverObject,
sizeof(NTFS_GLOBAL_DATA),
&DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&NtfsGlobalData->DeviceObject);
if (!NT_SUCCESS(Status))
{
WARN_(NTFS, "IoCreateDevice failed with status: %lx\n", Status);
goto ErrorEnd;
}
NtfsGlobalData->DeviceObject->Flags |= DO_DIRECT_IO;
/* Initialize IRP functions array */
NtfsInitializeFunctionPointers(DriverObject);
/* Register file system */
IoRegisterFileSystem(NtfsGlobalData->DeviceObject);
ObReferenceObject(NtfsGlobalData->DeviceObject);
/* Initialize CC functions array */
NtfsGlobalData->CacheMgrCallbacks.AcquireForLazyWrite = NtfsAcqLazyWrite;
NtfsGlobalData->CacheMgrCallbacks.ReleaseFromLazyWrite = NtfsRelLazyWrite;
NtfsGlobalData->CacheMgrCallbacks.AcquireForReadAhead = NtfsAcqReadAhead;
NtfsGlobalData->CacheMgrCallbacks.ReleaseFromReadAhead = NtfsRelReadAhead;
/* Driver can't be unloaded */
DriverObject->DriverUnload = NULL;
Status = IoCreateDevice(DriverObject,
sizeof(NTFS_GLOBAL_DATA),
&DeviceName,
FILE_DEVICE_DISK_FILE_SYSTEM,
0,
FALSE,
&NtfsGlobalData->DeviceObject);
if (!NT_SUCCESS(Status))
{
WARN_(NTFS, "IoCreateDevice failed with status: %lx\n", Status);
goto ErrorEnd;
}
NtfsGlobalData->DeviceObject->Flags |= DO_DIRECT_IO;
/* Register file system */
IoRegisterFileSystem(NtfsGlobalData->DeviceObject);
ObReferenceObject(NtfsGlobalData->DeviceObject);
ErrorEnd:
if (!NT_SUCCESS(Status))
{
if (NtfsGlobalData)
if (!NT_SUCCESS(Status))
{
ExDeleteResourceLite(&NtfsGlobalData->Resource);
ExFreePoolWithTag(NtfsGlobalData, 'GRDN');
if (NtfsGlobalData)
{
ExDeleteResourceLite(&NtfsGlobalData->Resource);
ExFreePoolWithTag(NtfsGlobalData, 'GRDN');
}
}
}
return Status;
return Status;
}
VOID NTAPI
NtfsInitializeFunctionPointers(PDRIVER_OBJECT DriverObject)
/*
* FUNCTION: Called within the driver entry to initialize the IRP functions array
* ARGUMENTS:
* DriverObject = object describing this driver
* RETURNS: Nothing
*/
VOID
NTAPI
NtfsInitializeFunctionPointers(PDRIVER_OBJECT DriverObject)
{
DriverObject->MajorFunction[IRP_MJ_CREATE] = NtfsFsdCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NtfsFsdClose;
DriverObject->MajorFunction[IRP_MJ_READ] = NtfsFsdRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = NtfsFsdWrite;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NtfsFsdQueryInformation;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = NtfsFsdDispatch;
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = NtfsFsdDispatch;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = NtfsFsdDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = NtfsFsdFileSystemControl;
return;
DriverObject->MajorFunction[IRP_MJ_CREATE] = NtfsFsdCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = NtfsFsdClose;
DriverObject->MajorFunction[IRP_MJ_READ] = NtfsFsdRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = NtfsFsdWrite;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = NtfsFsdQueryInformation;
DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = NtfsFsdDispatch;
DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = NtfsFsdDispatch;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = NtfsFsdDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = NtfsFsdFileSystemControl;
return;
}
/* EOF */

View file

@ -18,64 +18,60 @@
#include <pshpack1.h>
typedef struct _BIOS_PARAMETERS_BLOCK
{
USHORT BytesPerSector; // 0x0B
UCHAR SectorsPerCluster; // 0x0D
UCHAR Unused0[7]; // 0x0E, checked when volume is mounted
UCHAR MediaId; // 0x15
UCHAR Unused1[2]; // 0x16
USHORT SectorsPerTrack; // 0x18
USHORT Heads; // 0x1A
UCHAR Unused2[4]; // 0x1C
UCHAR Unused3[4]; // 0x20, checked when volume is mounted
USHORT BytesPerSector; // 0x0B
UCHAR SectorsPerCluster; // 0x0D
UCHAR Unused0[7]; // 0x0E, checked when volume is mounted
UCHAR MediaId; // 0x15
UCHAR Unused1[2]; // 0x16
USHORT SectorsPerTrack; // 0x18
USHORT Heads; // 0x1A
UCHAR Unused2[4]; // 0x1C
UCHAR Unused3[4]; // 0x20, checked when volume is mounted
} BIOS_PARAMETERS_BLOCK, *PBIOS_PARAMETERS_BLOCK;
typedef struct _EXTENDED_BIOS_PARAMETERS_BLOCK
{
USHORT Unknown[2]; // 0x24, always 80 00 80 00
ULONGLONG SectorCount; // 0x28
ULONGLONG MftLocation; // 0x30
ULONGLONG MftMirrLocation; // 0x38
CHAR ClustersPerMftRecord; // 0x40
UCHAR Unused4[3]; // 0x41
CHAR ClustersPerIndexRecord; // 0x44
UCHAR Unused5[3]; // 0x45
ULONGLONG SerialNumber; // 0x48
UCHAR Checksum[4]; // 0x50
USHORT Unknown[2]; // 0x24, always 80 00 80 00
ULONGLONG SectorCount; // 0x28
ULONGLONG MftLocation; // 0x30
ULONGLONG MftMirrLocation; // 0x38
CHAR ClustersPerMftRecord; // 0x40
UCHAR Unused4[3]; // 0x41
CHAR ClustersPerIndexRecord; // 0x44
UCHAR Unused5[3]; // 0x45
ULONGLONG SerialNumber; // 0x48
UCHAR Checksum[4]; // 0x50
} EXTENDED_BIOS_PARAMETERS_BLOCK, *PEXTENDED_BIOS_PARAMETERS_BLOCK;
typedef struct _BOOT_SECTOR
{
UCHAR Jump[3]; // 0x00
UCHAR OEMID[8]; // 0x03
BIOS_PARAMETERS_BLOCK BPB;
EXTENDED_BIOS_PARAMETERS_BLOCK EBPB;
UCHAR BootStrap[426]; // 0x54
USHORT EndSector; // 0x1FE
UCHAR Jump[3]; // 0x00
UCHAR OEMID[8]; // 0x03
BIOS_PARAMETERS_BLOCK BPB;
EXTENDED_BIOS_PARAMETERS_BLOCK EBPB;
UCHAR BootStrap[426]; // 0x54
USHORT EndSector; // 0x1FE
} BOOT_SECTOR, *PBOOT_SECTOR;
#include <poppack.h>
//typedef struct _BootSector BootSector;
typedef struct _NTFS_INFO
{
ULONG BytesPerSector;
ULONG SectorsPerCluster;
ULONG BytesPerCluster;
ULONGLONG SectorCount;
ULARGE_INTEGER MftStart;
ULARGE_INTEGER MftMirrStart;
ULONG BytesPerFileRecord;
ULONG BytesPerSector;
ULONG SectorsPerCluster;
ULONG BytesPerCluster;
ULONGLONG SectorCount;
ULARGE_INTEGER MftStart;
ULARGE_INTEGER MftMirrStart;
ULONG BytesPerFileRecord;
ULONGLONG SerialNumber;
USHORT VolumeLabelLength;
WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH];
UCHAR MajorVersion;
UCHAR MinorVersion;
USHORT Flags;
ULONGLONG SerialNumber;
USHORT VolumeLabelLength;
WCHAR VolumeLabel[MAXIMUM_VOLUME_LABEL_LENGTH];
UCHAR MajorVersion;
UCHAR MinorVersion;
USHORT Flags;
} NTFS_INFO, *PNTFS_INFO;
@ -87,27 +83,26 @@ typedef struct _NTFS_INFO
typedef struct
{
ULONG Type;
ULONG Size;
ULONG Type;
ULONG Size;
} NTFSIDENTIFIER, *PNTFSIDENTIFIER;
typedef struct
{
NTFSIDENTIFIER Identifier;
NTFSIDENTIFIER Identifier;
ERESOURCE DirResource;
// ERESOURCE FatResource;
ERESOURCE DirResource;
// ERESOURCE FatResource;
KSPIN_LOCK FcbListLock;
LIST_ENTRY FcbListHead;
KSPIN_LOCK FcbListLock;
LIST_ENTRY FcbListHead;
PVPB Vpb;
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT StreamFileObject;
NTFS_INFO NtfsInfo;
PVPB Vpb;
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT StreamFileObject;
NTFS_INFO NtfsInfo;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION, NTFS_VCB, *PNTFS_VCB;
@ -119,88 +114,87 @@ typedef struct
typedef struct _FCB
{
NTFSIDENTIFIER Identifier;
NTFSIDENTIFIER Identifier;
FSRTL_COMMON_FCB_HEADER RFCB;
SECTION_OBJECT_POINTERS SectionObjectPointers;
FSRTL_COMMON_FCB_HEADER RFCB;
SECTION_OBJECT_POINTERS SectionObjectPointers;
PFILE_OBJECT FileObject;
PNTFS_VCB Vcb;
PFILE_OBJECT FileObject;
PNTFS_VCB Vcb;
WCHAR *ObjectName; /* point on filename (250 chars max) in PathName */
WCHAR PathName[MAX_PATH]; /* path+filename 260 max */
WCHAR *ObjectName; /* point on filename (250 chars max) in PathName */
WCHAR PathName[MAX_PATH]; /* path+filename 260 max */
ERESOURCE PagingIoResource;
ERESOURCE MainResource;
ERESOURCE PagingIoResource;
ERESOURCE MainResource;
LIST_ENTRY FcbListEntry;
struct _FCB* ParentFcb;
LIST_ENTRY FcbListEntry;
struct _FCB* ParentFcb;
ULONG DirIndex;
ULONG DirIndex;
LONG RefCount;
ULONG Flags;
LONG RefCount;
ULONG Flags;
// DIR_RECORD Entry;
} NTFS_FCB, *PNTFS_FCB;
typedef struct
{
NTFSIDENTIFIER Identifier;
LIST_ENTRY NextCCB;
PFILE_OBJECT PtrFileObject;
LARGE_INTEGER CurrentByteOffset;
/* for DirectoryControl */
ULONG Entry;
/* for DirectoryControl */
PWCHAR DirectorySearchPattern;
ULONG LastCluster;
ULONG LastOffset;
NTFSIDENTIFIER Identifier;
LIST_ENTRY NextCCB;
PFILE_OBJECT PtrFileObject;
LARGE_INTEGER CurrentByteOffset;
/* for DirectoryControl */
ULONG Entry;
/* for DirectoryControl */
PWCHAR DirectorySearchPattern;
ULONG LastCluster;
ULONG LastOffset;
} NTFS_CCB, *PNTFS_CCB;
#define TAG_CCB 'BCCI'
typedef struct
{
NTFSIDENTIFIER Identifier;
ERESOURCE Resource;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
ULONG Flags;
NTFSIDENTIFIER Identifier;
ERESOURCE Resource;
PDRIVER_OBJECT DriverObject;
PDEVICE_OBJECT DeviceObject;
CACHE_MANAGER_CALLBACKS CacheMgrCallbacks;
ULONG Flags;
} NTFS_GLOBAL_DATA, *PNTFS_GLOBAL_DATA;
typedef enum
{
AttributeStandardInformation = 0x10,
AttributeAttributeList = 0x20,
AttributeFileName = 0x30,
AttributeObjectId = 0x40,
AttributeSecurityDescriptor = 0x50,
AttributeVolumeName = 0x60,
AttributeVolumeInformation = 0x70,
AttributeData = 0x80,
AttributeIndexRoot = 0x90,
AttributeIndexAllocation = 0xA0,
AttributeBitmap = 0xB0,
AttributeReparsePoint = 0xC0,
AttributeEAInformation = 0xD0,
AttributeEA = 0xE0,
AttributePropertySet = 0xF0,
AttributeLoggedUtilityStream = 0x100
AttributeStandardInformation = 0x10,
AttributeAttributeList = 0x20,
AttributeFileName = 0x30,
AttributeObjectId = 0x40,
AttributeSecurityDescriptor = 0x50,
AttributeVolumeName = 0x60,
AttributeVolumeInformation = 0x70,
AttributeData = 0x80,
AttributeIndexRoot = 0x90,
AttributeIndexAllocation = 0xA0,
AttributeBitmap = 0xB0,
AttributeReparsePoint = 0xC0,
AttributeEAInformation = 0xD0,
AttributeEA = 0xE0,
AttributePropertySet = 0xF0,
AttributeLoggedUtilityStream = 0x100
} ATTRIBUTE_TYPE, *PATTRIBUTE_TYPE;
typedef struct
{
ULONG Type; /* Magic number 'FILE' */
USHORT UsaOffset; /* Offset to the update sequence */
USHORT UsaCount; /* Size in words of Update Sequence Number & Array (S) */
ULONGLONG Lsn; /* $LogFile Sequence Number (LSN) */
ULONG Type; /* Magic number 'FILE' */
USHORT UsaOffset; /* Offset to the update sequence */
USHORT UsaCount; /* Size in words of Update Sequence Number & Array (S) */
ULONGLONG Lsn; /* $LogFile Sequence Number (LSN) */
} NTFS_RECORD_HEADER, *PNTFS_RECORD_HEADER;
/* NTFS_RECORD_HEADER.Type */
@ -209,17 +203,17 @@ typedef struct
typedef struct
{
NTFS_RECORD_HEADER Ntfs;
USHORT SequenceNumber; /* Sequence number */
USHORT LinkCount; /* Hard link count */
USHORT AttributeOffset; /* Offset to the first Attribute */
USHORT Flags; /* Flags */
ULONG BytesInUse; /* Real size of the FILE record */
ULONG BytesAllocated; /* Allocated size of the FILE record */
ULONGLONG BaseFileRecord; /* File reference to the base FILE record */
USHORT NextAttributeNumber; /* Next Attribute Id */
USHORT Pading; /* Align to 4 UCHAR boundary (XP) */
ULONG MFTRecordNumber; /* Number of this MFT Record (XP) */
NTFS_RECORD_HEADER Ntfs;
USHORT SequenceNumber; /* Sequence number */
USHORT LinkCount; /* Hard link count */
USHORT AttributeOffset; /* Offset to the first Attribute */
USHORT Flags; /* Flags */
ULONG BytesInUse; /* Real size of the FILE record */
ULONG BytesAllocated; /* Allocated size of the FILE record */
ULONGLONG BaseFileRecord; /* File reference to the base FILE record */
USHORT NextAttributeNumber; /* Next Attribute Id */
USHORT Pading; /* Align to 4 UCHAR boundary (XP) */
ULONG MFTRecordNumber; /* Number of this MFT Record (XP) */
} FILE_RECORD_HEADER, *PFILE_RECORD_HEADER;
/* Flags in FILE_RECORD_HEADER */
@ -231,106 +225,106 @@ typedef struct
typedef struct
{
ATTRIBUTE_TYPE AttributeType;
ULONG Length;
BOOLEAN Nonresident;
UCHAR NameLength;
USHORT NameOffset;
USHORT Flags;
USHORT AttributeNumber;
ATTRIBUTE_TYPE AttributeType;
ULONG Length;
BOOLEAN Nonresident;
UCHAR NameLength;
USHORT NameOffset;
USHORT Flags;
USHORT AttributeNumber;
} ATTRIBUTE, *PATTRIBUTE;
typedef struct
{
ATTRIBUTE Attribute;
ULONG ValueLength;
USHORT ValueOffset;
UCHAR Flags;
// UCHAR Padding0;
ATTRIBUTE Attribute;
ULONG ValueLength;
USHORT ValueOffset;
UCHAR Flags;
// UCHAR Padding0;
} RESIDENT_ATTRIBUTE, *PRESIDENT_ATTRIBUTE;
typedef struct
{
ATTRIBUTE Attribute;
ULONGLONG StartVcn; // LowVcn
ULONGLONG LastVcn; // HighVcn
USHORT RunArrayOffset;
USHORT CompressionUnit;
ULONG Padding0;
UCHAR IndexedFlag;
ULONGLONG AllocatedSize;
ULONGLONG DataSize;
ULONGLONG InitializedSize;
ULONGLONG CompressedSize;
ATTRIBUTE Attribute;
ULONGLONG StartVcn; // LowVcn
ULONGLONG LastVcn; // HighVcn
USHORT RunArrayOffset;
USHORT CompressionUnit;
ULONG Padding0;
UCHAR IndexedFlag;
ULONGLONG AllocatedSize;
ULONGLONG DataSize;
ULONGLONG InitializedSize;
ULONGLONG CompressedSize;
} NONRESIDENT_ATTRIBUTE, *PNONRESIDENT_ATTRIBUTE;
typedef struct
{
ULONGLONG CreationTime;
ULONGLONG ChangeTime;
ULONGLONG LastWriteTime;
ULONGLONG LastAccessTime;
ULONG FileAttribute;
ULONG AlignmentOrReserved[3];
ULONGLONG CreationTime;
ULONGLONG ChangeTime;
ULONGLONG LastWriteTime;
ULONGLONG LastAccessTime;
ULONG FileAttribute;
ULONG AlignmentOrReserved[3];
#if 0
ULONG QuotaId;
ULONG SecurityId;
ULONGLONG QuotaCharge;
USN Usn;
ULONG QuotaId;
ULONG SecurityId;
ULONGLONG QuotaCharge;
USN Usn;
#endif
} STANDARD_INFORMATION, *PSTANDARD_INFORMATION;
typedef struct
{
ATTRIBUTE_TYPE AttributeType;
USHORT Length;
UCHAR NameLength;
UCHAR NameOffset;
ULONGLONG StartVcn; // LowVcn
ULONGLONG FileReferenceNumber;
USHORT AttributeNumber;
USHORT AlignmentOrReserved[3];
ATTRIBUTE_TYPE AttributeType;
USHORT Length;
UCHAR NameLength;
UCHAR NameOffset;
ULONGLONG StartVcn; // LowVcn
ULONGLONG FileReferenceNumber;
USHORT AttributeNumber;
USHORT AlignmentOrReserved[3];
} ATTRIBUTE_LIST, *PATTRIBUTE_LIST;
typedef struct
{
ULONGLONG DirectoryFileReferenceNumber;
ULONGLONG CreationTime;
ULONGLONG ChangeTime;
ULONGLONG LastWriteTime;
ULONGLONG LastAccessTime;
ULONGLONG AllocatedSize;
ULONGLONG DataSize;
ULONG FileAttributes;
ULONG AlignmentOrReserved;
UCHAR NameLength;
UCHAR NameType;
WCHAR Name[1];
ULONGLONG DirectoryFileReferenceNumber;
ULONGLONG CreationTime;
ULONGLONG ChangeTime;
ULONGLONG LastWriteTime;
ULONGLONG LastAccessTime;
ULONGLONG AllocatedSize;
ULONGLONG DataSize;
ULONG FileAttributes;
ULONG AlignmentOrReserved;
UCHAR NameLength;
UCHAR NameType;
WCHAR Name[1];
} FILENAME_ATTRIBUTE, *PFILENAME_ATTRIBUTE;
typedef struct
{
ULONGLONG Unknown1;
UCHAR MajorVersion;
UCHAR MinorVersion;
USHORT Flags;
ULONG Unknown2;
ULONGLONG Unknown1;
UCHAR MajorVersion;
UCHAR MinorVersion;
USHORT Flags;
ULONG Unknown2;
} VOLINFO_ATTRIBUTE, *PVOLINFO_ATTRIBUTE;
typedef struct
{
NTFSIDENTIFIER Identifier;
ULONG Flags;
UCHAR MajorFunction;
UCHAR MinorFunction;
WORK_QUEUE_ITEM WorkQueueItem;
PIRP Irp;
BOOLEAN IsTopLevel;
PDEVICE_OBJECT DeviceObject;
NTSTATUS SavedExceptionCode;
NTFSIDENTIFIER Identifier;
ULONG Flags;
UCHAR MajorFunction;
UCHAR MinorFunction;
WORK_QUEUE_ITEM WorkQueueItem;
PIRP Irp;
BOOLEAN IsTopLevel;
PDEVICE_OBJECT DeviceObject;
NTSTATUS SavedExceptionCode;
} NTFS_IRP_CONTEXT, *PNTFS_IRP_CONTEXT;
@ -350,46 +344,49 @@ extern PNTFS_GLOBAL_DATA NtfsGlobalData;
//ULONG RunLength(PUCHAR run);
BOOLEAN
FindRun (PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
PULONGLONG lcn,
PULONGLONG count);
FindRun(PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
PULONGLONG lcn,
PULONGLONG count);
VOID
NtfsDumpFileAttributes (PFILE_RECORD_HEADER FileRecord);
NtfsDumpFileAttributes(PFILE_RECORD_HEADER FileRecord);
/* blockdev.c */
NTSTATUS
NtfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN ULONG SectorSize,
IN OUT PUCHAR Buffer,
IN BOOLEAN Override);
IN ULONG DiskSector,
IN ULONG SectorCount,
IN ULONG SectorSize,
IN OUT PUCHAR Buffer,
IN BOOLEAN Override);
NTSTATUS
NtfsDeviceIoControl(IN PDEVICE_OBJECT DeviceObject,
IN ULONG ControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer,
IN OUT PULONG OutputBufferSize,
IN BOOLEAN Override);
IN ULONG ControlCode,
IN PVOID InputBuffer,
IN ULONG InputBufferSize,
IN OUT PVOID OutputBuffer,
IN OUT PULONG OutputBufferSize,
IN BOOLEAN Override);
/* close.c */
DRIVER_DISPATCH NtfsFsdClose;
NTSTATUS NTAPI
NtfsFsdClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
PIRP Irp);
/* create.c */
DRIVER_DISPATCH NtfsFsdCreate;
NTSTATUS NTAPI
NtfsFsdCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
PIRP Irp);
/* dirctl.c */
@ -397,15 +394,19 @@ NtfsFsdCreate(PDEVICE_OBJECT DeviceObject,
DRIVER_DISPATCH NtfsFsdDirectoryControl;
NTSTATUS NTAPI
NtfsFsdDirectoryControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
PIRP Irp);
/* dispatch.c */
DRIVER_DISPATCH NtfsFsdDispatch;
NTSTATUS NTAPI
NtfsFsdDispatch(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
/* fastio.c */
BOOLEAN NTAPI
NtfsAcqLazyWrite(PVOID Context,
BOOLEAN Wait);
@ -420,10 +421,12 @@ NtfsAcqReadAhead(PVOID Context,
VOID NTAPI
NtfsRelReadAhead(PVOID Context);
/* fcb.c */
PNTFS_FCB
NtfsCreateFCB(PCWSTR FileName, PNTFS_VCB Vcb);
NtfsCreateFCB(PCWSTR FileName,
PNTFS_VCB Vcb);
VOID
NtfsDestroyFCB(PNTFS_FCB Fcb);
@ -436,23 +439,23 @@ NtfsFCBIsRoot(PNTFS_FCB Fcb);
VOID
NtfsGrabFCB(PNTFS_VCB Vcb,
PNTFS_FCB Fcb);
PNTFS_FCB Fcb);
VOID
NtfsReleaseFCB(PNTFS_VCB Vcb,
PNTFS_FCB Fcb);
PNTFS_FCB Fcb);
VOID
NtfsAddFCBToTable(PNTFS_VCB Vcb,
PNTFS_FCB Fcb);
PNTFS_FCB Fcb);
PNTFS_FCB
NtfsGrabFCBFromTable(PNTFS_VCB Vcb,
PCWSTR FileName);
PCWSTR FileName);
NTSTATUS
NtfsFCBInitializeCache(PNTFS_VCB Vcb,
PNTFS_FCB Fcb);
PNTFS_FCB Fcb);
PNTFS_FCB
NtfsMakeRootFCB(PNTFS_VCB Vcb);
@ -462,14 +465,14 @@ NtfsOpenRootFCB(PNTFS_VCB Vcb);
NTSTATUS
NtfsAttachFCBToFileObject(PNTFS_VCB Vcb,
PNTFS_FCB Fcb,
PFILE_OBJECT FileObject);
PNTFS_FCB Fcb,
PFILE_OBJECT FileObject);
NTSTATUS
NtfsGetFCBForFile(PNTFS_VCB Vcb,
PNTFS_FCB *pParentFCB,
PNTFS_FCB *pFCB,
const PWSTR pFileName);
PNTFS_FCB *pParentFCB,
PNTFS_FCB *pFCB,
const PWSTR pFileName);
/* finfo.c */
@ -477,7 +480,7 @@ NtfsGetFCBForFile(PNTFS_VCB Vcb,
DRIVER_DISPATCH NtfsFsdQueryInformation;
NTSTATUS NTAPI
NtfsFsdQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
PIRP Irp);
/* fsctl.c */
@ -485,69 +488,72 @@ NtfsFsdQueryInformation(PDEVICE_OBJECT DeviceObject,
DRIVER_DISPATCH NtfsFsdFileSystemControl;
NTSTATUS NTAPI
NtfsFsdFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
PIRP Irp);
/* mft.c */
NTSTATUS
NtfsOpenMft (PDEVICE_EXTENSION Vcb);
NtfsOpenMft(PDEVICE_EXTENSION Vcb);
VOID
ReadAttribute(PATTRIBUTE attr, PVOID buffer, PDEVICE_EXTENSION Vcb,
PDEVICE_OBJECT DeviceObject);
ReadAttribute(PATTRIBUTE attr,
PVOID buffer,
PDEVICE_EXTENSION Vcb,
PDEVICE_OBJECT DeviceObject);
ULONG
AttributeDataLength(PATTRIBUTE attr);
AttributeDataLength(PATTRIBUTE attr);
ULONG
AttributeAllocatedLength (PATTRIBUTE Attribute);
AttributeAllocatedLength(PATTRIBUTE Attribute);
NTSTATUS
ReadFileRecord (PDEVICE_EXTENSION Vcb,
ULONG index,
PFILE_RECORD_HEADER file,
PFILE_RECORD_HEADER Mft);
ReadFileRecord(PDEVICE_EXTENSION Vcb,
ULONG index,
PFILE_RECORD_HEADER file,
PFILE_RECORD_HEADER Mft);
PATTRIBUTE
FindAttribute(PFILE_RECORD_HEADER file,
ATTRIBUTE_TYPE type,
PWSTR name);
ATTRIBUTE_TYPE type,
PWSTR name);
ULONG
AttributeLengthAllocated(PATTRIBUTE attr);
VOID
ReadVCN (PDEVICE_EXTENSION Vcb,
PFILE_RECORD_HEADER file,
ATTRIBUTE_TYPE type,
ULONGLONG vcn,
ULONG count,
PVOID buffer);
VOID FixupUpdateSequenceArray(PFILE_RECORD_HEADER file);
ReadVCN(PDEVICE_EXTENSION Vcb,
PFILE_RECORD_HEADER file,
ATTRIBUTE_TYPE type,
ULONGLONG vcn,
ULONG count,
PVOID buffer);
VOID
ReadExternalAttribute (PDEVICE_EXTENSION Vcb,
PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
ULONG count,
PVOID buffer);
FixupUpdateSequenceArray(PFILE_RECORD_HEADER file);
VOID
ReadExternalAttribute(PDEVICE_EXTENSION Vcb,
PNONRESIDENT_ATTRIBUTE NresAttr,
ULONGLONG vcn,
ULONG count,
PVOID buffer);
NTSTATUS
ReadLCN (PDEVICE_EXTENSION Vcb,
ULONGLONG lcn,
ULONG count,
PVOID buffer);
ReadLCN(PDEVICE_EXTENSION Vcb,
ULONGLONG lcn,
ULONG count,
PVOID buffer);
VOID
EnumerAttribute(PFILE_RECORD_HEADER file,
PDEVICE_EXTENSION Vcb,
PDEVICE_OBJECT DeviceObject);
PDEVICE_EXTENSION Vcb,
PDEVICE_OBJECT DeviceObject);
/* misc.c */
BOOLEAN
NtfsIsIrpTopLevel(PIRP Irp);
@ -573,17 +579,18 @@ CdfsFileFlagsToAttributes(PFCB Fcb,
PULONG FileAttributes);
#endif
/* rw.c */
DRIVER_DISPATCH NtfsFsdRead;
NTSTATUS NTAPI
NtfsFsdRead(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
PIRP Irp);
DRIVER_DISPATCH NtfsFsdWrite;
NTSTATUS NTAPI
NtfsFsdWrite(PDEVICE_OBJECT DeviceObject,
PIRP Irp);
PIRP Irp);
/* volinfo.c */
@ -594,9 +601,13 @@ NtfsQueryVolumeInformation(PNTFS_IRP_CONTEXT IrpContext);
NTSTATUS
NtfsSetVolumeInformation(PNTFS_IRP_CONTEXT IrpContext);
/* ntfs.c */
DRIVER_INITIALIZE DriverEntry;
VOID NTAPI NtfsInitializeFunctionPointers(PDRIVER_OBJECT DriverObject);
VOID
NTAPI
NtfsInitializeFunctionPointers(PDRIVER_OBJECT DriverObject);
#endif /* NTFS_H */

View file

@ -19,7 +19,7 @@
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: drivers/filesystem/ntfs/rw.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PURPOSE: NTFS filesystem driver
* PROGRAMMER: Art Yerkes
* UPDATE HISTORY:
*/
@ -27,12 +27,11 @@
/* INCLUDES *****************************************************************/
#include <ntddk.h>
#include "ntfs.h"
#define NDEBUG
#include <debug.h>
#include "ntfs.h"
/* GLOBALS *******************************************************************/
@ -42,17 +41,18 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS
NtfsReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PUCHAR Buffer,
ULONG Length,
ULONG ReadOffset,
ULONG IrpFlags,
PULONG LengthRead)
/*
* FUNCTION: Reads data from a file
*/
static
NTSTATUS
NtfsReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PUCHAR Buffer,
ULONG Length,
ULONG ReadOffset,
ULONG IrpFlags,
PULONG LengthRead)
{
#if 0
NTSTATUS Status = STATUS_SUCCESS;
@ -123,73 +123,75 @@ NtfsReadFile(PDEVICE_EXTENSION DeviceExt,
return(Status);
#else
*LengthRead = 0;
return STATUS_END_OF_FILE;
*LengthRead = 0;
return STATUS_END_OF_FILE;
#endif
}
NTSTATUS NTAPI
NTSTATUS
NTAPI
NtfsFsdRead(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
PDEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PVOID Buffer;
ULONG ReadLength;
LARGE_INTEGER ReadOffset;
ULONG ReturnedReadLength = 0;
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_EXTENSION DeviceExt;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PVOID Buffer;
ULONG ReadLength;
LARGE_INTEGER ReadOffset;
ULONG ReturnedReadLength = 0;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtfsRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DPRINT("NtfsRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DeviceExt = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
DeviceExt = DeviceObject->DeviceExtension;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
ReadLength = Stack->Parameters.Read.Length;
ReadOffset = Stack->Parameters.Read.ByteOffset;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
ReadLength = Stack->Parameters.Read.Length;
ReadOffset = Stack->Parameters.Read.ByteOffset;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Status = NtfsReadFile(DeviceExt,
FileObject,
Buffer,
ReadLength,
ReadOffset.u.LowPart,
Irp->Flags,
&ReturnedReadLength);
if (NT_SUCCESS(Status))
Status = NtfsReadFile(DeviceExt,
FileObject,
Buffer,
ReadLength,
ReadOffset.u.LowPart,
Irp->Flags,
&ReturnedReadLength);
if (NT_SUCCESS(Status))
{
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
FileObject->CurrentByteOffset.QuadPart =
ReadOffset.QuadPart + ReturnedReadLength;
}
Irp->IoStatus.Information = ReturnedReadLength;
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
FileObject->CurrentByteOffset.QuadPart =
ReadOffset.QuadPart + ReturnedReadLength;
}
Irp->IoStatus.Information = ReturnedReadLength;
}
else
else
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Information = 0;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
return Status;
}
NTSTATUS NTAPI
NTSTATUS
NTAPI
NtfsFsdWrite(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
PIRP Irp)
{
DPRINT("NtfwWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
DPRINT("NtfwWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
return(STATUS_NOT_SUPPORTED);
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
return STATUS_NOT_SUPPORTED;
}
/* EOF */

View file

@ -32,216 +32,219 @@
/* FUNCTIONS ****************************************************************/
static NTSTATUS
static
NTSTATUS
NtfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
PULONG BufferLength)
{
DPRINT("NtfsGetFsVolumeInformation() called\n");
DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("NtfsGetFsVolumeInformation() called\n");
DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Vpb %p\n", DeviceObject->Vpb);
DPRINT("Vpb %p\n", DeviceObject->Vpb);
DPRINT("Required length %lu\n",
sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
DPRINT("LabelLength %hu\n",
DeviceObject->Vpb->VolumeLabelLength);
DPRINT("Label %*.S\n",
DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR),
DeviceObject->Vpb->VolumeLabel);
DPRINT("Required length %lu\n",
sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
DPRINT("LabelLength %hu\n",
DeviceObject->Vpb->VolumeLabelLength);
DPRINT("Label %*.S\n",
DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR),
DeviceObject->Vpb->VolumeLabel);
if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
return STATUS_INFO_LENGTH_MISMATCH;
if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
return STATUS_INFO_LENGTH_MISMATCH;
if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
return STATUS_BUFFER_OVERFLOW;
if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
return STATUS_BUFFER_OVERFLOW;
/* valid entries */
FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
memcpy(FsVolumeInfo->VolumeLabel,
DeviceObject->Vpb->VolumeLabel,
DeviceObject->Vpb->VolumeLabelLength);
/* valid entries */
FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
memcpy(FsVolumeInfo->VolumeLabel,
DeviceObject->Vpb->VolumeLabel,
DeviceObject->Vpb->VolumeLabelLength);
/* dummy entries */
FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
FsVolumeInfo->SupportsObjects = FALSE;
/* dummy entries */
FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
FsVolumeInfo->SupportsObjects = FALSE;
*BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
*BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("NtfsGetFsVolumeInformation() done\n");
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("NtfsGetFsVolumeInformation() done\n");
return STATUS_SUCCESS;
return STATUS_SUCCESS;
}
static NTSTATUS
static
NTSTATUS
NtfsGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
PULONG BufferLength)
{
DPRINT("NtfsGetFsAttributeInformation()\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
DPRINT("NtfsGetFsAttributeInformation()\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
return(STATUS_INFO_LENGTH_MISMATCH);
if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
return STATUS_INFO_LENGTH_MISMATCH;
if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
return STATUS_BUFFER_OVERFLOW;
FsAttributeInfo->FileSystemAttributes =
FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
FsAttributeInfo->MaximumComponentNameLength = 255;
FsAttributeInfo->FileSystemNameLength = 8;
FsAttributeInfo->FileSystemAttributes =
FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
FsAttributeInfo->MaximumComponentNameLength = 255;
FsAttributeInfo->FileSystemNameLength = 8;
memcpy(FsAttributeInfo->FileSystemName, L"NTFS", 8);
memcpy(FsAttributeInfo->FileSystemName, L"NTFS", 8);
DPRINT("Finished NtfsGetFsAttributeInformation()\n");
DPRINT("Finished NtfsGetFsAttributeInformation()\n");
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
DPRINT("BufferLength %lu\n", *BufferLength);
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
DPRINT("BufferLength %lu\n", *BufferLength);
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS
static
NTSTATUS
NtfsGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
PFILE_FS_SIZE_INFORMATION FsSizeInfo,
PULONG BufferLength)
{
PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status = STATUS_SUCCESS;
PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT("NtfsGetFsSizeInformation()\n");
DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
DPRINT("NtfsGetFsSizeInformation()\n");
DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
DeviceExt = DeviceObject->DeviceExtension;
DeviceExt = DeviceObject->DeviceExtension;
FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->NtfsInfo.SectorCount; /* ?? */
FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->NtfsInfo.SectorsPerCluster;
FsSizeInfo->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->NtfsInfo.SectorCount; /* ?? */
FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->NtfsInfo.SectorsPerCluster;
FsSizeInfo->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
DPRINT("Finished NtfsGetFsSizeInformation()\n");
if (NT_SUCCESS(Status))
*BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
DPRINT("Finished NtfsGetFsSizeInformation()\n");
if (NT_SUCCESS(Status))
*BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
return(Status);
return Status;
}
static NTSTATUS
static
NTSTATUS
NtfsGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
PULONG BufferLength)
{
DPRINT("NtfsGetFsDeviceInformation()\n");
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
DPRINT("NtfsGetFsDeviceInformation()\n");
DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
return STATUS_BUFFER_OVERFLOW;
FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
DPRINT("NtfsGetFsDeviceInformation() finished.\n");
DPRINT("NtfsGetFsDeviceInformation() finished.\n");
*BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
DPRINT("BufferLength %lu\n", *BufferLength);
*BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
DPRINT("BufferLength %lu\n", *BufferLength);
return(STATUS_SUCCESS);
return STATUS_SUCCESS;
}
NTSTATUS
NtfsQueryVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
{
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
FS_INFORMATION_CLASS FsInformationClass;
PIO_STACK_LOCATION Stack;
NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer;
ULONG BufferLength;
PIRP Irp;
PDEVICE_OBJECT DeviceObject;
FS_INFORMATION_CLASS FsInformationClass;
PIO_STACK_LOCATION Stack;
NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer;
ULONG BufferLength;
DPRINT("NtfsQueryVolumeInformation() called\n");
DPRINT("NtfsQueryVolumeInformation() called\n");
ASSERT(IrpContext);
ASSERT(IrpContext);
Irp = IrpContext->Irp;
DeviceObject = IrpContext->DeviceObject;
Stack = IoGetCurrentIrpStackLocation(Irp);
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
BufferLength = Stack->Parameters.QueryVolume.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
RtlZeroMemory(SystemBuffer, BufferLength);
Irp = IrpContext->Irp;
DeviceObject = IrpContext->DeviceObject;
Stack = IoGetCurrentIrpStackLocation(Irp);
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
BufferLength = Stack->Parameters.QueryVolume.Length;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
RtlZeroMemory(SystemBuffer, BufferLength);
DPRINT("FsInformationClass %d\n", FsInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
DPRINT("FsInformationClass %d\n", FsInformationClass);
DPRINT("SystemBuffer %p\n", SystemBuffer);
switch (FsInformationClass)
{
case FileFsVolumeInformation:
Status = NtfsGetFsVolumeInformation(DeviceObject,
SystemBuffer,
&BufferLength);
break;
switch (FsInformationClass)
{
case FileFsVolumeInformation:
Status = NtfsGetFsVolumeInformation(DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileFsAttributeInformation:
Status = NtfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
SystemBuffer,
&BufferLength);
break;
case FileFsAttributeInformation:
Status = NtfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
SystemBuffer,
&BufferLength);
break;
case FileFsSizeInformation:
Status = NtfsGetFsSizeInformation(DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileFsSizeInformation:
Status = NtfsGetFsSizeInformation(DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileFsDeviceInformation:
Status = NtfsGetFsDeviceInformation(SystemBuffer,
&BufferLength);
break;
case FileFsDeviceInformation:
Status = NtfsGetFsDeviceInformation(SystemBuffer,
&BufferLength);
break;
default:
Status = STATUS_NOT_SUPPORTED;
}
default:
Status = STATUS_NOT_SUPPORTED;
}
if (NT_SUCCESS(Status))
Irp->IoStatus.Information =
Stack->Parameters.QueryVolume.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
if (NT_SUCCESS(Status))
Irp->IoStatus.Information =
Stack->Parameters.QueryVolume.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
return Status;
return Status;
}
NTSTATUS
NtfsSetVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
{
PIRP Irp;
DPRINT("NtfsSetVolumeInformation() called\n");
PIRP Irp;
ASSERT(IrpContext);
DPRINT("NtfsSetVolumeInformation() called\n");
Irp = IrpContext->Irp;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
ASSERT(IrpContext);
return STATUS_NOT_SUPPORTED;
Irp = IrpContext->Irp;
Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
Irp->IoStatus.Information = 0;
return STATUS_NOT_SUPPORTED;
}
/* EOF */