亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? apa.cpp

?? PS2游戲硬盤直灌(HDL)的Windows下VC的源代碼
?? CPP
?? 第 1 頁 / 共 2 頁
字號:
/*
 * apa.c
 * $Id: apa.c,v 1.11 2005/02/17 17:51:42 b081 Exp $
 *
 * Copyright 2004 Bobi B., w1zard0f07@yahoo.com
 *
 * This file is part of hdl_dump.
 *
 * hdl_dump is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * hdl_dump is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with hdl_dump; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

#include "byteseq.h"
#include "retcodes.h"
#include "common.h"
#include "ps2_hdd.h"
#include "osal.h"
#include "apa.h"
#include "hio_probe.h"


#define AUTO_DELETE_EMPTY


#define _MB * (1024 * 1024) /* really ugly :-) */

typedef struct ps2_partition_run_type
{
  unsigned long sector;
  u_int32_t size_in_mb;
} ps2_partition_run_t;


static int apa_check (const apa_partition_table_t *table);


/**************************************************************/
u_int32_t
apa_partition_checksum (const ps2_partition_header_t *part)
{
  const u_int32_t *p = (const u_int32_t*) part;
  register u_int32_t i;
  u_int32_t sum = 0;
  for (i=1; i<256; ++i)
    sum += get_u32 (p + i);
  return (sum);
}


/**************************************************************/
int /* RET_OK, RET_NOT_APA, RET_ERR */
is_apa_partition (osal_handle_t handle)
{
  ps2_partition_header_t part;
  u_int32_t bytes;

  int result = osal_read (handle, &part, sizeof (part), &bytes);
  if (result == OSAL_OK)
    {
      if (bytes == sizeof (part) &&
	  memcmp (part.magic, PS2_PARTITION_MAGIC, 4) == 0 &&
	  get_u32 (&part.checksum) == apa_partition_checksum (&part))
	return (RET_OK); /* APA */
      else
	return (RET_NOT_APA); /* not APA */
    }
  else
    return (result); /* error */
}


/**************************************************************/
static apa_partition_table_t*
apa_ptable_alloc (void)
{
  apa_partition_table_t *table = (apa_partition_table_t *)osal_alloc (sizeof (apa_partition_table_t));
  if (table != NULL)
    memset (table, 0, sizeof (apa_partition_table_t));
  return (table);
}


/**************************************************************/
void
apa_ptable_free (apa_partition_table_t *table)
{
  if (table != NULL)
    {
      if (table->chunks_map != NULL)
	osal_free (table->chunks_map);
      if (table->parts != NULL)
	osal_free (table->parts);
      osal_free (table);
    }
}


/**************************************************************/
static int
apa_part_add (apa_partition_table_t *table,
	      const ps2_partition_header_t *part,
	      int existing,
	      int linked)
{
  if (table->part_count == table->part_alloc_)
    { /* grow buffer */
      u_int32_t bytes = (table->part_alloc_ + 16) * sizeof (apa_partition_t);
      apa_partition_t *tmp = (apa_partition_t *)osal_alloc (bytes);
      if (tmp != NULL)
	{
	  memset (tmp, 0, bytes);
	  if (table->parts != NULL) /* copy existing */
	    memcpy (tmp, table->parts, table->part_count * sizeof (apa_partition_t));
	  osal_free (table->parts);
	  table->parts = tmp;
	  table->part_alloc_ += 16;
	}
      else
	return (RET_NO_MEM);
    }

  memcpy (&table->parts [table->part_count].header, part, sizeof (ps2_partition_header_t));
  table->parts [table->part_count].existing = existing;
  table->parts [table->part_count].modified = !existing;
  table->parts [table->part_count].linked = linked;
  ++table->part_count;
  return (RET_OK);
}


