Reworked code for handling of asynchonous i/o requests.

svn path=/trunk/; revision=2346
This commit is contained in:
Hartmut Birr 2001-11-02 22:47:36 +00:00
parent 75bfca5f83
commit c2c9804f47
10 changed files with 725 additions and 402 deletions

View file

@ -1,4 +1,4 @@
/* $Id: cleanup.c,v 1.2 2001/03/08 22:06:02 dwelch Exp $ /* $Id: cleanup.c,v 1.3 2001/11/02 22:44:34 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -26,32 +26,36 @@ VfatCleanupFile(PDEVICE_EXTENSION DeviceExt,
*/ */
{ {
DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n", DPRINT("VfatCleanupFile(DeviceExt %x, FileObject %x)\n",
DeviceExt, FileObject); DeviceExt, FileObject);
/* FIXME: handle file/directory deletion here */ /* FIXME: handle file/directory deletion here */
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS STDCALL NTSTATUS VfatCleanup (PVFAT_IRP_CONTEXT IrpContext)
VfatCleanup (PDEVICE_OBJECT DeviceObject, PIRP Irp)
/* /*
* FUNCTION: Cleans up after a file has been closed. * FUNCTION: Cleans up after a file has been closed.
*/ */
{ {
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
DPRINT("VfatCleanup(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); DPRINT("VfatCleanup(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
Status = VfatCleanupFile(DeviceExtension, FileObject); if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
Irp->IoStatus.Status = Status; Status = VfatCleanupFile(IrpContext->DeviceExt, IrpContext->FileObject);
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT); ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return (Status); return (Status);
} }

View file

@ -1,4 +1,4 @@
/* $Id: close.c,v 1.8 2001/08/14 20:47:30 hbirr Exp $ /* $Id: close.c,v 1.9 2001/11/02 22:44:34 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -65,27 +65,28 @@ VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
return Status; return Status;
} }
NTSTATUS STDCALL NTSTATUS VfatClose (PVFAT_IRP_CONTEXT IrpContext)
VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp)
/* /*
* FUNCTION: Closes a file * FUNCTION: Closes a file
*/ */
{ {
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status; NTSTATUS Status;
DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); DPRINT ("VfatClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
ExAcquireResourceExclusiveLite (&DeviceExtension->DirResource, TRUE); if (!ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
Status = VfatCloseFile (DeviceExtension, FileObject); {
ExReleaseResourceLite (&DeviceExtension->DirResource); return VfatQueueRequest (IrpContext);
}
Irp->IoStatus.Status = Status; Status = VfatCloseFile (IrpContext->DeviceExt, IrpContext->FileObject);
Irp->IoStatus.Information = 0; ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
IrpContext->Irp->IoStatus.Status = Status;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return (Status); return (Status);
} }

View file

@ -1,4 +1,4 @@
/* $Id: create.c,v 1.33 2001/10/10 22:12:34 hbirr Exp $ /* $Id: create.c,v 1.34 2001/11/02 22:44:34 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -83,7 +83,7 @@ static void vfat8Dot3ToVolumeLabel (PCHAR pBasename, PCHAR pExtension, PWSTR pN
{ {
int fromIndex, toIndex; int fromIndex, toIndex;
fromIndex = toIndex = 0; fromIndex = toIndex = 0;
while (fromIndex < 8 && pBasename [fromIndex] != ' ') while (fromIndex < 8 && pBasename [fromIndex] != ' ')
{ {
pName [toIndex++] = pBasename [fromIndex++]; pName [toIndex++] = pBasename [fromIndex++];
@ -667,32 +667,32 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
* same name * same name
*/ */
if (RequestedDisposition == FILE_SUPERSEDE) if (RequestedDisposition == FILE_SUPERSEDE)
{ {
ULONG Cluster, NextCluster; ULONG Cluster, NextCluster;
/* FIXME set size to 0 and free clusters */ /* FIXME set size to 0 and free clusters */
pFcb->entry.FileSize = 0; pFcb->entry.FileSize = 0;
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
Cluster = pFcb->entry.FirstCluster Cluster = pFcb->entry.FirstCluster
+ pFcb->entry.FirstClusterHigh * 65536; + pFcb->entry.FirstClusterHigh * 65536;
else else
Cluster = pFcb->entry.FirstCluster; Cluster = pFcb->entry.FirstCluster;
pFcb->entry.FirstCluster = 0; pFcb->entry.FirstCluster = 0;
pFcb->entry.FirstClusterHigh = 0; pFcb->entry.FirstClusterHigh = 0;
updEntry (DeviceExt, FileObject); updEntry (DeviceExt, FileObject);
if ((ULONG)pFcb->RFCB.FileSize.QuadPart > 0) if ((ULONG)pFcb->RFCB.FileSize.QuadPart > 0)
{ {
pFcb->RFCB.AllocationSize.QuadPart = 0; pFcb->RFCB.AllocationSize.QuadPart = 0;
pFcb->RFCB.FileSize.QuadPart = 0; pFcb->RFCB.FileSize.QuadPart = 0;
pFcb->RFCB.ValidDataLength.QuadPart = 0; pFcb->RFCB.ValidDataLength.QuadPart = 0;
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize); CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&pFcb->RFCB.AllocationSize);
} }
while (Cluster != 0xffffffff && Cluster > 1) while (Cluster != 0xffffffff && Cluster > 1)
{ {
Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE); Status = GetNextCluster (DeviceExt, Cluster, &NextCluster, FALSE);
WriteCluster (DeviceExt, Cluster, 0); WriteCluster (DeviceExt, Cluster, 0);
Cluster = NextCluster; Cluster = NextCluster;
} }
} }
/* /*
* Check the file has the requested attributes * Check the file has the requested attributes
@ -707,7 +707,7 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
{ {
Status = STATUS_NOT_A_DIRECTORY; Status = STATUS_NOT_A_DIRECTORY;
} }
/* FIXME : test share access */ /* FIXME : test share access */
/* FIXME : test write access if requested */ /* FIXME : test write access if requested */
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
VfatCloseFile (DeviceExt, FileObject); VfatCloseFile (DeviceExt, FileObject);
@ -722,39 +722,37 @@ VfatCreateFile (PDEVICE_OBJECT DeviceObject, PIRP Irp)
} }
NTSTATUS STDCALL NTSTATUS VfatCreate (PVFAT_IRP_CONTEXT IrpContext)
VfatCreate (PDEVICE_OBJECT DeviceObject, PIRP Irp)
/* /*
* FUNCTION: Create or open a file * FUNCTION: Create or open a file
*/ */
{ {
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
assert (DeviceObject); assert (IrpContext);
assert (Irp);
if (DeviceObject->Size == sizeof (DEVICE_OBJECT)) if (IrpContext->DeviceObject->Size == sizeof (DEVICE_OBJECT))
{ {
/* DeviceObject represents FileSystem instead of logical volume */ /* DeviceObject represents FileSystem instead of logical volume */
DbgPrint ("FsdCreate called with file system\n"); DbgPrint ("FsdCreate called with file system\n");
Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Information = FILE_OPENED;
Irp->IoStatus.Information = FILE_OPENED; Status = STATUS_SUCCESS;
IoCompleteRequest (Irp, IO_NO_INCREMENT); goto ByeBye;
return (Status); }
}
DeviceExt = DeviceObject->DeviceExtension; if (!(IrpContext->Flags & IRPCONTEXT_CANWAIT))
assert (DeviceExt); {
ExAcquireResourceExclusiveLite (&DeviceExt->DirResource, TRUE); return VfatQueueRequest (IrpContext);
}
Status = VfatCreateFile (DeviceObject, Irp); ExAcquireResourceExclusiveLite (&IrpContext->DeviceExt->DirResource, TRUE);
Status = VfatCreateFile (IrpContext->DeviceObject, IrpContext->Irp);
ExReleaseResourceLite (&DeviceExt->DirResource); ExReleaseResourceLite (&IrpContext->DeviceExt->DirResource);
Irp->IoStatus.Status = Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
ByeBye:
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest (IrpContext->Irp, NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return Status; return Status;
} }

View file

@ -1,5 +1,5 @@
/* /*
* $Id: dir.c,v 1.20 2001/10/10 22:13:26 hbirr Exp $ * $Id: dir.c,v 1.21 2001/11/02 22:44:34 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -225,8 +225,7 @@ VfatGetFileBothInformation (PVFATFCB pFcb,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
{ {
NTSTATUS RC = STATUS_SUCCESS; NTSTATUS RC = STATUS_SUCCESS;
long BufferLength = 0; long BufferLength = 0;
@ -235,32 +234,35 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
unsigned long FileIndex = 0; unsigned long FileIndex = 0;
unsigned char *Buffer = NULL; unsigned char *Buffer = NULL;
PFILE_NAMES_INFORMATION Buffer0 = NULL; PFILE_NAMES_INFORMATION Buffer0 = NULL;
PFILE_OBJECT pFileObject = NULL;
PVFATFCB pFcb; PVFATFCB pFcb;
VFATFCB tmpFcb; VFATFCB tmpFcb;
PVFATCCB pCcb; PVFATCCB pCcb;
PDEVICE_EXTENSION DeviceExt;
WCHAR star[5], *pCharPattern; WCHAR star[5], *pCharPattern;
unsigned long OldEntry, OldSector; unsigned long OldEntry, OldSector;
DeviceExt = DeviceObject->DeviceExtension;
// Obtain the callers parameters pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2;
BufferLength = Stack->Parameters.QueryDirectory.Length;
pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
FileInformationClass =
Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
pFileObject = Stack->FileObject;
pCcb = (PVFATCCB) pFileObject->FsContext2;
pFcb = pCcb->pFcb; pFcb = pCcb->pFcb;
if (Stack->Flags & SL_RESTART_SCAN)
if (!ExAcquireResourceSharedLite(&pFcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return STATUS_PENDING;
}
// Obtain the callers parameters
BufferLength = IrpContext->Stack->Parameters.QueryDirectory.Length;
pSearchPattern = IrpContext->Stack->Parameters.QueryDirectory.FileName;
FileInformationClass =
IrpContext->Stack->Parameters.QueryDirectory.FileInformationClass;
FileIndex = IrpContext->Stack->Parameters.QueryDirectory.FileIndex;
if (IrpContext->Stack->Flags & SL_RESTART_SCAN)
{ //FIXME : what is really use of RestartScan ? { //FIXME : what is really use of RestartScan ?
pCcb->StartEntry = pCcb->StartSector = 0; pCcb->StartEntry = pCcb->StartSector = 0;
} }
// determine Buffer for result : // determine Buffer for result :
if (Irp->MdlAddress) if (IrpContext->Irp->MdlAddress)
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
else else
Buffer = Irp->UserBuffer; Buffer = IrpContext->Irp->UserBuffer;
DPRINT ("Buffer=%x tofind=%S\n", Buffer, pSearchPattern->Buffer); DPRINT ("Buffer=%x tofind=%S\n", Buffer, pSearchPattern->Buffer);
if (pSearchPattern == NULL) if (pSearchPattern == NULL)
{ {
@ -278,7 +280,7 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
if (OldSector) if (OldSector)
pCcb->StartEntry++; pCcb->StartEntry++;
RC = RC =
FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL); FindFile (IrpContext->DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartEntry, NULL);
pCcb->StartSector = 1; pCcb->StartSector = 1;
DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC, DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC,
pCcb->StartSector, pCcb->StartEntry); pCcb->StartSector, pCcb->StartEntry);
@ -294,19 +296,19 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
break; break;
case FileDirectoryInformation: case FileDirectoryInformation:
RC = RC =
VfatGetFileDirectoryInformation (&tmpFcb, DeviceExt, VfatGetFileDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
(PFILE_DIRECTORY_INFORMATION) (PFILE_DIRECTORY_INFORMATION)
Buffer, BufferLength); Buffer, BufferLength);
break; break;
case FileFullDirectoryInformation: case FileFullDirectoryInformation:
RC = RC =
VfatGetFileFullDirectoryInformation (&tmpFcb, DeviceExt, VfatGetFileFullDirectoryInformation (&tmpFcb, IrpContext->DeviceExt,
(PFILE_FULL_DIRECTORY_INFORMATION) (PFILE_FULL_DIRECTORY_INFORMATION)
Buffer, BufferLength); Buffer, BufferLength);
break; break;
case FileBothDirectoryInformation: case FileBothDirectoryInformation:
RC = RC =
VfatGetFileBothInformation (&tmpFcb, DeviceExt, VfatGetFileBothInformation (&tmpFcb, IrpContext->DeviceExt,
(PFILE_BOTH_DIRECTORY_INFORMATION) (PFILE_BOTH_DIRECTORY_INFORMATION)
Buffer, BufferLength); Buffer, BufferLength);
break; break;
@ -330,7 +332,7 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
} }
Buffer0 = (PFILE_NAMES_INFORMATION) Buffer; Buffer0 = (PFILE_NAMES_INFORMATION) Buffer;
Buffer0->FileIndex = FileIndex++; Buffer0->FileIndex = FileIndex++;
if (Stack->Flags & SL_RETURN_SINGLE_ENTRY) if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
break; break;
BufferLength -= Buffer0->NextEntryOffset; BufferLength -= Buffer0->NextEntryOffset;
Buffer += Buffer0->NextEntryOffset; Buffer += Buffer0->NextEntryOffset;
@ -338,27 +340,28 @@ DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
if (Buffer0) if (Buffer0)
Buffer0->NextEntryOffset = 0; Buffer0->NextEntryOffset = 0;
if (FileIndex > 0) if (FileIndex > 0)
return STATUS_SUCCESS; RC = STATUS_SUCCESS;
if (IrpContext->Flags & IRPCONTEXT_CANWAIT)
{
ExReleaseResourceLite(&pFcb->MainResource);
}
return RC; return RC;
} }
NTSTATUS STDCALL NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext)
VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
/* /*
* FUNCTION: directory control : read/write directory informations * FUNCTION: directory control : read/write directory informations
*/ */
{ {
NTSTATUS RC = STATUS_SUCCESS; NTSTATUS RC = STATUS_SUCCESS;
PFILE_OBJECT FileObject = NULL;
PIO_STACK_LOCATION Stack;
Stack = IoGetCurrentIrpStackLocation (Irp);
CHECKPOINT; CHECKPOINT;
FileObject = Stack->FileObject; switch (IrpContext->MinorFunction)
switch (Stack->MinorFunction)
{ {
case IRP_MN_QUERY_DIRECTORY: case IRP_MN_QUERY_DIRECTORY:
RC = DoQuery (DeviceObject, Irp, Stack); RC = DoQuery (IrpContext);
break; break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY: case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
DPRINT (" vfat, dir : change\n"); DPRINT (" vfat, dir : change\n");
@ -367,14 +370,21 @@ VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
default: default:
// error // error
DbgPrint ("unexpected minor function %x in VFAT driver\n", DbgPrint ("unexpected minor function %x in VFAT driver\n",
Stack->MinorFunction); IrpContext->MinorFunction);
RC = STATUS_INVALID_DEVICE_REQUEST; RC = STATUS_INVALID_DEVICE_REQUEST;
break; break;
} }
Irp->IoStatus.Status = RC; if (RC == STATUS_PENDING)
Irp->IoStatus.Information = 0; {
RC = VfatQueueRequest(IrpContext);
IoCompleteRequest (Irp, IO_NO_INCREMENT); }
else
{
IrpContext->Irp->IoStatus.Status = RC;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
}
return RC; return RC;
} }

View file

@ -1,4 +1,4 @@
/* $Id: finfo.c,v 1.10 2001/11/01 10:44:11 hbirr Exp $ /* $Id: finfo.c,v 1.11 2001/11/02 22:47:36 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -224,8 +224,8 @@ VfatGetNameInformation(PFILE_OBJECT FileObject,
static NTSTATUS static NTSTATUS
VfatGetInternalInformation(PVFATFCB Fcb, VfatGetInternalInformation(PVFATFCB Fcb,
PFILE_INTERNAL_INFORMATION InternalInfo, PFILE_INTERNAL_INFORMATION InternalInfo,
PULONG BufferLength) PULONG BufferLength)
{ {
assert (InternalInfo); assert (InternalInfo);
assert (Fcb); assert (Fcb);
@ -238,71 +238,72 @@ VfatGetInternalInformation(PVFATFCB Fcb,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS STDCALL
VfatQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp) NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
/* /*
* FUNCTION: Retrieve the specified file information * FUNCTION: Retrieve the specified file information
*/ */
{ {
PIO_STACK_LOCATION Stack;
FILE_INFORMATION_CLASS FileInformationClass; FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL; PVFATFCB FCB = NULL;
// PVFATCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS; NTSTATUS RC = STATUS_SUCCESS;
PVOID SystemBuffer; PVOID SystemBuffer;
ULONG BufferLength; ULONG BufferLength;
/* PRECONDITION */ /* PRECONDITION */
assert (DeviceObject != NULL); assert (IrpContext);
assert (Irp != NULL);
/* INITIALIZATION */ /* INITIALIZATION */
Stack = IoGetCurrentIrpStackLocation (Irp); FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass; FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
FileObject = Stack->FileObject;
// CCB = (PVFATCCB)(FileObject->FsContext2); SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
// FCB = CCB->Buffer; // Should be CCB->FCB??? BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
if (!ExAcquireResourceSharedLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
}
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = Stack->Parameters.QueryFile.Length;
switch (FileInformationClass) switch (FileInformationClass)
{ {
case FileStandardInformation: case FileStandardInformation:
RC = VfatGetStandardInformation(FCB, RC = VfatGetStandardInformation(FCB,
DeviceObject, IrpContext->DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FilePositionInformation: case FilePositionInformation:
RC = VfatGetPositionInformation(FileObject, RC = VfatGetPositionInformation(IrpContext->FileObject,
FCB, FCB,
DeviceObject, IrpContext->DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileBasicInformation: case FileBasicInformation:
RC = VfatGetBasicInformation(FileObject, RC = VfatGetBasicInformation(IrpContext->FileObject,
FCB, FCB,
DeviceObject, IrpContext->DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileNameInformation: case FileNameInformation:
RC = VfatGetNameInformation(FileObject, RC = VfatGetNameInformation(IrpContext->FileObject,
FCB, FCB,
DeviceObject, IrpContext->DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileInternalInformation: case FileInternalInformation:
RC = VfatGetInternalInformation(FCB, RC = VfatGetInternalInformation(FCB,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
case FileAlternateNameInformation: case FileAlternateNameInformation:
case FileAllInformation: case FileAllInformation:
@ -312,61 +313,72 @@ VfatQueryInformation(PDEVICE_OBJECT DeviceObject,
RC = STATUS_NOT_SUPPORTED; RC = STATUS_NOT_SUPPORTED;
} }
Irp->IoStatus.Status = RC; if (!(FCB->Flags & FCB_IS_PAGE_FILE))
{
ExReleaseResourceLite(&FCB->MainResource);
}
IrpContext->Irp->IoStatus.Status = RC;
if (NT_SUCCESS(RC)) if (NT_SUCCESS(RC))
Irp->IoStatus.Information = IrpContext->Irp->IoStatus.Information =
Stack->Parameters.QueryFile.Length - BufferLength; IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
else else
Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
IO_NO_INCREMENT); VfatFreeIrpContext(IrpContext);
return RC; return RC;
} }
NTSTATUS STDCALL NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
VfatSetInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/* /*
* FUNCTION: Retrieve the specified file information * FUNCTION: Retrieve the specified file information
*/ */
{ {
PIO_STACK_LOCATION Stack;
FILE_INFORMATION_CLASS FileInformationClass; FILE_INFORMATION_CLASS FileInformationClass;
PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL; PVFATFCB FCB = NULL;
// PVFATCCB CCB = NULL;
NTSTATUS RC = STATUS_SUCCESS; NTSTATUS RC = STATUS_SUCCESS;
PVOID SystemBuffer; PVOID SystemBuffer;
/* PRECONDITION */ /* PRECONDITION */
assert(DeviceObject != NULL); assert(IrpContext);
assert(Irp != NULL);
DPRINT("VfatSetInformation(DeviceObject %x, Irp %x)\n", DeviceObject, Irp); DPRINT("VfatSetInformation(IrpContext %x)\n", IrpContext);
/* INITIALIZATION */ /* INITIALIZATION */
Stack = IoGetCurrentIrpStackLocation (Irp); FileInformationClass = IrpContext->Stack->Parameters.SetFile.FileInformationClass;
FileInformationClass = Stack->Parameters.SetFile.FileInformationClass; FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
FileObject = Stack->FileObject; SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
DPRINT("FileInformationClass %d\n", FileInformationClass); DPRINT("FileInformationClass %d\n", FileInformationClass);
DPRINT("SystemBuffer %x\n", SystemBuffer); DPRINT("SystemBuffer %x\n", SystemBuffer);
if (FCB->Flags & FCB_IS_PAGE_FILE)
{
if (!ExAcquireResourceExclusiveLite(&FCB->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
}
else
{
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
}
switch (FileInformationClass) switch (FileInformationClass)
{ {
case FilePositionInformation: case FilePositionInformation:
RC = VfatSetPositionInformation(FileObject, RC = VfatSetPositionInformation(IrpContext->FileObject,
FCB, FCB,
DeviceObject, IrpContext->DeviceObject,
SystemBuffer); SystemBuffer);
break; break;
case FileDispositionInformation: case FileDispositionInformation:
RC = VfatSetDispositionInformation(FileObject, RC = VfatSetDispositionInformation(IrpContext->FileObject,
FCB, FCB,
DeviceObject, IrpContext->DeviceObject,
SystemBuffer); SystemBuffer);
break; break;
case FileBasicInformation: case FileBasicInformation:
@ -379,10 +391,19 @@ VfatSetInformation(PDEVICE_OBJECT DeviceObject,
RC = STATUS_NOT_SUPPORTED; RC = STATUS_NOT_SUPPORTED;
} }
Irp->IoStatus.Status = RC; if (FCB->Flags & FCB_IS_PAGE_FILE)
Irp->IoStatus.Information = 0; {
IoCompleteRequest(Irp, ExReleaseResourceLite(&FCB->PagingIoResource);
IO_NO_INCREMENT); }
else
{
ExReleaseResourceLite(&FCB->MainResource);
}
IrpContext->Irp->IoStatus.Status = RC;
IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return RC; return RC;
} }

View file

@ -1,4 +1,4 @@
/* $Id: iface.c,v 1.58 2001/10/10 22:18:58 hbirr Exp $ /* $Id: iface.c,v 1.59 2001/11/02 22:47:36 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -61,7 +61,7 @@ VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
return(Status); return(Status);
} }
DPRINT("Boot->SysType %.5s\n", Boot->SysType); DPRINT1("Boot->SysType %.5s\n", Boot->SysType);
if (strncmp(Boot->SysType, "FAT12", 5) == 0 || if (strncmp(Boot->SysType, "FAT12", 5) == 0 ||
strncmp(Boot->SysType, "FAT16", 5) == 0 || strncmp(Boot->SysType, "FAT16", 5) == 0 ||
strncmp(((struct _BootSector32 *) (Boot))->SysType, "FAT32", 5) == 0) strncmp(((struct _BootSector32 *) (Boot))->SysType, "FAT32", 5) == 0)
@ -153,29 +153,41 @@ VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
static NTSTATUS static NTSTATUS
VfatMount (PDEVICE_OBJECT DeviceToMount) VfatMount (PVFAT_IRP_CONTEXT IrpContext)
/* /*
* FUNCTION: Mount the filesystem * FUNCTION: Mount the filesystem
*/ */
{ {
PDEVICE_OBJECT DeviceObject; PDEVICE_OBJECT DeviceObject = NULL;
PDEVICE_EXTENSION DeviceExt; PDEVICE_EXTENSION DeviceExt = NULL;
BOOLEAN RecognizedFS; BOOLEAN RecognizedFS;
NTSTATUS Status; NTSTATUS Status;
PVFATFCB Fcb; PVFATFCB Fcb = NULL;
PVFATCCB Ccb; PVFATCCB Ccb = NULL;
Status = VfatHasFileSystem (DeviceToMount, &RecognizedFS); DPRINT1("VfatMount(IrpContext %x)\n", IrpContext);
assert (IrpContext);
if (IrpContext->DeviceObject != VfatDriverObject->DeviceObject)
{
// Only allowed on the main device object
Status = STATUS_INVALID_DEVICE_REQUEST;
goto ByeBye;
}
Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); goto ByeBye;
} }
if (RecognizedFS == FALSE) if (RecognizedFS == FALSE)
{ {
DPRINT("VFAT: Unrecognized Volume\n"); DPRINT("VFAT: Unrecognized Volume\n");
return(STATUS_UNRECOGNIZED_VOLUME); Status = STATUS_UNRECOGNIZED_VOLUME;
} goto ByeBye;
}
DPRINT("VFAT: Recognized volume\n"); DPRINT("VFAT: Recognized volume\n");
@ -187,21 +199,22 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
FALSE, FALSE,
&DeviceObject); &DeviceObject);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
return(Status); goto ByeBye;
} }
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO; DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
DeviceExt = (PVOID) DeviceObject->DeviceExtension; DeviceExt = (PVOID) DeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION));
/* use same vpb as device disk */ /* use same vpb as device disk */
DeviceObject->Vpb = DeviceToMount->Vpb; DeviceObject->Vpb = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
Status = VfatMountDevice(DeviceExt, Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
DeviceToMount);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
/* FIXME: delete device object */ /* FIXME: delete device object */
return(Status); goto ByeBye;
} }
#if 1 #if 1
DbgPrint("BytesPerSector: %d\n", DeviceExt->Boot->BytesPerSector); DbgPrint("BytesPerSector: %d\n", DeviceExt->Boot->BytesPerSector);
@ -230,24 +243,26 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
} }
#endif #endif
DeviceObject->Vpb->Flags |= VPB_MOUNTED; DeviceObject->Vpb->Flags |= VPB_MOUNTED;
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
DeviceToMount);
DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice); DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
Fcb = vfatNewFCB(NULL); Fcb = vfatNewFCB(NULL);
if (Fcb == NULL) if (Fcb == NULL)
{ {
return STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
} }
Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB); Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
if (Ccb == NULL) if (Ccb == NULL)
{ {
return STATUS_INSUFFICIENT_RESOURCES; Status = STATUS_INSUFFICIENT_RESOURCES;
goto ByeBye;
} }
memset(Ccb, 0, sizeof (VFATCCB)); memset(Ccb, 0, sizeof (VFATCCB));
DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ; DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB; DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB;
DeviceExt->FATFileObject->FsContext2 = Ccb; DeviceExt->FATFileObject->FsContext2 = Ccb;
DeviceExt->FATFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
Ccb->pFcb = Fcb; Ccb->pFcb = Fcb;
Ccb->PtrFileObject = DeviceExt->FATFileObject; Ccb->PtrFileObject = DeviceExt->FATFileObject;
Fcb->FileObject = DeviceExt->FATFileObject; Fcb->FileObject = DeviceExt->FATFileObject;
@ -255,6 +270,16 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
Fcb->Flags = FCB_IS_FAT; Fcb->Flags = FCB_IS_FAT;
if (DeviceExt->Boot->Sectors != 0)
{
DeviceExt->NumberOfClusters = (DeviceExt->Boot->Sectors - DeviceExt->dataStart)
/ DeviceExt->Boot->SectorsPerCluster + 2;
}
else
{
DeviceExt->NumberOfClusters = (DeviceExt->Boot->SectorsHuge - DeviceExt->dataStart)
/ DeviceExt->Boot->SectorsPerCluster + 2;
}
if (DeviceExt->FatType == FAT32) if (DeviceExt->FatType == FAT32)
{ {
Fcb->RFCB.FileSize.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE; Fcb->RFCB.FileSize.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
@ -282,12 +307,10 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
if (!NT_SUCCESS (Status)) if (!NT_SUCCESS (Status))
{ {
DbgPrint ("CcRosInitializeFileCache failed\n"); DbgPrint ("CcRosInitializeFileCache failed\n");
// KeBugCheck (0); goto ByeBye;
// FIXME: delete device object
return(Status);
} }
DeviceExt->LastAvailableCluster = 0;
ExInitializeResourceLite(&DeviceExt->DirResource); ExInitializeResourceLite(&DeviceExt->DirResource);
ExInitializeResourceLite(&DeviceExt->FatResource); ExInitializeResourceLite(&DeviceExt->FatResource);
@ -304,22 +327,39 @@ VfatMount (PDEVICE_OBJECT DeviceToMount)
/* read volume label */ /* read volume label */
ReadVolumeLabel(DeviceExt, DeviceObject->Vpb); ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
Status = STATUS_SUCCESS;
return(STATUS_SUCCESS); ByeBye:
if (!NT_SUCCESS(Status))
{
// cleanup
if (DeviceExt && DeviceExt->FATFileObject)
ObDereferenceObject (DeviceExt->FATFileObject);
if (Fcb)
ExFreePool(Fcb);
if (Ccb)
ExFreePool(Ccb);
if (DeviceObject)
IoDeleteDevice(DeviceObject);
}
return Status;
} }
NTSTATUS STDCALL NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
VfatFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/* /*
* FUNCTION: File system control * FUNCTION: File system control
*/ */
{ {
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
NTSTATUS Status; NTSTATUS Status;
switch (Stack->MinorFunction) DPRINT1("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
assert (IrpContext);
switch (IrpContext->MinorFunction)
{ {
case IRP_MN_USER_FS_REQUEST: case IRP_MN_USER_FS_REQUEST:
DPRINT1("VFAT FSC: IRP_MN_USER_FS_REQUEST\n"); DPRINT1("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
@ -327,7 +367,7 @@ VfatFileSystemControl(PDEVICE_OBJECT DeviceObject,
break; break;
case IRP_MN_MOUNT_VOLUME: case IRP_MN_MOUNT_VOLUME:
Status = VfatMount(Stack->Parameters.Mount.DeviceObject); Status = VfatMount(IrpContext);
break; break;
case IRP_MN_VERIFY_VOLUME: case IRP_MN_VERIFY_VOLUME:
@ -336,15 +376,15 @@ VfatFileSystemControl(PDEVICE_OBJECT DeviceObject,
break; break;
default: default:
DPRINT1("VFAT FSC: MinorFunction %d\n", Stack->MinorFunction); DPRINT1("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction);
Status = STATUS_INVALID_DEVICE_REQUEST; Status = STATUS_INVALID_DEVICE_REQUEST;
break; break;
} }
Irp->IoStatus.Status = Status; IrpContext->Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT); IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
return (Status); return (Status);
} }
@ -383,24 +423,24 @@ DriverEntry(PDRIVER_OBJECT _DriverObject,
} }
DeviceObject->Flags = DO_DIRECT_IO; DeviceObject->Flags = DO_DIRECT_IO;
VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatClose; VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatCreate; VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatRead; VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatWrite; VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
VfatFileSystemControl; VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
VfatQueryInformation; VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
VfatSetInformation; VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
VfatDirectoryControl; VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
VfatQueryVolumeInformation; VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = VfatDriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
VfatSetVolumeInformation; VfatBuildRequest;
VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown; VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatCleanup; VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
VfatDriverObject->DriverUnload = NULL; VfatDriverObject->DriverUnload = NULL;

View file

@ -1,4 +1,4 @@
# $Id: makefile,v 1.35 2001/08/21 20:13:13 chorns Exp $ # $Id: makefile,v 1.36 2001/11/02 22:47:36 hbirr Exp $
PATH_TO_TOP = ../../.. PATH_TO_TOP = ../../..
@ -21,8 +21,14 @@ TARGET_OBJECTS = \
rw.o \ rw.o \
shutdown.o \ shutdown.o \
string.o \ string.o \
volume.o volume.o \
misc.o
DEP_OBJECTS = $(TARGET_OBJECTS)
include $(PATH_TO_TOP)/rules.mak include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk include $(TOOLS_PATH)/helper.mk
include $(TOOLS_PATH)/depend.mk

View file

@ -0,0 +1,209 @@
/* $Id: misc.c,v 1.1 2001/11/02 22:44:34 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/vfat/misc.c
* PURPOSE: VFAT Filesystem
* PROGRAMMER: Hartmut Birr
*
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <wchar.h>
#define NDEBUG
#include <debug.h>
#include "vfat.h"
/* FUNCTIONS ****************************************************************/
static LONG QueueCount = 0;
NTSTATUS VfatDispatchRequest (
IN PVFAT_IRP_CONTEXT IrpContext)
{
DPRINT ("VfatDispatchRequest (IrpContext %x), MajorFunction %x\n", IrpContext, IrpContext->MajorFunction);
assert (IrpContext);
switch (IrpContext->MajorFunction)
{
case IRP_MJ_CLOSE:
return VfatClose (IrpContext);
case IRP_MJ_CREATE:
return VfatCreate (IrpContext);
case IRP_MJ_READ:
return VfatRead (IrpContext);
case IRP_MJ_WRITE:
return VfatWrite (IrpContext);
case IRP_MJ_FILE_SYSTEM_CONTROL:
return VfatFileSystemControl(IrpContext);
case IRP_MJ_QUERY_INFORMATION:
return VfatQueryInformation (IrpContext);
case IRP_MJ_SET_INFORMATION:
return VfatSetInformation (IrpContext);
case IRP_MJ_DIRECTORY_CONTROL:
return VfatDirectoryControl(IrpContext);
case IRP_MJ_QUERY_VOLUME_INFORMATION:
return VfatQueryVolumeInformation(IrpContext);
case IRP_MJ_SET_VOLUME_INFORMATION:
return VfatSetVolumeInformation(IrpContext);
case IRP_MJ_CLEANUP:
return VfatCleanup(IrpContext);
default:
DPRINT1 ("Unexpected major function %x\n", IrpContext->MajorFunction);
IrpContext->Irp->IoStatus.Status = STATUS_DRIVER_INTERNAL_ERROR;
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return STATUS_DRIVER_INTERNAL_ERROR;
}
}
NTSTATUS STDCALL VfatBuildRequest (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
NTSTATUS Status;
PVFAT_IRP_CONTEXT IrpContext;
DPRINT ("VfatBuildRequest (DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
assert (DeviceObject);
assert (Irp);
FsRtlEnterFileSystem();
IrpContext = VfatAllocateIrpContext(DeviceObject, Irp);
if (IrpContext == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
Irp->IoStatus.Status = Status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
}
else
{
Status = VfatDispatchRequest (IrpContext);
}
FsRtlExitFileSystem();
return Status;
}
VOID VfatFreeIrpContext (PVFAT_IRP_CONTEXT IrpContext)
{
assert (IrpContext);
ExFreePool(IrpContext);
}
// Copyed from ntoskrnl\io\irp.c and changed access to FileObject
BOOLEAN
STDCALL
VfatIoIsOperationSynchronous (
IN PIRP Irp
)
{
ULONG Flags = 0;
PFILE_OBJECT FileObject = NULL;
PIO_STACK_LOCATION Stack;
/*
* Check the associated FILE_OBJECT's
* flags first.
*/
// FileObject = Irp->Tail.Overlay.OriginalFileObject;
Stack = IoGetCurrentIrpStackLocation(Irp);
FileObject = Stack->FileObject;
assert (FileObject);
if (!(FO_SYNCHRONOUS_IO & FileObject->Flags))
{
/* Check IRP's flags. */
Flags = Irp->Flags;
if (!( (IRP_SYNCHRONOUS_API | IRP_SYNCHRONOUS_PAGING_IO)
& Flags
))
{
return FALSE;
}
}
/*
* Check more IRP's flags.
*/
Flags = Irp->Flags;
if ( !(IRP_MOUNT_COMPLETION & Flags)
|| (IRP_SYNCHRONOUS_PAGING_IO & Flags)
)
{
return TRUE;
}
/*
* Otherwise, it is an
* asynchronous operation.
*/
return FALSE;
}
PVFAT_IRP_CONTEXT VfatAllocateIrpContext(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
PVFAT_IRP_CONTEXT IrpContext;
PIO_STACK_LOCATION Stack;
UCHAR MajorFunction;
DPRINT ("VfatAllocateIrpContext(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
assert (DeviceObject);
assert (Irp);
IrpContext = ExAllocatePool (NonPagedPool, sizeof(VFAT_IRP_CONTEXT));
if (IrpContext)
{
RtlZeroMemory(IrpContext, sizeof(IrpContext));
IrpContext->Irp = Irp;
IrpContext->DeviceObject = DeviceObject;
IrpContext->DeviceExt = DeviceObject->DeviceExtension;
IrpContext->Stack = IoGetCurrentIrpStackLocation(Irp);
assert (IrpContext->Stack);
MajorFunction = IrpContext->MajorFunction = IrpContext->Stack->MajorFunction;
IrpContext->MinorFunction = IrpContext->Stack->MinorFunction;
IrpContext->FileObject = IrpContext->Stack->FileObject;
if (MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL ||
MajorFunction == IRP_MJ_DEVICE_CONTROL ||
MajorFunction == IRP_MJ_SHUTDOWN)
{
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
}
else if (MajorFunction != IRP_MJ_CLEANUP &&
MajorFunction != IRP_MJ_CLOSE &&
VfatIoIsOperationSynchronous(Irp))
{
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
}
}
return IrpContext;
}
VOID STDCALL VfatDoRequest (PVOID IrpContext)
{
ULONG Count = InterlockedDecrement(&QueueCount);
DPRINT ("VfatDoRequest (IrpContext %x), MajorFunction %x, %d\n", IrpContext, ((PVFAT_IRP_CONTEXT)IrpContext)->MajorFunction, Count);
VfatDispatchRequest((PVFAT_IRP_CONTEXT)IrpContext);
}
NTSTATUS VfatQueueRequest(PVFAT_IRP_CONTEXT IrpContext)
{
ULONG Count = InterlockedIncrement(&QueueCount);
DPRINT ("VfatQueueRequest (IrpContext %x), %d\n", IrpContext, Count);
assert (IrpContext != NULL);
assert (IrpContext->Irp != NULL);
IrpContext->Flags |= IRPCONTEXT_CANWAIT;
IoMarkIrpPending (IrpContext->Irp);
ExInitializeWorkItem (&IrpContext->WorkQueueItem, VfatDoRequest, IrpContext);
ExQueueWorkItem(&IrpContext->WorkQueueItem, CriticalWorkQueue);
return STATUS_PENDING;
}

View file

@ -1,5 +1,5 @@
/* $Id: rw.c,v 1.33 2001/10/11 15:39:51 hbirr Exp $ /* $Id: rw.c,v 1.34 2001/11/02 22:47:36 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -419,7 +419,7 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
// Is this a write to the FAT ? // Is this a write to the FAT ?
if (Fcb->Flags & FCB_IS_FAT) if (Fcb->Flags & FCB_IS_FAT)
{ {
if (!NoCache) if (!NoCache && !PageIo)
{ {
DbgPrint ("Cached FAT write outside from VFATFS.SYS\n"); DbgPrint ("Cached FAT write outside from VFATFS.SYS\n");
KeBugCheck (0); KeBugCheck (0);
@ -604,119 +604,6 @@ VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
return Status; return Status;
} }
NTSTATUS STDCALL
VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Write to a file
*/
{
ULONG Length;
PVOID Buffer;
ULONG Offset;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
NTSTATUS Status;
ULONG NoCache;
DPRINT ("VfatWrite(DeviceObject %x Irp %x)\n", DeviceObject, Irp);
Length = Stack->Parameters.Write.Length;
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
if (Irp->Flags & IRP_PAGING_IO ||
FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
{
NoCache = TRUE;
}
else
{
NoCache = FALSE;
}
Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset,
NoCache, Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
if (!(Irp->Flags & IRP_PAGING_IO) && NT_SUCCESS(Status))
{
FileObject->CurrentByteOffset.QuadPart = Offset + Length;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return (Status);
}
NTSTATUS STDCALL
VfatRead (PDEVICE_OBJECT DeviceObject, PIRP Irp)
/*
* FUNCTION: Read from a file
*/
{
ULONG Length;
PVOID Buffer;
ULONG Offset;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PDEVICE_EXTENSION DeviceExt;
NTSTATUS Status;
ULONG LengthRead;
PVFATFCB Fcb;
ULONG NoCache;
DPRINT ("VfatRead(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
/* Precondition / Initialization */
assert (Irp != NULL);
Stack = IoGetCurrentIrpStackLocation (Irp);
assert (Stack != NULL);
FileObject = Stack->FileObject;
assert (FileObject != NULL);
DeviceExt = DeviceObject->DeviceExtension;
assert (DeviceExt != NULL);
Length = Stack->Parameters.Read.Length;
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
if (Irp->Flags & IRP_PAGING_IO ||
FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING)
{
NoCache = TRUE;
}
else
{
NoCache = FALSE;
}
Fcb = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
/* fail if file is a directory and no paged read */
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(Irp->Flags & IRP_PAGING_IO))
{
Status = STATUS_FILE_IS_A_DIRECTORY;
}
else
{
Status = VfatReadFile (DeviceExt, FileObject, Buffer, Length,
Offset, &LengthRead, NoCache);
}
if (!(Irp->Flags & IRP_PAGING_IO))
{
// update the file pointer
FileObject->CurrentByteOffset.QuadPart = Offset + LengthRead;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = LengthRead;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return (Status);
}
NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize) NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject, ULONG NewSize)
{ {
ULONG FirstCluster; ULONG FirstCluster;
@ -833,3 +720,159 @@ NTSTATUS vfatExtendSpace (PDEVICE_EXTENSION pDeviceExt, PFILE_OBJECT pFileObject
} }
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS VfatRead(PVFAT_IRP_CONTEXT IrpContext)
{
PVFATFCB Fcb;
PVFATCCB Ccb;
NTSTATUS Status = STATUS_SUCCESS;
ULONG ReadLength;
ULONG ReturnedReadLength = 0;
LARGE_INTEGER ReadOffset;
PVOID Buffer;
DPRINT ("VfatRead(IrpContext %x)\n", IrpContext);
assert (IrpContext);
Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2;
assert (Ccb);
Fcb = Ccb->pFcb;
assert (Fcb);
if (IrpContext->Irp->Flags & IRP_PAGING_IO)
{
if (!ExAcquireResourceSharedLite(&Fcb->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
}
else
{
if (!ExAcquireResourceSharedLite(&Fcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
}
ReadLength = IrpContext->Stack->Parameters.Read.Length;
ReadOffset = IrpContext->Stack->Parameters.Read.ByteOffset;
Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
/* fail if file is a directory and no paged read */
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
{
Status = STATUS_FILE_IS_A_DIRECTORY;
}
else
{
Status = VfatReadFile (IrpContext->DeviceExt, IrpContext->FileObject,
Buffer, ReadLength, ReadOffset.u.LowPart, &ReturnedReadLength,
IrpContext->FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING
|| IrpContext->Irp->Flags & IRP_PAGING_IO);
}
if (IrpContext->Irp->Flags & IRP_PAGING_IO)
{
ExReleaseResourceLite(&Fcb->PagingIoResource);
}
else
{
ExReleaseResourceLite(&Fcb->MainResource);
}
if (NT_SUCCESS(Status))
{
if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
{
IrpContext->FileObject->CurrentByteOffset.QuadPart = ReadOffset.QuadPart + ReturnedReadLength;
}
IrpContext->Irp->IoStatus.Information = ReturnedReadLength;
}
else
{
IrpContext->Irp->IoStatus.Information = 0;
}
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext (IrpContext);
return Status;
}
NTSTATUS VfatWrite(PVFAT_IRP_CONTEXT IrpContext)
{
PVFATFCB Fcb;
PVFATCCB Ccb;
NTSTATUS Status = STATUS_SUCCESS;
ULONG WriteLength;
LARGE_INTEGER WriteOffset;
PVOID Buffer;
DPRINT ("VfatWrite(), %S\n", ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb->FileName);
assert (IrpContext);
Ccb = (PVFATCCB) IrpContext->FileObject->FsContext2;
assert (Ccb);
Fcb = Ccb->pFcb;
assert (Fcb);
if (IrpContext->Irp->Flags & IRP_PAGING_IO)
{
if (!ExAcquireResourceExclusiveLite(&Fcb->PagingIoResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
}
else
{
if (!ExAcquireResourceExclusiveLite(&Fcb->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
}
WriteLength = IrpContext->Stack->Parameters.Write.Length;
WriteOffset = IrpContext->Stack->Parameters.Write.ByteOffset;
Buffer = MmGetSystemAddressForMdl (IrpContext->Irp->MdlAddress);
/* fail if file is a directory and no paged read */
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
{
Status = STATUS_FILE_IS_A_DIRECTORY;
}
else
{
Status = VfatWriteFile (IrpContext->DeviceExt, IrpContext->FileObject,
Buffer, WriteLength, WriteOffset.u.LowPart,
IrpContext->FileObject->Flags & FO_NO_INTERMEDIATE_BUFFERING,
IrpContext->Irp->Flags & IRP_PAGING_IO);
}
if (IrpContext->Irp->Flags & IRP_PAGING_IO)
{
ExReleaseResourceLite(&Fcb->PagingIoResource);
}
else
{
ExReleaseResourceLite(&Fcb->MainResource);
}
if (NT_SUCCESS(Status))
{
if (IrpContext->FileObject->Flags & FO_SYNCHRONOUS_IO && !(IrpContext->Irp->Flags & IRP_PAGING_IO))
{
IrpContext->FileObject->CurrentByteOffset.QuadPart = WriteOffset.QuadPart + WriteLength;
}
IrpContext->Irp->IoStatus.Information = WriteLength;
}
else
{
IrpContext->Irp->IoStatus.Information = 0;
}
IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext (IrpContext);
return Status;
}

View file

@ -1,4 +1,4 @@
/* $Id: volume.c,v 1.13 2001/11/01 10:41:53 hbirr Exp $ /* $Id: volume.c,v 1.14 2001/11/02 22:47:36 hbirr Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -20,9 +20,7 @@
/* FUNCTIONS ****************************************************************/ /* FUNCTIONS ****************************************************************/
static NTSTATUS static NTSTATUS
FsdGetFsVolumeInformation(PFILE_OBJECT FileObject, FsdGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
PVFATFCB FCB,
PDEVICE_OBJECT DeviceObject,
PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
PULONG BufferLength) PULONG BufferLength)
{ {
@ -38,12 +36,15 @@ FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
DPRINT("LabelLength %lu\n", LabelLength); DPRINT("LabelLength %lu\n", LabelLength);
DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel); DPRINT("Label %S\n", DeviceObject->Vpb->VolumeLabel);
if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
return STATUS_INFO_LENGTH_MISMATCH;
if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR))) if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + LabelLength*sizeof(WCHAR)))
return(STATUS_BUFFER_OVERFLOW); return STATUS_BUFFER_OVERFLOW;
/* valid entries */ /* valid entries */
FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber; FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
FsVolumeInfo->VolumeLabelLength = LabelLength; FsVolumeInfo->VolumeLabelLength = LabelLength * sizeof (WCHAR);
wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel); wcscpy(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel);
/* dummy entries */ /* dummy entries */
@ -69,9 +70,11 @@ FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6)); DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6));
/* FIXME: This does not work correctly! Why?? */ if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
// if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6)); return STATUS_INFO_LENGTH_MISMATCH;
// return(STATUS_BUFFER_OVERFLOW);
if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 6))
return STATUS_BUFFER_OVERFLOW;
FsAttributeInfo->FileSystemAttributes = FsAttributeInfo->FileSystemAttributes =
FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK; FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
@ -175,37 +178,31 @@ FsdSetFsLabelInformation(PDEVICE_OBJECT DeviceObject,
} }
NTSTATUS STDCALL NTSTATUS VfatQueryVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/* /*
* FUNCTION: Retrieve the specified volume information * FUNCTION: Retrieve the specified volume information
*/ */
{ {
PIO_STACK_LOCATION Stack;
FS_INFORMATION_CLASS FsInformationClass; FS_INFORMATION_CLASS FsInformationClass;
PFILE_OBJECT FileObject = NULL;
PVFATFCB FCB = NULL;
NTSTATUS RC = STATUS_SUCCESS; NTSTATUS RC = STATUS_SUCCESS;
PVOID SystemBuffer; PVOID SystemBuffer;
ULONG BufferLength; ULONG BufferLength;
/* PRECONDITION */ /* PRECONDITION */
assert(DeviceObject != NULL); assert(IrpContext);
assert(Irp != NULL);
DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n", DPRINT("VfatQueryVolumeInformation(IrpContext %x)\n", IrpContext);
DeviceObject, Irp);
if (!ExAcquireResourceSharedLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
{
return VfatQueueRequest (IrpContext);
}
/* INITIALIZATION */ /* INITIALIZATION */
Stack = IoGetCurrentIrpStackLocation (Irp); FsInformationClass = IrpContext->Stack->Parameters.QueryVolume.FsInformationClass;
FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass; BufferLength = IrpContext->Stack->Parameters.QueryVolume.Length;
BufferLength = Stack->Parameters.QueryVolume.Length; SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
FileObject = Stack->FileObject;
// CCB = (PVfatCCB)(FileObject->FsContext2);
// FCB = CCB->Buffer; // Should be CCB->FCB???
FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
DPRINT ("FsInformationClass %d\n", FsInformationClass); DPRINT ("FsInformationClass %d\n", FsInformationClass);
DPRINT ("SystemBuffer %x\n", SystemBuffer); DPRINT ("SystemBuffer %x\n", SystemBuffer);
@ -213,9 +210,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
switch (FsInformationClass) switch (FsInformationClass)
{ {
case FileFsVolumeInformation: case FileFsVolumeInformation:
RC = FsdGetFsVolumeInformation(FileObject, RC = FsdGetFsVolumeInformation(IrpContext->DeviceObject,
FCB,
DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
@ -226,7 +221,7 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
break; break;
case FileFsSizeInformation: case FileFsSizeInformation:
RC = FsdGetFsSizeInformation(DeviceObject, RC = FsdGetFsSizeInformation(IrpContext->DeviceObject,
SystemBuffer, SystemBuffer,
&BufferLength); &BufferLength);
break; break;
@ -240,57 +235,52 @@ VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject,
RC = STATUS_NOT_SUPPORTED; RC = STATUS_NOT_SUPPORTED;
} }
Irp->IoStatus.Status = RC; ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
IrpContext->Irp->IoStatus.Status = RC;
if (NT_SUCCESS(RC)) if (NT_SUCCESS(RC))
Irp->IoStatus.Information = IrpContext->Irp->IoStatus.Information =
Stack->Parameters.QueryVolume.Length - BufferLength; IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength;
else else
Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
IO_NO_INCREMENT); VfatFreeIrpContext(IrpContext);
return RC; return RC;
} }
NTSTATUS STDCALL NTSTATUS VfatSetVolumeInformation(PVFAT_IRP_CONTEXT IrpContext)
VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/* /*
* FUNCTION: Set the specified volume information * FUNCTION: Set the specified volume information
*/ */
{ {
PIO_STACK_LOCATION Stack;
FS_INFORMATION_CLASS FsInformationClass; FS_INFORMATION_CLASS FsInformationClass;
// PFILE_OBJECT FileObject = NULL;
// PVFATFCB FCB = NULL;
NTSTATUS Status = STATUS_SUCCESS; NTSTATUS Status = STATUS_SUCCESS;
PVOID SystemBuffer; PVOID SystemBuffer;
ULONG BufferLength; ULONG BufferLength;
/* PRECONDITION */ /* PRECONDITION */
assert(DeviceObject != NULL); assert(IrpContext);
assert(Irp != NULL);
DPRINT("FsdSetVolumeInformation(DeviceObject %x, Irp %x)\n", DPRINT1("VfatSetVolumeInformation(IrpContext %x)\n", IrpContext);
DeviceObject,
Irp);
Stack = IoGetCurrentIrpStackLocation(Irp); if (!ExAcquireResourceExclusiveLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
FsInformationClass = Stack->Parameters.SetVolume.FsInformationClass; {
BufferLength = Stack->Parameters.SetVolume.Length; return VfatQueueRequest (IrpContext);
SystemBuffer = Irp->AssociatedIrp.SystemBuffer; }
// FileObject = Stack->FileObject;
// FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
DPRINT("FsInformationClass %d\n", FsInformationClass); FsInformationClass = IrpContext->Stack->Parameters.SetVolume.FsInformationClass;
DPRINT("BufferLength %d\n", BufferLength); BufferLength = IrpContext->Stack->Parameters.SetVolume.Length;
DPRINT("SystemBuffer %x\n", SystemBuffer); SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
DPRINT1("FsInformationClass %d\n", FsInformationClass);
DPRINT1("BufferLength %d\n", BufferLength);
DPRINT1("SystemBuffer %x\n", SystemBuffer);
switch(FsInformationClass) switch(FsInformationClass)
{ {
case FileFsLabelInformation: case FileFsLabelInformation:
Status = FsdSetFsLabelInformation(DeviceObject, Status = FsdSetFsLabelInformation(IrpContext->DeviceObject,
SystemBuffer); SystemBuffer);
break; break;
@ -298,10 +288,11 @@ VfatSetVolumeInformation(PDEVICE_OBJECT DeviceObject,
Status = STATUS_NOT_SUPPORTED; Status = STATUS_NOT_SUPPORTED;
} }
Irp->IoStatus.Status = Status; ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
Irp->IoStatus.Information = 0; IrpContext->Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IrpContext->Irp->IoStatus.Information = 0;
IO_NO_INCREMENT); IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
VfatFreeIrpContext(IrpContext);
return(Status); return(Status);
} }