#include <exec/types.h>
#include <dos/dos.h>

struct Key
{
   UBYTE Product[10];
   UBYTE Junk1[10];
   UBYTE Name[50];
   UBYTE Junk[182];
   ULONG Serial;
};

struct Key key;
UBYTE *keybuf;

ULONG checksums[16];
UBYTE *longbuf;

ULONG Checksum9(void)
{
   ULONG rol,c;

   rol=0;

   for(c=0;c<sizeof(struct Key);c++)
      if(c<70 || c>=252 || c%2==0)
      {
         rol|=1;
         rol<<=keybuf[c]%4;
      }

   return(rol);
}

ULONG Checksum11(void)
{
   ULONG bit3,c;

   bit3=0;

   for(c=0;c<sizeof(struct Key);c++)
      if(c<70 || c>=252 || c%2==0)
      {
         bit3|=keybuf[c]+c & 0x0f0f0f0f;
         bit3<<=2;
      }

   return(bit3);
}

ULONG Checksum13(void)
{
   ULONG zm2,c;

   zm2=0;

   for(c=0;c<sizeof(struct Key);c++)
      if(c<70 || c>=252 || c%2==0)
      {
         zm2^=c*(keybuf[c]+c);
         zm2<<=c%3;
      }

   return(zm2);
}

main(int argc, char **argv)
{
   ULONG c;
   UBYTE xor,newxor;
   BPTR fh;

   if(!(fh=Open(argv[1],MODE_OLDFILE)))
   {
      Printf("Unable to open %s for reading\n",argv[1]);
      exit(10);
   }

   Read(fh,&key,sizeof(struct Key));
   Close(fh);

   keybuf=(UBYTE *)&key;

   xor=255;

   for(c=0;c<sizeof(struct Key);c++)
   {
      newxor=keybuf[c];
      keybuf[c]^=xor;
      xor=newxor;
   }

   longbuf=(UBYTE *)checksums;

   for(c=0;c<4*16;c++)
      longbuf[c]=keybuf[70+c*2+1];

   Printf("\n");

   Printf("Product: %s\n",key.Product);
   Printf("   Name: %s\n",key.Name);
   Printf(" Number: %lu\n",key.Serial);

   Printf("\n");

   if(Checksum9()!=checksums[9])
      Printf("Wrong checksum #9\n");
   else
      Printf("Checksum #9 ok\n");

   if(Checksum11()!=checksums[11])
      Printf("Wrong checksum #11\n");
   else
      Printf("Checksum #11 ok\n");

   if(Checksum13()!=checksums[13])
      Printf("Wrong checksum #13\n");
   else
      Printf("Checksum #13 ok\n");

   Printf("\n");

   exit(10);
}