/**************************************************************/
static int
apa_setup_statistics (apa_partition_table_t *table)
{
  u_int32_t i;
  char *map;

  table->total_chunks = table->device_size_in_mb / 128;
  map = (char *)osal_alloc (table->total_chunks * sizeof (char));
  if (map != NULL)
    {
      for (i=0; i<table->total_chunks; ++i)
	map [i] = MAP_AVAIL;

      /* build occupided/available space map */
      table->allocated_chunks = 0;
      table->free_chunks = table->total_chunks;
      for (i=0; i<table->part_count; ++i)
	{
	  const ps2_partition_header_t *part = &table->parts [i].header;
	  u_int32_t part_no = get_u32 (&part->start) / ((128 _MB) / 512);
	  u_int32_t num_parts = get_u32 (&part->length) / ((128 _MB) / 512);

	  /* "alloc" num_parts starting at part_no */
	  while (num_parts)
	    {
	      if (map [part_no] == MAP_AVAIL)
		map [part_no] = get_u32 (&part->main) == 0 ? MAP_MAIN : MAP_SUB;
	      else
		map [part_no] = MAP_COLL; /* collision */
	      ++part_no;
	      --num_parts;
	      ++table->allocated_chunks;
	      --table->free_chunks;
	    }
	}

      if (table->chunks_map != NULL)
	osal_free (table->chunks_map);
      table->chunks_map = map;

      return (RET_OK);
    }
  else
    return (RET_NO_MEM);
}


/**************************************************************/
int
apa_ptable_read (const char *path,
		 apa_partition_table_t **table)
{
  hio_t *hio;
  int result = hio_probe (path, &hio); /* do not disable caching */
  if (result == OSAL_OK)
    {
      result = apa_ptable_read_ex (hio, table);
      hio->close (hio);
    }
  return (result);
}


/**************************************************************/
int
apa_ptable_read_ex (hio_t *hio,
		    apa_partition_table_t **table)
{
  u_int32_t size_in_kb;
  int result = hio->stat (hio, &size_in_kb);
  if (result == OSAL_OK)
    {
      u_int32_t total_sectors;
#if defined (LIMIT_HDD_TO_128GB)
      /* limit HDD size to 128GB - 1KB; that is: exclude the last 128MB chunk */
      if (size_in_kb > 128 * 1024 * 1024 - 1)
	size_in_kb = 128 * 1024 * 1024 - 1;
#endif
      total_sectors = size_in_kb * 2; /* 1KB = 2 sectors of 512 bytes, each */

      *table = apa_ptable_alloc ();
      if (table != NULL)
	{
	  u_int32_t sector = 0;
	  do
	    {
	      u_int32_t bytes;
	      ps2_partition_header_t part;
	      result = hio->read (hio, sector, sizeof (part) / 512, &part, &bytes);
	      if (result == OSAL_OK)
		{
		  if (bytes == sizeof (part) &&
		      get_u32 (&part.checksum) == apa_partition_checksum (&part) &&
		      memcmp (part.magic, PS2_PARTITION_MAGIC, 4) == 0)
		    {
		      if (get_u32 (&part.start) < total_sectors &&
			  get_u32 (&part.start) + get_u32 (&part.length) < total_sectors)
			{
			  result = apa_part_add (*table, &part, 1, 1);
			  if (result == RET_OK)
			    sector = get_u32 (&part.next);
			}
		      else
			{ /* partition behind end-of-HDD */
#if defined (LIMIT_HDD_TO_128GB)
			  result = RET_CROSS_128GB; /* data behind 128GB mark */
#else
			  result = RET_BAD_APA; /* data behind end-of-HDD */
#endif
			  break;
			}
		    }
		  else
		    result = RET_NOT_APA;
		}
	    }
	  while (result == RET_OK && sector != 0);

	  if (result == RET_OK)
	    {
	      (*table)->device_size_in_mb = size_in_kb / 1024;
	      result = apa_setup_statistics (*table);
	      if (result == RET_OK)
		result = apa_check (*table);
	    }

#if defined (AUTO_DELETE_EMPTY)
	  if (result == RET_OK)
	    { /* automatically delete "__empty" partitions */
	      do
		{
		  result = apa_delete_partition (*table, "__empty");
		}
	      while (result == RET_OK);
	      if (result == RET_NOT_FOUND)
		result = apa_check (*table);
	    }
#endif

	  if (result != RET_OK)
	    apa_ptable_free (*table);
	}
      else
	result = RET_NO_MEM;
    }
  return (result);
}


/**************************************************************/
int
apa_find_partition (const apa_partition_table_t *table,
		    const char *partition_name,
		    u_int32_t *partition_index)
{
  u_int32_t i;
  int result = RET_NOT_FOUND;
  for (i=0; i<table->part_count; ++i)
    {
      const ps2_partition_header_t *part = &table->parts [i].header;
      if (get_u32 (&part->main) == 0)
	{ /* trim partition name */
	  char id_copy [PS2_PART_IDMAX + 1];
	  char *part_id_end = id_copy + PS2_PART_IDMAX - 1;
	  memcpy (id_copy, part->id, PS2_PART_IDMAX);
	  id_copy [PS2_PART_IDMAX] = '\0';
	  while (part_id_end > id_copy &&
		 *part_id_end == ' ')
	    *part_id_end-- = '\0';
	  if (caseless_compare (id_copy, partition_name))
	    { /* found */
	      *partition_index = i;
	      result = RET_OK;
	      break;
	    }
	}
    }
  return (result);
}


