Index: tools/ipodscsi/ipodscsi.rc |
— | — | @@ -0,0 +1 @@ |
| 2 | +1 24 MOVEABLE PURE "ipodscsi.exe.manifest"
|
Index: tools/ipodscsi/ipodscsi.exe.manifest |
— | — | @@ -0,0 +1,11 @@ |
| 2 | +<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
| 3 | +<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
| 4 | + <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="ipodscsi.exe" type="win32"/>
|
| 5 | + <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
| 6 | + <security>
|
| 7 | + <requestedPrivileges>
|
| 8 | + <requestedExecutionLevel level="asInvoker"/>
|
| 9 | + </requestedPrivileges>
|
| 10 | + </security>
|
| 11 | + </trustInfo>
|
| 12 | +</assembly>
|
Index: tools/ipodscsi/SOURCES |
— | — | @@ -0,0 +1,2 @@ |
| 2 | +main.c
|
| 3 | +ipodscsi.rc
|
Index: tools/ipodscsi/main.c |
— | — | @@ -0,0 +1,228 @@ |
| 2 | +// |
| 3 | +// |
| 4 | +// Copyright 2011 TheSeven |
| 5 | +// |
| 6 | +// |
| 7 | +// This file is part of emCORE. |
| 8 | +// |
| 9 | +// emCORE is free software: you can redistribute it and/or |
| 10 | +// modify it under the terms of the GNU General Public License as |
| 11 | +// published by the Free Software Foundation, either version 2 of the |
| 12 | +// License, or (at your option) any later version. |
| 13 | +// |
| 14 | +// emCORE is distributed in the hope that it will be useful, |
| 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| 17 | +// See the GNU General Public License for more details. |
| 18 | +// |
| 19 | +// You should have received a copy of the GNU General Public License along |
| 20 | +// with emCORE. If not, see <http://www.gnu.org/licenses/>. |
| 21 | +// |
| 22 | +// |
| 23 | + |
| 24 | + |
| 25 | +#define WIN32_LEAN_AND_MEAN |
| 26 | +#define _WIN32_WINNT 0x500 |
| 27 | +#include <windows.h> |
| 28 | +#include <ntddscsi.h> |
| 29 | +#include <stdbool.h> |
| 30 | +#include <inttypes.h> |
| 31 | + |
| 32 | + |
| 33 | +struct scsi_cmd |
| 34 | +{ |
| 35 | + SCSI_PASS_THROUGH_DIRECT sptd; |
| 36 | + unsigned char sense[14]; |
| 37 | + unsigned char data[65536]; |
| 38 | +} cmd; |
| 39 | + |
| 40 | +char devname[] = "\\\\.\\?:"; |
| 41 | + |
| 42 | + |
| 43 | +int usage(char const* msg, char const* msgarg, int argc, char const* const* argv) |
| 44 | +{ |
| 45 | + printf(msg, msgarg); |
| 46 | + printf("\r\n" |
| 47 | + "\r\n" |
| 48 | + "Usage: %s <drive>: <type> <command> [options...]\r\n" |
| 49 | + "\r\n" |
| 50 | + "Available device types: ipod6g\r\n" |
| 51 | + "\r\n" |
| 52 | + "Commands for ipod6g:\r\n" |
| 53 | + " writefirmware [-p] <firmware.mse>\r\n" |
| 54 | + " -r: Reboot device\r\n" |
| 55 | + " -p: Repartition device\r\n", argv[0]); |
| 56 | + return 1; |
| 57 | +} |
| 58 | + |
| 59 | +void print_last_error(char* text, bool force) |
| 60 | +{ |
| 61 | + DWORD dw = GetLastError();
|
| 62 | + if (!dw && !force) return;
|
| 63 | + LPVOID lpMsgBuf;
|
| 64 | + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
| 65 | + NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, NULL); |
| 66 | + printf("\r\n%s: Error %d: %s\n", text, dw, lpMsgBuf); |
| 67 | +} |
| 68 | + |
| 69 | +int send_cmd(HANDLE dev, struct scsi_cmd* req, int size) |
| 70 | +{ |
| 71 | + SetLastError(0); |
| 72 | + DWORD bytes; |
| 73 | + if (!DeviceIoControl(dev, IOCTL_SCSI_PASS_THROUGH_DIRECT, req, size, req, size, &bytes, NULL)) |
| 74 | + { |
| 75 | + print_last_error("DeviceIoControl", true); |
| 76 | + return 0; |
| 77 | + } |
| 78 | + return 1; |
| 79 | +} |
| 80 | + |
| 81 | +int cmd_ipod6g_writefirmware(HANDLE dev, int argc, char const* const* argv) |
| 82 | +{ |
| 83 | + int arg = 4; |
| 84 | + char const* mse_filename = NULL; |
| 85 | + int repartition = 0; |
| 86 | + int reboot = 0; |
| 87 | + while (arg < argc) |
| 88 | + { |
| 89 | + if (argv[arg][0] == '-') |
| 90 | + { |
| 91 | + if (!strcmp(argv[arg], "-p")) repartition = 1; |
| 92 | + else if (!strcmp(argv[arg], "-r")) reboot = 1; |
| 93 | + else return usage("Unknown option: %s", argv[arg], argc, argv); |
| 94 | + } |
| 95 | + else if (mse_filename) return usage("Excessive argument: %s", argv[arg], argc, argv); |
| 96 | + else mse_filename = argv[arg]; |
| 97 | + arg++; |
| 98 | + } |
| 99 | + if (!mse_filename) return usage("No MSE file name specified", NULL, argc, argv); |
| 100 | + SetLastError(0); |
| 101 | + HANDLE f = CreateFile(mse_filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); |
| 102 | + if (!f || f == (HANDLE)-1) |
| 103 | + { |
| 104 | + print_last_error("Error opening MSE file: CreateFile", true); |
| 105 | + return 2; |
| 106 | + } |
| 107 | + LARGE_INTEGER size; |
| 108 | + SetLastError(0); |
| 109 | + if (!GetFileSizeEx(f, &size)) |
| 110 | + { |
| 111 | + print_last_error("Error getting MSE file size: GetFileSizeEx", true); |
| 112 | + return 2; |
| 113 | + } |
| 114 | + int bytes = size.LowPart; |
| 115 | + if (bytes & 0xfff) |
| 116 | + { |
| 117 | + printf("MSE file size must be a multiple of 4096\r\n"); |
| 118 | + return 2; |
| 119 | + } |
| 120 | + int sectors = bytes >> 12; |
| 121 | + |
| 122 | + if (repartition) |
| 123 | + { |
| 124 | + printf("Repartitioning..."); |
| 125 | + int partsize = sectors << 2; |
| 126 | + cmd.sptd.CdbLength = 6; |
| 127 | + cmd.sptd.Cdb[0] = 0xc6; |
| 128 | + cmd.sptd.Cdb[1] = 0x94; |
| 129 | + cmd.sptd.Cdb[2] = (partsize >> 24) & 0xff; |
| 130 | + cmd.sptd.Cdb[3] = (partsize >> 16) & 0xff; |
| 131 | + cmd.sptd.Cdb[4] = (partsize >> 8) & 0xff; |
| 132 | + cmd.sptd.Cdb[5] = (partsize) & 0xff; |
| 133 | + cmd.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; |
| 134 | + cmd.sptd.DataTransferLength = 0; |
| 135 | + cmd.sptd.TimeOutValue = 60000; |
| 136 | + if (!send_cmd(dev, &cmd, sizeof(cmd))) return 2; |
| 137 | + printf(" done\r\n"); |
| 138 | + } |
| 139 | + |
| 140 | + printf("Initiating firmware transfer..."); |
| 141 | + cmd.sptd.CdbLength = 2; |
| 142 | + cmd.sptd.Cdb[0] = 0xc6; |
| 143 | + cmd.sptd.Cdb[1] = 0x90; |
| 144 | + cmd.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; |
| 145 | + cmd.sptd.DataTransferLength = 0; |
| 146 | + cmd.sptd.TimeOutValue = 1000; |
| 147 | + if (!send_cmd(dev, &cmd, sizeof(cmd))) return 2; |
| 148 | + printf(" done\r\n"); |
| 149 | + |
| 150 | + printf("Writing firmware..."); |
| 151 | + while (sectors) |
| 152 | + { |
| 153 | + int tsize = sectors > 0x10 ? 0x10 : sectors; |
| 154 | + int got = 0; |
| 155 | + while (got < (tsize << 12)) |
| 156 | + { |
| 157 | + SetLastError(0); |
| 158 | + DWORD b; |
| 159 | + if (!ReadFile(f, &cmd.data[got], (tsize << 12) - got, &b, NULL) || !b) |
| 160 | + { |
| 161 | + print_last_error("Error reading from MSE file: ReadFile", true); |
| 162 | + return 2; |
| 163 | + } |
| 164 | + got += b; |
| 165 | + } |
| 166 | + cmd.sptd.CdbLength = 4; |
| 167 | + cmd.sptd.Cdb[0] = 0xc6; |
| 168 | + cmd.sptd.Cdb[1] = 0x91; |
| 169 | + cmd.sptd.Cdb[2] = 0x00; |
| 170 | + cmd.sptd.Cdb[3] = tsize; |
| 171 | + cmd.sptd.DataIn = SCSI_IOCTL_DATA_OUT; |
| 172 | + cmd.sptd.DataTransferLength = tsize << 12; |
| 173 | + cmd.sptd.TimeOutValue = 5000; |
| 174 | + if (!send_cmd(dev, &cmd, sizeof(cmd))) return 2; |
| 175 | + sectors -= tsize; |
| 176 | + printf("."); |
| 177 | + } |
| 178 | + printf(" done\r\n"); |
| 179 | + |
| 180 | + if (reboot) |
| 181 | + { |
| 182 | + printf("Rebooting device..."); |
| 183 | + cmd.sptd.CdbLength = 6; |
| 184 | + cmd.sptd.Cdb[0] = 0x1b; |
| 185 | + cmd.sptd.Cdb[1] = 0x00; |
| 186 | + cmd.sptd.Cdb[2] = 0x00; |
| 187 | + cmd.sptd.Cdb[3] = 0x00; |
| 188 | + cmd.sptd.Cdb[4] = 0x02; |
| 189 | + cmd.sptd.Cdb[5] = 0x00; |
| 190 | + cmd.sptd.DataIn = SCSI_IOCTL_DATA_UNSPECIFIED; |
| 191 | + cmd.sptd.DataTransferLength = 0; |
| 192 | + cmd.sptd.TimeOutValue = 10000; |
| 193 | + if (!send_cmd(dev, &cmd, sizeof(cmd))) return 2; |
| 194 | + printf(" done\r\n"); |
| 195 | + } |
| 196 | + |
| 197 | + CloseHandle(f); |
| 198 | + return 0; |
| 199 | +} |
| 200 | + |
| 201 | +int cmd_ipod6g(HANDLE dev, int argc, char const* const* argv) |
| 202 | +{ |
| 203 | + if (!strcmp(argv[3], "writefirmware")) return cmd_ipod6g_writefirmware(dev, argc, argv); |
| 204 | + return usage("Unknown command for device type type ipod6g: %s", argv[3], argc, argv); |
| 205 | +} |
| 206 | + |
| 207 | +int main(int argc, char const* const* argv) |
| 208 | +{ |
| 209 | + if (argc < 4) return usage("Not enough arguments specified", NULL, argc, argv); |
| 210 | + |
| 211 | + if (strlen(argv[1]) != 2 || argv[1][1] != ':') return usage("Bad drive letter: %s", argv[1], argc, argv); |
| 212 | + devname[4] = argv[1][0]; |
| 213 | + SetLastError(0); |
| 214 | + HANDLE dev = CreateFile(devname, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); |
| 215 | + if (!dev || dev == (HANDLE)-1) |
| 216 | + { |
| 217 | + print_last_error("Error opening SCSI device: CreateFile", true); |
| 218 | + return 2; |
| 219 | + } |
| 220 | + cmd.sptd.Length = sizeof(cmd.sptd); |
| 221 | + cmd.sptd.SenseInfoOffset = sizeof(cmd.sptd); |
| 222 | + cmd.sptd.SenseInfoLength = 14; |
| 223 | + cmd.sptd.DataBuffer = cmd.data; |
| 224 | + |
| 225 | + if (!strcmp(argv[2], "ipod6g")) return cmd_ipod6g(dev, argc, argv); |
| 226 | + return usage("Unknown device type: %s", argv[2], argc, argv); |
| 227 | + |
| 228 | + CloseHandle(dev); |
| 229 | +} |
Index: tools/ipodscsi/version.h |
— | — | @@ -0,0 +1,36 @@ |
| 2 | +//
|
| 3 | +//
|
| 4 | +// Copyright 2011 TheSeven
|
| 5 | +//
|
| 6 | +//
|
| 7 | +// This file is part of emCORE.
|
| 8 | +//
|
| 9 | +// emCORE is free software: you can redistribute it and/or
|
| 10 | +// modify it under the terms of the GNU General Public License as
|
| 11 | +// published by the Free Software Foundation, either version 2 of the
|
| 12 | +// License, or (at your option) any later version.
|
| 13 | +//
|
| 14 | +// emCORE is distributed in the hope that it will be useful,
|
| 15 | +// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| 16 | +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
| 17 | +// See the GNU General Public License for more details.
|
| 18 | +//
|
| 19 | +// You should have received a copy of the GNU General Public License along
|
| 20 | +// with emCORE. If not, see <http://www.gnu.org/licenses/>.
|
| 21 | +//
|
| 22 | +//
|
| 23 | +
|
| 24 | +
|
| 25 | +#ifndef __VERSION_H__
|
| 26 | +#define __VERSION_H__
|
| 27 | +
|
| 28 | +
|
| 29 | +#define VERSION "0.1.0"
|
| 30 | +#define VERSION_MAJOR 0
|
| 31 | +#define VERSION_MINOR 1
|
| 32 | +#define VERSION_PATCH 0
|
| 33 | +#define VERSION_SVN "$REVISION$"
|
| 34 | +#define VERSION_SVN_INT $REVISIONINT$
|
| 35 | +
|
| 36 | +
|
| 37 | +#endif |
\ No newline at end of file |
Index: tools/ipodscsi/Makefile |
— | — | @@ -0,0 +1,94 @@ |
| 2 | +NAME := ipodscsi
|
| 3 | +
|
| 4 | +ifeq ($(shell uname),WindowsNT)
|
| 5 | +CCACHE :=
|
| 6 | +else
|
| 7 | +CCACHE := $(shell which ccache)
|
| 8 | +endif
|
| 9 | +
|
| 10 | +CC := $(CCACHE) gcc
|
| 11 | +LD := $(CCACHE) gcc
|
| 12 | +
|
| 13 | +CFLAGS += -Os -fomit-frame-pointer "-DDFUIMAGE=\"$(DFUIMAGE)\""
|
| 14 | +LDFLAGS += -Wl,-s
|
| 15 | +
|
| 16 | +preprocess = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#")
|
| 17 | +preprocesspaths = $(shell $(CC) $(PPCFLAGS) $(2) -E -P -x c $(1) | grep -v "^\#" | sed -e "s:^..*:$(dir $(1))&:" | sed -e "s:^\\./::")
|
| 18 | +
|
| 19 | +REVISION := $(shell svnversion .)
|
| 20 | +REVISIONINT := $(shell echo $(REVISION) | sed -e "s/[^0-9].*$$//")
|
| 21 | +
|
| 22 | +SRC := $(call preprocesspaths,SOURCES,-I. -I..)
|
| 23 | +OBJ := $(SRC:%.c=build/%.o)
|
| 24 | +OBJ := $(OBJ:%.S=build/%.o)
|
| 25 | +OBJ := $(OBJ:%.rc=build/%.o)
|
| 26 | +
|
| 27 | +all: $(NAME)
|
| 28 | +
|
| 29 | +-include $(OBJ:%=%.dep)
|
| 30 | +
|
| 31 | +ipodscsi.rc: ipodscsi.exe.manifest
|
| 32 | +
|
| 33 | +$(NAME): build/$(NAME).exe
|
| 34 | +
|
| 35 | +build/$(NAME).exe: $(OBJ)
|
| 36 | + @echo [LD] $@
|
| 37 | + @$(LD) -o $@ $(OBJ) $(LDFLAGS)
|
| 38 | +
|
| 39 | +build/%.o: %.c build/version.h
|
| 40 | + @echo [CC] $<
|
| 41 | +ifeq ($(shell uname),WindowsNT)
|
| 42 | + @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
|
| 43 | +else
|
| 44 | + @-mkdir -p $(dir $@)
|
| 45 | +endif
|
| 46 | + @$(CC) -c $(CFLAGS) -o $@ $<
|
| 47 | + @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
|
| 48 | + @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
|
| 49 | +ifeq ($(shell uname),WindowsNT)
|
| 50 | + @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
|
| 51 | +else
|
| 52 | + @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
|
| 53 | +endif
|
| 54 | + @rm -f $@.dep.tmp
|
| 55 | +
|
| 56 | +build/%.o: %.S build/version.h
|
| 57 | + @echo [CC] $<
|
| 58 | +ifeq ($(shell uname),WindowsNT)
|
| 59 | + @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
|
| 60 | +else
|
| 61 | + @-mkdir -p $(dir $@)
|
| 62 | +endif
|
| 63 | + @$(CC) -c $(CFLAGS) -o $@ $<
|
| 64 | + @$(CC) -MM $(CFLAGS) $< > $@.dep.tmp
|
| 65 | + @sed -e "s|.*:|$@:|" < $@.dep.tmp > $@.dep
|
| 66 | +ifeq ($(shell uname),WindowsNT)
|
| 67 | + @sed -e "s/.*://" -e "s/\\$$//" < $@.dep.tmp | fmt -1 | sed -e "s/^ *//" -e "s/$$/:/" >> $@.dep
|
| 68 | +else
|
| 69 | + @sed -e 's/.*://' -e 's/\\$$//' < $@.dep.tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $@.dep
|
| 70 | +endif
|
| 71 | + @rm -f $@.dep.tmp
|
| 72 | +
|
| 73 | +build/%.o: %.rc
|
| 74 | + @echo [WINRES] $<
|
| 75 | +ifeq ($(shell uname),WindowsNT)
|
| 76 | + @-if not exist $(subst /,\,$(dir $@)) md $(subst /,\,$(dir $@))
|
| 77 | +else
|
| 78 | + @-mkdir -p $(dir $@)
|
| 79 | +endif
|
| 80 | + @windres -i $< -o $@
|
| 81 | +
|
| 82 | +build/version.h: version.h .svn/entries
|
| 83 | + @echo [PP] $<
|
| 84 | +ifeq ($(shell uname),WindowsNT)
|
| 85 | + @-if not exist build md build
|
| 86 | + @sed -e "s/\$$REVISION\$$/$(REVISION)/" -e "s/\$$REVISIONINT\$$/$(REVISIONINT)/" < $< > $@
|
| 87 | +else
|
| 88 | + @-mkdir -p build
|
| 89 | + @sed -e 's/\$$REVISION\$$/$(REVISION)/' -e 's/\$$REVISIONINT\$$/$(REVISIONINT)/' < $< > $@
|
| 90 | +endif
|
| 91 | +
|
| 92 | +clean:
|
| 93 | + @rm -rf build
|
| 94 | +
|
| 95 | +.PHONY: all clean $(NAME)
|
Index: tools/ipodscsi |
Property changes on: tools/ipodscsi |
___________________________________________________________________ |
Added: svn:ignore |
## -0,0 +1 ## |
| 96 | +build |