summaryrefslogtreecommitdiff
path: root/rbutil
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2009-08-04 20:32:30 +0000
committerDave Chapman <dave@dchapman.com>2009-08-04 20:32:30 +0000
commit1eca02d86384bd399f3d3b0fce5e6be48ce8156f (patch)
tree64ef1c7da7c4986bc4ebda1b543ec3b22ff5ab23 /rbutil
parent71f0814e52df8d862b2658fd3075c3020347d0fd (diff)
downloadrockbox-1eca02d86384bd399f3d3b0fce5e6be48ce8156f.tar.gz
rockbox-1eca02d86384bd399f3d3b0fce5e6be48ce8156f.zip
Add support (on Linux and win32 only - I couldn't figure this out on OS X) for reading the XML device information from ipods. This information includes the RAM size, which is potentially useful for rbutil to distinguish between the two ipod video builds. This is implemented as both a new --dump-xml option (to dump the entire XML to a file) and a new 'ramsize' field in struct ipod_t.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22165 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'rbutil')
-rw-r--r--rbutil/ipodpatcher/Makefile4
-rw-r--r--rbutil/ipodpatcher/ipodio-posix.c63
-rw-r--r--rbutil/ipodpatcher/ipodio-win32-scsi.c118
-rw-r--r--rbutil/ipodpatcher/ipodio-win32.c4
-rw-r--r--rbutil/ipodpatcher/ipodio.h5
-rw-r--r--rbutil/ipodpatcher/ipodpatcher.c80
-rw-r--r--rbutil/ipodpatcher/ipodpatcher.h2
-rw-r--r--rbutil/ipodpatcher/main.c50
8 files changed, 319 insertions, 7 deletions
diff --git a/rbutil/ipodpatcher/Makefile b/rbutil/ipodpatcher/Makefile
index 263d64ed01..9c32587fa1 100644
--- a/rbutil/ipodpatcher/Makefile
+++ b/rbutil/ipodpatcher/Makefile
@@ -36,8 +36,8 @@ ipodpatcher: $(SRC) ipodio-posix.c $(BOOTSRC)
36 gcc $(CFLAGS) -o ipodpatcher $(SRC) ipodio-posix.c $(BOOTSRC) 36 gcc $(CFLAGS) -o ipodpatcher $(SRC) ipodio-posix.c $(BOOTSRC)
37 strip ipodpatcher 37 strip ipodpatcher
38 38
39ipodpatcher.exe: $(SRC) ipodio-win32.c ipodpatcher-rc.o $(BOOTSRC) 39ipodpatcher.exe: $(SRC) ipodio-win32.c ipodio-win32-scsi.c ipodpatcher-rc.o $(BOOTSRC)
40 $(CC) $(CFLAGS) -o ipodpatcher.exe $(SRC) ipodio-win32.c ipodpatcher-rc.o $(BOOTSRC) 40 $(CC) $(CFLAGS) -o ipodpatcher.exe $(SRC) ipodio-win32.c ipodio-win32-scsi.c ipodpatcher-rc.o $(BOOTSRC)
41 $(CROSS)strip ipodpatcher.exe 41 $(CROSS)strip ipodpatcher.exe
42 42
43ipodpatcher-rc.o: ipodpatcher.rc ipodpatcher.manifest 43ipodpatcher-rc.o: ipodpatcher.rc ipodpatcher.manifest
diff --git a/rbutil/ipodpatcher/ipodio-posix.c b/rbutil/ipodpatcher/ipodio-posix.c
index 6dfb09ed33..be048fc986 100644
--- a/rbutil/ipodpatcher/ipodio-posix.c
+++ b/rbutil/ipodpatcher/ipodio-posix.c
@@ -34,6 +34,9 @@
34#if defined(linux) || defined (__linux) 34#if defined(linux) || defined (__linux)
35#include <sys/mount.h> 35#include <sys/mount.h>
36#include <linux/hdreg.h> 36#include <linux/hdreg.h>
37#include <scsi/scsi_ioctl.h>
38#include <scsi/sg.h>
39
37#define IPOD_SECTORSIZE_IOCTL BLKSSZGET 40#define IPOD_SECTORSIZE_IOCTL BLKSSZGET
38 41
39static void get_geometry(struct ipod_t* ipod) 42static void get_geometry(struct ipod_t* ipod)
@@ -50,6 +53,51 @@ static void get_geometry(struct ipod_t* ipod)
50 } 53 }
51} 54}
52 55
56/* Linux SCSI Inquiry code based on the documentation and example code from
57 http://www.ibm.com/developerworks/linux/library/l-scsi-api/index.html
58*/
59
60int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
61 unsigned char* buf, int bufsize)
62{
63 unsigned char cdb[6];
64 struct sg_io_hdr hdr;
65 unsigned char sense_buffer[255];
66
67 memset(&hdr, 0, sizeof(hdr));
68
69 hdr.interface_id = 'S'; /* this is the only choice we have! */
70 hdr.flags = SG_FLAG_LUN_INHIBIT; /* this would put the LUN to 2nd byte of cdb*/
71
72 /* Set xfer data */
73 hdr.dxferp = buf;
74 hdr.dxfer_len = bufsize;
75
76 /* Set sense data */
77 hdr.sbp = sense_buffer;
78 hdr.mx_sb_len = sizeof(sense_buffer);
79
80 /* Set the cdb format */
81 cdb[0] = 0x12;
82 cdb[1] = 1; /* Enable Vital Product Data (EVPD) */
83 cdb[2] = page_code & 0xff;
84 cdb[3] = 0;
85 cdb[4] = 0xff;
86 cdb[5] = 0; /* For control filed, just use 0 */
87
88 hdr.dxfer_direction = SG_DXFER_FROM_DEV;
89 hdr.cmdp = cdb;
90 hdr.cmd_len = 6;
91
92 int ret = ioctl(ipod->dh, SG_IO, &hdr);
93
94 if (ret < 0) {
95 return -1;
96 } else {
97 return 0;
98 }
99}
100
53#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \ 101#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) \
54 || defined(__bsdi__) || defined(__DragonFly__) 102 || defined(__bsdi__) || defined(__DragonFly__)
55#include <sys/disk.h> 103#include <sys/disk.h>
@@ -63,6 +111,13 @@ static void get_geometry(struct ipod_t* ipod)
63 ipod->sectors_per_track = 63; 111 ipod->sectors_per_track = 63;
64} 112}
65 113
114int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
115 unsigned char* buf, int bufsize)
116{
117 /* TODO: Implement for BSD */
118 return -1;
119}
120
66#elif defined(__APPLE__) && defined(__MACH__) 121#elif defined(__APPLE__) && defined(__MACH__)
67#include <sys/disk.h> 122#include <sys/disk.h>
68#define IPOD_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE 123#define IPOD_SECTORSIZE_IOCTL DKIOCGETBLOCKSIZE
@@ -75,6 +130,13 @@ static void get_geometry(struct ipod_t* ipod)
75 ipod->sectors_per_track = 63; 130 ipod->sectors_per_track = 63;
76} 131}
77 132
133int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
134 unsigned char* buf, int bufsize)
135{
136 /* TODO: Implement for OS X */
137 return -1;
138}
139
78#else 140#else
79 #error No sector-size detection implemented for this platform 141 #error No sector-size detection implemented for this platform
80#endif 142#endif
@@ -180,3 +242,4 @@ ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes)
180{ 242{
181 return write(ipod->dh, buf, nbytes); 243 return write(ipod->dh, buf, nbytes);
182} 244}
245
diff --git a/rbutil/ipodpatcher/ipodio-win32-scsi.c b/rbutil/ipodpatcher/ipodio-win32-scsi.c
new file mode 100644
index 0000000000..5843ce5d2f
--- /dev/null
+++ b/rbutil/ipodpatcher/ipodio-win32-scsi.c
@@ -0,0 +1,118 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: ipodio-win32.c 17847 2008-06-28 18:10:04Z bagder $
9 *
10 * Copyright (C) 2009 Dave Chapman
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 *
21 * Based on the getCapsUsingSCSIPassThrough() function from "cddrv.cpp":
22 * - http://www.farmanager.com/svn/trunk/unicode_far/cddrv.cpp
23 *
24 * Copyright (c) 1996 Eugene Roshal
25 * Copyright (c) 2000 Far Group
26 * All rights reserved.
27 *
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
30 * are met:
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. The name of the authors may not be used to endorse or promote products
37 * derived from this software without specific prior written permission.
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
40 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
42 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
43 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
46 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
48 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49 *
50 ****************************************************************************/
51
52#include <windows.h>
53#include <stddef.h>
54#include <stdio.h>
55#include <ddk/ntddscsi.h>
56
57#include "ipodio.h"
58
59typedef struct _SCSI_PASS_THROUGH_WITH_BUFFERS {
60 SCSI_PASS_THROUGH Spt;
61 ULONG Filler; /* realign buffers to double word boundary */
62 UCHAR SenseBuf[32];
63 UCHAR DataBuf[512];
64} SCSI_PASS_THROUGH_WITH_BUFFERS, *PSCSI_PASS_THROUGH_WITH_BUFFERS;
65
66int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
67 unsigned char* buf, int bufsize)
68{
69 SCSI_PASS_THROUGH_WITH_BUFFERS sptwb;
70 ULONG length;
71 DWORD returned;
72 BOOL status;
73
74 if (bufsize > 255) {
75 fprintf(stderr,"[ERR] Invalid bufsize in ipod_scsi_inquiry\n");
76 return -1;
77 }
78
79 memset(&sptwb, 0, sizeof(sptwb));
80
81 sptwb.Spt.Length = sizeof(SCSI_PASS_THROUGH);
82 sptwb.Spt.PathId = 0;
83 sptwb.Spt.TargetId = 1;
84 sptwb.Spt.Lun = 0;
85 sptwb.Spt.CdbLength = 6;
86 sptwb.Spt.SenseInfoLength = 32; /* sbuf size */;
87 sptwb.Spt.DataIn = SCSI_IOCTL_DATA_IN;
88 sptwb.Spt.DataTransferLength = bufsize;
89 sptwb.Spt.TimeOutValue = 2; /* 2 seconds */
90 sptwb.Spt.DataBufferOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf);
91 sptwb.Spt.SenseInfoOffset = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, SenseBuf);
92 length = offsetof(SCSI_PASS_THROUGH_WITH_BUFFERS, DataBuf) +
93 sptwb.Spt.DataTransferLength;
94
95 /* Set cdb info */
96 sptwb.Spt.Cdb[0] = 0x12; /* SCSI Inquiry */
97 sptwb.Spt.Cdb[1] = 1;
98 sptwb.Spt.Cdb[2] = page_code;
99 sptwb.Spt.Cdb[3] = 0;
100 sptwb.Spt.Cdb[4] = bufsize;
101 sptwb.Spt.Cdb[5] = 0;
102
103 status = DeviceIoControl(ipod->dh,
104 IOCTL_SCSI_PASS_THROUGH,
105 &sptwb,
106 sizeof(SCSI_PASS_THROUGH),
107 &sptwb,
108 length,
109 &returned,
110 FALSE);
111
112 if (status) {
113 memcpy(buf, sptwb.DataBuf, returned);
114 return 0;
115 } else {
116 return -1;
117 }
118}
diff --git a/rbutil/ipodpatcher/ipodio-win32.c b/rbutil/ipodpatcher/ipodio-win32.c
index ceec4a3d6c..5125c070f8 100644
--- a/rbutil/ipodpatcher/ipodio-win32.c
+++ b/rbutil/ipodpatcher/ipodio-win32.c
@@ -32,10 +32,9 @@
32#include <stdlib.h> 32#include <stdlib.h>
33#include <sys/types.h> 33#include <sys/types.h>
34#include <sys/stat.h> 34#include <sys/stat.h>
35#ifdef __WIN32__
36#include <windows.h> 35#include <windows.h>
36#include <stddef.h>
37#include <winioctl.h> 37#include <winioctl.h>
38#endif
39 38
40#include "ipodio.h" 39#include "ipodio.h"
41 40
@@ -201,3 +200,4 @@ ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes)
201 200
202 return count; 201 return count;
203} 202}
203
diff --git a/rbutil/ipodpatcher/ipodio.h b/rbutil/ipodpatcher/ipodio.h
index dbd3d5e1ff..e0692ca6d9 100644
--- a/rbutil/ipodpatcher/ipodio.h
+++ b/rbutil/ipodpatcher/ipodio.h
@@ -80,6 +80,9 @@ struct ipod_t {
80 char* modelstr; 80 char* modelstr;
81 char* targetname; 81 char* targetname;
82 int macpod; 82 int macpod;
83 char* xmlinfo; /* The XML Device Information (if available) */
84 int xmlinfo_len;
85 int ramsize; /* The amount of RAM in the ipod (if available) */
83#ifdef WITH_BOOTOBJS 86#ifdef WITH_BOOTOBJS
84 unsigned char* bootloader; 87 unsigned char* bootloader;
85 int bootloader_len; 88 int bootloader_len;
@@ -91,6 +94,8 @@ int ipod_open(struct ipod_t* ipod, int silent);
91int ipod_reopen_rw(struct ipod_t* ipod); 94int ipod_reopen_rw(struct ipod_t* ipod);
92int ipod_close(struct ipod_t* ipod); 95int ipod_close(struct ipod_t* ipod);
93int ipod_seek(struct ipod_t* ipod, unsigned long pos); 96int ipod_seek(struct ipod_t* ipod, unsigned long pos);
97int ipod_scsi_inquiry(struct ipod_t* ipod, int page_code,
98 unsigned char* buf, int bufsize);
94ssize_t ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes); 99ssize_t ipod_read(struct ipod_t* ipod, unsigned char* buf, int nbytes);
95ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes); 100ssize_t ipod_write(struct ipod_t* ipod, unsigned char* buf, int nbytes);
96int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize); 101int ipod_alloc_buffer(unsigned char** sectorbuf, int bufsize);
diff --git a/rbutil/ipodpatcher/ipodpatcher.c b/rbutil/ipodpatcher/ipodpatcher.c
index dd650506a1..1a5268bb6d 100644
--- a/rbutil/ipodpatcher/ipodpatcher.c
+++ b/rbutil/ipodpatcher/ipodpatcher.c
@@ -1401,6 +1401,86 @@ int write_dos_partition_table(struct ipod_t* ipod)
1401 return 0; 1401 return 0;
1402} 1402}
1403 1403
1404/* Get the XML Device Information, as documented here:
1405
1406 http://www.ipodlinux.org/wiki/Device_Information
1407*/
1408
1409int ipod_get_xmlinfo(struct ipod_t* ipod)
1410{
1411 unsigned char hdr[255];
1412 unsigned char buf[255];
1413 char* p;
1414 int psize;
1415 int npages;
1416 int i;
1417
1418 if (ipod_scsi_inquiry(ipod, 0xc0, buf, sizeof(buf)) < 0)
1419 {
1420 fprintf(stderr,"[ERR] Sending SCSI Command failed.\n");
1421 return -1;
1422 }
1423
1424 /* Reading directly into hdr[] causes problems (for an unknown reason) on
1425 win32 */
1426 memcpy(hdr, buf, sizeof(hdr));
1427
1428 npages = hdr[3];
1429
1430 psize = npages * 0xf8; /* Hopefully this is enough. */
1431
1432 ipod->xmlinfo = malloc(psize);
1433 ipod->xmlinfo_len = 0;
1434
1435 if (ipod->xmlinfo == NULL) {
1436 fprintf(stderr,"[ERR] Could not allocate RAM for xmlinfo\n");
1437 return -1;
1438 }
1439
1440 p = ipod->xmlinfo;
1441
1442 for (i=0; i < npages; i++) {
1443 if (ipod_scsi_inquiry(ipod, hdr[i+4], buf, sizeof(buf)) < 0) {
1444 fprintf(stderr,"[ERR] Sending SCSI Command failed.\n");
1445 return -1;
1446 }
1447
1448 if ((buf[3] + ipod->xmlinfo_len) > psize) {
1449 fprintf(stderr,"[ERR] Ran out of memory reading xmlinfo\n");
1450 free(ipod->xmlinfo);
1451 ipod->xmlinfo = NULL;
1452 ipod->xmlinfo_len = 0;
1453 return -1;
1454 }
1455
1456 memcpy(p, buf + 4, buf[3]);
1457 p += buf[3];
1458 ipod->xmlinfo_len += buf[3];
1459 }
1460
1461 /* NULL-terminate the XML info */
1462 *p = 0;
1463
1464 fprintf(stderr,"[INFO] Read XML info (%d bytes)\n",ipod->xmlinfo_len);
1465
1466 return 0;
1467}
1468
1469void ipod_get_ramsize(struct ipod_t* ipod)
1470{
1471 const char needle[] = "<key>RAM</key>\n<integer>";
1472 char* p;
1473
1474 if (ipod->xmlinfo == NULL)
1475 return;
1476
1477 p = strstr(ipod->xmlinfo, needle);
1478
1479 if (p) {
1480 ipod->ramsize = atoi(p + sizeof(needle) - 1);
1481 }
1482}
1483
1404#ifndef RBUTIL 1484#ifndef RBUTIL
1405 1485
1406static inline uint32_t getuint32le(unsigned char* buf) 1486static inline uint32_t getuint32le(unsigned char* buf)
diff --git a/rbutil/ipodpatcher/ipodpatcher.h b/rbutil/ipodpatcher/ipodpatcher.h
index bb80ba3758..3fbb83ca9e 100644
--- a/rbutil/ipodpatcher/ipodpatcher.h
+++ b/rbutil/ipodpatcher/ipodpatcher.h
@@ -54,6 +54,8 @@ int list_images(struct ipod_t* ipod);
54int getmodel(struct ipod_t* ipod, int ipod_version); 54int getmodel(struct ipod_t* ipod, int ipod_version);
55int ipod_scan(struct ipod_t* ipod); 55int ipod_scan(struct ipod_t* ipod);
56int write_dos_partition_table(struct ipod_t* ipod); 56int write_dos_partition_table(struct ipod_t* ipod);
57int ipod_get_xmlinfo(struct ipod_t* ipod);
58void ipod_get_ramsize(struct ipod_t* ipod);
57int read_aupd(struct ipod_t* ipod, char* filename); 59int read_aupd(struct ipod_t* ipod, char* filename);
58int write_aupd(struct ipod_t* ipod, char* filename); 60int write_aupd(struct ipod_t* ipod, char* filename);
59off_t filesize(int fd); 61off_t filesize(int fd);
diff --git a/rbutil/ipodpatcher/main.c b/rbutil/ipodpatcher/main.c
index 88ac3a60e1..1dcb916240 100644
--- a/rbutil/ipodpatcher/main.c
+++ b/rbutil/ipodpatcher/main.c
@@ -50,6 +50,7 @@ enum {
50 READ_PARTITION, 50 READ_PARTITION,
51 WRITE_PARTITION, 51 WRITE_PARTITION,
52 FORMAT_PARTITION, 52 FORMAT_PARTITION,
53 DUMP_XML,
53 CONVERT_TO_FAT32 54 CONVERT_TO_FAT32
54}; 55};
55 56
@@ -93,6 +94,7 @@ void print_usage(void)
93 fprintf(stderr," -c, --convert\n"); 94 fprintf(stderr," -c, --convert\n");
94 fprintf(stderr," --read-aupd filename.bin\n"); 95 fprintf(stderr," --read-aupd filename.bin\n");
95 fprintf(stderr," --write-aupd filename.bin\n"); 96 fprintf(stderr," --write-aupd filename.bin\n");
97 fprintf(stderr," -x --dump-xml filename.xml\n");
96 fprintf(stderr,"\n"); 98 fprintf(stderr,"\n");
97 99
98#ifdef __WIN32__ 100#ifdef __WIN32__
@@ -315,6 +317,13 @@ int main(int argc, char* argv[])
315 if (i == argc) { print_usage(); return 1; } 317 if (i == argc) { print_usage(); return 1; }
316 filename=argv[i]; 318 filename=argv[i];
317 i++; 319 i++;
320 } else if ((strcmp(argv[i],"-x")==0) ||
321 (strcmp(argv[i],"--dump-xml")==0)) {
322 action = DUMP_XML;
323 i++;
324 if (i == argc) { print_usage(); return 1; }
325 filename=argv[i];
326 i++;
318 } else if ((strcmp(argv[i],"-c")==0) || 327 } else if ((strcmp(argv[i],"-c")==0) ||
319 (strcmp(argv[i],"--convert")==0)) { 328 (strcmp(argv[i],"--convert")==0)) {
320 action = CONVERT_TO_FAT32; 329 action = CONVERT_TO_FAT32;
@@ -361,8 +370,26 @@ int main(int argc, char* argv[])
361 return -1; 370 return -1;
362 } 371 }
363 372
364 printf("[INFO] Ipod model: %s (\"%s\")\n",ipod.modelstr, 373#ifdef __WIN32__
365 ipod.macpod ? "macpod" : "winpod"); 374 /* Windows requires the ipod in R/W mode for SCSI Inquiry */
375 if (ipod_reopen_rw(&ipod) < 0) {
376 return 5;
377 }
378#endif
379
380
381 /* Read the XML info, and if successful, look for the ramsize
382 (only available for some models - set to 0 if not known) */
383
384 ipod.ramsize = 0;
385
386 if (ipod_get_xmlinfo(&ipod) == 0) {
387 ipod_get_ramsize(&ipod);
388 }
389
390 printf("[INFO] Ipod model: %s ",ipod.modelstr);
391 if (ipod.ramsize > 0) { printf("(%dMB RAM) ",ipod.ramsize); }
392 printf("(\"%s\")\n",ipod.macpod ? "macpod" : "winpod");
366 393
367 if (ipod.ipod_directory[0].vers == 0x10000) { 394 if (ipod.ipod_directory[0].vers == 0x10000) {
368 fprintf(stderr,"[ERR] *** ipodpatcher does not support the 2nd Generation Nano! ***\n"); 395 fprintf(stderr,"[ERR] *** ipodpatcher does not support the 2nd Generation Nano! ***\n");
@@ -476,6 +503,24 @@ int main(int argc, char* argv[])
476 } else { 503 } else {
477 fprintf(stderr,"[ERR] --write-aupd failed.\n"); 504 fprintf(stderr,"[ERR] --write-aupd failed.\n");
478 } 505 }
506 } else if (action==DUMP_XML) {
507 if (ipod.xmlinfo == NULL) {
508 fprintf(stderr,"[ERR] No XML to write\n");
509 return 1;
510 }
511
512 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE);
513 if (outfile < 0) {
514 perror(filename);
515 return 4;
516 }
517
518 if (write(outfile, ipod.xmlinfo, ipod.xmlinfo_len) < 0) {
519 fprintf(stderr,"[ERR] --dump-xml failed.\n");
520 } else {
521 fprintf(stderr,"[INFO] XML info written to %s.\n",filename);
522 }
523 close(outfile);
479 } else if (action==READ_PARTITION) { 524 } else if (action==READ_PARTITION) {
480 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE); 525 outfile = open(filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IREAD|S_IWRITE);
481 if (outfile < 0) { 526 if (outfile < 0) {
@@ -571,6 +616,5 @@ int main(int argc, char* argv[])
571 } 616 }
572#endif 617#endif
573 618
574
575 return 0; 619 return 0;
576} 620}