/**************************************************************/
static int
compare_partitions (const void *e1,
		    const void *e2)
{
  const ps2_partition_run_t *p1 = (const ps2_partition_run_t *)e1;
  const ps2_partition_run_t *p2 = (const ps2_partition_run_t *)e2;
  int diff = (int) p2->size_in_mb - (int) p1->size_in_mb;
  if (diff != 0)
    return (diff);
  else
    return ((int) p1->sector - (int) p2->sector);
}


/* descending by size, ascending by sector */
static void
sort_partitions (ps2_partition_run_t *partitions,
		 u_int32_t partitions_used)
{
  /* TODO: consider better sorting to take care about partitioning on as few runs as possible */
  qsort (partitions, partitions_used, sizeof (ps2_partition_run_t), &compare_partitions);
}


/* join neighbour partitions of the same size, but sum up to max_part_size_in_mb */
static void
optimize_partitions (ps2_partition_run_t *partitions,
		     u_int32_t *partitions_used,
		     u_int32_t max_part_size_in_mb)
{
  int have_join;
  do
    {
      u_int32_t i;
      have_join = 0;
      for (i=0; i<*partitions_used - 1; ++i)
	{
	  u_int32_t curr_part_end_sector = 
	    partitions [i].sector +
	    partitions [i].size_in_mb * ((1 _MB) / 512);
	  u_int32_t u_int32_to_be = partitions [i].size_in_mb * 2;
	  int next_is_same_size =
	    partitions [i].size_in_mb == partitions [i + 1].size_in_mb;
	  int would_be_aligned =
	    partitions [i].sector % (u_int32_to_be * ((1 _MB) / 512)) == 0;

	  if (u_int32_to_be <= max_part_size_in_mb &&
	      curr_part_end_sector == partitions [i + 1].sector &&
	      next_is_same_size &&
	      would_be_aligned)
	    {
	      partitions [i].size_in_mb *= 2;
	      memmove (partitions + i + 1, partitions + i + 2,
		       (*partitions_used - i - 2) * sizeof (ps2_partition_run_t));
	      --(*partitions_used);
	      have_join = 1;
	    }
	}
    }
  while (have_join);
}


/**************************************************************/
static void
set_ps2fs_datetime (ps2fs_datetime_t *dt,
		    time_t to)
{
  struct tm tm;
  memcpy (&tm, localtime (&to), sizeof (struct tm));
  dt->unused = 0;
  dt->sec = (u_int8_t) tm.tm_sec;
  dt->min = (u_int8_t) tm.tm_min;
  dt->hour = (u_int8_t) tm.tm_hour;
  dt->day = (u_int8_t) tm.tm_mday;
  dt->month = (u_int8_t) (tm.tm_mon + 1);
  set_u16 (&dt->year, (u_int16_t) (tm.tm_year + 1900));
}


static void
setup_main_part (ps2_partition_header_t *part,
		 const char *name,
		 const ps2_partition_run_t *partitions,
		 u_int32_t partitions_used,
		 u_int32_t last_partition_sector)
{
  u_int32_t i;
  memset (part, 0, sizeof (ps2_partition_header_t));
  memcpy (part->magic, PS2_PARTITION_MAGIC, 4);
  set_u32 (&part->next, partitions_used > 0 ? partitions [1].sector : 0);
  set_u32 (&part->prev, last_partition_sector);
  memcpy (part->id, name,
	  strlen (name) > PS2_PART_IDMAX ? PS2_PART_IDMAX : strlen (name));
  set_u32 (&part->start, partitions [0].sector);
  set_u32 (&part->length, partitions [0].size_in_mb * ((1 _MB) / 512));
  set_u16 (&part->type, 0x1337);
  set_u16 (&part->flags, 0);
  set_u32 (&part->nsub, partitions_used - 1);
  set_ps2fs_datetime (&part->created, time (NULL));
  set_u32 (&part->main, 0);
  set_u32 (&part->number, 0);
  set_u16 (&part->unknown2, 513);
  for (i=1; i<partitions_used; ++i)
    {
      set_u32 (&part->subs [i - 1].start, partitions [i].sector);
      set_u32 (&part->subs [i - 1].length, partitions [i].size_in_mb * ((1 _MB) / 512));
    }
  set_u32 (&part->checksum, apa_partition_checksum (part));
}


