mirror of
https://github.com/reactos/reactos.git
synced 2024-07-01 18:24:24 +00:00
Implemented MmAllocateContinuousMemory
VFAT driver cleanups svn path=/trunk/; revision=1487
This commit is contained in:
parent
1f1ae27105
commit
ed20b9b6ba
|
@ -18,10 +18,9 @@
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
BOOLEAN
|
||||||
IN ULONG DiskSector,
|
VFATReadSectors (IN PDEVICE_OBJECT pDeviceObject,
|
||||||
IN ULONG SectorCount,
|
IN ULONG DiskSector, IN ULONG SectorCount, IN UCHAR * Buffer)
|
||||||
IN UCHAR* Buffer)
|
|
||||||
{
|
{
|
||||||
LARGE_INTEGER sectorNumber;
|
LARGE_INTEGER sectorNumber;
|
||||||
PIRP irp;
|
PIRP irp;
|
||||||
|
@ -33,69 +32,59 @@ BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
sectorNumber.u.LowPart = DiskSector << 9;
|
sectorNumber.u.LowPart = DiskSector << 9;
|
||||||
sectorNumber.u.HighPart = DiskSector >> 23;
|
sectorNumber.u.HighPart = DiskSector >> 23;
|
||||||
|
|
||||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
KeInitializeEvent (&event, NotificationEvent, FALSE);
|
||||||
sectorSize = BLOCKSIZE * SectorCount;
|
sectorSize = BLOCKSIZE * SectorCount;
|
||||||
|
|
||||||
|
|
||||||
DPRINT("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
DPRINT ("VFATReadSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||||
pDeviceObject,
|
pDeviceObject, DiskSector, Buffer);
|
||||||
DiskSector,
|
DPRINT ("sectorNumber %08lx:%08lx sectorSize %ld\n",
|
||||||
Buffer);
|
(unsigned long int) sectorNumber.u.LowPart,
|
||||||
DPRINT("sectorNumber %08lx:%08lx sectorSize %ld\n",
|
(unsigned long int) sectorNumber.u.HighPart, sectorSize);
|
||||||
(unsigned long int)sectorNumber.u.LowPart,
|
|
||||||
(unsigned long int)sectorNumber.u.HighPart,
|
|
||||||
sectorSize);
|
|
||||||
|
|
||||||
|
|
||||||
DPRINT("Building synchronous FSD Request...\n");
|
DPRINT ("Building synchronous FSD Request...\n");
|
||||||
irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
|
irp = IoBuildSynchronousFsdRequest (IRP_MJ_READ,
|
||||||
pDeviceObject,
|
pDeviceObject,
|
||||||
Buffer,
|
Buffer,
|
||||||
sectorSize,
|
sectorSize,
|
||||||
§orNumber,
|
§orNumber, &event, &ioStatus);
|
||||||
&event,
|
|
||||||
&ioStatus );
|
|
||||||
|
|
||||||
if (!irp) {
|
if (!irp)
|
||||||
DbgPrint("READ failed!!!\n");
|
{
|
||||||
|
DbgPrint ("READ failed!!!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Calling IO Driver... with irp %x\n", irp);
|
DPRINT ("Calling IO Driver... with irp %x\n", irp);
|
||||||
status = IoCallDriver(pDeviceObject,
|
status = IoCallDriver (pDeviceObject, irp);
|
||||||
irp);
|
|
||||||
|
|
||||||
DPRINT("Waiting for IO Operation for %x\n", irp);
|
DPRINT ("Waiting for IO Operation for %x\n", irp);
|
||||||
if (status == STATUS_PENDING)
|
if (status == STATUS_PENDING)
|
||||||
{
|
{
|
||||||
DPRINT("Operation pending\n");
|
DPRINT ("Operation pending\n");
|
||||||
KeWaitForSingleObject(&event,
|
KeWaitForSingleObject (&event, Suspended, KernelMode, FALSE, NULL);
|
||||||
Suspended,
|
DPRINT ("Getting IO Status... for %x\n", irp);
|
||||||
KernelMode,
|
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
DPRINT("Getting IO Status... for %x\n", irp);
|
|
||||||
status = ioStatus.Status;
|
status = ioStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS (status))
|
||||||
DbgPrint("IO failed!!! VFATREadSectors : Error code: %x\n", status);
|
{
|
||||||
DbgPrint("(pDeviceObject %x, DiskSector %x, Buffer %x, offset 0x%x%x)\n",
|
DbgPrint ("IO failed!!! VFATREadSectors : Error code: %x\n", status);
|
||||||
pDeviceObject,
|
DbgPrint
|
||||||
DiskSector,
|
("(pDeviceObject %x, DiskSector %x, Buffer %x, offset 0x%x%x)\n",
|
||||||
Buffer,
|
pDeviceObject, DiskSector, Buffer, sectorNumber.u.HighPart,
|
||||||
sectorNumber.u.HighPart,
|
|
||||||
sectorNumber.u.LowPart);
|
sectorNumber.u.LowPart);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
DPRINT("Block request succeeded for %x\n", irp);
|
DPRINT ("Block request succeeded for %x\n", irp);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
BOOLEAN
|
||||||
|
VFATWriteSectors (IN PDEVICE_OBJECT pDeviceObject,
|
||||||
IN ULONG DiskSector,
|
IN ULONG DiskSector,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount, IN UCHAR * Buffer)
|
||||||
IN UCHAR* Buffer)
|
|
||||||
{
|
{
|
||||||
LARGE_INTEGER sectorNumber;
|
LARGE_INTEGER sectorNumber;
|
||||||
PIRP irp;
|
PIRP irp;
|
||||||
|
@ -104,51 +93,46 @@ BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
ULONG sectorSize;
|
ULONG sectorSize;
|
||||||
|
|
||||||
DPRINT("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
DPRINT ("VFATWriteSector(pDeviceObject %x, DiskSector %d, Buffer %x)\n",
|
||||||
pDeviceObject,DiskSector,Buffer);
|
pDeviceObject, DiskSector, Buffer);
|
||||||
|
|
||||||
sectorNumber.u.LowPart = DiskSector << 9;
|
sectorNumber.u.LowPart = DiskSector << 9;
|
||||||
sectorNumber.u.HighPart = DiskSector >> 23;
|
sectorNumber.u.HighPart = DiskSector >> 23;
|
||||||
|
|
||||||
KeInitializeEvent(&event, NotificationEvent, FALSE);
|
KeInitializeEvent (&event, NotificationEvent, FALSE);
|
||||||
|
|
||||||
sectorSize = BLOCKSIZE*SectorCount;
|
sectorSize = BLOCKSIZE * SectorCount;
|
||||||
|
|
||||||
DPRINT("Building synchronous FSD Request...\n");
|
DPRINT ("Building synchronous FSD Request...\n");
|
||||||
irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE,
|
irp = IoBuildSynchronousFsdRequest (IRP_MJ_WRITE,
|
||||||
pDeviceObject,
|
pDeviceObject,
|
||||||
Buffer,
|
Buffer,
|
||||||
sectorSize,
|
sectorSize,
|
||||||
§orNumber,
|
§orNumber, &event, &ioStatus);
|
||||||
&event,
|
|
||||||
&ioStatus );
|
|
||||||
|
|
||||||
if (!irp) {
|
if (!irp)
|
||||||
DbgPrint("WRITE failed!!!\n");
|
{
|
||||||
|
DbgPrint ("WRITE failed!!!\n");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Calling IO Driver...\n");
|
DPRINT ("Calling IO Driver...\n");
|
||||||
status = IoCallDriver(pDeviceObject,
|
status = IoCallDriver (pDeviceObject, irp);
|
||||||
irp);
|
|
||||||
|
|
||||||
DPRINT("Waiting for IO Operation...\n");
|
DPRINT ("Waiting for IO Operation...\n");
|
||||||
if (status == STATUS_PENDING) {
|
if (status == STATUS_PENDING)
|
||||||
KeWaitForSingleObject(&event,
|
{
|
||||||
Suspended,
|
KeWaitForSingleObject (&event, Suspended, KernelMode, FALSE, NULL);
|
||||||
KernelMode,
|
DPRINT ("Getting IO Status...\n");
|
||||||
FALSE,
|
|
||||||
NULL);
|
|
||||||
DPRINT("Getting IO Status...\n");
|
|
||||||
status = ioStatus.Status;
|
status = ioStatus.Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(status)) {
|
if (!NT_SUCCESS (status))
|
||||||
DbgPrint("IO failed!!! VFATWriteSectors : Error code: %x\n", status);
|
{
|
||||||
|
DbgPrint ("IO failed!!! VFATWriteSectors : Error code: %x\n", status);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Block request succeeded\n");
|
DPRINT ("Block request succeeded\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: close.c,v 1.2 2000/09/12 10:12:13 jean Exp $
|
/* $Id: close.c,v 1.3 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -18,7 +18,8 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
NTSTATUS
|
||||||
|
VfatCloseFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Closes a file
|
* FUNCTION: Closes a file
|
||||||
*/
|
*/
|
||||||
|
@ -27,51 +28,52 @@ NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject)
|
||||||
PVFATCCB pCcb;
|
PVFATCCB pCcb;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
|
|
||||||
DPRINT("FsdCloseFile(DeviceExt %x, FileObject %x)\n",
|
DPRINT ("FsdCloseFile(DeviceExt %x, FileObject %x)\n",
|
||||||
DeviceExt,FileObject);
|
DeviceExt, FileObject);
|
||||||
|
|
||||||
//FIXME : update entry in directory ?
|
//FIXME : update entry in directory ?
|
||||||
pCcb = (PVFATCCB)(FileObject->FsContext2);
|
pCcb = (PVFATCCB) (FileObject->FsContext2);
|
||||||
|
|
||||||
DPRINT("pCcb %x\n",pCcb);
|
DPRINT ("pCcb %x\n", pCcb);
|
||||||
if (pCcb == NULL)
|
if (pCcb == NULL)
|
||||||
{
|
{
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
pFcb = pCcb->pFcb;
|
pFcb = pCcb->pFcb;
|
||||||
|
|
||||||
pFcb->RefCount--;
|
pFcb->RefCount--;
|
||||||
if(pFcb->RefCount<=0)
|
if (pFcb->RefCount <= 0)
|
||||||
{
|
{
|
||||||
KeAcquireSpinLock(&DeviceExt->FcbListLock, &oldIrql);
|
KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql);
|
||||||
RemoveEntryList(&pFcb->FcbListEntry);
|
RemoveEntryList (&pFcb->FcbListEntry);
|
||||||
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
|
KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql);
|
||||||
ExFreePool(pFcb);
|
ExFreePool (pFcb);
|
||||||
}
|
}
|
||||||
ExFreePool(pCcb);
|
ExFreePool (pCcb);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatClose (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Closes a file
|
* FUNCTION: Closes a file
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("FsdClose(DeviceObject %x, Irp %x)\n",DeviceObject, Irp);
|
DPRINT ("FsdClose(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
Status = FsdCloseFile(DeviceExtension,FileObject);
|
Status = VfatCloseFile (DeviceExtension, FileObject);
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
return(Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -18,10 +18,10 @@
|
||||||
|
|
||||||
|
|
||||||
// function like DosDateTimeToFileTime
|
// function like DosDateTimeToFileTime
|
||||||
BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime)
|
BOOL FsdDosDateTimeToFileTime (WORD wDosDate, WORD wDosTime, TIME * FileTime)
|
||||||
{
|
{
|
||||||
PDOSTIME pdtime = (PDOSTIME)&wDosTime;
|
PDOSTIME pdtime = (PDOSTIME) & wDosTime;
|
||||||
PDOSDATE pddate = (PDOSDATE)&wDosDate;
|
PDOSDATE pddate = (PDOSDATE) & wDosDate;
|
||||||
TIME_FIELDS TimeFields;
|
TIME_FIELDS TimeFields;
|
||||||
|
|
||||||
if (FileTime == NULL)
|
if (FileTime == NULL)
|
||||||
|
@ -36,23 +36,24 @@ BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime)
|
||||||
TimeFields.Month = pddate->Month;
|
TimeFields.Month = pddate->Month;
|
||||||
TimeFields.Year = 1980 + pddate->Year;
|
TimeFields.Year = 1980 + pddate->Year;
|
||||||
|
|
||||||
RtlTimeFieldsToTime(&TimeFields, (PLARGE_INTEGER)FileTime);
|
RtlTimeFieldsToTime (&TimeFields, (PLARGE_INTEGER) FileTime);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// function like FileTimeToDosDateTime
|
// function like FileTimeToDosDateTime
|
||||||
BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime)
|
BOOL
|
||||||
|
FsdFileTimeToDosDateTime (TIME * FileTime, WORD * pwDosDate, WORD * pwDosTime)
|
||||||
{
|
{
|
||||||
PDOSTIME pdtime = (PDOSTIME)pwDosTime;
|
PDOSTIME pdtime = (PDOSTIME) pwDosTime;
|
||||||
PDOSDATE pddate = (PDOSDATE)pwDosDate;
|
PDOSDATE pddate = (PDOSDATE) pwDosDate;
|
||||||
TIME_FIELDS TimeFields;
|
TIME_FIELDS TimeFields;
|
||||||
|
|
||||||
if (FileTime == NULL)
|
if (FileTime == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
RtlTimeToTimeFields((PLARGE_INTEGER)FileTime, &TimeFields);
|
RtlTimeToTimeFields ((PLARGE_INTEGER) FileTime, &TimeFields);
|
||||||
|
|
||||||
if (pdtime)
|
if (pdtime)
|
||||||
{
|
{
|
||||||
|
@ -73,146 +74,159 @@ BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned long vfat_wstrlen(PWSTR s)
|
unsigned long
|
||||||
|
vfat_wstrlen (PWSTR s)
|
||||||
{
|
{
|
||||||
WCHAR c=' ';
|
WCHAR c = ' ';
|
||||||
unsigned int len=0;
|
unsigned int len = 0;
|
||||||
|
|
||||||
while(c!=0) {
|
while (c != 0)
|
||||||
c=*s;
|
{
|
||||||
|
c = *s;
|
||||||
s++;
|
s++;
|
||||||
len++;
|
len++;
|
||||||
};
|
};
|
||||||
s-=len;
|
s -= len;
|
||||||
|
|
||||||
return len-1;
|
return len - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DWORD_ROUND_UP(x) ( (((ULONG)(x))%32) ? ((((ULONG)x)&(~0x1f))+0x20) : ((ULONG)x) )
|
#define DWORD_ROUND_UP(x) ( (((ULONG)(x))%32) ? ((((ULONG)x)&(~0x1f))+0x20) : ((ULONG)x) )
|
||||||
|
|
||||||
NTSTATUS FsdGetFileNameInformation(PVFATFCB pFcb,
|
NTSTATUS
|
||||||
PFILE_NAMES_INFORMATION pInfo,ULONG BufferLength)
|
VfatGetFileNameInformation (PVFATFCB pFcb,
|
||||||
|
PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength)
|
||||||
{
|
{
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length=vfat_wstrlen(pFcb->ObjectName);
|
Length = vfat_wstrlen (pFcb->ObjectName);
|
||||||
if( (sizeof(FILE_DIRECTORY_INFORMATION)+Length) >BufferLength)
|
if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength=Length;
|
pInfo->FileNameLength = Length;
|
||||||
pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION)+Length);
|
pInfo->NextEntryOffset =
|
||||||
memcpy(pInfo->FileName,pFcb->ObjectName
|
DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + Length);
|
||||||
,sizeof(WCHAR)*(pInfo->FileNameLength));
|
memcpy (pInfo->FileName, pFcb->ObjectName,
|
||||||
|
sizeof (WCHAR) * (pInfo->FileNameLength));
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetFileDirectoryInformation(PVFATFCB pFcb,
|
NTSTATUS
|
||||||
|
VfatGetFileDirectoryInformation (PVFATFCB pFcb,
|
||||||
PDEVICE_EXTENSION DeviceExt,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PFILE_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
|
PFILE_DIRECTORY_INFORMATION pInfo,
|
||||||
|
ULONG BufferLength)
|
||||||
{
|
{
|
||||||
unsigned long long AllocSize;
|
unsigned long long AllocSize;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length=vfat_wstrlen(pFcb->ObjectName);
|
Length = vfat_wstrlen (pFcb->ObjectName);
|
||||||
if( (sizeof(FILE_DIRECTORY_INFORMATION)+Length) >BufferLength)
|
if ((sizeof (FILE_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength=Length;
|
pInfo->FileNameLength = Length;
|
||||||
pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION)+Length);
|
pInfo->NextEntryOffset =
|
||||||
memcpy(pInfo->FileName,pFcb->ObjectName
|
DWORD_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + Length);
|
||||||
,sizeof(WCHAR)*(pInfo->FileNameLength));
|
memcpy (pInfo->FileName, pFcb->ObjectName,
|
||||||
|
sizeof (WCHAR) * (pInfo->FileNameLength));
|
||||||
// pInfo->FileIndex=;
|
// pInfo->FileIndex=;
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.CreationDate,pFcb->entry.CreationTime
|
FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
|
||||||
,&pInfo->CreationTime);
|
pFcb->entry.CreationTime, &pInfo->CreationTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.AccessDate,0
|
FsdDosDateTimeToFileTime (pFcb->entry.AccessDate, 0,
|
||||||
,&pInfo->LastAccessTime);
|
&pInfo->LastAccessTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
,&pInfo->LastWriteTime);
|
&pInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
,&pInfo->ChangeTime);
|
&pInfo->ChangeTime);
|
||||||
pInfo->EndOfFile=RtlConvertUlongToLargeInteger(pFcb->entry.FileSize);
|
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
|
AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
|
||||||
DeviceExt->BytesPerCluster) *
|
DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
|
||||||
DeviceExt->BytesPerCluster;
|
|
||||||
pInfo->AllocationSize.QuadPart = AllocSize;
|
pInfo->AllocationSize.QuadPart = AllocSize;
|
||||||
pInfo->FileAttributes=pFcb->entry.Attrib;
|
pInfo->FileAttributes = pFcb->entry.Attrib;
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetFileFullDirectoryInformation(PVFATFCB pFcb,
|
NTSTATUS
|
||||||
|
VfatGetFileFullDirectoryInformation (PVFATFCB pFcb,
|
||||||
PDEVICE_EXTENSION DeviceExt,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PFILE_FULL_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
|
PFILE_FULL_DIRECTORY_INFORMATION pInfo,
|
||||||
|
ULONG BufferLength)
|
||||||
{
|
{
|
||||||
unsigned long long AllocSize;
|
unsigned long long AllocSize;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length=vfat_wstrlen(pFcb->ObjectName);
|
Length = vfat_wstrlen (pFcb->ObjectName);
|
||||||
if( (sizeof(FILE_FULL_DIRECTORY_INFORMATION)+Length) >BufferLength)
|
if ((sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength=Length;
|
pInfo->FileNameLength = Length;
|
||||||
pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_FULL_DIRECTORY_INFORMATION)+Length);
|
pInfo->NextEntryOffset =
|
||||||
memcpy(pInfo->FileName,pFcb->ObjectName
|
DWORD_ROUND_UP (sizeof (FILE_FULL_DIRECTORY_INFORMATION) + Length);
|
||||||
,sizeof(WCHAR)*(pInfo->FileNameLength));
|
memcpy (pInfo->FileName, pFcb->ObjectName,
|
||||||
|
sizeof (WCHAR) * (pInfo->FileNameLength));
|
||||||
// pInfo->FileIndex=;
|
// pInfo->FileIndex=;
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.CreationDate,pFcb->entry.CreationTime
|
FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
|
||||||
,&pInfo->CreationTime);
|
pFcb->entry.CreationTime, &pInfo->CreationTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.AccessDate,0
|
FsdDosDateTimeToFileTime (pFcb->entry.AccessDate, 0,
|
||||||
,&pInfo->LastAccessTime);
|
&pInfo->LastAccessTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
,&pInfo->LastWriteTime);
|
&pInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
,&pInfo->ChangeTime);
|
&pInfo->ChangeTime);
|
||||||
pInfo->EndOfFile=RtlConvertUlongToLargeInteger(pFcb->entry.FileSize);
|
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
|
AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
|
||||||
DeviceExt->BytesPerCluster) *
|
DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
|
||||||
DeviceExt->BytesPerCluster;
|
|
||||||
pInfo->AllocationSize.QuadPart = AllocSize;
|
pInfo->AllocationSize.QuadPart = AllocSize;
|
||||||
pInfo->FileAttributes=pFcb->entry.Attrib;
|
pInfo->FileAttributes = pFcb->entry.Attrib;
|
||||||
// pInfo->EaSize=;
|
// pInfo->EaSize=;
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetFileBothInformation(PVFATFCB pFcb,
|
NTSTATUS
|
||||||
|
VfatGetFileBothInformation (PVFATFCB pFcb,
|
||||||
PDEVICE_EXTENSION DeviceExt,
|
PDEVICE_EXTENSION DeviceExt,
|
||||||
PFILE_BOTH_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
|
PFILE_BOTH_DIRECTORY_INFORMATION pInfo,
|
||||||
|
ULONG BufferLength)
|
||||||
{
|
{
|
||||||
short i;
|
short i;
|
||||||
unsigned long long AllocSize;
|
unsigned long long AllocSize;
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
Length=vfat_wstrlen(pFcb->ObjectName);
|
Length = vfat_wstrlen (pFcb->ObjectName);
|
||||||
if( (sizeof(FILE_BOTH_DIRECTORY_INFORMATION)+Length) >BufferLength)
|
if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||||
return STATUS_BUFFER_OVERFLOW;
|
return STATUS_BUFFER_OVERFLOW;
|
||||||
pInfo->FileNameLength=Length;
|
pInfo->FileNameLength = Length;
|
||||||
pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION)+Length);
|
pInfo->NextEntryOffset =
|
||||||
memcpy(pInfo->FileName,pFcb->ObjectName
|
DWORD_ROUND_UP (sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length);
|
||||||
,sizeof(WCHAR)*(pInfo->FileNameLength));
|
memcpy (pInfo->FileName, pFcb->ObjectName,
|
||||||
|
sizeof (WCHAR) * (pInfo->FileNameLength));
|
||||||
// pInfo->FileIndex=;
|
// pInfo->FileIndex=;
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.CreationDate,pFcb->entry.CreationTime
|
FsdDosDateTimeToFileTime (pFcb->entry.CreationDate,
|
||||||
,&pInfo->CreationTime);
|
pFcb->entry.CreationTime, &pInfo->CreationTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.AccessDate,0
|
FsdDosDateTimeToFileTime (pFcb->entry.AccessDate, 0,
|
||||||
,&pInfo->LastAccessTime);
|
&pInfo->LastAccessTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
,&pInfo->LastWriteTime);
|
&pInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
|
FsdDosDateTimeToFileTime (pFcb->entry.UpdateDate, pFcb->entry.UpdateTime,
|
||||||
,&pInfo->ChangeTime);
|
&pInfo->ChangeTime);
|
||||||
pInfo->EndOfFile=RtlConvertUlongToLargeInteger(pFcb->entry.FileSize);
|
pInfo->EndOfFile = RtlConvertUlongToLargeInteger (pFcb->entry.FileSize);
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
|
AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
|
||||||
DeviceExt->BytesPerCluster) *
|
DeviceExt->BytesPerCluster) * DeviceExt->BytesPerCluster;
|
||||||
DeviceExt->BytesPerCluster;
|
|
||||||
pInfo->AllocationSize.QuadPart = AllocSize;
|
pInfo->AllocationSize.QuadPart = AllocSize;
|
||||||
pInfo->FileAttributes=pFcb->entry.Attrib;
|
pInfo->FileAttributes = pFcb->entry.Attrib;
|
||||||
// pInfo->EaSize=;
|
// pInfo->EaSize=;
|
||||||
for (i=0;i<8 && (pFcb->entry.Filename[i]!=' ') ;i++)
|
for (i = 0; i < 8 && (pFcb->entry.Filename[i] != ' '); i++)
|
||||||
pInfo->ShortName[i]=pFcb->entry.Filename[i];
|
pInfo->ShortName[i] = pFcb->entry.Filename[i];
|
||||||
pInfo->ShortNameLength=i;
|
pInfo->ShortNameLength = i;
|
||||||
pInfo->ShortName[i]='.';
|
pInfo->ShortName[i] = '.';
|
||||||
for (i=0 ;i<3 && (pFcb->entry.Ext[i]!=' ') ;i++)
|
for (i = 0; i < 3 && (pFcb->entry.Ext[i] != ' '); i++)
|
||||||
pInfo->ShortName[i+1+pInfo->ShortNameLength]=pFcb->entry.Ext[i];
|
pInfo->ShortName[i + 1 + pInfo->ShortNameLength] = pFcb->entry.Ext[i];
|
||||||
if(i) pInfo->ShortNameLength += (i+1);
|
if (i)
|
||||||
|
pInfo->ShortNameLength += (i + 1);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS DoQuery(PDEVICE_OBJECT DeviceObject, PIRP Irp,PIO_STACK_LOCATION Stack)
|
NTSTATUS
|
||||||
|
DoQuery (PDEVICE_OBJECT DeviceObject, PIRP Irp, PIO_STACK_LOCATION Stack)
|
||||||
{
|
{
|
||||||
NTSTATUS RC=STATUS_SUCCESS;
|
NTSTATUS RC = STATUS_SUCCESS;
|
||||||
long BufferLength = 0;
|
long BufferLength = 0;
|
||||||
PUNICODE_STRING pSearchPattern = NULL;
|
PUNICODE_STRING pSearchPattern = NULL;
|
||||||
FILE_INFORMATION_CLASS FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass;
|
||||||
|
@ -224,92 +238,111 @@ NTSTATUS DoQuery(PDEVICE_OBJECT DeviceObject, PIRP Irp,PIO_STACK_LOCATION Stack)
|
||||||
VFATFCB tmpFcb;
|
VFATFCB tmpFcb;
|
||||||
PVFATCCB pCcb;
|
PVFATCCB pCcb;
|
||||||
PDEVICE_EXTENSION DeviceExt;
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
WCHAR star[5],*pCharPattern;
|
WCHAR star[5], *pCharPattern;
|
||||||
unsigned long OldEntry,OldSector;
|
unsigned long OldEntry, OldSector;
|
||||||
DeviceExt = DeviceObject->DeviceExtension;
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
// Obtain the callers parameters
|
// Obtain the callers parameters
|
||||||
BufferLength = Stack->Parameters.QueryDirectory.Length;
|
BufferLength = Stack->Parameters.QueryDirectory.Length;
|
||||||
pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
|
pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
|
||||||
FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
|
FileInformationClass =
|
||||||
|
Stack->Parameters.QueryDirectory.FileInformationClass;
|
||||||
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
|
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
|
||||||
pFileObject = Stack->FileObject;
|
pFileObject = Stack->FileObject;
|
||||||
pCcb =(PVFATCCB)pFileObject->FsContext2;
|
pCcb = (PVFATCCB) pFileObject->FsContext2;
|
||||||
pFcb = pCcb->pFcb;
|
pFcb = pCcb->pFcb;
|
||||||
if(Stack->Flags & SL_RESTART_SCAN)
|
if (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 (Irp->MdlAddress)
|
||||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
else
|
else
|
||||||
Buffer = Irp->UserBuffer;
|
Buffer = 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)
|
||||||
{
|
{
|
||||||
star[0]='*';
|
star[0] = '*';
|
||||||
star[1]=0;
|
star[1] = 0;
|
||||||
pCharPattern=star;
|
pCharPattern = star;
|
||||||
}
|
}
|
||||||
else pCharPattern=pSearchPattern->Buffer;
|
else
|
||||||
tmpFcb.ObjectName=tmpFcb.PathName;
|
pCharPattern = pSearchPattern->Buffer;
|
||||||
while(RC==STATUS_SUCCESS && BufferLength >0)
|
tmpFcb.ObjectName = tmpFcb.PathName;
|
||||||
|
while (RC == STATUS_SUCCESS && BufferLength > 0)
|
||||||
{
|
{
|
||||||
OldSector=pCcb->StartSector;
|
OldSector = pCcb->StartSector;
|
||||||
OldEntry=pCcb->StartEntry;
|
OldEntry = pCcb->StartEntry;
|
||||||
if(OldSector)pCcb->StartEntry++;
|
if (OldSector)
|
||||||
RC=FindFile(DeviceExt,&tmpFcb,pFcb,pCharPattern,&pCcb->StartSector,&pCcb->StartEntry);
|
pCcb->StartEntry++;
|
||||||
DPRINT("Found %S,RC=%x, sector %x entry %x\n",tmpFcb.ObjectName,RC
|
RC =
|
||||||
,pCcb->StartSector,pCcb->StartEntry);
|
FindFile (DeviceExt, &tmpFcb, pFcb, pCharPattern, &pCcb->StartSector,
|
||||||
if (NT_SUCCESS(RC))
|
&pCcb->StartEntry);
|
||||||
|
DPRINT ("Found %S,RC=%x, sector %x entry %x\n", tmpFcb.ObjectName, RC,
|
||||||
|
pCcb->StartSector, pCcb->StartEntry);
|
||||||
|
if (NT_SUCCESS (RC))
|
||||||
{
|
{
|
||||||
switch(FileInformationClass)
|
switch (FileInformationClass)
|
||||||
{
|
{
|
||||||
case FileNameInformation:
|
case FileNameInformation:
|
||||||
RC=FsdGetFileNameInformation(&tmpFcb
|
RC =
|
||||||
,(PFILE_NAMES_INFORMATION)Buffer,BufferLength);
|
VfatGetFileNameInformation (&tmpFcb,
|
||||||
|
(PFILE_NAMES_INFORMATION) Buffer,
|
||||||
|
BufferLength);
|
||||||
break;
|
break;
|
||||||
case FileDirectoryInformation:
|
case FileDirectoryInformation:
|
||||||
RC= FsdGetFileDirectoryInformation(&tmpFcb
|
RC =
|
||||||
,DeviceExt,(PFILE_DIRECTORY_INFORMATION)Buffer,BufferLength);
|
VfatGetFileDirectoryInformation (&tmpFcb, DeviceExt,
|
||||||
|
(PFILE_DIRECTORY_INFORMATION)
|
||||||
|
Buffer, BufferLength);
|
||||||
break;
|
break;
|
||||||
case FileFullDirectoryInformation :
|
case FileFullDirectoryInformation:
|
||||||
RC= FsdGetFileFullDirectoryInformation(&tmpFcb
|
RC =
|
||||||
,DeviceExt,(PFILE_FULL_DIRECTORY_INFORMATION)Buffer,BufferLength);
|
VfatGetFileFullDirectoryInformation (&tmpFcb, DeviceExt,
|
||||||
|
(PFILE_FULL_DIRECTORY_INFORMATION)
|
||||||
|
Buffer, BufferLength);
|
||||||
break;
|
break;
|
||||||
case FileBothDirectoryInformation :
|
case FileBothDirectoryInformation:
|
||||||
RC=FsdGetFileBothInformation(&tmpFcb
|
RC =
|
||||||
,DeviceExt,(PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,BufferLength);
|
VfatGetFileBothInformation (&tmpFcb, DeviceExt,
|
||||||
|
(PFILE_BOTH_DIRECTORY_INFORMATION)
|
||||||
|
Buffer, BufferLength);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
RC=STATUS_INVALID_INFO_CLASS;
|
RC = STATUS_INVALID_INFO_CLASS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(Buffer0) Buffer0->NextEntryOffset=0;
|
if (Buffer0)
|
||||||
|
Buffer0->NextEntryOffset = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(RC==STATUS_BUFFER_OVERFLOW)
|
if (RC == STATUS_BUFFER_OVERFLOW)
|
||||||
{
|
{
|
||||||
if(Buffer0) Buffer0->NextEntryOffset=0;
|
if (Buffer0)
|
||||||
pCcb->StartSector=OldSector;
|
Buffer0->NextEntryOffset = 0;
|
||||||
pCcb->StartEntry=OldEntry;
|
pCcb->StartSector = OldSector;
|
||||||
|
pCcb->StartEntry = OldEntry;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Buffer0=(PFILE_NAMES_INFORMATION)Buffer;
|
Buffer0 = (PFILE_NAMES_INFORMATION) Buffer;
|
||||||
Buffer0->FileIndex=FileIndex++;
|
Buffer0->FileIndex = FileIndex++;
|
||||||
if(Stack->Flags & SL_RETURN_SINGLE_ENTRY) break;
|
if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
|
||||||
|
break;
|
||||||
BufferLength -= Buffer0->NextEntryOffset;
|
BufferLength -= Buffer0->NextEntryOffset;
|
||||||
Buffer += Buffer0->NextEntryOffset;
|
Buffer += Buffer0->NextEntryOffset;
|
||||||
}
|
}
|
||||||
if(Buffer0) Buffer0->NextEntryOffset=0;
|
if (Buffer0)
|
||||||
if(FileIndex>0) return STATUS_SUCCESS;
|
Buffer0->NextEntryOffset = 0;
|
||||||
|
if (FileIndex > 0)
|
||||||
|
return STATUS_SUCCESS;
|
||||||
return RC;
|
return RC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatDirectoryControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: directory control : read/write directory informations
|
* FUNCTION: directory control : read/write directory informations
|
||||||
*/
|
*/
|
||||||
|
@ -317,28 +350,28 @@ NTSTATUS STDCALL FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
NTSTATUS RC = STATUS_SUCCESS;
|
NTSTATUS RC = STATUS_SUCCESS;
|
||||||
PFILE_OBJECT FileObject = NULL;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
PIO_STACK_LOCATION Stack;
|
PIO_STACK_LOCATION Stack;
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
switch (Stack->MinorFunction)
|
switch (Stack->MinorFunction)
|
||||||
{
|
{
|
||||||
case IRP_MN_QUERY_DIRECTORY:
|
case IRP_MN_QUERY_DIRECTORY:
|
||||||
RC=DoQuery(DeviceObject,Irp,Stack);
|
RC = DoQuery (DeviceObject, Irp, Stack);
|
||||||
break;
|
break;
|
||||||
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
|
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
|
||||||
DPRINT(" vfat, dir : change\n");
|
DPRINT (" vfat, dir : change\n");
|
||||||
RC=STATUS_NOT_IMPLEMENTED;
|
RC = STATUS_NOT_IMPLEMENTED;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// error
|
// error
|
||||||
DbgPrint("unexpected minor function %x in VFAT driver\n",Stack->MinorFunction);
|
DbgPrint ("unexpected minor function %x in VFAT driver\n",
|
||||||
|
Stack->MinorFunction);
|
||||||
RC = STATUS_INVALID_DEVICE_REQUEST;
|
RC = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Irp->IoStatus.Status = RC;
|
Irp->IoStatus.Status = RC;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
return RC;
|
return RC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dirwr.c,v 1.13 2000/06/29 23:35:50 dwelch Exp $
|
/* $Id: dirwr.c,v 1.14 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -26,7 +26,7 @@
|
||||||
* from complaining.
|
* from complaining.
|
||||||
*/
|
*/
|
||||||
static VOID
|
static VOID
|
||||||
FillSlot (slot *Slot, WCHAR *FileName)
|
FillSlot (slot * Slot, WCHAR * FileName)
|
||||||
{
|
{
|
||||||
BOOLEAN fill = FALSE;
|
BOOLEAN fill = FALSE;
|
||||||
WCHAR *src = FileName;
|
WCHAR *src = FileName;
|
||||||
|
@ -80,372 +80,382 @@ FillSlot (slot *Slot, WCHAR *FileName)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject)
|
NTSTATUS updEntry (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT pFileObject)
|
||||||
/*
|
/*
|
||||||
update an existing FAT entry
|
update an existing FAT entry
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
WCHAR DirName[MAX_PATH],*FileName,*PathFileName;
|
WCHAR DirName[MAX_PATH], *FileName, *PathFileName;
|
||||||
VFATFCB FileFcb;
|
VFATFCB FileFcb;
|
||||||
ULONG Sector=0,Entry=0;
|
ULONG Sector = 0, Entry = 0;
|
||||||
PUCHAR Buffer;
|
PUCHAR Buffer;
|
||||||
FATDirEntry * pEntries;
|
FATDirEntry *pEntries;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
FILE_OBJECT FileObject;
|
FILE_OBJECT FileObject;
|
||||||
PVFATCCB pDirCcb;
|
PVFATCCB pDirCcb;
|
||||||
PVFATFCB pDirFcb,pFcb;
|
PVFATFCB pDirFcb, pFcb;
|
||||||
short i,posCar,NameLen;
|
short i, posCar, NameLen;
|
||||||
|
|
||||||
PathFileName=pFileObject->FileName.Buffer;
|
PathFileName = pFileObject->FileName.Buffer;
|
||||||
pFcb=((PVFATCCB)pFileObject->FsContext2)->pFcb;
|
pFcb = ((PVFATCCB) pFileObject->FsContext2)->pFcb;
|
||||||
DPRINT("PathFileName \'%S\'\n", PathFileName);
|
DPRINT ("PathFileName \'%S\'\n", PathFileName);
|
||||||
|
|
||||||
//find last \ in PathFileName
|
//find last \ in PathFileName
|
||||||
posCar=-1;
|
posCar = -1;
|
||||||
for(i=0;PathFileName[i];i++)
|
for (i = 0; PathFileName[i]; i++)
|
||||||
if(PathFileName[i]=='\\')posCar=i;
|
if (PathFileName[i] == '\\')
|
||||||
if(posCar==-1)
|
posCar = i;
|
||||||
|
if (posCar == -1)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
FileName=&PathFileName[posCar+1];
|
FileName = &PathFileName[posCar + 1];
|
||||||
for(NameLen=0;FileName[NameLen];NameLen++);
|
for (NameLen = 0; FileName[NameLen]; NameLen++);
|
||||||
|
|
||||||
// extract directory name from pathname
|
// extract directory name from pathname
|
||||||
if( posCar == 0 )
|
if (posCar == 0)
|
||||||
{
|
{
|
||||||
// root dir
|
// root dir
|
||||||
DirName[0] = L'\\';
|
DirName[0] = L'\\';
|
||||||
DirName[1] = 0;
|
DirName[1] = 0;
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
memcpy(DirName,PathFileName,posCar*sizeof(WCHAR));
|
{
|
||||||
DirName[posCar]=0;
|
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
|
||||||
|
DirName[posCar] = 0;
|
||||||
}
|
}
|
||||||
if(FileName[0]==0 && DirName[0]==0)
|
if (FileName[0] == 0 && DirName[0] == 0)
|
||||||
return STATUS_SUCCESS;//root : nothing to do ?
|
return STATUS_SUCCESS; //root : nothing to do ?
|
||||||
memset(&FileObject,0,sizeof(FILE_OBJECT));
|
memset (&FileObject, 0, sizeof (FILE_OBJECT));
|
||||||
DPRINT("open directory \'%S\' for update of entry \'%S\'\n",DirName,FileName);
|
DPRINT ("open directory \'%S\' for update of entry \'%S\'\n", DirName,
|
||||||
status=FsdOpenFile(DeviceExt,&FileObject,DirName);
|
FileName);
|
||||||
if (!NT_SUCCESS(status))
|
status = FsdOpenFile (DeviceExt, &FileObject, DirName);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
DbgPrint ("Failed to open \'%S\'. Status %lx\n", DirName, status);
|
DbgPrint ("Failed to open \'%S\'. Status %lx\n", DirName, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
pDirCcb=(PVFATCCB)FileObject.FsContext2;
|
pDirCcb = (PVFATCCB) FileObject.FsContext2;
|
||||||
assert(pDirCcb);
|
assert (pDirCcb);
|
||||||
pDirFcb=pDirCcb->pFcb;
|
pDirFcb = pDirCcb->pFcb;
|
||||||
assert(pDirFcb);
|
assert (pDirFcb);
|
||||||
FileFcb.ObjectName=&FileFcb.PathName[0];
|
FileFcb.ObjectName = &FileFcb.PathName[0];
|
||||||
status=FindFile(DeviceExt,&FileFcb,pDirFcb,FileName,&Sector,&Entry);
|
status = FindFile (DeviceExt, &FileFcb, pDirFcb, FileName, &Sector, &Entry);
|
||||||
if(NT_SUCCESS(status))
|
if (NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
Buffer=ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
Buffer = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
||||||
DPRINT("update entry: sector %d, entry %d\n",Sector,Entry);
|
DPRINT ("update entry: sector %d, entry %d\n", Sector, Entry);
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,Sector,1,Buffer);
|
VFATReadSectors (DeviceExt->StorageDevice, Sector, 1, Buffer);
|
||||||
pEntries=(FATDirEntry *)Buffer;
|
pEntries = (FATDirEntry *) Buffer;
|
||||||
memcpy(&pEntries[Entry],&pFcb->entry,sizeof(FATDirEntry));
|
memcpy (&pEntries[Entry], &pFcb->entry, sizeof (FATDirEntry));
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,Sector,1,Buffer);
|
VFATWriteSectors (DeviceExt->StorageDevice, Sector, 1, Buffer);
|
||||||
ExFreePool(Buffer);
|
ExFreePool (Buffer);
|
||||||
}
|
}
|
||||||
FsdCloseFile(DeviceExt,&FileObject);
|
VfatCloseFile (DeviceExt, &FileObject);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS addEntry(PDEVICE_EXTENSION DeviceExt,
|
NTSTATUS
|
||||||
PFILE_OBJECT pFileObject,
|
addEntry (PDEVICE_EXTENSION DeviceExt,
|
||||||
ULONG RequestedOptions,
|
PFILE_OBJECT pFileObject, ULONG RequestedOptions, UCHAR ReqAttr)
|
||||||
UCHAR ReqAttr)
|
|
||||||
/*
|
/*
|
||||||
create a new FAT entry
|
create a new FAT entry
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
WCHAR DirName[MAX_PATH],*FileName,*PathFileName;
|
WCHAR DirName[MAX_PATH], *FileName, *PathFileName;
|
||||||
VFATFCB DirFcb,FileFcb;
|
VFATFCB DirFcb, FileFcb;
|
||||||
FATDirEntry FatEntry;
|
FATDirEntry FatEntry;
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
FILE_OBJECT FileObject;
|
FILE_OBJECT FileObject;
|
||||||
FATDirEntry *pEntry;
|
FATDirEntry *pEntry;
|
||||||
slot *pSlots;
|
slot *pSlots;
|
||||||
ULONG LengthRead,Offset;
|
ULONG LengthRead, Offset;
|
||||||
short nbSlots=0,nbFree=0,i,j,posCar,NameLen;
|
short nbSlots = 0, nbFree = 0, i, j, posCar, NameLen;
|
||||||
PUCHAR Buffer,Buffer2;
|
PUCHAR Buffer, Buffer2;
|
||||||
BOOLEAN needTilde=FALSE,needLong=FALSE;
|
BOOLEAN needTilde = FALSE, needLong = FALSE;
|
||||||
PVFATFCB newFCB;
|
PVFATFCB newFCB;
|
||||||
PVFATCCB newCCB;
|
PVFATCCB newCCB;
|
||||||
ULONG CurrentCluster;
|
ULONG CurrentCluster;
|
||||||
KIRQL oldIrql;
|
KIRQL oldIrql;
|
||||||
LARGE_INTEGER SystemTime, LocalTime;
|
LARGE_INTEGER SystemTime, LocalTime;
|
||||||
|
|
||||||
PathFileName=pFileObject->FileName.Buffer;
|
PathFileName = pFileObject->FileName.Buffer;
|
||||||
DPRINT("addEntry: Pathname=%S\n",PathFileName);
|
DPRINT ("addEntry: Pathname=%S\n", PathFileName);
|
||||||
//find last \ in PathFileName
|
//find last \ in PathFileName
|
||||||
posCar=-1;
|
posCar = -1;
|
||||||
for(i=0;PathFileName[i];i++)
|
for (i = 0; PathFileName[i]; i++)
|
||||||
if(PathFileName[i]=='\\')posCar=i;
|
if (PathFileName[i] == '\\')
|
||||||
if(posCar==-1)
|
posCar = i;
|
||||||
|
if (posCar == -1)
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
FileName=&PathFileName[posCar+1];
|
FileName = &PathFileName[posCar + 1];
|
||||||
for(NameLen=0;FileName[NameLen];NameLen++);
|
for (NameLen = 0; FileName[NameLen]; NameLen++);
|
||||||
// extract directory name from pathname
|
// extract directory name from pathname
|
||||||
memcpy(DirName,PathFileName,posCar*sizeof(WCHAR));
|
memcpy (DirName, PathFileName, posCar * sizeof (WCHAR));
|
||||||
DirName[posCar]=0;
|
DirName[posCar] = 0;
|
||||||
// open parent directory
|
// open parent directory
|
||||||
memset(&FileObject,0,sizeof(FILE_OBJECT));
|
memset (&FileObject, 0, sizeof (FILE_OBJECT));
|
||||||
status=FsdOpenFile(DeviceExt,&FileObject,DirName);
|
status = FsdOpenFile (DeviceExt, &FileObject, DirName);
|
||||||
nbSlots=(NameLen+12)/13+1;//nb of entry needed for long name+normal entry
|
nbSlots = (NameLen + 12) / 13 + 1; //nb of entry needed for long name+normal entry
|
||||||
DPRINT("NameLen= %d, nbSlots =%d\n",NameLen,nbSlots);
|
DPRINT ("NameLen= %d, nbSlots =%d\n", NameLen, nbSlots);
|
||||||
Buffer=ExAllocatePool(NonPagedPool,(nbSlots+1)*sizeof(FATDirEntry));
|
Buffer =
|
||||||
memset(Buffer,0,(nbSlots+1)*sizeof(FATDirEntry));
|
ExAllocatePool (NonPagedPool, (nbSlots + 1) * sizeof (FATDirEntry));
|
||||||
pEntry=(FATDirEntry *)(Buffer+(nbSlots-1)*sizeof(FATDirEntry));
|
memset (Buffer, 0, (nbSlots + 1) * sizeof (FATDirEntry));
|
||||||
pSlots=(slot *)Buffer;
|
pEntry = (FATDirEntry *) (Buffer + (nbSlots - 1) * sizeof (FATDirEntry));
|
||||||
|
pSlots = (slot *) Buffer;
|
||||||
// create 8.3 name
|
// create 8.3 name
|
||||||
needTilde=FALSE;
|
needTilde = FALSE;
|
||||||
// find last point in name
|
// find last point in name
|
||||||
posCar=0;
|
posCar = 0;
|
||||||
for(i=0;FileName[i];i++)
|
for (i = 0; FileName[i]; i++)
|
||||||
if(FileName[i]=='.')posCar=i;
|
if (FileName[i] == '.')
|
||||||
if(!posCar) posCar=i;
|
posCar = i;
|
||||||
if(posCar>8) needTilde=TRUE;
|
if (!posCar)
|
||||||
|
posCar = i;
|
||||||
|
if (posCar > 8)
|
||||||
|
needTilde = TRUE;
|
||||||
//copy 8 characters max
|
//copy 8 characters max
|
||||||
memset(pEntry,' ',11);
|
memset (pEntry, ' ', 11);
|
||||||
for(i=0,j=0;j<8 && i<posCar;i++)
|
for (i = 0, j = 0; j < 8 && i < posCar; i++)
|
||||||
{
|
{
|
||||||
//FIXME : is there other characters to ignore ?
|
//FIXME : is there other characters to ignore ?
|
||||||
if( FileName[i]!='.'
|
if (FileName[i] != '.'
|
||||||
&& FileName[i]!=' '
|
&& FileName[i] != ' '
|
||||||
&& FileName[i]!='+'
|
&& FileName[i] != '+'
|
||||||
&& FileName[i]!=','
|
&& FileName[i] != ','
|
||||||
&& FileName[i]!=';'
|
&& FileName[i] != ';'
|
||||||
&& FileName[i]!='='
|
&& FileName[i] != '=' && FileName[i] != '[' && FileName[i] != ']')
|
||||||
&& FileName[i]!='['
|
pEntry->Filename[j++] = toupper ((char) FileName[i]);
|
||||||
&& FileName[i]!=']'
|
|
||||||
)
|
|
||||||
pEntry->Filename[j++]=toupper((char) FileName[i]);
|
|
||||||
else
|
else
|
||||||
needTilde=TRUE;
|
needTilde = TRUE;
|
||||||
}
|
}
|
||||||
//copy extension
|
//copy extension
|
||||||
if(FileName[posCar])
|
if (FileName[posCar])
|
||||||
for(j=0,i=posCar+1;FileName[i] && i<posCar+4;i++)
|
for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
|
||||||
{
|
{
|
||||||
pEntry->Ext[j++]=toupper((char)( FileName[i] &0x7F));
|
pEntry->Ext[j++] = toupper ((char) (FileName[i] & 0x7F));
|
||||||
}
|
}
|
||||||
if(FileName[i])
|
if (FileName[i])
|
||||||
needTilde=TRUE;
|
needTilde = TRUE;
|
||||||
//find good value for tilde
|
//find good value for tilde
|
||||||
if(needTilde)
|
if (needTilde)
|
||||||
{
|
{
|
||||||
needLong=TRUE;
|
needLong = TRUE;
|
||||||
DPRINT("searching a good value for tilde\n");
|
DPRINT ("searching a good value for tilde\n");
|
||||||
for(i=0;i<6;i++)
|
for (i = 0; i < 6; i++)
|
||||||
DirName[i]=pEntry->Filename[i];
|
DirName[i] = pEntry->Filename[i];
|
||||||
for(i=0;i<3;i++)
|
for (i = 0; i < 3; i++)
|
||||||
DirName[i+8]=pEntry->Ext[i];
|
DirName[i + 8] = pEntry->Ext[i];
|
||||||
//try first with xxxxxx~y.zzz
|
//try first with xxxxxx~y.zzz
|
||||||
DirName[6]='~';
|
DirName[6] = '~';
|
||||||
pEntry->Filename[6]='~';
|
pEntry->Filename[6] = '~';
|
||||||
DirName[8]='.';
|
DirName[8] = '.';
|
||||||
DirName[12]=0;
|
DirName[12] = 0;
|
||||||
for(i=1;i<9;i++)
|
for (i = 1; i < 9; i++)
|
||||||
{
|
{
|
||||||
DirName[7]='0'+i;
|
DirName[7] = '0' + i;
|
||||||
pEntry->Filename[7]='0'+i;
|
pEntry->Filename[7] = '0' + i;
|
||||||
status=FindFile(DeviceExt,&FileFcb
|
status =
|
||||||
,&DirFcb,DirName,NULL,NULL);
|
FindFile (DeviceExt, &FileFcb, &DirFcb, DirName, NULL, NULL);
|
||||||
if(status!=STATUS_SUCCESS)break;
|
if (status != STATUS_SUCCESS)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
//try second with xxxxx~yy.zzz
|
//try second with xxxxx~yy.zzz
|
||||||
if(i==10)
|
if (i == 10)
|
||||||
{
|
{
|
||||||
DirName[5]='~';
|
DirName[5] = '~';
|
||||||
for( ;i<99;i++)
|
for (; i < 99; i++)
|
||||||
{
|
{
|
||||||
DirName[7]='0'+i;
|
DirName[7] = '0' + i;
|
||||||
pEntry->Filename[7]='0'+i;
|
pEntry->Filename[7] = '0' + i;
|
||||||
status=FindFile(DeviceExt,&FileFcb
|
status =
|
||||||
,&DirFcb,DirName,NULL,NULL);
|
FindFile (DeviceExt, &FileFcb, &DirFcb, DirName, NULL, NULL);
|
||||||
if(status!=STATUS_SUCCESS)break;
|
if (status != STATUS_SUCCESS)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(i==100)//FIXME : what to do after 99 tilde ?
|
if (i == 100) //FIXME : what to do after 99 tilde ?
|
||||||
{
|
{
|
||||||
FsdCloseFile(DeviceExt,&FileObject);
|
VfatCloseFile (DeviceExt, &FileObject);
|
||||||
ExFreePool(Buffer);
|
ExFreePool (Buffer);
|
||||||
return STATUS_UNSUCCESSFUL;
|
return STATUS_UNSUCCESSFUL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("check if long name entry needed, needlong=%d\n",needLong);
|
DPRINT ("check if long name entry needed, needlong=%d\n", needLong);
|
||||||
for(i=0;i<posCar;i++)
|
for (i = 0; i < posCar; i++)
|
||||||
if((USHORT)pEntry->Filename[i]!=FileName[i])
|
if ((USHORT) pEntry->Filename[i] != FileName[i])
|
||||||
{
|
{
|
||||||
DPRINT("i=%d,%d,%d\n",i,pEntry->Filename[i],FileName[i]);
|
DPRINT ("i=%d,%d,%d\n", i, pEntry->Filename[i], FileName[i]);
|
||||||
needLong=TRUE;
|
needLong = TRUE;
|
||||||
}
|
}
|
||||||
if(FileName[i])
|
if (FileName[i])
|
||||||
{
|
{
|
||||||
i++;//jump on point char
|
i++; //jump on point char
|
||||||
for(j=0,i=posCar+1;FileName[i] && i<posCar+4;i++)
|
for (j = 0, i = posCar + 1; FileName[i] && i < posCar + 4; i++)
|
||||||
if((USHORT)pEntry->Ext[j++]!= FileName[i])
|
if ((USHORT) pEntry->Ext[j++] != FileName[i])
|
||||||
{
|
{
|
||||||
DPRINT("i=%d,j=%d,%d,%d\n",i,j,pEntry->Filename[i],FileName[i]);
|
DPRINT ("i=%d,j=%d,%d,%d\n", i, j, pEntry->Filename[i],
|
||||||
needLong=TRUE;
|
FileName[i]);
|
||||||
|
needLong = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(needLong==FALSE)
|
if (needLong == FALSE)
|
||||||
{
|
{
|
||||||
nbSlots=1;
|
nbSlots = 1;
|
||||||
memcpy(Buffer,pEntry,sizeof(FATDirEntry));
|
memcpy (Buffer, pEntry, sizeof (FATDirEntry));
|
||||||
memset(pEntry,0,sizeof(FATDirEntry));
|
memset (pEntry, 0, sizeof (FATDirEntry));
|
||||||
pEntry=(FATDirEntry *)Buffer;
|
pEntry = (FATDirEntry *) Buffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memset(DirName,0xff,sizeof(DirName));
|
memset (DirName, 0xff, sizeof (DirName));
|
||||||
memcpy(DirName,FileName,NameLen*sizeof(WCHAR));
|
memcpy (DirName, FileName, NameLen * sizeof (WCHAR));
|
||||||
DirName[NameLen]=0;
|
DirName[NameLen] = 0;
|
||||||
}
|
}
|
||||||
DPRINT("dos name=%11.11s\n",pEntry->Filename);
|
DPRINT ("dos name=%11.11s\n", pEntry->Filename);
|
||||||
|
|
||||||
/* set attributes */
|
/* set attributes */
|
||||||
pEntry->Attrib=ReqAttr;
|
pEntry->Attrib = ReqAttr;
|
||||||
if(RequestedOptions&FILE_DIRECTORY_FILE)
|
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||||
pEntry->Attrib |= FILE_ATTRIBUTE_DIRECTORY;
|
pEntry->Attrib |= FILE_ATTRIBUTE_DIRECTORY;
|
||||||
|
|
||||||
/* set dates and times */
|
/* set dates and times */
|
||||||
KeQuerySystemTime (&SystemTime);
|
KeQuerySystemTime (&SystemTime);
|
||||||
ExSystemTimeToLocalTime (&SystemTime,
|
ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
|
||||||
&LocalTime);
|
FsdFileTimeToDosDateTime ((TIME *) & LocalTime,
|
||||||
FsdFileTimeToDosDateTime ((TIME*)&LocalTime,
|
&pEntry->CreationDate, &pEntry->CreationTime);
|
||||||
&pEntry->CreationDate,
|
|
||||||
&pEntry->CreationTime);
|
|
||||||
pEntry->UpdateDate = pEntry->CreationDate;
|
pEntry->UpdateDate = pEntry->CreationDate;
|
||||||
pEntry->UpdateTime = pEntry->CreationTime;
|
pEntry->UpdateTime = pEntry->CreationTime;
|
||||||
pEntry->AccessDate = pEntry->CreationDate;
|
pEntry->AccessDate = pEntry->CreationDate;
|
||||||
|
|
||||||
// calculate checksum for 8.3 name
|
// calculate checksum for 8.3 name
|
||||||
for(pSlots[0].alias_checksum=i=0;i<11;i++)
|
for (pSlots[0].alias_checksum = i = 0; i < 11; i++)
|
||||||
{
|
{
|
||||||
pSlots[0].alias_checksum=(((pSlots[0].alias_checksum&1)<<7
|
pSlots[0].alias_checksum = (((pSlots[0].alias_checksum & 1) << 7
|
||||||
|((pSlots[0].alias_checksum&0xfe)>>1))
|
| ((pSlots[0].alias_checksum & 0xfe) >> 1))
|
||||||
+pEntry->Filename[i]);
|
+ pEntry->Filename[i]);
|
||||||
}
|
}
|
||||||
//construct slots and entry
|
//construct slots and entry
|
||||||
for(i=nbSlots-2;i>=0;i--)
|
for (i = nbSlots - 2; i >= 0; i--)
|
||||||
{
|
{
|
||||||
DPRINT("construct slot %d\n",i);
|
DPRINT ("construct slot %d\n", i);
|
||||||
pSlots[i].attr=0xf;
|
pSlots[i].attr = 0xf;
|
||||||
if (i)
|
if (i)
|
||||||
pSlots[i].id=nbSlots-i-1;
|
pSlots[i].id = nbSlots - i - 1;
|
||||||
else
|
else
|
||||||
pSlots[i].id=nbSlots-i-1+0x40;
|
pSlots[i].id = nbSlots - i - 1 + 0x40;
|
||||||
pSlots[i].alias_checksum=pSlots[0].alias_checksum;
|
pSlots[i].alias_checksum = pSlots[0].alias_checksum;
|
||||||
//FIXME pSlots[i].start=;
|
//FIXME pSlots[i].start=;
|
||||||
FillSlot (&pSlots[i], FileName+(nbSlots-i-2)*13);
|
FillSlot (&pSlots[i], FileName + (nbSlots - i - 2) * 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
//try to find nbSlots contiguous entries frees in directory
|
//try to find nbSlots contiguous entries frees in directory
|
||||||
for(i=0,status=STATUS_SUCCESS;status==STATUS_SUCCESS;i++)
|
for (i = 0, status = STATUS_SUCCESS; status == STATUS_SUCCESS; i++)
|
||||||
{
|
{
|
||||||
status=FsdReadFile(DeviceExt,&FileObject,&FatEntry
|
status =
|
||||||
,sizeof(FATDirEntry),i*sizeof(FATDirEntry),&LengthRead);
|
VfatReadFile (DeviceExt, &FileObject, &FatEntry, sizeof (FATDirEntry),
|
||||||
if( status == STATUS_END_OF_FILE )
|
i * sizeof (FATDirEntry), &LengthRead);
|
||||||
|
if (status == STATUS_END_OF_FILE)
|
||||||
break;
|
break;
|
||||||
if( !NT_SUCCESS( status ) )
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
DPRINT1( "FsdReadFile failed to read the directory entry\n" );
|
DPRINT1 ("VfatReadFile failed to read the directory entry\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if( LengthRead != sizeof( FATDirEntry ) )
|
if (LengthRead != sizeof (FATDirEntry))
|
||||||
{
|
{
|
||||||
DPRINT1( "FsdReadFile did not read a complete directory entry\n" );
|
DPRINT1 ("VfatReadFile did not read a complete directory entry\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(IsDeletedEntry(&FatEntry,0))
|
if (IsDeletedEntry (&FatEntry, 0))
|
||||||
nbFree++;
|
nbFree++;
|
||||||
else
|
else
|
||||||
nbFree=0;
|
nbFree = 0;
|
||||||
|
|
||||||
if (nbFree==nbSlots)
|
if (nbFree == nbSlots)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DPRINT("nbSlots %d nbFree %d, entry number %d\n",nbSlots,nbFree,i);
|
DPRINT ("nbSlots %d nbFree %d, entry number %d\n", nbSlots, nbFree, i);
|
||||||
|
|
||||||
if(RequestedOptions&FILE_DIRECTORY_FILE)
|
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||||
{
|
{
|
||||||
CurrentCluster=GetNextWriteCluster(DeviceExt,0);
|
CurrentCluster = GetNextWriteCluster (DeviceExt, 0);
|
||||||
// zero the cluster
|
// zero the cluster
|
||||||
Buffer2=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
||||||
memset(Buffer2,0,DeviceExt->BytesPerCluster);
|
memset (Buffer2, 0, DeviceExt->BytesPerCluster);
|
||||||
VFATWriteCluster(DeviceExt,Buffer2,CurrentCluster);
|
VFATWriteCluster (DeviceExt, Buffer2, CurrentCluster);
|
||||||
ExFreePool(Buffer2);
|
ExFreePool (Buffer2);
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
pEntry->FirstClusterHigh=CurrentCluster>>16;
|
pEntry->FirstClusterHigh = CurrentCluster >> 16;
|
||||||
pEntry->FirstCluster=CurrentCluster;
|
pEntry->FirstCluster = CurrentCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
pEntry->FirstCluster=CurrentCluster;
|
pEntry->FirstCluster = CurrentCluster;
|
||||||
}
|
}
|
||||||
if(nbFree==nbSlots)
|
if (nbFree == nbSlots)
|
||||||
{//use old slots
|
{ //use old slots
|
||||||
Offset=(i-nbSlots+1)*sizeof(FATDirEntry);
|
Offset = (i - nbSlots + 1) * sizeof (FATDirEntry);
|
||||||
status=FsdWriteFile(DeviceExt,&FileObject,Buffer
|
status =
|
||||||
,sizeof(FATDirEntry)*nbSlots,Offset);
|
VfatWriteFile (DeviceExt, &FileObject, Buffer,
|
||||||
DPRINT( "FsdWriteFile() returned: %x\n", status );
|
sizeof (FATDirEntry) * nbSlots, Offset);
|
||||||
|
DPRINT ("VfatWriteFile() returned: %x\n", status);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{//write at end of directory
|
{ //write at end of directory
|
||||||
Offset=(i-nbFree)*sizeof(FATDirEntry);
|
Offset = (i - nbFree) * sizeof (FATDirEntry);
|
||||||
status=FsdWriteFile(DeviceExt,&FileObject,Buffer
|
status =
|
||||||
,sizeof(FATDirEntry)*(nbSlots+1),Offset);
|
VfatWriteFile (DeviceExt, &FileObject, Buffer,
|
||||||
|
sizeof (FATDirEntry) * (nbSlots + 1), Offset);
|
||||||
}
|
}
|
||||||
DPRINT("write entry offset %d status=%x\n",Offset,status);
|
DPRINT ("write entry offset %d status=%x\n", Offset, status);
|
||||||
newCCB = ExAllocatePool(NonPagedPool,sizeof(VFATCCB));
|
newCCB = ExAllocatePool (NonPagedPool, sizeof (VFATCCB));
|
||||||
newFCB = ExAllocatePool(NonPagedPool,sizeof(VFATFCB));
|
newFCB = ExAllocatePool (NonPagedPool, sizeof (VFATFCB));
|
||||||
memset(newCCB,0,sizeof(VFATCCB));
|
memset (newCCB, 0, sizeof (VFATCCB));
|
||||||
memset(newFCB,0,sizeof(VFATFCB));
|
memset (newFCB, 0, sizeof (VFATFCB));
|
||||||
newCCB->pFcb=newFCB;
|
newCCB->pFcb = newFCB;
|
||||||
newCCB->PtrFileObject=pFileObject;
|
newCCB->PtrFileObject = pFileObject;
|
||||||
newFCB->RefCount++;
|
newFCB->RefCount++;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME : initialize all fields in FCB and CCB
|
* FIXME : initialize all fields in FCB and CCB
|
||||||
*/
|
*/
|
||||||
KeAcquireSpinLock(&DeviceExt->FcbListLock, &oldIrql);
|
KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql);
|
||||||
InsertTailList(&DeviceExt->FcbListHead, &newFCB->FcbListEntry);
|
InsertTailList (&DeviceExt->FcbListHead, &newFCB->FcbListEntry);
|
||||||
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
|
KeReleaseSpinLock (&DeviceExt->FcbListLock, oldIrql);
|
||||||
|
|
||||||
|
|
||||||
memcpy(&newFCB->entry,pEntry,sizeof(FATDirEntry));
|
memcpy (&newFCB->entry, pEntry, sizeof (FATDirEntry));
|
||||||
DPRINT("new : entry=%11.11s\n",newFCB->entry.Filename);
|
DPRINT ("new : entry=%11.11s\n", newFCB->entry.Filename);
|
||||||
DPRINT("new : entry=%11.11s\n",pEntry->Filename);
|
DPRINT ("new : entry=%11.11s\n", pEntry->Filename);
|
||||||
vfat_wcsncpy(newFCB->PathName,PathFileName,MAX_PATH);
|
vfat_wcsncpy (newFCB->PathName, PathFileName, MAX_PATH);
|
||||||
newFCB->ObjectName=newFCB->PathName+(PathFileName-FileName);
|
newFCB->ObjectName = newFCB->PathName + (PathFileName - FileName);
|
||||||
newFCB->pDevExt=DeviceExt;
|
newFCB->pDevExt = DeviceExt;
|
||||||
pFileObject->FsContext =(PVOID) &newFCB->NTRequiredFCB;
|
pFileObject->FsContext = (PVOID)&newFCB->RFCB;
|
||||||
pFileObject->FsContext2 = newCCB;
|
pFileObject->FsContext2 = newCCB;
|
||||||
if(RequestedOptions&FILE_DIRECTORY_FILE)
|
if (RequestedOptions & FILE_DIRECTORY_FILE)
|
||||||
{
|
{
|
||||||
// create . and ..
|
// create . and ..
|
||||||
memcpy(pEntry->Filename,". ",11);
|
memcpy (pEntry->Filename, ". ", 11);
|
||||||
status=FsdWriteFile(DeviceExt,pFileObject,pEntry
|
status =
|
||||||
,sizeof(FATDirEntry),0L);
|
VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
|
||||||
pEntry->FirstCluster
|
0L);
|
||||||
=((VFATCCB *)(FileObject.FsContext2))->pFcb->entry.FirstCluster;
|
pEntry->FirstCluster =
|
||||||
pEntry->FirstClusterHigh
|
((VFATCCB *) (FileObject.FsContext2))->pFcb->entry.FirstCluster;
|
||||||
=((VFATCCB *)(FileObject.FsContext2))->pFcb->entry.FirstClusterHigh;
|
pEntry->FirstClusterHigh =
|
||||||
memcpy(pEntry->Filename,".. ",11);
|
((VFATCCB *) (FileObject.FsContext2))->pFcb->entry.FirstClusterHigh;
|
||||||
if(pEntry->FirstCluster==1 && DeviceExt->FatType!=FAT32)
|
memcpy (pEntry->Filename, ".. ", 11);
|
||||||
pEntry->FirstCluster=0;
|
if (pEntry->FirstCluster == 1 && DeviceExt->FatType != FAT32)
|
||||||
status=FsdWriteFile(DeviceExt,pFileObject,pEntry
|
pEntry->FirstCluster = 0;
|
||||||
,sizeof(FATDirEntry),sizeof(FATDirEntry));
|
status =
|
||||||
|
VfatWriteFile (DeviceExt, pFileObject, pEntry, sizeof (FATDirEntry),
|
||||||
|
sizeof (FATDirEntry));
|
||||||
}
|
}
|
||||||
FsdCloseFile(DeviceExt,&FileObject);
|
VfatCloseFile (DeviceExt, &FileObject);
|
||||||
ExFreePool(Buffer);
|
ExFreePool (Buffer);
|
||||||
DPRINT("addentry ok\n");
|
DPRINT ("addentry ok\n");
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* $Id: fat.c,v 1.8 2000/12/28 03:38:08 dwelch Exp $
|
* $Id: fat.c,v 1.9 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <ddk/cctypes.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -23,7 +22,7 @@
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
Fat32GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical
|
* FUNCTION: Retrieve the next FAT32 cluster from the FAT table via a physical
|
||||||
* disk read
|
* disk read
|
||||||
|
@ -33,143 +32,144 @@ Fat32GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
ULONG FATeis;
|
ULONG FATeis;
|
||||||
PULONG Block;
|
PULONG Block;
|
||||||
|
|
||||||
Block = ExAllocatePool(NonPagedPool,1024);
|
Block = ExAllocatePool (NonPagedPool, 1024);
|
||||||
FATsector=CurrentCluster/(512/sizeof(ULONG));
|
FATsector = CurrentCluster / (512 / sizeof (ULONG));
|
||||||
FATeis=CurrentCluster-(FATsector*(512/sizeof(ULONG)));
|
FATeis = CurrentCluster - (FATsector * (512 / sizeof (ULONG)));
|
||||||
VFATReadSectors(DeviceExt->StorageDevice
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
,(ULONG)(DeviceExt->FATStart+FATsector), 1,(UCHAR*) Block);
|
(ULONG) (DeviceExt->FATStart + FATsector), 1,
|
||||||
|
(UCHAR *) Block);
|
||||||
CurrentCluster = Block[FATeis];
|
CurrentCluster = Block[FATeis];
|
||||||
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
if (CurrentCluster >= 0xffffff8 && CurrentCluster <= 0xfffffff)
|
||||||
CurrentCluster = 0xffffffff;
|
CurrentCluster = 0xffffffff;
|
||||||
ExFreePool(Block);
|
ExFreePool (Block);
|
||||||
return(CurrentCluster);
|
return (CurrentCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
Fat16GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
Fat16GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the next FAT16 cluster from the FAT table from the
|
* FUNCTION: Retrieve the next FAT16 cluster from the FAT table from the
|
||||||
* in-memory FAT
|
* in-memory FAT
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PUSHORT Block;
|
PUSHORT Block;
|
||||||
Block=(PUSHORT)DeviceExt->FAT;
|
Block = (PUSHORT) DeviceExt->FAT;
|
||||||
CurrentCluster = Block[CurrentCluster];
|
CurrentCluster = Block[CurrentCluster];
|
||||||
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
if (CurrentCluster >= 0xfff8 && CurrentCluster <= 0xffff)
|
||||||
CurrentCluster = 0xffffffff;
|
CurrentCluster = 0xffffffff;
|
||||||
DPRINT("Returning %x\n",CurrentCluster);
|
DPRINT ("Returning %x\n", CurrentCluster);
|
||||||
return(CurrentCluster);
|
return (CurrentCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
Fat12GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
Fat12GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table from the
|
* FUNCTION: Retrieve the next FAT12 cluster from the FAT table from the
|
||||||
* in-memory FAT
|
* in-memory FAT
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
unsigned char* CBlock;
|
unsigned char *CBlock;
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
CBlock = DeviceExt->FAT;
|
CBlock = DeviceExt->FAT;
|
||||||
FATOffset = (CurrentCluster * 12)/ 8;//first byte containing value
|
FATOffset = (CurrentCluster * 12) / 8; //first byte containing value
|
||||||
if ((CurrentCluster % 2) == 0)
|
if ((CurrentCluster % 2) == 0)
|
||||||
{
|
{
|
||||||
Entry = CBlock[FATOffset];
|
Entry = CBlock[FATOffset];
|
||||||
Entry |= ((CBlock[FATOffset+1] & 0xf)<<8);
|
Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Entry = (CBlock[FATOffset] >> 4);
|
|
||||||
Entry |= (CBlock[FATOffset+1] << 4);
|
|
||||||
}
|
|
||||||
DPRINT("Entry %x\n",Entry);
|
|
||||||
if (Entry >= 0xff8 && Entry <= 0xfff)
|
|
||||||
Entry = 0xffffffff;
|
|
||||||
DPRINT("Returning %x\n",Entry);
|
|
||||||
return(Entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG
|
|
||||||
GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Retrieve the next cluster depending on the FAT type
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
ULONG NextCluster;
|
|
||||||
|
|
||||||
DPRINT("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
|
|
||||||
DeviceExt,CurrentCluster);
|
|
||||||
|
|
||||||
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
|
|
||||||
|
|
||||||
if (DeviceExt->FatType == FAT16)
|
|
||||||
{
|
|
||||||
NextCluster = Fat16GetNextCluster(DeviceExt, CurrentCluster);
|
|
||||||
}
|
|
||||||
else if (DeviceExt->FatType == FAT32)
|
|
||||||
{
|
|
||||||
NextCluster = Fat32GetNextCluster(DeviceExt, CurrentCluster);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NextCluster = Fat12GetNextCluster(DeviceExt, CurrentCluster);
|
|
||||||
}
|
|
||||||
|
|
||||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
|
||||||
|
|
||||||
return(NextCluster);
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG
|
|
||||||
FAT16FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Finds the first available cluster in a FAT16 table
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
PUSHORT Block;
|
|
||||||
int i;
|
|
||||||
Block=(PUSHORT)DeviceExt->FAT;
|
|
||||||
for(i=2;i<(DeviceExt->Boot->FATSectors*256) ;i++)
|
|
||||||
if(Block[i]==0)
|
|
||||||
return (i);
|
|
||||||
/* Give an error message (out of disk space) if we reach here) */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
ULONG
|
|
||||||
FAT12FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
|
||||||
/*
|
|
||||||
* FUNCTION: Finds the first available cluster in a FAT12 table
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
ULONG FATOffset;
|
|
||||||
ULONG Entry;
|
|
||||||
PUCHAR CBlock=DeviceExt->FAT;
|
|
||||||
ULONG i;
|
|
||||||
for(i=2;i<((DeviceExt->Boot->FATSectors*512*8)/12) ;i++)
|
|
||||||
{
|
|
||||||
FATOffset = (i * 12)/8;
|
|
||||||
if ((i % 2) == 0)
|
|
||||||
{
|
|
||||||
Entry = CBlock[FATOffset];
|
|
||||||
Entry |= ((CBlock[FATOffset + 1] & 0xf)<<8);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Entry = (CBlock[FATOffset] >> 4);
|
Entry = (CBlock[FATOffset] >> 4);
|
||||||
Entry |= (CBlock[FATOffset + 1] << 4);
|
Entry |= (CBlock[FATOffset + 1] << 4);
|
||||||
}
|
}
|
||||||
if(Entry==0)
|
DPRINT ("Entry %x\n", Entry);
|
||||||
return (i);
|
if (Entry >= 0xff8 && Entry <= 0xfff)
|
||||||
|
Entry = 0xffffffff;
|
||||||
|
DPRINT ("Returning %x\n", Entry);
|
||||||
|
return (Entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
GetNextCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Retrieve the next cluster depending on the FAT type
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG NextCluster;
|
||||||
|
|
||||||
|
DPRINT ("GetNextCluster(DeviceExt %x, CurrentCluster %x)\n",
|
||||||
|
DeviceExt, CurrentCluster);
|
||||||
|
|
||||||
|
ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
|
||||||
|
|
||||||
|
if (DeviceExt->FatType == FAT16)
|
||||||
|
{
|
||||||
|
NextCluster = Fat16GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
|
else if (DeviceExt->FatType == FAT32)
|
||||||
|
{
|
||||||
|
NextCluster = Fat32GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NextCluster = Fat12GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExReleaseResourceLite (&DeviceExt->FatResource);
|
||||||
|
|
||||||
|
return (NextCluster);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
FAT16FindAvailableCluster (PDEVICE_EXTENSION DeviceExt)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Finds the first available cluster in a FAT16 table
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
PUSHORT Block;
|
||||||
|
int i;
|
||||||
|
Block = (PUSHORT) DeviceExt->FAT;
|
||||||
|
for (i = 2; i < (DeviceExt->Boot->FATSectors * 256); i++)
|
||||||
|
if (Block[i] == 0)
|
||||||
|
return (i);
|
||||||
/* Give an error message (out of disk space) if we reach here) */
|
/* Give an error message (out of disk space) if we reach here) */
|
||||||
DbgPrint("Disk full, %d clusters used\n",i);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
FAT32FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
FAT12FindAvailableCluster (PDEVICE_EXTENSION DeviceExt)
|
||||||
|
/*
|
||||||
|
* FUNCTION: Finds the first available cluster in a FAT12 table
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ULONG FATOffset;
|
||||||
|
ULONG Entry;
|
||||||
|
PUCHAR CBlock = DeviceExt->FAT;
|
||||||
|
ULONG i;
|
||||||
|
for (i = 2; i < ((DeviceExt->Boot->FATSectors * 512 * 8) / 12); i++)
|
||||||
|
{
|
||||||
|
FATOffset = (i * 12) / 8;
|
||||||
|
if ((i % 2) == 0)
|
||||||
|
{
|
||||||
|
Entry = CBlock[FATOffset];
|
||||||
|
Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Entry = (CBlock[FATOffset] >> 4);
|
||||||
|
Entry |= (CBlock[FATOffset + 1] << 4);
|
||||||
|
}
|
||||||
|
if (Entry == 0)
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
/* Give an error message (out of disk space) if we reach here) */
|
||||||
|
DbgPrint ("Disk full, %d clusters used\n", i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
FAT32FindAvailableCluster (PDEVICE_EXTENSION DeviceExt)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Finds the first available cluster in a FAT32 table
|
* FUNCTION: Finds the first available cluster in a FAT32 table
|
||||||
*/
|
*/
|
||||||
|
@ -177,66 +177,67 @@ FAT32FindAvailableCluster(PDEVICE_EXTENSION DeviceExt)
|
||||||
ULONG sector;
|
ULONG sector;
|
||||||
PULONG Block;
|
PULONG Block;
|
||||||
int i;
|
int i;
|
||||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
Block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
||||||
for(sector=0
|
for (sector = 0;
|
||||||
;sector< ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32
|
sector < ((struct _BootSector32 *) (DeviceExt->Boot))->FATSectors32;
|
||||||
;sector++)
|
sector++)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
,(ULONG)(DeviceExt->FATStart+sector), 1,(UCHAR*) Block);
|
(ULONG) (DeviceExt->FATStart + sector), 1,
|
||||||
|
(UCHAR *) Block);
|
||||||
|
|
||||||
for(i=0; i<512; i++)
|
for (i = 0; i < 512; i++)
|
||||||
{
|
{
|
||||||
if(Block[i]==0)
|
if (Block[i] == 0)
|
||||||
{
|
{
|
||||||
ExFreePool(Block);
|
ExFreePool (Block);
|
||||||
return (i+sector*128);
|
return (i + sector * 128);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Give an error message (out of disk space) if we reach here) */
|
/* Give an error message (out of disk space) if we reach here) */
|
||||||
ExFreePool(Block);
|
ExFreePool (Block);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
FAT12CountAvailableClusters (PDEVICE_EXTENSION DeviceExt)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Counts free cluster in a FAT12 table
|
* FUNCTION: Counts free cluster in a FAT12 table
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
ULONG Entry;
|
ULONG Entry;
|
||||||
PUCHAR CBlock=DeviceExt->FAT;
|
PUCHAR CBlock = DeviceExt->FAT;
|
||||||
ULONG ulCount = 0;
|
ULONG ulCount = 0;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
|
ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
|
||||||
|
|
||||||
for(i=2;i<((DeviceExt->Boot->FATSectors*512*8)/12) ;i++)
|
for (i = 2; i < ((DeviceExt->Boot->FATSectors * 512 * 8) / 12); i++)
|
||||||
{
|
{
|
||||||
FATOffset = (i * 12)/8;
|
FATOffset = (i * 12) / 8;
|
||||||
if ((i % 2) == 0)
|
if ((i % 2) == 0)
|
||||||
{
|
{
|
||||||
Entry = CBlock[FATOffset];
|
Entry = CBlock[FATOffset];
|
||||||
Entry |= ((CBlock[FATOffset + 1] & 0xf)<<8);
|
Entry |= ((CBlock[FATOffset + 1] & 0xf) << 8);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Entry = (CBlock[FATOffset] >> 4);
|
Entry = (CBlock[FATOffset] >> 4);
|
||||||
Entry |= (CBlock[FATOffset + 1] << 4);
|
Entry |= (CBlock[FATOffset + 1] << 4);
|
||||||
}
|
}
|
||||||
if(Entry==0)
|
if (Entry == 0)
|
||||||
ulCount++;
|
ulCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
ExReleaseResourceLite (&DeviceExt->FatResource);
|
||||||
|
|
||||||
return ulCount;
|
return ulCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
FAT16CountAvailableClusters (PDEVICE_EXTENSION DeviceExt)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Counts free clusters in a FAT16 table
|
* FUNCTION: Counts free clusters in a FAT16 table
|
||||||
*/
|
*/
|
||||||
|
@ -245,22 +246,22 @@ FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
||||||
ULONG ulCount = 0;
|
ULONG ulCount = 0;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
|
ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
|
||||||
|
|
||||||
Block=(PUSHORT)DeviceExt->FAT;
|
Block = (PUSHORT) DeviceExt->FAT;
|
||||||
for(i=2;i<(DeviceExt->Boot->FATSectors*256);i++)
|
for (i = 2; i < (DeviceExt->Boot->FATSectors * 256); i++)
|
||||||
{
|
{
|
||||||
if(Block[i]==0)
|
if (Block[i] == 0)
|
||||||
ulCount++;
|
ulCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
ExReleaseResourceLite (&DeviceExt->FatResource);
|
||||||
|
|
||||||
return ulCount;
|
return ulCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
FAT32CountAvailableClusters (PDEVICE_EXTENSION DeviceExt)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Counts free clusters in a FAT32 table
|
* FUNCTION: Counts free clusters in a FAT32 table
|
||||||
*/
|
*/
|
||||||
|
@ -270,30 +271,31 @@ FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt)
|
||||||
ULONG ulCount = 0;
|
ULONG ulCount = 0;
|
||||||
ULONG i;
|
ULONG i;
|
||||||
|
|
||||||
ExAcquireResourceSharedLite(&DeviceExt->FatResource, TRUE);
|
ExAcquireResourceSharedLite (&DeviceExt->FatResource, TRUE);
|
||||||
|
|
||||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
Block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
||||||
for(sector=0
|
for (sector = 0;
|
||||||
;sector< ((struct _BootSector32*)(DeviceExt->Boot))->FATSectors32
|
sector < ((struct _BootSector32 *) (DeviceExt->Boot))->FATSectors32;
|
||||||
;sector++)
|
sector++)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
,(ULONG)(DeviceExt->FATStart+sector), 1,(UCHAR*) Block);
|
(ULONG) (DeviceExt->FATStart + sector), 1,
|
||||||
|
(UCHAR *) Block);
|
||||||
|
|
||||||
for(i=0; i<512; i++)
|
for (i = 0; i < 512; i++)
|
||||||
{
|
{
|
||||||
if(Block[i]==0)
|
if (Block[i] == 0)
|
||||||
ulCount++;
|
ulCount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Give an error message (out of disk space) if we reach here) */
|
/* Give an error message (out of disk space) if we reach here) */
|
||||||
ExFreePool(Block);
|
ExFreePool (Block);
|
||||||
ExReleaseResourceLite(&DeviceExt->FatResource);
|
ExReleaseResourceLite (&DeviceExt->FatResource);
|
||||||
return ulCount;
|
return ulCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
FAT12WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG NewValue)
|
ULONG NewValue)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
|
* FUNCTION: Writes a cluster to the FAT12 physical and in-memory tables
|
||||||
|
@ -301,48 +303,44 @@ FAT12WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
{
|
{
|
||||||
ULONG FATsector;
|
ULONG FATsector;
|
||||||
ULONG FATOffset;
|
ULONG FATOffset;
|
||||||
PUCHAR CBlock=DeviceExt->FAT;
|
PUCHAR CBlock = DeviceExt->FAT;
|
||||||
int i;
|
int i;
|
||||||
FATOffset = (ClusterToWrite * 12)/8;
|
FATOffset = (ClusterToWrite * 12) / 8;
|
||||||
if ((ClusterToWrite % 2) == 0)
|
if ((ClusterToWrite % 2) == 0)
|
||||||
{
|
{
|
||||||
CBlock[FATOffset]=NewValue;
|
CBlock[FATOffset] = NewValue;
|
||||||
CBlock[FATOffset + 1] &=0xf0;
|
CBlock[FATOffset + 1] &= 0xf0;
|
||||||
CBlock[FATOffset + 1]
|
CBlock[FATOffset + 1] |= (NewValue & 0xf00) >> 8;
|
||||||
|= (NewValue&0xf00)>>8;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CBlock[FATOffset] &=0x0f;
|
CBlock[FATOffset] &= 0x0f;
|
||||||
CBlock[FATOffset]
|
CBlock[FATOffset] |= (NewValue & 0xf) << 4;
|
||||||
|= (NewValue&0xf)<<4;
|
CBlock[FATOffset + 1] = NewValue >> 4;
|
||||||
CBlock[FATOffset+1]=NewValue>>4;
|
|
||||||
}
|
}
|
||||||
/* Write the changed FAT sector(s) to disk */
|
/* Write the changed FAT sector(s) to disk */
|
||||||
FATsector=FATOffset/BLOCKSIZE;
|
FATsector = FATOffset / BLOCKSIZE;
|
||||||
for(i=0;i<DeviceExt->Boot->FATCount;i++)
|
for (i = 0; i < DeviceExt->Boot->FATCount; i++)
|
||||||
{
|
{
|
||||||
if( (FATOffset%BLOCKSIZE)==(BLOCKSIZE-1))//entry is on 2 sectors
|
if ((FATOffset % BLOCKSIZE) == (BLOCKSIZE - 1)) //entry is on 2 sectors
|
||||||
{
|
{
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice,
|
||||||
DeviceExt->FATStart+FATsector
|
DeviceExt->FATStart + FATsector
|
||||||
+i*DeviceExt->Boot->FATSectors,
|
+ i * DeviceExt->Boot->FATSectors,
|
||||||
2,
|
2, CBlock + FATsector * 512);
|
||||||
CBlock+FATsector*512);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice,
|
||||||
DeviceExt->FATStart+FATsector
|
DeviceExt->FATStart + FATsector
|
||||||
+i*DeviceExt->Boot->FATSectors,
|
+ i * DeviceExt->Boot->FATSectors,
|
||||||
1,
|
1, CBlock + FATsector * 512);
|
||||||
CBlock+FATsector*512);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
FAT16WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG NewValue)
|
ULONG NewValue)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
|
* FUNCTION: Writes a cluster to the FAT16 physical and in-memory tables
|
||||||
|
@ -353,10 +351,10 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG Start;
|
ULONG Start;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
DbgPrint("FAT16WriteCluster %u : %u\n", ClusterToWrite, NewValue);
|
DbgPrint ("FAT16WriteCluster %u : %u\n", ClusterToWrite, NewValue);
|
||||||
|
|
||||||
Block=(PUSHORT)DeviceExt->FAT;
|
Block = (PUSHORT) DeviceExt->FAT;
|
||||||
FATsector=ClusterToWrite/(512/sizeof(USHORT));
|
FATsector = ClusterToWrite / (512 / sizeof (USHORT));
|
||||||
|
|
||||||
/* Update the in-memory FAT */
|
/* Update the in-memory FAT */
|
||||||
Block[ClusterToWrite] = NewValue;
|
Block[ClusterToWrite] = NewValue;
|
||||||
|
@ -365,16 +363,14 @@ FAT16WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
Start = DeviceExt->FATStart + FATsector;
|
Start = DeviceExt->FATStart + FATsector;
|
||||||
for (i = 0; i < DeviceExt->Boot->FATCount; i++)
|
for (i = 0; i < DeviceExt->Boot->FATCount; i++)
|
||||||
{
|
{
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice,
|
||||||
Start,
|
Start, 1, ((UCHAR *) Block) + FATsector * 512);
|
||||||
1,
|
|
||||||
((UCHAR *)Block)+FATsector*512);
|
|
||||||
Start += DeviceExt->Boot->FATSectors;
|
Start += DeviceExt->Boot->FATSectors;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
FAT32WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG NewValue)
|
ULONG NewValue)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Writes a cluster to the FAT32 physical tables
|
* FUNCTION: Writes a cluster to the FAT32 physical tables
|
||||||
|
@ -386,53 +382,48 @@ FAT32WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG Start;
|
ULONG Start;
|
||||||
int i;
|
int i;
|
||||||
struct _BootSector32 *pBoot;
|
struct _BootSector32 *pBoot;
|
||||||
DbgPrint("FAT32WriteCluster %u : %u\n",ClusterToWrite,NewValue);
|
DbgPrint ("FAT32WriteCluster %u : %u\n", ClusterToWrite, NewValue);
|
||||||
Block = ExAllocatePool(NonPagedPool,BLOCKSIZE);
|
Block = ExAllocatePool (NonPagedPool, BLOCKSIZE);
|
||||||
FATsector=ClusterToWrite/128;
|
FATsector = ClusterToWrite / 128;
|
||||||
FATeis=ClusterToWrite-(FATsector*128);
|
FATeis = ClusterToWrite - (FATsector * 128);
|
||||||
/* load sector, change value, then rewrite sector */
|
/* load sector, change value, then rewrite sector */
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
DeviceExt->FATStart+FATsector,
|
DeviceExt->FATStart + FATsector, 1, (UCHAR *) Block);
|
||||||
1,
|
|
||||||
(UCHAR *)Block);
|
|
||||||
Block[FATeis] = NewValue;
|
Block[FATeis] = NewValue;
|
||||||
/* Write the changed FAT sector to disk (all FAT's) */
|
/* Write the changed FAT sector to disk (all FAT's) */
|
||||||
Start = DeviceExt->FATStart + FATsector;
|
Start = DeviceExt->FATStart + FATsector;
|
||||||
pBoot = (struct _BootSector32*) DeviceExt->Boot;
|
pBoot = (struct _BootSector32 *) DeviceExt->Boot;
|
||||||
for (i = 0; i < pBoot->FATCount; i++)
|
for (i = 0; i < pBoot->FATCount; i++)
|
||||||
{
|
{
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice, Start, 1, (UCHAR *) Block);
|
||||||
Start,
|
|
||||||
1,
|
|
||||||
(UCHAR *)Block);
|
|
||||||
Start += pBoot->FATSectors;
|
Start += pBoot->FATSectors;
|
||||||
}
|
}
|
||||||
ExFreePool(Block);
|
ExFreePool (Block);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
WriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
WriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG ClusterToWrite,
|
||||||
ULONG NewValue)
|
ULONG NewValue)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Write a changed FAT entry
|
* FUNCTION: Write a changed FAT entry
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
if (DeviceExt->FatType==FAT16)
|
if (DeviceExt->FatType == FAT16)
|
||||||
{
|
{
|
||||||
FAT16WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
FAT16WriteCluster (DeviceExt, ClusterToWrite, NewValue);
|
||||||
}
|
}
|
||||||
else if (DeviceExt->FatType==FAT32)
|
else if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
FAT32WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
FAT32WriteCluster (DeviceExt, ClusterToWrite, NewValue);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FAT12WriteCluster(DeviceExt, ClusterToWrite, NewValue);
|
FAT12WriteCluster (DeviceExt, ClusterToWrite, NewValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
GetNextWriteCluster (PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Determines the next cluster to be written
|
* FUNCTION: Determines the next cluster to be written
|
||||||
*/
|
*/
|
||||||
|
@ -440,12 +431,11 @@ GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
ULONG LastCluster, NewCluster;
|
ULONG LastCluster, NewCluster;
|
||||||
UCHAR *Buffer2;
|
UCHAR *Buffer2;
|
||||||
|
|
||||||
DPRINT("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n",
|
DPRINT ("GetNextWriteCluster(DeviceExt %x, CurrentCluster %x)\n",
|
||||||
DeviceExt,CurrentCluster);
|
DeviceExt, CurrentCluster);
|
||||||
|
|
||||||
/* Find out what was happening in the last cluster's AU */
|
/* Find out what was happening in the last cluster's AU */
|
||||||
LastCluster=GetNextCluster(DeviceExt,
|
LastCluster = GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
CurrentCluster);
|
|
||||||
/* Check to see if we must append or overwrite */
|
/* Check to see if we must append or overwrite */
|
||||||
if (LastCluster == 0xffffffff)
|
if (LastCluster == 0xffffffff)
|
||||||
{
|
{
|
||||||
|
@ -454,31 +444,31 @@ GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
/* Firstly, find the next available open allocation unit */
|
/* Firstly, find the next available open allocation unit */
|
||||||
if (DeviceExt->FatType == FAT16)
|
if (DeviceExt->FatType == FAT16)
|
||||||
{
|
{
|
||||||
NewCluster = FAT16FindAvailableCluster(DeviceExt);
|
NewCluster = FAT16FindAvailableCluster (DeviceExt);
|
||||||
DPRINT1("NewCluster %x\n", NewCluster);
|
DPRINT1 ("NewCluster %x\n", NewCluster);
|
||||||
}
|
}
|
||||||
else if (DeviceExt->FatType == FAT32)
|
else if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
NewCluster = FAT32FindAvailableCluster(DeviceExt);
|
NewCluster = FAT32FindAvailableCluster (DeviceExt);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NewCluster = FAT12FindAvailableCluster(DeviceExt);
|
NewCluster = FAT12FindAvailableCluster (DeviceExt);
|
||||||
DPRINT( "NewFat12Cluster: %x\n", NewCluster );
|
DPRINT ("NewFat12Cluster: %x\n", NewCluster);
|
||||||
}
|
}
|
||||||
/* Mark the new AU as the EOF */
|
/* Mark the new AU as the EOF */
|
||||||
WriteCluster(DeviceExt, NewCluster, 0xFFFFFFFF);
|
WriteCluster (DeviceExt, NewCluster, 0xFFFFFFFF);
|
||||||
/* Now, write the AU of the LastCluster with the value of the newly
|
/* Now, write the AU of the LastCluster with the value of the newly
|
||||||
found AU */
|
found AU */
|
||||||
if(CurrentCluster)
|
if (CurrentCluster)
|
||||||
{
|
{
|
||||||
WriteCluster(DeviceExt, CurrentCluster, NewCluster);
|
WriteCluster (DeviceExt, CurrentCluster, NewCluster);
|
||||||
}
|
}
|
||||||
// fill cluster with zero
|
// fill cluster with zero
|
||||||
Buffer2=ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
Buffer2 = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
||||||
memset(Buffer2,0,DeviceExt->BytesPerCluster);
|
memset (Buffer2, 0, DeviceExt->BytesPerCluster);
|
||||||
VFATWriteCluster(DeviceExt,Buffer2,NewCluster);
|
VFATWriteCluster (DeviceExt, Buffer2, NewCluster);
|
||||||
ExFreePool(Buffer2);
|
ExFreePool (Buffer2);
|
||||||
/* Return NewCluster as CurrentCluster */
|
/* Return NewCluster as CurrentCluster */
|
||||||
return NewCluster;
|
return NewCluster;
|
||||||
}
|
}
|
||||||
|
@ -490,51 +480,46 @@ GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster)
|
||||||
}
|
}
|
||||||
|
|
||||||
ULONG
|
ULONG
|
||||||
ClusterToSector(PDEVICE_EXTENSION DeviceExt,
|
ClusterToSector (PDEVICE_EXTENSION DeviceExt, unsigned long Cluster)
|
||||||
unsigned long Cluster)
|
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Converts the cluster number to a sector number for this physical
|
* FUNCTION: Converts the cluster number to a sector number for this physical
|
||||||
* device
|
* device
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
return DeviceExt->dataStart+((Cluster-2)*DeviceExt->Boot->SectorsPerCluster);
|
return DeviceExt->dataStart +
|
||||||
|
((Cluster - 2) * DeviceExt->Boot->SectorsPerCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
VFATLoadCluster (PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Load a cluster from the physical device
|
* FUNCTION: Load a cluster from the physical device
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG Sector;
|
ULONG Sector;
|
||||||
|
|
||||||
DPRINT("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
DPRINT ("VFATLoadCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||||
DeviceExt,Buffer,Cluster);
|
DeviceExt, Buffer, Cluster);
|
||||||
|
|
||||||
Sector = ClusterToSector(DeviceExt, Cluster);
|
Sector = ClusterToSector (DeviceExt, Cluster);
|
||||||
|
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
Sector,
|
Sector, DeviceExt->Boot->SectorsPerCluster, Buffer);
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DPRINT ("Finished VFATReadSectors\n");
|
||||||
Buffer);
|
|
||||||
DPRINT("Finished VFATReadSectors\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
VFATWriteCluster (PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Write a cluster to the physical device
|
* FUNCTION: Write a cluster to the physical device
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
ULONG Sector;
|
ULONG Sector;
|
||||||
DPRINT("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
DPRINT ("VFATWriteCluster(DeviceExt %x, Buffer %x, Cluster %d)\n",
|
||||||
DeviceExt,Buffer,Cluster);
|
DeviceExt, Buffer, Cluster);
|
||||||
|
|
||||||
Sector = ClusterToSector(DeviceExt, Cluster);
|
Sector = ClusterToSector (DeviceExt, Cluster);
|
||||||
|
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice,
|
||||||
Sector,
|
Sector, DeviceExt->Boot->SectorsPerCluster, Buffer);
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
|
||||||
Buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: finfo.c,v 1.4 2000/09/12 10:12:13 jean Exp $
|
/* $Id: finfo.c,v 1.5 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <ddk/cctypes.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -21,7 +20,8 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
NTSTATUS FsdGetStandardInformation(PVFATFCB FCB, PDEVICE_OBJECT DeviceObject,
|
NTSTATUS
|
||||||
|
VfatGetStandardInformation (PVFATFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_STANDARD_INFORMATION StandardInfo)
|
PFILE_STANDARD_INFORMATION StandardInfo)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the standard file information
|
* FUNCTION: Retrieve the standard file information
|
||||||
|
@ -32,102 +32,111 @@ NTSTATUS FsdGetStandardInformation(PVFATFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
DeviceExtension = DeviceObject->DeviceExtension;
|
DeviceExtension = DeviceObject->DeviceExtension;
|
||||||
/* PRECONDITION */
|
/* PRECONDITION */
|
||||||
assert(DeviceExtension != NULL);
|
assert (DeviceExtension != NULL);
|
||||||
assert(DeviceExtension->BytesPerCluster != 0);
|
assert (DeviceExtension->BytesPerCluster != 0);
|
||||||
assert(StandardInfo != NULL);
|
assert (StandardInfo != NULL);
|
||||||
assert(FCB != NULL);
|
assert (FCB != NULL);
|
||||||
|
|
||||||
RtlZeroMemory(StandardInfo, sizeof(FILE_STANDARD_INFORMATION));
|
RtlZeroMemory (StandardInfo, sizeof (FILE_STANDARD_INFORMATION));
|
||||||
|
|
||||||
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
/* Make allocsize a rounded up multiple of BytesPerCluster */
|
||||||
AllocSize = ((FCB->entry.FileSize + DeviceExtension->BytesPerCluster - 1) /
|
AllocSize = ((FCB->entry.FileSize + DeviceExtension->BytesPerCluster - 1) /
|
||||||
DeviceExtension->BytesPerCluster) *
|
DeviceExtension->BytesPerCluster) *
|
||||||
DeviceExtension->BytesPerCluster;
|
DeviceExtension->BytesPerCluster;
|
||||||
|
|
||||||
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger(AllocSize);
|
StandardInfo->AllocationSize = RtlConvertUlongToLargeInteger (AllocSize);
|
||||||
StandardInfo->EndOfFile = RtlConvertUlongToLargeInteger(FCB->entry.FileSize);
|
StandardInfo->EndOfFile =
|
||||||
|
RtlConvertUlongToLargeInteger (FCB->entry.FileSize);
|
||||||
StandardInfo->NumberOfLinks = 0;
|
StandardInfo->NumberOfLinks = 0;
|
||||||
StandardInfo->DeletePending = FALSE;
|
StandardInfo->DeletePending = FALSE;
|
||||||
if((FCB->entry.Attrib & 0x10)>0) {
|
if ((FCB->entry.Attrib & 0x10) > 0)
|
||||||
|
{
|
||||||
StandardInfo->Directory = TRUE;
|
StandardInfo->Directory = TRUE;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
StandardInfo->Directory = FALSE;
|
StandardInfo->Directory = FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdSetPositionInformation(PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatSetPositionInformation (PFILE_OBJECT FileObject,
|
||||||
PVFATFCB FCB,
|
PVFATFCB FCB,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_POSITION_INFORMATION PositionInfo)
|
PFILE_POSITION_INFORMATION PositionInfo)
|
||||||
{
|
{
|
||||||
DPRINT("FsdSetPositionInformation()\n");
|
DPRINT ("FsdSetPositionInformation()\n");
|
||||||
|
|
||||||
DPRINT("PositionInfo %x\n", PositionInfo);
|
DPRINT ("PositionInfo %x\n", PositionInfo);
|
||||||
DPRINT("Setting position %d\n", PositionInfo->CurrentByteOffset.u.LowPart);
|
DPRINT ("Setting position %d\n", PositionInfo->CurrentByteOffset.u.LowPart);
|
||||||
memcpy(&FileObject->CurrentByteOffset,&PositionInfo->CurrentByteOffset,
|
memcpy (&FileObject->CurrentByteOffset, &PositionInfo->CurrentByteOffset,
|
||||||
sizeof(LARGE_INTEGER));
|
sizeof (LARGE_INTEGER));
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetPositionInformation(PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatGetPositionInformation (PFILE_OBJECT FileObject,
|
||||||
PVFATFCB FCB,
|
PVFATFCB FCB,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_POSITION_INFORMATION PositionInfo)
|
PFILE_POSITION_INFORMATION PositionInfo)
|
||||||
{
|
{
|
||||||
DPRINT("FsdGetPositionInformation()\n");
|
DPRINT ("VfatGetPositionInformation()\n");
|
||||||
|
|
||||||
memcpy(&PositionInfo->CurrentByteOffset, &FileObject->CurrentByteOffset,
|
memcpy (&PositionInfo->CurrentByteOffset, &FileObject->CurrentByteOffset,
|
||||||
sizeof(LARGE_INTEGER));
|
sizeof (LARGE_INTEGER));
|
||||||
DPRINT("Getting position %x\n", PositionInfo->CurrentByteOffset.u.LowPart);
|
DPRINT ("Getting position %x\n", PositionInfo->CurrentByteOffset.u.LowPart);
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetBasicInformation(PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatGetBasicInformation (PFILE_OBJECT FileObject,
|
||||||
PVFATFCB FCB,
|
PVFATFCB FCB,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_BASIC_INFORMATION BasicInfo)
|
PFILE_BASIC_INFORMATION BasicInfo)
|
||||||
{
|
{
|
||||||
DPRINT("FsdGetBasicInformation()\n");
|
DPRINT ("VfatGetBasicInformation()\n");
|
||||||
|
|
||||||
FsdDosDateTimeToFileTime(FCB->entry.CreationDate,FCB->entry.CreationTime,
|
FsdDosDateTimeToFileTime (FCB->entry.CreationDate, FCB->entry.CreationTime,
|
||||||
&BasicInfo->CreationTime);
|
&BasicInfo->CreationTime);
|
||||||
FsdDosDateTimeToFileTime(FCB->entry.AccessDate,0,
|
FsdDosDateTimeToFileTime (FCB->entry.AccessDate, 0,
|
||||||
&BasicInfo->LastAccessTime);
|
&BasicInfo->LastAccessTime);
|
||||||
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,FCB->entry.UpdateTime,
|
FsdDosDateTimeToFileTime (FCB->entry.UpdateDate, FCB->entry.UpdateTime,
|
||||||
&BasicInfo->LastWriteTime);
|
&BasicInfo->LastWriteTime);
|
||||||
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,FCB->entry.UpdateTime,
|
FsdDosDateTimeToFileTime (FCB->entry.UpdateDate, FCB->entry.UpdateTime,
|
||||||
&BasicInfo->ChangeTime);
|
&BasicInfo->ChangeTime);
|
||||||
|
|
||||||
BasicInfo->FileAttributes = FCB->entry.Attrib;
|
BasicInfo->FileAttributes = FCB->entry.Attrib;
|
||||||
|
|
||||||
DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes);
|
DPRINT ("Getting attributes %x\n", BasicInfo->FileAttributes);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS FsdSetDispositionInformation(PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatSetDispositionInformation (PFILE_OBJECT FileObject,
|
||||||
PVFATFCB FCB,
|
PVFATFCB FCB,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_DISPOSITION_INFORMATION DispositionInfo)
|
PFILE_DISPOSITION_INFORMATION DispositionInfo)
|
||||||
{
|
{
|
||||||
DPRINT("FsdSetDispositionInformation()\n");
|
DPRINT ("FsdSetDispositionInformation()\n");
|
||||||
|
|
||||||
FileObject->DeletePending = DispositionInfo->DoDeleteFile;
|
FileObject->DeletePending = DispositionInfo->DoDeleteFile;
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatQueryInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the specified file information
|
* FUNCTION: Retrieve the specified file information
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FILE_INFORMATION_CLASS FileInformationClass =
|
FILE_INFORMATION_CLASS FileInformationClass =
|
||||||
Stack->Parameters.QueryFile.FileInformationClass;
|
Stack->Parameters.QueryFile.FileInformationClass;
|
||||||
PFILE_OBJECT FileObject = NULL;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
|
@ -138,57 +147,55 @@ NTSTATUS STDCALL FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
void *SystemBuffer;
|
void *SystemBuffer;
|
||||||
|
|
||||||
/* PRECONDITION */
|
/* PRECONDITION */
|
||||||
assert(DeviceObject != NULL);
|
assert (DeviceObject != NULL);
|
||||||
assert(Irp != NULL);
|
assert (Irp != NULL);
|
||||||
|
|
||||||
/* INITIALIZATION */
|
/* INITIALIZATION */
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
|
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
// CCB = (PVFATCCB)(FileObject->FsContext2);
|
// CCB = (PVFATCCB)(FileObject->FsContext2);
|
||||||
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
||||||
FCB = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
|
FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
|
||||||
|
|
||||||
// FIXME : determine Buffer for result :
|
// FIXME : determine Buffer for result :
|
||||||
if (Irp->MdlAddress)
|
if (Irp->MdlAddress)
|
||||||
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
SystemBuffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
else
|
else
|
||||||
SystemBuffer = Irp->UserBuffer;
|
SystemBuffer = Irp->UserBuffer;
|
||||||
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
switch(FileInformationClass) {
|
switch (FileInformationClass)
|
||||||
|
{
|
||||||
case FileStandardInformation:
|
case FileStandardInformation:
|
||||||
RC = FsdGetStandardInformation(FCB, DeviceObject, SystemBuffer);
|
RC = VfatGetStandardInformation (FCB, DeviceObject, SystemBuffer);
|
||||||
break;
|
break;
|
||||||
case FilePositionInformation:
|
case FilePositionInformation:
|
||||||
RC = FsdGetPositionInformation(FileObject,
|
RC = VfatGetPositionInformation (FileObject,
|
||||||
FCB,
|
FCB, DeviceObject, SystemBuffer);
|
||||||
DeviceObject,
|
|
||||||
SystemBuffer);
|
|
||||||
break;
|
break;
|
||||||
case FileBasicInformation:
|
case FileBasicInformation:
|
||||||
RC = FsdGetBasicInformation(FileObject,
|
RC = VfatGetBasicInformation (FileObject,
|
||||||
FCB,
|
FCB, DeviceObject, SystemBuffer);
|
||||||
DeviceObject,
|
|
||||||
SystemBuffer);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
RC=STATUS_NOT_IMPLEMENTED;
|
RC = STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = RC;
|
Irp->IoStatus.Status = RC;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return RC;
|
return RC;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatSetInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the specified file information
|
* FUNCTION: Retrieve the specified file information
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FILE_INFORMATION_CLASS FileInformationClass;
|
FILE_INFORMATION_CLASS FileInformationClass;
|
||||||
PFILE_OBJECT FileObject = NULL;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
PVFATFCB FCB = NULL;
|
PVFATFCB FCB = NULL;
|
||||||
|
@ -197,41 +204,36 @@ NTSTATUS STDCALL VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
PVOID SystemBuffer;
|
PVOID SystemBuffer;
|
||||||
|
|
||||||
/* PRECONDITION */
|
/* PRECONDITION */
|
||||||
assert(DeviceObject != NULL);
|
assert (DeviceObject != NULL);
|
||||||
assert(Irp != NULL);
|
assert (Irp != NULL);
|
||||||
|
|
||||||
DPRINT("FsdSetInformation(DeviceObject %x, Irp %x)\n",
|
DPRINT ("VfatSetInformation(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
|
||||||
DeviceObject,Irp);
|
|
||||||
|
|
||||||
/* INITIALIZATION */
|
/* INITIALIZATION */
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
|
FileInformationClass = Stack->Parameters.SetFile.FileInformationClass;
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
FCB = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
|
FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
|
||||||
|
|
||||||
// FIXME : determine Buffer for result :
|
// FIXME : determine Buffer for result :
|
||||||
if (Irp->MdlAddress)
|
if (Irp->MdlAddress)
|
||||||
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
SystemBuffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
else
|
else
|
||||||
SystemBuffer = Irp->UserBuffer;
|
SystemBuffer = Irp->UserBuffer;
|
||||||
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
DPRINT("FileInformationClass %d\n",FileInformationClass);
|
DPRINT ("FileInformationClass %d\n", FileInformationClass);
|
||||||
DPRINT("SystemBuffer %x\n",SystemBuffer);
|
DPRINT ("SystemBuffer %x\n", SystemBuffer);
|
||||||
|
|
||||||
switch(FileInformationClass)
|
switch (FileInformationClass)
|
||||||
{
|
{
|
||||||
case FilePositionInformation:
|
case FilePositionInformation:
|
||||||
RC = FsdSetPositionInformation(FileObject,
|
RC = VfatSetPositionInformation (FileObject,
|
||||||
FCB,
|
FCB, DeviceObject, SystemBuffer);
|
||||||
DeviceObject,
|
|
||||||
SystemBuffer);
|
|
||||||
break;
|
break;
|
||||||
case FileDispositionInformation:
|
case FileDispositionInformation:
|
||||||
RC = FsdSetDispositionInformation(FileObject,
|
RC = VfatSetDispositionInformation (FileObject,
|
||||||
FCB,
|
FCB, DeviceObject, SystemBuffer);
|
||||||
DeviceObject,
|
|
||||||
SystemBuffer);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
RC = STATUS_NOT_IMPLEMENTED;
|
RC = STATUS_NOT_IMPLEMENTED;
|
||||||
|
@ -239,10 +241,7 @@ NTSTATUS STDCALL VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
|
|
||||||
Irp->IoStatus.Status = RC;
|
Irp->IoStatus.Status = RC;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return RC;
|
return RC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: iface.c,v 1.44 2000/12/29 13:45:01 ekohl Exp $
|
/* $Id: iface.c,v 1.45 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -8,11 +8,15 @@
|
||||||
* UPDATE HISTORY:
|
* UPDATE HISTORY:
|
||||||
* ?? Created
|
* ?? Created
|
||||||
* 24-10-1998 Fixed bugs in long filename support
|
* 24-10-1998 Fixed bugs in long filename support
|
||||||
* Fixed a bug that prevented unsuccessful file open requests being reported
|
* Fixed a bug that prevented unsuccessful file open requests
|
||||||
* Now works with long filenames that span over a sector boundary
|
* being reported
|
||||||
|
* Now works with long filenames that span over a sector
|
||||||
|
* boundary
|
||||||
* 28-10-1998 Reads entire FAT into memory
|
* 28-10-1998 Reads entire FAT into memory
|
||||||
* VFatReadSector modified to read in more than one sector at a time
|
* VFatReadSector modified to read in more than one sector at a
|
||||||
* 7-11-1998 Fixed bug that assumed that directory data could be fragmented
|
* time
|
||||||
|
* 7-11-1998 Fixed bug that assumed that directory data could be
|
||||||
|
* fragmented
|
||||||
* 8-12-1998 Added FAT32 support
|
* 8-12-1998 Added FAT32 support
|
||||||
* Added initial writability functions
|
* Added initial writability functions
|
||||||
* WARNING: DO NOT ATTEMPT TO TEST WRITABILITY FUNCTIONS!!!
|
* WARNING: DO NOT ATTEMPT TO TEST WRITABILITY FUNCTIONS!!!
|
||||||
|
@ -36,67 +40,73 @@ static PDRIVER_OBJECT VfatDriverObject;
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
BOOLEAN FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
BOOLEAN
|
||||||
|
VfatHasFileSystem (PDEVICE_OBJECT DeviceToMount)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
||||||
* by this fsd
|
* by this fsd
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
BootSector* Boot;
|
BootSector *Boot;
|
||||||
|
|
||||||
Boot = ExAllocatePool(NonPagedPool,512);
|
Boot = ExAllocatePool (NonPagedPool, 512);
|
||||||
|
|
||||||
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)Boot);
|
VFATReadSectors (DeviceToMount, 0, 1, (UCHAR *) Boot);
|
||||||
|
|
||||||
DPRINT("Boot->SysType %.5s\n", Boot->SysType);
|
DPRINT ("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)
|
||||||
{
|
{
|
||||||
ExFreePool(Boot);
|
ExFreePool (Boot);
|
||||||
return(TRUE);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
ExFreePool(Boot);
|
ExFreePool (Boot);
|
||||||
return(FALSE);
|
return (FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
NTSTATUS
|
||||||
PDEVICE_OBJECT DeviceToMount)
|
VfatMountDevice (PDEVICE_EXTENSION DeviceExt, PDEVICE_OBJECT DeviceToMount)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Mounts the device
|
* FUNCTION: Mounts the device
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
DPRINT("Mounting VFAT device...");
|
DPRINT ("Mounting VFAT device...");
|
||||||
DPRINT("DeviceExt %x\n",DeviceExt);
|
DPRINT ("DeviceExt %x\n", DeviceExt);
|
||||||
|
|
||||||
DeviceExt->Boot = ExAllocatePool(NonPagedPool,512);
|
DeviceExt->Boot = ExAllocatePool (NonPagedPool, 512);
|
||||||
VFATReadSectors(DeviceToMount, 0, 1, (UCHAR *)DeviceExt->Boot);
|
VFATReadSectors (DeviceToMount, 0, 1, (UCHAR *) DeviceExt->Boot);
|
||||||
|
|
||||||
DPRINT("DeviceExt->Boot->BytesPerSector %x\n",
|
DPRINT ("DeviceExt->Boot->BytesPerSector %x\n",
|
||||||
DeviceExt->Boot->BytesPerSector);
|
DeviceExt->Boot->BytesPerSector);
|
||||||
|
|
||||||
DeviceExt->FATStart=DeviceExt->Boot->ReservedSectors;
|
DeviceExt->FATStart = DeviceExt->Boot->ReservedSectors;
|
||||||
DeviceExt->rootDirectorySectors=
|
DeviceExt->rootDirectorySectors =
|
||||||
(DeviceExt->Boot->RootEntries*32)/DeviceExt->Boot->BytesPerSector;
|
(DeviceExt->Boot->RootEntries * 32) / DeviceExt->Boot->BytesPerSector;
|
||||||
DeviceExt->rootStart=
|
DeviceExt->rootStart =
|
||||||
DeviceExt->FATStart+DeviceExt->Boot->FATCount*DeviceExt->Boot->FATSectors;
|
DeviceExt->FATStart +
|
||||||
DeviceExt->dataStart=DeviceExt->rootStart+DeviceExt->rootDirectorySectors;
|
DeviceExt->Boot->FATCount * DeviceExt->Boot->FATSectors;
|
||||||
DeviceExt->FATEntriesPerSector=DeviceExt->Boot->BytesPerSector/32;
|
DeviceExt->dataStart =
|
||||||
|
DeviceExt->rootStart + DeviceExt->rootDirectorySectors;
|
||||||
|
DeviceExt->FATEntriesPerSector = DeviceExt->Boot->BytesPerSector / 32;
|
||||||
DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
|
DeviceExt->BytesPerCluster = DeviceExt->Boot->SectorsPerCluster *
|
||||||
DeviceExt->Boot->BytesPerSector;
|
DeviceExt->Boot->BytesPerSector;
|
||||||
|
|
||||||
if (strncmp(DeviceExt->Boot->SysType,"FAT12",5)==0)
|
if (strncmp (DeviceExt->Boot->SysType, "FAT12", 5) == 0)
|
||||||
{
|
{
|
||||||
DeviceExt->FatType = FAT12;
|
DeviceExt->FatType = FAT12;
|
||||||
}
|
}
|
||||||
else if (strncmp(((struct _BootSector32 *)(DeviceExt->Boot))->SysType,"FAT32",5)==0)
|
else
|
||||||
|
if (strncmp
|
||||||
|
(((struct _BootSector32 *) (DeviceExt->Boot))->SysType, "FAT32",
|
||||||
|
5) == 0)
|
||||||
{
|
{
|
||||||
DeviceExt->FatType = FAT32;
|
DeviceExt->FatType = FAT32;
|
||||||
DeviceExt->rootDirectorySectors=DeviceExt->Boot->SectorsPerCluster;
|
DeviceExt->rootDirectorySectors = DeviceExt->Boot->SectorsPerCluster;
|
||||||
DeviceExt->rootStart=
|
DeviceExt->rootStart =
|
||||||
DeviceExt->FATStart+DeviceExt->Boot->FATCount
|
DeviceExt->FATStart + DeviceExt->Boot->FATCount
|
||||||
*((struct _BootSector32 *)( DeviceExt->Boot))->FATSectors32;
|
* ((struct _BootSector32 *) (DeviceExt->Boot))->FATSectors32;
|
||||||
DeviceExt->dataStart=DeviceExt->rootStart;
|
DeviceExt->dataStart = DeviceExt->rootStart;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -105,15 +115,19 @@ NTSTATUS FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
|
||||||
// with FAT32 it's not a good idea to load always fat in memory
|
// with FAT32 it's not a good idea to load always fat in memory
|
||||||
// because on a 8GB partition with 2 KO clusters, the fat = 8 MO
|
// because on a 8GB partition with 2 KO clusters, the fat = 8 MO
|
||||||
if(DeviceExt->FatType!=FAT32)
|
if (DeviceExt->FatType != FAT32)
|
||||||
{
|
{
|
||||||
DeviceExt->FAT = ExAllocatePool(NonPagedPool, BLOCKSIZE*DeviceExt->Boot->FATSectors);
|
DeviceExt->FAT =
|
||||||
VFATReadSectors(DeviceToMount, DeviceExt->FATStart, DeviceExt->Boot->FATSectors, (UCHAR *)DeviceExt->FAT);
|
ExAllocatePool (NonPagedPool,
|
||||||
|
BLOCKSIZE * DeviceExt->Boot->FATSectors);
|
||||||
|
VFATReadSectors (DeviceToMount, DeviceExt->FATStart,
|
||||||
|
DeviceExt->Boot->FATSectors, (UCHAR *) DeviceExt->FAT);
|
||||||
}
|
}
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
NTSTATUS
|
||||||
|
VfatMount (PDEVICE_OBJECT DeviceToMount)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Mount the filesystem
|
* FUNCTION: Mount the filesystem
|
||||||
*/
|
*/
|
||||||
|
@ -121,76 +135,73 @@ NTSTATUS FsdMount(PDEVICE_OBJECT DeviceToMount)
|
||||||
PDEVICE_OBJECT DeviceObject;
|
PDEVICE_OBJECT DeviceObject;
|
||||||
PDEVICE_EXTENSION DeviceExt;
|
PDEVICE_EXTENSION DeviceExt;
|
||||||
|
|
||||||
IoCreateDevice(VfatDriverObject,
|
IoCreateDevice (VfatDriverObject,
|
||||||
sizeof(DEVICE_EXTENSION),
|
sizeof (DEVICE_EXTENSION),
|
||||||
NULL,
|
NULL, FILE_DEVICE_FILE_SYSTEM, 0, FALSE, &DeviceObject);
|
||||||
FILE_DEVICE_FILE_SYSTEM,
|
|
||||||
0,
|
|
||||||
FALSE,
|
|
||||||
&DeviceObject);
|
|
||||||
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
|
||||||
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
|
DeviceExt = (PVOID) DeviceObject->DeviceExtension;
|
||||||
// use same vpb as device disk
|
// use same vpb as device disk
|
||||||
DeviceObject->Vpb=DeviceToMount->Vpb;
|
DeviceObject->Vpb = DeviceToMount->Vpb;
|
||||||
FsdMountDevice(DeviceExt,DeviceToMount);
|
VfatMountDevice (DeviceExt, DeviceToMount);
|
||||||
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
|
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
|
||||||
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
|
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack (DeviceObject,
|
||||||
DeviceToMount);
|
DeviceToMount);
|
||||||
ExInitializeResourceLite(&DeviceExt->DirResource);
|
ExInitializeResourceLite (&DeviceExt->DirResource);
|
||||||
ExInitializeResourceLite(&DeviceExt->FatResource);
|
ExInitializeResourceLite (&DeviceExt->FatResource);
|
||||||
|
|
||||||
KeInitializeSpinLock(&DeviceExt->FcbListLock);
|
KeInitializeSpinLock (&DeviceExt->FcbListLock);
|
||||||
InitializeListHead(&DeviceExt->FcbListHead);
|
InitializeListHead (&DeviceExt->FcbListHead);
|
||||||
|
|
||||||
/* read serial number */
|
/* read serial number */
|
||||||
if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
|
if (DeviceExt->FatType == FAT12 || DeviceExt->FatType == FAT16)
|
||||||
DeviceObject->Vpb->SerialNumber =
|
DeviceObject->Vpb->SerialNumber =
|
||||||
((struct _BootSector *)(DeviceExt->Boot))->VolumeID;
|
((struct _BootSector *) (DeviceExt->Boot))->VolumeID;
|
||||||
else if (DeviceExt->FatType == FAT32)
|
else if (DeviceExt->FatType == FAT32)
|
||||||
DeviceObject->Vpb->SerialNumber =
|
DeviceObject->Vpb->SerialNumber =
|
||||||
((struct _BootSector32 *)(DeviceExt->Boot))->VolumeID;
|
((struct _BootSector32 *) (DeviceExt->Boot))->VolumeID;
|
||||||
|
|
||||||
/* read volume label */
|
/* read volume label */
|
||||||
ReadVolumeLabel (DeviceExt, DeviceObject->Vpb);
|
ReadVolumeLabel (DeviceExt, DeviceObject->Vpb);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatFileSystemControl (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: File system control
|
* FUNCTION: File system control
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
// PVPB vpb = Stack->Parameters.Mount.Vpb;
|
// PVPB vpb = Stack->Parameters.Mount.Vpb;
|
||||||
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
PDEVICE_OBJECT DeviceToMount = Stack->Parameters.Mount.DeviceObject;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
// DPRINT("VFAT FSC\n");
|
// DPRINT("VFAT FSC\n");
|
||||||
DbgPrint("VFAT FSC\n");
|
DbgPrint ("VFAT FSC\n");
|
||||||
|
|
||||||
/* FIXME: should make sure that this is actually a mount request! */
|
/* FIXME: should make sure that this is actually a mount request! */
|
||||||
|
|
||||||
if (FsdHasFileSystem(DeviceToMount))
|
if (VfatHasFileSystem (DeviceToMount))
|
||||||
{
|
{
|
||||||
DPRINT("VFAT: Recognized volume\n");
|
DPRINT ("VFAT: Recognized volume\n");
|
||||||
Status = FsdMount(DeviceToMount);
|
Status = VfatMount (DeviceToMount);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DPRINT("VFAT: Unrecognized Volume\n");
|
DPRINT ("VFAT: Unrecognized Volume\n");
|
||||||
Status = STATUS_UNRECOGNIZED_VOLUME;
|
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
return(Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT _DriverObject,
|
NTSTATUS STDCALL
|
||||||
PUNICODE_STRING RegistryPath)
|
DriverEntry (PDRIVER_OBJECT _DriverObject, PUNICODE_STRING RegistryPath)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Called by the system to initalize the driver
|
* FUNCTION: Called by the system to initalize the driver
|
||||||
* ARGUMENTS:
|
* ARGUMENTS:
|
||||||
|
@ -203,40 +214,38 @@ NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT _DriverObject,
|
||||||
NTSTATUS ret;
|
NTSTATUS ret;
|
||||||
UNICODE_STRING DeviceName;
|
UNICODE_STRING DeviceName;
|
||||||
|
|
||||||
DbgPrint("VFAT 0.0.6\n");
|
DbgPrint ("VFAT 0.0.6\n");
|
||||||
|
|
||||||
VfatDriverObject = _DriverObject;
|
VfatDriverObject = _DriverObject;
|
||||||
|
|
||||||
RtlInitUnicodeString(&DeviceName, L"\\Device\\Vfat");
|
RtlInitUnicodeString (&DeviceName, L"\\Device\\Vfat");
|
||||||
ret = IoCreateDevice(VfatDriverObject,0,&DeviceName,
|
ret = IoCreateDevice (VfatDriverObject, 0, &DeviceName,
|
||||||
FILE_DEVICE_FILE_SYSTEM,0,FALSE,&DeviceObject);
|
FILE_DEVICE_FILE_SYSTEM, 0, FALSE, &DeviceObject);
|
||||||
if (ret!=STATUS_SUCCESS)
|
if (ret != STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
return(ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeviceObject->Flags = DO_DIRECT_IO;
|
DeviceObject->Flags = DO_DIRECT_IO;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
|
VfatDriverObject->MajorFunction[IRP_MJ_CLOSE] = VfatClose;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
|
VfatDriverObject->MajorFunction[IRP_MJ_CREATE] = VfatCreate;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
|
VfatDriverObject->MajorFunction[IRP_MJ_READ] = VfatRead;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
|
VfatDriverObject->MajorFunction[IRP_MJ_WRITE] = VfatWrite;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
VfatDriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
|
||||||
FsdFileSystemControl;
|
VfatFileSystemControl;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
|
||||||
FsdQueryInformation;
|
VfatQueryInformation;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
|
VfatDriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] =
|
||||||
VfatSetInformation;
|
VfatSetInformation;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
VfatDriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
|
||||||
FsdDirectoryControl;
|
VfatDirectoryControl;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
|
VfatDriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] =
|
||||||
VfatQueryVolumeInformation;
|
VfatQueryVolumeInformation;
|
||||||
VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
|
VfatDriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = VfatShutdown;
|
||||||
VfatShutdown;
|
|
||||||
|
|
||||||
VfatDriverObject->DriverUnload = NULL;
|
VfatDriverObject->DriverUnload = NULL;
|
||||||
|
|
||||||
IoRegisterFileSystem(DeviceObject);
|
IoRegisterFileSystem (DeviceObject);
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: rw.c,v 1.11 2000/12/05 17:12:16 jean Exp $
|
/* $Id: rw.c,v 1.12 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <ddk/cctypes.h>
|
|
||||||
#include <ntos/minmax.h>
|
#include <ntos/minmax.h>
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
|
@ -22,9 +21,9 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
PVOID Buffer, ULONG Length, ULONG ReadOffset,
|
VfatReadFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PULONG LengthRead)
|
PVOID Buffer, ULONG Length, ULONG ReadOffset, PULONG LengthRead)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Reads data from a file
|
* FUNCTION: Reads data from a file
|
||||||
*/
|
*/
|
||||||
|
@ -37,71 +36,71 @@ NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
ULONG TempLength;
|
ULONG TempLength;
|
||||||
|
|
||||||
/* PRECONDITION */
|
/* PRECONDITION */
|
||||||
assert(DeviceExt != NULL);
|
assert (DeviceExt != NULL);
|
||||||
assert(DeviceExt->BytesPerCluster != 0);
|
assert (DeviceExt->BytesPerCluster != 0);
|
||||||
assert(FileObject != NULL);
|
assert (FileObject != NULL);
|
||||||
assert(FileObject->FsContext != NULL);
|
assert (FileObject->FsContext != NULL);
|
||||||
|
|
||||||
DPRINT("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
|
DPRINT ("FsdReadFile(DeviceExt %x, FileObject %x, Buffer %x, "
|
||||||
"Length %d, ReadOffset %d)\n",DeviceExt,FileObject,Buffer,
|
"Length %d, ReadOffset %d)\n", DeviceExt, FileObject, Buffer,
|
||||||
Length,ReadOffset);
|
Length, ReadOffset);
|
||||||
|
|
||||||
Fcb = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
|
Fcb = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
CurrentCluster = Fcb->entry.FirstCluster
|
CurrentCluster = Fcb->entry.FirstCluster
|
||||||
+Fcb->entry.FirstClusterHigh*65536;
|
+ Fcb->entry.FirstClusterHigh * 65536;
|
||||||
else
|
else
|
||||||
CurrentCluster = Fcb->entry.FirstCluster;
|
CurrentCluster = Fcb->entry.FirstCluster;
|
||||||
FirstCluster=CurrentCluster;
|
FirstCluster = CurrentCluster;
|
||||||
DPRINT("DeviceExt->BytesPerCluster %x\n",DeviceExt->BytesPerCluster);
|
DPRINT ("DeviceExt->BytesPerCluster %x\n", DeviceExt->BytesPerCluster);
|
||||||
|
|
||||||
if ( !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
if (!(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
{
|
{
|
||||||
if (ReadOffset >= Fcb->entry.FileSize)
|
if (ReadOffset >= Fcb->entry.FileSize)
|
||||||
{
|
{
|
||||||
return(STATUS_END_OF_FILE);
|
return (STATUS_END_OF_FILE);
|
||||||
}
|
}
|
||||||
if ((ReadOffset + Length) > Fcb->entry.FileSize)
|
if ((ReadOffset + Length) > Fcb->entry.FileSize)
|
||||||
{
|
{
|
||||||
Length = Fcb->entry.FileSize - ReadOffset;
|
Length = Fcb->entry.FileSize - ReadOffset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
*LengthRead = 0;
|
*LengthRead = 0;
|
||||||
/* FIXME: optimize by remembering the last cluster read and using if possible */
|
/* FIXME: optimize by remembering the last cluster read and using if possible */
|
||||||
Temp = ExAllocatePool(NonPagedPool,DeviceExt->BytesPerCluster);
|
Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
||||||
if(!Temp) return STATUS_UNSUCCESSFUL;
|
if (!Temp)
|
||||||
if (FirstCluster==1)
|
return STATUS_UNSUCCESSFUL;
|
||||||
|
if (FirstCluster == 1)
|
||||||
{ //root of FAT16 or FAT12
|
{ //root of FAT16 or FAT12
|
||||||
CurrentCluster=DeviceExt->rootStart+ReadOffset
|
CurrentCluster = DeviceExt->rootStart + ReadOffset
|
||||||
/(DeviceExt->BytesPerCluster)*DeviceExt->Boot->SectorsPerCluster;
|
/ (DeviceExt->BytesPerCluster) * DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (FileOffset=0; FileOffset < ReadOffset / DeviceExt->BytesPerCluster
|
for (FileOffset = 0; FileOffset < ReadOffset / DeviceExt->BytesPerCluster;
|
||||||
; FileOffset++)
|
FileOffset++)
|
||||||
{
|
{
|
||||||
CurrentCluster = GetNextCluster(DeviceExt,CurrentCluster);
|
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
if ((ReadOffset % DeviceExt->BytesPerCluster)!=0)
|
if ((ReadOffset % DeviceExt->BytesPerCluster) != 0)
|
||||||
{
|
{
|
||||||
if (FirstCluster == 1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Temp);
|
||||||
Temp);
|
|
||||||
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
VFATLoadCluster (DeviceExt, Temp, CurrentCluster);
|
||||||
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
TempLength = min (Length, DeviceExt->BytesPerCluster -
|
||||||
(ReadOffset % DeviceExt->BytesPerCluster));
|
(ReadOffset % DeviceExt->BytesPerCluster));
|
||||||
|
|
||||||
memcpy(Buffer, Temp + ReadOffset % DeviceExt->BytesPerCluster,
|
memcpy (Buffer, Temp + ReadOffset % DeviceExt->BytesPerCluster,
|
||||||
TempLength);
|
TempLength);
|
||||||
|
|
||||||
(*LengthRead) = (*LengthRead) + TempLength;
|
(*LengthRead) = (*LengthRead) + TempLength;
|
||||||
|
@ -113,21 +112,20 @@ CHECKPOINT;
|
||||||
{
|
{
|
||||||
if (FirstCluster == 1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Buffer);
|
||||||
Buffer);
|
|
||||||
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt,Buffer,CurrentCluster);
|
VFATLoadCluster (DeviceExt, Buffer, CurrentCluster);
|
||||||
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
if (CurrentCluster == 0xffffffff)
|
if (CurrentCluster == 0xffffffff)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool (Temp);
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
(*LengthRead) = (*LengthRead) + DeviceExt->BytesPerCluster;
|
(*LengthRead) = (*LengthRead) + DeviceExt->BytesPerCluster;
|
||||||
|
@ -140,24 +138,24 @@ CHECKPOINT;
|
||||||
(*LengthRead) = (*LengthRead) + Length;
|
(*LengthRead) = (*LengthRead) + Length;
|
||||||
if (FirstCluster == 1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Temp);
|
||||||
Temp);
|
|
||||||
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
VFATLoadCluster (DeviceExt, Temp, CurrentCluster);
|
||||||
CurrentCluster = GetNextCluster(DeviceExt, CurrentCluster);
|
CurrentCluster = GetNextCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
memcpy(Buffer, Temp, Length);
|
memcpy (Buffer, Temp, Length);
|
||||||
}
|
}
|
||||||
ExFreePool(Temp);
|
ExFreePool (Temp);
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatWriteFile (PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PVOID Buffer, ULONG Length, ULONG WriteOffset)
|
PVOID Buffer, ULONG Length, ULONG WriteOffset)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Writes data to file
|
* FUNCTION: Writes data to file
|
||||||
|
@ -169,62 +167,63 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PVFATFCB Fcb;
|
PVFATFCB Fcb;
|
||||||
PVFATCCB pCcb;
|
PVFATCCB pCcb;
|
||||||
PVOID Temp;
|
PVOID Temp;
|
||||||
ULONG TempLength,Length2=Length;
|
ULONG TempLength, Length2 = Length;
|
||||||
LARGE_INTEGER SystemTime, LocalTime;
|
LARGE_INTEGER SystemTime, LocalTime;
|
||||||
|
|
||||||
DPRINT1("FsdWriteFile(FileObject %x, Buffer %x, Length %x, "
|
DPRINT1 ("FsdWriteFile(FileObject %x, Buffer %x, Length %x, "
|
||||||
"WriteOffset %x\n", FileObject, Buffer, Length, WriteOffset);
|
"WriteOffset %x\n", FileObject, Buffer, Length, WriteOffset);
|
||||||
|
|
||||||
/* Locate the first cluster of the file */
|
/* Locate the first cluster of the file */
|
||||||
assert(FileObject);
|
assert (FileObject);
|
||||||
pCcb=(PVFATCCB)(FileObject->FsContext2);
|
pCcb = (PVFATCCB) (FileObject->FsContext2);
|
||||||
assert(pCcb);
|
assert (pCcb);
|
||||||
Fcb = pCcb->pFcb;
|
Fcb = pCcb->pFcb;
|
||||||
assert(Fcb);
|
assert (Fcb);
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
CurrentCluster =
|
CurrentCluster =
|
||||||
Fcb->entry.FirstCluster+Fcb->entry.FirstClusterHigh*65536;
|
Fcb->entry.FirstCluster + Fcb->entry.FirstClusterHigh * 65536;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CurrentCluster = Fcb->entry.FirstCluster;
|
CurrentCluster = Fcb->entry.FirstCluster;
|
||||||
}
|
}
|
||||||
FirstCluster=CurrentCluster;
|
FirstCluster = CurrentCluster;
|
||||||
|
|
||||||
/* Allocate a buffer to hold 1 cluster of data */
|
/* Allocate a buffer to hold 1 cluster of data */
|
||||||
Temp = ExAllocatePool(NonPagedPool, DeviceExt->BytesPerCluster);
|
Temp = ExAllocatePool (NonPagedPool, DeviceExt->BytesPerCluster);
|
||||||
assert(Temp);
|
assert (Temp);
|
||||||
|
|
||||||
/* Find the cluster according to the offset in the file */
|
/* Find the cluster according to the offset in the file */
|
||||||
if (CurrentCluster==1)
|
if (CurrentCluster == 1)
|
||||||
{
|
{
|
||||||
CurrentCluster=DeviceExt->rootStart+WriteOffset
|
CurrentCluster = DeviceExt->rootStart + WriteOffset
|
||||||
/ DeviceExt->BytesPerCluster*DeviceExt->Boot->SectorsPerCluster;
|
/ DeviceExt->BytesPerCluster * DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (CurrentCluster==0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* File of size zero
|
* File of size zero
|
||||||
*/
|
*/
|
||||||
CurrentCluster=GetNextWriteCluster(DeviceExt,0);
|
CurrentCluster = GetNextWriteCluster (DeviceExt, 0);
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
Fcb->entry.FirstClusterHigh = CurrentCluster>>16;
|
Fcb->entry.FirstClusterHigh = CurrentCluster >> 16;
|
||||||
Fcb->entry.FirstCluster = CurrentCluster;
|
Fcb->entry.FirstCluster = CurrentCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Fcb->entry.FirstCluster=CurrentCluster;
|
Fcb->entry.FirstCluster = CurrentCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (FileOffset=0;
|
for (FileOffset = 0;
|
||||||
FileOffset < WriteOffset / DeviceExt->BytesPerCluster;
|
FileOffset < WriteOffset / DeviceExt->BytesPerCluster;
|
||||||
FileOffset++)
|
FileOffset++)
|
||||||
{
|
{
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt,CurrentCluster);
|
CurrentCluster =
|
||||||
|
GetNextWriteCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
@ -235,44 +234,41 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
* then we have to write only from the specified offset
|
* then we have to write only from the specified offset
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ((WriteOffset % DeviceExt->BytesPerCluster)!=0)
|
if ((WriteOffset % DeviceExt->BytesPerCluster) != 0)
|
||||||
{
|
{
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
TempLength = min(Length,DeviceExt->BytesPerCluster -
|
TempLength = min (Length, DeviceExt->BytesPerCluster -
|
||||||
(WriteOffset % DeviceExt->BytesPerCluster));
|
(WriteOffset % DeviceExt->BytesPerCluster));
|
||||||
/* Read in the existing cluster data */
|
/* Read in the existing cluster data */
|
||||||
if (FirstCluster==1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Temp);
|
||||||
Temp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
VFATLoadCluster (DeviceExt, Temp, CurrentCluster);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Overwrite the last parts of the data as necessary */
|
/* Overwrite the last parts of the data as necessary */
|
||||||
memcpy(Temp + (WriteOffset % DeviceExt->BytesPerCluster),
|
memcpy (Temp + (WriteOffset % DeviceExt->BytesPerCluster),
|
||||||
Buffer,
|
Buffer, TempLength);
|
||||||
TempLength);
|
|
||||||
|
|
||||||
/* Write the cluster back */
|
/* Write the cluster back */
|
||||||
Length2 -= TempLength;
|
Length2 -= TempLength;
|
||||||
if (FirstCluster==1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Temp);
|
||||||
Temp);
|
|
||||||
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
|
VFATWriteCluster (DeviceExt, Temp, CurrentCluster);
|
||||||
if (Length2 >0)
|
if (Length2 > 0)
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
CurrentCluster = GetNextWriteCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
Buffer = Buffer + TempLength;
|
Buffer = Buffer + TempLength;
|
||||||
}
|
}
|
||||||
|
@ -285,23 +281,22 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool (Temp);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return (STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
Length2 -= DeviceExt->BytesPerCluster;
|
Length2 -= DeviceExt->BytesPerCluster;
|
||||||
if (FirstCluster==1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Buffer);
|
||||||
Buffer);
|
|
||||||
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
CurrentCluster += DeviceExt->Boot->SectorsPerCluster;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATWriteCluster(DeviceExt,Buffer,CurrentCluster);
|
VFATWriteCluster (DeviceExt, Buffer, CurrentCluster);
|
||||||
if (Length2 >0)
|
if (Length2 > 0)
|
||||||
CurrentCluster = GetNextWriteCluster(DeviceExt, CurrentCluster);
|
CurrentCluster = GetNextWriteCluster (DeviceExt, CurrentCluster);
|
||||||
}
|
}
|
||||||
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
Buffer = Buffer + DeviceExt->BytesPerCluster;
|
||||||
}
|
}
|
||||||
|
@ -314,34 +309,32 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
if (CurrentCluster == 0)
|
if (CurrentCluster == 0)
|
||||||
{
|
{
|
||||||
ExFreePool(Temp);
|
ExFreePool (Temp);
|
||||||
return(STATUS_UNSUCCESSFUL);
|
return (STATUS_UNSUCCESSFUL);
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
/* Read in the existing cluster data */
|
/* Read in the existing cluster data */
|
||||||
if (FirstCluster==1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATReadSectors(DeviceExt->StorageDevice,
|
VFATReadSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Temp);
|
||||||
Temp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATLoadCluster(DeviceExt,Temp,CurrentCluster);
|
VFATLoadCluster (DeviceExt, Temp, CurrentCluster);
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
memcpy(Temp, Buffer, Length2);
|
memcpy (Temp, Buffer, Length2);
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
if (FirstCluster==1)
|
if (FirstCluster == 1)
|
||||||
{
|
{
|
||||||
VFATWriteSectors(DeviceExt->StorageDevice,
|
VFATWriteSectors (DeviceExt->StorageDevice,
|
||||||
CurrentCluster,
|
CurrentCluster,
|
||||||
DeviceExt->Boot->SectorsPerCluster,
|
DeviceExt->Boot->SectorsPerCluster, Temp);
|
||||||
Temp);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
VFATWriteCluster(DeviceExt,Temp,CurrentCluster);
|
VFATWriteCluster (DeviceExt, Temp, CurrentCluster);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CHECKPOINT;
|
CHECKPOINT;
|
||||||
|
@ -350,28 +343,27 @@ NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
|
|
||||||
/* set dates and times */
|
/* set dates and times */
|
||||||
KeQuerySystemTime (&SystemTime);
|
KeQuerySystemTime (&SystemTime);
|
||||||
ExSystemTimeToLocalTime (&SystemTime,
|
ExSystemTimeToLocalTime (&SystemTime, &LocalTime);
|
||||||
&LocalTime);
|
FsdFileTimeToDosDateTime ((TIME *) & LocalTime,
|
||||||
FsdFileTimeToDosDateTime ((TIME*)&LocalTime,
|
&Fcb->entry.UpdateDate, &Fcb->entry.UpdateTime);
|
||||||
&Fcb->entry.UpdateDate,
|
|
||||||
&Fcb->entry.UpdateTime);
|
|
||||||
Fcb->entry.AccessDate = Fcb->entry.UpdateDate;
|
Fcb->entry.AccessDate = Fcb->entry.UpdateDate;
|
||||||
|
|
||||||
if (Fcb->entry.FileSize < WriteOffset+Length
|
if (Fcb->entry.FileSize < WriteOffset + Length
|
||||||
&& ! (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
&& !(Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
{
|
{
|
||||||
Fcb->entry.FileSize = WriteOffset+Length;
|
Fcb->entry.FileSize = WriteOffset + Length;
|
||||||
/*
|
/*
|
||||||
* update entry in directory
|
* update entry in directory
|
||||||
*/
|
*/
|
||||||
updEntry(DeviceExt,FileObject);
|
updEntry (DeviceExt, FileObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
ExFreePool(Temp);
|
ExFreePool (Temp);
|
||||||
return (STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatWrite (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Write to a file
|
* FUNCTION: Write to a file
|
||||||
*/
|
*/
|
||||||
|
@ -379,27 +371,28 @@ NTSTATUS STDCALL FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
ULONG Length;
|
ULONG Length;
|
||||||
PVOID Buffer;
|
PVOID Buffer;
|
||||||
ULONG Offset;
|
ULONG Offset;
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
PFILE_OBJECT FileObject = Stack->FileObject;
|
PFILE_OBJECT FileObject = Stack->FileObject;
|
||||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
|
|
||||||
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
|
DPRINT ("VfatWrite(DeviceObject %x Irp %x)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
Length = Stack->Parameters.Write.Length;
|
Length = Stack->Parameters.Write.Length;
|
||||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
|
Offset = Stack->Parameters.Write.ByteOffset.u.LowPart;
|
||||||
|
|
||||||
Status = FsdWriteFile(DeviceExt,FileObject,Buffer,Length,Offset);
|
Status = VfatWriteFile (DeviceExt, FileObject, Buffer, Length, Offset);
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = Length;
|
Irp->IoStatus.Information = Length;
|
||||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return(Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS STDCALL FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatRead (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Read from a file
|
* FUNCTION: Read from a file
|
||||||
*/
|
*/
|
||||||
|
@ -414,42 +407,36 @@ NTSTATUS STDCALL FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
ULONG LengthRead;
|
ULONG LengthRead;
|
||||||
PVFATFCB Fcb;
|
PVFATFCB Fcb;
|
||||||
|
|
||||||
DPRINT("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
|
DPRINT ("VfatRead(DeviceObject %x, Irp %x)\n", DeviceObject, Irp);
|
||||||
|
|
||||||
/* Precondition / Initialization */
|
/* Precondition / Initialization */
|
||||||
assert(Irp != NULL);
|
assert (Irp != NULL);
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
assert(Stack != NULL);
|
assert (Stack != NULL);
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
assert(FileObject != NULL);
|
assert (FileObject != NULL);
|
||||||
DeviceExt = DeviceObject->DeviceExtension;
|
DeviceExt = DeviceObject->DeviceExtension;
|
||||||
assert(DeviceExt != NULL);
|
assert (DeviceExt != NULL);
|
||||||
|
|
||||||
Length = Stack->Parameters.Read.Length;
|
Length = Stack->Parameters.Read.Length;
|
||||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
|
Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
|
||||||
|
|
||||||
/* fail if file is a directory */
|
/* fail if file is a directory */
|
||||||
Fcb = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
|
Fcb = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
|
||||||
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
if (Fcb->entry.Attrib & FILE_ATTRIBUTE_DIRECTORY)
|
||||||
{
|
{
|
||||||
Status = STATUS_FILE_IS_A_DIRECTORY;
|
Status = STATUS_FILE_IS_A_DIRECTORY;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Status = FsdReadFile(DeviceExt,
|
Status = VfatReadFile (DeviceExt,
|
||||||
FileObject,
|
FileObject, Buffer, Length, Offset, &LengthRead);
|
||||||
Buffer,
|
|
||||||
Length,
|
|
||||||
Offset,
|
|
||||||
&LengthRead);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = Status;
|
Irp->IoStatus.Status = Status;
|
||||||
Irp->IoStatus.Information = LengthRead;
|
Irp->IoStatus.Information = LengthRead;
|
||||||
IoCompleteRequest(Irp,IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return(Status);
|
return (Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: string.c,v 1.3 2000/06/29 23:35:51 dwelch Exp $
|
/* $Id: string.c,v 1.4 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -12,7 +12,6 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <ddk/cctypes.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
/* $Id: vfat.h,v 1.18 2000/12/29 13:45:01 ekohl Exp $ */
|
/* $Id: vfat.h,v 1.19 2000/12/29 23:17:12 dwelch Exp $ */
|
||||||
|
|
||||||
|
#include <ddk/ntifs.h>
|
||||||
|
|
||||||
struct _BootSector {
|
struct _BootSector {
|
||||||
unsigned char magic0, res0, magic1;
|
unsigned char magic0, res0, magic1;
|
||||||
|
@ -85,37 +87,20 @@ typedef struct
|
||||||
ULONG BytesPerCluster;
|
ULONG BytesPerCluster;
|
||||||
ULONG FatType;
|
ULONG FatType;
|
||||||
unsigned char* FAT;
|
unsigned char* FAT;
|
||||||
|
|
||||||
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
|
||||||
|
|
||||||
typedef struct _FSRTL_COMMON_FCB_HEADER{
|
|
||||||
char IsFastIoPossible;//is char the realtype ?
|
|
||||||
ERESOURCE Resource;
|
|
||||||
ERESOURCE PagingIoResource;
|
|
||||||
ULONG Flags;// is long the real type ?
|
|
||||||
LARGE_INTEGER AllocationSize;
|
|
||||||
LARGE_INTEGER FileSize;
|
|
||||||
LARGE_INTEGER ValidDataLength;
|
|
||||||
// other fields ??
|
|
||||||
} FSRTL_COMMON_FCB_HEADER;
|
|
||||||
|
|
||||||
typedef struct _SFsdNTRequiredFCB {
|
|
||||||
FSRTL_COMMON_FCB_HEADER CommonFCBHeader;
|
|
||||||
SECTION_OBJECT_POINTERS SectionObject;
|
|
||||||
ERESOURCE MainResource;
|
|
||||||
ERESOURCE PagingIoResource;
|
|
||||||
} SFsdNTRequiredFCB, *PtrSFsdNTRequiredFCB;
|
|
||||||
|
|
||||||
typedef struct _VFATFCB
|
typedef struct _VFATFCB
|
||||||
{
|
{
|
||||||
SFsdNTRequiredFCB NTRequiredFCB;
|
REACTOS_COMMON_FCB_HEADER RFCB;
|
||||||
FATDirEntry entry;
|
FATDirEntry entry;
|
||||||
WCHAR *ObjectName; // point on filename (250 chars max) in PathName
|
/* point on filename (250 chars max) in PathName */
|
||||||
WCHAR PathName[MAX_PATH];// path+filename 260 max
|
WCHAR *ObjectName;
|
||||||
long RefCount;
|
/* path+filename 260 max */
|
||||||
|
WCHAR PathName[MAX_PATH];
|
||||||
|
LONG RefCount;
|
||||||
PDEVICE_EXTENSION pDevExt;
|
PDEVICE_EXTENSION pDevExt;
|
||||||
LIST_ENTRY FcbListEntry;
|
LIST_ENTRY FcbListEntry;
|
||||||
struct _VFATFCB * parentFcb;
|
struct _VFATFCB* parentFcb;
|
||||||
} VFATFCB, *PVFATFCB;
|
} VFATFCB, *PVFATFCB;
|
||||||
|
|
||||||
typedef struct _VFATCCB
|
typedef struct _VFATCCB
|
||||||
|
@ -124,9 +109,11 @@ typedef struct _VFATCCB
|
||||||
LIST_ENTRY NextCCB;
|
LIST_ENTRY NextCCB;
|
||||||
PFILE_OBJECT PtrFileObject;
|
PFILE_OBJECT PtrFileObject;
|
||||||
LARGE_INTEGER CurrentByteOffset;
|
LARGE_INTEGER CurrentByteOffset;
|
||||||
ULONG StartSector; // for DirectoryControl
|
/* for DirectoryControl */
|
||||||
ULONG StartEntry; //for DirectoryControl
|
ULONG StartSector;
|
||||||
// PSTRING DirectorySearchPattern;// for DirectoryControl ?
|
/* for DirectoryControl */
|
||||||
|
ULONG StartEntry;
|
||||||
|
// PSTRING DirectorySearchPattern;// for DirectoryControl ?
|
||||||
} VFATCCB, *PVFATCCB;
|
} VFATCCB, *PVFATCCB;
|
||||||
|
|
||||||
|
|
||||||
|
@ -147,97 +134,135 @@ typedef struct __DOSDATE
|
||||||
WORD Year:5;
|
WORD Year:5;
|
||||||
} DOSDATE, *PDOSDATE;
|
} DOSDATE, *PDOSDATE;
|
||||||
|
|
||||||
// functions called by i/o manager :
|
/* functions called by i/o manager : */
|
||||||
NTSTATUS STDCALL DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
|
NTSTATUS STDCALL
|
||||||
NTSTATUS STDCALL FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
DriverEntry(PDRIVER_OBJECT _DriverObject,PUNICODE_STRING RegistryPath);
|
||||||
NTSTATUS STDCALL FsdRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
NTSTATUS STDCALL
|
||||||
NTSTATUS STDCALL FsdWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
VfatDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
NTSTATUS STDCALL FsdCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
NTSTATUS STDCALL
|
||||||
NTSTATUS STDCALL FsdClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
VfatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
NTSTATUS STDCALL FsdFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
NTSTATUS STDCALL
|
||||||
NTSTATUS STDCALL FsdQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
VfatWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
VfatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
VfatClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
VfatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
NTSTATUS STDCALL
|
||||||
|
VfatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
|
||||||
|
|
||||||
// internal functions in blockdev.c
|
/* internal functions in blockdev.c */
|
||||||
BOOLEAN VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
BOOLEAN
|
||||||
|
VFATReadSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
IN ULONG DiskSector,
|
IN ULONG DiskSector,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount,
|
||||||
IN UCHAR* Buffer);
|
IN UCHAR* Buffer);
|
||||||
|
|
||||||
BOOLEAN VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
BOOLEAN
|
||||||
|
VFATWriteSectors(IN PDEVICE_OBJECT pDeviceObject,
|
||||||
IN ULONG DiskSector,
|
IN ULONG DiskSector,
|
||||||
IN ULONG SectorCount,
|
IN ULONG SectorCount,
|
||||||
IN UCHAR* Buffer);
|
IN UCHAR* Buffer);
|
||||||
|
|
||||||
//internal functions in dir.c :
|
/* internal functions in dir.c : */
|
||||||
BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime);
|
BOOL FsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime);
|
||||||
BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime);
|
BOOL FsdFileTimeToDosDateTime(TIME *FileTime,WORD *pwDosDate,WORD *pwDosTime);
|
||||||
|
|
||||||
//internal functions in iface.c :
|
/* internal functions in iface.c : */
|
||||||
NTSTATUS FindFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
NTSTATUS
|
||||||
|
FindFile(PDEVICE_EXTENSION DeviceExt, PVFATFCB Fcb,
|
||||||
PVFATFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
|
PVFATFCB Parent, PWSTR FileToFind,ULONG *StartSector,ULONG *Entry);
|
||||||
NTSTATUS FsdCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject);
|
NTSTATUS
|
||||||
NTSTATUS FsdGetStandardInformation(PVFATFCB FCB, PDEVICE_OBJECT DeviceObject,
|
VfatCloseFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject);
|
||||||
|
NTSTATUS
|
||||||
|
VfatGetStandardInformation(PVFATFCB FCB, PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_STANDARD_INFORMATION StandardInfo);
|
PFILE_STANDARD_INFORMATION StandardInfo);
|
||||||
NTSTATUS FsdOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatOpenFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PWSTR FileName);
|
PWSTR FileName);
|
||||||
NTSTATUS FsdReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatReadFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PVOID Buffer, ULONG Length, ULONG ReadOffset,
|
PVOID Buffer, ULONG Length, ULONG ReadOffset,
|
||||||
PULONG LengthRead);
|
PULONG LengthRead);
|
||||||
NTSTATUS FsdWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
VfatWriteFile(PDEVICE_EXTENSION DeviceExt, PFILE_OBJECT FileObject,
|
||||||
PVOID Buffer, ULONG Length, ULONG WriteOffset);
|
PVOID Buffer, ULONG Length, ULONG WriteOffset);
|
||||||
ULONG GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster);
|
ULONG
|
||||||
BOOLEAN IsDeletedEntry(PVOID Block, ULONG Offset);
|
GetNextWriteCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster);
|
||||||
BOOLEAN IsLastEntry(PVOID Block, ULONG Offset);
|
BOOLEAN
|
||||||
wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
|
IsDeletedEntry(PVOID Block, ULONG Offset);
|
||||||
void VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster);
|
BOOLEAN
|
||||||
|
IsLastEntry(PVOID Block, ULONG Offset);
|
||||||
//internal functions in dirwr.c
|
wchar_t*
|
||||||
NTSTATUS addEntry(PDEVICE_EXTENSION DeviceExt
|
vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
|
||||||
,PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr);
|
VOID
|
||||||
NTSTATUS updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
|
VFATWriteCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* internal functions in dirwr.c */
|
||||||
|
NTSTATUS
|
||||||
|
addEntry(PDEVICE_EXTENSION DeviceExt,
|
||||||
|
PFILE_OBJECT pFileObject,ULONG RequestedOptions,UCHAR ReqAttr);
|
||||||
|
NTSTATUS
|
||||||
|
updEntry(PDEVICE_EXTENSION DeviceExt,PFILE_OBJECT pFileObject);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* String functions
|
* String functions
|
||||||
*/
|
*/
|
||||||
void RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length);
|
VOID
|
||||||
void RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length);
|
RtlAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length);
|
||||||
void vfat_initstr(wchar_t *wstr, ULONG wsize);
|
VOID
|
||||||
wchar_t * vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount);
|
RtlCatAnsiToUnicode(PWSTR Dest, PCH Source, ULONG Length);
|
||||||
wchar_t * vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
|
VOID
|
||||||
wchar_t * vfat_movstr(wchar_t *src, ULONG dpos, ULONG spos, ULONG len);
|
vfat_initstr(wchar_t *wstr, ULONG wsize);
|
||||||
BOOLEAN wstrcmpi(PWSTR s1, PWSTR s2);
|
wchar_t*
|
||||||
BOOLEAN wstrcmpjoki(PWSTR s1, PWSTR s2);
|
vfat_wcsncat(wchar_t * dest, const wchar_t * src,size_t wstart, size_t wcount);
|
||||||
|
wchar_t*
|
||||||
|
vfat_wcsncpy(wchar_t * dest, const wchar_t *src,size_t wcount);
|
||||||
|
wchar_t*
|
||||||
|
vfat_movstr(wchar_t *src, ULONG dpos, ULONG spos, ULONG len);
|
||||||
|
BOOLEAN
|
||||||
|
wstrcmpi(PWSTR s1, PWSTR s2);
|
||||||
|
BOOLEAN
|
||||||
|
wstrcmpjoki(PWSTR s1, PWSTR s2);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* functions from fat.c
|
* functions from fat.c
|
||||||
*/
|
*/
|
||||||
ULONG ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster);
|
ULONG
|
||||||
ULONG GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster);
|
ClusterToSector(PDEVICE_EXTENSION DeviceExt, ULONG Cluster);
|
||||||
VOID VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster);
|
ULONG
|
||||||
ULONG FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
|
GetNextCluster(PDEVICE_EXTENSION DeviceExt, ULONG CurrentCluster);
|
||||||
ULONG FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
|
VOID
|
||||||
ULONG FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
|
VFATLoadCluster(PDEVICE_EXTENSION DeviceExt, PVOID Buffer, ULONG Cluster);
|
||||||
|
ULONG
|
||||||
|
FAT12CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
|
||||||
|
ULONG
|
||||||
|
FAT16CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
|
||||||
|
ULONG
|
||||||
|
FAT32CountAvailableClusters(PDEVICE_EXTENSION DeviceExt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* functions from volume.c
|
* functions from volume.c
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
NTSTATUS STDCALL
|
||||||
|
VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* functions from finfo.c
|
* functions from finfo.c
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
NTSTATUS STDCALL
|
||||||
|
VfatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From create.c
|
* From create.c
|
||||||
*/
|
*/
|
||||||
NTSTATUS ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
|
NTSTATUS
|
||||||
|
ReadVolumeLabel(PDEVICE_EXTENSION DeviceExt, PVPB Vpb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* functions from shutdown.c
|
* functions from shutdown.c
|
||||||
*/
|
*/
|
||||||
NTSTATUS STDCALL VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
NTSTATUS STDCALL VfatShutdown(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: volume.c,v 1.4 2000/09/12 10:12:13 jean Exp $
|
/* $Id: volume.c,v 1.5 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -11,7 +11,6 @@
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
#include <ddk/cctypes.h>
|
|
||||||
|
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
@ -20,16 +19,17 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
NTSTATUS FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
|
NTSTATUS
|
||||||
|
FsdGetFsVolumeInformation (PFILE_OBJECT FileObject,
|
||||||
PVFATFCB FCB,
|
PVFATFCB FCB,
|
||||||
PDEVICE_OBJECT DeviceObject,
|
PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_FS_VOLUME_INFORMATION FsVolumeInfo)
|
PFILE_FS_VOLUME_INFORMATION FsVolumeInfo)
|
||||||
{
|
{
|
||||||
DPRINT("FsdGetFsVolumeInformation()\n");
|
DPRINT ("FsdGetFsVolumeInformation()\n");
|
||||||
DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
|
DPRINT ("FsVolumeInfo = %p\n", FsVolumeInfo);
|
||||||
|
|
||||||
if (!FsVolumeInfo)
|
if (!FsVolumeInfo)
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
|
|
||||||
|
|
||||||
/* valid entries */
|
/* valid entries */
|
||||||
|
@ -41,44 +41,47 @@ NTSTATUS FsdGetFsVolumeInformation(PFILE_OBJECT FileObject,
|
||||||
FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
|
FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
|
||||||
FsVolumeInfo->SupportsObjects = FALSE;
|
FsVolumeInfo->SupportsObjects = FALSE;
|
||||||
|
|
||||||
DPRINT("Finished FsdGetFsVolumeInformation()\n");
|
DPRINT ("Finished FsdGetFsVolumeInformation()\n");
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS FsdGetFsAttributeInformation(PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo)
|
NTSTATUS
|
||||||
|
FsdGetFsAttributeInformation (PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo)
|
||||||
{
|
{
|
||||||
DPRINT("FsdGetFsAttributeInformation()\n");
|
DPRINT ("FsdGetFsAttributeInformation()\n");
|
||||||
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
|
DPRINT ("FsAttributeInfo = %p\n", FsAttributeInfo);
|
||||||
|
|
||||||
if (!FsAttributeInfo)
|
if (!FsAttributeInfo)
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
|
|
||||||
FsAttributeInfo->FileSystemAttributes = FS_CASE_IS_PRESERVED;
|
FsAttributeInfo->FileSystemAttributes = FS_CASE_IS_PRESERVED;
|
||||||
FsAttributeInfo->MaximumComponentNameLength = 255;
|
FsAttributeInfo->MaximumComponentNameLength = 255;
|
||||||
FsAttributeInfo->FileSystemNameLength = 3;
|
FsAttributeInfo->FileSystemNameLength = 3;
|
||||||
wcscpy (FsAttributeInfo->FileSystemName, L"FAT");
|
wcscpy (FsAttributeInfo->FileSystemName, L"FAT");
|
||||||
|
|
||||||
DPRINT("Finished FsdGetFsAttributeInformation()\n");
|
DPRINT ("Finished FsdGetFsAttributeInformation()\n");
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
|
NTSTATUS
|
||||||
|
FsdGetFsSizeInformation (PDEVICE_OBJECT DeviceObject,
|
||||||
PFILE_FS_SIZE_INFORMATION FsSizeInfo)
|
PFILE_FS_SIZE_INFORMATION FsSizeInfo)
|
||||||
{
|
{
|
||||||
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
||||||
|
|
||||||
DPRINT("FsdGetFsSizeInformation()\n");
|
DPRINT ("FsdGetFsSizeInformation()\n");
|
||||||
DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
|
DPRINT ("FsSizeInfo = %p\n", FsSizeInfo);
|
||||||
|
|
||||||
if (!FsSizeInfo)
|
if (!FsSizeInfo)
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
|
|
||||||
if (DeviceExt->FatType == FAT32)
|
if (DeviceExt->FatType == FAT32)
|
||||||
{
|
{
|
||||||
struct _BootSector32 *BootSect = (struct _BootSector32 *)DeviceExt->Boot;
|
struct _BootSector32 *BootSect =
|
||||||
|
(struct _BootSector32 *) DeviceExt->Boot;
|
||||||
|
|
||||||
if (BootSect->Sectors)
|
if (BootSect->Sectors)
|
||||||
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->Sectors;
|
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->Sectors;
|
||||||
|
@ -86,14 +89,14 @@ NTSTATUS FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->SectorsHuge;
|
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->SectorsHuge;
|
||||||
|
|
||||||
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
||||||
FAT32CountAvailableClusters(DeviceExt);
|
FAT32CountAvailableClusters (DeviceExt);
|
||||||
|
|
||||||
FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
|
FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
|
||||||
FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
|
FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
struct _BootSector *BootSect = (struct _BootSector *)DeviceExt->Boot;
|
struct _BootSector *BootSect = (struct _BootSector *) DeviceExt->Boot;
|
||||||
|
|
||||||
if (BootSect->Sectors)
|
if (BootSect->Sectors)
|
||||||
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->Sectors;
|
FsSizeInfo->TotalAllocationUnits.QuadPart = BootSect->Sectors;
|
||||||
|
@ -102,27 +105,28 @@ NTSTATUS FsdGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
|
||||||
|
|
||||||
if (DeviceExt->FatType == FAT16)
|
if (DeviceExt->FatType == FAT16)
|
||||||
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
||||||
FAT16CountAvailableClusters(DeviceExt);
|
FAT16CountAvailableClusters (DeviceExt);
|
||||||
else
|
else
|
||||||
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
FsSizeInfo->AvailableAllocationUnits.QuadPart =
|
||||||
FAT12CountAvailableClusters(DeviceExt);
|
FAT12CountAvailableClusters (DeviceExt);
|
||||||
|
|
||||||
FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
|
FsSizeInfo->SectorsPerAllocationUnit = BootSect->SectorsPerCluster;
|
||||||
FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
|
FsSizeInfo->BytesPerSector = BootSect->BytesPerSector;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINT("Finished FsdGetFsSizeInformation()\n");
|
DPRINT ("Finished FsdGetFsSizeInformation()\n");
|
||||||
|
|
||||||
return(STATUS_SUCCESS);
|
return (STATUS_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NTSTATUS STDCALL VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
NTSTATUS STDCALL
|
||||||
|
VfatQueryVolumeInformation (PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
/*
|
/*
|
||||||
* FUNCTION: Retrieve the specified file information
|
* FUNCTION: Retrieve the specified file information
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
|
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FILE_INFORMATION_CLASS FileInformationClass =
|
FILE_INFORMATION_CLASS FileInformationClass =
|
||||||
Stack->Parameters.QueryVolume.FileInformationClass;
|
Stack->Parameters.QueryVolume.FileInformationClass;
|
||||||
PFILE_OBJECT FileObject = NULL;
|
PFILE_OBJECT FileObject = NULL;
|
||||||
|
@ -133,56 +137,52 @@ NTSTATUS STDCALL VfatQueryVolumeInformation(PDEVICE_OBJECT DeviceObject, PIRP Ir
|
||||||
void *SystemBuffer;
|
void *SystemBuffer;
|
||||||
|
|
||||||
/* PRECONDITION */
|
/* PRECONDITION */
|
||||||
assert(DeviceObject != NULL);
|
assert (DeviceObject != NULL);
|
||||||
assert(Irp != NULL);
|
assert (Irp != NULL);
|
||||||
|
|
||||||
DPRINT("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
|
DPRINT ("FsdQueryVolumeInformation(DeviceObject %x, Irp %x)\n",
|
||||||
DeviceObject,Irp);
|
DeviceObject, Irp);
|
||||||
|
|
||||||
/* INITIALIZATION */
|
/* INITIALIZATION */
|
||||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
Stack = IoGetCurrentIrpStackLocation (Irp);
|
||||||
FileInformationClass = Stack->Parameters.QueryVolume.FileInformationClass;
|
FileInformationClass = Stack->Parameters.QueryVolume.FileInformationClass;
|
||||||
FileObject = Stack->FileObject;
|
FileObject = Stack->FileObject;
|
||||||
// CCB = (PVfatCCB)(FileObject->FsContext2);
|
// CCB = (PVfatCCB)(FileObject->FsContext2);
|
||||||
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
// FCB = CCB->Buffer; // Should be CCB->FCB???
|
||||||
FCB = ((PVFATCCB)(FileObject->FsContext2))->pFcb;
|
FCB = ((PVFATCCB) (FileObject->FsContext2))->pFcb;
|
||||||
|
|
||||||
// FIXME : determine Buffer for result :
|
// FIXME : determine Buffer for result :
|
||||||
if (Irp->MdlAddress)
|
if (Irp->MdlAddress)
|
||||||
SystemBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
SystemBuffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||||
else
|
else
|
||||||
SystemBuffer = Irp->UserBuffer;
|
SystemBuffer = Irp->UserBuffer;
|
||||||
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
// SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
|
||||||
DPRINT("FileInformationClass %d\n",FileInformationClass);
|
DPRINT ("FileInformationClass %d\n", FileInformationClass);
|
||||||
DPRINT("SystemBuffer %x\n",SystemBuffer);
|
DPRINT ("SystemBuffer %x\n", SystemBuffer);
|
||||||
|
|
||||||
switch (FileInformationClass)
|
switch (FileInformationClass)
|
||||||
{
|
{
|
||||||
case FileFsVolumeInformation:
|
case FileFsVolumeInformation:
|
||||||
RC = FsdGetFsVolumeInformation(FileObject,
|
RC = FsdGetFsVolumeInformation (FileObject,
|
||||||
FCB,
|
FCB, DeviceObject, SystemBuffer);
|
||||||
DeviceObject,
|
|
||||||
SystemBuffer);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FileFsAttributeInformation:
|
case FileFsAttributeInformation:
|
||||||
RC = FsdGetFsAttributeInformation(SystemBuffer);
|
RC = FsdGetFsAttributeInformation (SystemBuffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FileFsSizeInformation:
|
case FileFsSizeInformation:
|
||||||
RC = FsdGetFsSizeInformation(DeviceObject, SystemBuffer);
|
RC = FsdGetFsSizeInformation (DeviceObject, SystemBuffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
RC=STATUS_NOT_IMPLEMENTED;
|
RC = STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Irp->IoStatus.Status = RC;
|
Irp->IoStatus.Status = RC;
|
||||||
Irp->IoStatus.Information = 0;
|
Irp->IoStatus.Information = 0;
|
||||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
IoCompleteRequest (Irp, IO_NO_INCREMENT);
|
||||||
|
|
||||||
return RC;
|
return RC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -73,4 +73,9 @@ typedef struct _SECTION_OBJECT_POINTERS
|
||||||
|
|
||||||
typedef VOID (*PFLUSH_TO_LSN)(IN PVOID LogHandle, IN LARGE_INTEGER Lsn);
|
typedef VOID (*PFLUSH_TO_LSN)(IN PVOID LogHandle, IN LARGE_INTEGER Lsn);
|
||||||
|
|
||||||
|
typedef struct _REACTOS_COMMON_FCB_HEADER
|
||||||
|
{
|
||||||
|
PBCB Bcb;
|
||||||
|
} REACTOS_COMMON_FCB_HEADER;
|
||||||
|
|
||||||
#endif /* __INCLUDE_DDK_CCTYPES_H */
|
#endif /* __INCLUDE_DDK_CCTYPES_H */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: iotypes.h,v 1.20 2000/10/06 22:53:21 ekohl Exp $
|
/* $Id: iotypes.h,v 1.21 2000/12/29 23:17:11 dwelch Exp $
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -267,6 +267,11 @@ typedef struct _IO_COMPLETION_CONTEXT
|
||||||
#define FO_HANDLE_CREATED 0x00040000
|
#define FO_HANDLE_CREATED 0x00040000
|
||||||
#define FO_FILE_FAST_IO_READ 0x00080000
|
#define FO_FILE_FAST_IO_READ 0x00080000
|
||||||
|
|
||||||
|
#define FO_DIRECT_CACHE_READ 0x72000001
|
||||||
|
#define FO_DIRECT_CACHE_WRITE 0x72000002
|
||||||
|
#define FO_DIRECT_CACHE_PAGING_READ 0x72000004
|
||||||
|
#define FO_DIRECT_CACHE_PAGING_WRITE 0x72000008
|
||||||
|
|
||||||
typedef struct _FILE_OBJECT
|
typedef struct _FILE_OBJECT
|
||||||
{
|
{
|
||||||
CSHORT Type;
|
CSHORT Type;
|
||||||
|
|
|
@ -34,39 +34,24 @@ typedef struct _CACHE_SEGMENT
|
||||||
PBCB Bcb;
|
PBCB Bcb;
|
||||||
} CACHE_SEGMENT, *PCACHE_SEGMENT;
|
} CACHE_SEGMENT, *PCACHE_SEGMENT;
|
||||||
|
|
||||||
NTSTATUS
|
NTSTATUS STDCALL
|
||||||
STDCALL
|
CcFlushCachePage (PCACHE_SEGMENT CacheSeg);
|
||||||
CcFlushCachePage (
|
NTSTATUS STDCALL
|
||||||
PCACHE_SEGMENT CacheSeg
|
CcReleaseCachePage (PBCB Bcb,
|
||||||
);
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
CcReleaseCachePage (
|
|
||||||
PBCB Bcb,
|
|
||||||
PCACHE_SEGMENT CacheSeg,
|
PCACHE_SEGMENT CacheSeg,
|
||||||
BOOLEAN Valid
|
BOOLEAN Valid);
|
||||||
);
|
NTSTATUS STDCALL
|
||||||
NTSTATUS
|
CcRequestCachePage (PBCB Bcb,
|
||||||
STDCALL
|
|
||||||
CcRequestCachePage (
|
|
||||||
PBCB Bcb,
|
|
||||||
ULONG FileOffset,
|
ULONG FileOffset,
|
||||||
PVOID * BaseAddress,
|
PVOID* BaseAddress,
|
||||||
PBOOLEAN UptoDate,
|
PBOOLEAN UptoDate,
|
||||||
PCACHE_SEGMENT * CacheSeg
|
PCACHE_SEGMENT* CacheSeg);
|
||||||
);
|
NTSTATUS STDCALL
|
||||||
NTSTATUS
|
CcInitializeFileCache (PFILE_OBJECT FileObject,
|
||||||
STDCALL
|
PBCB* Bcb);
|
||||||
CcInitializeFileCache (
|
NTSTATUS STDCALL
|
||||||
PFILE_OBJECT FileObject,
|
CcReleaseFileCache (PFILE_OBJECT FileObject,
|
||||||
PBCB * Bcb
|
PBCB Bcb);
|
||||||
);
|
|
||||||
NTSTATUS
|
|
||||||
STDCALL
|
|
||||||
CcReleaseFileCache (
|
|
||||||
PFILE_OBJECT FileObject,
|
|
||||||
PBCB Bcb
|
|
||||||
);
|
|
||||||
|
|
||||||
#include <ddk/cctypes.h>
|
#include <ddk/cctypes.h>
|
||||||
|
|
||||||
|
|
|
@ -304,6 +304,9 @@ NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG Count);
|
||||||
NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
|
NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG Count);
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
MmCreatePhysicalMemorySection(VOID);
|
MmCreatePhysicalMemorySection(VOID);
|
||||||
|
PVOID
|
||||||
|
MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
|
PHYSICAL_ADDRESS HighestAcceptableAddress);
|
||||||
|
|
||||||
#define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
|
#define MM_PHYSICAL_PAGE_MPW_PENDING (0x8)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: cont.c,v 1.4 2000/03/29 13:11:54 dwelch Exp $
|
/* $Id: cont.c,v 1.5 2000/12/29 23:17:12 dwelch Exp $
|
||||||
*
|
*
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
* PROJECT: ReactOS kernel
|
* PROJECT: ReactOS kernel
|
||||||
|
@ -12,6 +12,7 @@
|
||||||
/* INCLUDES *****************************************************************/
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
|
#include <internal/mm.h>
|
||||||
|
|
||||||
#include <internal/debug.h>
|
#include <internal/debug.h>
|
||||||
|
|
||||||
|
@ -44,11 +45,38 @@
|
||||||
* REVISIONS
|
* REVISIONS
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
PVOID STDCALL MmAllocateContiguousMemory (
|
PVOID STDCALL
|
||||||
IN ULONG NumberOfBytes,
|
MmAllocateContiguousMemory (IN ULONG NumberOfBytes,
|
||||||
IN PHYSICAL_ADDRESS HighestAcceptableAddress)
|
IN PHYSICAL_ADDRESS HighestAcceptableAddress)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PMEMORY_AREA MArea;
|
||||||
|
NTSTATUS Status;
|
||||||
|
PVOID BaseAddress;
|
||||||
|
PVOID PBase;
|
||||||
|
ULONG i;
|
||||||
|
|
||||||
|
Status = MmCreateMemoryArea(NULL,
|
||||||
|
MmGetKernelAddressSpace(),
|
||||||
|
MEMORY_AREA_CONTINUOUS_MEMORY,
|
||||||
|
&BaseAddress,
|
||||||
|
NumberOfBytes,
|
||||||
|
0,
|
||||||
|
&MArea);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
PBase = MmGetContinuousPages(NumberOfBytes,
|
||||||
|
HighestAcceptableAddress);
|
||||||
|
for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / 4096); i++)
|
||||||
|
{
|
||||||
|
MmCreateVirtualMapping(NULL,
|
||||||
|
BaseAddress + (i * 4096),
|
||||||
|
PAGE_EXECUTE_READWRITE,
|
||||||
|
(ULONG)(PBase + (i * 4096)));
|
||||||
|
}
|
||||||
|
return(BaseAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -74,9 +102,13 @@ PVOID STDCALL MmAllocateContiguousMemory (
|
||||||
* REVISIONS
|
* REVISIONS
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
VOID STDCALL MmFreeContiguousMemory(IN PVOID BaseAddress)
|
VOID STDCALL
|
||||||
|
MmFreeContiguousMemory(IN PVOID BaseAddress)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
MmFreeMemoryArea(MmGetKernelAddressSpace(),
|
||||||
|
BaseAddress,
|
||||||
|
0,
|
||||||
|
TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,62 @@ static LIST_ENTRY BiosPageListHead;
|
||||||
|
|
||||||
/* FUNCTIONS *************************************************************/
|
/* FUNCTIONS *************************************************************/
|
||||||
|
|
||||||
|
PVOID
|
||||||
|
MmGetContinuousPages(ULONG NumberOfBytes,
|
||||||
|
PHYSICAL_ADDRESS HighestAcceptableAddress)
|
||||||
|
{
|
||||||
|
ULONG NrPages;
|
||||||
|
ULONG i;
|
||||||
|
ULONG start;
|
||||||
|
ULONG length;
|
||||||
|
KIRQL oldIrql;
|
||||||
|
|
||||||
|
NrPages = PAGE_ROUND_UP(NumberOfBytes) / PAGESIZE;
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&PageListLock, &oldIrql);
|
||||||
|
|
||||||
|
start = -1;
|
||||||
|
length = 0;
|
||||||
|
for (i = 0; i < (HighestAcceptableAddress.QuadPart / PAGESIZE); i++)
|
||||||
|
{
|
||||||
|
if (MmPageArray[i].Flags & MM_PHYSICAL_PAGE_FREE)
|
||||||
|
{
|
||||||
|
if (start == -1)
|
||||||
|
{
|
||||||
|
start = i;
|
||||||
|
length = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length++;
|
||||||
|
}
|
||||||
|
if (length == NrPages)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (start != -1)
|
||||||
|
{
|
||||||
|
start = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (start == -1)
|
||||||
|
{
|
||||||
|
KeReleaseSpinLock(&PageListLock, oldIrql);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
for (i = start; i < (start + length); i++)
|
||||||
|
{
|
||||||
|
RemoveEntryList(&MmPageArray[i].ListEntry);
|
||||||
|
MmPageArray[i].Flags = MM_PHYSICAL_PAGE_USED;
|
||||||
|
MmPageArray[i].ReferenceCount = 1;
|
||||||
|
MmPageArray[i].LockCount = 0;
|
||||||
|
MmPageArray[i].SavedSwapEntry = 0;
|
||||||
|
InsertTailList(&UsedPageListHead, &MmPageArray[i].ListEntry);
|
||||||
|
}
|
||||||
|
return((PVOID)(start * 4096));
|
||||||
|
}
|
||||||
|
|
||||||
PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
PVOID MmInitializePageList(PVOID FirstPhysKernelAddress,
|
||||||
PVOID LastPhysKernelAddress,
|
PVOID LastPhysKernelAddress,
|
||||||
ULONG MemorySizeInPages,
|
ULONG MemorySizeInPages,
|
||||||
|
|
Loading…
Reference in a new issue