1
0
Fork 0
forked from len0rd/rockbox

Move ipodpatcher into rbutil directory

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12263 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Dave Chapman 2007-02-10 19:49:43 +00:00
parent f0efde2303
commit 955afed1b7
9 changed files with 0 additions and 0 deletions

View file

@ -0,0 +1,61 @@
CFLAGS=-Wall
BOOT_H = ipod3g.h ipod4g.h ipodcolor.h ipodmini.h ipodmini2g.h ipodnano.h ipodvideo.h
# Uncomment the next two lines to build with embedded bootloaders and the
# --install option and interactive mode. You need the full set of Rockbox
# bootloaders in this directory - download them from
# http://download.rockbox.org/bootloader/ipod/bootloaders.zip
#BOOTSRC = ipod3g.c ipod4g.c ipodcolor.c ipodmini.c ipodmini2g.c ipodnano.c ipodvideo.c
#CFLAGS += -DWITH_BOOTOBJS
ifeq ($(findstring CYGWIN,$(shell uname)),CYGWIN)
OUTPUT=ipodpatcher.exe
CROSS=
CFLAGS+=-mno-cygwin
else
OUTPUT=ipodpatcher
CROSS=i586-mingw32msvc-
endif
NATIVECC = gcc
CC = $(CROSS)gcc
all: $(OUTPUT)
ipodpatcher: main.c ipodpatcher.c ipodio-posix.c parttypes.h $(BOOTSRC)
gcc $(CFLAGS) -o ipodpatcher main.c ipodpatcher.c ipodio-posix.c $(BOOTSRC)
strip ipodpatcher
ipodpatcher.exe: main.c ipodpatcher.c ipodio-win32.c parttypes.h $(BOOTSRC)
$(CC) $(CFLAGS) -o ipodpatcher.exe main.c ipodpatcher.c ipodio-win32.c $(BOOTSRC)
$(CROSS)strip ipodpatcher.exe
ipod2c: ipod2c.c
$(NATIVECC) $(CFLAGS) -o ipod2c ipod2c.c
ipod3g.c: bootloader-ipod3g.ipod ipod2c
./ipod2c bootloader-ipod3g.ipod ipod3g
ipod4g.c: bootloader-ipod4g.ipod ipod2c
./ipod2c bootloader-ipod4g.ipod ipod4g
ipodcolor.c: bootloader-ipodcolor.ipod ipod2c
./ipod2c bootloader-ipodcolor.ipod ipodcolor
ipodmini.c: bootloader-ipodmini.ipod ipod2c
./ipod2c bootloader-ipodmini.ipod ipodmini
ipodmini2g.c: bootloader-ipodmini2g.ipod ipod2c
./ipod2c bootloader-ipodmini2g.ipod ipodmini2g
ipodnano.c: bootloader-ipodnano.ipod ipod2c
./ipod2c bootloader-ipodnano.ipod ipodnano
ipodvideo.c: bootloader-ipodvideo.ipod ipod2c
./ipod2c bootloader-ipodvideo.ipod ipodvideo
clean:
rm -f ipodpatcher.exe ipodpatcher ipod2c *~ $(BOOTSRC) $(BOOT_H)

139
rbutil/ipodpatcher/ipod2c.c Normal file
View file

