- Gather drivers in a special "drivers" subdirectory.
[reactos.git] / rosapps / drivers / ramdrv / minix / dir.c
diff --git a/rosapps/drivers/ramdrv/minix/dir.c b/rosapps/drivers/ramdrv/minix/dir.c
new file mode 100644 (file)
index 0000000..0b727c3
--- /dev/null
@@ -0,0 +1,234 @@
+/*
+ * 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);
+}
+