mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Added media change support (untested).
Added directory listing (works only on the root directory). svn path=/trunk/; revision=2872
This commit is contained in:
parent
321c888721
commit
23f679e571
4 changed files with 744 additions and 58 deletions
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: common.c,v 1.2 2002/04/15 20:39:49 ekohl Exp $
|
||||
/* $Id: common.c,v 1.3 2002/04/26 23:21:28 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -93,6 +93,19 @@ CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
if (Status == STATUS_VERIFY_REQUIRED)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
NTSTATUS NewStatus;
|
||||
|
||||
DPRINT1("STATUS_VERIFY_REQUIRED\n");
|
||||
DeviceToVerify = IoGetDeviceToVerify(PsGetCurrentThread());
|
||||
IoSetDeviceToVerify(PsGetCurrentThread(), NULL);
|
||||
|
||||
NewStatus = IoVerifyVolume(DeviceToVerify, FALSE);
|
||||
DPRINT1("IoVerifyVolume() retuned (Status %lx)\n", NewStatus);
|
||||
}
|
||||
|
||||
DPRINT("CdfsReadSectors() failed (Status %x)\n", Status);
|
||||
DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n",
|
||||
DeviceObject, DiskSector, Buffer,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: dirctl.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
|
||||
/* $Id: dirctl.c,v 1.2 2002/04/26 23:21:28 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#include "cdfs.h"
|
||||
|
@ -38,42 +38,597 @@
|
|||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
/* HACK -- NEEDS FIXING */
|
||||
#if 0
|
||||
int
|
||||
FsdExtractDirectoryEntry(PDEVICE_EXTENSION DeviceExt,
|
||||
FsdFcbEntry *parent,
|
||||
FsdFcbEntry *fill_in,
|
||||
int entry_to_get)
|
||||
|
||||
static BOOLEAN
|
||||
wstrcmpjoki(PWSTR s1, PWSTR s2)
|
||||
/*
|
||||
* FUNCTION: Compare two wide character strings, s2 with jokers (* or ?)
|
||||
* return TRUE if s1 like s2
|
||||
*/
|
||||
{
|
||||
switch( entry_to_get )
|
||||
while ((*s2=='*')||(*s2=='?')||(towlower(*s1)==towlower(*s2)))
|
||||
{
|
||||
case 0:
|
||||
wcscpy( fill_in->name, L"." );
|
||||
fill_in->extent_start = parent->extent_start;
|
||||
fill_in->byte_count = parent->byte_count;
|
||||
break;
|
||||
if ((*s1)==0 && (*s2)==0)
|
||||
return(TRUE);
|
||||
|
||||
case 1:
|
||||
wcscpy( fill_in->name, L".." );
|
||||
fill_in->extent_start = parent->extent_start;
|
||||
fill_in->byte_count = parent->byte_count;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
wcscpy( fill_in->name, L"readme.txt" );
|
||||
fill_in->extent_start = 0x190;
|
||||
fill_in->byte_count = 0x800;
|
||||
break;
|
||||
|
||||
default:
|
||||
return 1;
|
||||
if(*s2=='*')
|
||||
{
|
||||
s2++;
|
||||
while (*s1)
|
||||
if (wstrcmpjoki(s1,s2))
|
||||
return TRUE;
|
||||
else
|
||||
s1++;
|
||||
}
|
||||
else
|
||||
{
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
if ((*s2)=='.')
|
||||
{
|
||||
for (;((*s2)=='.')||((*s2)=='*')||((*s2)=='?');s2++)
|
||||
;
|
||||
}
|
||||
|
||||
if ((*s1)==0 && (*s2)==0)
|
||||
return(TRUE);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
CdfsSwapString(PWCHAR Out,
|
||||
PUCHAR In,
|
||||
ULONG Count)
|
||||
{
|
||||
PUCHAR t = (PUCHAR)Out;
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < Count; i += 2)
|
||||
{
|
||||
t[i] = In[i+1];
|
||||
t[i+1] = In[i];
|
||||
}
|
||||
t[i] = 0;
|
||||
t[i+1] = 0;
|
||||
}
|
||||
|
||||
|
||||
static VOID
|
||||
CdfsDateTimeToFileTime(PFCB Fcb,
|
||||
TIME *FileTime)
|
||||
{
|
||||
TIME_FIELDS TimeFields;
|
||||
|
||||
TimeFields.Milliseconds = 0;
|
||||
TimeFields.Second = Fcb->Entry.Second;
|
||||
TimeFields.Minute = Fcb->Entry.Minute;
|
||||
TimeFields.Hour = Fcb->Entry.Hour;
|
||||
|
||||
TimeFields.Day = Fcb->Entry.Day;
|
||||
TimeFields.Month = Fcb->Entry.Month;
|
||||
TimeFields.Year = Fcb->Entry.Year + 1900;
|
||||
|
||||
RtlTimeFieldsToTime(&TimeFields,
|
||||
(PLARGE_INTEGER)FileTime);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CdfsGetEntryName(PDEVICE_EXTENSION DeviceExt,
|
||||
PVOID Block,
|
||||
ULONG BlockLength,
|
||||
PVOID *Ptr,
|
||||
PWSTR Name,
|
||||
PULONG pIndex,
|
||||
PULONG pIndex2)
|
||||
/*
|
||||
* FUNCTION: Retrieves the file name, be it in short or long file name format
|
||||
*/
|
||||
{
|
||||
PDIR_RECORD Record;
|
||||
NTSTATUS Status;
|
||||
ULONG Index = 0;
|
||||
ULONG Offset = 0;
|
||||
|
||||
Record = (PDIR_RECORD)Block;
|
||||
while(Index < *pIndex)
|
||||
{
|
||||
Offset = Offset + Record->RecordLength;
|
||||
|
||||
Record = (PDIR_RECORD)(Block + Offset);
|
||||
if (Record->RecordLength == 0)
|
||||
{
|
||||
Offset = ROUND_UP(Offset, 2048);
|
||||
Record = (PDIR_RECORD)(Block + Offset);
|
||||
}
|
||||
|
||||
if (Offset >= BlockLength)
|
||||
return(STATUS_NO_MORE_ENTRIES);
|
||||
|
||||
Index++;
|
||||
}
|
||||
|
||||
DPRINT("Index %lu RecordLength %lu Offset %lu\n",
|
||||
Index, Record->RecordLength, Offset);
|
||||
|
||||
if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
|
||||
{
|
||||
wcscpy(Name, L".");
|
||||
}
|
||||
else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
|
||||
{
|
||||
wcscpy(Name, L"..");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (DeviceExt->CdInfo.JolietLevel == 0)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
|
||||
Name[i] = (WCHAR)Record->FileId[i];
|
||||
Name[i] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
CdfsSwapString(Name, Record->FileId, Record->FileIdLength);
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT("Name '%S'\n", Name);
|
||||
|
||||
*Ptr = Record;
|
||||
|
||||
*pIndex = Index;
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
CdfsFindFile(PDEVICE_EXTENSION DeviceExt,
|
||||
PFCB Fcb,
|
||||
PFCB Parent,
|
||||
PWSTR FileToFind,
|
||||
PULONG pDirIndex,
|
||||
PULONG pDirIndex2)
|
||||
/*
|
||||
* FUNCTION: Find a file
|
||||
*/
|
||||
{
|
||||
WCHAR name[256];
|
||||
char * block;
|
||||
WCHAR TempStr[2];
|
||||
NTSTATUS Status;
|
||||
ULONG len;
|
||||
ULONG DirIndex;
|
||||
ULONG Offset;
|
||||
ULONG FirstSector;
|
||||
ULONG Read;
|
||||
BOOLEAN IsRoot;
|
||||
LARGE_INTEGER FileOffset;
|
||||
PVOID Context = NULL;
|
||||
|
||||
ULONG DirSize;
|
||||
ULONG BufferSize;
|
||||
ULONG SectorCount;
|
||||
PUCHAR Ptr;
|
||||
PDIR_RECORD Record;
|
||||
|
||||
DPRINT("FindFile(Parent %x, FileToFind '%S', DirIndex: %d)\n", Parent, FileToFind, pDirIndex ? *pDirIndex : 0);
|
||||
DPRINT("FindFile: old Pathname %x, old Objectname %x)\n",Fcb->PathName, Fcb->ObjectName);
|
||||
|
||||
IsRoot = FALSE;
|
||||
DirIndex = 0;
|
||||
if (wcslen (FileToFind) == 0)
|
||||
{
|
||||
CHECKPOINT;
|
||||
TempStr[0] = (WCHAR) '.';
|
||||
TempStr[1] = 0;
|
||||
FileToFind = (PWSTR)&TempStr;
|
||||
}
|
||||
|
||||
if (Parent)
|
||||
{
|
||||
FirstSector = Parent->Entry.ExtentLocationL;
|
||||
if (FirstSector == DeviceExt->CdInfo.RootStart)
|
||||
{
|
||||
IsRoot = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
IsRoot = TRUE;
|
||||
}
|
||||
|
||||
if (IsRoot == TRUE)
|
||||
{
|
||||
FirstSector = DeviceExt->CdInfo.RootStart;
|
||||
DirSize = DeviceExt->CdInfo.RootSize;
|
||||
|
||||
|
||||
if (FileToFind[0] == 0 || (FileToFind[0] == '\\' && FileToFind[1] == 0)
|
||||
|| (FileToFind[0] == '.' && FileToFind[1] == 0))
|
||||
{
|
||||
/* it's root : complete essentials fields then return ok */
|
||||
RtlZeroMemory(Fcb, sizeof(FCB));
|
||||
|
||||
Fcb->PathName[0]='\\';
|
||||
Fcb->ObjectName = &Fcb->PathName[1];
|
||||
Fcb->Entry.ExtentLocationL = DeviceExt->CdInfo.RootStart;
|
||||
Fcb->Entry.DataLengthL = DeviceExt->CdInfo.RootSize;
|
||||
Fcb->Entry.FileFlags = 0x02; //FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
||||
if (pDirIndex)
|
||||
*pDirIndex = 0;
|
||||
if (pDirIndex2)
|
||||
*pDirIndex2 = 0;
|
||||
DPRINT("CdfsFindFile: new Pathname %S, new Objectname %S)\n",Fcb->PathName, Fcb->ObjectName);
|
||||
return (STATUS_SUCCESS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FirstSector = Parent->Entry.ExtentLocationL;
|
||||
DirSize = Parent->Entry.DataLengthL;
|
||||
}
|
||||
|
||||
DPRINT("FirstSector %lu DirSize %lu\n", FirstSector, DirSize);
|
||||
|
||||
if (pDirIndex && (*pDirIndex))
|
||||
DirIndex = *pDirIndex;
|
||||
|
||||
BufferSize = ROUND_UP(DirSize, BLOCKSIZE);
|
||||
SectorCount = BufferSize / BLOCKSIZE;
|
||||
|
||||
DPRINT("FirstSector %lu DirSize %lu BufferSize %lu SectorCount %lu\n",
|
||||
FirstSector, DirSize, BufferSize, SectorCount);
|
||||
|
||||
block = ExAllocatePool(NonPagedPool, BufferSize);
|
||||
|
||||
Status = CdfsReadSectors(DeviceExt->StorageDevice,
|
||||
FirstSector,
|
||||
SectorCount,
|
||||
block);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT("Reading directory extent failed (Status %lx)\n", Status);
|
||||
ExFreePool(block);
|
||||
return(Status);
|
||||
}
|
||||
|
||||
Ptr = (PUCHAR)block;
|
||||
while(TRUE)
|
||||
{
|
||||
Record = (PDIR_RECORD)Ptr;
|
||||
if (Record->RecordLength == 0)
|
||||
{
|
||||
DPRINT1("Stopped!\n");
|
||||
break;
|
||||
}
|
||||
|
||||
DPRINT("RecordLength %u ExtAttrRecordLength %u NameLength %u\n",
|
||||
Record->RecordLength, Record->ExtAttrRecordLength, Record->FileIdLength);
|
||||
|
||||
Status = CdfsGetEntryName(DeviceExt, block, DirSize, (PVOID*)&Ptr, name, &DirIndex, pDirIndex2);
|
||||
if (Status == STATUS_NO_MORE_ENTRIES)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// DPRINT("Name '%S'\n", name);
|
||||
|
||||
if (wstrcmpjoki(name, FileToFind)) /* || wstrcmpjoki (name2, FileToFind)) */
|
||||
{
|
||||
if (Parent && Parent->PathName)
|
||||
{
|
||||
len = wcslen(Parent->PathName);
|
||||
memcpy(Fcb->PathName, Parent->PathName, len*sizeof(WCHAR));
|
||||
Fcb->ObjectName=&Fcb->PathName[len];
|
||||
if (len != 1 || Fcb->PathName[0] != '\\')
|
||||
{
|
||||
Fcb->ObjectName[0] = '\\';
|
||||
Fcb->ObjectName = &Fcb->ObjectName[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Fcb->ObjectName=Fcb->PathName;
|
||||
Fcb->ObjectName[0]='\\';
|
||||
Fcb->ObjectName=&Fcb->ObjectName[1];
|
||||
}
|
||||
|
||||
DPRINT("PathName '%S' ObjectName '%S'\n", Fcb->PathName, Fcb->ObjectName);
|
||||
|
||||
memcpy(&Fcb->Entry, Ptr, sizeof(DIR_RECORD));
|
||||
wcsncpy(Fcb->ObjectName, name, MAX_PATH);
|
||||
if (pDirIndex)
|
||||
*pDirIndex = DirIndex;
|
||||
|
||||
DPRINT("FindFile: new Pathname %S, new Objectname %S, DirIndex %d\n",Fcb->PathName, Fcb->ObjectName, DirIndex);
|
||||
|
||||
ExFreePool(block);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
Ptr = Ptr + Record->RecordLength;
|
||||
DirIndex++;
|
||||
|
||||
if (((ULONG)Ptr - (ULONG)block) >= DirSize)
|
||||
{
|
||||
DPRINT("Stopped!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ExFreePool(block);
|
||||
|
||||
if (pDirIndex)
|
||||
*pDirIndex = DirIndex;
|
||||
|
||||
return(STATUS_UNSUCCESSFUL);
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
CdfsGetBothInformation(PFCB Fcb,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_BOTH_DIRECTORY_INFORMATION Info,
|
||||
ULONG BufferLength)
|
||||
{
|
||||
// short i;
|
||||
// ULONGLONG AllocSize;
|
||||
ULONG Length;
|
||||
|
||||
DPRINT("FileBothDirectoryInformation() called\n");
|
||||
|
||||
Length = wcslen(Fcb->ObjectName) * sizeof(WCHAR);
|
||||
if ((sizeof (FILE_BOTH_DIRECTORY_INFORMATION) + Length) > BufferLength)
|
||||
return(STATUS_BUFFER_OVERFLOW);
|
||||
|
||||
Info->FileNameLength = Length;
|
||||
Info->NextEntryOffset =
|
||||
ROUND_UP(sizeof(FILE_BOTH_DIRECTORY_INFORMATION) + Length, 4);
|
||||
memcpy(Info->FileName, Fcb->ObjectName, Length);
|
||||
|
||||
// Info->FileIndex=;
|
||||
|
||||
/* Convert file times */
|
||||
CdfsDateTimeToFileTime(Fcb,
|
||||
&Info->CreationTime);
|
||||
CdfsDateTimeToFileTime(Fcb,
|
||||
&Info->LastAccessTime);
|
||||
CdfsDateTimeToFileTime(Fcb,
|
||||
&Info->LastWriteTime);
|
||||
CdfsDateTimeToFileTime(Fcb,
|
||||
&Info->ChangeTime);
|
||||
|
||||
Info->EndOfFile.QuadPart = Fcb->Entry.DataLengthL;
|
||||
|
||||
/* Make AllocSize a rounded up multiple of the sector size */
|
||||
// AllocSize = ((Fcb->Entry.DataLengthL + BLOCKSIZE - 1) /
|
||||
// BLOCKSIZE) * BLOCKSIZE;
|
||||
// Info->AllocationSize.QuadPart = AllocSize;
|
||||
Info->AllocationSize.QuadPart = ROUND_UP(Fcb->Entry.DataLengthL, BLOCKSIZE);
|
||||
|
||||
/* FIXME: Convert file flags to file attributes */
|
||||
Info->FileAttributes = (Fcb->Entry.FileFlags & 0x02) ? FILE_ATTRIBUTE_DIRECTORY : 0;
|
||||
Info->EaSize = 0;
|
||||
|
||||
/* FIXME: Copy or create a short file name */
|
||||
#if 0
|
||||
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);
|
||||
pInfo->ShortNameLength *= sizeof(WCHAR);
|
||||
#endif
|
||||
|
||||
Info->ShortName[0] = 0;
|
||||
Info->ShortNameLength = 0;
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
CdfsQueryDirectory(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PDEVICE_EXTENSION DeviceExtension;
|
||||
LONG BufferLength = 0;
|
||||
PUNICODE_STRING SearchPattern = NULL;
|
||||
FILE_INFORMATION_CLASS FileInformationClass;
|
||||
ULONG FileIndex = 0;
|
||||
PUCHAR Buffer = NULL;
|
||||
PFILE_NAMES_INFORMATION Buffer0 = NULL;
|
||||
PFCB Fcb;
|
||||
PCCB Ccb;
|
||||
FCB TempFcb;
|
||||
BOOLEAN First = FALSE;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PFILE_OBJECT FileObject;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
|
||||
DPRINT("CdfsQueryDirectory() called\n");
|
||||
|
||||
DeviceExtension = DeviceObject->DeviceExtension;
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = Stack->FileObject;
|
||||
|
||||
Ccb = (PCCB)FileObject->FsContext2;
|
||||
Fcb = Ccb->Fcb;
|
||||
|
||||
/* Obtain the callers parameters */
|
||||
BufferLength = Stack->Parameters.QueryDirectory.Length;
|
||||
SearchPattern = Stack->Parameters.QueryDirectory.FileName;
|
||||
FileInformationClass =
|
||||
Stack->Parameters.QueryDirectory.FileInformationClass;
|
||||
FileIndex = Stack->Parameters.QueryDirectory.FileIndex;
|
||||
|
||||
|
||||
if (SearchPattern != NULL)
|
||||
{
|
||||
if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
First = TRUE;
|
||||
Ccb->DirectorySearchPattern =
|
||||
ExAllocatePool(NonPagedPool, SearchPattern->Length + sizeof(WCHAR));
|
||||
if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
memcpy(Ccb->DirectorySearchPattern,
|
||||
SearchPattern->Buffer,
|
||||
SearchPattern->Length);
|
||||
Ccb->DirectorySearchPattern[SearchPattern->Length / sizeof(WCHAR)] = 0;
|
||||
}
|
||||
}
|
||||
else if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
First = TRUE;
|
||||
Ccb->DirectorySearchPattern = ExAllocatePool(NonPagedPool, 2 * sizeof(WCHAR));
|
||||
if (!Ccb->DirectorySearchPattern)
|
||||
{
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
Ccb->DirectorySearchPattern[0] = L'*';
|
||||
Ccb->DirectorySearchPattern[1] = 0;
|
||||
}
|
||||
DPRINT("Search pattern '%S'\n", Ccb->DirectorySearchPattern);
|
||||
|
||||
/* Determine directory index */
|
||||
if (Stack->Flags & SL_INDEX_SPECIFIED)
|
||||
{
|
||||
Ccb->Entry = Ccb->CurrentByteOffset.u.LowPart;
|
||||
}
|
||||
else if (First || (Stack->Flags & SL_RESTART_SCAN))
|
||||
{
|
||||
Ccb->Entry = 0;
|
||||
}
|
||||
|
||||
/* Determine Buffer for result */
|
||||
if (Irp->MdlAddress)
|
||||
{
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer = Irp->UserBuffer;
|
||||
}
|
||||
DPRINT("Buffer=%x tofind=%S\n", Buffer, Ccb->DirectorySearchPattern);
|
||||
|
||||
TempFcb.ObjectName = TempFcb.PathName;
|
||||
while (Status == STATUS_SUCCESS && BufferLength > 0)
|
||||
{
|
||||
Status = CdfsFindFile(DeviceExtension,
|
||||
&TempFcb,
|
||||
Fcb,
|
||||
Ccb->DirectorySearchPattern,
|
||||
&Ccb->Entry,
|
||||
NULL);
|
||||
DPRINT("Found %S, Status=%x, entry %x\n", TempFcb.ObjectName, Status, Ccb->Entry);
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
switch (FileInformationClass)
|
||||
{
|
||||
case FileNameInformation:
|
||||
DPRINT1("FileNameInformation\n");
|
||||
// Status = VfatGetFileNameInformation(&TempFcb,
|
||||
// (PFILE_NAMES_INFORMATION) Buffer, BufferLength);
|
||||
// break;
|
||||
|
||||
case FileDirectoryInformation:
|
||||
DPRINT1("FileDirectoryInformation\n");
|
||||
// Status = VfatGetFileDirectoryInformation(&TempFcb, DeviceExtension,
|
||||
// (PFILE_DIRECTORY_INFORMATION) Buffer, BufferLength);
|
||||
break;
|
||||
|
||||
case FileFullDirectoryInformation:
|
||||
DPRINT1("FileFullDirecrotyInformation\n");
|
||||
// Status = CdfsGetFullDirectoryInformation(&TempFcb,
|
||||
// DeviceExtension,
|
||||
// (PFILE_FULL_DIRECTORY_INFORMATION)Buffer, BufferLength);
|
||||
break;
|
||||
|
||||
case FileBothDirectoryInformation:
|
||||
Status = CdfsGetBothInformation(&TempFcb,
|
||||
DeviceExtension,
|
||||
(PFILE_BOTH_DIRECTORY_INFORMATION)Buffer,
|
||||
BufferLength);
|
||||
break;
|
||||
|
||||
default:
|
||||
Status = STATUS_INVALID_INFO_CLASS;
|
||||
}
|
||||
|
||||
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
if (Buffer0)
|
||||
{
|
||||
Buffer0->NextEntryOffset = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Buffer0)
|
||||
{
|
||||
Buffer0->NextEntryOffset = 0;
|
||||
}
|
||||
|
||||
if (First)
|
||||
{
|
||||
Status = STATUS_NO_SUCH_FILE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_NO_MORE_FILES;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Buffer0 = (PFILE_NAMES_INFORMATION)Buffer;
|
||||
Buffer0->FileIndex = FileIndex++;
|
||||
Ccb->Entry++;
|
||||
|
||||
if (Stack->Flags & SL_RETURN_SINGLE_ENTRY)
|
||||
{
|
||||
break;
|
||||
}
|
||||
BufferLength -= Buffer0->NextEntryOffset;
|
||||
Buffer += Buffer0->NextEntryOffset;
|
||||
}
|
||||
|
||||
if (Buffer0)
|
||||
{
|
||||
Buffer0->NextEntryOffset = 0;
|
||||
}
|
||||
|
||||
if (FileIndex > 0)
|
||||
{
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
CdfsDirectoryControl(PDEVICE_OBJECT DeviceObject,
|
||||
|
@ -88,9 +643,18 @@ CdfsDirectoryControl(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
switch (Stack->MinorFunction)
|
||||
{
|
||||
case IRP_MN_QUERY_DIRECTORY:
|
||||
Status = CdfsQueryDirectory(DeviceObject,
|
||||
Irp);
|
||||
break;
|
||||
|
||||
case IRP_MN_NOTIFY_CHANGE_DIRECTORY:
|
||||
DPRINT1("IRP_MN_NOTIFY_CHANGE_DIRECTORY\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT("CDFS: MinorFunction %d\n", Stack->MinorFunction);
|
||||
DPRINT1("CDFS: MinorFunction %d\n", Stack->MinorFunction);
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: fcb.c,v 1.2 2002/04/15 20:39:49 ekohl Exp $
|
||||
/* $Id: fcb.c,v 1.3 2002/04/26 23:21:28 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -283,7 +283,7 @@ vfatMakeFCBFromDirEntry(PVCB vcb,
|
|||
PVFATFCB directoryFCB,
|
||||
PWSTR longName,
|
||||
PFAT_DIR_ENTRY dirEntry,
|
||||
ULONG dirIndex,
|
||||
ULONG dirIndex,
|
||||
PVFATFCB * fileFCB)
|
||||
{
|
||||
PVFATFCB rcFCB;
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
/* $Id: fsctl.c,v 1.1 2002/04/15 20:39:49 ekohl Exp $
|
||||
/* $Id: fsctl.c,v 1.2 2002/04/26 23:21:28 ekohl Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -118,6 +118,8 @@ CdfsGetSVDData(PUCHAR Buffer,
|
|||
JolietLevel = 3;
|
||||
}
|
||||
|
||||
/* Don't support Joliet yet! */
|
||||
//#if 0
|
||||
Vcb->CdInfo.JolietLevel = JolietLevel;
|
||||
|
||||
if (JolietLevel != 0)
|
||||
|
@ -128,6 +130,7 @@ CdfsGetSVDData(PUCHAR Buffer,
|
|||
DPRINT1("RootStart: %lu\n", Svd->RootDirRecord.ExtentLocationL);
|
||||
DPRINT1("RootSize: %lu\n", Svd->RootDirRecord.DataLengthL);
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -199,41 +202,47 @@ CdfsGetVolumeData(PDEVICE_OBJECT DeviceObject,
|
|||
}
|
||||
|
||||
|
||||
static BOOLEAN
|
||||
static NTSTATUS
|
||||
CdfsHasFileSystem(PDEVICE_OBJECT DeviceToMount)
|
||||
/*
|
||||
* FUNCTION: Tests if the device contains a filesystem that can be mounted
|
||||
* by this fsd
|
||||
*/
|
||||
{
|
||||
PUCHAR bytebuf; // [CDFS_BASIC_SECTOR];
|
||||
PUCHAR Buffer;
|
||||
NTSTATUS Status;
|
||||
int ret;
|
||||
|
||||
bytebuf = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
|
||||
if( !bytebuf ) return FALSE;
|
||||
Buffer = ExAllocatePool(NonPagedPool,
|
||||
CDFS_BASIC_SECTOR);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
DPRINT1("CDFS: Checking on mount of device %08x\n", DeviceToMount);
|
||||
|
||||
Status = CdfsReadSectors(DeviceToMount,
|
||||
CDFS_PRIMARY_DESCRIPTOR_LOCATION,
|
||||
1,
|
||||
bytebuf);
|
||||
bytebuf[6] = 0;
|
||||
DPRINT1( "CD-identifier: [%.5s]\n", bytebuf + 1 );
|
||||
Buffer);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
return(Status);
|
||||
}
|
||||
|
||||
ret =
|
||||
Status == STATUS_SUCCESS &&
|
||||
bytebuf[0] == 1 &&
|
||||
bytebuf[1] == 'C' &&
|
||||
bytebuf[2] == 'D' &&
|
||||
bytebuf[3] == '0' &&
|
||||
bytebuf[4] == '0' &&
|
||||
bytebuf[5] == '1';
|
||||
Buffer[6] = 0;
|
||||
DPRINT1("CD-identifier: [%.5s]\n", Buffer + 1);
|
||||
|
||||
ExFreePool( bytebuf );
|
||||
Status = (Buffer[0] == 1 &&
|
||||
Buffer[1] == 'C' &&
|
||||
Buffer[2] == 'D' &&
|
||||
Buffer[3] == '0' &&
|
||||
Buffer[4] == '0' &&
|
||||
Buffer[5] == '1') ? STATUS_SUCCESS : STATUS_UNRECOGNIZED_VOLUME;
|
||||
|
||||
return ret;
|
||||
ExFreePool(Buffer);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,9 +269,9 @@ CdfsMountVolume(PDEVICE_OBJECT DeviceObject,
|
|||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
|
||||
|
||||
if (CdfsHasFileSystem(DeviceToMount) == FALSE)
|
||||
Status = CdfsHasFileSystem(DeviceToMount);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
Status = STATUS_UNRECOGNIZED_VOLUME;
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
|
@ -358,6 +367,106 @@ ByeBye:
|
|||
IoDeleteDevice(NewDeviceObject);
|
||||
}
|
||||
|
||||
DPRINT1("CdfsMountVolume() done (Status: %lx)\n", Status);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
CdfsVerifyVolume(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
{
|
||||
PDEVICE_OBJECT DeviceToVerify;
|
||||
PIO_STACK_LOCATION Stack;
|
||||
PUCHAR Buffer;
|
||||
ULONG Sector;
|
||||
ULONG i;
|
||||
NTSTATUS Status;
|
||||
|
||||
union
|
||||
{
|
||||
ULONG Value;
|
||||
UCHAR Part[4];
|
||||
} Serial;
|
||||
|
||||
DPRINT1("CdfsVerifyVolume() called\n");
|
||||
|
||||
if (DeviceObject != CdfsGlobalData->DeviceObject)
|
||||
{
|
||||
return(STATUS_INVALID_DEVICE_REQUEST);
|
||||
}
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
DeviceToVerify = Stack->Parameters.VerifyVolume.DeviceObject;
|
||||
|
||||
Sector = CDFS_PRIMARY_DESCRIPTOR_LOCATION;
|
||||
|
||||
Buffer = ExAllocatePool(NonPagedPool,
|
||||
CDFS_BASIC_SECTOR);
|
||||
if (Buffer == NULL)
|
||||
{
|
||||
return(STATUS_INSUFFICIENT_RESOURCES);
|
||||
}
|
||||
|
||||
Status = STATUS_WRONG_VOLUME;
|
||||
|
||||
do
|
||||
{
|
||||
/* Read the Primary Volume Descriptor (PVD) */
|
||||
Status = CdfsReadSectors(DeviceToVerify,
|
||||
Sector,
|
||||
1,
|
||||
Buffer);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
goto ByeBye;
|
||||
}
|
||||
|
||||
if (Buffer[0] == 1 &&
|
||||
Buffer[1] == 'C' &&
|
||||
Buffer[2] == 'D' &&
|
||||
Buffer[3] == '0' &&
|
||||
Buffer[4] == '0' &&
|
||||
Buffer[5] == '1')
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Sector++;
|
||||
}
|
||||
while (Buffer[0] != 255);
|
||||
|
||||
if (Buffer[0] == 255)
|
||||
goto ByeBye;
|
||||
|
||||
|
||||
/* Calculate the volume serial number */
|
||||
Serial.Value = 0;
|
||||
for (i = 0; i < 2048; i += 4)
|
||||
{
|
||||
/* DON'T optimize this to ULONG!!! (breaks overflow) */
|
||||
Serial.Part[0] += Buffer[i+3];
|
||||
Serial.Part[1] += Buffer[i+2];
|
||||
Serial.Part[2] += Buffer[i+1];
|
||||
Serial.Part[3] += Buffer[i+0];
|
||||
}
|
||||
|
||||
DPRINT1("Current serial number %08lx Vpb serial number %08lx\n",
|
||||
Serial.Value, DeviceToVerify->Vpb->SerialNumber);
|
||||
|
||||
if (Serial.Value == DeviceToVerify->Vpb->SerialNumber)
|
||||
Status = STATUS_SUCCESS;
|
||||
|
||||
ByeBye:
|
||||
|
||||
ExFreePool(Buffer);
|
||||
|
||||
|
||||
// Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
|
||||
DPRINT1("CdfsVerifyVolume() done (Status: %lx)\n", Status);
|
||||
|
||||
return(Status);
|
||||
}
|
||||
|
||||
|
@ -369,7 +478,7 @@ CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
|
|||
PIO_STACK_LOCATION Stack;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT1("CdfsFileSystemControl() called\n");
|
||||
DPRINT("CdfsFileSystemControl() called\n");
|
||||
|
||||
Stack = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
|
@ -386,8 +495,8 @@ CdfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
|
|||
break;
|
||||
|
||||
case IRP_MN_VERIFY_VOLUME:
|
||||
DPRINT("CDFS: IRP_MN_VERIFY_VOLUME\n");
|
||||
Status = STATUS_INVALID_DEVICE_REQUEST;
|
||||
DPRINT1("CDFS: IRP_MN_VERIFY_VOLUME\n");
|
||||
Status = CdfsVerifyVolume(DeviceObject, Irp);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
Loading…
Reference in a new issue