home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 13
/
AACD13.ISO
/
AACD
/
Utilities
/
ACDPlay
/
src
/
V1.5
/
pickcdid
/
PickCDID.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-04-26
|
21KB
|
720 lines
/**************************************************************************
|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| PickCDID - Tool |
| ----------------- |
| |
| Version 0.9 |
|___________________________________________|
Autor : Martin Kresse [mak]
Copyright: Freeware
Was: Programm, das CDIDs eingelegter CDs aus einem Verzeichnis in
ein anderes kopiert.
Umgebung : Maxon C++ light auf Amiga 12oo OS3.0 68o3o 2MB Chip 12MB Fast
Status : 1. Release mit ACDPlay 1.5
Bugs : keine bekannt
Autor Version Datum Veränderungen
------- --------- -------- ------------------------------------------
mak 0.1 22.04.97 - Programmgerüst (Window+Gads und Timer...)
0.2 23.04.97 - CD-Zeugs eingebaut
- DiskFiles werden eingelesen und im LV angezeigt
- Windowgröße ist jetzt veränderbar
0.3 24.04.97 - ShowTitles() und OpenFile() eingefügt
0.4 25.04.97 - Programm kopiert jetzt nicht vorhandene IDs
- Parameter per Tooltypes
0.9 26.04.97 - kosmetische Änderungen
- Tastaturunterstützung
- ShowMsgA() benutzt ReqToolsLib falls vorhanden
- ToolType AUTOEJECT dazu
**************************************************************************/
static char prog_version[] = "\0$VER: PickCDID V0.9 ("__DATE2__")";
/*----- Includes ---------------< >-*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <libraries/gadtools.h>
#include <devices/timer.h>
#include <devices/scsidisk.h>
#include <clib/alib_protos.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/icon_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <wbstartup.h>
#include <string.h>
#include <stdio.h>
#include "CD-ROM.h"
/*----- globale Variablen ------< >-*/
struct Library *IntuitionBase = NULL;
struct Library *IconBase = NULL;
struct Library *GadToolsBase = NULL;
struct Library *GfxBase = NULL;
struct Library *ReqToolsBase = NULL;
#define GAD_LIST 0
#define GAD_DELETE 1
#define ANZ_GADS 2
struct Window *window;
struct Gadget *mygad[ANZ_GADS];
struct MsgPort *timer_mp;
struct timerequest *timereq;
struct CDxRequest *cdx;
char *devicename, *destpath, *sourcepath;
ULONG unit = 0, lun = 0;
BOOL autoej = FALSE;
struct CDIDNode
{
struct Node cdid_Node; /* ln_Name zeigt auf CD-ID */
char cdid_CDID[20];
};
/*----- interne Funktionen -----< >-*/
struct List *GetDirContents(char *dirname);
void ShowTitles(struct List *list, ULONG pos);
void DeleteTitle(struct List *list, ULONG item);
BOOL InitAll(char *progname);
void FreeAll(void);
BOOL InitTimer(void);
void FreeTimer(void);
void AddTimeRequest(ULONG micro);
BOOL OpenLibs(void);
void CloseLibs(void);
char *OpenFile(char * name);
void FreeList(List *list);
LONG FindNodeName(List *list, char *name);
Node *FindNode(List * list, ULONG number);
/*----- externe Funktionen -----< >-*/
#include "Quick.h"
/*------------------ main() -----------------------------------< >-*/
int main(int argc, char *argv[])
{
struct Gadget *glist, *aktgad;
struct IntuiMessage *imsg;
struct Screen *screen;
struct List *idlist;
APTR visualinfo;
BOOL terminate = FALSE;
UBYTE laststatus = AUDIO_STAT_NO_DISK;
UWORD imsgcode, fontY;
WORD lastitem = ~0;
ULONG rc = RETURN_FAIL, imsgclass, seconds, lastseconds=0, micros, lastmicros=0;
if (!OpenLibs())
{
CloseLibs();
return(rc);
}
if (InitAll(argv[0]))
{
if (screen = LockPubScreen("Workbench"))
{
fontY = screen->Font->ta_YSize;
if (visualinfo = GetVisualInfo(screen, TAG_END))
{
if (aktgad = CreateContext(&glist))
{
struct NewGadget ng = { screen->WBorLeft + 4, // ng_LeftEdge,
screen->WBorTop+2*fontY+8, // ng_TopEdge,
192 - screen->WBorLeft - screen->WBorRight, // ng_Width,
8*fontY, // ng_Height,
"Known CDs", // ng_GadgetText,
NULL, // ng_TextAttr,
GAD_LIST, // ng_GadgetID,
0, // ng_Flags,
visualinfo, // ng_VisualInfo,
NULL }; // ng_UserData
idlist = GetDirContents(destpath);
mygad[GAD_LIST] = aktgad = CreateGadget(LISTVIEW_KIND, aktgad, &ng, GTLV_ShowSelected, FALSE, GTLV_Labels, idlist, GTLV_ScrollWidth, 2*fontY, TAG_END);
ng.ng_GadgetID = GAD_DELETE;
ng.ng_TopEdge += ng.ng_Height+1;
ng.ng_Width = aktgad->Width;
ng.ng_Height = fontY+6;
ng.ng_GadgetText = "_Delete";
mygad[GAD_DELETE] = aktgad = CreateGadget(BUTTON_KIND, aktgad, &ng, GT_Underscore, '_', GA_Disabled, IsListEmpty(idlist), TAG_END);
if (window = OpenWindowTags(NULL,
WA_Left, 220,
WA_Top, 100,
WA_Width, 200,
WA_Height, aktgad->TopEdge + aktgad->Height + 14,
WA_Title, "PickCDID V0.9",
WA_Gadgets, glist,
WA_PubScreen, screen,
WA_Flags, WFLG_SIZEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_SIZEBBOTTOM | WFLG_ACTIVATE,
WA_IDCMP, LISTVIEWIDCMP | BUTTONIDCMP | IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_NEWSIZE,
WA_AutoAdjust, TRUE,
WA_MinWidth, 100,
WA_MinHeight, 100,
WA_MaxWidth, ~0,
WA_MaxHeight, ~0,
TAG_END))
{
GT_RefreshWindow(window, NULL);
AddTimeRequest(10);
while (!terminate)
{
Wait((1L << window->UserPort->mp_SigBit) | (1L << timer_mp->mp_SigBit));
if (GetMsg(timer_mp))
{
/* Update wird fällig */
CDUpdateA(cdx);
if (cdx->cdx_AudioStatus != laststatus)
{
/* wurde CD eingelegt? */
if (laststatus == AUDIO_STAT_NO_DISK)
{
char IDBuffer[20];
ULONG i;
strcpy(IDBuffer, "ID");
strncat(IDBuffer, cdx->cdx_TOCData->CDID, 17);
/* Diskfile der eingelegten CD nicht vorhanden? */
if ((i = FindNodeName(idlist, IDBuffer)) == ~0)
{
char filename[256];
char *file;
strcpy(filename, sourcepath);
AddPart(filename, IDBuffer, 255);
/* Diskfile aus der Sammlung laden */
if (file = OpenFile(filename))
{
BPTR fh;
strcpy(filename, destpath);
AddPart(filename, IDBuffer, 255);
/* Diskfile ins Zielverzeichnis kopieren */
if (fh = Open(filename, MODE_NEWFILE))
{
struct CDIDNode *tempnode;
Write(fh, file+4, *(ULONG *)file);
Close(fh);
SetProtection(filename, FIBF_EXECUTE);
/* neues Listview-Item dazu */
if (tempnode = GetVecA(sizeof(struct CDIDNode), MEMF_PUBLIC | MEMF_CLEAR))
{
strncpy(tempnode->cdid_CDID, IDBuffer, 19);
tempnode->cdid_Node.ln_Name = tempnode->cdid_CDID;
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Labels, ~0, TAG_END);
AddTail(idlist, (struct Node *)tempnode);
lastitem = i = FindNodeName(idlist, IDBuffer);
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Labels, idlist, GTLV_Selected, i, GTLV_MakeVisible, i, TAG_END);
/* Liste nicht mehr leer? */
if (i==0)
GT_SetGadgetAttrs(mygad[GAD_DELETE], window, NULL, GA_Disabled, FALSE, TAG_END);
if (autoej)
CDEjectA(cdx, TRUE);
}
}
FreeVec(file);
}
else DisplayBeep(NULL);
}
else
{
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Selected, i, GTLV_MakeVisible, i, TAG_END);
lastitem = i;
}
}
laststatus = cdx->cdx_AudioStatus;
}
/* Damit immer ein Item selektiert ist */
if (lastitem == ~0 && !IsListEmpty(idlist))
{
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Selected, 0, TAG_END);
lastitem = 0;
}
/* In 0,25s nächstes Update */
AddTimeRequest(250000);
}
while (imsg = GT_GetIMsg(window->UserPort))
{
aktgad = (struct Gadget *)imsg->IAddress;
imsgclass = imsg->Class;
imsgcode = imsg->Code;
seconds = imsg->Seconds;
micros = imsg->Micros;
GT_ReplyIMsg(imsg);
switch(imsgclass)
{
case IDCMP_NEWSIZE:
RemoveGList(window, glist, -1);
FreeGadgets(glist);
EraseRect(window->RPort, window->BorderLeft, window->BorderTop,
window->Width - window->BorderRight - 1,
window->Height - window->BorderBottom - 1);
RefreshWindowFrame(window);
aktgad = CreateContext(&glist);
ng.ng_LeftEdge = window->BorderLeft + 4;
ng.ng_TopEdge = window->BorderTop + fontY + 7;
ng.ng_Width = window->Width - window->BorderLeft - window->BorderRight - 8;
ng.ng_Height = window->Height - window->BorderTop - window->BorderBottom - 2*fontY - 16;
ng.ng_GadgetText= "Known CDs";
ng.ng_GadgetID = GAD_LIST;
mygad[GAD_LIST] = aktgad = CreateGadget(LISTVIEW_KIND, aktgad, &ng, GTLV_ShowSelected, FALSE, GTLV_Labels, idlist, GTLV_ScrollWidth, 2*fontY, GTLV_Selected, lastitem, GTLV_MakeVisible, lastitem, TAG_END);
ng.ng_TopEdge += (ng.ng_Height+aktgad->Height)/2 + 1;
ng.ng_Width = aktgad->Width;
ng.ng_Height = fontY+6;
ng.ng_GadgetText = "_Delete";
ng.ng_GadgetID = GAD_DELETE;
mygad[GAD_DELETE] = aktgad = CreateGadget(BUTTON_KIND, aktgad, &ng, GT_Underscore, '_', GA_Disabled, IsListEmpty(idlist), TAG_END);
AddGList(window, glist, ~0, -1, NULL);
RefreshGList(glist, window, NULL, -1);
GT_RefreshWindow(window, NULL);
break;
case IDCMP_GADGETUP:
switch(aktgad->GadgetID)
{
case GAD_LIST:
if (lastitem == imsgcode && DoubleClick(lastseconds, lastmicros, seconds, micros))
{
ShowTitles(idlist, lastitem);
lastseconds = 0;
lastmicros = 0;
}
else
{
lastseconds = seconds;
lastmicros = micros;
lastitem = imsgcode;
}
break;
case GAD_DELETE:
if (lastitem != ~0 && !IsListEmpty(idlist))
{
DeleteTitle(idlist, lastitem);
/* Wenn unterstes Item eines LVs gelöscht wird rutscht das LV nach oben */
if (lastitem >= ListLengthA(idlist))
lastitem = ListLengthA(idlist)-1;
}
}
break;
case IDCMP_VANILLAKEY:
switch (imsgcode)
{
case 13: /* Return */
ShowTitles(idlist, lastitem);
break;
case 32: /* Space */
if (!CDTestUnitA(cdx) || (cdx->cdx_Flags & SPECIALF_JUSTCLOSED))
CDEjectA(cdx, TRUE);
else
CDEjectA(cdx, FALSE);
break;
case 'd':
case 'D':
case 127: /* Delete */
if (lastitem != ~0 && !IsListEmpty(idlist))
{
DeleteTitle(idlist, lastitem);
if (lastitem >= ListLengthA(idlist))
lastitem = ListLengthA(idlist)-1;
}
break;
case 27: /* ESC */
terminate = TRUE;
}
break;
case IDCMP_RAWKEY:
if (lastitem != ~0 && !IsListEmpty(idlist))
{
switch (imsgcode)
{
case 0x4C: /* Cursor hoch */
if (lastitem > 0)
{
lastitem--;
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Selected, lastitem, GTLV_MakeVisible, lastitem, TAG_END);
}
break;
case 0x4D: /* Cursor runter */
if (lastitem < ListLengthA(idlist)-1)
{
lastitem++;
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Selected, lastitem, GTLV_MakeVisible, lastitem, TAG_END);
}
break;
}
}
break;
case IDCMP_CLOSEWINDOW:
terminate = TRUE;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(window);
GT_EndRefresh(window, TRUE);
}
}
}
CloseWindow(window);
/* Damit nicht auf Antwort gewartet werden muß */
if (!GetMsg(timer_mp))
{
AbortIO((struct IORequest *)timereq);
WaitIO((struct IORequest *)timereq);
}
rc = RETURN_OK;
}
FreeGadgets(glist);
FreeList(idlist);
}
FreeVisualInfo(visualinfo);
}
UnlockPubScreen(NULL, screen);
}
FreeAll();
}
CloseLibs();
return rc;
}
/*------------------ GetDirContents() -------------------------< >-*/
struct List *GetDirContents(char *dirname)
{
BPTR filelock;
struct FileInfoBlock *fib;
struct List *dirlist = NULL;
if (filelock = Lock(dirname, SHARED_LOCK))
{
if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL))
{
if (Examine(filelock, fib) != DOSFALSE)
{
/* Directory-Test */
if (fib->fib_DirEntryType >= 0 && fib->fib_DirEntryType != ST_SOFTLINK)
{
if (dirlist = GetVecA(sizeof(struct List), MEMF_PUBLIC | MEMF_CLEAR))
{
struct CDIDNode *tempnode;
NewList(dirlist);
while (ExNext(filelock, fib) != DOSFALSE)
{
/* Nur Files mit den Anfangsbuchstaben "ID" werden akzeptiert */
if ((fib->fib_DirEntryType == ST_FILE || fib->fib_DirEntryType == ST_LINKFILE) && *(UWORD *)fib->fib_FileName == 0x4944)
{
if (tempnode = GetVecA(sizeof(struct CDIDNode), MEMF_PUBLIC | MEMF_CLEAR))
{
strncpy(tempnode->cdid_CDID, fib->fib_FileName, 20);
tempnode->cdid_Node.ln_Name = tempnode->cdid_CDID;
AddTail(dirlist, (struct Node *)tempnode);
}
}
}
}
}
}
FreeDosObject(DOS_FIB, (APTR)fib);
}
UnLock(filelock);
}
return (dirlist);
}
/*------------------ ShowTitles() -----------------------------< >-*/
void ShowTitles(List *list, ULONG pos)
{
struct Node *node;
char filename[256];
char *file;
if (node = FindNode(list, pos))
{
strcpy(filename, destpath);
AddPart(filename, node->ln_Name, 256);
if (file = (char *)OpenFile(filename))
{
if (IntuitionBase->lib_Version >= 39)
SetWindowPointer(window, WA_BusyPointer, TRUE, TAG_END);
ShowMsgA("CD Info", "%s", file+4);
if (IntuitionBase->lib_Version >= 39)
SetWindowPointer(window, WA_BusyPointer, FALSE, TAG_END);
FreeVec(file);
}
}
}
/*------------------ DeleteTitle() ----------------------------< >-*/
void DeleteTitle(struct List *list, ULONG item)
{
char buffer[256];
struct Node *node = FindNode(list, item);
if (node)
{
strcpy(buffer, destpath);
AddPart(buffer, node->ln_Name, 255);
if (DeleteFile(buffer))
{
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Labels, ~0, TAG_END);
Remove(node);
FreeVec(node);
GT_SetGadgetAttrs(mygad[GAD_LIST], window, NULL, GTLV_Labels, list, TAG_END);
if (IsListEmpty(list))
GT_SetGadgetAttrs(mygad[GAD_DELETE], window, NULL, GA_Disabled, TRUE, TAG_END);
}
}
}
/*------------------ InitAll() --------------------------------< >-*/
BOOL InitAll(char *progname)
{
if (devicename = GetVecA(32+256+256, MEMF_PUBLIC | MEMF_CLEAR))
{
struct DiskObject *dobj;
destpath = devicename + 32;
sourcepath = destpath + 256;
/* Tooltypes auslesen */
if (dobj = GetDiskObject(progname))
{
char **toolarray, *s;
toolarray = dobj->do_ToolTypes;
if (s = (char *)FindToolType((UBYTE **)toolarray, "DEVICE"))
strncpy(devicename, s, 31);
if (s = (char *)FindToolType((UBYTE **)toolarray, "SOURCEPATH"))
strncpy(sourcepath, s, 255);
if (s = (char *)FindToolType((UBYTE **)toolarray, "DESTPATH"))
strncpy(destpath, s, 255);
if (s = (char *)FindToolType((UBYTE **)toolarray, "AUTOEJECT"))
if (!strcmp(s, "NO") || !strcmp(s, "no"))
autoej = FALSE;
else
autoej = TRUE;
if (s = (char *)FindToolType((UBYTE **)toolarray, "UNIT"))
if (s[0] >= '0' && s[0] <= '7')
unit = (ULONG)(s[0]-48);
if (s = (char *)FindToolType((UBYTE **)toolarray, "LUN"))
if (s[0] >= '0' && s[0] <= '7')
lun = (ULONG)(s[0]-48);
FreeDiskObject(dobj);
}
if (cdx = CDOpenDeviceA(devicename, unit, lun))
{
if (InitTimer())
{
return (TRUE);
}
CDCloseDeviceA(cdx);
}
FreeVec(devicename);
}
return (FALSE);
}
/*------------------ FreeAll() --------------------------------< >-*/
void FreeAll(void)
{
FreeTimer();
CDCloseDeviceA(cdx);
FreeVec(devicename);
}
/*------------------ InitTimer() ------------------------------< >-*/
BOOL InitTimer(void)
{
if (timer_mp = CreateMsgPort())
{
if (timereq = CreateIORequest(timer_mp, sizeof(struct timerequest)));
{
if (!OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)timereq, 0L))
{
return (TRUE);
}
DeleteIORequest(timereq);
}
DeleteMsgPort(timer_mp);
}
return (FALSE);
}
/*------------------ FreeTimer() ------------------------------< >-*/
void FreeTimer(void)
{
CloseDevice((struct IORequest *)timereq);
DeleteIORequest(timereq);
DeleteMsgPort(timer_mp);
}
/*------------------ AddTimeRequest() -------------------------< >-*/
void AddTimeRequest(ULONG micro)
{
timereq->tr_node.io_Command = TR_ADDREQUEST;
timereq->tr_time.tv_secs = 0;
timereq->tr_time.tv_micro = micro;
SendIO((struct IORequest *)timereq);
}
/*------------------ OpenLibs() -------------------------------< >-*/
BOOL OpenLibs(void)
{
if (IntuitionBase=OpenLibrary("intuition.library",37))
{
if (IconBase=OpenLibrary("icon.library",37))
{
if (GadToolsBase=OpenLibrary("gadtools.library",37))
{
if (GfxBase=OpenLibrary("graphics.library",37))
{
ReqToolsBase=OpenLibrary("reqtools.library", 37);
return(TRUE);
}
}
}
}
return(FALSE);
}
/*------------------ CloseLibs() ------------------------------< >-*/
void CloseLibs(void)
{
if (GfxBase) CloseLibrary(GfxBase);
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (IconBase) CloseLibrary(IconBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
}
/*------------------ OpenFile() -------------------------------< >-*/
char * OpenFile(char * name)
{
BPTR filehandle;
struct FileInfoBlock *fib;
APTR buffer = NULL;
/* Datei öffnen */
if (filehandle = Open(name, MODE_OLDFILE))
{
if (fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL))
{
/* FileInfoblock auslesen, für Dateigröße */
if (ExamineFH(filehandle, fib) == DOSTRUE)
{
if (fib->fib_Size)
{
/* Speicher für File, Filelänge und Nullbyte reservieren */
if (buffer = (char *)GetVecA(fib->fib_Size+5, MEMF_PUBLIC | MEMF_CLEAR))
{
*(ULONG *)buffer = fib->fib_Size;
/* Datei in Speicher schreiben */
if (Read(filehandle, (char *)buffer+4, fib->fib_Size) != fib->fib_Size)
{
FreeVec(buffer);
buffer = NULL;
}
}
}
}
FreeDosObject(DOS_FIB, (APTR)fib);
}
/* Datei schließen */
Close(filehandle);
}
return ((char *)buffer);
}
/*------------------ FreeList() -------------------------------< >-*/
void FreeList(List *list)
{
if (list)
{
Node *temp_node, *next_temp_node;
for (temp_node = list->lh_Head; temp_node->ln_Succ;)
{
next_temp_node = temp_node->ln_Succ;
FreeVec(temp_node);
temp_node = next_temp_node;
}
FreeVec(list);
}
}
/*------------------ FindNodeName() ---------------------------< >-*/
LONG FindNodeName(List *list, char *name)
{
register Node *node = list->lh_Head;
register LONG i=0;
for (node = list->lh_Head ; node->ln_Succ && strcmp(name, node->ln_Name) ; node = node->ln_Succ)
i++;
return (node->ln_Succ?i:~0);
}
/*------------------ FindNode() -------------------------------< >-*/
Node *FindNode(List * list, ULONG number)
{
register Node *tempnode = list->lh_Head;
ULONG i;
for (i = 0; i < number; i++)
{
if (tempnode->ln_Succ)
tempnode = tempnode->ln_Succ;
else
break;
}
return (tempnode->ln_Succ?tempnode:NULL);
}