static void
setup_sub_part (ps2_partition_header_t *part,
		u_int32_t index,
		const ps2_partition_run_t *partitions,
		u_int32_t partitions_used)
{
  memset (part, 0, sizeof (ps2_partition_header_t));
  memcpy (part->magic, PS2_PARTITION_MAGIC, 4);
  set_u32 (&part->next, index + 1 < partitions_used ? partitions [index + 1].sector : 0);
  set_u32 (&part->prev, partitions [index - 1].sector);
  set_u32 (&part->start, partitions [index].sector);
  set_u32 (&part->length, partitions [index].size_in_mb * ((1 _MB) / 512));
  set_u16 (&part->type, 0x1337);
  set_u16 (&part->flags, PS2_PART_FLAG_SUB);
  set_u32 (&part->nsub, 0);
  set_ps2fs_datetime (&part->created, time (NULL));
  set_u32 (&part->main, partitions [0].sector);
  set_u32 (&part->number, index);
  set_u16 (&part->unknown2, 513);
  set_u32 (&part->checksum, apa_partition_checksum (part));
}


/**************************************************************/
static int
sort_by_starting_sector (const void *e1,
			 const void *e2)
{
  const apa_partition_t *p1 = (const apa_partition_t*) e1;
  const apa_partition_t *p2 = (const apa_partition_t*) e2;
  return (get_u32 (&p1->header.start) > get_u32 (&p2->header.start) ? 1 : -1);
}

