reactos/rosapps/ramdrv/minix/dir.c

235 lines
5.4 KiB
C

/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: services/fs/minix/minix.c
* PURPOSE: Minix FSD
* PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
#include <ntddk.h>
#include <string.h>
//#define NDEBUG
#include <debug.h>
#include "minix.h"
/* FUNCTIONS ****************************************************************/
BOOLEAN MinixCompareUnicodeStringToAnsi(PCH AnsiStr,
PWCHAR UnicodeStr,
ULONG MaxLen)
{
unsigned int i = 0;
while (i<MaxLen)
{
if ((*AnsiStr)!=(*UnicodeStr))
{
return(FALSE);
}
if ((*AnsiStr)==0 && (*UnicodeStr)==0)
{
return(TRUE);
}
AnsiStr++;
UnicodeStr++;
i++;
}
return(TRUE);
}
#define ENTRIES_PER_BLOCK (BLOCKSIZE / MINIX_DIR_ENTRY_SIZE)
ULONG MinixDirLookup(PMINIX_DEVICE_EXTENSION DeviceExt,
PDEVICE_OBJECT DeviceObject,
struct minix_inode* dir,
PWCHAR Name)
{
struct minix_dir_entry* current_entry = NULL;
unsigned int offset;
unsigned int i;
unsigned int inode;
PVOID Block;
ULONG DiskOffset;
DPRINT("MinixDirLookup(DeviceExt %x, dir %x, Name %S)\n",DeviceExt,dir,
Name);
Block = ExAllocatePool(NonPagedPool, 512);
for (i=0;i<(dir->i_size/MINIX_DIR_ENTRY_SIZE);i++)
{
CHECKPOINT;
offset = i*MINIX_DIR_ENTRY_SIZE;
if ((offset%BLOCKSIZE)==0)
{
MinixReadBlock(DeviceObject,
DeviceExt,
dir,
offset/BLOCKSIZE,
&DiskOffset);
MinixReadSector(DeviceObject,
DiskOffset,
Block);
}
current_entry = (struct minix_dir_entry *)
(Block+offset%BLOCKSIZE);
DPRINT("Inode %x Name %.30s\n",current_entry->inode,
current_entry->name);
if (MinixCompareUnicodeStringToAnsi(current_entry->name,
Name,30))
{
inode = current_entry->inode;
ExFreePool(Block);
DPRINT("MinixDirLookup() = %d\n",inode);
return(inode);
}
}
CHECKPOINT;
ExFreePool(Block);
DPRINT("MinixDirLookup() = %d\n",0);
return(0);
}
NTSTATUS MinixOpen(PDEVICE_OBJECT DeviceObject,
MINIX_DEVICE_EXTENSION* DeviceExt,
PFILE_OBJECT FileObject,
PMINIX_FSCONTEXT result,
PULONG Information)
{
PWSTR current;
PWSTR next;
PWSTR string;
struct minix_inode current_dir;
unsigned int current_ino;
string = ExAllocatePool(NonPagedPool,
2*(wcslen(FileObject->FileName.Buffer)+1));
wcscpy(string, FileObject->FileName.Buffer);
DbgPrint("MinixOpen(DeviceObject %x, DeviceName %S, result %x)\n",
DeviceObject,string,result);
next = &string[0];
current = next+1;
current_ino = MINIX_ROOT_INO;
while (next != NULL && current_ino != 0)
{
MinixReadInode(DeviceObject,DeviceExt,current_ino,&current_dir);
DPRINT("current %S next %x\n",current,next);
*next = '\\';
current = next+1;
next = wcschr(next+1,'\\');
if (next!=NULL)
{
*next=0;
}
current_ino = MinixDirLookup(DeviceExt,
DeviceObject,
&current_dir,
current);
}
if (next == NULL && current_ino != 0)
{
MinixReadInode(DeviceObject,DeviceExt,current_ino,&current_dir);
}
else
{
(*Information) = FILE_DOES_NOT_EXIST;
return(STATUS_UNSUCCESSFUL);
}
result = ExAllocatePool(NonPagedPool, sizeof(MINIX_FSCONTEXT));
memcpy(&result->inode,&current_dir,sizeof(struct minix_inode));
DPRINT("MinxOpen() = STATUS_SUCCESS\n",0);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
MinixClose(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
DPRINT("MinixClose(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
ExFreePool(FileObject->FsContext);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
MinixDirectoryControl(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
// PFILE_OBJECT FileObject = Stack->FileObject;
if (Stack->MinorFunction != IRP_MN_QUERY_DIRECTORY)
{
return(STATUS_NOT_IMPLEMENTED);
}
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL
MinixCreate(PDEVICE_OBJECT DeviceObject,
PIRP Irp)
{
PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject = Stack->FileObject;
NTSTATUS Status;
PMINIX_FSCONTEXT result;
MINIX_DEVICE_EXTENSION* DeviceExt;
DPRINT("MinixCreate(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
DPRINT("Opening file %x %S\n",FileObject->FileName.Buffer,
FileObject->FileName.Buffer);
DPRINT("FileObject->FileName.Buffer %x\n",
FileObject->FileName.Buffer);
DeviceExt = (MINIX_DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
result = ExAllocatePool(NonPagedPool,sizeof(struct minix_inode));
DPRINT("result %x\n",result);
Status = MinixOpen(DeviceExt->AttachedDevice,
DeviceExt,
FileObject,
result,
&Irp->IoStatus.Information);
if (NT_SUCCESS(Status))
{
FileObject->FsContext = result;
}
Irp->IoStatus.Status = Status;
Irp->IoStatus.Information = 0;
DPRINT("Finished MinixCreate()\n");
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(Status);
}