@ -0,0 +1,139 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: ipodio-win32.c 12205 2007-02-05 01:20:20Z dave $
*
* Copyright (C) 2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#ifndef O_BINARY
#define O_BINARY 0
#endif
static off_t filesize(int fd)
{
struct stat buf;
fstat(fd,&buf);
return buf.st_size;
}
static int write_cfile(unsigned char* buf, off_t len, char* cname)
{
char filename[256];
FILE* fp;
int i;
snprintf(filename,256,"%s.c",cname);
fp = fopen(filename,"w+");
if (fp == NULL) {
fprintf(stderr,"Couldn't open %s\n",filename);
return -1;
}
fprintf(fp,"/* Generated by ipod2c */\n\n");
fprintf(fp,"unsigned char %s[] = {",cname);
for (i=0;i<len;i++) {
if ((i % 16) == 0) {
fprintf(fp,"\n ");
}
if (i == (len-1)) {
fprintf(fp,"0x%02x",buf[i]);
} else {
fprintf(fp,"0x%02x, ",buf[i]);
}
}
fprintf(fp,"\n};\n");
fclose(fp);
return 0;
}
static int write_hfile(unsigned char* buf, off_t len, char* cname)
{
char filename[256];
FILE* fp;
snprintf(filename,256,"%s.h",cname);
fp = fopen(filename,"w+");
if (fp == NULL) {
fprintf(stderr,"Couldn't open %s\n",filename);
return -1;
}
fprintf(fp,"/* Generated by ipod2c */\n\n");
fprintf(fp,"#define LEN_%s %d\n",cname,(int)len);
fprintf(fp,"extern unsigned char %s[];\n",cname);
fclose(fp);
return 0;
}
int main (int argc, char* argv[])
{
char* infile;
char* cname;
int fd;
unsigned char* buf;
int len;
int n;
if (argc != 3) {
fprintf(stderr,"Usage: ipod2c file.bin cname\n");
return 0;
}
infile=argv[1];
cname=argv[2];
fd = open(infile,O_RDONLY);
if (fd < 0) {
fprintf(stderr,"Can not open %s\n",infile);
return 0;
}
len = filesize(fd) - 8;
n = lseek(fd,8,SEEK_SET);
if (n != 8) {
fprintf(stderr,"Seek failed\n");
return 0;
}
buf = malloc(len);
n = read(fd,buf,len);
if (n < len) {
fprintf(stderr,"Short read, aborting\n");
return 0;
}
close(fd);
if (write_cfile(buf,len,cname) < 0) {
return -1;
}
if (write_hfile(buf,len,cname) < 0) {
return -1;
}
return 0;
}

View file

@ -0,0 +1,115 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006-2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#if defined(linux) || defined (__linux)
#include <sys/mount.h>
#define IPOD_SECTORSIZE_IOCTL BLKSSZGET
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
|| defined(__bsdi__) || defined(__DragonFly__)
#include <sys/disk.h>
#define IPOD_SECTORSIZE_IOCTL DIOCGSECTORSIZE
#elif defined(__APPLE__) && defined(__MACH__)
#include <sys/disk.h>
#define IPOD_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
#else
#error No sector-size detection implemented for this platform
#endif
#include "ipodio.h"
void print_error(char* msg)
{
perror(msg);
}
int ipod_open(struct ipod_t* ipod, int silent)
{
ipod->dh=open(ipod->diskname,O_RDONLY);
if (ipod->dh < 0) {
if (!silent) perror(ipod->diskname);
return -1;
}
if(ioctl(ipod->dh,IPOD_SECTORSIZE_IOCTL,&ipod->sector_size) < 0) {
ipod->sector_size=512;
if (!silent) {
fprintf(stderr,"[ERR] ioctl() call to get sector size failed, defaulting to %d\n"
,ipod->sector_size);
}
}
return 0;
}
int ipod_reopen_rw(struct ipod_t* ipod)
{
close(ipod->dh);
ipod->dh=open(ipod->diskname,O_RDWR);
if (ipod->dh < 0) {
perror(ipod->diskname);
return -1;
}
return 0;
}
int ipod_close(struct ipod_t* ipod)
{
close(ipod->dh);
return 0;
}
int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize)
{
*sectorbuf=malloc(bufsize);
if (*sectorbuf == NULL) {
return -1;
}
return 0;
}
int ipod_seek(struct ipod_t* ipod, unsigned long pos)
{
off_t res;
res = lseek(ipod->dh, pos, SEEK_SET);
if (res == -1) {
return -1;
}
return 0;
}
int ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes)
{
return read(ipod->dh, buf, nbytes);
}
int ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes)
{
return write(ipod->dh, buf, nbytes);
}

View file

