Beispiel #1
0
struct quad_stage *sp_quad_shade_stage( struct softpipe_context *softpipe )
{
   struct quad_shade_stage *qss = CALLOC_STRUCT(quad_shade_stage);
   uint i;

   /* allocate storage for program inputs/outputs, aligned to 16 bytes */
   qss->inputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->inputs) + 16);
   qss->outputs = MALLOC(PIPE_MAX_ATTRIBS * sizeof(*qss->outputs) + 16);
   qss->machine.Inputs = align16(qss->inputs);
   qss->machine.Outputs = align16(qss->outputs);

   qss->stage.softpipe = softpipe;
   qss->stage.begin = shade_begin;
   qss->stage.run = shade_quad;
   qss->stage.destroy = shade_destroy;

   /* set TGSI sampler state that's constant */
   for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
      assert(softpipe->tex_cache[i]);
      qss->samplers[i].get_samples = sp_get_samples;
      qss->samplers[i].pipe = &softpipe->pipe;
      qss->samplers[i].cache = softpipe->tex_cache[i];
   }

   tgsi_exec_machine_init( &qss->machine );

   return &qss->stage;
}
Beispiel #2
0
    void q_atomic_lock(int *lock)
    {
        // ldcw requires a 16-byte aligned address
        volatile int *x = align16(lock);
        while (q_ldcw(x) == 0)
	    ;
    }
