mirror of
https://github.com/reactos/reactos.git
synced 2025-02-21 16:04:57 +00:00
[NTFS]
Fix indentation and coding style. No code changes!!! svn path=/trunk/; revision=59229
This commit is contained in:
parent
67115c45ed
commit
78a3d923b6
17 changed files with 2162 additions and 2065 deletions
|
@ -16,7 +16,7 @@ list(APPEND SOURCE
|
|||
rw.c
|
||||
volinfo.c
|
||||
ntfs.rc)
|
||||
|
||||
|
||||
add_library(ntfs SHARED ${SOURCE})
|
||||
|
||||
set_module_type(ntfs kernelmodedriver)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in a new issue