@ -0,0 +1,190 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006-2007 Dave Chapman
*
* error(), lock_volume() and unlock_volume() functions and inspiration taken
* from:
* RawDisk - Direct Disk Read/Write Access for NT/2000/XP
* Copyright (c) 2003 Jan Kiszka
* http://www.stud.uni-hannover.de/user/73174/RawDisk/
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifdef __WIN32__
#include <windows.h>
#include <winioctl.h>
#endif
#include "ipodio.h"
static int lock_volume(HANDLE hDisk)
{
DWORD dummy;
return DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0,
&dummy, NULL);
}
static int unlock_volume(HANDLE hDisk)
{
DWORD dummy;
return DeviceIoControl(hDisk, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0,
&dummy, NULL);
}
void print_error(char* msg)
{
char* pMsgBuf;
printf(msg);
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&pMsgBuf,
0, NULL);
printf(pMsgBuf);
LocalFree(pMsgBuf);
}
int ipod_open(struct ipod_t* ipod, int silent)
{
DISK_GEOMETRY_EX diskgeometry_ex;
DISK_GEOMETRY diskgeometry;
unsigned long n;
ipod->dh = CreateFile(ipod->diskname, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
if (ipod->dh == INVALID_HANDLE_VALUE) {
if (!silent) print_error(" Error opening disk: ");
return -1;
}
if (!lock_volume(ipod->dh)) {
if (!silent) print_error(" Error locking disk: ");
return -1;
}
if (!DeviceIoControl(ipod->dh,
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
NULL,
0,
&diskgeometry_ex,
sizeof(diskgeometry_ex),
&n,
NULL)) {
if (!DeviceIoControl(ipod->dh,
IOCTL_DISK_GET_DRIVE_GEOMETRY,
NULL,
0,
&diskgeometry,
sizeof(diskgeometry),
&n,
NULL)) {
if (!silent) print_error(" Error reading disk geometry: ");
return -1;
} else {
ipod->sector_size=diskgeometry.BytesPerSector;
}
} else {
ipod->sector_size=diskgeometry_ex.Geometry.BytesPerSector;
}
return 0;
}
int ipod_reopen_rw(struct ipod_t* ipod)
{
/* Close existing file and re-open for writing */
unlock_volume(ipod->dh);
CloseHandle(ipod->dh);
ipod->dh = CreateFile(ipod->diskname, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, NULL);
if (ipod->dh == INVALID_HANDLE_VALUE) {
print_error(" Error opening disk: ");
return -1;
}
if (!lock_volume(ipod->dh)) {
print_error(" Error locking disk: ");
return -1;
}
return 0;
}
int ipod_close(struct ipod_t* ipod)
{
unlock_volume(ipod->dh);
CloseHandle(ipod->dh);
return 0;
}
int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize)
{
/* The ReadFile function requires a memory buffer aligned to a multiple of
the disk sector size. */
*sectorbuf = (unsigned char*)VirtualAlloc(NULL, bufsize, MEM_COMMIT, PAGE_READWRITE);
if (*sectorbuf == NULL) {
print_error(" Error allocating a buffer: ");
return -1;
}
return 0;
}
int ipod_seek(struct ipod_t* ipod, unsigned long pos)
{
if (SetFilePointer(ipod->dh, pos, NULL, FILE_BEGIN)==0xffffffff) {
print_error(" Seek error ");
return -1;
}
return 0;
}
int ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes)
{
unsigned long count;
if (!ReadFile(ipod->dh, buf, nbytes, &count, NULL)) {
print_error(" Error reading from disk: ");
return -1;
}
return count;
}
int ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes)
{
unsigned long count;
if (!WriteFile(ipod->dh, buf, nbytes, &count, NULL)) {
print_error(" Error writing to disk: ");
return -1;
}
return count;
}

View file

