2002-02-08 02:57:10 +00:00
|
|
|
/* $Id: iface.c,v 1.61 2002/02/08 02:57:09 chorns Exp $
|
1999-12-04 20:58:45 +00:00
|
|
|
*
|
1998-10-05 04:00:59 +00:00
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: services/fs/vfat/iface.c
|
|
|
|
* PURPOSE: VFAT Filesystem
|
|
|
|
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
|
1998-10-31 15:54:07 +00:00
|
|
|
* UPDATE HISTORY:
|
1999-12-11 21:14:49 +00:00
|
|
|
* ?? Created
|
|
|
|
* 24-10-1998 Fixed bugs in long filename support
|
2001-10-10 22:18:58 +00:00
|
|
|
* Fixed a bug that prevented unsuccessful file open requests
|
2000-12-29 23:17:12 +00:00
|
|
|
* being reported
|
2001-10-10 22:18:58 +00:00
|
|
|
* Now works with long filenames that span over a sector
|
2000-12-29 23:17:12 +00:00
|
|
|
* boundary
|
1999-12-11 21:14:49 +00:00
|
|
|
* 28-10-1998 Reads entire FAT into memory
|
2000-12-29 23:17:12 +00:00
|
|
|
* VFatReadSector modified to read in more than one sector at a
|
|
|
|
* time
|
2001-10-10 22:18:58 +00:00
|
|
|
* 7-11-1998 Fixed bug that assumed that directory data could be
|
2000-12-29 23:17:12 +00:00
|
|
|
* fragmented
|
1999-12-11 21:14:49 +00:00
|
|
|
* 8-12-1998 Added FAT32 support
|
|
|
|
* Added initial writability functions
|
|
|
|
* WARNING: DO NOT ATTEMPT TO TEST WRITABILITY FUNCTIONS!!!
|
|
|
|
* 12-12-1998 Added basic support for FILE_STANDARD_INFORMATION request
|
|
|
|
*
|
|
|
|
*/
|
1998-12-20 19:41:39 +00:00
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
/* INCLUDES *****************************************************************/
|
1998-12-20 19:41:39 +00:00
|
|
|
|
2000-02-21 22:44:37 +00:00
|
|
|
#include <ddk/ntddk.h>
|
1998-12-20 19:41:39 +00:00
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
#define NDEBUG
|
2000-06-29 23:35:53 +00:00
|
|
|
#include <debug.h>
|
1998-10-05 04:00:59 +00:00
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
#include "vfat.h"
|
1998-12-20 19:41:39 +00:00
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
/* GLOBALS *****************************************************************/
|
1998-10-05 04:00:59 +00:00
|
|
|
|
2001-07-13 10:31:14 +00:00
|
|
|
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->BytesPerCluster > PAGESIZE ? \
|
|
|
|
(pDeviceExt)->BytesPerCluster : PAGESIZE)
|
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
static PDRIVER_OBJECT VfatDriverObject;
|
1998-10-05 04:00:59 +00:00
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
/* FUNCTIONS ****************************************************************/
|
1999-06-27 23:06:50 +00:00
|
|
|
|
2001-03-06 08:19:58 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatHasFileSystem(PDEVICE_OBJECT DeviceToMount,
|
|
|
|
PBOOLEAN RecognizedFS)
|
1998-12-30 18:43:27 +00:00
|
|
|
/*
|
2001-10-10 22:18:58 +00:00
|
|
|
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
1999-12-11 21:14:49 +00:00
|
|
|
* by this fsd
|
1998-12-30 18:43:27 +00:00
|
|
|
*/
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2001-03-06 08:19:58 +00:00
|
|
|
BootSector *Boot;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
Boot = ExAllocatePool(NonPagedPool, 512);
|
|
|
|
|
|
|
|
Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) Boot);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2001-07-20 08:00:21 +00:00
|
|
|
return(Status);
|
2001-03-06 08:19:58 +00:00
|
|
|
}
|
|
|
|
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("Boot->SysType %.5s\n", Boot->SysType);
|
2001-03-06 08:19:58 +00:00
|
|
|
if (strncmp(Boot->SysType, "FAT12", 5) == 0 ||
|
|
|
|
strncmp(Boot->SysType, "FAT16", 5) == 0 ||
|
|
|
|
strncmp(((struct _BootSector32 *) (Boot))->SysType, "FAT32", 5) == 0)
|
|
|
|
{
|
|
|
|
*RecognizedFS = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
*RecognizedFS = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ExFreePool(Boot);
|
|
|
|
|
2001-07-20 08:00:21 +00:00
|
|
|
return(STATUS_SUCCESS);
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
2001-03-06 08:19:58 +00:00
|
|
|
|
|
|
|
static NTSTATUS
|
2001-07-20 08:00:21 +00:00
|
|
|
VfatMountDevice(PDEVICE_EXTENSION DeviceExt,
|
|
|
|
PDEVICE_OBJECT DeviceToMount)
|
1998-12-30 18:43:27 +00:00
|
|
|
/*
|
1999-12-11 21:14:49 +00:00
|
|
|
* FUNCTION: Mounts the device
|
1998-12-30 18:43:27 +00:00
|
|
|
*/
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2001-03-06 08:19:58 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
DPRINT("Mounting VFAT device...");
|
|
|
|
DPRINT("DeviceExt %x\n", DeviceExt);
|
|
|
|
|
|
|
|
DeviceExt->Boot = ExAllocatePool(NonPagedPool, 512);
|
|
|
|
|
|
|
|
Status = VfatReadSectors(DeviceToMount, 0, 1, (UCHAR *) DeviceExt->Boot);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2001-07-20 08:00:21 +00:00
|
|
|
return(Status);
|
2001-03-06 08:19:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DeviceExt->FATStart = DeviceExt->Boot->ReservedSectors;
|
|
|
|
DeviceExt->rootDirectorySectors =
|
|
|
|
(DeviceExt->Boot->RootEntries * 32) / DeviceExt->Boot->BytesPerSector;
|
|
|
|
DeviceExt->rootStart =
|
|
|
|
DeviceExt->FATStart +
|
|
|
|
DeviceExt->Boot->FATCount * DeviceExt->Boot->FATSectors;
|
|
|
|
DeviceExt->dataStart =
|
|
|
|
DeviceExt->rootStart + DeviceExt->rootDirectorySectors;
|
2001-07-05 01:51:53 +00:00
|
|
|
DeviceExt->BytesPerSector = DeviceExt->Boot->BytesPerSector;
|
2001-03-06 08:19:58 +00:00
|
|
|
DeviceExt->FATEntriesPerSector = DeviceExt->Boot->BytesPerSector / 32;
|
|
|
|
DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
|
|
|
|
DeviceExt->Boot->BytesPerSector;
|
|
|
|
|
|
|
|
if (DeviceExt->BytesPerCluster >= PAGESIZE &&
|
|
|
|
(DeviceExt->BytesPerCluster % PAGESIZE) != 0)
|
|
|
|
{
|
|
|
|
DbgPrint("Invalid cluster size\n");
|
|
|
|
KeBugCheck(0);
|
|
|
|
}
|
|
|
|
else if (DeviceExt->BytesPerCluster < PAGESIZE &&
|
|
|
|
(PAGESIZE % DeviceExt->BytesPerCluster) != 0)
|
|
|
|
{
|
|
|
|
DbgPrint("Invalid cluster size2\n");
|
|
|
|
KeBugCheck(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strncmp (DeviceExt->Boot->SysType, "FAT12", 5) == 0)
|
|
|
|
{
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("FAT12\n");
|
2001-03-06 08:19:58 +00:00
|
|
|
DeviceExt->FatType = FAT12;
|
|
|
|
}
|
|
|
|
else if (strncmp
|
|
|
|
(((struct _BootSector32 *) (DeviceExt->Boot))->SysType, "FAT32",
|
|
|
|
5) == 0)
|
|
|
|
{
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("FAT32\n");
|
2001-03-06 08:19:58 +00:00
|
|
|
DeviceExt->FatType = FAT32;
|
|
|
|
DeviceExt->rootDirectorySectors = DeviceExt->Boot->SectorsPerCluster;
|
2001-07-20 08:00:21 +00:00
|
|
|
DeviceExt->dataStart = DeviceExt->FATStart + DeviceExt->Boot->FATCount
|
2001-03-06 08:19:58 +00:00
|
|
|
* ((struct _BootSector32 *) (DeviceExt->Boot))->FATSectors32;
|
2001-07-20 08:00:21 +00:00
|
|
|
DeviceExt->rootStart = ClusterToSector (DeviceExt,
|
|
|
|
((struct _BootSector32 *)(DeviceExt->Boot))->RootCluster);
|
2001-03-06 08:19:58 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("FAT16\n");
|
2001-03-06 08:19:58 +00:00
|
|
|
DeviceExt->FatType = FAT16;
|
|
|
|
}
|
|
|
|
|
2001-07-20 08:00:21 +00:00
|
|
|
return(STATUS_SUCCESS);
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
2001-03-06 08:19:58 +00:00
|
|
|
|
|
|
|
static NTSTATUS
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatMount (PVFAT_IRP_CONTEXT IrpContext)
|
1998-12-30 18:43:27 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Mount the filesystem
|
|
|
|
*/
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2001-11-02 22:47:36 +00:00
|
|
|
PDEVICE_OBJECT DeviceObject = NULL;
|
|
|
|
PDEVICE_EXTENSION DeviceExt = NULL;
|
2001-07-20 08:00:21 +00:00
|
|
|
BOOLEAN RecognizedFS;
|
|
|
|
NTSTATUS Status;
|
2001-11-02 22:47:36 +00:00
|
|
|
PVFATFCB Fcb = NULL;
|
|
|
|
PVFATCCB Ccb = NULL;
|
2001-07-20 08:00:21 +00:00
|
|
|
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("VfatMount(IrpContext %x)\n", IrpContext);
|
2001-11-02 22:47:36 +00:00
|
|
|
|
|
|
|
assert (IrpContext);
|
|
|
|
|
|
|
|
Status = VfatHasFileSystem (IrpContext->Stack->Parameters.Mount.DeviceObject, &RecognizedFS);
|
2001-07-20 08:00:21 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2001-11-02 22:47:36 +00:00
|
|
|
{
|
|
|
|
goto ByeBye;
|
|
|
|
}
|
2001-07-20 08:00:21 +00:00
|
|
|
|
|
|
|
if (RecognizedFS == FALSE)
|
2001-11-02 22:47:36 +00:00
|
|
|
{
|
|
|
|
DPRINT("VFAT: Unrecognized Volume\n");
|
|
|
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
|
|
|
goto ByeBye;
|
|
|
|
}
|
2001-07-20 08:00:21 +00:00
|
|
|
|
|
|
|
DPRINT("VFAT: Recognized volume\n");
|
|
|
|
|
|
|
|
Status = IoCreateDevice(VfatDriverObject,
|
|
|
|
sizeof (DEVICE_EXTENSION),
|
|
|
|
NULL,
|
|
|
|
FILE_DEVICE_FILE_SYSTEM,
|
|
|
|
0,
|
|
|
|
FALSE,
|
|
|
|
&DeviceObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
2001-11-02 22:47:36 +00:00
|
|
|
{
|
|
|
|
goto ByeBye;
|
|
|
|
}
|
2001-07-20 08:00:21 +00:00
|
|
|
|
|
|
|
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
|
|
|
DeviceExt = (PVOID) DeviceObject->DeviceExtension;
|
2001-11-02 22:47:36 +00:00
|
|
|
RtlZeroMemory(DeviceExt, sizeof(DEVICE_EXTENSION));
|
|
|
|
|
2001-07-20 08:00:21 +00:00
|
|
|
/* use same vpb as device disk */
|
2001-11-02 22:47:36 +00:00
|
|
|
DeviceObject->Vpb = IrpContext->Stack->Parameters.Mount.DeviceObject->Vpb;
|
|
|
|
Status = VfatMountDevice(DeviceExt, IrpContext->Stack->Parameters.Mount.DeviceObject);
|
2001-07-20 08:00:21 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
2001-11-02 22:47:36 +00:00
|
|
|
{
|
|
|
|
/* FIXME: delete device object */
|
|
|
|
goto ByeBye;
|
|
|
|
}
|
2001-07-20 08:00:21 +00:00
|
|
|
|
2002-02-08 02:57:10 +00:00
|
|
|
#ifdef DBG
|
2001-07-20 08:00:21 +00:00
|
|
|
DbgPrint("BytesPerSector: %d\n", DeviceExt->Boot->BytesPerSector);
|
|
|
|
DbgPrint("SectorsPerCluster: %d\n", DeviceExt->Boot->SectorsPerCluster);
|
|
|
|
DbgPrint("ReservedSectors: %d\n", DeviceExt->Boot->ReservedSectors);
|
|
|
|
DbgPrint("FATCount: %d\n", DeviceExt->Boot->FATCount);
|
|
|
|
DbgPrint("RootEntries: %d\n", DeviceExt->Boot->RootEntries);
|
|
|
|
DbgPrint("Sectors: %d\n", DeviceExt->Boot->Sectors);
|
|
|
|
DbgPrint("FATSectors: %d\n", DeviceExt->Boot->FATSectors);
|
|
|
|
DbgPrint("SectorsPerTrack: %d\n", DeviceExt->Boot->SectorsPerTrack);
|
|
|
|
DbgPrint("Heads: %d\n", DeviceExt->Boot->Heads);
|
|
|
|
DbgPrint("HiddenSectors: %d\n", DeviceExt->Boot->HiddenSectors);
|
|
|
|
DbgPrint("SectorsHuge: %d\n", DeviceExt->Boot->SectorsHuge);
|
|
|
|
DbgPrint("RootStart: %d\n", DeviceExt->rootStart);
|
|
|
|
DbgPrint("DataStart: %d\n", DeviceExt->dataStart);
|
|
|
|
if (DeviceExt->FatType == FAT32)
|
|
|
|
{
|
|
|
|
DbgPrint("FATSectors32: %d\n",
|
|
|
|
((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32);
|
|
|
|
DbgPrint("RootCluster: %d\n",
|
|
|
|
((struct _BootSector32*)(DeviceExt->Boot))->RootCluster);
|
|
|
|
DbgPrint("FSInfoSector: %d\n",
|
|
|
|
((struct _BootSector32*)(DeviceExt->Boot))->FSInfoSector);
|
|
|
|
DbgPrint("BootBackup: %d\n",
|
|
|
|
((struct _BootSector32*)(DeviceExt->Boot))->BootBackup);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
|
2001-11-02 22:47:36 +00:00
|
|
|
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject, IrpContext->Stack->Parameters.Mount.DeviceObject);
|
2001-10-10 22:18:58 +00:00
|
|
|
|
|
|
|
DeviceExt->FATFileObject = IoCreateStreamFileObject(NULL, DeviceExt->StorageDevice);
|
|
|
|
Fcb = vfatNewFCB(NULL);
|
|
|
|
if (Fcb == NULL)
|
|
|
|
{
|
2001-11-02 22:47:36 +00:00
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto ByeBye;
|
2001-10-10 22:18:58 +00:00
|
|
|
}
|
|
|
|
Ccb = ExAllocatePoolWithTag (NonPagedPool, sizeof (VFATCCB), TAG_CCB);
|
|
|
|
if (Ccb == NULL)
|
|
|
|
{
|
2001-11-02 22:47:36 +00:00
|
|
|
Status = STATUS_INSUFFICIENT_RESOURCES;
|
|
|
|
goto ByeBye;
|
2001-10-10 22:18:58 +00:00
|
|
|
}
|
|
|
|
memset(Ccb, 0, sizeof (VFATCCB));
|
|
|
|
DeviceExt->FATFileObject->Flags = DeviceExt->FATFileObject->Flags | FO_FCB_IS_VALID | FO_DIRECT_CACHE_PAGING_READ;
|
|
|
|
DeviceExt->FATFileObject->FsContext = (PVOID) &Fcb->RFCB;
|
|
|
|
DeviceExt->FATFileObject->FsContext2 = Ccb;
|
2001-11-02 22:47:36 +00:00
|
|
|
DeviceExt->FATFileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
|
2001-10-10 22:18:58 +00:00
|
|
|
Ccb->pFcb = Fcb;
|
|
|
|
Ccb->PtrFileObject = DeviceExt->FATFileObject;
|
|
|
|
Fcb->FileObject = DeviceExt->FATFileObject;
|
|
|
|
Fcb->pDevExt = (PDEVICE_EXTENSION)DeviceExt->StorageDevice;
|
|
|
|
|
|
|
|
Fcb->Flags = FCB_IS_FAT;
|
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
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;
|
|
|
|
}
|
2001-10-10 22:18:58 +00:00
|
|
|
if (DeviceExt->FatType == FAT32)
|
|
|
|
{
|
|
|
|
Fcb->RFCB.FileSize.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
|
|
|
|
Fcb->RFCB.ValidDataLength.QuadPart = ((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE;
|
|
|
|
Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(((struct _BootSector32 *)DeviceExt->Boot)->FATSectors32 * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
|
|
|
|
Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (DeviceExt->FatType == FAT16)
|
2001-07-20 08:00:21 +00:00
|
|
|
{
|
2001-10-10 22:18:58 +00:00
|
|
|
Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
|
|
|
|
Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
|
|
|
|
Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(DeviceExt->Boot->FATSectors * BLOCKSIZE, CACHEPAGESIZE(DeviceExt));
|
|
|
|
Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, CACHEPAGESIZE(DeviceExt));
|
2001-07-20 08:00:21 +00:00
|
|
|
}
|
2001-10-10 22:18:58 +00:00
|
|
|
else
|
2001-07-20 08:00:21 +00:00
|
|
|
{
|
2001-10-10 22:18:58 +00:00
|
|
|
Fcb->RFCB.FileSize.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
|
|
|
|
Fcb->RFCB.ValidDataLength.QuadPart = DeviceExt->Boot->FATSectors * BLOCKSIZE;
|
|
|
|
Fcb->RFCB.AllocationSize.QuadPart = 2 * PAGESIZE;
|
|
|
|
Status = CcRosInitializeFileCache(DeviceExt->FATFileObject, &Fcb->RFCB.Bcb, 2 * PAGESIZE);
|
2001-07-20 08:00:21 +00:00
|
|
|
}
|
2001-10-10 22:18:58 +00:00
|
|
|
}
|
|
|
|
if (!NT_SUCCESS (Status))
|
|
|
|
{
|
|
|
|
DbgPrint ("CcRosInitializeFileCache failed\n");
|
2001-11-02 22:47:36 +00:00
|
|
|
goto ByeBye;
|
2001-10-10 22:18:58 +00:00
|
|
|
}
|
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
DeviceExt->LastAvailableCluster = 0;
|
2001-07-20 08:00:21 +00:00
|
|
|
ExInitializeResourceLite(&DeviceExt->DirResource);
|
|
|
|
ExInitializeResourceLite(&DeviceExt->FatResource);
|
|
|
|
|
|
|
|
KeInitializeSpinLock(&DeviceExt->FcbListLock);
|
|
|
|
InitializeListHead(&DeviceExt->FcbListHead);
|
|
|
|
|
|
|
|
/* read serial number */
|
|
|
|
if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
|
|
|
|
DeviceObject->Vpb->SerialNumber =
|
|
|
|
((struct _BootSector *) (DeviceExt->Boot))->VolumeID;
|
|
|
|
else if (DeviceExt->FatType == FAT32)
|
|
|
|
DeviceObject->Vpb->SerialNumber =
|
|
|
|
((struct _BootSector32 *) (DeviceExt->Boot))->VolumeID;
|
|
|
|
|
|
|
|
/* read volume label */
|
2001-10-10 22:18:58 +00:00
|
|
|
ReadVolumeLabel(DeviceExt, DeviceObject->Vpb);
|
2001-11-02 22:47:36 +00:00
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
|
|
|
|
ByeBye:
|
2001-07-20 08:00:21 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
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;
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
2001-03-06 08:19:58 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
NTSTATUS VfatFileSystemControl(PVFAT_IRP_CONTEXT IrpContext)
|
1998-12-30 18:43:27 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: File system control
|
|
|
|
*/
|
1998-10-05 04:00:59 +00:00
|
|
|
{
|
2001-11-02 22:47:36 +00:00
|
|
|
|
2001-03-06 08:19:58 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("VfatFileSystemControl(IrpContext %x)\n", IrpContext);
|
2001-11-02 22:47:36 +00:00
|
|
|
|
|
|
|
assert (IrpContext);
|
|
|
|
|
|
|
|
switch (IrpContext->MinorFunction)
|
2001-03-06 08:19:58 +00:00
|
|
|
{
|
|
|
|
case IRP_MN_USER_FS_REQUEST:
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("VFAT FSC: IRP_MN_USER_FS_REQUEST\n");
|
2001-03-06 08:19:58 +00:00
|
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case IRP_MN_MOUNT_VOLUME:
|
2001-11-02 22:47:36 +00:00
|
|
|
Status = VfatMount(IrpContext);
|
2001-03-06 08:19:58 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case IRP_MN_VERIFY_VOLUME:
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("VFAT FSC: IRP_MN_VERIFY_VOLUME\n");
|
2001-03-06 08:19:58 +00:00
|
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("VFAT FSC: MinorFunction %d\n", IrpContext->MinorFunction);
|
2001-03-06 08:19:58 +00:00
|
|
|
Status = STATUS_INVALID_DEVICE_REQUEST;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
IrpContext->Irp->IoStatus.Status = Status;
|
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
2001-03-06 08:19:58 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
|
2001-03-06 08:19:58 +00:00
|
|
|
return (Status);
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
|
|
|
|
2001-03-06 08:19:58 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
NTSTATUS STDCALL
|
2001-06-11 19:52:22 +00:00
|
|
|
DriverEntry(PDRIVER_OBJECT _DriverObject,
|
|
|
|
PUNICODE_STRING RegistryPath)
|
1998-10-05 04:00:59 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Called by the system to initalize the driver
|
|
|
|
* ARGUMENTS:
|
|
|
|
* DriverObject = object describing this driver
|
|
|
|
* RegistryPath = path to our configuration entries
|
|
|
|
* RETURNS: Success or failure
|
|
|
|
*/
|
|
|
|
{
|
2001-03-06 08:19:58 +00:00
|
|
|
PDEVICE_OBJECT DeviceObject;
|
|
|
|
UNICODE_STRING DeviceName;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
2002-02-08 02:57:10 +00:00
|
|
|
DPRINT("VFAT 0.0.6\n");
|
2001-03-06 08:19:58 +00:00
|
|
|
|
|
|
|
VfatDriverObject = _DriverObject;
|
|
|
|
|
|
|
|
RtlInitUnicodeString(&DeviceName,
|
|
|
|
L"\\Device\\Vfat");
|
|
|
|
Status = IoCreateDevice(VfatDriverObject,
|
|
|
|
0,
|
|
|
|
&DeviceName,
|
|
|
|
FILE_DEVICE_FILE_SYSTEM,
|
|
|
|
0,
|
|
|
|
FALSE,
|
|
|
|
&DeviceObject);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
return (Status);
|
|
|
|
}
|
|
|
|
|
|
|
|
DeviceObject->Flags = DO_DIRECT_IO;
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatBuildRequest;
|
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatBuildRequest;
|
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatBuildRequest;
|
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatBuildRequest;
|
2001-03-06 08:19:58 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatBuildRequest;
|
2001-03-06 08:19:58 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatBuildRequest;
|
2001-03-06 08:19:58 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatBuildRequest;
|
2001-03-06 08:19:58 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatBuildRequest;
|
2001-03-06 08:19:58 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatBuildRequest;
|
2001-06-11 19:52:22 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] =
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatBuildRequest;
|
2001-03-06 08:19:58 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
|
2001-11-02 22:47:36 +00:00
|
|
|
VfatDriverObject->MajorFunction[IRP_MJ_CLEANUP] = VfatBuildRequest;
|
2001-03-06 08:19:58 +00:00
|
|
|
|
|
|
|
VfatDriverObject->DriverUnload = NULL;
|
|
|
|
|
|
|
|
IoRegisterFileSystem(DeviceObject);
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
1998-10-05 04:00:59 +00:00
|
|
|
}
|
2001-03-06 08:19:58 +00:00
|
|
|
|
|
|
|
/* EOF */
|