2003-01-11 16:00:16 +00:00
|
|
|
/* $Id: finfo.c,v 1.24 2003/01/11 16:00:16 hbirr Exp $
|
1999-12-11 21:14:49 +00:00
|
|
|
*
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS kernel
|
|
|
|
* FILE: services/fs/vfat/finfo.c
|
|
|
|
* PURPOSE: VFAT Filesystem
|
|
|
|
* PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *****************************************************************/
|
|
|
|
|
2000-02-22 02:02:08 +00:00
|
|
|
#include <ddk/ntddk.h>
|
1999-12-11 21:14:49 +00:00
|
|
|
#include <wchar.h>
|
|
|
|
|
|
|
|
#define NDEBUG
|
2000-06-29 23:35:53 +00:00
|
|
|
#include <debug.h>
|
1999-12-11 21:14:49 +00:00
|
|
|
|
|
|
|
#include "vfat.h"
|
|
|
|
|
|
|
|
/* FUNCTIONS ****************************************************************/
|
|
|
|
|
2001-03-07 13:44:41 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatGetStandardInformation(PVFATFCB FCB,
|
2001-06-12 12:35:42 +00:00
|
|
|
PFILE_STANDARD_INFORMATION StandardInfo,
|
|
|
|
PULONG BufferLength)
|
1999-12-11 21:14:49 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the standard file information
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
|
1999-12-11 21:14:49 +00:00
|
|
|
/* PRECONDITION */
|
2000-12-29 23:17:12 +00:00
|
|
|
assert (StandardInfo != NULL);
|
|
|
|
assert (FCB != NULL);
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
RtlZeroMemory(StandardInfo,
|
|
|
|
sizeof(FILE_STANDARD_INFORMATION));
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-11-01 10:44:11 +00:00
|
|
|
StandardInfo->AllocationSize = FCB->RFCB.AllocationSize;
|
|
|
|
StandardInfo->EndOfFile = FCB->RFCB.FileSize;
|
2000-12-29 23:17:12 +00:00
|
|
|
StandardInfo->NumberOfLinks = 0;
|
2001-11-01 10:44:11 +00:00
|
|
|
StandardInfo->DeletePending = FCB->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
|
|
|
|
StandardInfo->Directory = FCB->entry.Attrib & 0x10 ? TRUE : FALSE;
|
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
*BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
|
|
|
|
return(STATUS_SUCCESS);
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
2001-03-07 13:44:41 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatSetPositionInformation(PFILE_OBJECT FileObject,
|
2000-12-29 23:17:12 +00:00
|
|
|
PFILE_POSITION_INFORMATION PositionInfo)
|
1999-12-11 21:14:49 +00:00
|
|
|
{
|
2000-12-29 23:17:12 +00:00
|
|
|
DPRINT ("FsdSetPositionInformation()\n");
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
DPRINT ("PositionInfo %x\n", PositionInfo);
|
|
|
|
DPRINT ("Setting position %d\n", PositionInfo->CurrentByteOffset.u.LowPart);
|
|
|
|
memcpy (&FileObject->CurrentByteOffset, &PositionInfo->CurrentByteOffset,
|
|
|
|
sizeof (LARGE_INTEGER));
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
return (STATUS_SUCCESS);
|
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-03-07 13:44:41 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatGetPositionInformation(PFILE_OBJECT FileObject,
|
2000-12-29 23:17:12 +00:00
|
|
|
PVFATFCB FCB,
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
PFILE_POSITION_INFORMATION PositionInfo,
|
|
|
|
PULONG BufferLength)
|
2000-12-29 23:17:12 +00:00
|
|
|
{
|
|
|
|
DPRINT ("VfatGetPositionInformation()\n");
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
|
|
|
|
PositionInfo->CurrentByteOffset.QuadPart =
|
|
|
|
FileObject->CurrentByteOffset.QuadPart;
|
|
|
|
|
|
|
|
DPRINT("Getting position %I64x\n",
|
|
|
|
PositionInfo->CurrentByteOffset.QuadPart);
|
|
|
|
|
|
|
|
*BufferLength -= sizeof(FILE_POSITION_INFORMATION);
|
|
|
|
return(STATUS_SUCCESS);
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
2002-12-27 23:50:21 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatSetBasicInformation(PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
|
|
|
PFILE_BASIC_INFORMATION BasicInfo)
|
|
|
|
{
|
|
|
|
DPRINT("VfatSetBasicInformation()\n");
|
|
|
|
|
|
|
|
assert (NULL != FileObject);
|
|
|
|
assert (NULL != FCB);
|
|
|
|
assert (NULL != DeviceExt);
|
|
|
|
assert (NULL != BasicInfo);
|
|
|
|
/* Check volume label bit */
|
|
|
|
assert(0 == (FCB->entry.Attrib & 0x08));
|
|
|
|
|
|
|
|
FsdFileTimeToDosDateTime(&(BasicInfo->CreationTime),
|
|
|
|
&(FCB->entry.CreationDate),
|
|
|
|
&(FCB->entry.CreationTime));
|
|
|
|
FsdFileTimeToDosDateTime(&(BasicInfo->LastAccessTime),
|
|
|
|
&(FCB->entry.AccessDate),
|
|
|
|
NULL);
|
|
|
|
FsdFileTimeToDosDateTime(&(BasicInfo->LastWriteTime),
|
|
|
|
&(FCB->entry.UpdateDate),
|
|
|
|
&(FCB->entry.UpdateTime));
|
|
|
|
|
|
|
|
FCB->entry.Attrib = (FCB->entry.Attrib &
|
|
|
|
(FILE_ATTRIBUTE_DIRECTORY | 0x48)) |
|
|
|
|
(BasicInfo->FileAttributes &
|
|
|
|
(FILE_ATTRIBUTE_ARCHIVE |
|
|
|
|
FILE_ATTRIBUTE_SYSTEM |
|
|
|
|
FILE_ATTRIBUTE_HIDDEN |
|
|
|
|
FILE_ATTRIBUTE_READONLY));
|
|
|
|
DPRINT("Setting attributes 0x%02x\n", FCB->entry.Attrib);
|
|
|
|
|
|
|
|
VfatUpdateEntry(DeviceExt, FileObject);
|
|
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2001-03-07 13:44:41 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatGetBasicInformation(PFILE_OBJECT FileObject,
|
2000-12-29 23:17:12 +00:00
|
|
|
PVFATFCB FCB,
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
PFILE_BASIC_INFORMATION BasicInfo,
|
|
|
|
PULONG BufferLength)
|
2000-12-29 23:17:12 +00:00
|
|
|
{
|
2001-06-12 12:35:42 +00:00
|
|
|
DPRINT("VfatGetBasicInformation()\n");
|
|
|
|
|
|
|
|
if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
|
|
|
|
FsdDosDateTimeToFileTime(FCB->entry.CreationDate,
|
|
|
|
FCB->entry.CreationTime,
|
|
|
|
&BasicInfo->CreationTime);
|
|
|
|
FsdDosDateTimeToFileTime(FCB->entry.AccessDate,
|
|
|
|
0,
|
|
|
|
&BasicInfo->LastAccessTime);
|
|
|
|
FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,
|
|
|
|
FCB->entry.UpdateTime,
|
|
|
|
&BasicInfo->LastWriteTime);
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
BasicInfo->ChangeTime = BasicInfo->LastWriteTime;
|
2000-12-29 23:17:12 +00:00
|
|
|
|
|
|
|
BasicInfo->FileAttributes = FCB->entry.Attrib;
|
2002-12-27 23:50:21 +00:00
|
|
|
/* Synthesize FILE_ATTRIBUTE_NORMAL */
|
|
|
|
if (0 == (BasicInfo->FileAttributes & (FILE_ATTRIBUTE_DIRECTORY |
|
|
|
|
FILE_ATTRIBUTE_ARCHIVE |
|
|
|
|
FILE_ATTRIBUTE_SYSTEM |
|
|
|
|
FILE_ATTRIBUTE_HIDDEN |
|
|
|
|
FILE_ATTRIBUTE_READONLY)))
|
|
|
|
{
|
|
|
|
BasicInfo->FileAttributes |= FILE_ATTRIBUTE_NORMAL;
|
|
|
|
}
|
|
|
|
DPRINT("Getting attributes 0x%02x\n", BasicInfo->FileAttributes);
|
2000-12-29 23:17:12 +00:00
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
*BufferLength -= sizeof(FILE_BASIC_INFORMATION);
|
|
|
|
return(STATUS_SUCCESS);
|
2000-12-29 23:17:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2001-03-07 13:44:41 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatSetDispositionInformation(PFILE_OBJECT FileObject,
|
2000-12-29 23:17:12 +00:00
|
|
|
PVFATFCB FCB,
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PFILE_DISPOSITION_INFORMATION DispositionInfo)
|
1999-12-11 21:14:49 +00:00
|
|
|
{
|
2001-08-14 20:47:30 +00:00
|
|
|
KIRQL oldIrql;
|
|
|
|
VFATFCB tmpFcb;
|
|
|
|
WCHAR star[2];
|
|
|
|
ULONG Index;
|
|
|
|
NTSTATUS Status = STATUS_SUCCESS;
|
|
|
|
int count;
|
|
|
|
|
|
|
|
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
|
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
DPRINT ("FsdSetDispositionInformation()\n");
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-08-14 20:47:30 +00:00
|
|
|
assert (DeviceExt != NULL);
|
2002-03-18 22:37:13 +00:00
|
|
|
assert (DeviceExt->FatInfo.BytesPerCluster != 0);
|
2001-08-14 20:47:30 +00:00
|
|
|
assert (FCB != NULL);
|
2000-12-29 23:17:12 +00:00
|
|
|
|
2001-08-14 20:47:30 +00:00
|
|
|
if (!wcscmp(FCB->PathName, L"\\") || !wcscmp(FCB->ObjectName, L"..")
|
|
|
|
|| !wcscmp(FCB->ObjectName, L"."))
|
|
|
|
{
|
|
|
|
// we cannot delete a '.', '..' or the root directory
|
|
|
|
return STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
if (DispositionInfo->DoDeleteFile)
|
|
|
|
{
|
2003-01-11 16:00:16 +00:00
|
|
|
if (MmFlushImageSection (FileObject->SectionObjectPointers, MmFlushForDelete))
|
|
|
|
{
|
|
|
|
KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql);
|
|
|
|
count = FCB->RefCount;
|
|
|
|
if (FCB->RefCount > 1)
|
|
|
|
{
|
|
|
|
DPRINT1("%d %x\n", FCB->RefCount, CcGetFileObjectFromSectionPtrs(FileObject->SectionObjectPointers));
|
|
|
|
Status = STATUS_ACCESS_DENIED;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
FCB->Flags |= FCB_DELETE_PENDING;
|
|
|
|
FileObject->DeletePending = TRUE;
|
|
|
|
}
|
|
|
|
KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
|
|
|
|
}
|
2001-08-14 20:47:30 +00:00
|
|
|
else
|
|
|
|
{
|
2003-01-11 16:00:16 +00:00
|
|
|
DPRINT1("MmFlushImageSection returned FALSE\n");
|
|
|
|
Status = STATUS_ACCESS_DENIED;
|
2001-08-14 20:47:30 +00:00
|
|
|
}
|
|
|
|
DPRINT("RefCount:%d\n", count);
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
if (NT_SUCCESS(Status) && vfatFCBIsDirectory(FCB))
|
2001-08-14 20:47:30 +00:00
|
|
|
{
|
|
|
|
memset (&tmpFcb, 0, sizeof(VFATFCB));
|
|
|
|
tmpFcb.ObjectName = tmpFcb.PathName;
|
|
|
|
star[0] = L'*';
|
|
|
|
star[1] = 0;
|
|
|
|
// skip '.' and '..', start by 2
|
|
|
|
Index = 2;
|
|
|
|
Status = FindFile (DeviceExt, &tmpFcb, FCB, star, &Index, NULL);
|
|
|
|
if (NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("found: \'%S\'\n", tmpFcb.PathName);
|
|
|
|
Status = STATUS_DIRECTORY_NOT_EMPTY;
|
|
|
|
FCB->Flags &= ~FCB_DELETE_PENDING;
|
|
|
|
FileObject->DeletePending = FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Status = STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
FileObject->DeletePending = FALSE;
|
|
|
|
return Status;
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatGetNameInformation(PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB FCB,
|
|
|
|
PDEVICE_OBJECT DeviceObject,
|
|
|
|
PFILE_NAME_INFORMATION NameInfo,
|
|
|
|
PULONG BufferLength)
|
2001-03-06 23:36:35 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the file name information
|
|
|
|
*/
|
|
|
|
{
|
2001-06-12 12:35:42 +00:00
|
|
|
ULONG NameLength;
|
|
|
|
|
2001-03-06 23:36:35 +00:00
|
|
|
assert (NameInfo != NULL);
|
|
|
|
assert (FCB != NULL);
|
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
NameLength = wcslen(FCB->PathName) * sizeof(WCHAR);
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR))
|
2001-06-12 12:35:42 +00:00
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
|
|
|
|
NameInfo->FileNameLength = NameLength;
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
memcpy(NameInfo->FileName, FCB->PathName, NameLength + sizeof(WCHAR));
|
2001-06-12 12:35:42 +00:00
|
|
|
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
*BufferLength -= (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
|
2001-03-06 23:36:35 +00:00
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-11-01 10:44:11 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatGetInternalInformation(PVFATFCB Fcb,
|
2001-11-02 22:47:36 +00:00
|
|
|
PFILE_INTERNAL_INFORMATION InternalInfo,
|
|
|
|
PULONG BufferLength)
|
2001-11-01 10:44:11 +00:00
|
|
|
{
|
|
|
|
assert (InternalInfo);
|
|
|
|
assert (Fcb);
|
2001-03-06 23:36:35 +00:00
|
|
|
|
2001-11-01 10:44:11 +00:00
|
|
|
if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
|
|
|
|
return STATUS_BUFFER_OVERFLOW;
|
|
|
|
// FIXME: get a real index, that can be used in a create operation
|
|
|
|
InternalInfo->IndexNumber.QuadPart = 0;
|
|
|
|
*BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
|
2002-07-20 00:57:36 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatGetNetworkOpenInformation(PVFATFCB Fcb,
|
|
|
|
PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
|
|
|
|
PULONG BufferLength)
|
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the file network open information
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
assert (NetworkInfo);
|
|
|
|
assert (Fcb);
|
|
|
|
|
|
|
|
if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
|
|
|
|
return(STATUS_BUFFER_OVERFLOW);
|
|
|
|
|
|
|
|
FsdDosDateTimeToFileTime(Fcb->entry.CreationDate,
|
|
|
|
Fcb->entry.CreationTime,
|
|
|
|
&NetworkInfo->CreationTime);
|
|
|
|
FsdDosDateTimeToFileTime(Fcb->entry.AccessDate,
|
|
|
|
0,
|
|
|
|
&NetworkInfo->LastAccessTime);
|
|
|
|
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
|
|
|
Fcb->entry.UpdateTime,
|
|
|
|
&NetworkInfo->LastWriteTime);
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
NetworkInfo->ChangeTime = NetworkInfo->LastWriteTime;
|
2002-07-20 00:57:36 +00:00
|
|
|
NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
|
|
|
|
NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
|
|
|
|
NetworkInfo->FileAttributes = Fcb->entry.Attrib;
|
|
|
|
|
|
|
|
*BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
|
2002-07-20 11:44:37 +00:00
|
|
|
static NTSTATUS
|
|
|
|
VfatGetAllInformation(PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB Fcb,
|
|
|
|
PFILE_ALL_INFORMATION Info,
|
|
|
|
PULONG BufferLength)
|
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the all file information
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
ULONG NameLength;
|
|
|
|
|
|
|
|
assert (Info);
|
|
|
|
assert (Fcb);
|
|
|
|
|
|
|
|
NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR))
|
2002-07-20 11:44:37 +00:00
|
|
|
return(STATUS_BUFFER_OVERFLOW);
|
|
|
|
|
|
|
|
/* Basic Information */
|
|
|
|
FsdDosDateTimeToFileTime(Fcb->entry.CreationDate,
|
|
|
|
Fcb->entry.CreationTime,
|
|
|
|
&Info->BasicInformation.CreationTime);
|
|
|
|
FsdDosDateTimeToFileTime(Fcb->entry.AccessDate,
|
|
|
|
0,
|
|
|
|
&Info->BasicInformation.LastAccessTime);
|
|
|
|
FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
|
|
|
|
Fcb->entry.UpdateTime,
|
|
|
|
&Info->BasicInformation.LastWriteTime);
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
Info->BasicInformation.ChangeTime = Info->BasicInformation.LastWriteTime;
|
2002-07-20 11:44:37 +00:00
|
|
|
Info->BasicInformation.FileAttributes = Fcb->entry.Attrib;
|
|
|
|
|
|
|
|
/* Standard Information */
|
|
|
|
Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
|
|
|
|
Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
|
|
|
|
Info->StandardInformation.NumberOfLinks = 0;
|
|
|
|
Info->StandardInformation.DeletePending = Fcb->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
|
|
|
|
Info->StandardInformation.Directory = Fcb->entry.Attrib & 0x10 ? TRUE : FALSE;
|
|
|
|
|
|
|
|
/* Internal Information */
|
|
|
|
/* FIXME: get a real index, that can be used in a create operation */
|
|
|
|
Info->InternalInformation.IndexNumber.QuadPart = 0;
|
|
|
|
|
|
|
|
/* EA Information */
|
|
|
|
Info->EaInformation.EaSize = 0;
|
|
|
|
|
|
|
|
/* Access Information */
|
|
|
|
/* The IO-Manager adds this information */
|
|
|
|
|
|
|
|
/* Position Information */
|
|
|
|
Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
|
|
|
|
|
|
|
|
/* Mode Information */
|
|
|
|
/* The IO-Manager adds this information */
|
|
|
|
|
|
|
|
/* Alignment Information */
|
|
|
|
/* The IO-Manager adds this information */
|
|
|
|
|
|
|
|
/* Name Information */
|
|
|
|
Info->NameInformation.FileNameLength = NameLength;
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
RtlCopyMemory(Info->NameInformation.FileName, Fcb->PathName, NameLength + sizeof(WCHAR));
|
2002-07-20 11:44:37 +00:00
|
|
|
|
|
|
|
*BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));
|
|
|
|
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2002-08-14 20:58:39 +00:00
|
|
|
NTSTATUS
|
|
|
|
VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
|
|
|
|
PVFATFCB Fcb,
|
2002-08-17 15:15:50 +00:00
|
|
|
PDEVICE_EXTENSION DeviceExt,
|
2002-08-14 20:58:39 +00:00
|
|
|
PLARGE_INTEGER AllocationSize)
|
|
|
|
{
|
|
|
|
ULONG OldSize;
|
2002-09-30 20:47:28 +00:00
|
|
|
ULONG Cluster, FirstCluster;
|
2002-08-17 15:15:50 +00:00
|
|
|
ULONG Offset;
|
2002-08-14 20:58:39 +00:00
|
|
|
NTSTATUS Status;
|
2002-08-17 15:15:50 +00:00
|
|
|
|
2002-08-14 20:58:39 +00:00
|
|
|
ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
|
|
|
|
ULONG NewSize = AllocationSize->u.LowPart;
|
2002-08-17 15:15:50 +00:00
|
|
|
ULONG NCluster;
|
|
|
|
|
2002-08-17 15:46:36 +00:00
|
|
|
DPRINT("VfatSetAllocationSizeInformation()\n");
|
2002-08-14 20:58:39 +00:00
|
|
|
|
|
|
|
OldSize = Fcb->entry.FileSize;
|
2002-08-17 15:15:50 +00:00
|
|
|
if (AllocationSize->u.HighPart > 0)
|
|
|
|
{
|
|
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
}
|
|
|
|
if (OldSize == NewSize)
|
2002-08-14 20:58:39 +00:00
|
|
|
{
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
2002-09-30 20:47:28 +00:00
|
|
|
|
|
|
|
FirstCluster = vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry);
|
2002-08-17 15:15:50 +00:00
|
|
|
|
|
|
|
if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
|
|
|
|
{
|
2002-09-30 20:47:28 +00:00
|
|
|
if (FirstCluster == 0)
|
2002-08-14 20:58:39 +00:00
|
|
|
{
|
2002-09-30 20:47:28 +00:00
|
|
|
Status = NextCluster (DeviceExt, Fcb, FirstCluster, &FirstCluster, TRUE);
|
2002-08-17 15:15:50 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("NextCluster failed.\n");
|
|
|
|
return Status;
|
|
|
|
}
|
2002-09-30 20:47:28 +00:00
|
|
|
if (FirstCluster == 0xffffffff)
|
2002-08-17 15:15:50 +00:00
|
|
|
{
|
|
|
|
return STATUS_DISK_FULL;
|
|
|
|
}
|
2002-09-30 20:47:28 +00:00
|
|
|
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
|
2002-08-17 15:15:50 +00:00
|
|
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
|
|
|
&NCluster, TRUE);
|
|
|
|
if (NCluster == 0xffffffff)
|
|
|
|
{
|
|
|
|
/* disk is full */
|
2002-09-30 20:47:28 +00:00
|
|
|
NCluster = Cluster = FirstCluster;
|
2002-08-17 15:15:50 +00:00
|
|
|
while (Cluster != 0xffffffff)
|
|
|
|
{
|
|
|
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
|
|
|
WriteCluster (DeviceExt, Cluster, 0);
|
|
|
|
Cluster = NCluster;
|
|
|
|
}
|
|
|
|
return STATUS_DISK_FULL;
|
|
|
|
}
|
2002-09-30 20:47:28 +00:00
|
|
|
Fcb->entry.FirstCluster = (FirstCluster & 0x0000FFFF);
|
|
|
|
Fcb->entry.FirstClusterHigh = (FirstCluster & 0xFFFF0000) >> 16;
|
2002-08-14 20:58:39 +00:00
|
|
|
}
|
2002-08-17 15:15:50 +00:00
|
|
|
else
|
2002-08-14 20:58:39 +00:00
|
|
|
{
|
2002-09-30 20:47:28 +00:00
|
|
|
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
|
2002-08-17 15:15:50 +00:00
|
|
|
Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
|
|
|
|
&Cluster, FALSE);
|
|
|
|
/* Cluster points now to the last cluster within the chain */
|
2002-09-30 20:47:28 +00:00
|
|
|
Status = OffsetToCluster(DeviceExt, Fcb, FirstCluster,
|
2002-08-17 15:15:50 +00:00
|
|
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
|
|
|
&NCluster, TRUE);
|
|
|
|
if (NCluster == 0xffffffff)
|
|
|
|
{
|
|
|
|
/* disk is full */
|
|
|
|
NCluster = Cluster;
|
|
|
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
|
|
|
WriteCluster(DeviceExt, Cluster, 0xffffffff);
|
|
|
|
Cluster = NCluster;
|
|
|
|
while (Cluster != 0xffffffff)
|
|
|
|
{
|
|
|
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
|
|
|
WriteCluster (DeviceExt, Cluster, 0);
|
|
|
|
Cluster = NCluster;
|
|
|
|
}
|
|
|
|
return STATUS_DISK_FULL;
|
|
|
|
}
|
2002-08-14 20:58:39 +00:00
|
|
|
}
|
2002-08-17 15:15:50 +00:00
|
|
|
}
|
|
|
|
else if (NewSize <= Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize)
|
|
|
|
{
|
|
|
|
if (NewSize > 0)
|
|
|
|
{
|
|
|
|
Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
|
|
|
|
ROUND_DOWN(NewSize - 1, ClusterSize),
|
|
|
|
&Cluster, FALSE);
|
2002-09-30 20:47:28 +00:00
|
|
|
|
2002-08-17 15:15:50 +00:00
|
|
|
}
|
|
|
|
NCluster = Cluster;
|
|
|
|
Status = NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
|
|
|
WriteCluster(DeviceExt, Cluster, 0xffffffff);
|
|
|
|
Cluster = NCluster;
|
|
|
|
while (Cluster != 0xffffffff)
|
|
|
|
{
|
|
|
|
NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
|
|
|
|
WriteCluster (DeviceExt, Cluster, 0);
|
|
|
|
Cluster = NCluster;
|
|
|
|
}
|
|
|
|
}
|
* Used look aside lists to allocate memory for VFATFCB, VFATCCB and VFAT_IRP_CONTEXT.
* Removed IsLastEntry, IsVolEntry, IsDeletedEntry, vfat_wstrlen, vfatGrabFCB,
vfat_initstr, vfat_wcsncat, vfat_wcsncpy, vfat_movestr, wstrcmpi and replaced
this functions with existing equivalents or functions from ntoskrnl.
* Merged GetEntryName into vfatGetNextDirEntry for reducing some overhead.
* Implemented a file name cache to speed up the searching for existing fcb.
* Removed some calls to FsdDosDateTimeToFileTime.
* Moved the call to CcZeroData behind the initializing of the cache (in VfatWrite).
* Using existing fcbs in FindFile if there is no '*?' within the search name.
svn path=/trunk/; revision=3740
2002-11-11 21:49:18 +00:00
|
|
|
if (!vfatFCBIsDirectory(Fcb))
|
2002-09-30 20:47:28 +00:00
|
|
|
{
|
|
|
|
Fcb->entry.FileSize = NewSize;
|
|
|
|
}
|
2002-08-17 15:15:50 +00:00
|
|
|
if (NewSize > 0)
|
|
|
|
{
|
|
|
|
Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize - 1, ClusterSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Fcb->RFCB.AllocationSize.QuadPart = 0LL;
|
|
|
|
Fcb->entry.FirstCluster = 0;
|
|
|
|
Fcb->entry.FirstClusterHigh = 0;
|
|
|
|
}
|
|
|
|
Fcb->RFCB.FileSize.QuadPart = NewSize;
|
|
|
|
Fcb->RFCB.ValidDataLength.QuadPart = NewSize;
|
2002-08-14 20:58:39 +00:00
|
|
|
|
2002-09-08 10:23:54 +00:00
|
|
|
if (FileObject->SectionObjectPointers->SharedCacheMap != NULL)
|
2002-08-17 15:15:50 +00:00
|
|
|
{
|
|
|
|
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
|
|
|
|
}
|
2002-08-14 20:58:39 +00:00
|
|
|
/* Update the on-disk directory entry */
|
|
|
|
VfatUpdateEntry(DeviceExt, FileObject);
|
2002-08-17 15:15:50 +00:00
|
|
|
return STATUS_SUCCESS;
|
2002-08-14 20:58:39 +00:00
|
|
|
}
|
2002-07-20 11:44:37 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
|
1999-12-11 21:14:49 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the specified file information
|
|
|
|
*/
|
|
|
|
{
|
2001-06-12 12:35:42 +00:00
|
|
|
FILE_INFORMATION_CLASS FileInformationClass;
|
2000-12-29 23:17:12 +00:00
|
|
|
PVFATFCB FCB = NULL;
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
NTSTATUS RC = STATUS_SUCCESS;
|
2001-06-12 12:35:42 +00:00
|
|
|
PVOID SystemBuffer;
|
|
|
|
ULONG BufferLength;
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
/* PRECONDITION */
|
2001-11-02 22:47:36 +00:00
|
|
|
assert (IrpContext);
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
/* INITIALIZATION */
|
2001-11-02 22:47:36 +00:00
|
|
|
FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
|
|
|
|
FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
|
|
|
|
|
|
|
|
SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
|
|
|
|
BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
|
|
|
|
|
|
|
|
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
|
|
|
|
{
|
|
|
|
if (!ExAcquireResourceSharedLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
|
|
|
|
{
|
|
|
|
return VfatQueueRequest (IrpContext);
|
|
|
|
}
|
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-11-01 10:44:11 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
switch (FileInformationClass)
|
|
|
|
{
|
|
|
|
case FileStandardInformation:
|
2001-06-12 12:35:42 +00:00
|
|
|
RC = VfatGetStandardInformation(FCB,
|
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
1999-12-11 21:14:49 +00:00
|
|
|
break;
|
2000-12-29 23:17:12 +00:00
|
|
|
case FilePositionInformation:
|
2001-11-02 22:47:36 +00:00
|
|
|
RC = VfatGetPositionInformation(IrpContext->FileObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
FCB,
|
2001-11-02 22:47:36 +00:00
|
|
|
IrpContext->DeviceObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
1999-12-11 21:14:49 +00:00
|
|
|
break;
|
2000-12-29 23:17:12 +00:00
|
|
|
case FileBasicInformation:
|
2001-11-02 22:47:36 +00:00
|
|
|
RC = VfatGetBasicInformation(IrpContext->FileObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
FCB,
|
2001-11-02 22:47:36 +00:00
|
|
|
IrpContext->DeviceObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
1999-12-11 21:14:49 +00:00
|
|
|
break;
|
2001-03-06 23:36:35 +00:00
|
|
|
case FileNameInformation:
|
2001-11-02 22:47:36 +00:00
|
|
|
RC = VfatGetNameInformation(IrpContext->FileObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
FCB,
|
2001-11-02 22:47:36 +00:00
|
|
|
IrpContext->DeviceObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
2001-03-06 23:36:35 +00:00
|
|
|
break;
|
2001-06-12 12:35:42 +00:00
|
|
|
case FileInternalInformation:
|
2001-11-01 10:44:11 +00:00
|
|
|
RC = VfatGetInternalInformation(FCB,
|
2001-11-02 22:47:36 +00:00
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
2001-11-01 10:44:11 +00:00
|
|
|
break;
|
2002-07-20 00:57:36 +00:00
|
|
|
case FileNetworkOpenInformation:
|
|
|
|
RC = VfatGetNetworkOpenInformation(FCB,
|
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
2002-07-20 11:44:37 +00:00
|
|
|
case FileAllInformation:
|
|
|
|
RC = VfatGetAllInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
|
|
|
SystemBuffer,
|
|
|
|
&BufferLength);
|
|
|
|
break;
|
2002-07-20 00:57:36 +00:00
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
case FileAlternateNameInformation:
|
2000-12-29 23:17:12 +00:00
|
|
|
RC = STATUS_NOT_IMPLEMENTED;
|
2001-06-12 12:35:42 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RC = STATUS_NOT_SUPPORTED;
|
2000-12-29 23:17:12 +00:00
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
if (!(FCB->Flags & FCB_IS_PAGE_FILE))
|
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&FCB->MainResource);
|
|
|
|
}
|
|
|
|
IrpContext->Irp->IoStatus.Status = RC;
|
2001-06-12 12:35:42 +00:00
|
|
|
if (NT_SUCCESS(RC))
|
2001-11-02 22:47:36 +00:00
|
|
|
IrpContext->Irp->IoStatus.Information =
|
|
|
|
IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
|
2001-06-12 12:35:42 +00:00
|
|
|
else
|
2001-11-02 22:47:36 +00:00
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
|
|
|
|
VfatFreeIrpContext(IrpContext);
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
return RC;
|
1999-12-11 21:14:49 +00:00
|
|
|
}
|
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
|
1999-12-11 21:14:49 +00:00
|
|
|
/*
|
|
|
|
* FUNCTION: Retrieve the specified file information
|
|
|
|
*/
|
|
|
|
{
|
2000-12-29 23:17:12 +00:00
|
|
|
FILE_INFORMATION_CLASS FileInformationClass;
|
|
|
|
PVFATFCB FCB = NULL;
|
|
|
|
NTSTATUS RC = STATUS_SUCCESS;
|
|
|
|
PVOID SystemBuffer;
|
2002-08-14 20:58:39 +00:00
|
|
|
BOOL CanWait = IrpContext->Flags & IRPCONTEXT_CANWAIT;
|
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
/* PRECONDITION */
|
2001-11-02 22:47:36 +00:00
|
|
|
assert(IrpContext);
|
2002-08-14 20:58:39 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
DPRINT("VfatSetInformation(IrpContext %x)\n", IrpContext);
|
2002-08-14 20:58:39 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
/* INITIALIZATION */
|
2002-08-14 20:58:39 +00:00
|
|
|
FileInformationClass =
|
|
|
|
IrpContext->Stack->Parameters.SetFile.FileInformationClass;
|
2001-11-02 22:47:36 +00:00
|
|
|
FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
|
|
|
|
SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
|
2002-08-14 20:58:39 +00:00
|
|
|
|
2001-06-12 12:35:42 +00:00
|
|
|
DPRINT("FileInformationClass %d\n", FileInformationClass);
|
|
|
|
DPRINT("SystemBuffer %x\n", SystemBuffer);
|
2002-08-14 20:58:39 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
if (FCB->Flags & FCB_IS_PAGE_FILE)
|
2002-08-14 20:58:39 +00:00
|
|
|
{
|
|
|
|
if (!ExAcquireResourceExclusiveLite(&FCB->PagingIoResource, CanWait))
|
|
|
|
{
|
|
|
|
return(VfatQueueRequest (IrpContext));
|
|
|
|
}
|
|
|
|
}
|
2001-11-02 22:47:36 +00:00
|
|
|
else
|
2002-08-14 20:58:39 +00:00
|
|
|
{
|
|
|
|
if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, CanWait))
|
|
|
|
{
|
|
|
|
return(VfatQueueRequest (IrpContext));
|
|
|
|
}
|
|
|
|
}
|
2001-11-02 22:47:36 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
switch (FileInformationClass)
|
|
|
|
{
|
|
|
|
case FilePositionInformation:
|
2001-11-02 22:47:36 +00:00
|
|
|
RC = VfatSetPositionInformation(IrpContext->FileObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
SystemBuffer);
|
2000-12-29 23:17:12 +00:00
|
|
|
break;
|
|
|
|
case FileDispositionInformation:
|
2001-11-02 22:47:36 +00:00
|
|
|
RC = VfatSetDispositionInformation(IrpContext->FileObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
FCB,
|
2001-11-02 22:47:36 +00:00
|
|
|
IrpContext->DeviceObject,
|
2001-06-12 12:35:42 +00:00
|
|
|
SystemBuffer);
|
2000-12-29 23:17:12 +00:00
|
|
|
break;
|
2002-08-14 20:58:39 +00:00
|
|
|
case FileAllocationInformation:
|
2001-06-12 12:35:42 +00:00
|
|
|
case FileEndOfFileInformation:
|
2002-08-14 20:58:39 +00:00
|
|
|
RC = VfatSetAllocationSizeInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
2002-08-17 15:15:50 +00:00
|
|
|
IrpContext->DeviceExt,
|
2002-08-14 20:58:39 +00:00
|
|
|
(PLARGE_INTEGER)SystemBuffer);
|
|
|
|
break;
|
|
|
|
case FileBasicInformation:
|
2002-12-27 23:50:21 +00:00
|
|
|
RC = VfatSetBasicInformation(IrpContext->FileObject,
|
|
|
|
FCB,
|
|
|
|
IrpContext->DeviceExt,
|
|
|
|
SystemBuffer);
|
|
|
|
break;
|
2001-06-12 12:35:42 +00:00
|
|
|
case FileRenameInformation:
|
2000-12-29 23:17:12 +00:00
|
|
|
RC = STATUS_NOT_IMPLEMENTED;
|
2001-06-12 12:35:42 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
RC = STATUS_NOT_SUPPORTED;
|
2000-12-29 23:17:12 +00:00
|
|
|
}
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2001-11-02 22:47:36 +00:00
|
|
|
if (FCB->Flags & FCB_IS_PAGE_FILE)
|
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&FCB->PagingIoResource);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ExReleaseResourceLite(&FCB->MainResource);
|
|
|
|
}
|
|
|
|
|
|
|
|
IrpContext->Irp->IoStatus.Status = RC;
|
|
|
|
IrpContext->Irp->IoStatus.Information = 0;
|
|
|
|
IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
|
|
|
|
VfatFreeIrpContext(IrpContext);
|
1999-12-11 21:14:49 +00:00
|
|
|
|
2000-12-29 23:17:12 +00:00
|
|
|
return RC;
|
|
|
|
}
|
2001-06-12 12:35:42 +00:00
|
|
|
|
|
|
|
/* EOF */
|