/**********************************************                                 
**                                                                              
**                                                                              
**      Defines & Functions for AwarDeco
**                                                                              
**                                                                              
***********************************************/                                

#ifndef AWARDFUNC_H                                                                                                                             
#define AWARDFUNC_H 1

#include	<stdio.h>

typedef unsigned char	byte;
typedef unsigned short	word;
typedef unsigned long	dword;

#define	Xtract 		0x10
#define	List   		0x11
#define	XtractM 	0x20
#define	Copyrights 	0x30
#define XtractA         0x40
#define ListA           0x41
#define	Help	 	0x80

#define	BLOCK		0x8000

#ifndef __LINUX_NOW__                                                           
    #define	IDSign          ""
#else
    #define	IDSign          "+"
#endif

typedef struct {
        FILE *infile;
        FILE *outfile;
        unsigned long original;
        unsigned long packed;
        int dicbit;
        int method;
        } interfacing;

typedef struct
	{
		byte	HeadLen;
		byte	HeadCrc;
		byte	Method[5];
		dword	PackLen;
		dword	RealLen;
		dword	TStamp;
		byte	Attr;
		byte	Level;
		byte	FilenameLen;
		byte	FileName[12];
		word	CRC16;
		byte	DOS;
		word	Empty;
	} LZHHead;

typedef struct
	{
                byte    hdr_size;                                               
                byte    hdr_crc;                                                
                byte    method[5];                                              
                dword   pack_len;                                               
                dword   real_len;                                               
                dword   real_cs;                                                
                byte    rsrv1;                                                  
                byte    rsrv2;                                                  
                byte    name_len;                                               
        } LZHHeader;

typedef struct
        {
                byte    HeadLen;
                byte    HeadCrc;
                byte    Method[5];
                dword   PackLen;
                dword   RealLen;
                dword   TStamp;
                byte    Attr;
                byte    Level;
                byte    FilenameLen;
                byte    FileName[128];
        } NewLZHHead;

byte* GetModuleName(word ID)
{
        switch(ID){
	    case 0x4000:	return ("Logo BitMap");
	    case 0x4001:	return ("CPU micro code");
	    case 0x4002:	return ("EPA Pattern");
	    case 0x4003:	return ("ACPI Table");
	    case 0x4004:	return ("VSA Driver");
	    case 0x4005:	return ("HPM ROM");
	    case 0x4006:	return ("HPC ROM");
	    case 0x4007:	return ("VRS ROM");
	    case 0x4008:	return ("FNT0 ROM");
	    case 0x4009:	return ("FNT1 ROM");
	    case 0x400a:	return ("FNT2 ROM");
	    case 0x400b:	return ("FNT3 ROM");
	    case 0x400c:	return ("FNT4 ROM");
	    case 0x400d:	return ("FNT5 ROM");
	    case 0x400e:	return ("YGROUP ROM");
	    case 0x400f:	return ("MIB ROM");
	    case 0x4010:	return ("EPA1 ROM");
	    case 0x4011:	return ("LOGO1 ROM");
	    case 0x4012:	return ("OEM0 ROM");
	    case 0x4013:	return ("OEM1 ROM");
	    case 0x4014:	return ("OEM2 ROM");
	    case 0x4015:	return ("OEM3 ROM");
	    case 0x4016:	return ("OEM4 ROM");
	    case 0x4017:	return ("OEM5 ROM");
	    case 0x4018:	return ("OEM6 ROM");
	    case 0x4019:	return ("OEM7 ROM");
	    case 0x401a:	return ("EPA2 ROM");
	    case 0x401b:	return ("EPA3 ROM");
	    case 0x401c:	return ("EPA4 ROM");
	    case 0x401d:	return ("EPA5 ROM");
	    case 0x401e:	return ("EPA6 ROM");
	    case 0x401f:	return ("EPA7 ROM");
	    case 0x4020:	return ("Logo2 ROM");
	    case 0x4021:	return ("Logo3 ROM");
	    case 0x4022:	return ("Logo4 ROM");
	    case 0x4023:	return ("Logo5 ROM");
	    case 0x4024:	return ("Logo6 ROM");
	    case 0x4025:	return ("Logo7 ROM");
	    case 0x4026:	return ("FlashROM");
	    case 0x4027:	return ("NNOPROM");
	    case 0x4028:	return ("ROS ROM");
	    
	    /*	ASUS related	*/
	    case 0x5000:	return ("MainBIOS ROM");
	    case 0x6000:	return ("BIOS Editor");
	    case 0x2400:	return ("OnScreen Strings");
	    
	    default:		return ("User-defined ;)");
	    }
}
	    
