⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hdl.cpp

📁 PS2游戏硬盘直灌(HDL)的Windows下VC的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		    {		      u_int32_t num_parts = buffer [0x001010f0];		      const u_int32_t *data = (u_int32_t*) (buffer + 0x001010f5);		      u_int32_t i;		      if (buffer [0x00101000] == 0xed &&			  buffer [0x00101001] == 0xfe &&			  buffer [0x00101002] == 0xad &&			  buffer [0x00101003] == 0xde)			{ /* 0xdeadfeed magic found */			  osal_handle_t file;			  u_int64_t total_size = 0;			  /* calculate output file size */			  for (i=0; i<num_parts; ++i)			    total_size += ((u_int64_t) get_u32 (data + i * 3 + 2)) << 8;			  pgs_prepare (pgs, total_size);			  /* create file and copy data */			  result = osal_create_file (output_file, &file, total_size);			  if (result == OSAL_OK)			    {			      u_int8_t *aligned = (u_int8_t *)(void*) (((long) buffer + 511) & ~511);			      for (i=0; result == OSAL_OK && i<num_parts; ++i)				{ /* seek and copy */				  u_int32_t start_s = get_u32 (data + i * 3 + 1) << 8;				  u_int32_t length_s = get_u32 (data + i * 3 + 2) / 2;				  u_int64_t curr = 0;				  while (length_s > 0 && result == OSAL_OK)				    {				      u_int32_t count_s =					length_s < IIN_NUM_SECTORS ? length_s : IIN_NUM_SECTORS;				      result = hio->read (hio, start_s, count_s,							  aligned, &len);				      if (result == OSAL_OK)					{					  u_int32_t written;					  result = osal_write (file, aligned,							       count_s * 512, &written);					  if (result == OSAL_OK)					    {					      start_s += count_s;					      length_s -= count_s;					      curr += count_s * 512;					      pgs_update (pgs, curr);					    }					}				    }				  pgs_chunk_complete (pgs);				} /* for */			      result = osal_close (file) == OSAL_OK ? result : OSAL_ERR;			    }			}		      else			result = RET_NOT_HDL_PART;		    }		  hio->close (hio);		}	      osal_free (buffer);	    }	  else	    result = RET_NO_MEM;	}      apa_ptable_free (table);    }  return (result);}/**************************************************************/static intinject_data (hio_t *hio,	     const apa_partition_table_t *table,	     u_int32_t starting_partition_sector,	     iin_t *iin,	     u_int32_t size_in_kb,	     const hdl_game_t *details,	     progress_t *pgs){  int result;  u_int32_t i;  const ps2_partition_header_t *part;  char *buffer = (char *)osal_alloc (4 _MB);  part = NULL;  if (buffer != NULL)    {      result = RET_NOT_FOUND;      for (i=0; i<table->part_count; ++i)	if (get_u32 (&table->parts [i].header.start) == starting_partition_sector)	  { /* locate starting partition index */	    part = &table->parts [i].header;	    /* verify apa */	    result = (get_u32 (&part->checksum) == apa_partition_checksum (part) ?		      RET_OK : RET_BAD_APA);	    break;	  }    }  else    result = RET_NO_MEM;  if (result == RET_OK)    {      result = prepare_main (details, table, starting_partition_sector,			     size_in_kb, (u_int8_t*) buffer);      if (result == RET_OK)	{	  u_int32_t kb_remaining = size_in_kb;	  u_int32_t start_sector = 0;	  u_int32_t bytes;	  u_int32_t main_hdr_size_s = (4 _MB) / 512;	  pgs_prepare (pgs, (u_int64_t) (size_in_kb + 4 * 1024) * 1024);	  /* first: write main partition header (4MB total) */	  result = hio->write (hio, get_u32 (&part->start), main_hdr_size_s, buffer, &bytes);	  if (result == OSAL_OK)	    result = bytes == 4 _MB ? OSAL_OK : OSAL_ERR;	  osal_free (buffer), buffer = NULL;	  /* track header, otherwise it would influence the progress calculation */	  pgs_update (pgs, 4 _MB);	  pgs_chunk_complete (pgs);	  /* next: fill-in 1st partition */	  if (result == RET_OK)	    {	      u_int64_t part_size = ((u_int64_t) get_u32 (&part->length)) * 512 - (4 _MB);	      u_int64_t chunk_length_in_bytes =		((u_int64_t) kb_remaining) * 1024 < part_size ?		((u_int64_t) kb_remaining) * 1024 : part_size;	      result = iin_copy_ex (iin, hio, start_sector,				    get_u32 (&part->start) + main_hdr_size_s,				    (u_int32_t) (chunk_length_in_bytes / IIN_SECTOR_SIZE),				    pgs);	      pgs_chunk_complete (pgs);	      start_sector += (u_int32_t) (chunk_length_in_bytes / IIN_SECTOR_SIZE);	      kb_remaining -= (u_int32_t) (chunk_length_in_bytes / 1024);	    }	  for (i=0; result == OSAL_OK && kb_remaining>0 && i!=get_u32 (&part->nsub); ++i)	    { /* next: fill-in remaining partitions */	      u_int32_t sub_part_start_s = get_u32 (&part->subs [i].start);	      u_int64_t sub_part_size = (((u_int64_t) get_u32 (&part->subs [i].length)) *					 512 - (1 _MB));	      u_int32_t sub_part_hdr_size_s = (1 _MB) / 512;	      u_int64_t chunk_length =		((u_int64_t) kb_remaining) * 1024 < sub_part_size ?		((u_int64_t) kb_remaining) * 1024 : sub_part_size;	      result = iin_copy_ex (iin, hio, start_sector,				    sub_part_start_s + sub_part_hdr_size_s,				    (u_int32_t) (chunk_length / IIN_SECTOR_SIZE), pgs);	      pgs_chunk_complete (pgs);	      start_sector += (u_int32_t) (chunk_length / IIN_SECTOR_SIZE);	      kb_remaining -= (u_int32_t) (chunk_length / 1024);	    }	  if (result == RET_OK &&	      kb_remaining != 0)	    result = RET_NO_SPACE; /* the game does not fit in the allocated space... why? */	  /* finally: commit partition table */	  if (result == OSAL_OK)	    result = apa_commit_ex (hio, table);	}    }  if (buffer != NULL)    osal_free (buffer);  return (result);}/**************************************************************/inthdl_inject (hio_t *hio,	    iin_t *iin,	    hdl_game_t *details,	    progress_t *pgs){  apa_partition_table_t *table = NULL;  int result = apa_ptable_read_ex (hio, &table);  if (result == OSAL_OK)    {      u_int32_t sector_size, num_sectors;      result = iin->stat (iin, &sector_size, &num_sectors);      if (result == OSAL_OK)	{	  u_int64_t input_size = (u_int64_t) num_sectors * (u_int64_t) sector_size;	  u_int32_t size_in_kb = (u_int32_t) (input_size / 1024);	  u_int32_t size_in_mb = (u_int32_t) ((input_size + (1 _MB - 1)) / (1 _MB));	  u_int32_t new_partition_start;	  if (details->partition_name [0] == '\0')	    hdl_pname (details->name, details->partition_name);	  result = apa_allocate_space (table, details->partition_name, size_in_mb,				       &new_partition_start, 0); /* order by size desc */	  if (result == RET_OK)	    {	      result = inject_data (hio,				    table,				    new_partition_start,				    iin,				    size_in_kb,				    details,				    pgs);	    }	}    }  if (table != NULL)    apa_ptable_free (table);  return (result);}/**************************************************************/static inthdl_ginfo_read (hio_t *hio,		const ps2_partition_header_t *part,		hdl_game_info_t *ginfo){  u_int32_t i, size;  /* data we're interested in starts @ 0x101000 and is header   * plus information for up to 65 partitions   * (1 main + 64 sub) by 12 bytes each */  const u_int32_t offset = 0x101000;  char buffer [1024];  int result;  u_int32_t bytes;  result = hio->read (hio, get_u32 (&part->start) + offset / 512, 2, buffer, &bytes);  if (result == RET_OK)    {      if (bytes == 1024)	{	  /* calculate total size */	  size = get_u32 (&part->length);	  for (i=0; i<get_u32 (&part->nsub); ++i)	    size += get_u32 (&part->subs [i].length);	  memcpy (ginfo->partition_name, part->id, PS2_PART_IDMAX);	  ginfo->partition_name [PS2_PART_IDMAX] = '\0';	  strcpy (ginfo->name, buffer + 0x101008 - offset);	  strcpy (ginfo->startup, buffer + 0x1010ac - offset);	  ginfo->compat_flags = buffer [0x1010a8 - offset];	  ginfo->is_dvd = buffer [0x1010ec - offset] == 0x14;	  ginfo->start_sector = get_u32 (&part->start);	  ginfo->total_size_in_kb = size / 2;	}      else	result = RET_ERR;    }  return (result);}/**************************************************************/inthdl_glist_read (hio_t *hio,		hdl_games_list_t **glist){  apa_partition_table_t *ptable;  int result;  result = apa_ptable_read_ex (hio, &ptable);  if (result == RET_OK)    {      u_int32_t i, count = 0;      void *tmp;      for (i=0; i<ptable->part_count; ++i)	count += (get_u16 (&ptable->parts [i].header.flags) == 0x00 &&		  get_u16 (&ptable->parts [i].header.type) == 0x1337);      tmp = osal_alloc (sizeof (hdl_game_info_t) * count);      if (tmp != NULL)	{	  memset (tmp, 0, sizeof (hdl_game_info_t) * count);	  *glist = (hdl_games_list_t *)osal_alloc (sizeof (hdl_games_list_t));	  if (*glist != NULL)	    {	      u_int32_t index = 0;	      memset (*glist, 0, sizeof (hdl_games_list_t));	      (*glist)->count = count;	      (*glist)->games = (hdl_game_info_type *)tmp;	      (*glist)->total_chunks = ptable->total_chunks;	      (*glist)->free_chunks = ptable->free_chunks;	      for (i=0; result==RET_OK&&i<ptable->part_count; ++i)		{		  const ps2_partition_header_t *part = &ptable->parts [i].header;		  if (get_u16 (&part->flags) == 0x00 && get_u16 (&part->type) == 0x1337)		    result = hdl_ginfo_read (hio, part, (*glist)->games + index++);		}	      if (result != RET_OK)		osal_free (*glist);	    }	  else	    result = RET_NO_MEM;	  if (result != RET_OK)	    osal_free (tmp);	}      else	result = RET_NO_MEM;      apa_ptable_free (ptable);    }  return (result);}/**************************************************************/voidhdl_glist_free (hdl_games_list_t *glist){  if (glist != NULL)    {      osal_free (glist->games);      osal_free (glist);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -