grub2: bring back build of aros-side grub2 tools
[AROS.git] / rom / filesys / CDVDFS / src / KillDevice.c
blob9e7e03dae0301f0976234f2c4d7a0d1d8575f842
1 /* WARNING!!!
2 This little program is actually a VERY BAD EVIL HACK! Avoid using it if possible!
3 Please think 10 times before you implement any technique used here!!!
4 Thanks to MorphOS team for so inflexible OS. :-( I hope some day unmounting issue
5 will be fixed and this crap will go into history.
6 Pavel Fedin <sonic_amiga@rambler.ru>
7 */
9 #include <devices/input.h>
10 #include <devices/inputevent.h>
11 #include <dos/dosextens.h>
12 #include <exec/execbase.h>
13 #include <proto/dos.h>
14 #include <proto/exec.h>
15 #include <string.h>
17 struct ExecBase *SysBase;
18 struct DosLibrary *DOSBase;
19 unsigned char name[256];
21 ULONG __abox__ = 1;
23 int Start()
25 BPTR lock;
26 STRPTR dev;
27 struct RDArgs *Args;
28 struct Task *task;
29 struct DosList *dl;
30 struct IOStdReq *InputRequest;
31 struct MsgPort *InputPort;
32 struct InputEvent InputEvent;
34 /* Initialise */
35 SysBase = *(struct ExecBase **)(4L);
36 DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",36);
37 if (!DOSBase)
38 return RETURN_FAIL;
40 /* Get device name from user */
41 Args = ReadArgs("NAME/A",(LONG *)&dev,0);
42 if (!Args)
44 PutStr("KillDevice: required argument missing\n");
45 CloseLibrary((struct Library *)DOSBase);
46 return RETURN_FAIL;
49 /* Suppress "Please replace volume in any drive" requester */
50 task=FindTask(NULL);
51 ((struct Process *)task)->pr_WindowPtr = (APTR)-1;
53 /* Check if there's a disk in drive and figure out volume name in the case */
54 lock=Lock(dev,ACCESS_READ);
55 if (lock)
57 NameFromLock(lock,name,256);
58 name[strlen(name)-1]='\0'; /* Strip the trailing colon */
59 UnLock(lock);
62 /* Cut off the trailing ':' */
63 dev[strlen(dev)-1]=0;
65 /* Well, let's play. Since we're doing REALLY evil thing we have to stop multitasking.
66 Otherwise the OS will not forgive us! */
67 Forbid();
69 /* First we destroy the handler's task. We cannot do RemTask() here because OS hangs
70 afterwards. This code is taken from Scout <http://sourceforge.net/projects/scoutos>
71 from Freeze function, it seems to be the safest way to stop a task in MorphOS.
72 If we just remove task from exec list and drop it without adding to TaskWait
73 list we well also hang.
74 Hope this really works. Thanks again to MorphOS team :-( */
75 if (task = FindTask (dev))
77 Remove ((struct Node *) task);
78 task->tc_State = 0xFF;
79 Enqueue ((struct List *) &SysBase->TaskWait, (struct Node *) task);
82 /* After that we unbind the corpse from the OS. */
83 dl = LockDosList(LDF_VOLUMES | LDF_DEVICES | LDF_WRITE);
85 /* Remove physical device name from DOS list */
86 RemDosEntry(FindDosEntry(dl, dev, LDF_DEVICES));
88 /* If there is a disk in drive we need to get rid of volume name also */
89 if (lock)
91 /* Remove it from DOS list */
92 RemDosEntry(FindDosEntry(dl, name, LDF_VOLUMES));
94 /* And send IECLASS_DISKREMOVED event in order to put away icon on Ambient */
95 InputPort = (struct MsgPort *) CreateMsgPort ();
96 if (InputPort)
98 InputRequest = (struct IOStdReq *)CreateIORequest (InputPort, sizeof (struct IOStdReq));
99 if (InputRequest)
101 if (!OpenDevice ("input.device", 0, (struct IORequest *) InputRequest, 0))
103 memset (&InputEvent, 0, sizeof (struct InputEvent));
104 InputEvent.ie_Class = IECLASS_DISKREMOVED;
105 InputRequest->io_Command = IND_WRITEEVENT;
106 InputRequest->io_Data = &InputEvent;
107 InputRequest->io_Length = sizeof (struct InputEvent);
108 /* DoIO() will break Forbid() state but this doesn't matter for us any more */
109 DoIO ((struct IORequest *) InputRequest);
110 CloseDevice ((struct IORequest *) InputRequest);
112 DeleteIORequest ((struct IORequest *)InputRequest);
114 DeleteMsgPort (InputPort);
118 /* Huh... Let's hope everything is OK. Release multitasking, free resources and return. R.I.P. */
119 UnLockDosList(LDF_VOLUMES | LDF_DEVICES | LDF_WRITE);
120 Permit();
121 FreeArgs(Args);
122 CloseLibrary((struct Library *)DOSBase);
123 return RETURN_OK;