static void
normalize_linked_list (apa_partition_table_t *table)
{
  qsort (table->parts, table->part_count, sizeof (apa_partition_t), sort_by_starting_sector);
  if (table->part_count >= 1)
    {
      u_int32_t i;
      for (i=0; i<table->part_count; ++i)
	{

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
蜜臀a∨国产成人精品| 日韩成人av影视| 久久疯狂做爰流白浆xx| 成人蜜臀av电影| 日韩一级黄色大片| 亚洲乱码中文字幕综合| 国产乱码精品一区二区三| 欧美日韩激情一区| 国产精品美女久久久久久2018| 日韩精品一区第一页| 91丝袜呻吟高潮美腿白嫩在线观看| 日韩精品在线一区| 五月综合激情婷婷六月色窝| 99视频热这里只有精品免费| 久久蜜桃香蕉精品一区二区三区| 亚洲高清视频的网址| 99re热视频精品| 国产拍揄自揄精品视频麻豆| 奇米色一区二区三区四区| 在线观看一区二区视频| 国产精品每日更新| 国产一区不卡视频| 日韩欧美一区中文| 日韩精品一级中文字幕精品视频免费观看 | 最新成人av在线| 国产在线不卡一区| 日韩欧美国产综合在线一区二区三区| 亚洲综合精品自拍| 色诱视频网站一区| 亚洲人xxxx| 99精品欧美一区二区三区综合在线| 国产三级一区二区| 国产精品伊人色| 久久久综合视频| 国产一区在线观看视频| 日韩欧美国产成人一区二区| 日韩中文字幕亚洲一区二区va在线| 欧美三级中文字| 亚洲大片在线观看| 欧美久久久久久久久久| 香港成人在线视频| 8v天堂国产在线一区二区| 亚洲1区2区3区4区| 欧美精品tushy高清| 日韩二区在线观看| 日韩一区二区视频在线观看| 欧美aaa在线| 欧美不卡一二三| 精品午夜久久福利影院| 精品国偷自产国产一区| 国产一区二区在线看| 精品国产免费人成电影在线观看四季 | 久久新电视剧免费观看| 国产一区美女在线| 国产精品无人区| 99精品热视频| 亚洲国产一区二区三区| 欧美精品丝袜中出| 免费成人小视频| 26uuu成人网一区二区三区| 国产一区二区三区免费观看| 亚洲国产高清不卡| 色综合天天性综合| 一区二区三区 在线观看视频| 欧美亚洲动漫另类| 日本大胆欧美人术艺术动态| 日韩限制级电影在线观看| 国产精品一级黄| 亚洲欧洲韩国日本视频| 欧美视频一区二区三区四区 | 日本一区二区在线不卡| av一区二区不卡| 亚洲v中文字幕| 日韩欧美国产高清| 成人18视频日本| 亚洲国产视频直播| 26uuu国产电影一区二区| 成人教育av在线| 亚洲一区二区三区在线看| 欧美一级日韩不卡播放免费| 国产精品一区二区黑丝| 综合欧美一区二区三区| 777奇米四色成人影色区| 老司机午夜精品| 中文文精品字幕一区二区| 91成人在线精品| 另类专区欧美蜜桃臀第一页| 国产精品色一区二区三区| 欧美日韩综合一区| 国产在线精品免费| 亚洲九九爱视频| 精品国产一区二区国模嫣然| jizzjizzjizz欧美| 蜜桃视频一区二区三区| 中文字幕一区二区三区色视频| 欧美日韩一区二区三区免费看 | 亚洲va中文字幕| 久久精品视频免费观看| 精品污污网站免费看| 国产一区日韩二区欧美三区| 一区二区三区四区乱视频| 精品少妇一区二区三区在线播放 | 欧美三级蜜桃2在线观看| 国产精品资源在线| 亚洲国产另类精品专区| 欧美经典一区二区| 欧美一卡2卡三卡4卡5免费| 成人av在线看| 蜜臀国产一区二区三区在线播放| 亚洲欧美综合网| 精品国一区二区三区| 在线观看日产精品| 国产成人啪免费观看软件| 午夜精品久久久久久久久久久| 国产欧美综合在线| 日韩欧美高清一区| 欧美午夜视频网站| 成人99免费视频| 国产又黄又大久久| 午夜精品久久久久| 亚洲欧美另类在线| 国产午夜精品在线观看| 8v天堂国产在线一区二区| 色综合天天做天天爱| 国产大陆精品国产| 久久精品99久久久| 日本欧美韩国一区三区| 一区二区三区四区在线| 欧美国产激情二区三区| 日韩欧美一区中文| 欧美人狂配大交3d怪物一区| 97aⅴ精品视频一二三区| 国产麻豆午夜三级精品| 日韩av一级片| 午夜国产不卡在线观看视频| 亚洲乱码日产精品bd| 国产精品福利一区二区三区| 日韩一区二区三区电影 | 久久99精品久久久久久| 天天做天天摸天天爽国产一区 | 日韩精品在线看片z| 91麻豆精品国产91久久久更新时间 | 免费欧美在线视频| 亚洲3atv精品一区二区三区| 亚洲精品国产一区二区精华液| 国产精品欧美一区喷水| 久久久美女毛片 | 色噜噜狠狠成人网p站| 播五月开心婷婷综合| 粉嫩aⅴ一区二区三区四区 | 日韩专区一卡二卡| 婷婷亚洲久悠悠色悠在线播放 | 久久综合色婷婷| 欧美成人三级在线| 精品久久久久久最新网址| 日韩一区二区在线观看视频| 91精品国产色综合久久ai换脸| 欧美日韩在线播放| 欧美日韩黄视频| 777亚洲妇女| 日韩一级视频免费观看在线| 91精品视频网| 日韩欧美中文字幕公布| 精品久久久三级丝袜| 久久中文娱乐网| 国产亚洲精品aa| 国产精品私人自拍| 成人欧美一区二区三区白人| 亚洲欧洲韩国日本视频| 一区二区三区在线视频免费观看 | 精品国产乱码久久久久久老虎| 91精品国产麻豆| 精品日产卡一卡二卡麻豆| 精品999久久久| 国产女人水真多18毛片18精品视频 | 成人午夜碰碰视频| proumb性欧美在线观看| 色综合天天天天做夜夜夜夜做| 在线观看亚洲专区| 欧美精品三级在线观看| 日韩精品一区二区三区四区视频 | 91麻豆精品国产91久久久久久久久 | 欧美日韩国产a| 日韩欧美在线观看一区二区三区| 久久亚洲综合av| 中文字幕一区二区三中文字幕| 亚洲在线免费播放| 麻豆精品精品国产自在97香蕉| 国产一区二区不卡| caoporn国产精品| 欧美日韩一区二区三区不卡 | 91福利社在线观看| 欧美一区二区免费观在线| 久久亚洲私人国产精品va媚药| 国产精品萝li| 亚洲成人动漫在线免费观看| 九色综合狠狠综合久久| 成人黄色电影在线| 欧美三区在线观看| 久久久蜜臀国产一区二区|