119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * dosio.c -- Disk I/O module for the ext2fs/DOS library.
319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (c) 1997 by Theodore Ts'o.
53984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (c) 1997 Mark Habersack
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
88558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %Begin-Header%
98558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * This file may be redistributed under the terms of the GNU Library
108558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * General Public License, version 2.
118558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall * %End-Header%
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <bios.h>
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h>
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <io.h>
1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h>
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ext2fs/ext2_types.h>
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "utils.h"
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "dosio.h"
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "et/com_err.h"
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2_err.h"
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "ext2fs/io.h"
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Some helper macros
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define LINUX_EXT2FS       0x83
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define LINUX_SWAP         0x82
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define WRITE_ERR(_msg_) write(2, _msg_, strlen(_msg_))
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define WRITE_ERR_S(_msg_) write(2, _msg_, sizeof(_msg_))
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Exported variables
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectunsigned long        _dio_error;
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectunsigned long        _dio_hw_error;
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Array of all opened partitions
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic PARTITION        **partitions = NULL;
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic unsigned short   npart = 0; /* Number of mapped partitions */
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic PARTITION        *active = NULL;
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * I/O Manager routine prototypes
5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_open(const char *dev, int flags, io_channel *channel);
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_close(io_channel channel);
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_set_blksize(io_channel channel, int blksize);
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_read_blk(io_channel channel, unsigned long block,
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                                             int count, void *buf);
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_write_blk(io_channel channel, unsigned long block,
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                               int count, const void *buf);
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_flush(io_channel channel);
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic struct struct_io_manager struct_dos_manager = {
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        EXT2_ET_MAGIC_IO_MANAGER,
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        "DOS I/O Manager",
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        dos_open,
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        dos_close,
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        dos_set_blksize,
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        dos_read_blk,
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        dos_write_blk,
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        dos_flush
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectio_manager dos_io_manager = &struct_dos_manager;
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Macro taken from unix_io.c
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * For checking structure magic numbers...
8019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define EXT2_CHECK_MAGIC(struct, code) \
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project          if ((struct)->magic != (code)) return (code)
8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Calculates a CHS address of a sector from its LBA
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * offset for the given partition.
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void lba2chs(unsigned long lba_addr, CHS *chs, PARTITION *part)
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  unsigned long      abss;
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  chs->offset = lba_addr & 0x000001FF;
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  abss = (lba_addr >> 9) + part->start;
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  chs->cyl    = abss / (part->sects * part->heads);
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  chs->head   = (abss / part->sects) % part->heads;
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  chs->sector = (abss % part->sects) + 1;
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __TURBOC__
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#pragma argsused
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Scans the passed partition table looking for *pno partition
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * that has LINUX_EXT2FS type.
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * TODO:
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * For partition numbers >5 Linux uses DOS extended partitions -
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * dive into them an return an appropriate entry. Also dive into
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * extended partitions when scanning for a first Linux/ext2fs.
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic PTABLE_ENTRY *scan_partition_table(PTABLE_ENTRY *pentry,
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                                          unsigned short phys,
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                                          unsigned char *pno)
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  unsigned        i;
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(*pno != 0xFF && *pno >= 5)
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project     return NULL; /* We don't support extended partitions for now */
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(*pno != 0xFF)
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    if(pentry[*pno].type == LINUX_EXT2FS)
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      return &pentry[*pno];
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    else
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    {
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      if(!pentry[*pno].type)
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        *pno = 0xFE;
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      else if(pentry[*pno].type == LINUX_SWAP)
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        *pno = 0xFD;
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      return NULL;
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    }
13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  for(i = 0; i < 4; i++)
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    if(pentry[i].type == LINUX_EXT2FS)
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    {
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      *pno = i;
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      return &pentry[i];
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    }
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  return NULL;
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Allocate libext2fs structures associated with I/O manager
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic io_channel alloc_io_channel(PARTITION *part)
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  io_channel     ioch;
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch = (io_channel)malloc(sizeof(struct struct_io_channel));
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if (!ioch)
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	  return NULL;
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  memset(ioch, 0, sizeof(struct struct_io_channel));
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch->magic = EXT2_ET_MAGIC_IO_CHANNEL;
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch->manager = dos_io_manager;
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch->name = (char *)malloc(strlen(part->dev)+1);
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if (!ioch->name) {
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	  free(ioch);
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	  return NULL;
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  strcpy(ioch->name, part->dev);
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch->private_data = part;
16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch->block_size = 1024; /* The smallest ext2fs block size */
16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch->read_error = 0;
16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ioch->write_error = 0;
16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  return ioch;
17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __TURBOC__
17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#pragma argsused
17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Open the 'name' partition, initialize all information structures
17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * we need to keep and create libext2fs I/O manager.
17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_open(const char *dev, int flags, io_channel *channel)
18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  unsigned char  *tmp, sec[512];
18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  PARTITION      *part;
18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  PTABLE_ENTRY   *pent;
18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  PARTITION        **newparts;
1853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(!dev)
18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = ERR_BADDEV;
18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return EXT2_ET_BAD_DEVICE_NAME;
19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * First check whether the dev name is OK
19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  tmp = (unsigned char*)strrchr(dev, '/');
19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(!tmp)
19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = ERR_BADDEV;
19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return EXT2_ET_BAD_DEVICE_NAME;
20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  *tmp = 0;
20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(strcmp(dev, "/dev"))
20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = ERR_BADDEV;
20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return EXT2_ET_BAD_DEVICE_NAME;
20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  *tmp++ = '/';
20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Check whether the partition data is already in cache
21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  part = (PARTITION*)malloc(sizeof(PARTITION));
21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if (!part)
21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	  return ENOMEM;
21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    int   i = 0;
21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    for(;i < npart; i++)
22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      if(!strcmp(partitions[i]->dev, dev))
22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      {
22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        /* Found it! Make it the active one */
22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        active = partitions[i];
22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        *channel = alloc_io_channel(active);
22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!*channel)
22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return ENOMEM;
22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        return 0;
22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      }
22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Drive number & optionally partn number
23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  switch(tmp[0])
23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    case 'h':
23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    case 's':
23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      part->phys = 0x80;
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      part->phys += toupper(tmp[2]) - 'A';
24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      /*
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project       * Do we have the partition number?
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project       */
24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      if(tmp[3])
24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        part->pno = isdigit((int)tmp[3]) ? tmp[3] - '0' - 1: 0;
24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      else
24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        part->pno = 0xFF;
24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      break;
24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    case 'f':
25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      if(tmp[2])
25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        part->phys = isdigit((int)tmp[2]) ? tmp[2] - '0' : 0;
25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      else
25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project        part->phys = 0x00; /* We'll assume /dev/fd0 */
25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      break;
25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    default:
25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      _dio_error = ERR_BADDEV;
25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      return ENODEV;
25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(part->phys < 0x80)
26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project     /* We don't support floppies for now */
26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project     _dio_error = ERR_NOTSUPP;
26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project     return EINVAL;
26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  part->dev = strdup(dev);
26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Get drive's geometry
27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  _dio_hw_error = biosdisk(DISK_GET_GEOMETRY,
27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           part->phys,
27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           0, /* head */
27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           0, /* cylinder */
27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           1, /* sector */
27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           1, /* just one sector */
27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           sec);
28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(!HW_OK())
28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = ERR_HARDWARE;
2843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt    free(part->dev);
2853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt    free(part);
28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return EFAULT;
28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Calculate the geometry
29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  part->cyls  = (unsigned short)(((sec[0] >> 6) << 8) + sec[1] + 1);
29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  part->heads = sec[3] + 1;
29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  part->sects = sec[0] & 0x3F;
29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Now that we know all we need, let's look for the partition
29819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  _dio_hw_error = biosdisk(DISK_READ, part->phys, 0, 0, 1, 1, sec);
30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(!HW_OK())
30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = ERR_HARDWARE;
3043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt    free(part->dev);
3053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt    free(part);
30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return EFAULT;
30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  pent = (PTABLE_ENTRY*)&sec[0x1BE];
31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  pent = scan_partition_table(pent, part->phys, &part->pno);
31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(!pent)
31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = part->pno == 0xFE ? ERR_EMPTYPART :
31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                 part->pno == 0xFD ? ERR_LINUXSWAP : ERR_NOTEXT2FS;
3163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt    free(part->dev);
3173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt    free(part);
31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return ENODEV;
31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Calculate the remaining figures
32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    unsigned long    fsec, fhead, fcyl;
32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    fsec = (unsigned long)(pent->start_sec & 0x3F);
32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    fhead = (unsigned long)pent->start_head;
32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    fcyl = ((pent->start_sec >> 6) << 8) + pent->start_cyl;
33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    part->start = fsec + fhead * part->sects + fcyl *
33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                  (part->heads * part->sects) - 1;
33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    part->len = pent->size;
33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Add the partition to the table
33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
33819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  newparts = (PARTITION**)realloc(partitions, sizeof(PARTITION) * npart);
33919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if (!newparts) {
34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	  free(part);
34119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	  return ENOMEM;
34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  partitions = newparts;
34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  partitions[npart++] = active = part;
34519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
34619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Now alloc all libe2fs structures
34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  *channel = alloc_io_channel(active);
35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if (!*channel)
35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	  return ENOMEM;
35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  return 0;
35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_close(io_channel channel)
35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
3583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	free(channel->name);
3593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	free(channel);
36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
36319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
36419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_set_blksize(io_channel channel, int blksize)
36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
36619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  channel->block_size = blksize;
36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  return 0;
36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
37119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_read_blk(io_channel channel, unsigned long block,
37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                                             int count, void *buf)
37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  PARTITION     *part;
37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  size_t        size;
37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ext2_loff_t   loc;
37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  CHS           chs;
37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
37919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
38019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  part = (PARTITION*)channel->private_data;
38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  size = (size_t)((count < 0) ? -count : count * channel->block_size);
38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  loc = (ext2_loff_t) block * channel->block_size;
38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  lba2chs(loc, &chs, part);
38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
38719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * Potential bug here:
38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   *   If DJGPP is used then reads of >18 sectors will fail!
38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   *   Have to rewrite biosdisk.
39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  _dio_hw_error = biosdisk(DISK_READ,
39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           part->phys,
39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           chs.head,
39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           chs.cyl,
39519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           chs.sector,
39619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           size < 512 ? 1 : size/512,
39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           buf);
39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(!HW_OK())
40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
40119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = ERR_HARDWARE;
40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return EFAULT;
40319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  return 0;
40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
40719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_write_blk(io_channel channel, unsigned long block,
40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                               int count, const void *buf)
41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  PARTITION     *part;
41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  size_t        size;
41319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  ext2_loff_t   loc;
41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  CHS           chs;
41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  part = (PARTITION*)channel->private_data;
41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(count == 1)
42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    size = (size_t)channel->block_size;
42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  else
42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    if (count < 0)
42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      size = (size_t)-count;
42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    else
42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project      size = (size_t)(count * channel->block_size);
42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  loc = (ext2_loff_t)block * channel->block_size;
43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  lba2chs(loc, &chs, part);
43119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  _dio_hw_error = biosdisk(DISK_WRITE,
43219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           part->phys,
43319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           chs.head,
43419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           chs.cyl,
43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           chs.sector,
43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           size < 512 ? 1 : size/512,
43719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project                           (void*)buf);
43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  if(!HW_OK())
44019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  {
44119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    _dio_error = ERR_HARDWARE;
44219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project    return EFAULT;
44319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  }
44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  return 0;
44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __TURBOC__
44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#pragma argsused
45019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t dos_flush(io_channel channel)
45219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  /*
45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   * No buffers, no flush...
45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project   */
45619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project  return 0;
45719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
458