byte StrLen(byte *Str){ int i=0; while(*(Str+i)!=0x0) i++; return(i); };
byte StrCmp(byte *Dst, byte *Src)
	{
	byte i;

	for( i = 0; i < StrLen(Src); i++ )
		if( Dst[i] != Src[i] ) return(1);
	return(0);
	}


byte *GetFullDate(byte *mon, byte *day, byte *year)
	{
		byte *Months[]={"",
				"January",
				"February",
				"March",
				"April",
				"May",
				"June",
				"July",
				"August",
				"September",
				"October",
				"November",
				"December"};
		byte Buf[20];
		sprintf(Buf,"%2.2s",year);

		if((atoi(Buf)>=0) && (atoi(Buf)<70)) sprintf(Buf,"%.2s %s %s%.2s",day,Months[atoi(mon)],"20",year);
			else sprintf(Buf,"%.2s %s %s%.2s",day,Months[atoi(mon)],"19",year);

                        return(Buf);
	}


byte Compute_Head_CRC(FILE *ptx, dword Offset,byte hdr_size)
	{
                byte CRC = 0, tmp, i;                                           
                                                                                
                fseek(ptx,Offset+2,0);                                          
                for(i=0;i<hdr_size;i++) {                                       
                        fread(&tmp,1,1,ptx);                                    
                        CRC += tmp;                                             
                        }                                                       
                return(CRC);                                                    
        }

/*---------------------------------
	FindHook
----------------------------------*/

dword FoundAt(FILE *ptx, byte *Buf, byte *Pattern, dword BLOCK_LEN)
{

	dword i, Ret;
	word Len;
	Len = StrLen(Pattern);
	for(i=0;i<BLOCK_LEN-0x80;i++){
		if(memcmp(Buf+i,Pattern,Len)==0)
			{
			Ret = ftell(ptx)-(BLOCK_LEN-i);
			return(Ret);
                        }
		}
	/* ---------- No Good, No Positive Result --------*/
	return 0;
}

