0b727c3f6dc29ba000048d100d0056365c003dfb
[reactos.git] / rosapps / ramdrv / 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 <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