update for HEAD-2003091401
[reactos.git] / drivers / fs / minix / dir.c
1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS kernel
4  * FILE:             services/fs/minix/minix.c
5  * PURPOSE:          Minix FSD
6  * PROGRAMMER:       David Welch (welch@mcmail.com)
7  * UPDATE HISTORY: 
8  */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ddk/ntddk.h>
13 #include <string.h>
14
15 //#define NDEBUG
16 #include <debug.h>
17
18 #include "minix.h"
19
20 /* FUNCTIONS ****************************************************************/
21
22 BOOLEAN MinixCompareUnicodeStringToAnsi(PCH AnsiStr, 
23                                         PWCHAR UnicodeStr,
24                                         ULONG MaxLen)
25 {
26    unsigned int i = 0;
27    
28    while (i<MaxLen)
29      {
30         if ((*AnsiStr)!=(*UnicodeStr))
31           {
32              return(FALSE);
33           }
34         if ((*AnsiStr)==0 && (*UnicodeStr)==0)
35           {
36              return(TRUE);
37           }
38         AnsiStr++;
39         UnicodeStr++;
40         i++;
41      }
42    return(TRUE);
43 }
44
45 #define ENTRIES_PER_BLOCK (BLOCKSIZE / MINIX_DIR_ENTRY_SIZE)
46
47 ULONG MinixDirLookup(PMINIX_DEVICE_EXTENSION DeviceExt,
48                      PDEVICE_OBJECT DeviceObject,
49                      struct minix_inode* dir,
50                      PWCHAR Name)
51 {
52    struct minix_dir_entry* current_entry = NULL;
53    unsigned int offset;
54    unsigned int i;
55    unsigned int inode;
56    PVOID Block;
57    ULONG DiskOffset;
58    
59    DPRINT("MinixDirLookup(DeviceExt %x, dir %x, Name %S)\n",DeviceExt,dir,
60           Name);
61    
62    Block = ExAllocatePool(NonPagedPool, 512);
63    
64    for (i=0;i<(dir->i_size/MINIX_DIR_ENTRY_SIZE);i++)
65      {
66         CHECKPOINT;
67         offset = i*MINIX_DIR_ENTRY_SIZE;
68         if ((offset%BLOCKSIZE)==0)
69           {
70              MinixReadBlock(DeviceObject,
71                             DeviceExt,
72                             dir,
73                             offset/BLOCKSIZE,
74                             &DiskOffset);
75              MinixReadSector(DeviceObject,
76                              DiskOffset,
77                              Block);
78           }
79         current_entry = (struct minix_dir_entry *)
80           (Block+offset%BLOCKSIZE);
81         DPRINT("Inode %x Name %.30s\n",current_entry->inode,
82                current_entry->name);
83         if (MinixCompareUnicodeStringToAnsi(current_entry->name,
84                                             Name,30))
85           {
86              inode = current_entry->inode;
87              ExFreePool(Block);
88              DPRINT("MinixDirLookup() = %d\n",inode);
89              return(inode);
90           }
91      }
92    CHECKPOINT;
93    ExFreePool(Block);
94    DPRINT("MinixDirLookup() = %d\n",0);
95    return(0);
96 }
97
98 NTSTATUS MinixOpen(PDEVICE_OBJECT DeviceObject,
99                    MINIX_DEVICE_EXTENSION* DeviceExt,
100                    PFILE_OBJECT FileObject,
101                    PMINIX_FSCONTEXT result,
102                    PULONG Information)
103 {
104    PWSTR current;
105    PWSTR next;
106    PWSTR string;
107    struct minix_inode current_dir;
108    unsigned int current_ino;
109    
110    string = ExAllocatePool(NonPagedPool, 
111                            2*(wcslen(FileObject->FileName.Buffer)+1));
112    wcscpy(string, FileObject->FileName.Buffer);
113    
114    DbgPrint("MinixOpen(DeviceObject %x, DeviceName %S, result %x)\n",
115           DeviceObject,string,result);
116    
117    
118    next = &string[0];
119    current = next+1;
120    
121    current_ino = MINIX_ROOT_INO;
122    
123    while (next != NULL && current_ino != 0)
124      {  
125         MinixReadInode(DeviceObject,DeviceExt,current_ino,&current_dir);
126
127         DPRINT("current %S next %x\n",current,next);
128         
129         *next = '\\';
130         current = next+1;
131         next = wcschr(next+1,'\\');
132         if (next!=NULL)
133           {
134              *next=0;
135           }
136         
137         current_ino = MinixDirLookup(DeviceExt,
138                                      DeviceObject,
139                                      &current_dir,
140                                      current);
141      }
142    if (next == NULL && current_ino != 0)
143      {
144         MinixReadInode(DeviceObject,DeviceExt,current_ino,&current_dir);       
145      }
146    else
147      {
148         (*Information) = FILE_DOES_NOT_EXIST;
149         return(STATUS_UNSUCCESSFUL);
150      }
151    
152    result = ExAllocatePool(NonPagedPool, sizeof(MINIX_FSCONTEXT));
153    memcpy(&result->inode,&current_dir,sizeof(struct minix_inode));
154    
155    DPRINT("MinxOpen() = STATUS_SUCCESS\n",0);
156    return(STATUS_SUCCESS);
157 }
158
159 NTSTATUS STDCALL
160 MinixClose(PDEVICE_OBJECT DeviceObject,
161            PIRP Irp)
162 {
163    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
164    PFILE_OBJECT FileObject = Stack->FileObject;
165
166    DPRINT("MinixClose(DeviceObject %x Irp %x)\n",DeviceObject,Irp);
167    
168    ExFreePool(FileObject->FsContext);
169
170    Irp->IoStatus.Status = STATUS_SUCCESS;
171    Irp->IoStatus.Information = 0;
172    
173    IoCompleteRequest(Irp, IO_NO_INCREMENT);
174    return(STATUS_SUCCESS);
175 }
176
177 NTSTATUS STDCALL
178 MinixDirectoryControl(PDEVICE_OBJECT DeviceObject,
179                       PIRP Irp)
180 {
181    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
182 //   PFILE_OBJECT FileObject = Stack->FileObject;
183    
184    if (Stack->MinorFunction != IRP_MN_QUERY_DIRECTORY)
185      {
186         return(STATUS_NOT_IMPLEMENTED);
187      }
188    
189    Irp->IoStatus.Status = STATUS_SUCCESS;
190    Irp->IoStatus.Information = 0;
191    
192    IoCompleteRequest(Irp, IO_NO_INCREMENT);
193    return(STATUS_SUCCESS);
194 }
195
196 NTSTATUS STDCALL
197 MinixCreate(PDEVICE_OBJECT DeviceObject,
198             PIRP Irp)
199 {
200    PIO_STACK_LOCATION Stack = IoGetCurrentIrpStackLocation(Irp);
201    PFILE_OBJECT FileObject = Stack->FileObject;
202    NTSTATUS Status;
203    PMINIX_FSCONTEXT result;
204    MINIX_DEVICE_EXTENSION* DeviceExt;
205    
206    DPRINT("MinixCreate(DeviceObject %x, Irp %x)\n",DeviceObject,Irp);
207    DPRINT("Opening file %x %S\n",FileObject->FileName.Buffer,
208             FileObject->FileName.Buffer);
209    DPRINT("FileObject->FileName.Buffer %x\n",
210             FileObject->FileName.Buffer);
211    
212    DeviceExt = (MINIX_DEVICE_EXTENSION *)DeviceObject->DeviceExtension;
213    result = ExAllocatePool(NonPagedPool,sizeof(struct minix_inode));
214    DPRINT("result %x\n",result);
215    Status = MinixOpen(DeviceExt->AttachedDevice,
216                       DeviceExt,
217                       FileObject,
218                       result,
219                       &Irp->IoStatus.Information);
220    
221    if (NT_SUCCESS(Status))
222      {
223         FileObject->FsContext = result;
224      }
225    
226    Irp->IoStatus.Status = Status;
227    Irp->IoStatus.Information = 0;
228    
229    DPRINT("Finished MinixCreate()\n");
230    
231    IoCompleteRequest(Irp, IO_NO_INCREMENT);
232    return(Status);
233 }
234