/*---------------------------------
	XtractAwd
----------------------------------*/
byte XtractAwd(FILE *ptx, byte Action, dword DecoOff, dword FirstOff, byte isASUS)
	{

	FILE *pto;
	interfacing interface;
	byte PartTotal=0, CntMods = 0;
	NewLZHHead head;
	byte Buf[32], Buf2[128], Len = 0xFF;
	dword i, k, CurPos = 0;
	byte SkipMech = 0;

    switch(Action)
	{
	    case List:
	printf("\n");
	printf(
"+-----------------------------------------------------------------------------+\n"
"|  #             Name       Description           FileOffset     Ratio   ID   |\n"
"+-----------------------------------------------------------------------------+\n");
	    break;
	    
	    case Xtract:
	printf("\n");
	printf(
"+-----------------------------------------------------------------------------+\n"
"|  #   Name            Offset   Packed   Real (decimal)  Ratio   MemorySEG    |\n"
"+-----------------------------------------------------------------------------+\n");
	    break;
	}



	/* ---------- Check the size of ROM -------------------------- */

	    if (DecoOff > 0x40000 || isASUS ) SkipMech = 2; else SkipMech = 1;
	    printf("\nHINT: SkipMechanism:\t%X", SkipMech);

	/* ---------- Count down the number of -lh5- modules --------- */
        i = FirstOff;                                                              
        do                                                                  
        {                                                                   
            fseek(ptx, i, 0);                                               

	    /* --------- */
            fread(&head, sizeof(head), 1, ptx);                            
	    /* -------- str differs if !ZERO --------- */
            if(StrCmp( head.Method, "-lh5-" ) ) 
	    {
 		if ( head.HeadLen == 0x0 ) 
		{
		    i+=SkipMech;
		    fseek(ptx, i , 0);
		    fread(&head, sizeof(head), 1, ptx);
		    if(StrCmp( head.Method, "-lh5-" ) ) break;
		} else if ( head. HeadLen == 0xFF ) break;
	    }

            head.FileName[head.FilenameLen] = '\x0';


	switch(Action){
		case List:


                printf("\n  %2.2i (%24.24s) [%16.16s]:", CntMods++, 
							 head.FileName, 
							 GetModuleName(head.TStamp >> 16));
                printf(" %6.6Xh, %2.2i%, %8.8X",
			    i,
                            ( 100 * head.PackLen / head.RealLen),
                            head.TStamp);
		
			break;

		case Xtract:
		/*	Xtracting Part	*/

                printf("\n  %2.2i (%24.24s): ", CntMods++, head.FileName );
                printf(" %5.5X => %6.6X, %2.2i%, ID: %8.8X",            
                            head.PackLen,                                       
                            head.RealLen,
                            ( 100 * head.PackLen / head.RealLen),               
                            head.TStamp);                                       
                                                                                

                memcpy(Buf2,head.FileName,head.FilenameLen);
                Buf2[head.FilenameLen] = '\x0';

		if((pto = fopen(Buf2,"wb")) == NULL) {
			printf("\nFile %s I/O error..Exit",Buf);
			exit(1);
			}

		interface.infile = ptx;
		interface.outfile = pto;
		interface.original = head.RealLen ;
		interface.packed = head.PackLen;

		interface.dicbit = 13;
		interface.method = 5;

		fseek(ptx, -sizeof(head) + head.HeadLen + 2 , 1);
		
		decode(interface);
		fclose(pto);
		
		printf(" ... Ok");


			break;
		/*	End of Xtract	*/

		case XtractM:
		/*	Xtracting Part	*/

                printf("\n  %2.2i (%12.12s): ", CntMods++, head.FileName );
                printf(" %5.5X => %6.6X (%6.6i), %2.2i%, ID: %8.8X",            
                            head.PackLen,                                       
                            head.RealLen,head.RealLen,                          
                            ( 100 * head.PackLen / head.RealLen),               
                            head.TStamp);                                       
                                                                                

		sprintf(Buf,"%.12s.lzh", head.FileName);

		if((pto = fopen(Buf,"wb")) == NULL) {
			printf("\nFile %s I/O error..Exit",Buf);
			exit(1);
			}

		fseek(ptx, -(sizeof(head)), 1);
		for( k=0; k < (head.PackLen+head.HeadLen+2); k++ )
		{
		
		fread (&Buf[0], 1, 1, ptx);
		fwrite(&Buf[0], 1, 1, pto);
	    
		}
		fclose(pto);


			break;
		/*	End of XtractM	*/

		case Copyrights:

	/* ---------- Print BIOS Copyrighted Info --------- */
	if(head.TStamp == 0x50000000)
	{
	    CurPos = ftell(ptx);

	    if(!FirstOff) fseek(ptx, head.HeadLen + 2, 0);

		if((pto = tmpfile()) == NULL) {
			printf("\nFile tmpfile I/O error..Exit");
			exit(1);
			}

		interface.infile = ptx;
		interface.outfile = pto;
		interface.original = head.RealLen ;
		interface.packed = head.PackLen;

		interface.dicbit = 13;
		interface.method = 5;
		decode(interface);

	    /* ------- Move to first (C) ---------- */

	printf("\n+---------------------------------------------------------+");

		fseek(pto, 0x1E060L, 0);
		fread(&Len, sizeof(byte), 1, pto);
		fread(&Buf2, Len, sizeof(byte), pto);
		printf("\n\t%s", Buf2);

		fseek(pto, 0x1E090L, 0);
		fread(&Len, sizeof(byte), 1, pto);
		fread(&Buf2, Len, sizeof(byte), pto);
		printf("\n\t%s", Buf2);

		fseek(pto, 0x1E0C0L, 0);
		fread(&Len, sizeof(byte), 1, pto);
		fread(&Buf2, Len, sizeof(byte), pto);
		printf("\n\t%s", Buf2);

		fseek(pto, 0x1EC70, 0);
		fread(&Len, 1, sizeof(byte), pto);
		fread(&Buf2, Len, sizeof(byte), pto);
		printf("\n\t%s", Buf2);

	printf("\n+---------------------------------------------------------+");

		fclose(pto);

	    fseek(ptx, CurPos, 0);
	}

		/*	Show Copyrights End 	*/
		break;
		}


	    if ( !isASUS && (head.TStamp == 0x50000000) && (CntMods == 1) )
		i+=2;

                i += (head.PackLen + head.HeadLen + 2); 


	} while ( (i < DecoOff) );


		return (CntMods);

	}


