Added basic iso-9660 file system driver. Thanks to Art Yerkes.

svn path=/trunk/; revision=2842
This commit is contained in:
Eric Kohl 2002-04-12 15:43:38 +00:00
parent bb24d01a48
commit c423031b39
9 changed files with 1127 additions and 1 deletions

View file

@ -47,7 +47,7 @@ DEVICE_DRIVERS = vidport vga blue ide null floppy
INPUT_DRIVERS = keyboard mouclass psaux
#FS_DRIVERS = vfat minix ext2 template
FS_DRIVERS = vfat ms np
FS_DRIVERS = vfat ms np cdfs
#NET_DRIVERS = ndis tdi tcpip tditest wshtcpip afd
NET_DRIVERS = ndis tdi tcpip tditest wshtcpip afd

View file

@ -4,5 +4,6 @@ system32\drivers\class2.sys
system32\drivers\disk.sys
system32\drivers\cdrom.sys
system32\drivers\vfatfs.sys
system32\drivers\cdfs.sys
system32\config\system.hiv
*

View file

@ -0,0 +1,756 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/cdfs/cdfs.c
* PURPOSE: CDROM (ISO 9660) filesystem driver
* PROGRAMMER: Art Yerkes
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
//#define NDEBUG
#include <debug.h>
#include "cdfs.h"
typedef struct
{
PDEVICE_OBJECT StorageDevice;
PFILE_OBJECT StreamFileObject;
struct _fcb_system *fss;
PFCB RootFcb;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
/* GLOBALS *****************************************************************/
static PDRIVER_OBJECT DriverObject;
/* FUNCTIONS ****************************************************************/
/* DIRECTORY FUNCTIONS ******************************************************/
/* Hacked until working directory code... */
NTSTATUS
FsdGetRootDirectoryData(PDEVICE_OBJECT DeviceObject,
PFCB RootFcb)
{
PPVD Buffer;
NTSTATUS Status;
Buffer = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
if (Buffer == NULL)
return(STATUS_INSUFFICIENT_RESOURCES);
Status = CdfsReadSectors(DeviceObject,
CDFS_PRIMARY_DESCRIPTOR_LOCATION,
1,
Buffer);
if (!NT_SUCCESS(Status))
return Status;
RootFcb->extent_start = Buffer->RootDirRecord.ExtentLocationL;
RootFcb->byte_count = Buffer->RootDirRecord.DataLengthL;
ExFreePool(Buffer);
DPRINT1("RootFcb->extent_start %lu\n", RootFcb->extent_start);
DPRINT1("RootFcb->byte_count %lu\n", RootFcb->byte_count);
return(STATUS_SUCCESS);
}
/* HACK -- NEEDS FIXING */
int
FsdExtractDirectoryEntry(PDEVICE_EXTENSION DeviceExt,
FsdFcbEntry *parent,
FsdFcbEntry *fill_in,
int entry_to_get)
{
switch( entry_to_get )
{
case 0:
wcscpy( fill_in->name, L"." );
fill_in->extent_start = parent->extent_start;
fill_in->byte_count = parent->byte_count;
break;
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;
}
return 0;
}
FsdFcbEntry *FsdSearchDirectoryAt( PDEVICE_EXTENSION DeviceExt,
FsdFcbEntry *parent,
wchar_t *look_for )
{
FsdFcbEntry *ent;
int i;
ent = FsdCreateFcb( DeviceExt->fss, parent, look_for );
if( ent )
return ent;
for( i = 0; i < parent->byte_count; i++ ) {
FsdFcbEntry new_ent;
if( FsdExtractDirectoryEntry( DeviceExt, parent, &new_ent, i ) )
return NULL;
if( !_wcsicmp( new_ent.name, look_for ) ) {
ent->extent_start = new_ent.extent_start;
ent->byte_count = new_ent.byte_count;
return ent;
}
}
/* Not found */
FsdDelete( ent );
return NULL;
}
NTSTATUS
FsdCloseFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject)
/*
* FUNCTION: Closes a file
*/
{
return(STATUS_SUCCESS);
}
/* Should go into a basic library */
PFCB
FsdSearchDirectory(PDEVICE_EXTENSION DeviceExt,
PFCB ParentFcb,
PWSTR filename)
{
wchar_t *string_imed = NULL;
wchar_t *string_end = NULL;
FsdFcbEntry *this_elt = NULL;
DPRINT1("FsdSearchDirectory(%S) called\n", filename);
if (ParentFcb == NULL && *filename == 0)
return(DeviceExt->RootFcb);
CHECKPOINT1;
string_imed = ExAllocatePool(NonPagedPool,
(wcslen( filename ) + 1) * sizeof( wchar_t ) );
if (string_imed == NULL)
return NULL;
wcscpy( string_imed, filename );
/* Chop off a component and try it */
string_end = wcschr( string_imed, L'\\' );
if (string_end != NULL)
{
*string_end = 0;
string_end++;
}
CHECKPOINT1;
if (ParentFcb == NULL)
this_elt = FsdGetFcbEntry(DeviceExt->fss, NULL, L"\\");
else
this_elt = FsdGetFcbEntry(DeviceExt->fss, ParentFcb, string_imed);
DPRINT1("this_elt %p\n", this_elt);
if (this_elt)
{
ExFreePool( string_imed );
CHECKPOINT1;
return this_elt;
}
CHECKPOINT1;
this_elt = FsdSearchDirectoryAt( DeviceExt, ParentFcb, string_imed );
CHECKPOINT1;
/* It's the end if we have nothing more to do */
if (string_end != NULL)
this_elt = FsdSearchDirectory( DeviceExt, this_elt, string_end );
CHECKPOINT1;
ExFreePool( string_imed );
DPRINT1("FsdSearchDirectory() done");
return this_elt;
}
NTSTATUS
FsdOpenFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PWSTR FileName)
/*
* FUNCTION: Opens a file
*/
{
PFCB Fcb;
DPRINT1("FsdOpenFile(FileName %S) called\n", FileName);
/* Just skip leading backslashes... */
while (*FileName == L'\\')
FileName++;
CHECKPOINT1;
Fcb = FsdSearchDirectory(DeviceExt->fss,
NULL,
FileName);
CHECKPOINT1;
if (Fcb == NULL)
{
DPRINT1("FsdSearchDirectory() failed\n");
return(STATUS_OBJECT_PATH_NOT_FOUND);
}
CHECKPOINT1;
FileObject->Flags = FileObject->Flags | FO_FCB_IS_VALID |
FO_DIRECT_CACHE_PAGING_READ;
FileObject->SectionObjectPointers = &Fcb->SectionObjectPointers;
FileObject->FsContext = Fcb;
FileObject->FsContext2 = DeviceExt->fss;
DPRINT1("FsdOpenFile() done\n");
return(STATUS_SUCCESS);
}
BOOLEAN
FsdHasFileSystem(PDEVICE_OBJECT DeviceToMount)
/*
* FUNCTION: Tests if the device contains a filesystem that can be mounted
* by this fsd
*/
{
PUCHAR bytebuf; // [CDFS_BASIC_SECTOR];
NTSTATUS readstatus;
int ret;
bytebuf = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
if( !bytebuf ) return FALSE;
DPRINT1( "CDFS: Checking on mount of device %08x\n", DeviceToMount );
readstatus = CdfsReadSectors(DeviceToMount,
CDFS_PRIMARY_DESCRIPTOR_LOCATION,
1,
bytebuf);
bytebuf[6] = 0;
DPRINT1( "CD-identifier: [%.5s]\n", bytebuf + 1 );
ret =
readstatus == STATUS_SUCCESS &&
bytebuf[0] == 1 &&
bytebuf[1] == 'C' &&
bytebuf[2] == 'D' &&
bytebuf[3] == '0' &&
bytebuf[4] == '0' &&
bytebuf[5] == '1';
ExFreePool( bytebuf );
return ret;
}
NTSTATUS
FsdMountDevice(PDEVICE_EXTENSION DeviceExt,
PDEVICE_OBJECT DeviceToMount)
/*
* FUNCTION: Mounts the device
*/
{
return(STATUS_SUCCESS);
}
NTSTATUS
FsdReadFile(PDEVICE_EXTENSION DeviceExt,
PFILE_OBJECT FileObject,
PVOID Buffer,
ULONG Length,
ULONG Offset)
/*
* FUNCTION: Reads data from a file
*/
{
PUCHAR bytebuf; // [CDFS_BASIC_SECTOR];
NTSTATUS Status;
int ret;
int sofar = 0;
FsdFcbEntry *ffe = FileObject->FsContext;
if( Length ) return STATUS_SUCCESS;
bytebuf = ExAllocatePool( NonPagedPool, CDFS_BASIC_SECTOR );
if (!bytebuf)
return FALSE;
if (Offset + Length > ffe->byte_count)
Length = ffe->byte_count - Offset;
DPRINT1( "Reading %d bytes at %d\n", Offset, Length );
if( Length == 0 ) return STATUS_UNSUCCESSFUL;
while( sofar < Length )
{
int remains = 0;
Status = CdfsReadSectors(DeviceExt->StorageDevice,
ffe->extent_start + (sofar >> 11),
1,
bytebuf);
if (!NT_SUCCESS(Status))
{
ExFreePool( bytebuf );
return(Status);
}
remains = Length - sofar;
if (remains > BLOCKSIZE)
remains = BLOCKSIZE;
memcpy( ((char *)Buffer) + sofar, bytebuf, remains );
sofar += remains;
}
ExFreePool( bytebuf );
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
FsdClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExtension = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT1( "Closing\n" );
Status = FsdCloseFile(DeviceExtension,FileObject);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS STDCALL
FsdCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt;
DeviceExt = DeviceObject->DeviceExtension;
Status = FsdOpenFile(DeviceExt,FileObject,FileObject->FileName.Buffer);
Irp->IoStatus.Status = Status;
if (Status == STATUS_SUCCESS)
Irp->IoStatus.Information = FILE_OPENED;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS STDCALL
FsdWrite(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
DPRINT("FsdWrite(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
return(STATUS_UNSUCCESSFUL);
}
NTSTATUS STDCALL
FsdRead(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
ULONG Length;
PVOID Buffer;
ULONG Offset;
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
NTSTATUS Status;
DPRINT1("FsdRead(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
Length = Stack->Parameters.Read.Length;
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
Offset = Stack->Parameters.Read.ByteOffset.u.LowPart;
Status = FsdReadFile(DeviceExt,FileObject,Buffer,Length,Offset);
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = Length;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return(Status);
}
// XXX The VPB in devicetomount may be null for some reason...
NTSTATUS
FsdMountVolume(PIRP Irp)
{
PDEVICE_OBJECT DeviceObject = NULL;
PDEVICE_OBJECT DeviceToMount;
PDEVICE_EXTENSION DeviceExt = NULL;
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
DPRINT1("FsdMountVolume() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp);
DeviceToMount = Stack->Parameters.MountVolume.DeviceObject;
if (FsdHasFileSystem(DeviceToMount) == FALSE)
return(STATUS_UNRECOGNIZED_VOLUME);
Status = IoCreateDevice(DriverObject,
sizeof(DEVICE_EXTENSION),
NULL,
FILE_DEVICE_CD_ROM_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status))
return(Status);
DeviceObject->Flags = DeviceObject->Flags | DO_DIRECT_IO;
DeviceExt = (PVOID)DeviceObject->DeviceExtension;
RtlZeroMemory(DeviceExt,sizeof(DEVICE_EXTENSION));
DeviceExt->fss = FsdFcbInit();
if (!DeviceExt->fss)
return(STATUS_UNSUCCESSFUL);
DeviceExt->RootFcb = FsdCreateFcb(DeviceExt->fss, NULL, L"\\");
Status = FsdGetRootDirectoryData(DeviceToMount, DeviceExt->RootFcb);
DeviceObject->Vpb = DeviceToMount->Vpb;
if (DeviceObject->Vpb != NULL)
DeviceObject->Vpb->Flags |= VPB_MOUNTED;
#if 0
Status = FsdMountDevice(DeviceExt,
DeviceToMount);
if (!NT_SUCCESS(Status))
return(Status);
#endif
DeviceExt->StorageDevice = IoAttachDeviceToDeviceStack(DeviceObject,
DeviceToMount);
DeviceExt->StreamFileObject = IoCreateStreamFileObject(NULL,
DeviceExt->StorageDevice);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
FsdFileSystemControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
DPRINT1("CDFS FsdFileSystemControl() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->MinorFunction)
{
case IRP_MN_USER_FS_REQUEST:
DPRINT("CDFS: IRP_MN_USER_FS_REQUEST\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
case IRP_MN_MOUNT_VOLUME:
DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
Status = FsdMountVolume(Irp);
break;
case IRP_MN_VERIFY_VOLUME:
DPRINT("CDFS: IRP_MN_VERIFY_VOLUME\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
default:
DPRINT("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS STDCALL
FsdDirectoryControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack;
NTSTATUS Status;
DPRINT1("FsdDirectoryControl() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp);
switch (Stack->MinorFunction)
{
#if 0
case IRP_MN_USER_FS_REQUEST:
DPRINT("CDFS: IRP_MN_USER_FS_REQUEST\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
case IRP_MN_MOUNT_VOLUME:
DPRINT("CDFS: IRP_MN_MOUNT_VOLUME\n");
Status = FsdMountVolume(Irp);
break;
case IRP_MN_VERIFY_VOLUME:
DPRINT("CDFS: IRP_MN_VERIFY_VOLUME\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
#endif
default:
DPRINT("CDFS FSC: MinorFunction %d\n", Stack->MinorFunction);
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
static NTSTATUS
FsdQueryNameInformation(PFILE_OBJECT FileObject,
PFCB Fcb,
PDEVICE_OBJECT DeviceObject,
PFILE_NAME_INFORMATION NameInfo,
PULONG BufferLength)
/*
* FUNCTION: Retrieve the file name information
*/
{
ULONG NameLength;
assert (NameInfo != NULL);
assert (Fcb != NULL);
#if 0
NameLength = wcslen(FCB->PathName) * sizeof(WCHAR);
if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
return STATUS_BUFFER_OVERFLOW;
NameInfo->FileNameLength = NameLength;
memcpy(NameInfo->FileName,
FCB->PathName,
NameLength + sizeof(WCHAR));
#endif
/* Fake name */
NameLength = 2;
wcscpy(NameInfo->FileName, L"\\");
*BufferLength -=
(sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
return STATUS_SUCCESS;
}
NTSTATUS STDCALL
FsdQueryInformation(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
/*
* FUNCTION: Retrieve the specified file information
*/
{
FILE_INFORMATION_CLASS FileInformationClass;
PIO_STACK_LOCATION Stack;
PFILE_OBJECT FileObject;
PFCB Fcb;
PVOID SystemBuffer;
ULONG BufferLength;
NTSTATUS Status = STATUS_SUCCESS;
DPRINT1("FsdQueryInformation() called\n");
Stack = IoGetCurrentIrpStackLocation(Irp);
FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
FileObject = Stack->FileObject;
Fcb = FileObject->FsContext;
SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
BufferLength = Stack->Parameters.QueryFile.Length;
switch (FileInformationClass)
{
#if 0
case FileStandardInformation:
Status = VfatGetStandardInformation(Fcb,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FilePositionInformation:
RC = VfatGetPositionInformation(IrpContext->FileObject,
FCB,
IrpContext->DeviceObject,
SystemBuffer,
&BufferLength);
break;
case FileBasicInformation:
RC = VfatGetBasicInformation(FileObject,
FCB,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
#endif
case FileNameInformation:
Status = FsdQueryNameInformation(FileObject,
Fcb,
DeviceObject,
SystemBuffer,
&BufferLength);
break;
#if 0
case FileInternalInformation:
Status = FsdGetInternalInformation(Fcb,
SystemBuffer,
&BufferLength);
break;
case FileAlternateNameInformation:
case FileAllInformation:
Status = STATUS_NOT_IMPLEMENTED;
break;
#endif
default:
DPRINT("Unimplemented information class %u\n", FileInformationClass);
Status = STATUS_NOT_SUPPORTED;
}
Irp->IoStatus.Status = Status;
if (NT_SUCCESS(Status))
Irp->IoStatus.Information =
Stack->Parameters.QueryFile.Length - BufferLength;
else
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}
NTSTATUS STDCALL
DriverEntry(PDRIVER_OBJECT _DriverObject,
PUNICODE_STRING RegistryPath)
/*
* FUNCTION: Called by the system to initalize the driver
* ARGUMENTS:
* DriverObject = object describing this driver
* RegistryPath = path to our configuration entries
* RETURNS: Success or failure
*/
{
PDEVICE_OBJECT DeviceObject;
NTSTATUS Status;
UNICODE_STRING DeviceName;
DbgPrint("CDFS 0.0.1\n");
DriverObject = _DriverObject;
RtlInitUnicodeString(&DeviceName,
L"\\Device\\cdfs");
Status = IoCreateDevice(DriverObject,
0,
&DeviceName,
FILE_DEVICE_CD_ROM_FILE_SYSTEM,
0,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
return(Status);
}
DeviceObject->Flags = DO_DIRECT_IO;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = FsdClose;
DriverObject->MajorFunction[IRP_MJ_CREATE] = FsdCreate;
DriverObject->MajorFunction[IRP_MJ_READ] = FsdRead;
DriverObject->MajorFunction[IRP_MJ_WRITE] = FsdWrite;
DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] =
FsdFileSystemControl;
DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] =
FsdDirectoryControl;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
FsdQueryInformation;
DriverObject->DriverUnload = NULL;
IoRegisterFileSystem(DeviceObject);
return(STATUS_SUCCESS);
}

View file

@ -0,0 +1,116 @@
#ifndef CDFS_H
#define CDFS_H
#include <ddk/ntifs.h>
#define CDFS_BASIC_SECTOR 2048
#define CDFS_PRIMARY_DESCRIPTOR_LOCATION 16
#define BLOCKSIZE CDFS_BASIC_SECTOR
#define CDFS_MAX_NAME_LEN 256
struct _DIR_RECORD
{
UCHAR RecordLength; // 1
UCHAR ExtAttrRecordLength; // 2
ULONG ExtentLocationL; // 3-6
ULONG ExtentLocationM; // 7-10
ULONG DataLengthL; // 11-14
ULONG DataLengthM; // 15-18
UCHAR Year; // 19
UCHAR Month; // 20
UCHAR Day; // 21
UCHAR Hour; // 22
UCHAR Minute; // 23
UCHAR Second; // 24
UCHAR TimeZone; // 25
UCHAR FileFlags; // 26
UCHAR FileUnitSize; // 27
UCHAR InterleaveGapSize; // 28
ULONG VolumeSequenceNumber; // 29-32
UCHAR FileIdLength; // 33
UCHAR FileId[1]; // 34
} __attribute__((packed));
typedef struct _DIR_RECORD DIR_RECORD, PDIR_RECORD;
/* Primary Volume Descriptor */
struct _PVD
{
unsigned char VdType; // 1
unsigned char StandardId[5]; // 2-6
unsigned char VdVersion; // 7
unsigned char unused0; // 8
unsigned char SystemId[32]; // 9-40
unsigned char VolumeId[32]; // 41-72
unsigned char unused1[8]; // 73-80
unsigned long VolumeSpaceSizeL; // 81-84
unsigned long VolumeSpaceSizeM; // 85-88
unsigned char unused2[32]; // 89-120
unsigned long VolumeSetSize; // 121-124
unsigned long VolumeSequenceNumber; // 125-128
unsigned long LogicalBlockSize; // 129-132
unsigned long PathTableSizeL; // 133-136
unsigned long PathTableSizeM; // 137-140
ULONG LPathTablePos; // 141-144
ULONG LOptPathTablePos; // 145-148
ULONG MPathTablePos; // 149-152
ULONG MOptPathTablePos; // 153-156
DIR_RECORD RootDirRecord; // 157-190
/* more data ... */
} __attribute__((packed));
typedef struct _PVD PVD, *PPVD;
typedef struct _FCB
{
REACTOS_COMMON_FCB_HEADER RFCB;
SECTION_OBJECT_POINTERS SectionObjectPointers;
/* CDFS owned elements */
struct _FCB *next;
struct _FCB *parent;
wchar_t name[CDFS_MAX_NAME_LEN];
int hashval;
unsigned int extent_start;
unsigned int byte_count;
unsigned int file_pointer;
} FsdFcbEntry, FCB, *PFCB;
NTSTATUS
CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer);
int CdfsStrcmpi( wchar_t *str1, wchar_t *str2 );
void CdfsWstrcpy( wchar_t *str1, wchar_t *str2, int max );
/*
CDFS: FCB system (Perhaps there should be a library to make this easier)
*/
typedef struct _fcb_system
{
int fcbs_in_use;
int fcb_table_size;
int fcb_table_mask;
FsdFcbEntry **fcb_table;
FsdFcbEntry *parent;
} fcb_system;
PFCB
FsdGetFcbEntry(fcb_system *fss,
PFCB ParentFcb,
PWSTR name);
#endif//CDFS_H

View file

@ -0,0 +1,39 @@
#include <defines.h>
#include <reactos/resource.h>
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
VS_VERSION_INFO VERSIONINFO
FILEVERSION RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
PRODUCTVERSION RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", RES_STR_COMPANY_NAME
VALUE "FileDescription", "ISO9660 Driver\0"
VALUE "FileVersion", "0.0.6\0"
VALUE "InternalName", "cdfs\0"
VALUE "LegalCopyright", RES_STR_LEGAL_COPYRIGHT
VALUE "OriginalFilename", "cdfs.sys\0"
VALUE "ProductName", RES_STR_PRODUCT_NAME
VALUE "ProductVersion", RES_STR_PRODUCT_VERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END

View file

@ -0,0 +1,75 @@
#include <ddk/ntddk.h>
#define NDEBUG
#include <debug.h>
#include "cdfs.h"
NTSTATUS
CdfsReadSectors(IN PDEVICE_OBJECT DeviceObject,
IN ULONG DiskSector,
IN ULONG SectorCount,
IN OUT PUCHAR Buffer)
{
IO_STATUS_BLOCK IoStatus;
LARGE_INTEGER Offset;
ULONG BlockSize;
KEVENT Event;
PIRP Irp;
NTSTATUS Status;
KeInitializeEvent(&Event,
NotificationEvent,
FALSE);
Offset.u.LowPart = DiskSector << 11;
Offset.u.HighPart = DiskSector >> 21;
BlockSize = BLOCKSIZE * SectorCount;
DPRINT("CdfsReadSectors(DeviceObject %x, DiskSector %d, Buffer %x)\n",
DeviceObject, DiskSector, Buffer);
DPRINT("Offset %I64x BlockSize %ld\n",
Offset.QuadPart,
BlockSize);
DPRINT("Building synchronous FSD Request...\n");
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ,
DeviceObject,
Buffer,
BlockSize,
&Offset,
&Event,
&IoStatus);
if (Irp == NULL)
{
DPRINT("IoBuildSynchronousFsdRequest failed\n");
return(STATUS_INSUFFICIENT_RESOURCES);
}
DPRINT("Calling IO Driver... with irp %x\n", Irp);
Status = IoCallDriver(DeviceObject, Irp);
DPRINT("Waiting for IO Operation for %x\n", Irp);
if (Status == STATUS_PENDING)
{
DPRINT("Operation pending\n");
KeWaitForSingleObject(&Event, Suspended, KernelMode, FALSE, NULL);
DPRINT("Getting IO Status... for %x\n", Irp);
Status = IoStatus.Status;
}
if (!NT_SUCCESS(Status))
{
DPRINT("CdfsReadSectors() failed (Status %x)\n", Status);
DPRINT("(DeviceObject %x, DiskSector %x, Buffer %x, Offset 0x%I64x)\n",
DeviceObject, DiskSector, Buffer,
Offset.QuadPart);
return(Status);
}
DPRINT("Block request succeeded for %x\n", Irp);
return(STATUS_SUCCESS);
}

View file

@ -0,0 +1,123 @@
#include <ddk/ntddk.h>
#include "cdfs.h"
/*
CDFS: FCB system (Perhaps there should be a library to make this easier)
*/
#if 0
typedef struct _fcb_system {
int fcbs_in_use;
int fcb_table_size;
int fcb_table_mask;
FsdFcbEntry **fcb_table;
FsdFcbEntry *parent;
} fcb_system;
#endif
// Create a hash over this name for table
static int FsdNameHash( FsdFcbEntry *parent, wchar_t *name ) {
int i;
int hashval = 0;
for( i = 0; name[i]; i++ )
hashval ^= name[i] << (i & 0xf);
hashval ^= (int)parent;
return hashval;
}
// Init the fcb system
fcb_system *FsdFcbInit() {
fcb_system *fss = ExAllocatePool( NonPagedPool,
sizeof( fcb_system ) );
if( !fss ) return NULL;
RtlZeroMemory( fss, sizeof( *fss ) );
fss->fcb_table_size = 128;
fss->fcb_table_mask = fss->fcb_table_size - 1;
fss->fcb_table = ExAllocatePool( NonPagedPool,
sizeof( FsdFcbEntry ** ) *
fss->fcb_table_size );
if( !fss->fcb_table ) {
ExFreePool( fss );
return NULL;
}
RtlZeroMemory( fss->fcb_table, sizeof( FsdFcbEntry ** ) *
fss->fcb_table_size );
return fss;
}
// Delete the fcb system
void FsdFcbDeinit( fcb_system *fss ) {
if( fss->fcb_table ) ExFreePool( fss->fcb_table );
}
// Get one entry from the FCB system by name...
FsdFcbEntry *FsdGetFcbEntry( fcb_system *fss, FsdFcbEntry *parent,
wchar_t *name ) {
int hashval;
FsdFcbEntry *table_ent = NULL;
hashval = FsdNameHash( parent, name ) & fss->fcb_table_mask;
table_ent = fss->fcb_table[hashval];
while( table_ent && _wcsicmp( table_ent->name, name ) &&
table_ent->parent != parent )
table_ent = table_ent->next;
return table_ent;
}
// Create an fcb with the given name...
FsdFcbEntry *FsdCreateFcb( fcb_system *fss, FsdFcbEntry *parent,
wchar_t *filename ) {
int hashval;
int tableval;
FsdFcbEntry *table_ent = FsdGetFcbEntry( fss, parent, filename );
if( table_ent ) return table_ent;
hashval = FsdNameHash( parent, filename );
tableval = hashval & fss->fcb_table_mask;
table_ent = ExAllocatePool( NonPagedPool, sizeof( FsdFcbEntry ) );
if( table_ent ) {
table_ent->next = fss->fcb_table[tableval];
table_ent->hashval = hashval;
table_ent->parent = parent;
wcscpy( table_ent->name, filename );
fss->fcb_table[tableval] = table_ent;
}
return table_ent;
}
// Delete this fcb...
void FsdDelete( fcb_system *fss, FsdFcbEntry *which ) {
int tableval = which->hashval & fss->fcb_table_mask;
FsdFcbEntry *table_ent = fss->fcb_table[tableval];
if( table_ent == which ) {
fss->fcb_table[tableval] = fss->fcb_table[tableval]->next;
ExFreePool( which );
return;
}
if( !table_ent ) return;
while( table_ent->next ) {
if( table_ent->next == which ) {
table_ent->next = table_ent->next->next;
ExFreePool( which );
return;
}
table_ent = table_ent->next;
}
}

View file

@ -0,0 +1,15 @@
# $Id: makefile,v 1.1 2002/04/12 15:41:39 ekohl Exp $
PATH_TO_TOP = ../../..
TARGET_TYPE = driver
TARGET_NAME = cdfs
TARGET_OBJECTS = $(TARGET_NAME).o common.o fcb.o
include $(PATH_TO_TOP)/rules.mak
include $(TOOLS_PATH)/helper.mk
# EOF

View file

@ -26,6 +26,7 @@ copy ntoskrnl\ntoskrnl.exe %ROS_INSTALL%\system32
copy ntoskrnl\ntoskrnl.sym %ROS_INSTALL%\symbols
copy hal\halx86\hal.dll %ROS_INSTALL%\system32
copy services\fs\vfat\vfatfs.sys %ROS_INSTALL%\system32\drivers
copy services\fs\cdfs\cdfs.sys %ROS_INSTALL%\system32\drivers
copy services\fs\ms\msfs.sys %ROS_INSTALL%\system32\drivers
copy services\fs\np\npfs.sys %ROS_INSTALL%\system32\drivers
copy services\bus\acpi\acpi.sys %ROS_INSTALL%\system32\drivers