@ -0,0 +1,89 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (C) 2006-2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef __IPODIO_H
#define __IPODIO_H
#include <stdint.h>
#ifdef __WIN32__
#include <windows.h>
#else
#define HANDLE int
#define O_BINARY 0
#endif
/* The maximum number of images in a firmware partition - a guess... */
#define MAX_IMAGES 10
enum firmwaretype_t {
FTYPE_OSOS = 0,
FTYPE_RSRC,
FTYPE_AUPD,
FTYPE_HIBE
};
struct ipod_directory_t {
enum firmwaretype_t ftype;
int id;
uint32_t devOffset; /* Offset of image relative to one sector into bootpart*/
uint32_t len;
uint32_t addr;
uint32_t entryOffset;
uint32_t chksum;
uint32_t vers;
uint32_t loadAddr;
};
struct partinfo_t {
unsigned long start; /* first sector (LBA) */
unsigned long size; /* number of sectors */
int type;
};
struct ipod_t {
HANDLE dh;
char diskname[4096];
int sector_size;
struct ipod_directory_t ipod_directory[MAX_IMAGES];
int nimages;
off_t diroffset;
off_t start; /* Offset in bytes of firmware partition from start of disk */
off_t fwoffset; /* Offset in bytes of start of firmware images from start of disk */
struct partinfo_t pinfo[4];
int modelnum;
char* modelname;
char* modelstr;
int macpod;
#ifdef WITH_BOOTOBJS
unsigned char* bootloader;
int bootloader_len;
#endif
};
void print_error(char* msg);
int ipod_open(struct ipod_t* ipod, int silent);
int ipod_reopen_rw(struct ipod_t* ipod);
int ipod_close(struct ipod_t* ipod);
int ipod_seek(struct ipod_t* ipod, unsigned long pos);
int ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes);
int ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes);
int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: ipodpatcher.c 12237 2007-02-08 21:31:38Z dave $
*
* Copyright (C) 2006-2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#ifndef _IPODPATCHER_H
#define _IPODPATCHER_H
#include "ipodio.h"
/* Size of buffer for disk I/O - 8MB is large enough for any version
of the Apple firmware, but not the Nano's RSRC image. */
#define BUFFER_SIZE 8*1024*1024
extern unsigned char* sectorbuf;
#define FILETYPE_DOT_IPOD 0
#define FILETYPE_DOT_BIN 1
#ifdef WITH_BOOTOBJS
#define FILETYPE_INTERNAL 2
#endif
void display_partinfo(struct ipod_t* ipod);
int read_partinfo(struct ipod_t* ipod, int silent);
int read_partition(struct ipod_t* ipod, int outfile);
int write_partition(struct ipod_t* ipod, int infile);
int diskmove(struct ipod_t* ipod, int delta);
int add_bootloader(struct ipod_t* ipod, char* filename, int type);
int delete_bootloader(struct ipod_t* ipod);
int write_firmware(struct ipod_t* ipod, char* filename, int type);
int read_firmware(struct ipod_t* ipod, char* filename);
int read_directory(struct ipod_t* ipod);
int list_images(struct ipod_t* ipod);
int getmodel(struct ipod_t* ipod, int ipod_version);
int ipod_scan(struct ipod_t* ipod);
off_t filesize(int fd);
#endif

429
rbutil/ipodpatcher/main.c Normal file
View file

