4 Original GPL release version 4.12
5 Copyright 1993-2000 Jonathan Potter
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 All users of Directory Opus 4 (including versions distributed
22 under the GPL) are entitled to upgrade to the latest version of
23 Directory Opus version 5 at a reduced price. Please see
24 http://www.gpsoft.com.au for more information.
26 The release of Directory Opus 4 under the GPL in NO WAY affects
27 the existing commercial status of Directory Opus 5.
37 struct DOpusRemember
*memkey
=NULL
;
39 char **dummy_args
,*port
,*opbuf
,*stringname
;
40 struct StringData
*stringdata
;
43 if (!(DOpusBase
=(struct DOpusBase
*)OpenLibrary("dopus.library",18)))
54 if ((vis
=LAllocRemember(&memkey
,sizeof(struct VisInfo
),MEMF_CLEAR
)) &&
55 (dummy_args
=LAllocRemember(&memkey
,sizeof(char *)*16,MEMF_CLEAR
)) &&
56 (opbuf
=LAllocRemember(&memkey
,80,MEMF_CLEAR
)) &&
57 (stringname
=LAllocRemember(&memkey
,80,MEMF_CLEAR
)) &&
58 (stringdata
=LAllocRemember(&memkey
,sizeof(struct StringData
),MEMF_CLEAR
))) {
60 IntuitionBase
=DOpusBase
->IntuitionBase
;
61 GfxBase
=DOpusBase
->GfxBase
;
62 IconBase
=OpenLibrary("icon.library",0);
65 struct WBStartup
*startup
;
68 startup
=(struct WBStartup
*)argv
;
69 for (arg
=0;arg
<startup
->sm_NumArgs
&& arg
<16;arg
++) {
70 dummy_args
[arg
]=startup
->sm_ArgList
[arg
].wa_Name
;
76 struct DiskObject
*dobj
;
79 if (dobj
=GetDiskObject(argv
[0])) {
80 if (str
=FindToolType(dobj
->do_ToolTypes
,"OPERATION")) {
81 LStrnCpy(opbuf
,str
,80);
91 if (argc
>2 && argv
[2][0]=='&') {
99 get_vis_info(vis
,port
);
101 stringdata
->default_table
=default_strings
;
102 stringdata
->string_count
=STR_STRING_COUNT
;
103 stringdata
->min_version
=STRING_VERSION
;
105 if (vis
->vi_language
)
106 lsprintf(stringname
,"DOpus:Modules/S/DM_Disk_%s.STR",vis
->vi_language
);
107 else stringname
[0]=0;
109 if (ReadStringFile(stringdata
,stringname
)) {
110 string_table
=stringdata
->string_table
;
112 switch (argv
[1][0]) {
115 diskop_format(vis
,port
,argc
-arg
,&argv
[arg
]);
119 diskop_diskcopy(vis
,port
,argc
-arg
,&argv
[arg
]);
123 diskop_install(vis
,argc
-arg
,&argv
[arg
]);
127 FreeStringFile(stringdata
);
130 if (IconBase
) CloseLibrary(IconBase
);
133 LFreeRemember(&memkey
);
135 CloseLibrary((struct Library
*)DOpusBase
);
147 void get_vis_info(vis
,portname
)
151 vis
->vi_fg
=1; vis
->vi_bg
=0;
152 vis
->vi_shine
=2; vis
->vi_shadow
=1;
155 vis
->vi_stringcol
[0]=1; vis
->vi_stringcol
[1]=0;
156 vis
->vi_activestringcol
[0]=1; vis
->vi_activestringcol
[1]=0;
157 vis
->vi_flags
=VISF_WINDOW
;
158 vis
->vi_language
=NULL
;
160 if (dopus_message(DOPUSMSG_GETVIS
,(APTR
)vis
,portname
)) return;
162 if (IntuitionBase
->LibNode
.lib_Version
>35) {
163 struct DrawInfo
*drinfo
;
166 if (pub
=LockPubScreen(NULL
)) {
167 drinfo
=GetScreenDrawInfo(pub
);
168 vis
->vi_shine
=drinfo
->dri_Pens
[SHINEPEN
];
169 vis
->vi_shadow
=drinfo
->dri_Pens
[SHADOWPEN
];
170 vis
->vi_fg
=drinfo
->dri_Pens
[TEXTPEN
];
171 vis
->vi_bg
=drinfo
->dri_Pens
[BACKGROUNDPEN
];
172 FreeScreenDrawInfo(pub
,drinfo
);
173 UnlockPubScreen(NULL
,pub
);
178 int dopus_message(cmd
,data
,portname
)
183 struct MsgPort
*port
,*replyport
;
184 struct DOpusMessage msg
;
187 if (portname
&& portname
[0] &&
188 (port
=FindPort(portname
)) &&
189 (replyport
=LCreatePort(NULL
,0))) {
190 msg
.msg
.mn_Node
.ln_Type
=NT_MESSAGE
;
191 msg
.msg
.mn_Node
.ln_Name
=NULL
;
192 msg
.msg
.mn_ReplyPort
=replyport
;
193 msg
.msg
.mn_Length
=(UWORD
)sizeof(struct DOpusMessage
);
196 PutMsg(port
,(struct Message
*)&msg
);
200 LDeletePort(replyport
);
207 void fill_out_req(req
,vis
)
208 struct RequesterBase
*req
;
211 req
->rb_fg
=vis
->vi_fg
;
212 req
->rb_bg
=vis
->vi_bg
;
213 req
->rb_shine
=vis
->vi_shine
;
214 req
->rb_shadow
=vis
->vi_shadow
;
215 req
->rb_font
=vis
->vi_font
;
216 req
->rb_flags
&=~RBF_WINDOWCENTER
;
217 if (vis
->vi_screen
) {
218 if (vis
->vi_flags
&VISF_WINDOW
) {
219 req
->rb_screen
=((struct Window
*)vis
->vi_screen
)->WScreen
;
220 req
->rb_window
=(struct Window
*)vis
->vi_screen
;
221 req
->rb_flags
|=RBF_WINDOWCENTER
;
223 else req
->rb_screen
=vis
->vi_screen
;
225 else req
->rb_screen
=NULL
;
228 struct Gadget
*addreqgadgets(reqbase
,gadgets
,mask
,count
)
229 struct RequesterBase
*reqbase
;
230 struct TagItem
**gadgets
;
234 struct Gadget
*gadget
=NULL
,*newgadget
,*firstgadget
;
237 if (!gadgets
[gad
]) break;
238 if (!(mask
&(1<<gad
))) {
239 if (!(newgadget
=(struct Gadget
*)
240 AddRequesterObject(reqbase
,gadgets
[gad
]))) return(NULL
);
241 if (gadget
) gadget
->NextGadget
=newgadget
;
242 else firstgadget
=newgadget
;
247 AddGadgets(reqbase
->rb_window
,firstgadget
,NULL
,gad
,reqbase
->rb_shine
,reqbase
->rb_shadow
,1);
251 int error_rets
[]={1,0};
253 int check_error(reqbase
,str
,gadtxt
)
254 struct RequesterBase
*reqbase
;
258 struct DOpusSimpleRequest req
;
262 error_gads
[0]=string_table
[gadtxt
];
263 error_gads
[1]=string_table
[STR_CANCEL
];
267 req
.hi
=reqbase
->rb_shine
;
268 req
.lo
=reqbase
->rb_shadow
;
269 req
.fg
=reqbase
->rb_fg
;
270 req
.bg
=reqbase
->rb_bg
;
272 req
.flags
=SRF_RECESSHI
;
273 if (reqbase
->rb_flags
&RBF_BORDERS
) req
.flags
|=SRF_BORDERS
;
274 req
.font
=reqbase
->rb_font
;
275 req
.title
="DOpus_Disk";
276 return(DoSimpleRequest(reqbase
->rb_window
,&req
));
279 ULONG
do_checksum(sector
)
285 for (sum
=0,i
=0;i
<(TD_SECTOR
>>2);i
++) sum
+=sector
[i
];
289 int do_writeblock(device_req
,buffer
,offset
)
290 struct IOExtTD
*device_req
;
294 device_req
->iotd_Req
.io_Command
=CMD_WRITE
;
295 device_req
->iotd_Req
.io_Data
=buffer
;
296 device_req
->iotd_Req
.io_Length
=TD_SECTOR
;
297 device_req
->iotd_Req
.io_Offset
=offset
*TD_SECTOR
;
298 return((int)DoIO((struct IORequest
*)device_req
));
301 void inhibit_drive(device
,state
)
306 struct MsgPort
*handler
;
308 if (DOSBase
->dl_lib
.lib_Version
<36) {
309 if (handler
=(struct MsgPort
*)DeviceProc(device
))
310 SendPacket(handler
,ACTION_INHIBIT
,&state
,1);
312 else Inhibit(device
,state
);
314 Inhibit(device
,state
);
318 void border_text(reqbase
,border
,infobuf
)
319 struct RequesterBase
*reqbase
;
320 Object_Border
*border
;
325 rp
=reqbase
->rb_window
->RPort
;
326 SetAPen(rp
,reqbase
->rb_bg
);
327 RectFill(rp
,border
->ob_left
,border
->ob_top
,
328 border
->ob_left
+border
->ob_width
-1,border
->ob_top
+border
->ob_height
-1);
329 SetAPen(rp
,reqbase
->rb_fg
);
338 TEXTPOS_CENTER
|TEXTPOS_F_NOUSCORE
);
342 struct DeviceNode
*find_device(name
)
346 struct RootNode
*rootnode
;
347 struct DosInfo
*dosinfo
;
348 struct DeviceNode
*devnode
;
349 char matchname
[32],devname
[32];
352 if (!name
) return(NULL
);
354 for (a
=0;name
[a
];a
++) {
355 if (name
[a
]==':') break;
356 matchname
[a
]=name
[a
];
362 rootnode
=(struct RootNode
*) DOSBase
->dl_Root
;
363 dosinfo
=(struct DosInfo
*) BADDR(rootnode
->rn_Info
);
364 devnode
=(struct DeviceNode
*) BADDR(dosinfo
->di_DevInfo
);
367 if (devnode
->dn_Type
==DLT_DEVICE
&& devnode
->dn_Task
) {
368 BtoCStr((BPTR
)devnode
->dn_Name
,devname
,32);
369 if (strcmp(devname
,matchname
)==0) {
374 devnode
=(struct DeviceNode
*) BADDR(devnode
->dn_Next
);
382 if (dl
= LockDosList(LDF_DEVICES
| LDF_READ
))
383 dl
= (APTR
)FindDosEntry(dl
,name
,LDF_DEVICES
);
384 UnLockDosList(LDF_DEVICES
| LDF_READ
);
385 return (struct DeviceNode
*)dl
;
389 char **get_device_list(key
,alike
)
390 struct DOpusRemember
**key
;
393 // struct RootNode *rootnode;
394 // struct DosInfo *dosinfo;
395 struct DeviceNode
*devnode
,*alikenode
=NULL
;
397 char **listtable
,devname
[32];
399 if (alike
) alikenode
=find_device(alike
);
403 rootnode=(struct RootNode *) DOSBase->dl_Root;
404 dosinfo=(struct DosInfo *) BADDR(rootnode->rn_Info);
405 devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
407 devnode
= (struct DeviceNode
*)LockDosList(LDF_READ
| LDF_DEVICES
);
409 while ((devnode
= (struct DeviceNode
*)NextDosEntry((struct DosList
*)devnode
,LDF_DEVICES
))) {
410 if (/*devnode->dn_Type==DLT_DEVICE && devnode->dn_Task &&*/
411 devnode
->dn_Startup
>512) {
412 if (!alikenode
|| like_devices(devnode
,alikenode
))
415 // devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
418 if ((listtable
=LAllocRemember(key
,count
*4,MEMF_CLEAR
))) {
419 devnode
= (struct DeviceNode
*)LockDosList(LDF_READ
| LDF_DEVICES
);
420 // devnode=(struct DeviceNode *) BADDR(dosinfo->di_DevInfo);
422 while ((devnode
= (struct DeviceNode
*)NextDosEntry((struct DosList
*)devnode
,LDF_DEVICES
))) {
424 if (/*devnode->dn_Type==DLT_DEVICE && devnode->dn_Task &&*/
425 devnode
->dn_Startup
>512) {
426 if (!alikenode
|| like_devices(devnode
,alikenode
)) {
427 BtoCStr((BPTR
)devnode
->dn_Name
,devname
,32);
429 if ((listtable
[count
]=LAllocRemember(key
,strlen(devname
)+5,0)))
430 strcpy(listtable
[count
],devname
);
434 // devnode=(struct DeviceNode *) BADDR(devnode->dn_Next);
436 UnLockDosList(LDF_READ
| LDF_DEVICES
);
437 sort_device_list(listtable
);
439 UnLockDosList(LDF_READ
| LDF_DEVICES
);
445 void sort_device_list(table
)
451 for (count
=0;table
[count
];count
++);
453 for (gap
=count
/2;gap
>0;gap
/=2)
454 for (i
=gap
;i
<count
;i
++)
455 for (j
=i
-gap
;j
>=0;j
-=gap
) {
456 if (LStrCmpI(table
[j
],table
[j
+gap
])<=0) break;
458 table
[j
]=table
[j
+gap
];
463 int check_disk(reqbase
,device_req
,name
,prot
)
464 struct RequesterBase
*reqbase
;
465 struct IOExtTD
*device_req
;
472 device_req
->iotd_Req
.io_Command
=TD_CHANGESTATE
;
473 DoIO((struct IORequest
*)device_req
);
474 if (device_req
->iotd_Req
.io_Actual
) {
475 lsprintf(errorbuf
,string_table
[STR_NODISKPRESENT
],name
);
476 if (!(check_error(reqbase
,errorbuf
,STR_RETRY
))) return(0);
482 device_req
->iotd_Req
.io_Command
=TD_PROTSTATUS
;
483 DoIO((struct IORequest
*)device_req
);
484 if (device_req
->iotd_Req
.io_Actual
) {
485 lsprintf(errorbuf
,string_table
[STR_DISKWRITEPROTECTED
],name
);
486 if (!(check_error(reqbase
,errorbuf
,STR_RETRY
))) return(0);
494 int check_abort(window
)
495 struct Window
*window
;
497 struct IntuiMessage
*msg
;
500 while (msg
=(struct IntuiMessage
*)GetMsg(window
->UserPort
)) {
501 if (msg
->Class
==IDCMP_MOUSEBUTTONS
&& msg
->Code
==MENUDOWN
)
503 ReplyMsg((struct Message
*)msg
);
508 int check_blank_disk(reqbase
,device
,action
)
509 struct RequesterBase
*reqbase
;
510 char *device
,*action
;
513 struct InfoData __aligned info
;
514 struct FileInfoBlock __aligned fib
;
515 struct Process
*myproc
;
517 char blank
=0,*message
,diskname
[40],sizebuf
[20];
520 if (!(message
=AllocMem(400,MEMF_CLEAR
))) return(1);
522 myproc
=(struct Process
*)FindTask(NULL
);
523 wsave
=myproc
->pr_WindowPtr
;
524 myproc
->pr_WindowPtr
=(APTR
)-1;
526 if (lock
=Lock(device
,ACCESS_READ
)) {
528 switch (info
.id_DiskType
) {
529 case ID_UNREADABLE_DISK
:
530 case ID_NOT_REALLY_DOS
:
535 strcpy(diskname
,fib
.fib_FileName
);
536 if (!(ExNext(lock
,&fib
))) blank
=1;
543 myproc
->pr_WindowPtr
=wsave
;
545 if (!blank
&& action
) {
546 getsizestring(sizebuf
,info
.id_NumBlocksUsed
*info
.id_BytesPerBlock
);
548 lsprintf(message
,string_table
[STR_DISK_NOT_BLANK
],
549 device
,diskname
,sizebuf
,action
);
551 if (!(check_error(reqbase
,message
,STR_PROCEED
))) ret
=0;
553 FreeMem(message
,400);
557 void set_env(action
,gadget
,count
,list
)
559 struct Gadget
*gadget
;
561 struct DOpusListView
*list
;
566 char envname
[80],null
=0;
568 lsprintf(envname
,"ENV:DOpus_%s.prefs",action
);
569 if (!(file
=Open(envname
,MODE_NEWFILE
))) return;
571 while (gadget
&& count
--) {
572 if (gadget
->Activation
&GACT_TOGGLESELECT
) {
573 Write(file
,&gadget
->GadgetID
,sizeof(UWORD
));
574 Write(file
,&gadget
->GadgetType
,sizeof(UWORD
));
575 switch (gadget
->GadgetType
) {
576 case GTYP_BOOLGADGET
:
577 Write(file
,&gadget
->Flags
,sizeof(UWORD
));
580 len
=strlen(((struct StringInfo
*)gadget
->SpecialInfo
)->Buffer
)+1;
581 Write(file
,&len
,sizeof(UWORD
));
582 Write(file
,((struct StringInfo
*)gadget
->SpecialInfo
)->Buffer
,len
);
583 if (len
%2) Write(file
,&null
,1);
588 gadget
=gadget
->NextGadget
;
591 Write(file
,&listid
,sizeof(ULONG
));
592 Write(file
,list
->items
[list
->itemselected
],
593 (len
=(strlen(list
->items
[list
->itemselected
])+1)));
594 if (len
%2) Write(file
,&null
,1);
600 void get_env(action
,firstgadget
,count
,list
)
602 struct Gadget
*firstgadget
;
604 struct DOpusListView
*list
;
608 char envname
[80],*nptr
;
609 struct Gadget
*gadget
;
610 UWORD gadgettype
,gadgetid
,len
,*buf
;
612 lsprintf(envname
,"ENV:DOpus_%s.prefs",action
);
613 if (!(file
=Open(envname
,MODE_OLDFILE
))) return;
615 Seek(file
,0,OFFSET_END
);
616 size
=Seek(file
,0,OFFSET_BEGINNING
);
618 if (!(buf
=(UWORD
*)AllocMem(size
,MEMF_CLEAR
))) {
623 Read(file
,(char *)buf
,size
);
626 for (a
=0;a
<size
/2;) {
628 if (lbuf
[0]=='LIST') {
630 nptr
=(char *)&buf
[a
];
632 for (b
=0;list
->items
[b
];b
++) {
633 if (LStrCmpI(nptr
,list
->items
[b
])==0) {
634 list
->itemselected
=b
;
649 if (gadget
->GadgetID
==gadgetid
&& gadget
->GadgetType
==gadgettype
)
651 gadget
=gadget
->NextGadget
;
653 if (!count
--) gadget
=NULL
;
654 switch (gadgettype
) {
655 case GTYP_BOOLGADGET
:
656 if (gadget
) gadget
->Flags
=buf
[a
];
661 if (gadget
) strcpy(((struct StringInfo
*)gadget
->SpecialInfo
)->Buffer
,(char *)&buf
[a
]);
670 void fix_listview(reqbase
,list
)
671 struct RequesterBase
*reqbase
;
672 struct DOpusListView
*list
;
674 list
->window
=reqbase
->rb_window
;
675 list
->flags
|=DLVF_LEAVE
|DLVF_SLOW
;
677 list
->slidercol
=reqbase
->rb_fg
;
678 list
->sliderbgcol
=reqbase
->rb_bg
;
679 list
->textcol
=reqbase
->rb_fg
;
680 list
->boxhi
=reqbase
->rb_shine
;
681 list
->boxlo
=reqbase
->rb_shadow
;
682 list
->arrowfg
=reqbase
->rb_fg
;
683 list
->arrowbg
=reqbase
->rb_bg
;
684 list
->itemfg
=reqbase
->rb_fg
;
685 list
->itembg
=reqbase
->rb_bg
;
688 void select_device(list
,exclude
)
689 struct DOpusListView
*list
;
694 for (item
=0;list
->items
[item
];item
++) {
695 if (!exclude
|| LStrCmpI(list
->items
[item
],exclude
)) {
696 if (list
->items
[item
][0]=='D' &&
697 list
->items
[item
][1]=='F' &&
698 list
->items
[item
][3]==':') {
702 if (def
==-1) def
=item
;
706 list
->itemselected
=def
;
710 int like_devices(node
,likenode
)
711 struct DeviceNode
*node
,*likenode
;
713 struct DosEnvec
*envec
,*likeenvec
;
714 struct FileSysStartupMsg
*startup
,*likestartup
;
716 startup
=(struct FileSysStartupMsg
*)BADDR(node
->dn_Startup
);
717 likestartup
=(struct FileSysStartupMsg
*)BADDR(likenode
->dn_Startup
);
718 envec
=(struct DosEnvec
*)BADDR(startup
->fssm_Environ
);
719 likeenvec
=(struct DosEnvec
*)BADDR(likestartup
->fssm_Environ
);
721 if (envec
->de_SizeBlock
!=likeenvec
->de_SizeBlock
||
722 envec
->de_Surfaces
!=likeenvec
->de_Surfaces
||
723 envec
->de_BlocksPerTrack
!=likeenvec
->de_BlocksPerTrack
||
724 ((envec
->de_HighCyl
-envec
->de_LowCyl
))!=
725 ((likeenvec
->de_HighCyl
-likeenvec
->de_LowCyl
)))
730 int open_device(device
,handle
)
732 struct DeviceHandle
*handle
;
734 struct DeviceNode
*devnode
;
737 handle
->startup
=NULL
;
738 handle
->dosenvec
=NULL
;
739 handle
->device_port
=NULL
;
740 handle
->device_req
=NULL
;
742 if (!device
|| !(devnode
=find_device(device
))) return(0);
744 handle
->startup
=(struct FileSysStartupMsg
*)BADDR(devnode
->dn_Startup
);
745 handle
->dosenvec
=(struct DosEnvec
*)BADDR(handle
->startup
->fssm_Environ
);
746 BtoCStr((BPTR
)handle
->startup
->fssm_Device
,devicename
,40);
748 if (!(handle
->device_port
=LCreatePort(NULL
,0))) return(0);
749 if (handle
->device_req
=(struct IOExtTD
*)
750 LCreateExtIO(handle
->device_port
,sizeof(struct IOExtTD
))) {
751 if (!(OpenDevice(devicename
,handle
->startup
->fssm_Unit
,
752 (struct IORequest
*)handle
->device_req
,handle
->startup
->fssm_Flags
)))
754 LDeleteExtIO((struct IORequest
*)handle
->device_req
);
755 handle
->device_req
=NULL
;
760 void close_device(handle
)
761 struct DeviceHandle
*handle
;
763 if (handle
->device_req
) {
764 CloseDevice((struct IORequest
*)handle
->device_req
);
765 LDeleteExtIO((struct IORequest
*)handle
->device_req
);
766 handle
->device_req
=NULL
;
768 if (handle
->device_port
) {
769 LDeletePort(handle
->device_port
);
770 handle
->device_port
=NULL
;
774 void drive_motor(req
,state
)
778 req
->iotd_Req
.io_Command
=TD_MOTOR
;
779 req
->iotd_Req
.io_Length
=state
;
780 DoIO((struct IORequest
*)req
);
783 void show_sel_item(list
)
784 struct DOpusListView
*list
;
787 if (list
->itemselected
<list
->topitem
||
788 list
->itemselected
>(list
->topitem
+list
->lines
-1)) {
789 list
->topitem
=list
->itemselected
;
790 RefreshListView(list
,1);