-
/*
+ * $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: services/fs/vfat/dir.c
+ * FILE: drivers/fs/vfat/dir.c
* PURPOSE: VFAT Filesystem : directory control
* UPDATE HISTORY:
19-12-1998 : created
*/
-#include <ddk/ntddk.h>
-#include <internal/string.h>
-#include <wstring.h>
-#include <ddk/cctypes.h>
-#include <ddk/zwtypes.h>
#define NDEBUG
-#include <internal/debug.h>
-
#include "vfat.h"
-// buggy function, waiting the real function
-BOOL fsdDosDateTimeToFileTime(WORD wDosDate,WORD wDosTime, TIME *FileTime)
+
+// function like DosDateTimeToFileTime
+BOOLEAN
+FsdDosDateTimeToSystemTime (PDEVICE_EXTENSION DeviceExt, USHORT DosDate, USHORT DosTime, PLARGE_INTEGER SystemTime)
{
- WORD Day,Month,Year,Second,Minute,Hour;
- long long int *pTime=(long long int *)FileTime;
- long long int mult;
- Day=wDosDate&0x001f;
- Month= (wDosDate&0x00e0)>>5;//1=January
- Year= ((wDosDate&0xff00)>>8)+1980;
- Second=(wDosTime&0x001f)<<1;
- Minute=(wDosTime&0x07e0)>>5;
- Hour= (wDosTime&0xf100)>>11;
- mult=10000000;
- *pTime=Second*mult;
- mult *=60;
- *pTime +=Minute*mult;
- mult *=60;
- *pTime +=Hour*mult;
- mult *=24;
- *pTime +=(Day-1)*mult;
- *pTime +=(Month-1)*mult*30;//FIXME : not always 30 days in a month
- *pTime +=(Year-1601)*mult*365;//FIXME : not always 365 days in a year
+ PDOSTIME pdtime = (PDOSTIME) &DosTime;
+ PDOSDATE pddate = (PDOSDATE) &DosDate;
+ TIME_FIELDS TimeFields;
+ LARGE_INTEGER LocalTime;
+
+ if (SystemTime == NULL)
+ return FALSE;
+
+ TimeFields.Milliseconds = 0;
+ TimeFields.Second = pdtime->Second * 2;
+ TimeFields.Minute = pdtime->Minute;
+ TimeFields.Hour = pdtime->Hour;
+
+ TimeFields.Day = pddate->Day;
+ TimeFields.Month = pddate->Month;
+ TimeFields.Year = (CSHORT)(DeviceExt->BaseDateYear + pddate->Year);
+
+ RtlTimeFieldsToTime (&TimeFields, &LocalTime);
+ ExLocalTimeToSystemTime(&LocalTime, SystemTime);
+
return TRUE;
}
-#define DosDateTimeToFileTime fsdDosDateTimeToFileTime
+// function like FileTimeToDosDateTime
+BOOLEAN
+FsdSystemTimeToDosDateTime (PDEVICE_EXTENSION DeviceExt, PLARGE_INTEGER SystemTime, USHORT *pDosDate, USHORT *pDosTime)
+{
+ PDOSTIME pdtime = (PDOSTIME) pDosTime;
+ PDOSDATE pddate = (PDOSDATE) pDosDate;
+ TIME_FIELDS TimeFields;
+ LARGE_INTEGER LocalTime;
+ if (SystemTime == NULL)
+ return FALSE;
+ ExSystemTimeToLocalTime (SystemTime, &LocalTime);
+ RtlTimeToTimeFields (&LocalTime, &TimeFields);
-unsigned long vfat_wstrlen(PWSTR s)
-{
- WCHAR c=' ';
- unsigned int len=0;
+ if (pdtime)
+ {
+ pdtime->Second = TimeFields.Second / 2;
+ pdtime->Minute = TimeFields.Minute;
+ pdtime->Hour = TimeFields.Hour;
+ }
- while(c!=0) {
- c=*s;
- s++;
- len++;
- };
- s-=len;
+ if (pddate)
+ {
+ pddate->Day = TimeFields.Day;
+ pddate->Month = TimeFields.Month;
+ pddate->Year = (USHORT) (TimeFields.Year - DeviceExt->BaseDateYear);
+ }
- return len-1;
+ return TRUE;
}
-#define DWORD_ROUND_UP(x) ( (((ULONG)(x))%32) ? ((((ULONG)x)&(~0x1f))+0x20) : ((ULONG)x) )
-NTSTATUS FsdGetFileNameInformation(PFCB pFcb,
- PFILE_NAMES_INFORMATION pInfo,ULONG BufferLength)
+#define ULONG_ROUND_UP(x) ROUND_UP((x), (sizeof(ULONG)))
+
+NTSTATUS
+VfatGetFileNameInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PFILE_NAMES_INFORMATION pInfo, ULONG BufferLength)
{
- ULONG Length;
- Length=vfat_wstrlen(pFcb->ObjectName);
- if( (sizeof(FILE_DIRECTORY_INFORMATION)+Length) >BufferLength)
- return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength=Length;
- pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION)+Length);
- memcpy(pInfo->FileName,pFcb->ObjectName
- ,sizeof(WCHAR)*(pInfo->FileNameLength));
+ if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
+ return STATUS_BUFFER_OVERFLOW;
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ pInfo->NextEntryOffset =
+ ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
return STATUS_SUCCESS;
}
-NTSTATUS FsdGetFileDirectoryInformation(PFCB pFcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
+NTSTATUS
+VfatGetFileDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_DIRECTORY_INFORMATION pInfo,
+ ULONG BufferLength)
{
- unsigned long long AllocSize;
- ULONG Length;
-
- DPRINT("BufferLength %d\n",BufferLength);
-
- Length=vfat_wstrlen(pFcb->ObjectName);
- if( (sizeof(FILE_DIRECTORY_INFORMATION)+Length) >BufferLength)
- return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength=Length;
- pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_DIRECTORY_INFORMATION)+Length);
- memcpy(pInfo->FileName,pFcb->ObjectName
- ,sizeof(WCHAR)*(pInfo->FileNameLength));
- DPRINT("pInfo->FileName %w\n",pInfo->FileName);
+ if ((sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
+ return STATUS_BUFFER_OVERFLOW;
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ pInfo->NextEntryOffset =
+ ULONG_ROUND_UP (sizeof (FILE_DIRECTORY_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
// pInfo->FileIndex=;
- DosDateTimeToFileTime(pFcb->entry.CreationDate,pFcb->entry.CreationTime
- ,&pInfo->CreationTime);
- DosDateTimeToFileTime(pFcb->entry.AccessDate,0
- ,&pInfo->LastAccessTime);
- DosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
- ,&pInfo->LastWriteTime);
- DosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
- ,&pInfo->ChangeTime);
- pInfo->EndOfFile=RtlConvertUlongToLargeInteger(pFcb->entry.FileSize);
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) *
- DeviceExt->BytesPerCluster;
- LARGE_INTEGER_QUAD_PART(pInfo->AllocationSize) = AllocSize;
- pInfo->FileAttributes=pFcb->entry.Attrib;
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
+ }
+ else
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
return STATUS_SUCCESS;
}
-NTSTATUS FsdGetFileFullDirectoryInformation(PFCB pFcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_FULL_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
+NTSTATUS
+VfatGetFileFullDirectoryInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_FULL_DIR_INFORMATION pInfo,
+ ULONG BufferLength)
{
- unsigned long long AllocSize;
- ULONG Length;
- Length=vfat_wstrlen(pFcb->ObjectName);
- if( (sizeof(FILE_FULL_DIRECTORY_INFORMATION)+Length) >BufferLength)
- return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength=Length;
- pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_FULL_DIRECTORY_INFORMATION)+Length);
- memcpy(pInfo->FileName,pFcb->ObjectName
- ,sizeof(WCHAR)*(pInfo->FileNameLength));
+ if ((sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
+ return STATUS_BUFFER_OVERFLOW;
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ pInfo->NextEntryOffset =
+ ULONG_ROUND_UP (sizeof (FILE_FULL_DIR_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
// pInfo->FileIndex=;
- DosDateTimeToFileTime(pFcb->entry.CreationDate,pFcb->entry.CreationTime
- ,&pInfo->CreationTime);
- DosDateTimeToFileTime(pFcb->entry.AccessDate,0
- ,&pInfo->LastAccessTime);
- DosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
- ,&pInfo->LastWriteTime);
- DosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
- ,&pInfo->ChangeTime);
- pInfo->EndOfFile=RtlConvertUlongToLargeInteger(pFcb->entry.FileSize);
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) *
- DeviceExt->BytesPerCluster;
- LARGE_INTEGER_QUAD_PART(pInfo->AllocationSize) = AllocSize;
- pInfo->FileAttributes=pFcb->entry.Attrib;
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
+ }
+ else
+ {
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate,
+ 0, &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
// pInfo->EaSize=;
return STATUS_SUCCESS;
}
-NTSTATUS FsdGetFileBothInformation(PFCB pFcb,
- PDEVICE_EXTENSION DeviceExt,
- PFILE_BOTH_DIRECTORY_INFORMATION pInfo,ULONG BufferLength)
+NTSTATUS
+VfatGetFileBothInformation (PVFAT_DIRENTRY_CONTEXT DirContext,
+ PDEVICE_EXTENSION DeviceExt,
+ PFILE_BOTH_DIR_INFORMATION pInfo,
+ ULONG BufferLength)
{
- short i;
- unsigned long long AllocSize;
- ULONG Length;
- Length=vfat_wstrlen(pFcb->ObjectName);
- if( (sizeof(FILE_BOTH_DIRECTORY_INFORMATION)+Length) >BufferLength)
- return STATUS_BUFFER_OVERFLOW;
- pInfo->FileNameLength=Length;
- pInfo->NextEntryOffset=DWORD_ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION)+Length);
-DPRINT("sizeof %d,Length %d, BufLength %d, Next %d\n"
- ,sizeof(FILE_BOTH_DIRECTORY_INFORMATION),Length,BufferLength
- ,pInfo->NextEntryOffset);
- memcpy(pInfo->FileName,pFcb->ObjectName
- ,sizeof(WCHAR)*(pInfo->FileNameLength));
-// pInfo->FileIndex=;
- DosDateTimeToFileTime(pFcb->entry.CreationDate,pFcb->entry.CreationTime
- ,&pInfo->CreationTime);
- DosDateTimeToFileTime(pFcb->entry.AccessDate,0
- ,&pInfo->LastAccessTime);
- DosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
- ,&pInfo->LastWriteTime);
- DosDateTimeToFileTime(pFcb->entry.UpdateDate,pFcb->entry.UpdateTime
- ,&pInfo->ChangeTime);
- pInfo->EndOfFile=RtlConvertUlongToLargeInteger(pFcb->entry.FileSize);
- /* Make allocsize a rounded up multiple of BytesPerCluster */
- AllocSize = ((pFcb->entry.FileSize + DeviceExt->BytesPerCluster - 1) /
- DeviceExt->BytesPerCluster) *
- DeviceExt->BytesPerCluster;
- LARGE_INTEGER_QUAD_PART(pInfo->AllocationSize) = AllocSize;
- pInfo->FileAttributes=pFcb->entry.Attrib;
-// pInfo->EaSize=;
- for (i=0;i<8 && (pFcb->entry.Filename[i]!=' ') ;i++)
- pInfo->ShortName[i]=pFcb->entry.Filename[i];
- pInfo->ShortNameLength=i;
- pInfo->ShortName[i]='.';
- for (i=0 ;i<3 && (pFcb->entry.Ext[i]!=' ') ;i++)
- pInfo->ShortName[i+1+pInfo->ShortNameLength]=pFcb->entry.Ext[i];
- if(i) pInfo->ShortNameLength += (i+1);
+ if ((sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length) > BufferLength)
+ return STATUS_BUFFER_OVERFLOW;
+
+ if (DeviceExt->Flags & VCB_IS_FATX)
+ {
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ RtlCopyMemory(pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+ pInfo->NextEntryOffset =
+ ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length);
+ pInfo->ShortName[0] = 0;
+ pInfo->ShortNameLength = 0;
+ // pInfo->FileIndex=;
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.CreationDate,
+ DirContext->DirEntry.FatX.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.AccessDate,
+ DirContext->DirEntry.FatX.AccessTime,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.FatX.UpdateDate,
+ DirContext->DirEntry.FatX.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.FatX.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.FatX.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.FatX.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.FatX.Attrib & 0x3f;
+ }
+ else
+ {
+ pInfo->FileNameLength = DirContext->LongNameU.Length;
+ pInfo->NextEntryOffset =
+ ULONG_ROUND_UP (sizeof (FILE_BOTH_DIR_INFORMATION) + DirContext->LongNameU.Length);
+ RtlCopyMemory(pInfo->ShortName, DirContext->ShortNameU.Buffer, DirContext->ShortNameU.Length);
+ pInfo->ShortNameLength = (CCHAR)DirContext->ShortNameU.Length;
+ RtlCopyMemory (pInfo->FileName, DirContext->LongNameU.Buffer, DirContext->LongNameU.Length);
+ // pInfo->FileIndex=;
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.CreationDate,
+ DirContext->DirEntry.Fat.CreationTime,
+ &pInfo->CreationTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.AccessDate, 0,
+ &pInfo->LastAccessTime);
+ FsdDosDateTimeToSystemTime (DeviceExt, DirContext->DirEntry.Fat.UpdateDate,
+ DirContext->DirEntry.Fat.UpdateTime,
+ &pInfo->LastWriteTime);
+ pInfo->ChangeTime = pInfo->LastWriteTime;
+ if (DirContext->DirEntry.Fat.Attrib & FILE_ATTRIBUTE_DIRECTORY)
+ {
+ pInfo->EndOfFile.QuadPart = 0LL;
+ pInfo->AllocationSize.QuadPart = 0LL;
+ }
+ else
+ {
+ pInfo->EndOfFile.u.HighPart = 0;
+ pInfo->EndOfFile.u.LowPart = DirContext->DirEntry.Fat.FileSize;
+ /* Make allocsize a rounded up multiple of BytesPerCluster */
+ pInfo->AllocationSize.u.HighPart = 0;
+ pInfo->AllocationSize.u.LowPart = ROUND_UP(DirContext->DirEntry.Fat.FileSize, DeviceExt->FatInfo.BytesPerCluster);
+ }
+ pInfo->FileAttributes = DirContext->DirEntry.Fat.Attrib & 0x3f;
+ }
+ pInfo->EaSize=0;
return STATUS_SUCCESS;
}
-NTSTATUS DoQuery(PDEVICE_OBJECT DeviceObject,
- PIRP Irp,
- PIO_STACK_LOCATION Stack)
+NTSTATUS DoQuery (PVFAT_IRP_CONTEXT IrpContext)
{
- NTSTATUS RC=STATUS_SUCCESS;
- long BufferLength = 0;
- PUNICODE_STRING pSearchPattern = NULL;
- FILE_INFORMATION_CLASS FileInformationClass;
- unsigned long FileIndex = 0;
- unsigned char *Buffer = NULL;
- PFILE_NAMES_INFORMATION Buffer0 = NULL;
- PFILE_OBJECT pFileObject = NULL;
- PFCB pFcb;
- FCB tmpFcb;
- PDEVICE_EXTENSION DeviceExt;
- WCHAR star[5],*pCharPattern;
- unsigned long OldEntry,OldSector;
- BOOLEAN RestartScan;
-
- DeviceExt = DeviceObject->DeviceExtension;
- // Obtain the callers parameters
- BufferLength = Stack->Parameters.QueryDirectory.Length;
- pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
- FileInformationClass = Stack->Parameters.QueryDirectory.FileInformationClass;
- FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
- pFileObject = Stack->FileObject;
- pFcb=(PFCB)(pFileObject->FsContext);
-
-
- if(Stack->Flags & SL_RESTART_SCAN)
- {
- pFcb->StartEntry=pFcb->StartSector=0;
- }
-
- // determine Buffer for result :
- if (Irp->MdlAddress)
- Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
- else
- Buffer = Irp->UserBuffer;
-
- if (pSearchPattern==NULL)
- {
- star[0]='*';
- star[1]=0;
- pCharPattern=star;
- }
- else pCharPattern=pSearchPattern->Buffer;
-
- while(RC==STATUS_SUCCESS && BufferLength >0)
- {
- OldSector=pFcb->StartSector;
- OldEntry=pFcb->StartEntry;
- if(OldSector)pFcb->StartEntry++;
- RC=FindFile(DeviceExt,
- &tmpFcb,
- pFcb,
- pCharPattern,
- &pFcb->StartSector,
- &pFcb->StartEntry);
- DPRINT("Found %w\n",tmpFcb.ObjectName);
- if (NT_SUCCESS(RC))
- {
- switch(FileInformationClass)
- {
- case FileNameInformation:
- RC=FsdGetFileNameInformation(&tmpFcb
- ,(PFILE_NAMES_INFORMATION)Buffer,BufferLength);
- break;
- case FileDirectoryInformation:
- RC= FsdGetFileDirectoryInformation(&tmpFcb,
- DeviceExt,
- (PFILE_DIRECTORY_INFORMATION)Buffer,
- BufferLength);
- break;
- case FileFullDirectoryInformation :
- RC= FsdGetFileFullDirectoryInformation(&tmpFcb
- ,DeviceExt,(PFILE_FULL_DIRECTORY_INFORMATION)Buffer,BufferLength);
- break;
- case FileBothDirectoryInformation :
- RC=FsdGetFileBothInformation(&tmpFcb
- ,DeviceExt,(PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,BufferLength);
- break;
- default:
- RC=STATUS_INVALID_INFO_CLASS;
- }
+ NTSTATUS RC = STATUS_SUCCESS;
+ long BufferLength = 0;
+ PUNICODE_STRING pSearchPattern = NULL;
+ FILE_INFORMATION_CLASS FileInformationClass;
+ unsigned char *Buffer = NULL;
+ PFILE_NAMES_INFORMATION Buffer0 = NULL;
+ PVFATFCB pFcb;
+ PVFATCCB pCcb;
+ BOOLEAN FirstQuery = FALSE;
+ BOOLEAN FirstCall = TRUE;
+ VFAT_DIRENTRY_CONTEXT DirContext;
+ WCHAR LongNameBuffer[LONGNAME_MAX_LENGTH + 1];
+ WCHAR ShortNameBuffer[13];
+
+ PIO_STACK_LOCATION Stack = IrpContext->Stack;
+
+ pCcb = (PVFATCCB) IrpContext->FileObject->FsContext2;
+ pFcb = (PVFATFCB) IrpContext->FileObject->FsContext;
+
+ // determine Buffer for result :
+ BufferLength = Stack->Parameters.QueryDirectory.Length;
+#if 0
+ /* Do not probe the user buffer until SEH is available */
+ if (IrpContext->Irp->RequestorMode != KernelMode &&
+ IrpContext->Irp->MdlAddress == NULL &&
+ IrpContext->Irp->UserBuffer != NULL)
+ {
+ ProbeForWrite(IrpContext->Irp->UserBuffer, BufferLength, 1);
}
- else
+#endif
+ Buffer = VfatGetUserBuffer(IrpContext->Irp);
+
+ if (!ExAcquireResourceSharedLite(&pFcb->MainResource,
+ (BOOLEAN)(IrpContext->Flags & IRPCONTEXT_CANWAIT)))
{
- if(Buffer0) Buffer0->NextEntryOffset=0;
- break;
+ RC = VfatLockUserBuffer(IrpContext->Irp, BufferLength, IoWriteAccess);
+ if (NT_SUCCESS(RC))
+ {
+ RC = STATUS_PENDING;
+ }
+ return RC;
}
- if(RC==STATUS_BUFFER_OVERFLOW)
+
+ /* Obtain the callers parameters */
+#ifdef _MSC_VER
+ /* HACKHACK: Bug in the MS ntifs.h header:
+ * FileName is really a PUNICODE_STRING, not a PSTRING */
+ pSearchPattern = (PUNICODE_STRING)Stack->Parameters.QueryDirectory.FileName;
+#else
+ pSearchPattern = Stack->Parameters.QueryDirectory.FileName;
+#endif
+ FileInformationClass =
+ Stack->Parameters.QueryDirectory.FileInformationClass;
+ if (pSearchPattern)
{
- if(Buffer0) Buffer0->NextEntryOffset=0;
- pFcb->StartSector=OldSector;
- pFcb->StartEntry=OldEntry;
- break;
+ if (!pCcb->SearchPattern.Buffer)
+ {
+ FirstQuery = TRUE;
+ pCcb->SearchPattern.MaximumLength = pSearchPattern->Length + sizeof(WCHAR);
+ pCcb->SearchPattern.Buffer = ExAllocatePool(NonPagedPool, pCcb->SearchPattern.MaximumLength);
+ if (!pCcb->SearchPattern.Buffer)
+ {
+ ExReleaseResourceLite(&pFcb->MainResource);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ RtlCopyUnicodeString(&pCcb->SearchPattern, pSearchPattern);
+ pCcb->SearchPattern.Buffer[pCcb->SearchPattern.Length / sizeof(WCHAR)] = 0;
+ }
}
- Buffer0=(PFILE_NAMES_INFORMATION)Buffer;
- Buffer0->FileIndex=FileIndex++;
- DPRINT("Stack->Flags %x\n",Stack->Flags);
- if(Stack->Flags & SL_RETURN_SINGLE_ENTRY) break;
- BufferLength -= Buffer0->NextEntryOffset;
- Buffer += Buffer0->NextEntryOffset;
- }
- if(Buffer0) Buffer0->NextEntryOffset=0;
- if(FileIndex>0) return STATUS_SUCCESS;
+ else if (!pCcb->SearchPattern.Buffer)
+ {
+ FirstQuery = TRUE;
+ pCcb->SearchPattern.MaximumLength = 2 * sizeof(WCHAR);
+ pCcb->SearchPattern.Buffer = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
+ if (!pCcb->SearchPattern.Buffer)
+ {
+ ExReleaseResourceLite(&pFcb->MainResource);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+ pCcb->SearchPattern.Buffer[0] = L'*';
+ pCcb->SearchPattern.Buffer[1] = 0;
+ pCcb->SearchPattern.Length = sizeof(WCHAR);
+ }
+
+ if (IrpContext->Stack->Flags & SL_INDEX_SPECIFIED)
+ {
+ DirContext.DirIndex = pCcb->Entry = Stack->Parameters.QueryDirectory.FileIndex;
+ }
+ else if (FirstQuery || (IrpContext->Stack->Flags & SL_RESTART_SCAN))
+ {
+ DirContext.DirIndex = pCcb->Entry = 0;
+ }
+ else
+ {
+ DirContext.DirIndex = pCcb->Entry;
+ }
+
+ DPRINT ("Buffer=%x tofind=%wZ\n", Buffer, &pCcb->SearchPattern);
+
+ DirContext.LongNameU.Buffer = LongNameBuffer;
+ DirContext.LongNameU.MaximumLength = sizeof(LongNameBuffer);
+ DirContext.ShortNameU.Buffer = ShortNameBuffer;
+ DirContext.ShortNameU.MaximumLength = sizeof(ShortNameBuffer);
+
+ while (RC == STATUS_SUCCESS && BufferLength > 0)
+ {
+ RC = FindFile (IrpContext->DeviceExt, pFcb,
+ &pCcb->SearchPattern, &DirContext, FirstCall);
+ pCcb->Entry = DirContext.DirIndex;
+ DPRINT ("Found %wZ, RC=%x, entry %x\n", &DirContext.LongNameU, RC, pCcb->Entry);
+ FirstCall = FALSE;
+ if (NT_SUCCESS (RC))
+ {
+ switch (FileInformationClass)
+ {
+ case FileNameInformation:
+ RC = VfatGetFileNameInformation (&DirContext,
+ (PFILE_NAMES_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ case FileDirectoryInformation:
+ RC = VfatGetFileDirectoryInformation (&DirContext,
+ IrpContext->DeviceExt,
+ (PFILE_DIRECTORY_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ case FileFullDirectoryInformation:
+ RC = VfatGetFileFullDirectoryInformation (&DirContext,
+ IrpContext->DeviceExt,
+ (PFILE_FULL_DIR_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ case FileBothDirectoryInformation:
+ RC = VfatGetFileBothInformation (&DirContext,
+ IrpContext->DeviceExt,
+ (PFILE_BOTH_DIR_INFORMATION) Buffer,
+ BufferLength);
+ break;
+ default:
+ RC = STATUS_INVALID_INFO_CLASS;
+ }
+ if (RC == STATUS_BUFFER_OVERFLOW)
+ {
+ break;
+ }
+ }
+ else
+ {
+ if (FirstQuery)
+ {
+ RC = STATUS_NO_SUCH_FILE;
+ }
+ else
+ {
+ RC = STATUS_NO_MORE_FILES;
+ }
+ break;
+ }
+ Buffer0 = (PFILE_NAMES_INFORMATION) Buffer;
+ Buffer0->FileIndex = DirContext.DirIndex;
+ pCcb->Entry = ++DirContext.DirIndex;
+ BufferLength -= Buffer0->NextEntryOffset;
+ if (IrpContext->Stack->Flags & SL_RETURN_SINGLE_ENTRY)
+ {
+ break;
+ }
+ Buffer += Buffer0->NextEntryOffset;
+ }
+ if (Buffer0)
+ {
+ Buffer0->NextEntryOffset = 0;
+ RC = STATUS_SUCCESS;
+ IrpContext->Irp->IoStatus.Information = Stack->Parameters.QueryDirectory.Length - BufferLength;
+
+ }
+ ExReleaseResourceLite(&pFcb->MainResource);
return RC;
}
-NTSTATUS FsdDirectoryControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
+NTSTATUS VfatDirectoryControl (PVFAT_IRP_CONTEXT IrpContext)
/*
* FUNCTION: directory control : read/write directory informations
*/
{
- NTSTATUS RC = STATUS_SUCCESS;
- PFILE_OBJECT FileObject = NULL;
- PIO_STACK_LOCATION Stack;
-
- DPRINT("FsdDirectoryControl(DeviceObject %x, Irp %x)\n",
- DeviceObject,Irp);
-
- Stack = IoGetCurrentIrpStackLocation(Irp);
- FileObject = Stack->FileObject;
-
- switch (Stack->MinorFunction)
- {
+ NTSTATUS RC = STATUS_SUCCESS;
+ CHECKPOINT;
+ IrpContext->Irp->IoStatus.Information = 0;
+ switch (IrpContext->MinorFunction)
+ {
case IRP_MN_QUERY_DIRECTORY:
- RC=DoQuery(DeviceObject,Irp,Stack);
+ RC = DoQuery (IrpContext);
break;
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
- DPRINT(" vfat, dir : change\n");
+ DPRINT (" vfat, dir : change\n");
+ RC = STATUS_NOT_IMPLEMENTED;
break;
default:
// error
- DbgPrint("unexpected minor function %x in VFAT driver\n",Stack->MinorFunction);
- RC = STATUS_INVALID_DEVICE_REQUEST;
- break;
- }
- Irp->IoStatus.Status = RC;
- Irp->IoStatus.Information = 0;
-
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- return RC;
+ DbgPrint ("unexpected minor function %x in VFAT driver\n",
+ IrpContext->MinorFunction);
+ RC = STATUS_INVALID_DEVICE_REQUEST;
+ break;
+ }
+ if (RC == STATUS_PENDING)
+ {
+ RC = VfatQueueRequest(IrpContext);
+ }
+ else
+ {
+ IrpContext->Irp->IoStatus.Status = RC;
+ IoCompleteRequest (IrpContext->Irp, IO_NO_INCREMENT);
+ VfatFreeIrpContext(IrpContext);
+ }
+ return RC;
}
+