@ -0,0 +1,429 @@
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id: ipodpatcher.c 12237 2007-02-08 21:31:38Z dave $
*
* Copyright (C) 2006-2007 Dave Chapman
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "ipodpatcher.h"
#include "ipodio.h"
#define VERSION "0.8 with r12194-070204 bootloaders"
int verbose = 0;
enum {
NONE,
#ifdef WITH_BOOTOBJS
INSTALL,
#endif
INTERACTIVE,
SHOW_INFO,
LIST_IMAGES,
DELETE_BOOTLOADER,
ADD_BOOTLOADER,
READ_FIRMWARE,
WRITE_FIRMWARE,
READ_PARTITION,
WRITE_PARTITION
};
void print_macpod_warning(void)
{
printf("[INFO] ************************************************************************\n");
printf("[INFO] *** WARNING FOR ROCKBOX USERS\n");
printf("[INFO] *** You must convert this ipod to FAT32 format (aka a \"winpod\")\n");
printf("[INFO] *** if you want to run Rockbox. Rockbox WILL NOT work on this ipod.\n");
printf("[INFO] *** See http://www.rockbox.org/twiki/bin/view/Main/IpodConversionToFAT32\n");
printf("[INFO] ************************************************************************\n");
}
void print_usage(void)
{
fprintf(stderr,"Usage: ipodpatcher --scan\n");
#ifdef __WIN32__
fprintf(stderr," or ipodpatcher [DISKNO] [action]\n");
#else
fprintf(stderr," or ipodpatcher [device] [action]\n");
#endif
fprintf(stderr,"\n");
fprintf(stderr,"Where [action] is one of the following options:\n");
#ifdef WITH_BOOTOBJS
fprintf(stderr," --install\n");
#endif
fprintf(stderr," -l, --list\n");
fprintf(stderr," -r, --read-partition bootpartition.bin\n");
fprintf(stderr," -w, --write-partition bootpartition.bin\n");
fprintf(stderr," -rf, --read-firmware filename.ipod\n");
fprintf(stderr," -wf, --write-firmware filename.ipod\n");
fprintf(stderr," -wfb, --write-firmware-bin filename.bin\n");
fprintf(stderr," -a, --add-bootloader filename.ipod\n");
fprintf(stderr," -ab, --add-bootloader-bin filename.bin\n");
fprintf(stderr," -d, --delete-bootloader\n");
fprintf(stderr,"\n");
#ifdef __WIN32__
fprintf(stderr,"DISKNO is the number (e.g. 2) Windows has assigned to your ipod's hard disk.\n");
fprintf(stderr,"The first hard disk in your computer (i.e. C:\\) will be disk 0, the next disk\n");
fprintf(stderr,"will be disk 1 etc. ipodpatcher will refuse to access a disk unless it\n");
fprintf(stderr,"can identify it as being an ipod.\n");
fprintf(stderr,"\n");
#else
#if defined(linux) || defined (__linux)
fprintf(stderr,"\"device\" is the device node (e.g. /dev/sda) assigned to your ipod.\n");
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
fprintf(stderr,"\"device\" is the device node (e.g. /dev/da1) assigned to your ipod.\n");
#elif defined(__APPLE__) && defined(__MACH__)
fprintf(stderr,"\"device\" is the device node (e.g. /dev/disk1) assigned to your ipod.\n");
#endif
fprintf(stderr,"ipodpatcher will refuse to access a disk unless it can identify it as being\n");
fprintf(stderr,"an ipod.\n");
#endif
}
int main(int argc, char* argv[])
{
#ifdef WITH_BOOTOBJS
char yesno[4];
#endif
int i;
int n;
int infile, outfile;
unsigned int inputsize;
char* filename;
int action = SHOW_INFO;
int type;
struct ipod_t ipod;
fprintf(stderr,"ipodpatcher v" VERSION " - (C) Dave Chapman 2006-2007\n");
fprintf(stderr,"This is free software; see the source for copying conditions. There is NO\n");
fprintf(stderr,"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n");
if ((argc > 1) && ((strcmp(argv[1],"-h")==0) || (strcmp(argv[1],"--help")==0))) {
print_usage();
return 1;
}
if (ipod_alloc_buffer(&sectorbuf,BUFFER_SIZE) < 0) {
fprintf(stderr,"Failed to allocate memory buffer\n");
}
if ((argc > 1) && (strcmp(argv[1],"--scan")==0)) {
if (ipod_scan(&ipod) == 0)
fprintf(stderr,"[ERR] No ipods found.\n");
return 0;
}
/* If the first parameter doesn't start with -, then we interpret it as a device */
if ((argc > 1) && (argv[1][0] != '-')) {
ipod.diskname[0]=0;
#ifdef __WIN32__
snprintf(ipod.diskname,sizeof(ipod.diskname),"\\\\.\\PhysicalDrive%s",argv[1]);
#else
strncpy(ipod.diskname,argv[1],sizeof(ipod.diskname));
#endif
i = 2;
} else {
/* Autoscan for ipods */
n = ipod_scan(&ipod);
if (n==0) {
fprintf(stderr,"[ERR] No ipods found, aborting\n");
fprintf(stderr,"[ERR] Please connect your ipod and ensure it is in disk mode\n");
#if defined(__APPLE__) && defined(__MACH__)
fprintf(stderr,"[ERR] Also ensure that itunes is closed, and that your ipod is not mounted.\n");
#elif !defined(__WIN32__)
if (geteuid()!=0) {
fprintf(stderr,"[ERR] You may also need to run ipodpatcher as root.\n");
}
#endif
fprintf(stderr,"[ERR] Please refer to the Rockbox manual if you continue to have problems.\n");
} else if (n > 1) {
fprintf(stderr,"[ERR] %d ipods found, aborting\n",n);
fprintf(stderr,"[ERR] Please connect only one ipod and re-run ipodpatcher.\n");
}
if (n != 1) {
#ifdef WITH_BOOTOBJS
if (argc==1) {
printf("\nPress ENTER to exit ipodpatcher :");
fgets(yesno,4,stdin);
}
#endif
return 0;
}
i = 1;
}
#ifdef WITH_BOOTOBJS
action = INTERACTIVE;
#else
action = NONE;
#endif
while (i < argc) {
if ((strcmp(argv[i],"-l")==0) || (strcmp(argv[i],"--list")==0)) {
action = LIST_IMAGES;
i++;
#ifdef WITH_BOOTOBJS
} else if (strcmp(argv[i],"--install")==0) {
action = INSTALL;
i++;
#endif
} else if ((strcmp(argv[i],"-d")==0) ||
(strcmp(argv[i],"--delete-bootloader")==0)) {
action = DELETE_BOOTLOADER;
i++;
} else if ((strcmp(argv[i],"-a")==0) ||
(strcmp(argv[i],"--add-bootloader")==0)) {
action = ADD_BOOTLOADER;
type = FILETYPE_DOT_IPOD;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
i++;
} else if ((strcmp(argv[i],"-ab")==0) ||
(strcmp(argv[i],"--add-bootloader-bin")==0)) {
action = ADD_BOOTLOADER;
type = FILETYPE_DOT_BIN;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
i++;
} else if ((strcmp(argv[i],"-rf")==0) ||
(strcmp(argv[i],"--read-firmware")==0)) {
action = READ_FIRMWARE;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
i++;
} else if ((strcmp(argv[i],"-wf")==0) ||
(strcmp(argv[i],"--write-firmware")==0)) {
action = WRITE_FIRMWARE;
type = FILETYPE_DOT_IPOD;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
i++;
} else if ((strcmp(argv[i],"-wfb")==0) ||
(strcmp(argv[i],"--write-firmware-bin")==0)) {
action = WRITE_FIRMWARE;
type = FILETYPE_DOT_BIN;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
i++;
} else if ((strcmp(argv[i],"-r")==0) ||
(strcmp(argv[i],"--read-partition")==0)) {
action = READ_PARTITION;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
i++;
} else if ((strcmp(argv[i],"-w")==0) ||
(strcmp(argv[i],"--write-partition")==0)) {
action = WRITE_PARTITION;
i++;
if (i == argc) { print_usage(); return 1; }
filename=argv[i];
i++;
} else if ((strcmp(argv[i],"-v")==0) ||
(strcmp(argv[i],"--verbose")==0)) {
verbose++;
i++;
} else {
print_usage(); return 1;
}
}
if (ipod.diskname[0]==0) {
print_usage();
return 1;
}
if (ipod_open(&ipod, 0) < 0) {
return 1;
}
fprintf(stderr,"[INFO] Reading partition table from %s\n",ipod.diskname);
fprintf(stderr,"[INFO] Sector size is %d bytes\n",ipod.sector_size);
if (read_partinfo(&ipod,0) < 0) {
return 2;
}
display_partinfo(&ipod);
if (ipod.pinfo[0].start==0) {
fprintf(stderr,"[ERR] No partition 0 on disk:\n");
display_partinfo(&ipod);
return 3;
}
read_directory(&ipod);
if (ipod.nimages <= 0) {
fprintf(stderr,"[ERR] Failed to read firmware directory - nimages=%d\n",ipod.nimages);
return 1;
}
if (getmodel(&ipod,(ipod.ipod_directory[0].vers>>8)) < 0) {
fprintf(stderr,"[ERR] Unknown version number in firmware (%08x)\n",
ipod.ipod_directory[0].vers);
return -1;
}
printf("[INFO] Ipod model: %s (\"%s\")\n",ipod.modelstr,
ipod.macpod ? "macpod" : "winpod");
if (ipod.macpod) {
print_macpod_warning();
}
if (action==LIST_IMAGES) {
list_images(&ipod);
#ifdef WITH_BOOTOBJS
} else if (action==INTERACTIVE) {
printf("Do you wish to install the rockbox bootloader? (y/n) :");
if (fgets(yesno,4,stdin)) {
if (yesno[0]=='y') {
if (ipod_reopen_rw(&ipod) < 0) {
return 5;
}
if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) {
fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
} else {
fprintf(stderr,"[ERR] --install failed.\n");
}
}
}
#endif
} else if (action==DELETE_BOOTLOADER) {
if (ipod_reopen_rw(&ipod) < 0) {
return 5;
}
if (ipod.ipod_directory[0].entryOffset==0) {
fprintf(stderr,"[ERR] No bootloader detected.\n");
} else {
if (delete_bootloader(&ipod)==0) {
fprintf(stderr,"[INFO] Bootloader removed.\n");
} else {
fprintf(stderr,"[ERR] --delete-bootloader failed.\n");
}
}
} else if (action==ADD_BOOTLOADER) {
if (ipod_reopen_rw(&ipod) < 0) {
return 5;
}
if (add_bootloader(&ipod, filename, type)==0) {
fprintf(stderr,"[INFO] Bootloader %s written to device.\n",filename);
} else {
fprintf(stderr,"[ERR] --add-bootloader failed.\n");
}
#ifdef WITH_BOOTOBJS
} else if (action==INSTALL) {
if (ipod_reopen_rw(&ipod) < 0) {
return 5;
}
if (add_bootloader(&ipod, NULL, FILETYPE_INTERNAL)==0) {
fprintf(stderr,"[INFO] Bootloader installed successfully.\n");
} else {
fprintf(stderr,"[ERR] --install failed.\n");
}
#endif
} else if (action==WRITE_FIRMWARE) {
if (ipod_reopen_rw(&ipod) < 0) {
return 5;
}
if (write_firmware(&ipod, filename,type)==0) {
fprintf(stderr,"[INFO] Firmware %s written to device.\n",filename);
} else {
fprintf(stderr,"[ERR] --write-firmware failed.\n");
}
} else if (action==READ_FIRMWARE) {
if (read_firmware(&ipod, filename)==0) {
fprintf(stderr,"[INFO] Firmware read to file %s.\n",filename);
} else {
fprintf(stderr,"[ERR] --read-firmware failed.\n");
}
} else if (action==READ_PARTITION) {
outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE);
if (outfile < 0) {
perror(filename);
return 4;
}
if (read_partition(&ipod, outfile) < 0) {
fprintf(stderr,"[ERR] --read-partition failed.\n");
} else {
fprintf(stderr,"[INFO] Partition extracted to %s.\n",filename);
}
close(outfile);
} else if (action==WRITE_PARTITION) {
if (ipod_reopen_rw(&ipod) < 0) {
return 5;
}
infile = open(filename,O_RDONLY|O_BINARY);
if (infile < 0) {
perror(filename);
return 2;
}
/* Check filesize is <= partition size */
inputsize=filesize(infile);
if (inputsize > 0) {
if (inputsize <= (ipod.pinfo[0].size*ipod.sector_size)) {
fprintf(stderr,"[INFO] Input file is %u bytes\n",inputsize);
if (write_partition(&ipod,infile) < 0) {
fprintf(stderr,"[ERR] --write-partition failed.\n");
} else {
fprintf(stderr,"[INFO] %s restored to partition\n",filename);
}
} else {
fprintf(stderr,"[ERR] File is too large for firmware partition, aborting.\n");
}
}
close(infile);
}
ipod_close(&ipod);
#ifdef WITH_BOOTOBJS
if (action==INTERACTIVE) {
printf("Press ENTER to exit ipodpatcher :");
fgets(yesno,4,stdin);
}
#endif
return 0;
}