Beispiel #3
0
static char *portaddr2str(struct PortAddress *addr)
{
	static char buf[BIN_BUF_SIZE];
	switch(align16(&addr->networkProtocol)) {
	case TRANS_UDP_IPV4:
		if (align16(&addr->addressLength) == 4
			&& inet_ntop(AF_INET, addr->address, buf, sizeof(buf)))
			return buf;
		break;
	case TRANS_UDP_IPV6:
		if (align16(&addr->addressLength) == 16
			&& inet_ntop(AF_INET6, addr->address, buf, sizeof(buf)))
			return buf;
		break;
	}
	bin2str_impl(addr->address, align16(&addr->addressLength), buf, sizeof(buf));
	return buf;
}
Beispiel #4
0
static ucell *aligncell(ucell *v)
{
  if (pc_cellsize==2)
    return align16(v);
  if (pc_cellsize==4)
    return align32(v);
  #if PAWN_CELL_SIZE>=64
    if (pc_cellsize==8)
      return align64(v);
  #endif
  assert(0);
}
Beispiel #5
0
int SavedataParam::UpdateHash(u8* sfoData, int sfoSize, int sfoDataParamsOffset, int encryptmode)
{
	int alignedLen = align16(sfoSize);
	memset(sfoData+sfoDataParamsOffset, 0, 128);
	u8 filehash[16];
	int ret = 0;

	/* Compute 11D0 hash over entire file */
	if ((ret = BuildHash(filehash, sfoData, sfoSize, alignedLen, (encryptmode & 2) ? 4 : 2, NULL)) < 0)
	{	// Not sure about "2"
		return ret - 400;
	}

	/* Copy 11D0 hash to param.sfo and set flag indicating it's there */
	memcpy(sfoData+sfoDataParamsOffset + 0x20, filehash, 0x10);
	*(sfoData+sfoDataParamsOffset) |= 0x01;

	/* If new encryption mode, compute and insert the 1220 hash. */
	if (encryptmode & 2)
	{

		/* Enable the hash bit first */
		*(sfoData+sfoDataParamsOffset) |= 0x20;

		if ((ret = BuildHash(filehash, sfoData, sfoSize, alignedLen, 3, 0)) < 0)
		{
			return ret - 500;
		}
		memcpy(sfoData+sfoDataParamsOffset + 0x70, filehash, 0x10);
	}

	/* Compute and insert the 11C0 hash. */
	if ((ret = BuildHash(filehash, sfoData, sfoSize, alignedLen, 1, 0)) < 0)
	{
		return ret - 600;
	}
	memcpy(sfoData+sfoDataParamsOffset + 0x10, filehash, 0x10);

	/* All done. */
	return 0;
}
Beispiel #6
0
/* Read, decrypt, and write a savedata file.  See main.c for example usage. */
int decrypt_file(const char *decrypted_filename,
		 const char *encrypted_filename,
		 const unsigned char *gamekey)
{
	FILE *in, *out;
	int len, aligned_len;
	unsigned char *data, *cryptkey;
	int retval;

	/* Open file and get size */

	if ((in = fopen(encrypted_filename, "r")) == NULL) {
		retval = -1;
		goto out;
	}

	fseek(in, 0, SEEK_END);
	len = ftell(in);
	fseek(in, 0, SEEK_SET);

	if (len <= 0) {
		retval = -2;
		goto out1;
	}

	/* Allocate buffers */

	aligned_len = align16(len);

	if ((data = (unsigned char *) memalign(0x10, aligned_len)) == NULL) {
		retval = -3;
		goto out1;
	}

	if ((cryptkey = (unsigned char *) memalign(0x10, 0x10)) == NULL) {
		retval = -4;
		goto out2;
	}

	/* Fill buffers */

	if (gamekey != NULL)
		memcpy(cryptkey, gamekey, 0x10);

	memset(data + len, 0, aligned_len - len);
	if (fread(data, 1, len, in) != len) {
		retval = -5;
		goto out3;
	}

	/* Do the decryption */

	if ((retval = decrypt_data( gamekey ? 3 : 1,
				    data, &len, &aligned_len,
				    gamekey ? cryptkey : NULL)) < 0) {
		retval -= 100;
		goto out3;
	}

	/* Write the data out.  decrypt_data has set len correctly. */

	if ((out = fopen(decrypted_filename, "w")) == NULL) {
		retval = -6;
		goto out3;
	}

	if (fwrite(data, 1, len, out) != len) {
		retval = -7;
		goto out4;
	}

	/* All done.  Return file length. */
	retval = len;
 out4:
	fclose(out);
 out3:
	free(cryptkey);
 out2:
	free(data);
 out1:
	fclose(in);
 out:
	return retval;
}
Beispiel #7
0
void parse_pe(struct aout *a, const char *buf, int len)
{
	int ad, i;
	PIMAGE_FILE_HEADER ph1;
	PIMAGE_OPTIONAL_HEADER32 ph2;
	PIMAGE_SECTION_HEADER sh;
	
	if (len < 0x40)
	{
		printf("FILE IS TOO SHORT: %d < %d\n", len, 0x40);
		return;
	}
	
	if (buf[0] != 'M' || buf[1] != 'Z')
	{
		printf("%08x: BAD SIGNATURE: %02x %02x (must be %02x %02x)\n",
			0, buf[0], buf[1], 'M', 'Z');
		return;
	}
	
	ad = *(int *)&buf[0x3c];
	if (ad < 0 || ad + 4 + sizeof(*ph1) + sizeof(*ph2) > len)
	{
		printf("FILE IS TOO SHORT: %08x < %08x\n", len, ad);
		return;
	}
	
	if (buf[ad] != 'P' || buf[ad + 1] != 'E')
	{
		printf("%08x: BAD SIGNATURE: %02x %02x (must be %02x %02x)\n",
			ad, buf[ad], buf[ad + 1], 'P', 'E');
		return;
	}
	ad += 4;
	
	ph1 = (PIMAGE_FILE_HEADER)&buf[ad];
	ad += sizeof(*ph1);
	
	ph2 = (PIMAGE_OPTIONAL_HEADER32)&buf[ad];
	ad += sizeof(*ph2);
	
	for (i = 0; i < ph1->NumberOfSections; i++)
	{
		char name[9];
		sh = (PIMAGE_SECTION_HEADER)&buf[ad];
		strncpy(name, sh->Name, 8);
		if (strcmp(name, ".text") == 0)
		{
			if (sh->VirtualAddress > 0x1000)
			{
				printf(".TEXT IS TOO FAR: %08x > 00001000\n", sh->VirtualAddress);
				return;
			}
			a->textvad = sh->VirtualAddress;
			a->textpos = sh->PointerToRawData;
			a->textlen = sh->VirtualSize;
			a->header.a_entry = ph2->AddressOfEntryPoint;
			a->header.a_text = a->textvad + align16(a->textlen);
		}
		else if (strcmp(name, ".data") == 0)
		{
			a->datavad = sh->VirtualAddress;
			a->datapos = sh->PointerToRawData;
			a->datalen = sh->VirtualSize;
			a->header.a_text = a->datavad;
			a->header.a_data = align16(a->datalen);
		}
		else if (strcmp(name, ".rdata") == 0)
		{
			a->rdatavad = sh->VirtualAddress;
			a->rdatapos = sh->PointerToRawData;
			a->rdatalen = sh->VirtualSize;
			if (a->datalen == 0)
			{
				a->header.a_text = a->rdatavad;
				a->header.a_data = align16(a->rdatalen);
			}
			else
				a->header.a_data = align16((a->rdatavad - a->datavad) + a->rdatalen);
		}
		else if (strcmp(name, ".bss") == 0)
		{
			a->header.a_bss = align16(sh->VirtualSize);
			if (a->datalen == 0 && a->rdatalen == 0)
				a->header.a_text = sh->VirtualAddress;
			else if (a->datalen == 0)
				a->header.a_data = sh->VirtualAddress - a->rdatavad;
			else
				a->header.a_data = sh->VirtualAddress - a->datavad;
		}
#if 0
		else if (strcmp(name, ".idata") == 0)
		{
			printf("CAN NOT IMPORT DLL!\n");
			a->header.a_text = 0;
			return;
		}
#endif
		ad += sizeof(*sh);
	}
	a->header.a_total += A_SYMPOS(a->header) - a->header.a_hdrlen;
}
Beispiel #8
0
SC_FUNC int assemble(FILE *fout,FILE *fin)
{
  AMX_HEADER hdr;
  AMX_FUNCSTUB func;
  int numpublics,numnatives,numoverlays,numlibraries,numpubvars,numtags;
  int padding;
  long nametablesize,nameofs;
  char line[512];
  char *instr,*params;
  int i,pass,size;
  int16_t count;
  symbol *sym;
  symbol **nativelist;
  constvalue *constptr;
  cell mainaddr;
  char nullchar;

  #if !defined NDEBUG
    /* verify that the opcode list is sorted (skip entry 1; it is reserved
     * for a non-existant opcode)
     */
    {
      #define MAX_OPCODE 176
      unsigned char opcodearray[MAX_OPCODE+1];
      assert(opcodelist[1].name!=NULL);
      memset(opcodearray,0,sizeof opcodearray);
      for (i=2; i<(sizeof opcodelist / sizeof opcodelist[0]); i++) {
        assert(opcodelist[i].name!=NULL);
        assert(stricmp(opcodelist[i].name,opcodelist[i-1].name)>0);
        /* also verify that no opcode number appears twice */
        assert((int)opcodelist[i].opcode<=MAX_OPCODE);
        assert(opcodelist[i].opcode==0 || opcodearray[(int)opcodelist[i].opcode]==0);
        opcodearray[(int)opcodelist[i].opcode] += 1;
      } /* for */
    }
  #endif

  writeerror=FALSE;
  nametablesize=sizeof(int16_t);
  numpublics=0;
  numnatives=0;
  numpubvars=0;
  numoverlays=0;
  mainaddr=-1;
  /* count number of public and native functions and public variables */
  for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
    int match=0;
    if (sym->ident==iFUNCTN) {
      if ((sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->index>=0)
        match=++numnatives;
      if ((sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0)
        match=++numpublics;
      if (pc_overlays>0 && (sym->usage & uNATIVE)==0
          && (sym->usage & (uREAD | uPUBLIC))!=0 && (sym->usage & uDEFINE)!=0)
      {
        if (strcmp(sym->name,uENTRYFUNC)!=0)
          ++numoverlays;  /* there is no stub function for state entry functions */
        if (sym->states!=NULL) {
          /* for functions with states, write an overlay block for every implementation */
          statelist *stlist;
          for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next)
            ++numoverlays;
        } /* if */
      } /* if */
      if (strcmp(sym->name,uMAINFUNC)==0) {
        assert(sym->vclass==sGLOBAL);
        mainaddr=(pc_overlays>0) ? sym->index : sym->addr;
      } /* if */
    } else if (sym->ident==iVARIABLE) {
      if ((sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0)
        match=++numpubvars;
    } /* if */
    if (match) {
      char alias[sNAMEMAX+1];
      assert(sym!=NULL);
      if ((sym->usage & uNATIVE)==0 || !lookup_alias(alias,sym->name)) {
        assert(strlen(sym->name)<=sNAMEMAX);
        strcpy(alias,sym->name);
      } /* if */
      nametablesize+=(int)strlen(alias)+1;
    } /* if */
  } /* for */
  assert(numnatives==ntv_funcid);

  /* count number of libraries */
  numlibraries=0;
  if (pc_addlibtable) {
    for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) {
      if (constptr->value>0) {
        assert(strlen(constptr->name)>0);
        numlibraries++;
        nametablesize+=(int)strlen(constptr->name)+1;
      } /* if */
    } /* for */
  } /* if */

  /* count number of public tags */
  numtags=0;
  for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
    if ((constptr->value & PUBLICTAG)!=0) {
      assert(strlen(constptr->name)>0);
      numtags++;
      nametablesize+=(int)strlen(constptr->name)+1;
    } /* if */
  } /* for */

  /* adjust the number of overlays by the special overlays */
  if (pc_overlays>0)
    for (i=0; i<ovlFIRST; i++)
      if (pc_ovl0size[i][1]!=0)
        numoverlays++;

  /* pad the header to sc_dataalign
   * => thereby the code segment is aligned
   * => since the code segment is padded to a sc_dataalign boundary, the data segment is aligned
   * => and thereby the stack top is aligned too
   */
  assert(sc_dataalign!=0);
  padding= (int)(sc_dataalign - (sizeof hdr + nametablesize) % sc_dataalign);
  if (padding==sc_dataalign)
    padding=0;

  /* write the abstract machine header */
  memset(&hdr, 0, sizeof hdr);
  if (pc_cellsize==2)
    hdr.magic=(unsigned short)AMX_MAGIC_16;
  else if (pc_cellsize==4)
    hdr.magic=(unsigned short)AMX_MAGIC_32;
  else if (pc_cellsize==8)
    hdr.magic=(unsigned short)AMX_MAGIC_64;
  hdr.file_version=CUR_FILE_VERSION;
  hdr.amx_version=MIN_AMX_VERSION;
  hdr.flags=(short)(sc_debug & sSYMBOLIC);
  if (sc_debug==0)
    hdr.flags|=AMX_FLAG_NOCHECKS;
  if (pc_memflags & suSLEEP_INSTR)
    hdr.flags|=AMX_FLAG_SLEEP;
  if (pc_overlays>0)
    hdr.flags|=AMX_FLAG_OVERLAY;
  if (pc_cryptkey!=0)
    hdr.flags|=AMX_FLAG_CRYPT;
  hdr.defsize=sizeof(AMX_FUNCSTUB);
  hdr.publics=sizeof hdr; /* public table starts right after the header */
  hdr.natives=hdr.publics + numpublics*sizeof(AMX_FUNCSTUB);
  hdr.libraries=hdr.natives + numnatives*sizeof(AMX_FUNCSTUB);
  hdr.pubvars=hdr.libraries + numlibraries*sizeof(AMX_FUNCSTUB);
  hdr.tags=hdr.pubvars + numpubvars*sizeof(AMX_FUNCSTUB);
  hdr.overlays=hdr.tags + numtags*sizeof(AMX_FUNCSTUB);
  hdr.nametable=hdr.overlays + numoverlays*sizeof(AMX_OVERLAYINFO);
  hdr.cod=hdr.nametable + nametablesize + padding;
  hdr.dat=(int32_t)(hdr.cod + code_idx);
  hdr.hea=(int32_t)(hdr.dat + glb_declared*pc_cellsize);
  hdr.stp=(int32_t)(hdr.hea + pc_stksize*pc_cellsize);
  hdr.cip=(int32_t)(mainaddr);
  hdr.size=hdr.hea;
  pc_writebin(fout,&hdr,sizeof hdr);

  /* dump zeros up to the rest of the header, so that we can easily "seek" */
  nullchar='\0';
  for (nameofs=sizeof hdr; nameofs<hdr.cod; nameofs++)
    pc_writebin(fout,&nullchar,1);
  nameofs=hdr.nametable+sizeof(int16_t);

  /* write the public functions table */
  count=0;
  for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
    if (sym->ident==iFUNCTN
        && (sym->usage & uPUBLIC)!=0 && (sym->usage & uDEFINE)!=0)
    {
      assert(sym->vclass==sGLOBAL);
      /* in the case of overlays, write the overlay index rather than the address */
      func.address=(uint32_t)((pc_overlays>0) ? sym->index : sym->addr);
      func.nameofs=nameofs;
      #if BYTE_ORDER==BIG_ENDIAN
        align32(&func.address);
        align32(&func.nameofs);
      #endif
      pc_resetbin(fout,hdr.publics+count*sizeof(AMX_FUNCSTUB));
      pc_writebin(fout,&func,sizeof func);
      pc_resetbin(fout,nameofs);
      pc_writebin(fout,sym->name,(int)strlen(sym->name)+1);
      nameofs+=(int)strlen(sym->name)+1;
      count++;
    } /* if */
  } /* for */

  /* write the natives table */
  /* The native functions must be written in sorted order. (They are
   * sorted on their "id", not on their name). A nested loop to find
   * each successive function would be an O(n^2) operation. But we
   * do not really need to sort, because the native function id's
   * are sequential and there are no duplicates. So we first walk
   * through the complete symbol list and store a pointer to every
   * native function of interest in a temporary table, where its id
   * serves as the index in the table. Now we can walk the table and
   * have all native functions in sorted order.
   */
  if (numnatives>0) {
    nativelist=(symbol **)malloc(numnatives*sizeof(symbol *));
    if (nativelist==NULL)
      error(103);               /* insufficient memory */
    #if !defined NDEBUG
      memset(nativelist,0,numnatives*sizeof(symbol *)); /* for NULL checking */
    #endif
    for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
      if (sym->ident==iFUNCTN && (sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)!=0 && sym->index>=0) {
        assert(sym->index < numnatives);
        nativelist[(int)sym->index]=sym;
      } /* if */
    } /* for */
    count=0;
    for (i=0; i<numnatives; i++) {
      char alias[sNAMEMAX+1];
      sym=nativelist[i];
      assert(sym!=NULL);
      if (!lookup_alias(alias,sym->name)) {
        assert(strlen(sym->name)<=sNAMEMAX);
        strcpy(alias,sym->name);
      } /* if */
      assert(sym->vclass==sGLOBAL);
      func.address=0;
      func.nameofs=nameofs;
      #if BYTE_ORDER==BIG_ENDIAN
        align32(&func.address);
        align32(&func.nameofs);
      #endif
      pc_resetbin(fout,hdr.natives+count*sizeof(AMX_FUNCSTUB));
      pc_writebin(fout,&func,sizeof func);
      pc_resetbin(fout,nameofs);
      pc_writebin(fout,alias,(int)strlen(alias)+1);
      nameofs+=(int)strlen(alias)+1;
      count++;
    } /* for */
    free(nativelist);
  } /* if */

  /* write the libraries table */
  if (pc_addlibtable) {
    count=0;
    for (constptr=libname_tab.next; constptr!=NULL; constptr=constptr->next) {
      if (constptr->value>0) {
        assert(strlen(constptr->name)>0);
        func.address=0;
        func.nameofs=nameofs;
        #if BYTE_ORDER==BIG_ENDIAN
          align32(&func.address);
          align32(&func.nameofs);
        #endif
        pc_resetbin(fout,hdr.libraries+count*sizeof(AMX_FUNCSTUB));
        pc_writebin(fout,&func,sizeof func);
        pc_resetbin(fout,nameofs);
        pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1);
        nameofs+=(int)strlen(constptr->name)+1;
        count++;
      } /* if */
    } /* for */
  } /* if */

  /* write the public variables table */
  count=0;
  for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
    if (sym->ident==iVARIABLE && (sym->usage & uPUBLIC)!=0 && (sym->usage & (uREAD | uWRITTEN))!=0) {
      assert((sym->usage & uDEFINE)!=0);
      assert(sym->vclass==sGLOBAL);
      func.address=(uint32_t)sym->addr;
      func.nameofs=nameofs;
      #if BYTE_ORDER==BIG_ENDIAN
        align32(&func.address);
        align32(&func.nameofs);
      #endif
      pc_resetbin(fout,hdr.pubvars+count*sizeof(AMX_FUNCSTUB));
      pc_writebin(fout,&func,sizeof func);
      pc_resetbin(fout,nameofs);
      pc_writebin(fout,sym->name,(int)strlen(sym->name)+1);
      nameofs+=(int)strlen(sym->name)+1;
      count++;
    } /* if */
  } /* for */

  /* write the public tagnames table */
  count=0;
  for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
    if ((constptr->value & PUBLICTAG)!=0) {
      assert(strlen(constptr->name)>0);
      func.address=(uint32_t)(constptr->value & TAGMASK);
      func.nameofs=nameofs;
      #if BYTE_ORDER==BIG_ENDIAN
        align32(&func.address);
        align32(&func.nameofs);
      #endif
      pc_resetbin(fout,hdr.tags+count*sizeof(AMX_FUNCSTUB));
      pc_writebin(fout,&func,sizeof func);
      pc_resetbin(fout,nameofs);
      pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1);
      nameofs+=(int)strlen(constptr->name)+1;
      count++;
    } /* if */
  } /* for */

  /* write the "maximum name length" field in the name table */
  assert(nameofs==hdr.nametable+nametablesize);
  pc_resetbin(fout,hdr.nametable);
  count=sNAMEMAX;
  #if BYTE_ORDER==BIG_ENDIAN
    align16(&count);
  #endif
  pc_writebin(fout,&count,sizeof count);

  /* write the overlay table */
  if (pc_overlays>0) {
    AMX_OVERLAYINFO info;
    #if !defined NDEBUG
      int count=0;
    #endif
    pc_resetbin(fout,hdr.overlays);
    /* first the special overlay(s) for the return point(s) */
    for (i=0; i<ovlFIRST; i++) {
      if (pc_ovl0size[i][1]!=0) {
        info.offset=pc_ovl0size[i][0];
        info.size=pc_ovl0size[i][1];
        #if BYTE_ORDER==BIG_ENDIAN
          align32(&info.offset);
          align32(&info.size);
        #endif
        pc_writebin(fout,&info,sizeof info);
        #if !defined NDEBUG
          count++;
        #endif
      } /* if */
    } /* for */
    /* now all real overlay functions */
    for (sym=glbtab.next; sym!=NULL; sym=sym->next) {
      if (sym->ident==iFUNCTN
          && (sym->usage & uNATIVE)==0 && (sym->usage & (uREAD | uPUBLIC))!=0
          && (sym->usage & uDEFINE)!=0)
      {
        assert(sym->vclass==sGLOBAL);
        assert(strcmp(sym->name,uENTRYFUNC)==0 || sym->index==count++);/* overlay indices must be in sequential order */
        assert(strcmp(sym->name,uENTRYFUNC)==0 || sym->addr<sym->codeaddr);
        /* write the overlay for the stub function first */
        if (strcmp(sym->name,uENTRYFUNC)!=0) {
          /* there is no stub function for state entry functions */
          info.offset=(int32_t)sym->addr;
          info.size=(uint32_t)(sym->codeaddr - sym->addr);
          #if BYTE_ORDER==BIG_ENDIAN
            align32(&info.offset);
            align32(&info.size);
          #endif
          pc_writebin(fout,&info,sizeof info);
        } /* if */
        if (sym->states!=NULL) {
          /* for functions with states, write an overlay block for every implementation */
          statelist *stlist;
          for (stlist=sym->states->next; stlist!=NULL; stlist=stlist->next) {
            assert(stlist->label==count++);
            info.offset=(int32_t)stlist->addr;
            info.size=(int32_t)(stlist->endaddr - stlist->addr);
            #if BYTE_ORDER==BIG_ENDIAN
              align32(&info.offset);
              align32(&info.size);
            #endif
            pc_writebin(fout,&info,sizeof info);
          } /* for */
        } /* if */
      } /* if */
    } /* for */
  } /* if */
  pc_resetbin(fout,hdr.cod);

  /* First pass: relocate all labels */
  /* This pass is necessary because the code addresses of labels is only known
   * after the peephole optimization flag. Labels can occur inside expressions
   * (e.g. the conditional operator), which are optimized.
   */
  lbltab=NULL;
  if (sc_labnum>0) {
    cell codeindex=0; /* address of the current opcode similar to "code_idx" */
    /* only very short programs have zero labels; no first pass is needed
     * if there are no labels */
    lbltab=(cell *)malloc(sc_labnum*sizeof(cell));
    if (lbltab==NULL)
      error(103);               /* insufficient memory */
    memset(lbltab,0,sc_labnum*sizeof(cell));
    pc_resetasm(fin);
    while (pc_readasm(fin,line,sizeof line)!=NULL) {
      stripcomment(line);
      instr=skipwhitespace(line);
      /* ignore empty lines */
      if (*instr=='\0')
        continue;
      if (tolower(*instr)=='l' && *(instr+1)=='.') {
        int lindex=(int)hex2ucell(instr+2,NULL);
        assert(lindex>=0 && lindex<sc_labnum);
        assert(lbltab[lindex]==0);  /* should not already be declared */
        lbltab[lindex]=codeindex;
      } else {
        /* get to the end of the instruction (make use of the '\n' that fgets()
         * added at the end of the line; this way we will *always* drop on a
         * whitespace character) */
        for (params=instr; *params!='\0' && !isspace(*params); params++)
          /* nothing */;
        assert(params>instr);
        i=findopcode(instr,(int)(params-instr));
        assert(opcodelist[i].name!=NULL);
        assert(opcodelist[i].opt_level<=pc_optimize || pc_optimize==0 && opcodelist[i].opt_level<=1);
        if (opcodelist[i].segment==sIN_CSEG)
          codeindex+=opcodelist[i].func(NULL,skipwhitespace(params),opcodelist[i].opcode,codeindex);
      } /* if */
    } /* while */
  } /* if */

  /* Second pass (actually 2 more passes, one for all code and one for all data) */
  for (pass=sIN_CSEG; pass<=sIN_DSEG; pass++) {
    cell codeindex=0; /* address of the current opcode similar to "code_idx" */
    pc_resetasm(fin);
    while (pc_readasm(fin,line,sizeof line)!=NULL) {
      stripcomment(line);
      instr=skipwhitespace(line);
      /* ignore empty lines and labels (labels have a special syntax, so these
       * must be parsed separately) */
      if (*instr=='\0' || tolower(*instr)=='l' && *(instr+1)=='.')
        continue;
      /* get to the end of the instruction (make use of the '\n' that fgets()
       * added at the end of the line; this way we will *always* drop on a
       * whitespace character) */
      for (params=instr; *params!='\0' && !isspace(*params); params++)
        /* nothing */;
      assert(params>instr);
      i=findopcode(instr,(int)(params-instr));
      assert(opcodelist[i].name!=NULL);
      assert(opcodelist[i].opt_level<=pc_optimize || pc_optimize==0 && opcodelist[i].opt_level<=1);
      if (opcodelist[i].segment==pass)
        codeindex+=opcodelist[i].func(fout,skipwhitespace(params),opcodelist[i].opcode,codeindex);
    } /* while */
  } /* for */

  if (lbltab!=NULL) {
    free(lbltab);
    #if !defined NDEBUG
      lbltab=NULL;
    #endif
  } /* if */

  assert(hdr.size==pc_lengthbin(fout));
  if (!writeerror && (sc_debug & sSYMBOLIC)!=0)
    append_dbginfo(fout);       /* optionally append debug file */

  if (writeerror)
    error(101,"disk full");

  /* adjust the header (for Big Endian architectures) */
  size=(int)hdr.cod;    /* save, the value in the header may need to be swapped */
  #if BYTE_ORDER==BIG_ENDIAN
    align32(&hdr.size);
    align16(&hdr.magic);
    align16(&hdr.flags);
    align16(&hdr.defsize);
    align32(&hdr.publics);
    align32(&hdr.natives);
    align32(&hdr.libraries);
    align32(&hdr.pubvars);
    align32(&hdr.tags);
    align32(&hdr.nametable);
    align32(&hdr.cod);
    align32(&hdr.dat);
    align32(&hdr.hea);
    align32(&hdr.stp);
    align32(&hdr.cip);
    pc_resetbin(fout,0);
    pc_writebin(fout,&hdr,sizeof hdr);
  #endif

  /* return the size of the header (including name tables, but excluding code
   * or data sections)
   */
  return size;
}
Beispiel #9
0
static void append_dbginfo(FILE *fout)
{
  AMX_DBG_HDR dbghdr;
  AMX_DBG_LINE dbgline;
  AMX_DBG_SYMBOL dbgsym;
  AMX_DBG_SYMDIM dbgidxtag[sDIMEN_MAX];
  int index,dim,dbgsymdim;
  const char *str,*prevstr,*name,*prevname;
  ucell codeidx,previdx;
  constvalue *constptr;
  char symname[2*sNAMEMAX+16];
  int16_t id1,id2;
  ucell address;

  /* header with general information */
  memset(&dbghdr, 0, sizeof dbghdr);
  dbghdr.size=sizeof dbghdr;
  dbghdr.magic=AMX_DBG_MAGIC;
  dbghdr.file_version=CUR_FILE_VERSION;
  dbghdr.amx_version=MIN_AMX_VERSION;

  /* first pass: collect the number of items in various tables */

  /* file table */
  previdx=0;
  prevstr=NULL;
  prevname=NULL;
  for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
    assert(str!=NULL);
    assert(str[0]!='\0' && str[1]==':');
    if (str[0]=='F') {
      codeidx=hex2ucell(str+2,&name);
      if (codeidx!=previdx) {
        if (prevstr!=NULL) {
          assert(prevname!=NULL);
          dbghdr.files++;
          dbghdr.size+=(int32_t)(sizeof(AMX_DBG_FILE)+strlen(prevname));
        } /* if */
        previdx=codeidx;
      } /* if */
      prevstr=str;
      prevname=skipwhitespace(name);
    } /* if */
  } /* for */
  if (prevstr!=NULL) {
    assert(prevname!=NULL);
    dbghdr.files++;
    dbghdr.size+=(int32_t)(sizeof(AMX_DBG_FILE)+strlen(prevname));
  } /* if */

  /* line number table */
  for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
    assert(str!=NULL);
    assert(str[0]!='\0' && str[1]==':');
    if (str[0]=='L') {
      dbghdr.lines++;
      dbghdr.size+=sizeof(AMX_DBG_LINE);
    } /* if */
  } /* for */

  /* symbol table */
  for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
    assert(str!=NULL);
    assert(str[0]!='\0' && str[1]==':');
    if (str[0]=='S') {
      dbghdr.symbols++;
      str=strchr(str+2,':');
      assert(str!=NULL);
      name=skipwhitespace(str+1);
      str=strchr(name,' ');
      assert(str!=NULL);
      assert((int)(str-name)<sizeof symname);
      strlcpy(symname,name,(int)(str-name)+1);
      dbghdr.size+=(int32_t)(sizeof(AMX_DBG_SYMBOL)+strlen(symname));
      if ((prevstr=strchr(name,'['))!=NULL)
        while ((prevstr=strchr(prevstr+1,':'))!=NULL)
          dbghdr.size+=sizeof(AMX_DBG_SYMDIM);
    } /* if */
  } /* for */

  /* tag table */
  for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
    assert(strlen(constptr->name)>0);
    dbghdr.tags++;
    dbghdr.size+=(int32_t)(sizeof(AMX_DBG_TAG)+strlen(constptr->name));
  } /* for */

  /* automaton table */
  for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) {
    assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0);
    dbghdr.automatons++;
    dbghdr.size+=(int32_t)(sizeof(AMX_DBG_MACHINE)+strlen(constptr->name));
  } /* for */

  /* state table */
  for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) {
    assert(strlen(constptr->name)>0);
    dbghdr.states++;
    dbghdr.size+=(int32_t)(sizeof(AMX_DBG_STATE)+strlen(constptr->name));
  } /* for */


  /* pass 2: generate the tables */
  #if BYTE_ORDER==BIG_ENDIAN
    align32((uint32_t*)&dbghdr.size);
    align16(&dbghdr.magic);
    align16(&dbghdr.flags);
    align16(&dbghdr.files);
    align16(&dbghdr.lines);
    align16(&dbghdr.symbols);
    align16(&dbghdr.tags);
    align16(&dbghdr.automatons);
    align16(&dbghdr.states);
  #endif
  writeerror |= !pc_writebin(fout,&dbghdr,sizeof dbghdr);

  /* file table */
  previdx=0;
  prevstr=NULL;
  prevname=NULL;
  for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
    assert(str!=NULL);
    assert(str[0]!='\0' && str[1]==':');
    if (str[0]=='F') {
      codeidx=hex2ucell(str+2,&name);
      if (codeidx!=previdx) {
        if (prevstr!=NULL) {
          assert(prevname!=NULL);
          #if BYTE_ORDER==BIG_ENDIAN
            align32(&previdx);
          #endif
          writeerror |= !pc_writebin(fout,&previdx,sizeof(uint32_t));
          writeerror |= !pc_writebin(fout,prevname,(int)strlen(prevname)+1);
        } /* if */
        previdx=codeidx;
      } /* if */
      prevstr=str;
      prevname=skipwhitespace(name);
    } /* if */
  } /* for */
  if (prevstr!=NULL) {
    assert(prevname!=NULL);
    #if BYTE_ORDER==BIG_ENDIAN
      align32(&previdx);
    #endif
    writeerror |= !pc_writebin(fout,&previdx,sizeof(uint32_t));
    writeerror |= !pc_writebin(fout,prevname,(int)strlen(prevname)+1);
  } /* if */

  /* line number table */
  for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
    assert(str!=NULL);
    assert(str[0]!='\0' && str[1]==':');
    if (str[0]=='L') {
      dbgline.address=(uint32_t)hex2ucell(str+2,&str);
      dbgline.line=(int32_t)hex2ucell(str,NULL);
      #if BYTE_ORDER==BIG_ENDIAN
        align32(&dbgline.address);
        align32(&dbgline.line);
      #endif
      writeerror |= !pc_writebin(fout,&dbgline,sizeof dbgline);
    } /* if */
  } /* for */

  /* symbol table */
  for (index=0; (str=get_dbgstring(index))!=NULL; index++) {
    assert(str!=NULL);
    assert(str[0]!='\0' && str[1]==':');
    if (str[0]=='S') {
      dbgsym.address=(uint32_t)hex2ucell(str+2,&str);
      dbgsym.tag=(int16_t)hex2ucell(str,&str);
      str=skipwhitespace(str);
      assert(*str==':');
      name=skipwhitespace(str+1);
      str=strchr(name,' ');
      assert(str!=NULL);
      assert((int)(str-name)<sizeof symname);
      strlcpy(symname,name,(int)(str-name)+1);
      dbgsym.codestart=(uint32_t)hex2ucell(str,&str);
      dbgsym.codeend=(uint32_t)hex2ucell(str,&str);
      dbgsym.ident=(char)hex2ucell(str,&str);
      dbgsym.vclass=(char)hex2ucell(str,&str);
      dbgsym.dim=0;
      str=skipwhitespace(str);
      if (*str=='[') {
        while (*(str=skipwhitespace(str+1))!=']') {
          dbgidxtag[dbgsym.dim].size=(uint32_t)hex2ucell(str,&str);
          dbgsym.dim++;
        } /* while */
      } /* if */
      dbgsymdim = dbgsym.dim;
      #if BYTE_ORDER==BIG_ENDIAN
        align32(&dbgsym.address);
        align16(&dbgsym.tag);
        align32(&dbgsym.codestart);
        align32(&dbgsym.codeend);
        align16(&dbgsym.dim);
      #endif
      writeerror |= !pc_writebin(fout,&dbgsym.address,sizeof dbgsym.codeend);
      writeerror |= !pc_writebin(fout,&dbgsym.tag,sizeof dbgsym.tag);
      writeerror |= !pc_writebin(fout,&dbgsym.codestart,sizeof dbgsym.codeend);
      writeerror |= !pc_writebin(fout,&dbgsym.codeend,sizeof dbgsym.codeend);
      writeerror |= !pc_writebin(fout,&dbgsym.ident,sizeof dbgsym.ident);
      writeerror |= !pc_writebin(fout,&dbgsym.vclass,sizeof dbgsym.vclass);
      writeerror |= !pc_writebin(fout,&dbgsym.dim,sizeof dbgsym.dim);
      writeerror |= !pc_writebin(fout,symname,(int)strlen(symname)+1);
      for (dim=0; dim<dbgsymdim; dim++) {
        #if BYTE_ORDER==BIG_ENDIAN
          align16(&dbgidxtag[dim].tag);
          align32(&dbgidxtag[dim].size);
        #endif
        writeerror |= !pc_writebin(fout,&dbgidxtag[dim].tag,sizeof dbgidxtag[dim].tag);
        writeerror |= !pc_writebin(fout,&dbgidxtag[dim].size,sizeof dbgidxtag[dim].size);
      } /* for */
    } /* if */
  } /* for */

  /* tag table */
  for (constptr=tagname_tab.next; constptr!=NULL; constptr=constptr->next) {
    assert(strlen(constptr->name)>0);
    id1=(int16_t)(constptr->value & TAGMASK);
    #if BYTE_ORDER==BIG_ENDIAN
      align16(&id1);
    #endif
    writeerror |= !pc_writebin(fout,&id1,sizeof id1);
    writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1);
  } /* for */

  /* automaton table */
  for (constptr=sc_automaton_tab.next; constptr!=NULL; constptr=constptr->next) {
    assert(constptr->index==0 && strlen(constptr->name)==0 || strlen(constptr->name)>0);
    id1=(int16_t)constptr->index;
    address=(ucell)constptr->value;
    #if BYTE_ORDER==BIG_ENDIAN
      align16(&id1);
      align32(&address);
    #endif
    writeerror |= !pc_writebin(fout,&id1,sizeof id1);
    writeerror |= !pc_writebin(fout,&address,sizeof(uint32_t));
    writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1);
  } /* for */

  /* state table */
  for (constptr=sc_state_tab.next; constptr!=NULL; constptr=constptr->next) {
    assert(strlen(constptr->name)>0);
    id1=(int16_t)constptr->value;
    id2=(int16_t)constptr->index;
    address=(ucell)constptr->value;
    #if BYTE_ORDER==BIG_ENDIAN
      align16(&id1);
      align16(&id2);
    #endif
    writeerror |= !pc_writebin(fout,&id1,sizeof id1);
    writeerror |= !pc_writebin(fout,&id2,sizeof id2);
    writeerror |= !pc_writebin(fout,constptr->name,(int)strlen(constptr->name)+1);
  } /* for */

  delete_dbgstringtable();
}
Beispiel #10
0
bool SavedataParam::Load(SceUtilitySavedataParam *param, int saveId)
{
	if (!param) {
		return false;
	}

	u8 *data_ = (u8*)Memory::GetPointer(param->dataBuf);

	std::string dirPath = GetSaveFilePath(param, saveId);
	if (saveId >= 0 && saveNameListDataCount > 0) // if user selection, use it
	{
		if (saveDataList[saveId].size == 0) // don't read no existing file
		{
			return false;
		}
	}

	std::string filePath = dirPath+"/"+GetFileName(param);
	s64 readSize;
	INFO_LOG(HLE,"Loading file with size %u in %s",param->dataBufSize,filePath.c_str());
	u8* saveData = 0;
	int saveSize = -1;
	if (!ReadPSPFile(filePath, &saveData, saveSize, &readSize))
	{
		ERROR_LOG(HLE,"Error reading file %s",filePath.c_str());
		return false;
	}
	saveSize = (int)readSize;

	// copy back save name in request
	strncpy(param->saveName,GetSaveDirName(param, saveId).c_str(),20);

	ParamSFOData sfoFile;
	std::string sfopath = dirPath+"/"+sfoName;
	PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath);
	if(sfoInfo.exists) // Read sfo
	{
		u8 *sfoData = new u8[(size_t)sfoInfo.size];
		size_t sfoSize = (size_t)sfoInfo.size;
		if(ReadPSPFile(sfopath,&sfoData,sfoSize, NULL))
		{
			sfoFile.ReadSFO(sfoData,sfoSize);

			// copy back info in request
			strncpy(param->sfoParam.title,sfoFile.GetValueString("TITLE").c_str(),128);
			strncpy(param->sfoParam.savedataTitle,sfoFile.GetValueString("SAVEDATA_TITLE").c_str(),128);
			strncpy(param->sfoParam.detail,sfoFile.GetValueString("SAVEDATA_DETAIL").c_str(),1024);
			param->sfoParam.parentalLevel = sfoFile.GetValueInt("PARENTAL_LEVEL");
		}
		delete[] sfoData;
	}
	// Don't know what it is, but PSP always respond this and this unlock some game
	param->bind = 1021;

	bool isCrypted = IsSaveEncrypted(param,saveId);
	bool saveDone = false;
	if(isCrypted)// Try to decrypt
	{
		int align_len = align16(saveSize);
		u8* data_base = new u8[align_len];
		u8* cryptKey = new u8[0x10];
		memset(cryptKey,0,0x10);

		if(param->key[0] != 0)
		{
			memcpy(cryptKey, param->key, 0x10);
		}
		memset(data_base + saveSize, 0, align_len - saveSize);
		memcpy(data_base, saveData, saveSize);

		int decryptMode = 1;
		if(param->key[0] != 0)
		{
			decryptMode = (GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3);
		}

		if(DecryptSave(decryptMode, data_base, &saveSize, &align_len, ((param->key[0] != 0)?cryptKey:0)) == 0)
		{
			memcpy(data_, data_base, saveSize);
			saveDone = true;
		}
		delete[] data_base;
		delete[] cryptKey;
	}
	if(!saveDone) // not crypted or decrypt fail
	{
		memcpy(data_, saveData, saveSize);
	}
	param->dataSize = (SceSize)saveSize;
	delete[] saveData;

	return true;
}
Beispiel #11
0
bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId)
{
	if (!param) {
		return false;
	}

	std::string dirPath = GetSaveFilePath(param, saveId);

	if (!pspFileSystem.GetFileInfo(dirPath).exists)
		pspFileSystem.MkDir(dirPath);

	u8* cryptedData = 0;
	int cryptedSize = 0;
	u8 cryptedHash[0x10];
	memset(cryptedHash,0,0x10);
	// Encrypt save.
	if(param->dataBuf != 0 && g_Config.bEncryptSave)
	{
		cryptedSize = param->dataSize;
		if(cryptedSize == 0 || (SceSize)cryptedSize > param->dataBufSize)
			cryptedSize = param->dataBufSize; // fallback, should never use this
		u8* data_ = (u8*)Memory::GetPointer(param->dataBuf);

		int aligned_len = align16(cryptedSize);
		cryptedData = new u8[aligned_len + 0x10];
		memcpy(cryptedData, data_, cryptedSize);

		int decryptMode = 1;
		if(param->key[0] != 0)
		{
			decryptMode = (GetSDKMainVersion(sceKernelGetCompiledSdkVersion()) >= 4 ? 5 : 3);
		}

		if(EncryptData(decryptMode, cryptedData, &cryptedSize, &aligned_len, cryptedHash, ((param->key[0] != 0)?param->key:0)) == 0)
		{
		}
		else
		{
			ERROR_LOG(HLE,"Save encryption failed. This save won't work on real PSP");
			delete[] cryptedData;
			cryptedData = 0;
		}
	}

	// SAVE PARAM.SFO
	ParamSFOData sfoFile;
	std::string sfopath = dirPath+"/"+sfoName;
	PSPFileInfo sfoInfo = pspFileSystem.GetFileInfo(sfopath);
	if(sfoInfo.exists) // Read old sfo if exist
	{
		u8 *sfoData = new u8[(size_t)sfoInfo.size];
		size_t sfoSize = (size_t)sfoInfo.size;
		if(ReadPSPFile(sfopath,&sfoData,sfoSize, NULL))
		{
			sfoFile.ReadSFO(sfoData,sfoSize);
			delete[] sfoData;
		}
	}

	// Update values
	sfoFile.SetValue("TITLE",param->sfoParam.title,128);
	sfoFile.SetValue("SAVEDATA_TITLE",param->sfoParam.savedataTitle,128);
	sfoFile.SetValue("SAVEDATA_DETAIL",param->sfoParam.detail,1024);
	sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4);
	sfoFile.SetValue("CATEGORY","MS",4);
	sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64);

	// For each file, 13 bytes for filename, 16 bytes for file hash (0 in PPSSPP), 3 byte for padding
	const int FILE_LIST_ITEM_SIZE = 13 + 16 + 3;
	const int FILE_LIST_COUNT_MAX = 99;
	const int FILE_LIST_TOTAL_SIZE = FILE_LIST_ITEM_SIZE * FILE_LIST_COUNT_MAX;
	u32 tmpDataSize = 0;
	u8* tmpDataOrig = sfoFile.GetValueData("SAVEDATA_FILE_LIST", &tmpDataSize);
	u8* tmpData = new u8[FILE_LIST_TOTAL_SIZE];

	if (tmpDataOrig != NULL)
		memcpy(tmpData, tmpDataOrig, tmpDataSize > FILE_LIST_TOTAL_SIZE ? FILE_LIST_TOTAL_SIZE : tmpDataSize);
	else
		memset(tmpData, 0, FILE_LIST_TOTAL_SIZE);

	if (param->dataBuf != 0)
	{
		char *fName = (char*)tmpData;
		for(int i = 0; i < FILE_LIST_COUNT_MAX; i++)
		{
			if(fName[0] == 0)
				break; // End of list
			if(strncmp(fName,GetFileName(param).c_str(),20) == 0)
				break;
			fName += FILE_LIST_ITEM_SIZE;
		}

		if (fName + 13 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE)
			snprintf(fName, 13, "%s",GetFileName(param).c_str());
		if (fName + 13 + 16 <= (char*)tmpData + FILE_LIST_TOTAL_SIZE)
			memcpy(fName+13, cryptedHash, 16);
	}
	sfoFile.SetValue("SAVEDATA_FILE_LIST", tmpData, FILE_LIST_TOTAL_SIZE, FILE_LIST_TOTAL_SIZE);
	delete[] tmpData;

	// Init param with 0. This will be used to detect crypted save or not on loading
	tmpData = new u8[128];
	memset(tmpData, 0, 128);
	sfoFile.SetValue("SAVEDATA_PARAMS", tmpData, 128, 128);
	delete[] tmpData;

	u8 *sfoData;
	size_t sfoSize;
	sfoFile.WriteSFO(&sfoData,&sfoSize);

	// Calc SFO hash for PSP.
	if(cryptedData != 0)
	{
		int offset = sfoFile.GetDataOffset(sfoData,"SAVEDATA_PARAMS");
		if(offset >= 0)
			UpdateHash(sfoData, sfoSize, offset, (param->key[0]?3:1));
	}
	WritePSPFile(sfopath, sfoData, (SceSize)sfoSize);
	delete[] sfoData;

	if(param->dataBuf != 0)	// Can launch save without save data in mode 13
	{
		std::string filePath = dirPath+"/"+GetFileName(param);
		u8* data_ = 0;
		SceSize saveSize = 0;
		if(cryptedData == 0) // Save decrypted data
		{
			saveSize = param->dataSize;
			if(saveSize == 0 || saveSize > param->dataBufSize)
				saveSize = param->dataBufSize; // fallback, should never use this

			data_ = (u8*)Memory::GetPointer(param->dataBuf);
		}
		else
		{
			data_ = cryptedData;
			saveSize = cryptedSize;
		}

		INFO_LOG(HLE,"Saving file with size %u in %s",saveSize,filePath.c_str());

		// copy back save name in request
		strncpy(param->saveName,GetSaveDirName(param, saveId).c_str(),20);

		if (!WritePSPFile(filePath, data_, saveSize))
		{
			ERROR_LOG(HLE,"Error writing file %s",filePath.c_str());
			if(cryptedData != 0)
			{
				delete[] cryptedData;
			}
			return false;
		}
		delete[] cryptedData;
	}


	// SAVE ICON0
	if (param->icon0FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->icon0FileData.buf);
		std::string icon0path = dirPath+"/"+icon0Name;
		WritePSPFile(icon0path, data_, param->icon0FileData.bufSize);
	}
	// SAVE ICON1
	if (param->icon1FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->icon1FileData.buf);
		std::string icon1path = dirPath+"/"+icon1Name;
		WritePSPFile(icon1path, data_, param->icon1FileData.bufSize);
	}
	// SAVE PIC1
	if (param->pic1FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->pic1FileData.buf);
		std::string pic1path = dirPath+"/"+pic1Name;
		WritePSPFile(pic1path, data_, param->pic1FileData.bufSize);
	}

	// Save SND
	if (param->snd0FileData.buf)
	{
		u8* data_ = (u8*)Memory::GetPointer(param->snd0FileData.buf);
		std::string snd0path = dirPath+"/"+snd0Name;
		WritePSPFile(snd0path, data_, param->snd0FileData.bufSize);
	}

	// Save Encryption Data
	{
		EncryptFileInfo encryptInfo;
		SceSize dataSize = sizeof(encryptInfo); // version + key + sdkVersion
		memset(&encryptInfo,0,dataSize);

		encryptInfo.fileVersion = 1;
		encryptInfo.sdkVersion = sceKernelGetCompiledSdkVersion();
		if(param->size > 1500)
			memcpy(encryptInfo.key,param->key,16);

		std::string encryptInfoPath = dirPath+"/"+"ENCRYPT_INFO.BIN";
		WritePSPFile(encryptInfoPath, (u8*)&encryptInfo, dataSize);
	}
	return true;
}
Beispiel #12
0
static void pmc_show(struct ptp_message *msg, FILE *fp)
{
	int action;
	struct TLV *tlv;
	struct management_tlv *mgt;
	struct management_tlv_datum *mtd;
	struct defaultDS *dds;
	struct currentDS *cds;
	struct parentDS *pds;
	struct timePropertiesDS *tp;
	struct time_status_np *tsn;
	struct grandmaster_settings_np *gsn;
	struct mgmt_clock_description *cd;
	struct tlv_extra *extra;
	struct portDS *p;
	struct port_ds_np *pnp;

	if (msg_type(msg) != MANAGEMENT) {
		return;
	}
	action = management_action(msg);
	if (action < GET || action > ACKNOWLEDGE) {
		return;
	}
	fprintf(fp, "\t%s seq %hu %s ",
		pid2str(&msg->header.sourcePortIdentity),
		msg->header.sequenceId, pmc_action_string(action));
	if (msg_tlv_count(msg) != 1) {
		goto out;
	}
	extra = TAILQ_FIRST(&msg->tlv_list);
	tlv = (struct TLV *) msg->management.suffix;
	if (tlv->type == TLV_MANAGEMENT) {
		fprintf(fp, "MANAGEMENT ");
	} else if (tlv->type == TLV_MANAGEMENT_ERROR_STATUS) {
		fprintf(fp, "MANAGEMENT_ERROR_STATUS ");
		goto out;
	} else {
		fprintf(fp, "unknown-tlv ");
		goto out;
	}
	mgt = (struct management_tlv *) msg->management.suffix;
	if (mgt->length == 2 && mgt->id != TLV_NULL_MANAGEMENT) {
		fprintf(fp, "empty-tlv ");
		goto out;
	}
	switch (mgt->id) {
	case TLV_CLOCK_DESCRIPTION:
		cd = &extra->cd;
		fprintf(fp, "CLOCK_DESCRIPTION "
			IFMT "clockType             0x%hx"
			IFMT "physicalLayerProtocol %s"
			IFMT "physicalAddress       %s"
			IFMT "protocolAddress       %hu %s",
			align16(cd->clockType),
			text2str(cd->physicalLayerProtocol),
			bin2str(cd->physicalAddress->address,
				align16(&cd->physicalAddress->length)),
			align16(&cd->protocolAddress->networkProtocol),
			portaddr2str(cd->protocolAddress));
		fprintf(fp, IFMT "manufacturerId        %s"
			IFMT "productDescription    %s",
			bin2str(cd->manufacturerIdentity, OUI_LEN),
			text2str(cd->productDescription));
		fprintf(fp, IFMT "revisionData          %s",
			text2str(cd->revisionData));
		fprintf(fp, IFMT "userDescription       %s"
			IFMT "profileId             %s",
			text2str(cd->userDescription),
			bin2str(cd->profileIdentity, PROFILE_ID_LEN));
		break;
	case TLV_USER_DESCRIPTION:
		fprintf(fp, "USER_DESCRIPTION "
			IFMT "userDescription  %s",
			text2str(extra->cd.userDescription));
		break;
	case TLV_DEFAULT_DATA_SET:
		dds = (struct defaultDS *) mgt->data;
		fprintf(fp, "DEFAULT_DATA_SET "
			IFMT "twoStepFlag             %d"
			IFMT "slaveOnly               %d"
			IFMT "numberPorts             %hu"
			IFMT "priority1               %hhu"
			IFMT "clockClass              %hhu"
			IFMT "clockAccuracy           0x%02hhx"
			IFMT "offsetScaledLogVariance 0x%04hx"
			IFMT "priority2               %hhu"
			IFMT "clockIdentity           %s"
			IFMT "domainNumber            %hhu",
			dds->flags & DDS_TWO_STEP_FLAG ? 1 : 0,
			dds->flags & DDS_SLAVE_ONLY ? 1 : 0,
			dds->numberPorts,
			dds->priority1,
			dds->clockQuality.clockClass,
			dds->clockQuality.clockAccuracy,
			dds->clockQuality.offsetScaledLogVariance,
			dds->priority2,
			cid2str(&dds->clockIdentity),
			dds->domainNumber);
		break;
	case TLV_CURRENT_DATA_SET:
		cds = (struct currentDS *) mgt->data;
		fprintf(fp, "CURRENT_DATA_SET "
			IFMT "stepsRemoved     %hd"
			IFMT "offsetFromMaster %.1f"
			IFMT "meanPathDelay    %.1f",
			cds->stepsRemoved, cds->offsetFromMaster / 65536.0,
			cds->meanPathDelay / 65536.0);
		break;
	case TLV_PARENT_DATA_SET:
		pds = (struct parentDS *) mgt->data;
		fprintf(fp, "PARENT_DATA_SET "
			IFMT "parentPortIdentity                    %s"
			IFMT "parentStats                           %hhu"
			IFMT "observedParentOffsetScaledLogVariance 0x%04hx"
			IFMT "observedParentClockPhaseChangeRate    0x%08x"
			IFMT "grandmasterPriority1                  %hhu"
			IFMT "gm.ClockClass                         %hhu"
			IFMT "gm.ClockAccuracy                      0x%02hhx"
			IFMT "gm.OffsetScaledLogVariance            0x%04hx"
			IFMT "grandmasterPriority2                  %hhu"
			IFMT "grandmasterIdentity                   %s",
			pid2str(&pds->parentPortIdentity),
			pds->parentStats,
			pds->observedParentOffsetScaledLogVariance,
			pds->observedParentClockPhaseChangeRate,
			pds->grandmasterPriority1,
			pds->grandmasterClockQuality.clockClass,
			pds->grandmasterClockQuality.clockAccuracy,
			pds->grandmasterClockQuality.offsetScaledLogVariance,
			pds->grandmasterPriority2,
			cid2str(&pds->grandmasterIdentity));
		break;
	case TLV_TIME_PROPERTIES_DATA_SET:
		tp = (struct timePropertiesDS *) mgt->data;
		fprintf(fp, "TIME_PROPERTIES_DATA_SET "
			IFMT "currentUtcOffset      %hd"
			IFMT "leap61                %d"
			IFMT "leap59                %d"
			IFMT "currentUtcOffsetValid %d"
			IFMT "ptpTimescale          %d"
			IFMT "timeTraceable         %d"
			IFMT "frequencyTraceable    %d"
			IFMT "timeSource            0x%02hhx",
			tp->currentUtcOffset,
			tp->flags & LEAP_61 ? 1 : 0,
			tp->flags & LEAP_59 ? 1 : 0,
			tp->flags & UTC_OFF_VALID ? 1 : 0,
			tp->flags & PTP_TIMESCALE ? 1 : 0,
			tp->flags & TIME_TRACEABLE ? 1 : 0,
			tp->flags & FREQ_TRACEABLE ? 1 : 0,
			tp->timeSource);
		break;
	case TLV_PRIORITY1:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "PRIORITY1 "
			IFMT "priority1 %hhu", mtd->val);
		break;
	case TLV_PRIORITY2:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "PRIORITY2 "
			IFMT "priority2 %hhu", mtd->val);
		break;
	case TLV_DOMAIN:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "DOMAIN "
			IFMT "domainNumber %hhu", mtd->val);
		break;
	case TLV_SLAVE_ONLY:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "SLAVE_ONLY "
			IFMT "slaveOnly %d", mtd->val & DDS_SLAVE_ONLY ? 1 : 0);
		break;
	case TLV_CLOCK_ACCURACY:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "CLOCK_ACCURACY "
			IFMT "clockAccuracy 0x%02hhx", mtd->val);
		break;
	case TLV_TRACEABILITY_PROPERTIES:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "TRACEABILITY_PROPERTIES "
			IFMT "timeTraceable      %d"
			IFMT "frequencyTraceable %d",
			mtd->val & TIME_TRACEABLE ? 1 : 0,
			mtd->val & FREQ_TRACEABLE ? 1 : 0);
		break;
	case TLV_TIMESCALE_PROPERTIES:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "TIMESCALE_PROPERTIES "
			IFMT "ptpTimescale %d", mtd->val & PTP_TIMESCALE ? 1 : 0);
		break;
	case TLV_TIME_STATUS_NP:
		tsn = (struct time_status_np *) mgt->data;
		fprintf(fp, "TIME_STATUS_NP "
			IFMT "master_offset              %" PRId64
			IFMT "ingress_time               %" PRId64
			IFMT "cumulativeScaledRateOffset %+.9f"
			IFMT "scaledLastGmPhaseChange    %d"
			IFMT "gmTimeBaseIndicator        %hu"
			IFMT "lastGmPhaseChange          0x%04hx'%016" PRIx64 ".%04hx"
			IFMT "gmPresent                  %s"
			IFMT "gmIdentity                 %s",
			tsn->master_offset,
			tsn->ingress_time,
			(tsn->cumulativeScaledRateOffset + 0.0) / P41,
			tsn->scaledLastGmPhaseChange,
			tsn->gmTimeBaseIndicator,
			tsn->lastGmPhaseChange.nanoseconds_msb,
			tsn->lastGmPhaseChange.nanoseconds_lsb,
			tsn->lastGmPhaseChange.fractional_nanoseconds,
			tsn->gmPresent ? "true" : "false",
			cid2str(&tsn->gmIdentity));
		break;
	case TLV_GRANDMASTER_SETTINGS_NP:
		gsn = (struct grandmaster_settings_np *) mgt->data;
		fprintf(fp, "GRANDMASTER_SETTINGS_NP "
			IFMT "clockClass              %hhu"
			IFMT "clockAccuracy           0x%02hhx"
			IFMT "offsetScaledLogVariance 0x%04hx"
			IFMT "currentUtcOffset        %hd"
			IFMT "leap61                  %d"
			IFMT "leap59                  %d"
			IFMT "currentUtcOffsetValid   %d"
			IFMT "ptpTimescale            %d"
			IFMT "timeTraceable           %d"
			IFMT "frequencyTraceable      %d"
			IFMT "timeSource              0x%02hhx",
			gsn->clockQuality.clockClass,
			gsn->clockQuality.clockAccuracy,
			gsn->clockQuality.offsetScaledLogVariance,
			gsn->utc_offset,
			gsn->time_flags & LEAP_61 ? 1 : 0,
			gsn->time_flags & LEAP_59 ? 1 : 0,
			gsn->time_flags & UTC_OFF_VALID ? 1 : 0,
			gsn->time_flags & PTP_TIMESCALE ? 1 : 0,
			gsn->time_flags & TIME_TRACEABLE ? 1 : 0,
			gsn->time_flags & FREQ_TRACEABLE ? 1 : 0,
			gsn->time_source);
		break;
	case TLV_PORT_DATA_SET:
		p = (struct portDS *) mgt->data;
		if (p->portState > PS_SLAVE) {
			p->portState = 0;
		}
		fprintf(fp, "PORT_DATA_SET "
			IFMT "portIdentity            %s"
			IFMT "portState               %s"
			IFMT "logMinDelayReqInterval  %hhd"
			IFMT "peerMeanPathDelay       %" PRId64
			IFMT "logAnnounceInterval     %hhd"
			IFMT "announceReceiptTimeout  %hhu"
			IFMT "logSyncInterval         %hhd"
			IFMT "delayMechanism          %hhu"
			IFMT "logMinPdelayReqInterval %hhd"
			IFMT "versionNumber           %hhu",
			pid2str(&p->portIdentity), ps_str[p->portState],
			p->logMinDelayReqInterval, p->peerMeanPathDelay >> 16,
			p->logAnnounceInterval, p->announceReceiptTimeout,
			p->logSyncInterval, p->delayMechanism,
			p->logMinPdelayReqInterval, p->versionNumber);
		break;
	case TLV_PORT_DATA_SET_NP:
		pnp = (struct port_ds_np *) mgt->data;
		fprintf(fp, "PORT_DATA_SET_NP "
			IFMT "neighborPropDelayThresh %u"
			IFMT "asCapable               %d",
			pnp->neighborPropDelayThresh,
			pnp->asCapable ? 1 : 0);
		break;
	case TLV_LOG_ANNOUNCE_INTERVAL:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "LOG_ANNOUNCE_INTERVAL "
			IFMT "logAnnounceInterval %hhd", mtd->val);
		break;
	case TLV_ANNOUNCE_RECEIPT_TIMEOUT:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "ANNOUNCE_RECEIPT_TIMEOUT "
			IFMT "announceReceiptTimeout %hhu", mtd->val);
		break;
	case TLV_LOG_SYNC_INTERVAL:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "LOG_SYNC_INTERVAL "
			IFMT "logSyncInterval %hhd", mtd->val);
		break;
	case TLV_VERSION_NUMBER:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "VERSION_NUMBER "
			IFMT "versionNumber %hhu", mtd->val);
		break;
	case TLV_DELAY_MECHANISM:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "DELAY_MECHANISM "
			IFMT "delayMechanism %hhu", mtd->val);
		break;
	case TLV_LOG_MIN_PDELAY_REQ_INTERVAL:
		mtd = (struct management_tlv_datum *) mgt->data;
		fprintf(fp, "LOG_MIN_PDELAY_REQ_INTERVAL "
			IFMT "logMinPdelayReqInterval %hhd", mtd->val);
		break;
	}
out:
	fprintf(fp, "\n");
	fflush(fp);
}