亚洲欧美第一页_禁久久精品乱码_粉嫩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一区二区三区免费野_久草精品视频
卡一卡二国产精品| www.欧美.com| 色哟哟在线观看一区二区三区| 成人亚洲精品久久久久软件| 国产精品白丝jk白祙喷水网站| 久久精品国产亚洲高清剧情介绍 | 国产精品久久久久久亚洲毛片 | 久色婷婷小香蕉久久| 麻豆专区一区二区三区四区五区| 久久精品国产亚洲高清剧情介绍 | 91麻豆精品国产综合久久久久久| 欧美福利视频导航| 欧美一区二区精品久久911| 欧美一区二区三区视频| 欧美激情一区二区三区全黄| 一区二区三区色| 蜜桃传媒麻豆第一区在线观看| 成人激情免费电影网址| 欧美色图第一页| 久久精品夜色噜噜亚洲aⅴ| 亚洲欧美一区二区三区极速播放| 亚洲第一久久影院| 国产成人免费视频| 欧美日韩国产综合视频在线观看| 怡红院av一区二区三区| 日韩欧美激情四射| 亚洲精品视频观看| 成人午夜激情在线| 日韩一区和二区| 亚洲特黄一级片| 精品一区二区精品| 这里只有精品视频在线观看| 亚洲高清免费一级二级三级| 91香蕉视频mp4| 亚洲激情欧美激情| www.成人网.com| 国产精品视频线看| 成人aaaa免费全部观看| 国产精品天干天干在线综合| 久草精品在线观看| 在线不卡免费欧美| 亚洲天堂网中文字| 91国内精品野花午夜精品| 亚洲天堂精品视频| 欧美性高清videossexo| 一区二区三区四区av| 欧美日韩中文字幕一区| 五月婷婷久久丁香| 日韩欧美电影一二三| 精品一区二区在线视频| 91精品国产高清一区二区三区 | 久久国产精品免费| 久久久久国产精品厨房| 成人h精品动漫一区二区三区| 国产精品网站在线观看| 欧美日韩一区二区在线视频| 日韩成人免费电影| 久久综合狠狠综合久久综合88| av一区二区三区四区| 一区二区三区精品在线| 精品福利视频一区二区三区| 国产成人日日夜夜| 婷婷中文字幕一区三区| 国产欧美日韩不卡免费| 在线观看日韩高清av| 国产尤物一区二区| 免费高清在线一区| 亚洲一级二级三级在线免费观看| 久久―日本道色综合久久| 欧美在线不卡视频| 不卡的电视剧免费网站有什么| 午夜视频一区二区| 亚洲观看高清完整版在线观看| 亚洲国产高清aⅴ视频| 欧美电影免费观看高清完整版 | 欧美刺激脚交jootjob| 日本久久电影网| 国产91色综合久久免费分享| 免费成人av在线| 亚洲国产一区二区三区青草影视| 中文字幕久久午夜不卡| 精品久久久久久久久久久久包黑料| 欧美性猛交一区二区三区精品| 91女神在线视频| 在线精品视频一区二区三四| 99国产精品久久久久久久久久| 国内成人免费视频| 国产精品一区二区免费不卡| 精品一区二区久久| 狠狠色狠狠色综合系列| 日韩精品电影一区亚洲| 日韩电影一区二区三区| 久久精品国产77777蜜臀| 久久国产麻豆精品| 国产一本一道久久香蕉| 国产99久久精品| 一本色道久久综合亚洲精品按摩| 91免费国产在线| 91视视频在线直接观看在线看网页在线看| 91毛片在线观看| 欧美一区二区在线观看| 国产午夜亚洲精品不卡| 亚洲女人的天堂| 久久精品免费观看| 91在线一区二区| 欧美一区二区三区日韩| 国产精品天天摸av网| 亚洲图片欧美色图| 国产精品18久久久久久久网站| 成人av网在线| 91精品国产欧美一区二区| 中文字幕+乱码+中文字幕一区| 蜜臀精品久久久久久蜜臀| 色综合色综合色综合色综合色综合| 欧美一区二区三区四区久久| 亚洲欧美日本韩国| 成人精品小蝌蚪| 欧美岛国在线观看| 青青草97国产精品免费观看| 懂色av一区二区三区蜜臀| 欧美一区二区三区在线| 亚洲蜜臀av乱码久久精品| 久久精品久久精品| 欧美日韩高清不卡| 天堂成人免费av电影一区| 欧美日韩精品福利| 亚洲成人av一区| 欧美一级在线视频| 午夜婷婷国产麻豆精品| 日本乱码高清不卡字幕| 国产精品久久久久影视| 成人爱爱电影网址| 中文字幕日韩一区| 成人中文字幕在线| 日本一区二区三区四区在线视频 | 一本一本大道香蕉久在线精品 | 亚洲品质自拍视频| 97精品久久久久中文字幕| 亚洲色图第一区| 一本一道久久a久久精品 | 欧美精品在线观看一区二区| 偷拍与自拍一区| 久久综合色播五月| 91丨porny丨中文| 日韩电影网1区2区| 国产精品黄色在线观看| 在线视频国产一区| 蜜臀91精品一区二区三区| 中文乱码免费一区二区| 欧美日产在线观看| 成人福利视频网站| 麻豆国产一区二区| 一区二区免费在线播放| 精品国产91亚洲一区二区三区婷婷| 99久久99久久精品免费看蜜桃| 琪琪久久久久日韩精品| 夜夜嗨av一区二区三区中文字幕 | 韩国精品一区二区| 亚洲成av人片一区二区三区| 日本一区二区成人在线| 日韩手机在线导航| 欧美人与z0zoxxxx视频| 91在线视频在线| www.视频一区| 国产盗摄一区二区| 国产一区欧美一区| 石原莉奈在线亚洲三区| 亚洲乱码中文字幕| 亚洲视频免费观看| 中文字幕在线不卡一区 | 成人性生交大片免费看视频在线 | 国产清纯在线一区二区www| 精品久久国产字幕高潮| 中文字幕一区视频| 日本中文字幕一区二区有限公司| 国产一区二区在线看| 欧美色手机在线观看| 精品三级在线看| 中文字幕在线观看一区| 久久av资源站| 欧美精品777| 国产欧美日韩亚州综合| 久久精品一二三| 亚洲日本中文字幕区| 蜜臀久久99精品久久久久久9| 激情文学综合网| 不卡视频免费播放| 欧美精品黑人性xxxx| 久久久久国产一区二区三区四区| 欧美国产日产图区| 亚洲第一久久影院| 成人理论电影网| 日韩午夜精品视频| 一区二区三区在线观看视频| 激情综合网天天干| 在线亚洲精品福利网址导航| 日韩一区二区精品葵司在线| 欧美高清在线精品一区| 美女网站视频久久| 91麻豆国产精品久久|