View file

@ -0,0 +1,109 @@
/* DOS partition types - taken from fdisk */
struct parttype {
unsigned char type;
char *name;
};
struct parttype parttypes[] = {
{0x00, "Empty"},
{0x01, "FAT12"},
{0x02, "XENIX root"},
{0x03, "XENIX usr"},
{0x04, "FAT16 <32M"},
{0x05, "Extended"}, /* DOS 3.3+ extended partition */
{0x06, "FAT16"}, /* DOS 16-bit >=32M */
{0x07, "HPFS/NTFS"}, /* OS/2 IFS, eg, HPFS or NTFS or QNX */
{0x08, "AIX"}, /* AIX boot (AIX -- PS/2 port) or SplitDrive */
{0x09, "AIX bootable"}, /* AIX data or Coherent */
{0x0a, "OS/2 Boot Manager"},/* OS/2 Boot Manager */
{0x0b, "W95 FAT32"},
{0x0c, "W95 FAT32 (LBA)"},/* LBA really is `Extended Int 13h' */
{0x0e, "W95 FAT16 (LBA)"},
{0x0f, "W95 Ext'd (LBA)"},
{0x10, "OPUS"},
{0x11, "Hidden FAT12"},
{0x12, "Compaq diagnostics"},
{0x14, "Hidden FAT16 <32M"},
{0x16, "Hidden FAT16"},
{0x17, "Hidden HPFS/NTFS"},
{0x18, "AST SmartSleep"},
{0x1b, "Hidden W95 FAT32"},
{0x1c, "Hidden W95 FAT32 (LBA)"},
{0x1e, "Hidden W95 FAT16 (LBA)"},
{0x24, "NEC DOS"},
{0x39, "Plan 9"},
{0x3c, "PartitionMagic recovery"},
{0x40, "Venix 80286"},
{0x41, "PPC PReP Boot"},
{0x42, "SFS"},
{0x4d, "QNX4.x"},
{0x4e, "QNX4.x 2nd part"},
{0x4f, "QNX4.x 3rd part"},
{0x50, "OnTrack DM"},
{0x51, "OnTrack DM6 Aux1"}, /* (or Novell) */
{0x52, "CP/M"}, /* CP/M or Microport SysV/AT */
{0x53, "OnTrack DM6 Aux3"},
{0x54, "OnTrackDM6"},
{0x55, "EZ-Drive"},
{0x56, "Golden Bow"},
{0x5c, "Priam Edisk"},
{0x61, "SpeedStor"},
{0x63, "GNU HURD or SysV"}, /* GNU HURD or Mach or Sys V/386 (such as ISC UNIX) */
{0x64, "Novell Netware 286"},
{0x65, "Novell Netware 386"},
{0x70, "DiskSecure Multi-Boot"},
{0x75, "PC/IX"},
{0x80, "Old Minix"}, /* Minix 1.4a and earlier */
{0x81, "Minix / old Linux"},/* Minix 1.4b and later */
{0x82, "Linux swap / Solaris"},
{0x83, "Linux"},
{0x84, "OS/2 hidden C: drive"},
{0x85, "Linux extended"},
{0x86, "NTFS volume set"},
{0x87, "NTFS volume set"},
{0x88, "Linux plaintext"},
{0x8e, "Linux LVM"},
{0x93, "Amoeba"},
{0x94, "Amoeba BBT"}, /* (bad block table) */
{0x9f, "BSD/OS"}, /* BSDI */
{0xa0, "IBM Thinkpad hibernation"},
{0xa5, "FreeBSD"}, /* various BSD flavours */
{0xa6, "OpenBSD"},
{0xa7, "NeXTSTEP"},
{0xa8, "Darwin UFS"},
{0xa9, "NetBSD"},
{0xab, "Darwin boot"},
{0xb7, "BSDI fs"},
{0xb8, "BSDI swap"},
{0xbb, "Boot Wizard hidden"},
{0xbe, "Solaris boot"},
{0xbf, "Solaris"},
{0xc1, "DRDOS/sec (FAT-12)"},
{0xc4, "DRDOS/sec (FAT-16 < 32M)"},
{0xc6, "DRDOS/sec (FAT-16)"},
{0xc7, "Syrinx"},
{0xda, "Non-FS data"},
{0xdb, "CP/M / CTOS / ..."},/* CP/M or Concurrent CP/M or
Concurrent DOS or CTOS */
{0xde, "Dell Utility"}, /* Dell PowerEdge Server utilities */
{0xdf, "BootIt"}, /* BootIt EMBRM */
{0xe1, "DOS access"}, /* DOS access or SpeedStor 12-bit FAT
extended partition */
{0xe3, "DOS R/O"}, /* DOS R/O or SpeedStor */
{0xe4, "SpeedStor"}, /* SpeedStor 16-bit FAT extended
partition < 1024 cyl. */
{0xeb, "BeOS fs"},
{0xee, "EFI GPT"}, /* Intel EFI GUID Partition Table */
{0xef, "EFI (FAT-12/16/32)"},/* Intel EFI System Partition */
{0xf0, "Linux/PA-RISC boot"},/* Linux/PA-RISC boot loader */
{0xf1, "SpeedStor"},
{0xf4, "SpeedStor"}, /* SpeedStor large partition */
{0xf2, "DOS secondary"}, /* DOS 3.3+ secondary */
{0xfd, "Linux raid autodetect"},/* New (2.2.x) raid partition with
autodetect using persistent
superblock */
{0xfe, "LANstep"}, /* SpeedStor >1024 cyl. or LANstep */
{0xff, "BBT"}, /* Xenix Bad Block Table */
{ 0, 0 }
};