2 Copyright © 1995-2003, The AROS Development Team. All rights reserved.
6 #define MUIMASTER_YES_INLINE_STDARG
9 #include <aros/debug.h>
11 #include <exec/types.h>
12 #include <exec/memory.h>
14 #include <proto/exec.h>
15 #include <proto/dos.h>
16 #include <proto/icon.h>
17 #include <proto/intuition.h>
21 #include "desktop_intern.h"
23 #include "desktop_intern_protos.h"
29 FUTURE WORK: 1. The worker should work inbetween messages from a
30 requester. This will give faster results. 2. The WorkerMessage structure
31 is a bit bloated, perhaps have a seperate message for starts?
34 void scan(struct ScannerWorkerContext
*swc
)
36 struct ExAllData
*ead
;
37 struct SingleResult
*sr
= NULL
;
41 struct FileInfoBlock
*fib
;
46 swc
->swc_DirLock
, (struct ExAllData
*) swc
->swc_Buffer
,
47 SCAN_BUFFER
, ED_OWNER
, swc
->swc_EAC
50 if (swc
->swc_EAC
->eac_Entries
)
52 ead
= swc
->swc_Buffer
;
53 sr
= (struct SingleResult
*) AllocVec
55 swc
->swc_EAC
->eac_Entries
* sizeof(struct SingleResult
), MEMF_ANY
57 for (i
= 0; i
< swc
->swc_EAC
->eac_Entries
; i
++)
59 ULONG length
= strlen(swc
->swc_DirName
) + 1 /* strlen("/") */
60 + strlen(ead
->ed_Name
) + 1 /* '\0' */;
62 sr
[i
].sr_Name
= ead
->ed_Name
;
64 fullPath
= AllocVec(length
, MEMF_ANY
);
66 strlcpy(fullPath
, swc
->swc_DirName
, length
);
67 if (swc
->swc_DirName
[strlen(swc
->swc_DirName
) - 1] != ':')
69 strlcat(fullPath
, "/", length
);
71 strlcat(fullPath
, ead
->ed_Name
, length
);
73 sr
[i
].sr_DiskObject
= GetDiskObjectNew(fullPath
);
75 fileLock
= Lock(fullPath
, ACCESS_READ
);
78 fib
= AllocDosObject(DOS_FIB
, NULL
);
81 if (Examine(fileLock
, fib
))
83 commentSize
= strlen(fib
->fib_Comment
) + 1;
84 sr
[i
].sr_Comment
= AllocVec(commentSize
, MEMF_ANY
);
85 CopyMem(fib
->fib_Comment
, sr
[i
].sr_Comment
,
87 sr
[i
].sr_Script
= fib
->fib_Protection
& FIBF_SCRIPT
;
88 sr
[i
].sr_Pure
= fib
->fib_Protection
& FIBF_PURE
;
89 sr
[i
].sr_Archive
= fib
->fib_Protection
& FIBF_ARCHIVE
;
90 sr
[i
].sr_Read
= fib
->fib_Protection
& FIBF_READ
;
91 sr
[i
].sr_Write
= fib
->fib_Protection
& FIBF_WRITE
;
92 sr
[i
].sr_Execute
= fib
->fib_Protection
& FIBF_EXECUTE
;
93 sr
[i
].sr_Delete
= fib
->fib_Protection
& FIBF_DELETE
;
94 sr
[i
].sr_Type
= fib
->fib_DirEntryType
;
95 sr
[i
].sr_Size
= fib
->fib_Size
;
96 sr
[i
].sr_LastModified
= fib
->fib_Date
;
98 FreeDosObject(DOS_FIB
, fib
);
109 ((struct WorkerScanRequest
*) swc
->swc_CurrentRequest
)->wsr_Results
=
110 swc
->swc_EAC
->eac_Entries
;
111 ((struct WorkerScanRequest
*) swc
->swc_CurrentRequest
)->wsr_ResultsArray
=
113 ((struct WorkerScanRequest
*) swc
->swc_CurrentRequest
)->wsr_More
=
117 void startScan(struct ScannerWorkerContext
*swc
)
120 UWORD bufferSize
= 100;
123 // a pointer to this buffer is given to the iconobserver class and
124 // will be freed when the class is destroyed
125 swc
->swc_Buffer
= (STRPTR
) AllocVec(SCAN_BUFFER
, MEMF_ANY
);
127 ((struct WorkerScanRequest
*) swc
->swc_CurrentRequest
)->wsr_DirLock
;
129 (struct ExAllControl
*) AllocDosObject(DOS_EXALLCONTROL
, NULL
);
130 swc
->swc_EAC
->eac_LastKey
= 0;
132 dirName
= (UBYTE
*) AllocVec(bufferSize
, MEMF_ANY
);
133 success
= NameFromLock(swc
->swc_DirLock
, dirName
, bufferSize
);
136 while (IoErr() == ERROR_LINE_TOO_LONG
)
140 dirName
= (UBYTE
*) AllocVec(bufferSize
, MEMF_ANY
);
141 success
= NameFromLock(swc
->swc_DirLock
, dirName
, bufferSize
);
147 swc
->swc_DirName
= dirName
;
152 void resumeScan(struct ScannerWorkerContext
*swc
)
154 swc
->swc_Buffer
= (STRPTR
) AllocVec(SCAN_BUFFER
, MEMF_ANY
);
158 void stopScan(struct ScannerWorkerContext
*swc
)
160 ExAllEnd(swc
->swc_DirLock
, (struct ExAllData
*) swc
->swc_Buffer
,
161 SCAN_BUFFER
, ED_OWNER
, swc
->swc_EAC
);
164 void destroyScanWorker(struct ScannerWorkerContext
*swc
)
166 UnLock(swc
->swc_DirLock
);
167 FreeDosObject(DOS_EXALLCONTROL
, swc
->swc_EAC
);
168 FreeVec(swc
->swc_DirName
);
172 ULONG
workerEntry(void)
175 struct MsgPort
*port
;
176 struct WorkerMessage
*msg
;
177 struct ScannerWorkerContext
*swc
= NULL
;
179 port
= &((struct Process
*) FindTask(NULL
))->pr_MsgPort
;
185 while ((msg
= (struct WorkerMessage
*) (GetMsg(port
))))
187 switch (msg
->w_Command
)
192 (struct ScannerWorkerContext
*)
193 AllocVec(sizeof(struct ScannerWorkerContext
),
195 swc
->swc_Context
.workerAction
= msg
->w_Command
;
196 swc
->swc_Context
.start
= (APTR
) startScan
;
197 swc
->swc_Context
.resume
= (APTR
) resumeScan
;
198 swc
->swc_Context
.stop
= (APTR
) stopScan
;
200 swc
->swc_DirLock
= NULL
;
201 swc
->swc_More
= FALSE
;
202 swc
->swc_Buffer
= NULL
;
203 swc
->swc_CurrentRequest
=
204 (struct WorkerMessage
*) msg
;
205 swc
->swc_Context
.start(swc
);
208 ((struct WorkerScanRequest
*) swc
->
209 swc_CurrentRequest
)->wsr_More
= FALSE
;
211 destroyScanWorker(swc
);
216 swc
->swc_CurrentRequest
= msg
;
217 swc
->swc_Context
.resume(swc
);
220 ((struct WorkerScanRequest
*) swc
->
221 swc_CurrentRequest
)->wsr_More
= FALSE
;
223 destroyScanWorker(swc
);
229 swc
->swc_Context
.stop(swc
);
230 destroyScanWorker(swc
);
238 ReplyMsg((struct Message
*) msg
);
245 struct WorkerMessage
*createWorkerScanMessage(ULONG workerCommand
,
248 struct MsgPort
*replyPort
,
251 struct WorkerMessage
*wm
= NULL
;
252 struct WorkerScanRequest
*sr
;
254 sr
= AllocVec(sizeof(struct WorkerScanRequest
), MEMF_ANY
);
255 sr
->wsr_WMessage
.w_Message
.mn_Node
.ln_Type
= NT_MESSAGE
;
256 sr
->wsr_WMessage
.w_Message
.mn_ReplyPort
= replyPort
;
257 sr
->wsr_WMessage
.w_Message
.mn_Length
= sizeof(struct WorkerScanRequest
);
258 sr
->wsr_WMessage
.w_Command
= workerCommand
;
260 sr
->wsr_WMessage
.w_Action
= workerAction
;
261 sr
->wsr_WMessage
.w_ID
= messageID
;
262 sr
->wsr_DirLock
= dirLock
;
263 wm
= (struct WorkerMessage
*) sr
;
268 struct MsgPort
*startScannerWorker(ULONG id
, BPTR dirLock
,
269 struct MsgPort
*replyPort
)
271 struct Process
*process
;
272 struct ScannerWorkerMessage
*msg
;
274 process
= CreateNewProcTags
276 NP_Entry
, (IPTR
) workerEntry
,
277 NP_Name
, (IPTR
) "Worker_Scanner",
282 if (process
== NULL
) return NULL
;
284 msg
= createWorkerScanMessage
286 WM_START
, WA_SCANNER
, id
, replyPort
, dirLock
289 PutMsg(&process
->pr_MsgPort
, (struct Message
*) msg
);
292 return &process
->pr_MsgPort
;