move registering of the ROM region after prepare execbase. rename i386-pc's kernel...
[AROS.git] / workbench / fs / ntfs / main.c
blob32a0be14bffa9d49ef1fcd22cf66ecee93dbe952
1 /*
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.
9 * $Id $
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>
17 #include <dos/dos.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>
26 #include <string.h>
28 #include "ntfs_fs.h"
29 #include "ntfs_protos.h"
30 #include "charset.h"
32 #include "debug.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)";
45 void handler(void)
47 struct Message *msg;
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))) {
77 error = InitTimer();
78 if (!error) {
79 InitCharsetTables();
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;
86 ULONG sigs;
87 struct MsgPort *rp;
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 */
105 while(!glob->quit) {
106 sigs = Wait(mask);
107 if (sigs & diskchgsig)
108 ProcessDiskChange();
109 if (sigs & pktsig)
110 ProcessPackets();
111 if (sigs & notifysig)
112 ProcessNotify();
113 if (sigs & timersig)
114 HandleTimer();
117 D(bug("\n[NTFS] %s: Handler shutdown initiated\n", __PRETTY_FUNCTION__));
119 error = 0;
120 startuppacket = NULL;
122 CleanupDiskHandler();
124 CleanupTimer();
126 DeletePool(glob->mempool);
128 else
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);
154 return;
157 static struct IntData
159 struct Interrupt Interrupt;
160 struct ExecBase *SysBase;
161 struct Task *task;
162 ULONG signal;
163 } DiskChangeIntData;
165 static AROS_INTH1(DiskChangeIntHandler, struct IntData *, MyIntData)
167 AROS_INTFUNC_INIT
169 struct ExecBase *SysBase = MyIntData->SysBase;
171 D(bug("[NTFS]: %s()\n", __PRETTY_FUNCTION__));
173 Signal(MyIntData->task, MyIntData->signal);
174 return 0;
176 AROS_INTFUNC_EXIT
179 LONG InitDiskHandler (struct FileSysStartupMsg *fssm)
181 LONG err;
182 ULONG diskchgintbit, flags;
183 IPTR unit;
184 UBYTE *device;
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__));
228 return 0;
230 else
231 err = ERROR_NO_FREE_STORE;
233 CloseDevice((struct IORequest *)glob->diskioreq);
235 else
236 err = ERROR_DEVICE_NOT_MOUNTED;
238 DeleteIORequest(glob->diskioreq);
239 glob->diskioreq = NULL;
241 else
242 err = ERROR_NO_FREE_STORE;
244 DeleteMsgPort(glob->diskport);
245 glob->diskport = NULL;
247 else
248 err = ERROR_NO_FREE_STORE;
250 FreeSignal(diskchgintbit);
252 glob->diskchgsig_bit = 0;
254 else
255 err = ERROR_NO_FREE_STORE;
257 return err;
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__));