byte TotalSecA(FILE *ptx, byte *Buf, byte Action, dword BootBlockOffset)
{
	FILE *pto;
	interfacing interface;
	byte Buffer[12];

	byte Buf2[128];

	dword CurPos = 0;
	dword RealRead = 0, i, TotalRead = 0, Tmp;
	byte Head[] = "-lh5-";
	dword End = 0xFFFFFFFF;
	byte TotalSec = 0;
	NewLZHHead awdhead;


    switch(Action)
	{
	    case ListA:
	printf("\n");
	printf(
"+-----------------------------------------------------------------------------+\n"
"|  #                 Name          Description    FileOffset   Ratio  ID      |\n"
"+-----------------------------------------------------------------------------+\n");
	    break;
	    
	    case XtractA:
	printf("\n");
	printf(
"+-----------------------------------------------------------------------------+\n"
"|  #   Name            Offset   Packed   Real (decimal)  Ratio   MemorySEG    |\n"
"+-----------------------------------------------------------------------------+\n");
	    break;
	}

	fseek(ptx,0,2); End = ftell(ptx); rewind(ptx);
	
	while( (!feof(ptx)) || (CurPos > BootBlockOffset) )
	{
			fseek(ptx, CurPos, 0);
			
			RealRead = fread(Buf,1,BLOCK,ptx);
			TotalRead += RealRead;

			if( RealRead != BLOCK )
			    {
				for( i = RealRead; i < BLOCK; i++) Buf[i] = 0xFF; 
			    }
			    
			if(RealRead < 0x80) break;

			if( (CurPos = FoundAt(ptx, Buf, Head, RealRead)) !=0 )
			{
				fseek(ptx, CurPos - 2, 0);
				TotalSec++;
				fread(&awdhead,1,sizeof(awdhead),ptx);
				awdhead.FileName[awdhead.FilenameLen] = '\x0';
				
	///////////////////////////////
	// switch action
	///////////////////////////////
	
	switch(Action)
	{
		case ListA:


                printf("\n  %2.2i (%24.24s) [%16.16s]:", TotalSec, 
							 awdhead.FileName, 
							 GetModuleName(awdhead.TStamp >> 16));
                printf(" %6.6Xh, %2.2i%, %8.8X",
			    CurPos - 2,
                            ( 100 * awdhead.PackLen / awdhead.RealLen),
                            awdhead.TStamp);
		
			break;

		case XtractA:
		/*	Xtracting Part	*/


                printf("\n  %2.2i (%24.24s): ", TotalSec, awdhead.FileName );
                printf(" %5.5X => %6.6X, %2.2i%, ID: %8.8X",
                            awdhead.PackLen,
                            awdhead.RealLen,
                            ( 100 * awdhead.PackLen / awdhead.RealLen),
                            awdhead.TStamp);
                                                                                

                memcpy(Buf2, awdhead.FileName, awdhead.FilenameLen);
                Buf2[awdhead.FilenameLen] = '\x0';

		if((pto = fopen(Buf2, "wb")) == NULL) {
			printf("\nFile %s I/O error..Exit", Buf);
			exit(1);
			}

		interface.infile = ptx;
		interface.outfile = pto;
		interface.original = awdhead.RealLen ;
		interface.packed = awdhead.PackLen;

		interface.dicbit = 13;
		interface.method = 5;

		fseek(ptx, -sizeof(awdhead) + awdhead.HeadLen + 2 , 1);
		
		decode(interface);
		fclose(pto);
		
		printf(" ... Ok");


			break;
			
		/*	End of Xtract	*/

	}
	//////////////////////////////
	///
	//////////////////////////////
				
				
				CurPos += awdhead.PackLen;
				
			} else CurPos = ftell(ptx);
			
	}


		return(TotalSec);
}

#endif
