2 * ntfs.handler - New Technology FileSystem handler
4 * Copyright © 2012 The AROS Development Team
6 * This program is free software; you can redistribute it and/or modify it
7 * under the same terms as AROS itself.
12 #include <exec/types.h>
13 #include <exec/execbase.h>
14 #include <dos/dosextens.h>
15 #include <dos/filehandler.h>
16 #include <dos/notify.h>
17 #include <devices/inputevent.h>
19 #include <proto/exec.h>
20 #include <proto/dos.h>
25 #include "ntfs_protos.h"
30 void ProcessPackets(void) {
32 struct DosPacket
*pkt
;
34 D(bug("[NTFS]: %s()\n", __PRETTY_FUNCTION__
));
36 while ((msg
= GetMsg(glob
->ourport
)) != NULL
) {
40 pkt
= (struct DosPacket
*) msg
->mn_Node
.ln_Name
;
42 switch(pkt
->dp_Type
) {
43 case ACTION_LOCATE_OBJECT
: {
44 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
= NULL
;
45 UBYTE
*path
= BADDR(pkt
->dp_Arg2
);
46 LONG access
= pkt
->dp_Arg3
;
48 D(bug("[NTFS] %s: ** LOCATE_OBJECT: lock 0x%08x (dir %ld/%d) name '", __PRETTY_FUNCTION__
, pkt
->dp_Arg1
,
49 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
50 RawPutChars(AROS_BSTR_ADDR(path
), AROS_BSTR_strlen(path
)); bug("' type %s\n",
51 pkt
->dp_Arg3
== EXCLUSIVE_LOCK
? "EXCLUSIVE" : "SHARED"));
53 if ((err
= TestLock(fl
)))
56 if ((err
= OpLockFile(fl
, AROS_BSTR_ADDR(path
), AROS_BSTR_strlen(path
), access
, &lock
)) == 0)
57 res
= (IPTR
)MKBADDR(lock
);
62 case ACTION_FREE_LOCK
: {
63 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
65 D(bug("[NTFS] %s: ** FREE_LOCK: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
67 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1));
76 case ACTION_COPY_DIR_FH
: {
77 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
= NULL
;
79 D(bug("[NTFS] %s: ** COPY_DIR: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
81 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1));
83 if ((err
= TestLock(fl
)))
86 if ((err
= OpCopyLock(fl
, &lock
)) == 0)
87 res
= (IPTR
)MKBADDR(lock
);
93 case ACTION_PARENT_FH
: {
94 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
= NULL
;
96 D(bug("[NTFS] %s: ** PARENT: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
98 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1));
100 if ((err
= TestLock(fl
)))
103 if ((err
= OpLockParent(fl
, &lock
)) == 0)
104 res
= (IPTR
)MKBADDR(lock
);
109 case ACTION_SAME_LOCK
: {
110 struct ExtFileLock
*fl1
= BADDR(pkt
->dp_Arg1
);
111 struct ExtFileLock
*fl2
= BADDR(pkt
->dp_Arg2
);
113 D(bug("[NTFS] %s: ** SAME_LOCK: lock #1 0x%08x (dir %ld/%d) lock #2 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
115 fl1
!= NULL
? fl1
->dir
->ioh
.mft
.mftrec_no
: 0, fl1
!= NULL
? fl1
->dir
->cur_no
: -1,
117 fl2
!= NULL
? fl2
->dir
->ioh
.mft
.mftrec_no
: 0, fl2
!= NULL
? fl2
->dir
->cur_no
: -1));
121 if (fl1
== fl2
|| fl1
->gl
== fl2
->gl
)
127 case ACTION_EXAMINE_OBJECT
:
128 case ACTION_EXAMINE_FH
: {
129 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
130 struct FileInfoBlock
*fib
= BADDR(pkt
->dp_Arg2
);
132 D(bug("[NTFS] %s: ** EXAMINE_OBJECT: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
134 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1));
136 if ((err
= TestLock(fl
)))
139 if ((err
= FillFIB(fl
, fib
)) == 0)
141 if (fl
->gl
->attr
& ATTR_DIRECTORY
)
147 if ((fl
->entry
->key
->indx
) && (fl
->entry
->key
->indx
!=fl
->dir
->ioh
.mft
.buf
))
149 D(bug("[NTFS] %s: ** EXAMINE_OBJECT: freeing old key indx buffer @ 0x%p\n", __PRETTY_FUNCTION__
, fl
->entry
->key
->indx
));
150 FreeMem(fl
->entry
->key
->indx
, glob
->data
->idx_size
<< SECTORSIZE_SHIFT
);
151 fl
->entry
->key
->indx
= NULL
;
153 D(bug("[NTFS] %s: ** EXAMINE_OBJECT: freeing old key @ 0x%p\n", __PRETTY_FUNCTION__
, fl
->entry
->key
));
154 FreeMem(fl
->entry
->key
, sizeof(struct Index_Key
));
155 fl
->entry
->key
= NULL
;
159 fl
->dir
->parent_mft
= fl
->dir
->ioh
.mft
.mftrec_no
;
160 fl
->dir
->ioh
.mft
.mftrec_no
= fl
->gl
->first_cluster
/ glob
->data
->mft_size
;
161 ReleaseDirHandle(fl
->dir
);
162 InitDirHandle(glob
->data
, fl
->dir
, FALSE
);
170 case ACTION_EXAMINE_NEXT
: {
171 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
), *lock
= NULL
;
172 struct FileInfoBlock
*fib
= BADDR(pkt
->dp_Arg2
);
175 D(bug("[NTFS] %s: ** EXAMINE_NEXT: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
177 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1));
179 if ((err
= TestLock(fl
)))
182 memset(&de
, 0, sizeof(struct DirEntry
));
183 if ((fl
->entry
!= NULL
) && (fl
->entry
->key
))
185 struct Index_Key searchkey
;
187 CopyMem(fl
->entry
->key
, &searchkey
, sizeof(struct Index_Key
));
191 if ((err
= GetNextDirEntry(fl
->dir
, &de
, TRUE
)) != 0) {
192 if (err
== ERROR_OBJECT_NOT_FOUND
)
193 err
= ERROR_NO_MORE_ENTRIES
;
194 D(bug("[NTFS] %s: ** EXAMINE_NEXT: no more entries..\n", __PRETTY_FUNCTION__
));
198 if ((err
= LockFile(&de
, SHARED_LOCK
, &lock
)) != 0) {
202 if (!(err
= FillFIB(lock
, fib
))) {
211 case ACTION_FINDINPUT
:
212 case ACTION_FINDOUTPUT
:
213 case ACTION_FINDUPDATE
: {
214 struct FileHandle
*fh
= BADDR(pkt
->dp_Arg1
);
215 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
216 UBYTE
*path
= BADDR(pkt
->dp_Arg3
);
217 struct ExtFileLock
*lock
;
219 D(bug("[NTFS] %s: ** %s: lock 0x%08x (dir %ld/%d) path '", __PRETTY_FUNCTION__
,
220 pkt
->dp_Type
== ACTION_FINDINPUT
? "FINDINPUT" :
221 pkt
->dp_Type
== ACTION_FINDOUTPUT
? "FINDOUTPUT" :
224 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
225 RawPutChars(AROS_BSTR_ADDR(path
), AROS_BSTR_strlen(path
)); bug("'\n"));
227 if ((err
= TestLock(fl
)))
230 if ((err
= OpOpenFile(fl
, AROS_BSTR_ADDR(path
), AROS_BSTR_strlen(path
), pkt
->dp_Type
, &lock
)) != 0)
233 fh
->fh_Arg1
= (IPTR
)MKBADDR(lock
);
234 fh
->fh_Port
= DOSFALSE
;
242 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
243 APTR buffer
= (APTR
)pkt
->dp_Arg2
;
244 ULONG want
= pkt
->dp_Arg3
;
248 bug("[NTFS] %s: ** READ: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
250 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
251 bug("[NTFS] %s: ** READ: want %u @ pos %u\n", __PRETTY_FUNCTION__
, want
, fl
->pos
);
254 if ((err
= TestLock(fl
))) {
259 if ((err
= OpRead(fl
, buffer
, (UQUAD
)want
, &read
)) != 0)
263 if (read
> 0x7FFFFFFF)
273 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
274 ULONG want
= pkt
->dp_Arg3
;
275 #if !defined(NTFS_READONLY)
276 APTR buffer
= (APTR
)pkt
->dp_Arg2
;
279 D(bug("[NTFS] %s: ** WRITE: lock 0x%08x (dir %ld/%ld pos %ld) want %ld\n", __PRETTY_FUNCTION__
,
281 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1,
284 #if defined(NTFS_READONLY)
285 res
= ERROR_DISK_WRITE_PROTECTED
;
287 (void)want
; // unused
289 if ((err
= TestLock(fl
))) {
294 if ((err
= OpWrite(fl
, buffer
, want
, &written
)) != 0)
298 if (written
> 0x7FFFFFFF)
308 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
309 LONG offset
= pkt
->dp_Arg2
;
310 ULONG offsetfrom
= pkt
->dp_Arg3
;
313 bug("[NTFS] %s: ** SEEK: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
, pkt
->dp_Arg1
,
314 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
315 bug("[NTFS] %s: ** SEEK: offset %d, current pos %u \n", __PRETTY_FUNCTION__
, offset
, fl
->pos
);
318 if ((err
= TestLock(fl
))) {
326 if (offsetfrom
== OFFSET_BEGINNING
&&
328 offset
<= fl
->gl
->size
)
330 D(bug("[NTFS] %s: ** SEEK: from BEGINNING\n", __PRETTY_FUNCTION__
));
333 else if (offsetfrom
== OFFSET_CURRENT
&&
334 offset
+ fl
->pos
>= 0 &&
335 offset
+ fl
->pos
<= fl
->gl
->size
)
337 D(bug("[NTFS] %s: ** SEEK: from CURRENT\n", __PRETTY_FUNCTION__
));
340 else if (offsetfrom
== OFFSET_END
342 && fl
->gl
->size
+ offset
>= 0)
344 D(bug("[NTFS] %s: ** SEEK: from END\n", __PRETTY_FUNCTION__
));
345 fl
->pos
= fl
->gl
->size
+ offset
;
349 err
= ERROR_SEEK_ERROR
;
355 #if defined(ACTION_CHANGE_FILE_POSITION64)
356 case ACTION_CHANGE_FILE_POSITION64
: {
357 D(bug("[NTFS] %s: ** CHANGE_FILE_POSITION64\n", __PRETTY_FUNCTION__
));
363 #if defined(ACTION_GET_FILE_POSITION64)
364 case ACTION_GET_FILE_POSITION64
: {
365 D(bug("[NTFS] %s: ** GET_FILE_POSITION64\n", __PRETTY_FUNCTION__
));
371 case ACTION_SET_FILE_SIZE
: {
372 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
373 LONG offset
= pkt
->dp_Arg2
;
374 #if !defined(NTFS_READONLY)
375 LONG offsetfrom
= pkt
->dp_Arg3
;
378 D(bug("[NTFS] %s: ** SET_FILE_SIZE: lock 0x%08x (dir %ld/%ld pos %ld) offset %ld\n", __PRETTY_FUNCTION__
,
380 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1,
384 #if defined(NTFS_READONLY)
385 res
= ERROR_DISK_WRITE_PROTECTED
;
387 (void)offset
; // unused
389 if ((err
= TestLock(fl
))) {
394 if ((err
= OpSetFileSize(fl
, offset
, offsetfrom
, &newsize
)) != 0)
403 #if defined(ACTION_CHANGE_FILE_SIZE64)
404 case ACTION_CHANGE_FILE_SIZE64
: {
405 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
406 UQUAD offset
= pkt
->dp_Arg2
;
407 LONG offsetfrom
= pkt
->dp_Arg3
;
408 #if !defined(NTFS_READONLY)
411 D(bug("[NTFS] %s: ** CHANGE_FILE_SIZE64: lock 0x%08x (dir %ld/%ld pos %ld) offset %lld offsetfrom %s\n", __PRETTY_FUNCTION__
,
413 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1,
416 offsetfrom
== OFFSET_BEGINNING
? "BEGINNING" :
417 offsetfrom
== OFFSET_END
? "END" :
418 offsetfrom
== OFFSET_CURRENT
? "CURRENT" :
421 #if defined(NTFS_READONLY)
422 res
= ERROR_DISK_WRITE_PROTECTED
;
424 (void)offsetfrom
; // unused
425 (void)offset
; // unused
427 if ((err
= TestLock(fl
))) {
432 if ((err
= OpSetFileSize(fl
, offset
, offsetfrom
, &newsize
)) != 0)
441 #if defined(ACTION_GET_FILE_SIZE64)
442 case ACTION_GET_FILE_SIZE64
: {
443 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
445 D(bug("[NTFS] %s: ** GET_FILE_SIZE64: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
447 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1));
449 if ((fl
->entry
) && (fl
->gl
))
450 res
= (IPTR
)&fl
->gl
->size
;
457 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
459 D(bug("[NTFS] %s: ** END: lock 0x%08x (dir %ld/%ld)\n", __PRETTY_FUNCTION__
,
461 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1));
463 if ((err
= TestLock(fl
)))
472 case ACTION_IS_FILESYSTEM
:
473 D(bug("[NTFS] %s: ** IS_FILESYSTEM\n", __PRETTY_FUNCTION__
));
478 case ACTION_CURRENT_VOLUME
: {
479 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
481 D(bug("[NTFS] %s: ** CURRENT_VOLUME: lock 0x%08x\n", __PRETTY_FUNCTION__
,
484 res
= (IPTR
)((fl
) ? fl
->fl_Volume
: ((glob
->data
!= NULL
) ? MKBADDR(glob
->data
->doslist
) : BNULL
));
489 case ACTION_DISK_INFO
: {
492 if (pkt
->dp_Type
== ACTION_INFO
) {
493 struct FileLock
*fl
= BADDR(pkt
->dp_Arg1
);
495 D(bug("[NTFS] %s: ** INFO: lock 0x%08x\n", __PRETTY_FUNCTION__
,
498 if (fl
&& (glob
->data
== NULL
|| fl
->fl_Volume
!= MKBADDR(glob
->data
->doslist
))) {
499 err
= ERROR_DEVICE_NOT_MOUNTED
;
503 id
= BADDR(pkt
->dp_Arg2
);
506 D(bug("[NTFS] %s: ** DISK_INFO\n", __PRETTY_FUNCTION__
));
508 id
= BADDR(pkt
->dp_Arg1
);
517 case ACTION_INHIBIT
: {
518 LONG inhibit
= pkt
->dp_Arg1
;
520 D(bug("[NTFS] %s: ** INHIBIT: %sinhibit\n", __PRETTY_FUNCTION__
,
521 inhibit
== DOSTRUE
? "" : "un"));
523 if (inhibit
== DOSTRUE
) {
524 glob
->disk_inhibited
++;
525 if (glob
->disk_inhibited
== 1)
528 else if (glob
->disk_inhibited
) {
529 glob
->disk_inhibited
--;
530 if (glob
->disk_inhibited
== 0)
539 struct FSData
*fs_data
;
540 struct NotifyNode
*nn
;
542 D(bug("[NTFS] %s: ** DIE\n", __PRETTY_FUNCTION__
));
544 /* clear our message port from notification requests so DOS won't send
545 * notification-end packets to us after we're gone */
546 ForeachNode(&glob
->sblist
, fs_data
) {
547 ForeachNode(&fs_data
->info
->notifies
, nn
) {
548 nn
->nr
->nr_Handler
= NULL
;
552 if ((glob
->data
!= NULL
553 && !(IsListEmpty(&glob
->data
->info
->locks
)
554 && IsListEmpty(&glob
->data
->info
->notifies
)))) {
556 D(bug("[NTFS] %s:\tThere are remaining locks or notification "
557 "requests. Shutting down is not possible\n", __PRETTY_FUNCTION__
));
559 err
= ERROR_OBJECT_IN_USE
;
563 D(bug("[NTFS] %s:\tNothing pending. Shutting down the handler\n", __PRETTY_FUNCTION__
));
565 DoDiskRemove(); /* risky, because of async. volume remove, but works */
568 glob
->death_packet
= pkt
;
569 glob
->devnode
->dol_Task
= NULL
;
576 /* XXX AROS needs these ACTION_ headers defined in dos/dosextens.h */
578 case ACTION_GET_DISK_FSSM
: {
579 D(bug("[NTFS] %s: ** ACTION_GET_DISK_FSSM\n", __PRETTY_FUNCTION__
));
581 res
= (ULONG
) glob
->fssm
;
585 case ACTION_FREE_DISK_FSSM
: {
586 D(bug("[NTFS] %s: ** ACTION_FREE_DISK_FSSM\n", __PRETTY_FUNCTION__
));
594 case ACTION_DISK_CHANGE
: { /* internal */
595 struct DosList
*vol
= (struct DosList
*)pkt
->dp_Arg2
;
596 struct VolumeInfo
*vol_info
= BADDR(vol
->dol_misc
.dol_volume
.dol_LockList
);
597 ULONG type
= pkt
->dp_Arg3
;
599 D(bug("[NTFS] %s: ** DISK_CHANGE [INTERNAL]\n", __PRETTY_FUNCTION__
));
601 if (pkt
->dp_Arg1
== ID_NTFS_DISK
) { /* security check */
603 if (AttemptLockDosList(LDF_VOLUMES
|LDF_WRITE
)) {
605 if (type
== ACTION_VOLUME_ADD
) {
607 UnLockDosList(LDF_VOLUMES
|LDF_WRITE
);
609 SendEvent(IECLASS_DISKINSERTED
);
611 D(bug("[NTFS] %s: \tVolume added successfuly\n", __PRETTY_FUNCTION__
));
613 else if (type
== ACTION_VOLUME_REMOVE
) {
615 DeletePool(vol_info
->mem_pool
);
616 UnLockDosList(LDF_VOLUMES
|LDF_WRITE
);
618 SendEvent(IECLASS_DISKREMOVED
);
620 D(bug("[NTFS] %s: \tVolume removed successfuly.\n", __PRETTY_FUNCTION__
));
623 FreeDosObject(DOS_STDPKT
, pkt
); /* cleanup */
626 D(bug("[NTFS] %s: Packet destroyed\n", __PRETTY_FUNCTION__
));
630 D(bug("[NTFS] %s:\tDosList is locked\n", __PRETTY_FUNCTION__
));
632 PutMsg(glob
->ourport
, pkt
->dp_Link
);
634 D(bug("[NTFS] %s: Message moved to the end of the queue\n", __PRETTY_FUNCTION__
));
638 err
= ERROR_OBJECT_WRONG_TYPE
;
643 case ACTION_RENAME_DISK
: {
644 UBYTE
*name
= BADDR(pkt
->dp_Arg1
);
646 D(bug("[NTFS] %s: ** RENAME_DISK: name '", __PRETTY_FUNCTION__
); RawPutChars(AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
)); bug("'\n"));
648 #if defined(NTFS_READONLY)
649 res
= ERROR_DISK_WRITE_PROTECTED
;
650 (void)name
; // unused
652 if (glob
->data
->doslist
== NULL
) {
653 err
= glob
->disk_inserted
? ERROR_NOT_A_DOS_DISK
: ERROR_NO_DISK
;
657 while (! AttemptLockDosList(LDF_VOLUMES
| LDF_WRITE
))
660 // err = SetVolumeName(glob->data, name);
661 UnLockDosList(LDF_VOLUMES
| LDF_WRITE
);
665 #ifdef AROS_FAST_BPTR
666 /* ReadFATSuper() sets a null byte after the
667 * string, so this should be fine */
668 CopyMem(glob
->data
->volume
.name
+ 1, glob
->data
->doslist
->dol_Name
,
669 glob
->data
->volume
.name
[0] + 1);
671 CopyMem(glob
->data
->volume
.name
, BADDR(glob
->data
->doslist
->dol_Name
),
672 glob
->data
->volume
.name
[0] + 2);
675 SendEvent(IECLASS_DISKINSERTED
);
682 case ACTION_DELETE_OBJECT
: {
683 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
684 UBYTE
*name
= BADDR(pkt
->dp_Arg2
);
686 D(bug("[NTFS] %s: ** DELETE_OBJECT: lock 0x%08x (dir %ld/%d) path '", __PRETTY_FUNCTION__
,
688 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
689 RawPutChars(AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
)); bug("'\n"));
691 #if defined(NTFS_READONLY)
692 res
= ERROR_DISK_WRITE_PROTECTED
;
694 (void)name
; // unused
696 if ((err
= TestLock(fl
)))
699 err
= OpDeleteFile(fl
, AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
));
704 case ACTION_RENAME_OBJECT
: {
705 struct ExtFileLock
*sfl
= BADDR(pkt
->dp_Arg1
), *dfl
= BADDR(pkt
->dp_Arg3
);
706 UBYTE
*sname
= BADDR(pkt
->dp_Arg2
), *dname
= BADDR(pkt
->dp_Arg4
);
708 D(bug("[NTFS] %s: ** RENAME_OBJECT: srclock 0x%08x (dir %ld/%d) name '", __PRETTY_FUNCTION__
,
710 sfl
!= NULL
? sfl
->dir
->ioh
.mft
.mftrec_no
: 0, sfl
!= NULL
? sfl
->dir
->cur_no
: -1);
711 RawPutChars(AROS_BSTR_ADDR(sname
), AROS_BSTR_strlen(sname
)); bug("' destlock 0x%08x (dir %ld/%d) name '",
713 dfl
!= NULL
? dfl
->dir
->ioh
.mft
.mftrec_no
: 0, dfl
!= NULL
? dfl
->dir
->cur_no
: -1);
714 RawPutChars(AROS_BSTR_ADDR(dname
), AROS_BSTR_strlen(dname
)); bug("'\n"));
716 #if defined(NTFS_READONLY)
717 res
= ERROR_DISK_WRITE_PROTECTED
;
720 (void)sname
; // unused
721 (void)dname
; // unused
723 if ((err
= TestLock(sfl
)) != 0 || (err
= TestLock(dfl
)) != 0)
726 err
= OpRenameFile(sfl
, AROS_BSTR_ADDR(sname
), AROS_BSTR_strlen(sname
), dfl
, AROS_BSTR_ADDR(dname
), AROS_BSTR_strlen(dname
));
731 case ACTION_CREATE_DIR
: {
732 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg1
);
733 UBYTE
*name
= BADDR(pkt
->dp_Arg2
);
734 #if !defined(NTFS_READONLY)
735 struct ExtFileLock
*nl
;
737 D(bug("[NTFS] %s: ** CREATE_DIR: lock 0x%08x (dir %ld/%d) name '", __PRETTY_FUNCTION__
,
739 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
740 RawPutChars(AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
)); bug("'\n"));
742 #if defined(NTFS_READONLY)
743 res
= ERROR_DISK_WRITE_PROTECTED
;
745 (void)name
; // unused
747 if ((err
= TestLock(fl
)))
750 if ((err
= OpCreateDir(fl
, AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
), &nl
)) == 0)
751 res
= (IPTR
)MKBADDR(nl
);
756 case ACTION_SET_PROTECT
: {
757 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
758 UBYTE
*name
= BADDR(pkt
->dp_Arg3
);
759 ULONG prot
= pkt
->dp_Arg4
;
761 D(bug("[NTFS] %s: ** SET_PROTECT: lock 0x%08x (dir %ld/%d) name '", __PRETTY_FUNCTION__
, pkt
->dp_Arg2
,
762 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
763 RawPutChars(AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
)); bug("' prot 0x%08x\n", prot
));
765 #if defined(NTFS_READONLY)
766 res
= ERROR_DISK_WRITE_PROTECTED
;
768 (void)name
; // unused
769 (void)prot
; // unused
771 if ((err
= TestLock(fl
)))
774 err
= OpSetProtect(fl
, AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
), prot
);
779 case ACTION_SET_DATE
: {
780 struct ExtFileLock
*fl
= BADDR(pkt
->dp_Arg2
);
781 UBYTE
*name
= BADDR(pkt
->dp_Arg3
);
782 struct DateStamp
*ds
= (struct DateStamp
*)pkt
->dp_Arg4
;
784 #if defined(DEBUG) && DEBUG != 0
787 char datestr
[LEN_DATSTRING
];
790 dt
.dat_Format
= FORMAT_DOS
;
792 dt
.dat_StrDay
= NULL
;
793 dt
.dat_StrDate
= datestr
;
794 dt
.dat_StrTime
= NULL
;
797 D(bug("[NTFS] %s: ** SET_DATE: lock 0x%08x (dir %ld/%d) name '", __PRETTY_FUNCTION__
,
799 (fl
!= NULL
&& fl
->dir
!= NULL
) ? fl
->dir
->ioh
.mft
.mftrec_no
: FILE_ROOT
, (fl
!= NULL
&& fl
->entry
!= NULL
) ? fl
->entry
->no
: -1);
800 RawPutChars(AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
)); bug("' ds '%s'\n", datestr
));
804 #if defined(NTFS_READONLY)
805 res
= ERROR_DISK_WRITE_PROTECTED
;
807 (void)name
; // unused
810 if ((err
= TestLock(fl
)))
813 err
= OpSetDate(fl
, AROS_BSTR_ADDR(name
), AROS_BSTR_strlen(name
), ds
);
818 case ACTION_ADD_NOTIFY
: {
819 struct NotifyRequest
*nr
= (struct NotifyRequest
*)pkt
->dp_Arg1
;
821 D(bug("[NTFS] %s: ** ADD_NOTIFY: nr 0x%08x name '%s'\n", __PRETTY_FUNCTION__
, nr
, nr
->nr_FullName
));
823 err
= OpAddNotify(nr
);
828 case ACTION_REMOVE_NOTIFY
: {
829 struct NotifyRequest
*nr
= (struct NotifyRequest
*)pkt
->dp_Arg1
;
831 D(bug("[NTFS] %s: ** REMOVE_NOTIFY: nr 0x%08x name '%s'\n", __PRETTY_FUNCTION__
, nr
, nr
->nr_FullName
));
833 err
= OpRemoveNotify(nr
);
839 D(bug("[NTFS] %s: got unknown packet type %ld\n", __PRETTY_FUNCTION__
, pkt
->dp_Type
));
841 err
= ERROR_ACTION_NOT_KNOWN
;
848 D(bug("[NTFS] %s: replying to packet [result 0x%x, error 0x%x]\n", __PRETTY_FUNCTION__
,
858 void ReplyPacket(struct DosPacket
*pkt
)
862 D(bug("[NTFS]: %s()\n", __PRETTY_FUNCTION__
));
866 pkt
->dp_Port
= glob
->ourport
;
868 PutMsg(rp
, pkt
->dp_Link
);