2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: services/fs/minix/minix.c
6 * PROGRAMMER: David Welch (welch@mcmail.com)
10 /* INCLUDES *****************************************************************/
12 #include <ddk/ntddk.h>
13 #include <internal/string.h>
17 #include <internal/debug.h>
21 /* GLOBALS ******************************************************************/
23 static PDRIVER_OBJECT DriverObject
;
27 PDEVICE_OBJECT AttachedDevice
;
28 struct minix_inode root_inode
;
29 char superblock_buf
[BLOCKSIZE
];
30 struct minix_super_block
* sb
;
31 } MINIX_DEVICE_EXTENSION
;
33 /* FUNCTIONS ****************************************************************/
36 static unsigned int MinixGetIndirectBlock(struct minix_inode
* inode
,
37 unsigned char* buffer
, int blk
)
39 unsigned short int* buf
= (unsigned short int *)buffer
;
43 static unsigned int MinixGetBlock(PDEVICE_OBJECT DeviceObject
,
44 struct minix_inode
* inode
,
51 DPRINT("MinixGetBlock(inode %x, blk %d)\n",inode
,blk
);
55 block
= inode
->i_zone
[blk
];
60 buffer
= ExAllocatePool(NonPagedPool
,1024);
64 block
= inode
->i_zone
[7];
65 MinixReadSector(DeviceObject
,block
,buffer
);
66 block
= MinixGetIndirectBlock(inode
,buffer
,blk
);
71 block
= inode
->i_zone
[8];
72 MinixReadSector(DeviceObject
,block
,buffer
);
73 block
= MinixGetIndirectBlock(inode
,buffer
,(blk
>>9)&511);
74 MinixReadSector(DeviceObject
,block
,buffer
);
75 block
= MinixGetIndirectBlock(inode
,buffer
,blk
&511);
80 NTSTATUS
MinixReadBlock(PDEVICE_OBJECT DeviceObject
,
81 struct minix_inode
* inode
,
87 DPRINT("MinixReadBlock(inode %x, blk %d, buffer %x)\n",inode
,blk
,buffer
);
88 block
= MinixGetBlock(DeviceObject
,inode
,blk
);
89 DPRINT("block %d\n",block
);
90 return(MinixReadSector(DeviceObject
,block
,buffer
));
93 VOID
MinixMount(PDEVICE_OBJECT DeviceToMount
)
95 PDEVICE_OBJECT DeviceObject
;
96 MINIX_DEVICE_EXTENSION
* DeviceExt
;
98 IoCreateDevice(DriverObject
,
99 sizeof(MINIX_DEVICE_EXTENSION
),
101 FILE_DEVICE_FILE_SYSTEM
,
105 DeviceObject
->Flags
= DeviceObject
->Flags
| DO_DIRECT_IO
;
106 DeviceExt
= DeviceObject
->DeviceExtension
;
108 MinixReadSector(DeviceToMount
,1,DeviceExt
->superblock_buf
);
109 DeviceExt
->sb
= (struct minix_super_block
*)(DeviceExt
->superblock_buf
);
111 DeviceExt
->AttachedDevice
= IoAttachDeviceToDeviceStack(DeviceObject
,
115 NTSTATUS
MinixFileSystemControl(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
117 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
118 PVPB vpb
= Stack
->Parameters
.Mount
.Vpb
;
119 PDEVICE_OBJECT DeviceToMount
= Stack
->Parameters
.Mount
.DeviceObject
;
121 char* superblock_buf
;
122 struct minix_super_block
* sb
;
124 DbgPrint("MinixFileSystemControl(DeviceObject %x, Irp %x)\n",DeviceObject
,
126 DPRINT("DeviceToMount %x\n",DeviceToMount
);
128 superblock_buf
= ExAllocatePool(NonPagedPool
,BLOCKSIZE
);
130 DPRINT("MinixReadSector %x\n",MinixReadSector
);
131 MinixReadSector(DeviceToMount
,1,superblock_buf
);
132 sb
= (struct minix_super_block
*)superblock_buf
;
133 DPRINT("Magic %x\n",sb
->s_magic
);
134 DPRINT("Imap blocks %x\n",sb
->s_imap_blocks
);
135 DPRINT("Zmap blocks %x\n",sb
->s_zmap_blocks
);
136 if (sb
->s_magic
==MINIX_SUPER_MAGIC2
)
138 DPRINT("%s() = STATUS_SUCCESS\n",__FUNCTION__
);
139 MinixMount(DeviceToMount
);
140 Status
= STATUS_SUCCESS
;
144 DPRINT("%s() = STATUS_UNRECOGNIZED_VOLUME\n",__FUNCTION__
);
145 Status
= STATUS_UNRECOGNIZED_VOLUME
;
148 Irp
->IoStatus
.Status
= Status
;
149 Irp
->IoStatus
.Information
= 0;
151 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
156 NTSTATUS
MinixReadInode(PDEVICE_OBJECT DeviceObject
,
157 MINIX_DEVICE_EXTENSION
* DeviceExt
,
159 struct minix_inode
* result
)
163 struct minix_inode
* inodes
;
165 DPRINT("MinixReadInode(ino %x, result %x)\n",ino
,result
);
167 buffer
= ExAllocatePool(NonPagedPool
,1024);
168 inodes
= (struct minix_inode
*)buffer
;
170 block
= 2 + DeviceExt
->sb
->s_imap_blocks
+ DeviceExt
->sb
->s_zmap_blocks
171 + ((ino
-1) / MINIX_INODES_PER_BLOCK
);
172 DPRINT("Reading block %x offset %x\n",block
,block
*BLOCKSIZE
);
173 DPRINT("Index %x\n",(ino
-1)%MINIX_INODES_PER_BLOCK
);
174 MinixReadSector(DeviceObject
,block
,buffer
);
175 memcpy(result
,&inodes
[(ino
-1)%MINIX_INODES_PER_BLOCK
],
176 sizeof(struct minix_inode
));
177 DPRINT("result->i_uid %x\n",result
->i_uid
);
178 DPRINT("result->i_size %x\n",result
->i_size
);
179 return(STATUS_SUCCESS
);
182 BOOLEAN
MinixCompareUnicodeStringToAnsi(PCH AnsiStr
, PWCHAR UnicodeStr
,
189 if ((*AnsiStr
)!=(*UnicodeStr
))
193 if ((*AnsiStr
)==0 && (*UnicodeStr
)==0)
204 ULONG
MinixDirLookup(PDEVICE_OBJECT DeviceObject
,
205 struct minix_inode
* dir
,
209 struct minix_dir_entry
* entry
;
214 buffer
=ExAllocatePool(NonPagedPool
,BLOCKSIZE
);
216 for (i
=0;i
<(dir
->i_size
/MINIX_DIR_ENTRY_SIZE
);i
++)
218 offset
= i
*MINIX_DIR_ENTRY_SIZE
;
219 if ((offset
%BLOCKSIZE
)==0)
221 MinixReadBlock(DeviceObject
,
226 entry
= (struct minix_dir_entry
*)&buffer
[offset
%BLOCKSIZE
];
227 DPRINT("Inode %x Name %.30s\n",entry
->inode
,entry
->name
);
228 if (MinixCompareUnicodeStringToAnsi(entry
->name
,Name
,30))
230 inode
= entry
->inode
;
232 DPRINT("MinixDirLookup() = %d\n",inode
);
237 DPRINT("MinixDirLookup() = %d\n",0);
241 NTSTATUS
MinixOpen(PDEVICE_OBJECT DeviceObject
,
242 MINIX_DEVICE_EXTENSION
* DeviceExt
,
244 struct minix_inode
* result
)
248 PWSTR string
= DeviceName
;
249 struct minix_inode current_dir
;
250 unsigned int current_ino
;
252 DbgPrint("MinixOpen(DeviceObject %x, DeviceName %S, result %x)\n",
253 DeviceObject
,DeviceName
,result
);
254 DPRINT("DeviceName %x\n",DeviceName
);
259 current_ino
= MINIX_ROOT_INO
;
261 while (next
!=NULL
&& current_ino
!=0)
263 MinixReadInode(DeviceObject
,DeviceExt
,current_ino
,¤t_dir
);
265 DPRINT("current %S next %x\n",current
,next
);
269 next
= wcschr(next
+1,'\\');
275 current_ino
= MinixDirLookup(DeviceObject
,¤t_dir
,current
);
277 if (next
==NULL
&& current_ino
!=0)
279 MinixReadInode(DeviceObject
,DeviceExt
,current_ino
,¤t_dir
);
281 memcpy(result
,¤t_dir
,sizeof(struct minix_inode
));
282 DPRINT("MinxOpen() = STATUS_SUCCESS\n",0);
283 return(STATUS_SUCCESS
);
286 NTSTATUS
MinixWrite(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
288 DPRINT("MinixWrite(DeviceObject %x Irp %x)\n",DeviceObject
,Irp
);
290 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
291 Irp
->IoStatus
.Information
= 0;
292 return(STATUS_UNSUCCESSFUL
);
295 NTSTATUS
MinixRead(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
301 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
302 PFILE_OBJECT FileObject
= Stack
->FileObject
;
303 MINIX_DEVICE_EXTENSION
* DeviceExt
= DeviceObject
->DeviceExtension
;
304 struct minix_inode
* inode
= (struct minix_inode
*)FileObject
->FsContext
;
308 DPRINT("MinixRead(DeviceObject %x, Irp %x)\n",DeviceObject
,Irp
);
310 Length
= Stack
->Parameters
.Read
.Length
;
311 Buffer
= MmGetSystemAddressForMdl(Irp
->MdlAddress
);
312 Offset
= Stack
->Parameters
.Read
.ByteOffset
.LowPart
;
314 TempBuffer
= ExAllocatePool(NonPagedPool
,BLOCKSIZE
);
316 DPRINT("Length %x Buffer %x Offset %x\n",Length
,Buffer
,Offset
);
318 CurrentOffset
=Offset
;
320 if ((Offset
%BLOCKSIZE
)!=0)
324 CurrentOffset
= Offset
- (Offset
%BLOCKSIZE
);
326 MinixReadBlock(DeviceExt
->AttachedDevice
,inode
,
327 CurrentOffset
/BLOCKSIZE
,
329 memcpy(Buffer
,TempBuffer
+(Offset
%BLOCKSIZE
),
330 min(BLOCKSIZE
- (Offset
%BLOCKSIZE
),Length
));
331 DPRINT("(BLOCKSIZE - (Offset%BLOCKSIZE)) %d\n",
332 (BLOCKSIZE
- (Offset
%BLOCKSIZE
)));
333 DPRINT("Length %d\n",Length
);
334 CurrentOffset
= CurrentOffset
+ BLOCKSIZE
;
335 Buffer
= Buffer
+ BLOCKSIZE
- (Offset
%BLOCKSIZE
);
336 Length
= Length
- min(BLOCKSIZE
- (Offset
%BLOCKSIZE
),Length
);
337 DPRINT("CurrentOffset %d Buffer %x Length %d\n",CurrentOffset
,Buffer
,
340 for (i
=0;i
<(Length
/BLOCKSIZE
);i
++)
344 MinixReadBlock(DeviceExt
->AttachedDevice
,inode
,
345 CurrentOffset
/BLOCKSIZE
,Buffer
);
346 CurrentOffset
= CurrentOffset
+ BLOCKSIZE
;
347 Buffer
= Buffer
+ BLOCKSIZE
;
348 Length
= Length
- BLOCKSIZE
;
354 MinixReadBlock(DeviceExt
->AttachedDevice
,inode
,
355 CurrentOffset
/BLOCKSIZE
,
357 memcpy(Buffer
,TempBuffer
,Length
);
360 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
361 Irp
->IoStatus
.Information
= Length
;
362 return(STATUS_SUCCESS
);
365 NTSTATUS
MinixClose(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
367 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
368 PFILE_OBJECT FileObject
= Stack
->FileObject
;
370 DPRINT("MinixClose(DeviceObject %x Irp %x)\n",DeviceObject
,Irp
);
372 ExFreePool(FileObject
->FsContext
);
374 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
375 Irp
->IoStatus
.Information
= 0;
377 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
378 return(STATUS_SUCCESS
);
381 NTSTATUS
MinixCreate(PDEVICE_OBJECT DeviceObject
, PIRP Irp
)
383 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
384 PFILE_OBJECT FileObject
= Stack
->FileObject
;
386 struct minix_inode
* result
;
387 MINIX_DEVICE_EXTENSION
* DeviceExt
;
389 DPRINT("MinixCreate(DeviceObject %x, Irp %x)\n",DeviceObject
,Irp
);
390 DPRINT("Opening file %x %S\n",FileObject
->FileName
.Buffer
,
391 FileObject
->FileName
.Buffer
);
392 DPRINT("FileObject->FileName.Buffer %x\n",
393 FileObject
->FileName
.Buffer
);
395 DeviceExt
= (MINIX_DEVICE_EXTENSION
*)DeviceObject
->DeviceExtension
;
396 result
= ExAllocatePool(NonPagedPool
,sizeof(struct minix_inode
));
397 DPRINT("result %x\n",result
);
398 Status
= MinixOpen(DeviceExt
->AttachedDevice
,DeviceExt
,
399 FileObject
->FileName
.Buffer
,result
);
401 if (Status
==STATUS_SUCCESS
)
403 FileObject
->FsContext
=result
;
406 Irp
->IoStatus
.Status
= Status
;
407 Irp
->IoStatus
.Information
= 0;
409 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
413 NTSTATUS
DriverEntry(PDRIVER_OBJECT _DriverObject
,
414 PUNICODE_STRING RegistryPath
)
416 * FUNCTION: Called by the system to initalize the driver
418 * DriverObject = object describing this driver
419 * RegistryPath = path to our configuration entries
420 * RETURNS: Success or failure
423 PDEVICE_OBJECT DeviceObject
;
428 DbgPrint("Minix FSD 0.0.1\n");
430 DriverObject
= _DriverObject
;
432 RtlInitAnsiString(&astr
,"\\Device\\Minix");
433 RtlAnsiStringToUnicodeString(&ustr
,&astr
,TRUE
);
434 ret
= IoCreateDevice(DriverObject
,0,&ustr
,
435 FILE_DEVICE_PARALLEL_PORT
,0,FALSE
,&DeviceObject
);
436 if (ret
!=STATUS_SUCCESS
)
441 DeviceObject
->Flags
=0;
442 DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = MinixClose
;
443 DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = MinixCreate
;
444 DriverObject
->MajorFunction
[IRP_MJ_READ
] = MinixRead
;
445 DriverObject
->MajorFunction
[IRP_MJ_WRITE
] = MinixWrite
;
446 DriverObject
->MajorFunction
[IRP_MJ_FILE_SYSTEM_CONTROL
] =
447 MinixFileSystemControl
;
448 DriverObject
->MajorFunction
[IRP_MJ_DIRECTORY_CONTROL
] =
449 MinixDirectoryControl
;
450 DriverObject
->DriverUnload
= NULL
;
452 IoRegisterFileSystem(DeviceObject
);
454 return(STATUS_SUCCESS
);