#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <st/st_proto.h>
#include <intuition/intuition.h>

main(int argc, char *argv[])
{
struct	FileHandle *fh = NULL;
long	out = NULL, file = NULL, err = NULL, n1, n2;
char	*prg, buf[1000];
struct MsgPort *ourport = NULL;
struct StandardPacket *stdpkt = NULL, *stdpkt2;
struct InfoData *info;
struct Window *window;

	out = Output();
	err = Open("*",MODE_OLDFILE);
	prg = FindTask(NULL)->tc_Node.ln_Name;

	fpf(out, "%s [%s]: %08lx memory pointer\n",
			prg, argv[0], FindTask(NULL)->tc_MemEntry);

	if(!(file = Open(argv[1], MODE_OLDFILE) )) {
		fpf(err,"%s: Couldn't open that nasty file\n", prg);
		goto cleanup;
	}

	fh = (struct FileHandle *)(file<<2);
	fpf(out,"File opened ok! Now for some statistic type stuff:\n"
			"File Handle at %08lx (BCPL %08lx)\n\n"

			"fh_Link %08lx (EXEC message)\n"
			"fh_Port %08lx (Reply port)\n"
			"fh_Type %08lx (Dest port)\n"
			"fh_Args %08lx (arg1)\n",
			fh, file, fh->fh_Link, fh->fh_Port, fh->fh_Type, fh->fh_Args);

/** GET A PORT AND SOME MEMORY */
	if(!(ourport = CreatePort("TestAsyncIO",0))) {
		fpf(err,"Couldn't create a port!\n");
		goto cleanup; }
	if(!(stdpkt = (struct StandardPacket *)
		AllocMem(sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR) )) {
			fpf(err,"Couldn't allocate memory!\n");
			goto cleanup; }
	if(!(info = (struct InfoData *)
		AllocMem(sizeof(struct InfoData), MEMF_CHIP | MEMF_CLEAR)) ) {
			fpf(err,"Couldn't get memory!\n");
			goto cleanup; }

	if(!(stdpkt2 = (struct StandardPacket *)
		AllocMem(sizeof(struct StandardPacket), MEMF_PUBLIC | MEMF_CLEAR) )) {
			fpf(err,"Couldn't allocate memory!\n");
			goto cleanup; }

/** CONSTRUCT A PACKET & SEND IT */
/*	n = Read(file, buf, 1000); */
	fpf( err,	"pkt=%08lx msg=%08lx por=%08lx act=%08lx\n"
				"ag1=%08lx ag2=%08lx ag3=%08lx\n",
	stdpkt->sp_Msg.mn_Node.ln_Name = (char *)&(stdpkt->sp_Pkt),
	stdpkt->sp_Pkt.dp_Link = &(stdpkt->sp_Msg),
	stdpkt->sp_Pkt.dp_Port = ourport,
	stdpkt->sp_Pkt.dp_Type = ACTION_DISK_INFO,
	stdpkt->sp_Pkt.dp_Arg1 = ((long)info)>>2,
	stdpkt->sp_Pkt.dp_Arg2 = 0,
	stdpkt->sp_Pkt.dp_Arg3 = 0 );
    PutMsg (fh->fh_Type, &(stdpkt->sp_Msg));
	fpf(out,"Waiting...\n");
	Wait(1<<ourport->mp_SigBit);
	GetMsg(ourport);
	n1 = stdpkt->sp_Pkt.dp_Res1;
	fpf(err,"Result=%08lx\n", n1);
	fpf(err,"nse=%08lx un=%08lx ds=%08lx nb=%08lx nbu=%08lx\n"
			"bpb=%08lx dt=%08lx vn=%08lx iu=%08lx\n",
			info->id_NumSoftErrors,
			info->id_UnitNumber,
			info->id_DiskState,	
			info->id_NumBlocks,	
			info->id_NumBlocksUsed,
			info->id_BytesPerBlock,
			info->id_DiskType,
			info->id_VolumeNode,
			info->id_InUse );
	window = (struct Window *)info->id_VolumeNode;
	fpf(err,"Window:\n"
			"bl=%ld bt=%ld br=%ld bb=%ld\n"
			"GZZWIdth=%ld, GZZHeight=%ld\n",
			window->BorderLeft, window->BorderTop, window->BorderRight,
			window->BorderBottom,
			window->GZZWidth, window->GZZHeight );
	if(window->IFont) {
		fpf(err,"Font: x=%ld y=%ld, dims: X=%ld, Y=%ld\n",
			window->IFont->tf_XSize,
			window->IFont->tf_YSize,
			window->GZZWidth / window->IFont->tf_XSize,
			window->GZZHeight / window->IFont->tf_YSize );
	}
	stdpkt2->sp_Msg.mn_Node.ln_Name = (char *)&(stdpkt2->sp_Pkt);
	stdpkt2->sp_Pkt.dp_Link = &(stdpkt2->sp_Msg);
	stdpkt2->sp_Pkt.dp_Port = ourport;
	stdpkt2->sp_Pkt.dp_Type = ACTION_READ;
	stdpkt2->sp_Pkt.dp_Arg1 = fh->fh_Args;
	stdpkt2->sp_Pkt.dp_Arg2 = (long)buf;
	stdpkt2->sp_Pkt.dp_Arg3 = 990;
    PutMsg (fh->fh_Type, &(stdpkt2->sp_Msg));
	fpf(out,"Waiting...\n");
	Wait(1<<ourport->mp_SigBit);
	GetMsg(ourport);
	n2 = stdpkt2->sp_Pkt.dp_Res1;

	Write(Output(), buf, n2);

cleanup:
	if(stdpkt) FreeMem(stdpkt, sizeof(struct StandardPacket));
	if(stdpkt2) FreeMem(stdpkt2, sizeof(struct StandardPacket));
	if(info) FreeMem(info, sizeof(struct InfoData));
	if(ourport) DeletePort(ourport);
	SafeClose(&file);
	SafeClose(&err);
}

