Exemplo n.º 1
0
int read_all_with_crc(int fd, void *buf, int size) {
	int ret;
	ret = read_all(fd, buf, size);
	if (ret)
		crc32_sum = Crc32_ComputeBuf(crc32_sum, buf, size);
	return ret;
}
Exemplo n.º 2
0
int slip_encode(int format,
		const unsigned char *src, int src_bytes, unsigned char *dst, int dst_len)
{
  switch(format) {
  case SLIP_FORMAT_SLIP:
    {
      int offset=0;

      if (offset+2>dst_len)
	return WHY("Dest buffer full");
      
      dst[offset++]=SLIP_END;
      
      int ret=encode_slip(src, src_bytes, dst + offset, dst_len - offset);
      if (ret<0)
	return ret;
      offset+=ret;
      
      unsigned char crc[4];
      write_uint32(crc, Crc32_ComputeBuf( 0, src, src_bytes));
      
      ret=encode_slip(crc, 4, dst + offset, dst_len - offset);
      if (ret<0)
	return ret;
      offset+=ret;
      
      dst[offset++]=SLIP_END;
      
      return offset;
    }
  case SLIP_FORMAT_UPPER7:
    /*
      The purpose of this encoder is to work nicely with the RFD900 radios,
      including allowing the reception of RSSI information in the middle of
      packets.
      RSSI reports look like:
      L/R RSSI: 48/0  L/R noise: 62/0 pkts: 0  txe=0 rxe=0 stx=0 srx=0 ecc=0/0 temp=21 dco=0
      So we are using 0x80-0xff to hold data, and { and } to frame packets.
    */
    if (config.debug.slip)
      dump("pre-slipped packet",src,src_bytes);
    {
      if (src_bytes<1) return 0;
      if (src_bytes>0x3fff) 
	return WHYF("UPPER7 SLIP encoder packets must be <=0x3fff bytes");
      if (dst_len<(9+src_bytes+(src_bytes/7)+1))
	return WHYF("UPPER7 SLIP encoder requires 9+(8/7)*bytes to encode");
      int i,j;
      int out_len=0;

      // Start of packet marker
      dst[out_len++]='{';
      // Length of (unencoded) packet
      dst[out_len++]=0x80+((src_bytes>>7)&0x7f);
      dst[out_len++]=0x80+((src_bytes>>0)&0x7f);
      // Add 32-bit CRC
      // (putting the CRC at the front allows it to be calculated progressively
      // on the receiver side, if we decide to support that)
      uint32_t crc=Crc32_ComputeBuf( 0, src, src_bytes);
      dst[out_len++]=0x80|((crc>>25)&0x7f);
      dst[out_len++]=0x80|((crc>>(25-7))&0x7f);
      dst[out_len++]=0x80|((crc>>(25-7-7))&0x7f);
      dst[out_len++]=0x80|((crc>>(25-7-7-7))&0x7f);
      dst[out_len++]=0x80|((crc>>0)&0x7f);

      for(i=0;i<src_bytes;i+=7)
	{
	  // Create 8 bytes of output consisting of 8x7 bits

	  // Generate vector of 7 bytes to encode
	  unsigned char v[7];
	  for(j=0;j<7&&i+j<src_bytes;j++) v[j]=src[i+j];
	  for(;j<7;j++) v[j]=0;
	  if (out_len+8>dst_len) 
	    return WHYF("Ran out of space in UPPER7 SLIP encoder (used all %d bytes after encoding %d of %d bytes)",
			dst_len,i,src_bytes);
	  // We could use a nice for loop to do this, but for 8 bytes, let's
	  // just do it explicitly.
	  dst[out_len++]=0x80|                 (v[0]>>1);
	  dst[out_len++]=0x80|((v[0]&0x01)<<6)|(v[1]>>2);
	  dst[out_len++]=0x80|((v[1]&0x03)<<5)|(v[2]>>3);
	  dst[out_len++]=0x80|((v[2]&0x07)<<4)|(v[3]>>4);
	  dst[out_len++]=0x80|((v[3]&0x0f)<<3)|(v[4]>>5);
	  dst[out_len++]=0x80|((v[4]&0x1f)<<2)|(v[5]>>6);
	  dst[out_len++]=0x80|((v[5]&0x3f)<<1)|(v[6]>>7);
	  dst[out_len++]=0x80|((v[6]&0x7f)<<0);
	}

      // Mark end of packet
      dst[out_len++]='}';
      // Detect fatal miscalculations on byte counts
      if (out_len>dst_len) {
	FATALF("overran output buffer in SLIP UPPER7 encapsulation of packet (used %d of %d bytes)",out_len,dst_len);
      }
      return out_len;
    }
  default:
    return WHYF("Unsupported slip encoding #%d",format);
  }

}
Exemplo n.º 3
0
/* state->src and state->src_size contain the freshly read bytes
   we must accumulate any partial state between calls.
*/
int slip_decode(struct slip_decode_state *state)
{
  switch(state->encapsulator) {
  case SLIP_FORMAT_SLIP:
    {
      /*
       Examine received bytes for end of packet marker.
       The challenge is that we need to make sure that the packet encapsulation
       is self-synchronising in the event that a data error occurs (including
       failure to receive an arbitrary number of bytes).
       */
      while(state->src_offset < state->src_size){
	// clear the valid bit flag if we hit the end of the destination buffer
	if (state->dst_offset >= sizeof state->dst)
	  state->state&=~DC_VALID;
	
	if (state->state&DC_ESC){
	  // clear escape bit
	  state->state&=~DC_ESC;
	  switch(state->src[state->src_offset]) {
	    case SLIP_ESC_END: // escaped END byte
	      state->dst[state->dst_offset++]=SLIP_END;
	      break;
	    case SLIP_ESC_ESC: // escaped escape character
	      state->dst[state->dst_offset++]=SLIP_ESC;
	      break;
	    case SLIP_ESC_0a:
	      state->dst[state->dst_offset++]=SLIP_0a;
	      break;
	    case SLIP_ESC_0d:
	      state->dst[state->dst_offset++]=SLIP_0d;
	      break;
	    case SLIP_ESC_0f:
	      state->dst[state->dst_offset++]=SLIP_0f;
	      break;
	    case SLIP_ESC_1b:
	      state->dst[state->dst_offset++]=SLIP_1b;
	      break;
	    default: /* Unknown escape character. This is an error. */
	      if (config.debug.packetradio)
		WARNF("Packet radio stream contained illegal escaped byte 0x%02x -- resetting parser.",state->src[state->src_offset]);
	      state->dst_offset=0;
	      // skip everything until the next SLIP_END
	      state->state=0;
	  }
	}else{
	  // non-escape character
	  switch(state->src[state->src_offset]) {
	    case SLIP_ESC:
	      // set escape bit
	      state->state|=DC_ESC; 
	      break;
	    case SLIP_END:
	      if (state->dst_offset>4){
		
		uint32_t src_crc = read_uint32(state->dst + state->dst_offset -4);
		uint32_t crc=Crc32_ComputeBuf( 0, state->dst, state->dst_offset -4);
		
		if (src_crc != crc){
		  DEBUGF("Dropping frame due to CRC failure (%08x vs %08x)", src_crc, crc);
		  dump("frame", state->dst, state->dst_offset);
		  state->dst_offset=0;
		  state->state=0;
		  break;
		}
		// return once we've successfully parsed a valid packet that isn't empty
		state->packet_length=state->dst_offset -4;
		return 1;
	      }
	      // set the valid flag to begin parsing the next packet
	      state->state=DC_VALID;
	      break;
	    default:
	      if (state->state&DC_VALID)
		state->dst[state->dst_offset++]=state->src[state->src_offset];
	  }
	}
	state->src_offset++;
      }
      return 0;
    }
  case SLIP_FORMAT_UPPER7:
    {
      if (config.debug.slip) {
	if (state->rssi_len>=RSSI_TEXT_SIZE) state->rssi_len=RSSI_TEXT_SIZE-1;
	state->rssi_text[state->rssi_len]=0;
	DEBUGF("RX state=%d, rssi_len=%u, rssi_text='%s',src=%p, src_size=%u",
	       state->state,state->rssi_len,state->rssi_text,
	       state->src,state->src_size);
      }
     while(state->src_offset<state->src_size) {
	if (upper7_decode(state,state->src[state->src_offset++])==1) {
	  if (config.debug.slip) {
	    dump("de-slipped packet",state->dst,state->packet_length);
          }
	 
	  // Check that CRC matches
	  uint32_t crc=Crc32_ComputeBuf( 0, state->dst, state->packet_length);
	  if (crc!=state->crc) {
	    if (config.debug.packetradio||config.debug.rejecteddata)
	      DEBUGF("Rejected packet of %u bytes due to CRC mis-match (%08x vs %08x)",
		     state->packet_length,crc,state->crc);
	    if (config.debug.rejecteddata) {
	      dump("bad packet",state->dst,state->packet_length);
	    }
	  } else {
	    if (config.debug.packetradio) 
	      DEBUGF("Accepted packet of %u bytes (CRC ok)",state->packet_length);
	    return 1;
	  }
	}
      }
    }
    return 0;
  default:
    return WHYF("Unknown SLIP encapsulation format #%d",state->encapsulator);
  }
}
Exemplo n.º 4
0
int patch_gcm(file_handle *file, ExecutableFile *filesToPatch, int numToPatch, int multiDol) {
	int i, num_patched = 0;
	
	// If the current device isn't SD Gecko, init SD Gecko Slot A or B to write patches.
	if(deviceHandler_initial != &initial_SD0 && deviceHandler_initial != &initial_SD1) {
		deviceHandler_setStatEnabled(0);
		if(deviceHandler_FAT_init(&initial_SD0)) {
			savePatchDevice = 0;
		}
		else if(deviceHandler_FAT_init(&initial_SD1)) {
			savePatchDevice = 1;
		}
		deviceHandler_setStatEnabled(1);
	}
	// Already using SD Gecko
	if(deviceHandler_initial == &initial_SD0)
		savePatchDevice = 0;
	else if(deviceHandler_initial == &initial_SD1)
		savePatchDevice = 1;
		
	if(savePatchDevice == -1) {
		DrawFrameStart();
		DrawMessageBox(D_FAIL, "No writable device present\nA SD Gecko must be inserted in\n order to utilise patches for this game.");
		DrawFrameFinish();
		sleep(5);
		return 0;
	}

	char patchFileName[256];
	char patchDirName[256];
	char patchBaseDirName[256];
	char gameID[8];
	memset(&gameID, 0, 8);
	memset(&patchDirName, 0, 256);
	memset(&patchBaseDirName, 0, 256);
	strncpy((char*)&gameID, (char*)&GCMDisk, 4);
	sprintf(&patchDirName[0],"%s:/swiss_patches/%s",(savePatchDevice ? "sdb":"sda"), &gameID[0]);
	sprintf(&patchBaseDirName[0],"%s:/swiss_patches",(savePatchDevice ? "sdb":"sda"));
	print_gecko("Patch dir will be: %s if required\r\n", patchDirName);
	*(u32*)VAR_EXECD_OFFSET = 0xFFFFFFFF;
	// Go through all the possible files we think need patching..
	for(i = 0; i < numToPatch; i++) {
		u32 patched = 0, crc32 = 0;

		sprintf(txtbuffer, "Patching File %i/%i",i+1,numToPatch);
		DrawFrameStart();
		DrawProgressBar((int)(((float)(i+1)/(float)numToPatch)*100), txtbuffer);
		DrawFrameFinish();
			
		// Round up to 32 bytes
		if(filesToPatch[i].size % 0x20) {
			filesToPatch[i].size += (0x20-(filesToPatch[i].size%0x20));
		}
		
		if(filesToPatch[i].size > 8*1024*1024) {
			print_gecko("Skipping %s %iKB too large\r\n", filesToPatch[i].name, filesToPatch[i].size/1024);
			continue;
		}
		print_gecko("Checking %s %iKb\r\n", filesToPatch[i].name, filesToPatch[i].size/1024);
		if(strstr(filesToPatch[i].name, "execD.")) {
			*(u32*)VAR_EXECD_OFFSET = filesToPatch[i].offset;
		}
		if(strstr(filesToPatch[i].name, "iwanagaD.dol") || strstr(filesToPatch[i].name, "switcherD.dol")) {
			continue;	// skip unused PSO files
		}
		int sizeToRead = filesToPatch[i].size;
		u8 *buffer = (u8*)memalign(32, sizeToRead);
		
		deviceHandler_seekFile(file,filesToPatch[i].offset, DEVICE_HANDLER_SEEK_SET);
		if(deviceHandler_readFile(file,buffer,sizeToRead)!= sizeToRead) {
			DrawFrameStart();
			DrawMessageBox(D_FAIL, "Failed to read!");
			DrawFrameFinish();
			sleep(5);
			return 0;
		}
		
		if(curDevice != DVD_DISC) {
			u32 ret = Patch_DVDLowLevelRead(buffer, sizeToRead, filesToPatch[i].type);
			if(READ_PATCHED_ALL != ret)	{
				DrawFrameStart();
				DrawMessageBox(D_FAIL, "Failed to find necessary functions for patching!");
				DrawFrameFinish();
				sleep(5);
			}
			else
				patched += 1;
		}
				
		if(swissSettings.debugUSB && usb_isgeckoalive(1) && !swissSettings.wiirdDebug) {
			patched += Patch_Fwrite(buffer, sizeToRead);
		}
		
		if(swissSettings.wiirdDebug || getEnabledCheatsSize() > 0) {
			Patch_CheatsHook(buffer, sizeToRead, filesToPatch[i].type);
		}
		
		if(curDevice == DVD_DISC && is_gamecube()) {
			patched += Patch_DVDLowLevelReadForDVD(buffer, sizeToRead, filesToPatch[i].type);
			patched += Patch_DVDReset(buffer, sizeToRead);
		}
		
		patched += Patch_VidMode(buffer, sizeToRead, filesToPatch[i].type);
		patched += Patch_FontEnc(buffer, sizeToRead);
		if(swissSettings.forceWidescreen)
			Patch_WideAspect(buffer, sizeToRead, filesToPatch[i].type);
		if(swissSettings.forceAnisotropy)
			Patch_TexFilt(buffer, sizeToRead, filesToPatch[i].type);
		if(patched) {
			// File handle for a patch we might need to write
			FILE *patchFile = 0;
			memset(patchFileName, 0, 256);
		
			// Make a base patches dir if we don't have one already
			if(mkdir(&patchBaseDirName[0], 0777) != 0) {
				if(errno != EEXIST) {
					return -2;
				}
			}
			if(mkdir(&patchDirName[0], 0777) != 0) {
				if(errno != EEXIST) {
					return -2;
				}
			}
			sprintf(patchFileName, "%s/%i",patchDirName, num_patched);

			// Work out the crc32
			crc32 = Crc32_ComputeBuf( 0, buffer, (u32) sizeToRead);

			// See if this file already exists, if it does, match crc
			patchFile = fopen( patchFileName, "rb" );
			if(patchFile) {
				//print_gecko("Old Patch exists\r\n");
				u32 oldCrc32 = 0;
				fseek(patchFile, 0L, SEEK_END);
				u32 file_size = ftell(patchFile);
				fseek(patchFile, file_size-4, SEEK_SET);
				fread(&oldCrc32, 1, 4, patchFile);
				if(oldCrc32 == crc32) {
					num_patched++;
					fclose(patchFile);
					free(buffer);
					print_gecko("CRC matched, no need to patch again\r\n");
					continue;
				}
				else {
					remove(patchFileName);
					fclose(patchFile);
					print_gecko("CRC mismatch, writing patch again\r\n");
				}
			}
			// Otherwise, write a file out for this game with the patched buffer inside.
			print_gecko("Writing patch file: %s %i bytes (disc offset %08X)\r\n", patchFileName, sizeToRead, filesToPatch[i].offset);
			patchFile = fopen(patchFileName, "wb");
			fwrite(buffer, 1, sizeToRead, patchFile);
			u32 magic = SWISS_MAGIC;
			fwrite(&filesToPatch[i].offset, 1, 4, patchFile);
			fwrite(&filesToPatch[i].size, 1, 4, patchFile);
			fwrite(&magic, 1, 4, patchFile);
			fwrite(&crc32, 1, 4, patchFile);
			fclose(patchFile);
			num_patched++;
		}
		free(buffer);
	}

	return num_patched;
}
int write_all_with_crc(int fd, void *buf, int size)
{
	crc32_sum = Crc32_ComputeBuf(crc32_sum, buf, size);
	return write_all(fd, buf, size);
}