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 <aros/asmcall.h>
13 #include <aros/macros.h>
14 #include <exec/types.h>
15 #include <exec/execbase.h>
16 #include <exec/memory.h>
18 #include <dos/dosextens.h>
19 #include <dos/dostags.h>
20 #include <dos/filehandler.h>
21 #include <devices/trackdisk.h>
23 #include <proto/exec.h>
24 #include <proto/dos.h>
29 #include "ntfs_protos.h"
34 struct DosLibrary
*DOSBase
;
35 struct Library
*UtilityBase
;
36 struct Library
*IntuitionBase
;
37 struct Library
*UUIDBase
;
38 struct Library
*CodesetsBase
= NULL
;
40 struct Globals global_data
;
41 struct Globals
*glob
= &global_data
;
43 const TEXT version_string
[] = "$VER: ntfs.handler 41.53 (11.02.2012)";
48 struct DosPacket
*startuppacket
;
49 LONG error
= ERROR_NO_FREE_STORE
;
51 D(bug("[NTFS]: %s()\n", __PRETTY_FUNCTION__
));
53 memset(glob
, 0, sizeof(struct Globals
));
54 NEWLIST(&glob
->sblist
);
55 glob
->ourtask
= FindTask(NULL
);
56 glob
->ourport
= &((struct Process
*)glob
->ourtask
)->pr_MsgPort
;
57 WaitPort(glob
->ourport
);
59 msg
= GetMsg(glob
->ourport
);
60 startuppacket
= (struct DosPacket
*) msg
->mn_Node
.ln_Name
;
61 glob
->devnode
= BADDR(startuppacket
->dp_Arg3
);
63 D(bug("[NTFS] %s: opening libraries.\n", __PRETTY_FUNCTION__
));
64 D(bug("\tFS task: 0x%p, port 0x%p\n", glob
->ourtask
, glob
->ourport
));
66 glob
->notifyport
= CreateMsgPort();
68 if ((DOSBase
= (struct DosLibrary
*)OpenLibrary("dos.library", 37))) {
69 if ((IntuitionBase
= OpenLibrary("intuition.library", 37))) {
70 if ((UtilityBase
= OpenLibrary("utility.library", 37))) {
71 if ((CodesetsBase
= OpenLibrary("codesets.library", 0))) {
72 if ((UUIDBase
= OpenLibrary("uuid.library", 0))) {
73 glob
->fssm
= BADDR(startuppacket
->dp_Arg2
);
75 if ((glob
->mempool
= CreatePool(MEMF_PUBLIC
, DEF_POOL_SIZE
, DEF_POOL_THRESHOLD
))) {
80 if ((error
= InitDiskHandler(glob
->fssm
)) == 0) {
81 ULONG pktsig
= 1 << glob
->ourport
->mp_SigBit
;
82 ULONG diskchgsig
= 1 << glob
->diskchgsig_bit
;
83 ULONG notifysig
= 1 << glob
->notifyport
->mp_SigBit
;
84 ULONG timersig
= 1 << glob
->timerport
->mp_SigBit
;
85 ULONG mask
= pktsig
| diskchgsig
| notifysig
| timersig
;
89 D(bug("\tInitiated device: %s\n", AROS_BSTR_ADDR(glob
->devnode
->dol_Name
)));
91 glob
->devnode
->dol_Task
= glob
->ourport
;
93 D(bug("[NTFS] %s: returning startup packet\n", __PRETTY_FUNCTION__
));
95 rp
= startuppacket
->dp_Port
;
96 startuppacket
->dp_Port
= glob
->ourport
;
97 startuppacket
->dp_Res1
= DOSTRUE
;
98 startuppacket
->dp_Res2
= 0;
99 PutMsg(rp
, startuppacket
->dp_Link
);
101 D(bug("[NTFS] %s: Handler init finished.\n", __PRETTY_FUNCTION__
));
103 ProcessDiskChange(); /* insert disk */
107 if (sigs
& diskchgsig
)
111 if (sigs
& notifysig
)
117 D(bug("\n[NTFS] %s: Handler shutdown initiated\n", __PRETTY_FUNCTION__
));
120 startuppacket
= NULL
;
122 CleanupDiskHandler();
126 DeletePool(glob
->mempool
);
129 error
= ERROR_NO_FREE_STORE
;
131 CloseLibrary(CodesetsBase
);
133 CloseLibrary(UtilityBase
);
135 CloseLibrary(IntuitionBase
);
137 CloseLibrary((struct Library
*)DOSBase
);
140 DeleteMsgPort(glob
->notifyport
);
142 if (glob
->death_packet
!= NULL
)
143 ReplyPacket(glob
->death_packet
);
145 D(bug("[NTFS] %s: The end.\n", __PRETTY_FUNCTION__
));
146 if (startuppacket
!= NULL
) {
147 D(bug("[NTFS] %s: returning startup packet\n", __PRETTY_FUNCTION__
));
149 startuppacket
->dp_Res1
= DOSTRUE
;
150 startuppacket
->dp_Res2
= 0;
151 ReplyPacket(startuppacket
);
157 static struct IntData
159 struct Interrupt Interrupt
;
160 struct ExecBase
*SysBase
;
165 static AROS_INTH1(DiskChangeIntHandler
, struct IntData
*, MyIntData
)
169 struct ExecBase
*SysBase
= MyIntData
->SysBase
;
171 D(bug("[NTFS]: %s()\n", __PRETTY_FUNCTION__
));
173 Signal(MyIntData
->task
, MyIntData
->signal
);
179 LONG
InitDiskHandler (struct FileSysStartupMsg
*fssm
)
182 ULONG diskchgintbit
, flags
;
186 unit
= fssm
->fssm_Unit
;
187 flags
= fssm
->fssm_Flags
;
189 D(bug("[NTFS]: %s()\n", __PRETTY_FUNCTION__
));
191 device
= AROS_BSTR_ADDR(fssm
->fssm_Device
);
193 if ((diskchgintbit
= AllocSignal(-1)) >= 0) {
194 glob
->diskchgsig_bit
= diskchgintbit
;
196 if ((glob
->diskport
= CreateMsgPort())) {
198 if ((glob
->diskioreq
= CreateIORequest(glob
->diskport
, sizeof(struct IOExtTD
)))) {
200 if (OpenDevice(device
, unit
, (struct IORequest
*)glob
->diskioreq
, flags
) == 0) {
201 D(bug("[NTFS] %s: %s:%d successfully opened\n", __PRETTY_FUNCTION__
, device
, unit
));
202 Probe_64bit_support();
204 if ((glob
->diskchgreq
= AllocVec(sizeof(struct IOExtTD
), MEMF_PUBLIC
))) {
205 CopyMem(glob
->diskioreq
, glob
->diskchgreq
, sizeof(struct IOExtTD
));
207 /* fill interrupt data */
208 DiskChangeIntData
.SysBase
= SysBase
;
209 DiskChangeIntData
.task
= glob
->ourtask
;
210 DiskChangeIntData
.signal
= 1 << diskchgintbit
;
212 DiskChangeIntData
.Interrupt
.is_Node
.ln_Type
= NT_INTERRUPT
;
213 DiskChangeIntData
.Interrupt
.is_Node
.ln_Pri
= 0;
214 DiskChangeIntData
.Interrupt
.is_Node
.ln_Name
= "NTFS\0";
215 DiskChangeIntData
.Interrupt
.is_Data
= &DiskChangeIntData
;
216 DiskChangeIntData
.Interrupt
.is_Code
= (void (*)(void))AROS_ASMSYMNAME(DiskChangeIntHandler
);
218 /* fill io request data */
219 glob
->diskchgreq
->iotd_Req
.io_Command
= TD_ADDCHANGEINT
;
220 glob
->diskchgreq
->iotd_Req
.io_Data
= &DiskChangeIntData
.Interrupt
;
221 glob
->diskchgreq
->iotd_Req
.io_Length
= sizeof(struct Interrupt
);
222 glob
->diskchgreq
->iotd_Req
.io_Flags
= 0;
224 SendIO((struct IORequest
*)glob
->diskchgreq
);
226 D(bug("[NTFS] %s: Disk change interrupt handler installed\n", __PRETTY_FUNCTION__
));
231 err
= ERROR_NO_FREE_STORE
;
233 CloseDevice((struct IORequest
*)glob
->diskioreq
);
236 err
= ERROR_DEVICE_NOT_MOUNTED
;
238 DeleteIORequest(glob
->diskioreq
);
239 glob
->diskioreq
= NULL
;
242 err
= ERROR_NO_FREE_STORE
;
244 DeleteMsgPort(glob
->diskport
);
245 glob
->diskport
= NULL
;
248 err
= ERROR_NO_FREE_STORE
;
250 FreeSignal(diskchgintbit
);
252 glob
->diskchgsig_bit
= 0;
255 err
= ERROR_NO_FREE_STORE
;
260 void CleanupDiskHandler(void)
262 D(bug("[NTFS]: %s()\n", __PRETTY_FUNCTION__
));
264 D(bug("[NTFS] %s: Freeing handler resources:\n", __PRETTY_FUNCTION__
));
266 /* remove disk change interrupt */
267 glob
->diskchgreq
->iotd_Req
.io_Command
= TD_REMCHANGEINT
;
268 glob
->diskchgreq
->iotd_Req
.io_Data
= &DiskChangeIntData
.Interrupt
;
269 glob
->diskchgreq
->iotd_Req
.io_Length
= sizeof(struct Interrupt
);
270 glob
->diskchgreq
->iotd_Req
.io_Flags
= 0;
272 DoIO((struct IORequest
*)glob
->diskchgreq
);
273 D(bug("[NTFS] %s: Disk change interrupt handler removed\n", __PRETTY_FUNCTION__
));
275 CloseDevice((struct IORequest
*)glob
->diskioreq
);
276 DeleteIORequest(glob
->diskioreq
);
277 FreeVec(glob
->diskchgreq
);
278 DeleteMsgPort(glob
->diskport
);
279 D(bug("[NTFS] %s: Device closed\n", __PRETTY_FUNCTION__
));
281 glob
->diskioreq
= NULL
;
282 glob
->diskchgreq
= NULL
;
283 glob
->diskport
= NULL
;
285 FreeSignal(glob
->diskchgsig_bit
);
287 D(bug("[NTFS] %s: Done.\n", __PRETTY_FUNCTION__
));