├── LICENSE
├── Makefile
├── README.md
├── README_YAWMM.txt
├── apps
└── some-yawmm-mod
│ ├── icon.png
│ └── meta.xml
├── data
├── background
└── ehcmodule.elf
├── include
└── wiilight.h
├── lib
└── libwiilight.a
├── source
├── fat.c
├── fat.h
├── globals.h
├── gui.c
├── gui.h
├── iospatch.c
├── iospatch.h
├── libpng
│ └── pngu
│ │ ├── pngu.c
│ │ └── pngu.h
├── menu.c
├── menu.h
├── mload.c
├── mload.h
├── nand.c
├── nand.h
├── restart.c
├── restart.h
├── sha1.c
├── sha1.h
├── stub.S
├── sys.c
├── sys.h
├── title.c
├── title.h
├── usbstorage.c
├── usbstorage.h
├── utils.h
├── video.c
├── video.h
├── wad-manager.c
├── wad.c
├── wad.h
├── wkb.c
├── wkb.h
├── wpad.c
└── wpad.h
└── wm_config.txt
/LICENSE:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 2, June 1991
3 |
4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6 | Everyone is permitted to copy and distribute verbatim copies
7 | of this license document, but changing it is not allowed.
8 |
9 | Preamble
10 |
11 | The licenses for most software are designed to take away your
12 | freedom to share and change it. By contrast, the GNU General Public
13 | License is intended to guarantee your freedom to share and change free
14 | software--to make sure the software is free for all its users. This
15 | General Public License applies to most of the Free Software
16 | Foundation's software and to any other program whose authors commit to
17 | using it. (Some other Free Software Foundation software is covered by
18 | the GNU Lesser General Public License instead.) You can apply it to
19 | your programs, too.
20 |
21 | When we speak of free software, we are referring to freedom, not
22 | price. Our General Public Licenses are designed to make sure that you
23 | have the freedom to distribute copies of free software (and charge for
24 | this service if you wish), that you receive source code or can get it
25 | if you want it, that you can change the software or use pieces of it
26 | in new free programs; and that you know you can do these things.
27 |
28 | To protect your rights, we need to make restrictions that forbid
29 | anyone to deny you these rights or to ask you to surrender the rights.
30 | These restrictions translate to certain responsibilities for you if you
31 | distribute copies of the software, or if you modify it.
32 |
33 | For example, if you distribute copies of such a program, whether
34 | gratis or for a fee, you must give the recipients all the rights that
35 | you have. You must make sure that they, too, receive or can get the
36 | source code. And you must show them these terms so they know their
37 | rights.
38 |
39 | We protect your rights with two steps: (1) copyright the software, and
40 | (2) offer you this license which gives you legal permission to copy,
41 | distribute and/or modify the software.
42 |
43 | Also, for each author's protection and ours, we want to make certain
44 | that everyone understands that there is no warranty for this free
45 | software. If the software is modified by someone else and passed on, we
46 | want its recipients to know that what they have is not the original, so
47 | that any problems introduced by others will not reflect on the original
48 | authors' reputations.
49 |
50 | Finally, any free program is threatened constantly by software
51 | patents. We wish to avoid the danger that redistributors of a free
52 | program will individually obtain patent licenses, in effect making the
53 | program proprietary. To prevent this, we have made it clear that any
54 | patent must be licensed for everyone's free use or not licensed at all.
55 |
56 | The precise terms and conditions for copying, distribution and
57 | modification follow.
58 |
59 | GNU GENERAL PUBLIC LICENSE
60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
61 |
62 | 0. This License applies to any program or other work which contains
63 | a notice placed by the copyright holder saying it may be distributed
64 | under the terms of this General Public License. The "Program", below,
65 | refers to any such program or work, and a "work based on the Program"
66 | means either the Program or any derivative work under copyright law:
67 | that is to say, a work containing the Program or a portion of it,
68 | either verbatim or with modifications and/or translated into another
69 | language. (Hereinafter, translation is included without limitation in
70 | the term "modification".) Each licensee is addressed as "you".
71 |
72 | Activities other than copying, distribution and modification are not
73 | covered by this License; they are outside its scope. The act of
74 | running the Program is not restricted, and the output from the Program
75 | is covered only if its contents constitute a work based on the
76 | Program (independent of having been made by running the Program).
77 | Whether that is true depends on what the Program does.
78 |
79 | 1. You may copy and distribute verbatim copies of the Program's
80 | source code as you receive it, in any medium, provided that you
81 | conspicuously and appropriately publish on each copy an appropriate
82 | copyright notice and disclaimer of warranty; keep intact all the
83 | notices that refer to this License and to the absence of any warranty;
84 | and give any other recipients of the Program a copy of this License
85 | along with the Program.
86 |
87 | You may charge a fee for the physical act of transferring a copy, and
88 | you may at your option offer warranty protection in exchange for a fee.
89 |
90 | 2. You may modify your copy or copies of the Program or any portion
91 | of it, thus forming a work based on the Program, and copy and
92 | distribute such modifications or work under the terms of Section 1
93 | above, provided that you also meet all of these conditions:
94 |
95 | a) You must cause the modified files to carry prominent notices
96 | stating that you changed the files and the date of any change.
97 |
98 | b) You must cause any work that you distribute or publish, that in
99 | whole or in part contains or is derived from the Program or any
100 | part thereof, to be licensed as a whole at no charge to all third
101 | parties under the terms of this License.
102 |
103 | c) If the modified program normally reads commands interactively
104 | when run, you must cause it, when started running for such
105 | interactive use in the most ordinary way, to print or display an
106 | announcement including an appropriate copyright notice and a
107 | notice that there is no warranty (or else, saying that you provide
108 | a warranty) and that users may redistribute the program under
109 | these conditions, and telling the user how to view a copy of this
110 | License. (Exception: if the Program itself is interactive but
111 | does not normally print such an announcement, your work based on
112 | the Program is not required to print an announcement.)
113 |
114 | These requirements apply to the modified work as a whole. If
115 | identifiable sections of that work are not derived from the Program,
116 | and can be reasonably considered independent and separate works in
117 | themselves, then this License, and its terms, do not apply to those
118 | sections when you distribute them as separate works. But when you
119 | distribute the same sections as part of a whole which is a work based
120 | on the Program, the distribution of the whole must be on the terms of
121 | this License, whose permissions for other licensees extend to the
122 | entire whole, and thus to each and every part regardless of who wrote it.
123 |
124 | Thus, it is not the intent of this section to claim rights or contest
125 | your rights to work written entirely by you; rather, the intent is to
126 | exercise the right to control the distribution of derivative or
127 | collective works based on the Program.
128 |
129 | In addition, mere aggregation of another work not based on the Program
130 | with the Program (or with a work based on the Program) on a volume of
131 | a storage or distribution medium does not bring the other work under
132 | the scope of this License.
133 |
134 | 3. You may copy and distribute the Program (or a work based on it,
135 | under Section 2) in object code or executable form under the terms of
136 | Sections 1 and 2 above provided that you also do one of the following:
137 |
138 | a) Accompany it with the complete corresponding machine-readable
139 | source code, which must be distributed under the terms of Sections
140 | 1 and 2 above on a medium customarily used for software interchange; or,
141 |
142 | b) Accompany it with a written offer, valid for at least three
143 | years, to give any third party, for a charge no more than your
144 | cost of physically performing source distribution, a complete
145 | machine-readable copy of the corresponding source code, to be
146 | distributed under the terms of Sections 1 and 2 above on a medium
147 | customarily used for software interchange; or,
148 |
149 | c) Accompany it with the information you received as to the offer
150 | to distribute corresponding source code. (This alternative is
151 | allowed only for noncommercial distribution and only if you
152 | received the program in object code or executable form with such
153 | an offer, in accord with Subsection b above.)
154 |
155 | The source code for a work means the preferred form of the work for
156 | making modifications to it. For an executable work, complete source
157 | code means all the source code for all modules it contains, plus any
158 | associated interface definition files, plus the scripts used to
159 | control compilation and installation of the executable. However, as a
160 | special exception, the source code distributed need not include
161 | anything that is normally distributed (in either source or binary
162 | form) with the major components (compiler, kernel, and so on) of the
163 | operating system on which the executable runs, unless that component
164 | itself accompanies the executable.
165 |
166 | If distribution of executable or object code is made by offering
167 | access to copy from a designated place, then offering equivalent
168 | access to copy the source code from the same place counts as
169 | distribution of the source code, even though third parties are not
170 | compelled to copy the source along with the object code.
171 |
172 | 4. You may not copy, modify, sublicense, or distribute the Program
173 | except as expressly provided under this License. Any attempt
174 | otherwise to copy, modify, sublicense or distribute the Program is
175 | void, and will automatically terminate your rights under this License.
176 | However, parties who have received copies, or rights, from you under
177 | this License will not have their licenses terminated so long as such
178 | parties remain in full compliance.
179 |
180 | 5. You are not required to accept this License, since you have not
181 | signed it. However, nothing else grants you permission to modify or
182 | distribute the Program or its derivative works. These actions are
183 | prohibited by law if you do not accept this License. Therefore, by
184 | modifying or distributing the Program (or any work based on the
185 | Program), you indicate your acceptance of this License to do so, and
186 | all its terms and conditions for copying, distributing or modifying
187 | the Program or works based on it.
188 |
189 | 6. Each time you redistribute the Program (or any work based on the
190 | Program), the recipient automatically receives a license from the
191 | original licensor to copy, distribute or modify the Program subject to
192 | these terms and conditions. You may not impose any further
193 | restrictions on the recipients' exercise of the rights granted herein.
194 | You are not responsible for enforcing compliance by third parties to
195 | this License.
196 |
197 | 7. If, as a consequence of a court judgment or allegation of patent
198 | infringement or for any other reason (not limited to patent issues),
199 | conditions are imposed on you (whether by court order, agreement or
200 | otherwise) that contradict the conditions of this License, they do not
201 | excuse you from the conditions of this License. If you cannot
202 | distribute so as to satisfy simultaneously your obligations under this
203 | License and any other pertinent obligations, then as a consequence you
204 | may not distribute the Program at all. For example, if a patent
205 | license would not permit royalty-free redistribution of the Program by
206 | all those who receive copies directly or indirectly through you, then
207 | the only way you could satisfy both it and this License would be to
208 | refrain entirely from distribution of the Program.
209 |
210 | If any portion of this section is held invalid or unenforceable under
211 | any particular circumstance, the balance of the section is intended to
212 | apply and the section as a whole is intended to apply in other
213 | circumstances.
214 |
215 | It is not the purpose of this section to induce you to infringe any
216 | patents or other property right claims or to contest validity of any
217 | such claims; this section has the sole purpose of protecting the
218 | integrity of the free software distribution system, which is
219 | implemented by public license practices. Many people have made
220 | generous contributions to the wide range of software distributed
221 | through that system in reliance on consistent application of that
222 | system; it is up to the author/donor to decide if he or she is willing
223 | to distribute software through any other system and a licensee cannot
224 | impose that choice.
225 |
226 | This section is intended to make thoroughly clear what is believed to
227 | be a consequence of the rest of this License.
228 |
229 | 8. If the distribution and/or use of the Program is restricted in
230 | certain countries either by patents or by copyrighted interfaces, the
231 | original copyright holder who places the Program under this License
232 | may add an explicit geographical distribution limitation excluding
233 | those countries, so that distribution is permitted only in or among
234 | countries not thus excluded. In such case, this License incorporates
235 | the limitation as if written in the body of this License.
236 |
237 | 9. The Free Software Foundation may publish revised and/or new versions
238 | of the General Public License from time to time. Such new versions will
239 | be similar in spirit to the present version, but may differ in detail to
240 | address new problems or concerns.
241 |
242 | Each version is given a distinguishing version number. If the Program
243 | specifies a version number of this License which applies to it and "any
244 | later version", you have the option of following the terms and conditions
245 | either of that version or of any later version published by the Free
246 | Software Foundation. If the Program does not specify a version number of
247 | this License, you may choose any version ever published by the Free Software
248 | Foundation.
249 |
250 | 10. If you wish to incorporate parts of the Program into other free
251 | programs whose distribution conditions are different, write to the author
252 | to ask for permission. For software which is copyrighted by the Free
253 | Software Foundation, write to the Free Software Foundation; we sometimes
254 | make exceptions for this. Our decision will be guided by the two goals
255 | of preserving the free status of all derivatives of our free software and
256 | of promoting the sharing and reuse of software generally.
257 |
258 | NO WARRANTY
259 |
260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
268 | REPAIR OR CORRECTION.
269 |
270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
278 | POSSIBILITY OF SUCH DAMAGES.
279 |
280 | END OF TERMS AND CONDITIONS
281 |
282 | How to Apply These Terms to Your New Programs
283 |
284 | If you develop a new program, and you want it to be of the greatest
285 | possible use to the public, the best way to achieve this is to make it
286 | free software which everyone can redistribute and change under these terms.
287 |
288 | To do so, attach the following notices to the program. It is safest
289 | to attach them to the start of each source file to most effectively
290 | convey the exclusion of warranty; and each file should have at least
291 | the "copyright" line and a pointer to where the full notice is found.
292 |
293 | {description}
294 | Copyright (C) {year} {fullname}
295 |
296 | This program is free software; you can redistribute it and/or modify
297 | it under the terms of the GNU General Public License as published by
298 | the Free Software Foundation; either version 2 of the License, or
299 | (at your option) any later version.
300 |
301 | This program is distributed in the hope that it will be useful,
302 | but WITHOUT ANY WARRANTY; without even the implied warranty of
303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
304 | GNU General Public License for more details.
305 |
306 | You should have received a copy of the GNU General Public License along
307 | with this program; if not, write to the Free Software Foundation, Inc.,
308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
309 |
310 | Also add information on how to contact you by electronic and paper mail.
311 |
312 | If the program is interactive, make it output a short notice like this
313 | when it starts in an interactive mode:
314 |
315 | Gnomovision version 69, Copyright (C) year name of author
316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
317 | This is free software, and you are welcome to redistribute it
318 | under certain conditions; type `show c' for details.
319 |
320 | The hypothetical commands `show w' and `show c' should show the appropriate
321 | parts of the General Public License. Of course, the commands you use may
322 | be called something other than `show w' and `show c'; they could even be
323 | mouse-clicks or menu items--whatever suits your program.
324 |
325 | You should also get your employer (if you work as a programmer) or your
326 | school, if any, to sign a "copyright disclaimer" for the program, if
327 | necessary. Here is a sample; alter the names:
328 |
329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program
330 | `Gnomovision' (which makes passes at compilers) written by James Hacker.
331 |
332 | {signature of Ty Coon}, 1 April 1989
333 | Ty Coon, President of Vice
334 |
335 | This General Public License does not permit incorporating your program into
336 | proprietary programs. If your program is a subroutine library, you may
337 | consider it more useful to permit linking proprietary applications with the
338 | library. If this is what you want to do, use the GNU Lesser General
339 | Public License instead of this License.
340 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #---------------------------------------------------------------------------------
2 | # Clear the implicit built in rules
3 | #---------------------------------------------------------------------------------
4 | .SUFFIXES:
5 | #---------------------------------------------------------------------------------
6 | #DEVKITPRO = /opt/devkitPPC
7 | #DEVKITPPC = /opt/devkitPPC
8 |
9 | ifeq ($(strip $(DEVKITPPC)),)
10 | $(error "Please set DEVKITPPC in your environment. export DEVKITPPC=devkitPPC")
11 | endif
12 |
13 | include $(DEVKITPPC)/wii_rules
14 |
15 | #---------------------------------------------------------------------------------
16 | # TARGET is the name of the output
17 | # BUILD is the directory where object files & intermediate files will be placed
18 | # SOURCES is a list of directories containing source code
19 | # INCLUDES is a list of directories containing extra header files
20 | #---------------------------------------------------------------------------------
21 | TARGET := $(notdir $(CURDIR))
22 | BUILD := build
23 | SOURCES := source include source/libtinysmb source/libpng source/libpng/pngu
24 | DATA := data
25 | INCLUDES :=
26 |
27 | #---------------------------------------------------------------------------------
28 | # options for code generation
29 | #---------------------------------------------------------------------------------
30 |
31 | CFLAGS = -Os -Wall $(MACHDEP) $(INCLUDE)
32 | CXXFLAGS = $(CFLAGS)
33 |
34 | LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
35 |
36 | #---------------------------------------------------------------------------------
37 | # any extra libraries we wish to link with the project
38 | #---------------------------------------------------------------------------------
39 | LIBS := -ltinysmb -lpng -lfat -lwiidrc -lwiiuse -lbte -logc -lm -lz -lwiilight
40 |
41 | #---------------------------------------------------------------------------------
42 | # list of directories containing libraries, this must be the top level containing
43 | # include and lib
44 | #---------------------------------------------------------------------------------
45 | LIBDIRS := $(CURDIR) $(PORTLIBS)
46 |
47 | #---------------------------------------------------------------------------------
48 | # no real need to edit anything past this point unless you need to add additional
49 | # rules for different file extensions
50 | #---------------------------------------------------------------------------------
51 | ifneq ($(BUILD),$(notdir $(CURDIR)))
52 | #---------------------------------------------------------------------------------
53 |
54 | export OUTPUT := $(CURDIR)/$(TARGET)
55 |
56 | export VPATH := $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
57 | $(foreach dir,$(DATA),$(CURDIR)/$(dir))
58 |
59 | export DEPSDIR := $(CURDIR)/$(BUILD)
60 |
61 | #---------------------------------------------------------------------------------
62 | # automatically build a list of object files for our project
63 | #---------------------------------------------------------------------------------
64 | CFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
65 | CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
66 | sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
67 | SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
68 | BINFILES := $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
69 |
70 | #---------------------------------------------------------------------------------
71 | # use CXX for linking C++ projects, CC for standard C
72 | #---------------------------------------------------------------------------------
73 | ifeq ($(strip $(CPPFILES)),)
74 | export LD := $(CC)
75 | else
76 | export LD := $(CXX)
77 | endif
78 |
79 | export OFILES := $(addsuffix .o,$(BINFILES)) \
80 | $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \
81 | $(sFILES:.s=.o) $(SFILES:.S=.o)
82 |
83 | #---------------------------------------------------------------------------------
84 | # build a list of include paths
85 | #---------------------------------------------------------------------------------
86 | export INCLUDE := $(foreach dir,$(INCLUDES), -iquote $(CURDIR)/$(dir)) \
87 | $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
88 | -I$(CURDIR)/$(BUILD) \
89 | -I$(LIBOGC_INC)
90 |
91 | #---------------------------------------------------------------------------------
92 | # build a list of library paths
93 | #---------------------------------------------------------------------------------
94 | export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
95 | -L$(LIBOGC_LIB)
96 |
97 | export OUTPUT := $(CURDIR)/$(TARGET)
98 | .PHONY: $(BUILD) clean
99 |
100 | #---------------------------------------------------------------------------------
101 | $(BUILD):
102 | @[ -d $@ ] || mkdir -p $@
103 | @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
104 |
105 | #---------------------------------------------------------------------------------
106 | clean:
107 | @echo clean ...
108 | @rm -fr $(BUILD) $(OUTPUT).elf $(OUTPUT).dol
109 |
110 | #---------------------------------------------------------------------------------
111 | run:
112 | wiiload $(TARGET).dol
113 |
114 |
115 | #---------------------------------------------------------------------------------
116 | else
117 |
118 | DEPENDS := $(OFILES:.o=.d)
119 |
120 | #---------------------------------------------------------------------------------
121 | # main targets
122 | #---------------------------------------------------------------------------------
123 | $(OUTPUT).dol: $(OUTPUT).elf
124 | $(OUTPUT).elf: $(OFILES)
125 |
126 | #---------------------------------------------------------------------------------
127 | # This rule links in binary data with the .jpg extension
128 | #---------------------------------------------------------------------------------
129 | %.jpg.o : %.jpg
130 | #---------------------------------------------------------------------------------
131 | @echo $(notdir $<)
132 | $(bin2o)
133 |
134 | %.elf.o : %.elf
135 | @echo $(notdir $<)
136 | $(bin2o)
137 |
138 | %.dat.o : %.dat
139 | @echo $(notdir $<)
140 | $(bin2o)
141 |
142 | -include $(DEPENDS)
143 |
144 | #---------------------------------------------------------------------------------
145 | endif
146 | #---------------------------------------------------------------------------------
147 |
148 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Some-YAWMM-Mod
2 | Based on YAWMM which itself is based on WAD Manager, modded up by various people.
3 | Changes from the last YAWMM googlecode version:
4 | -updated to be compiled in the latest devkitppc, libogc versions
5 | -added on-the-fly IOS patches when AHBPROT is disabled, so no cIOS is required in those cases
6 | -support for classic controller, wiiu pro controller (on both wii and vwii) and wiiu gamepad (in wii vc mode)
7 | -small corrections in how the root path is selected (having no "wad" folder now correctly displays on device root)
8 |
9 | For more info on YAWMM itself, check its [original readme](README_YAWMM.txt).
--------------------------------------------------------------------------------
/README_YAWMM.txt:
--------------------------------------------------------------------------------
1 |
2 | =YET ANOTHER WAD MANAGER MOD (YAWMM)=
3 |
4 | ==[ DISCLAIMER ]:==
5 |
6 | THIS APPLICATION COMES WITH NO WARRANTY AT ALL, NEITHER EXPRESSED NOR IMPLIED.
7 | NO ONE BUT YOURSELF IS RESPONSIBLE FOR ANY DAMAGE TO YOUR WII CONSOLE
8 | BECAUSE OF A IMPROPER USAGE OF THIS SOFTWARE.
9 |
10 |
11 | ==[ DESCRIPTION ]:==
12 |
13 | This is an application that allows you to (un)install WADs.
14 |
15 | It lists all the available WADs in a storage device
16 | so you can select which one to (un)install.
17 |
18 |
19 | ==[ SUPPORTED DEVICES ]:==
20 |
21 | * SDGecko.
22 | * Internal SD slot (with SDHC support).
23 | * USB device (1.1 and 2.0).
24 |
25 |
26 | ==[ USAGE ]:==
27 |
28 | * Copy the WAD(s) you wish to insall to your storage device.
29 | * Run the application with any method to load homebrew.
30 |
31 | * The following 3 options can be skipped/pre-set, see the [ CONFIG FILE USAGE ] Section for details
32 | # Select an IOS to use (must have proper patches), 2 commonly used IOSs are 249 and 36.
33 | # Select the device where you have saved the WADs.
34 | # Choose Nand Emulation Device (leave "disabled" to install to WADs to the Wii's real Nand)
35 |
36 | * Browse device to locate WADs ("A" to open folders, and "B" to go back)
37 |
38 | * Press the "A" Button on an individual WAD to (un)install.
39 | * If no file is marked, the normal single file (un)install menu will appear.
40 | * If at least one file is marked, the batch (un)install menu will appear.
41 |
42 | * Press the "+" Button to (un)mark the selected WAD for batch installation
43 | * Press the "-" Button to (un)mark the selected WAD for batch uninstallation
44 | * Hold +/- for 2 seconds to (un)mark all items in a directory.
45 | * A "+" will appear in front of the name of marked WADs for installation
46 | * A "-" will appear in front of the name of marked WADs for uninstallation
47 |
48 | * Press the "1" Button to go to the operations menu (currently can only delete single WADs)
49 |
50 |
51 | ==[ NOTES ]:==
52 |
53 | To use the NAND emulation is necessary to have a COMPLETE copy
54 | of the NAND filesystem in the root of the FAT device.
55 |
56 |
57 | ==;[ CONFIG FILE USAGE ]:==
58 |
59 | ; wm_config.txt resides in sd:/wad, and it is optional. You will get all the prompts if you don't have this file. If you are missing this file, copy and paste the entire [ CONFIG FILE USAGE ] Section to a new text file, rename it wm_config.txt, and Save it to sd:/wad.
60 |
61 | *; To bypass any of the params, just comment out the line using a ";" at the beginning of the line*
62 |
63 | ; If you don't have any of the other parameters, it will prompt you for it
64 |
65 | ; The param keywords are case-sensitive at this point.
66 |
67 | ; No spaces precede the keyword on a line
68 |
69 | ; If you don't have a password in the config file, the default is no password
70 |
71 | ; If you don't have a startupPath, the default is /wad
72 |
73 | ; Blank lines are ignored.
74 |
75 | ; Password=your_password ("LRUD" only, where L=left, R=right, U=up, D=down on the WiiMote or GC Controller, max 10 characters)
76 |
77 | ; StartupPath=startupPath (starting at the root dir "/"). Be sure that the path exists, else you will get an error.
78 |
79 |
80 |
81 | *;Password=UDLR*
82 |
83 | *;StartupPath=/myWAD*
84 |
85 | ; Example of StartupPath at the root of the SD card
86 |
87 | ;StartupPath=/
88 |
89 | ; cIOS: 249, 222, whatever
90 |
91 | *;cIOSVersion=249*
92 |
93 | ; FatDevice: sd usb usb2 gcsda gcsdb
94 |
95 | *;FatDevice=sd*
96 |
97 | ; NANDDevice: Disable SD USB
98 |
99 | ; Note that WM will prompt for NAND device only if you selected cIOS=249
100 |
101 | *;NANDDevice=Disable*
102 |
103 |
104 |
105 |
106 | ==[ CHANGELOG ]:==
107 |
108 | * YAWMM (cwstjdenobs)
109 | * Hold +/- for 2 seconds to select all items in a directory.
110 | * Supports Hermes v4/v5 cIOS. Mainly useful if 202 works best for your HDD/SDHC card.
111 | * More detailed failed report after batch un/installs.
112 | * Will not uninstall The System Menu, the SM's region EULA or rgsel, or their IOSs.
113 | * Will not install the wrong regions SM.
114 | * Will not load stub IOS.
115 | * Will not install titles if they rely on a stub IOS.
116 | * Will not install stub SM, EULA and rgsel IOS.
117 | * Will not install a SM lower than 4.0 on a boot2v4 Wii.
118 | * Gives a warning when uninstalling the HBCs IOS.
119 | * Read config file from usb.
120 | * Can load an alternative background from /wad/background.png.
121 | * Won't load incompatible cIOS in SNEEK.
122 |
123 | * Wad Manager Multi-Mod (Leathl) v3:
124 | * Reassigned the buttons again (Read Usage section)
125 | * Shortened on-screen instructions down to 2 lines
126 | * Fixed bug when changing directory with marked WADs
127 |
128 | * Wad Manager Multi-Mod (Leathl) v2:
129 | * Reassigned the buttons (Read the Usage section)
130 | * Batch un- and installation is now possible in one turn
131 | * Added confirmation screen before (un-)installation
132 | * Added file operations (can yet only delete single files)
133 |
134 | * Wad Manager Multi-Mod (Leathl) v1:
135 | * Added batch (un)installation
136 |
137 | * Wad Manager Folder Mod (WiiNinja) v3:
138 | * Config file contains additional params to automate the selection of IOS, Storage Device, and NAND Emulation
139 | * WiiLight mod by mariomaniac33
140 |
141 | * Wad Manager Folder Mod (WiiNinja) v2:
142 | * Config file in sd:/wad/wm_config.txt
143 | * Optional startup password. Very simple password using the D-Pads
144 | * Optional startup path
145 |
146 | * Wad Manager Folder Mod (WiiNinja) v1:
147 | * Folder support (10 levels deep)
148 | * GC Controller support
149 | * Removed disclaimer prompt
150 | * Sorg's enhancements are included
151 |
152 | * Wad Manager (Waninkoko) v1.5:
153 | * Allows NAND Emulation.
154 |
155 | * Wad Manager (Waninkoko) v1.4:
156 | * Allows user to choose which IOS to install WAD Manager.
157 |
158 |
159 | ==[ SOURCE ]:==
160 | * http://code.google.com/p/yawmm/source/checkout
161 |
162 |
163 | ==[ THANKS ]:==
164 | * X-Flak
165 | * Pepxl
166 |
167 | ==[ KUDOS ]:==
168 | * Leathl
169 | * WiiNinja
170 | * Sorg
171 | * Waninkoko
172 | * Team Twiizers/devkitPRO
--------------------------------------------------------------------------------
/apps/some-yawmm-mod/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FIX94/Some-YAWMM-Mod/e2708863036066c2cc8bad1fc142e90fb8a0464d/apps/some-yawmm-mod/icon.png
--------------------------------------------------------------------------------
/apps/some-yawmm-mod/meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Some YAWMM Mod
4 | 1.0
5 | various
6 | Install\Uninstall WADs
7 | Press the "A" key to (un)install WADs.
8 | If no files are selected for batch (un)installation, the normal individual (un)installation menu appears.
9 | If at least one file is selected, the batch (un)installation menu appears.
10 |
11 | Press the "+" button to add\remove the selected WAD to the batch installer list
12 | Press the "-" button to add\remove the selected WAD to batch uninstaller list
13 | Press the "1" key to enter the extension menu
14 |
15 | A "+" before the name means the WAD will be installed
16 | A "-" before the name means the WAD will be uninstalled
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/data/background:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FIX94/Some-YAWMM-Mod/e2708863036066c2cc8bad1fc142e90fb8a0464d/data/background
--------------------------------------------------------------------------------
/data/ehcmodule.elf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FIX94/Some-YAWMM-Mod/e2708863036066c2cc8bad1fc142e90fb8a0464d/data/ehcmodule.elf
--------------------------------------------------------------------------------
/include/wiilight.h:
--------------------------------------------------------------------------------
1 | void WIILIGHT_Init();
2 | void WIILIGHT_TurnOn();
3 | int WIILIGHT_GetLevel();
4 | int WIILIGHT_SetLevel(int level);
5 |
6 | void WIILIGHT_Toggle();
7 | void WIILIGHT_TurnOff();
8 |
--------------------------------------------------------------------------------
/lib/libwiilight.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/FIX94/Some-YAWMM-Mod/e2708863036066c2cc8bad1fc142e90fb8a0464d/lib/libwiilight.a
--------------------------------------------------------------------------------
/source/fat.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | //#include
5 |
6 | #include "fat.h"
7 |
8 |
9 | s32 Fat_Mount(fatDevice *dev)
10 | {
11 | s32 ret;
12 |
13 | /* Initialize interface */
14 | ret = dev->interface->startup();
15 | if (!ret)
16 | return -1;
17 |
18 | /* Mount device */
19 | ret = fatMountSimple(dev->mount, dev->interface);
20 | if (!ret)
21 | return -1;
22 |
23 | return 0;
24 | }
25 |
26 | void Fat_Unmount(fatDevice *dev)
27 | {
28 | /* Unmount device */
29 | fatUnmount(dev->mount);
30 |
31 | /* Shutdown interface */
32 | dev->interface->shutdown();
33 | }
34 |
35 | char *Fat_ToFilename(const char *filename)
36 | {
37 | static char buffer[128];
38 |
39 | u32 cnt, idx, len;
40 |
41 | /* Clear buffer */
42 | memset(buffer, 0, sizeof(buffer));
43 |
44 | /* Get filename length */
45 | len = strlen(filename);
46 |
47 | for (cnt = idx = 0; idx < len; idx++) {
48 | char c = filename[idx];
49 |
50 | /* Valid characters */
51 | if ( (c >= '#' && c <= ')') || (c >= '-' && c <= '.') ||
52 | (c >= '0' && c <= '9') || (c >= 'A' && c <= 'z') ||
53 | (c >= 'a' && c <= 'z') || (c == '!') )
54 | buffer[cnt++] = c;
55 | }
56 |
57 | return buffer;
58 | }
59 |
--------------------------------------------------------------------------------
/source/fat.h:
--------------------------------------------------------------------------------
1 | #ifndef _FAT_H_
2 | #define _FAT_H_
3 |
4 | /* libfat header */
5 | #include
6 | #include
7 |
8 | /* SD headers */
9 | #include
10 | #include
11 |
12 |
13 | /* 'FAT Device' structure */
14 | typedef struct {
15 | /* Device mount point */
16 | char *mount;
17 |
18 | /* Device name */
19 | char *name;
20 |
21 | /* Device interface */
22 | const DISC_INTERFACE *interface;
23 | } fatDevice;
24 |
25 | /* 'FAT File' structure */
26 | typedef struct {
27 | /* Filename */
28 | char filename[128];
29 | /* 1 = Batch Install, 2 = Batch Uninstall - Leathl */
30 | int install;
31 |
32 | int installstate;
33 |
34 | /* Filestat */
35 | bool isdir;
36 | size_t fsize;
37 | } fatFile;
38 |
39 |
40 | /* Prototypes */
41 | s32 Fat_Mount(fatDevice *);
42 | void Fat_Unmount(fatDevice *);
43 | char *Fat_ToFilename(const char *);
44 |
45 | #endif
46 |
47 |
--------------------------------------------------------------------------------
/source/globals.h:
--------------------------------------------------------------------------------
1 | #ifndef _GLOBALS_H_
2 | #define _GLOBALS_H_
3 |
4 | // Constants
5 | #define CIOS_VERSION 249
6 | #define ENTRIES_PER_PAGE 14
7 | #define MAX_FILE_PATH_LEN 1024
8 | #define MAX_DIR_LEVELS 10
9 | #define WAD_DIRECTORY "/"
10 | #define WAD_ROOT_DIRECTORY "/wad"
11 |
12 | #define MAX_PASSWORD_LENGTH 10
13 | #define MAX_FAT_DEVICE_LENGTH 10
14 | #define MAX_NAND_DEVICE_LENGTH 10
15 |
16 | #define WM_CONFIG_FILE_PATH ":/wad/wm_config.txt"
17 | #define WM_BACKGROUND_PATH ":/wad/background.png"
18 |
19 | // These are indices into the fatDevice fdevList
20 | #define FAT_DEVICE_INDEX_WII_SD 0
21 | #define FAT_DEVICE_INDXE_USB 1
22 | #define FAT_DEVICE_INDEX_USB2 2
23 | #define FAT_DEVICE_INDEX_GC_SDA 3
24 | #define FAT_DEVICE_INDEX_GC_SDB 4
25 | #define FAT_DEVICE_INDEX_INVALID -1
26 |
27 | // These are the indices into the nandDevice ndevList
28 | #define NAND_DEVICE_INDEX_DISABLE 0
29 | #define NAND_DEVICE_INDEX_SD 1
30 | #define NAND_DEVICE_INDEX_USB 2
31 | #define NAND_DEVICE_INDEX_INVALID -1
32 |
33 | #define CIOS_VERSION_INVALID -1
34 |
35 | // For the WiiLight
36 | #define WII_LIGHT_OFF 0
37 | #define WII_LIGHT_ON 1
38 |
39 | typedef struct
40 | {
41 | char password[MAX_PASSWORD_LENGTH];
42 | char startupPath [256];
43 | int cIOSVersion;
44 | int fatDeviceIndex;
45 | int nandDeviceIndex;
46 | const char *smbuser;
47 | const char *smbpassword;
48 | const char *share;
49 | const char *ip;
50 | } CONFIG;
51 |
52 |
53 | extern CONFIG gConfig;
54 | extern nandDevice ndevList[];
55 | extern fatDevice fdevList[];
56 |
57 |
58 | #endif
59 |
--------------------------------------------------------------------------------
/source/gui.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "video.h"
6 | #include "fat.h"
7 | #include "menu.h"
8 | #include "nand.h"
9 | #include "globals.h"
10 |
11 | /* Constants */
12 | #define CONSOLE_XCOORD 70
13 | #define CONSOLE_YCOORD 118
14 | #define CONSOLE_WIDTH 502
15 | #define CONSOLE_HEIGHT 320
16 |
17 | bool file_exists(const char * filename)
18 | {
19 | FILE * file;
20 | if ((file = fopen(filename, "r")))
21 | {
22 | fclose(file);
23 | return true;
24 | }
25 | return false;
26 | }
27 |
28 |
29 | s32 __Gui_DrawPng(void *img, u32 x, u32 y)
30 | {
31 | IMGCTX ctx = NULL;
32 | PNGUPROP imgProp;
33 |
34 | s32 ret;
35 |
36 | fatDevice *fdev = &fdevList[0];
37 | ret = Fat_Mount(fdev);
38 | if (file_exists("sd:/wad/background.png")) ctx = PNGU_SelectImageFromDevice ("sd:/wad/background.png");
39 |
40 | if (ret < 0)
41 | {
42 | fdev = &fdevList[2];
43 | Fat_Mount(fdev);
44 | if (file_exists("usb2:/wad/background.png")) ctx = PNGU_SelectImageFromDevice ("usb2:/wad/background.png");
45 | }
46 |
47 | if(!ctx)
48 | {
49 | /* Select PNG data */
50 | ctx = PNGU_SelectImageFromBuffer(img);
51 | if (!ctx) {
52 | ret = -1;
53 | goto out;
54 | }
55 | }
56 | /* Get image properties */
57 | ret = PNGU_GetImageProperties(ctx, &imgProp);
58 | if (ret != PNGU_OK) {
59 | ret = -1;
60 | goto out;
61 | }
62 |
63 | /* Draw image */
64 | Video_DrawPng(ctx, imgProp, x, y);
65 |
66 | /* Success */
67 | ret = 0;
68 |
69 | out:
70 | /* Free memory */
71 | if (ctx)
72 | PNGU_ReleaseImageContext(ctx);
73 |
74 | return ret;
75 | }
76 |
77 |
78 | void Gui_InitConsole(void)
79 | {
80 | /* Initialize console */
81 | Con_Init(CONSOLE_XCOORD, CONSOLE_YCOORD, CONSOLE_WIDTH, CONSOLE_HEIGHT);
82 | }
83 |
84 | void Gui_DrawBackground(void)
85 | {
86 | extern char bgData[];
87 |
88 | /* Draw background */
89 | __Gui_DrawPng(bgData, 0, 0);
90 | }
91 |
--------------------------------------------------------------------------------
/source/gui.h:
--------------------------------------------------------------------------------
1 | #ifndef _GUI_H_
2 | #define _GUI_H_
3 |
4 | /* Prototypes */
5 | void Gui_InitConsole(void);
6 | void Gui_DrawBackground(void);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/source/iospatch.c:
--------------------------------------------------------------------------------
1 | // This program is free software: you can redistribute it and/or modify
2 | // it under the terms of the GNU General Public License as published by
3 | // the Free Software Foundation, version 2.0.
4 |
5 | // This program is distributed in the hope that it will be useful,
6 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
7 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 | // GNU General Public License 2.0 for more details.
9 |
10 | // Copyright 2010 Joseph Jordan
11 | // Wii U vWii patches Copyright 2012/2013 damysteryman
12 |
13 |
14 | #include
15 | #include
16 | #include
17 | #include
18 |
19 | #include "iospatch.h"
20 |
21 | #define MEM_REG_BASE 0xd8b4000
22 | #define MEM_PROT (MEM_REG_BASE + 0x20a)
23 |
24 | static void disable_memory_protection() {
25 | write32(MEM_PROT, read32(MEM_PROT) & 0x0000FFFF);
26 | }
27 |
28 | static u32 apply_patch(char *name, const u8 *old, u32 old_size, const u8 *patch, u32 patch_size, u32 patch_offset) {
29 | u8 *ptr_start = (u8*)*((u32*)0x80003134), *ptr_end = (u8*)0x94000000;
30 | u32 found = 0;
31 | printf(" Patching %-30s", name);
32 | u8 *location = NULL;
33 | while (ptr_start < (ptr_end - patch_size)) {
34 | if (!memcmp(ptr_start, old, old_size)) {
35 | found++;
36 | location = ptr_start + patch_offset;
37 | u8 *start = location;
38 | u32 i;
39 | for (i = 0; i < patch_size; i++) {
40 | *location++ = patch[i];
41 | }
42 | DCFlushRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64);
43 | ICInvalidateRange((u8 *)(((u32)start) >> 5 << 5), (patch_size >> 5 << 5) + 64);
44 | }
45 | ptr_start++;
46 | }
47 | if (found)
48 | printf(" patched\n");
49 | else
50 | printf(" not patched\n");
51 | return found;
52 | }
53 | /*
54 | static const u8 di_readlimit_old[] = {
55 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 | 0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0A, 0x00, 0x00,
57 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
58 | 0x7E, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08
59 | };
60 | static const u8 di_readlimit_patch[] = { 0x7e, 0xd4 };
61 |
62 | const u8 isfs_permissions_old[] = { 0x42, 0x8B, 0xD0, 0x01, 0x25, 0x66 };
63 | const u8 isfs_permissions_patch[] = { 0x42, 0x8B, 0xE0, 0x01, 0x25, 0x66 };
64 | static const u8 setuid_old[] = { 0xD1, 0x2A, 0x1C, 0x39 };
65 | static const u8 setuid_patch[] = { 0x46, 0xC0 };
66 | const u8 es_identify_old[] = { 0x28, 0x03, 0xD1, 0x23 };
67 | const u8 es_identify_patch[] = { 0x00, 0x00 };*/
68 | const u8 hash_old[] = { 0x20, 0x07, 0x23, 0xA2 };
69 | const u8 hash_patch[] = { 0x00 };
70 | const u8 new_hash_old[] = { 0x20, 0x07, 0x4B, 0x0B };
71 | const u8 es_set_ahbprot_old[] = { 0x68, 0x5B, 0x22, 0xEC, 0x00, 0x52, 0x18, 0x9B, 0x68, 0x1B, 0x46, 0x98, 0x07, 0xDB };
72 | const u8 es_set_ahbprot_patch[] = { 0x01 };
73 | const u8 ES_TitleVersionCheck_old[] = { 0xD2, 0x01, 0x4E, 0x56 };
74 | const u8 ES_TitleVersionCheck_patch[] = { 0xE0, 0x01, 0x4E, 0x56 };
75 | const u8 ES_TitleDeleteCheck_old[] = { 0xD8, 0x00, 0x4A, 0x04 };
76 | const u8 ES_TitleDeleteCheck_patch[] = { 0xE0, 0x00, 0x4A, 0x04 };
77 |
78 | //Following patches made my damysteryman for use with Wii U's vWii
79 | const u8 Kill_AntiSysTitleInstallv3_pt1_old[] = { 0x68, 0x1A, 0x2A, 0x01, 0xD0, 0x05 }; // Make sure that the pt1
80 | const u8 Kill_AntiSysTitleInstallv3_pt1_patch[] = { 0x68, 0x1A, 0x2A, 0x01, 0x46, 0xC0 }; // patch is applied twice. -dmm
81 | const u8 Kill_AntiSysTitleInstallv3_pt2_old[] = { 0xD0, 0x02, 0x33, 0x06, 0x42, 0x9A, 0xD1, 0x01 }; // Make sure that the pt2 patch
82 | const u8 Kill_AntiSysTitleInstallv3_pt2_patch[] = { 0x46, 0xC0, 0x33, 0x06, 0x42, 0x9A, 0xE0, 0x01 }; // is also applied twice. -dmm
83 | const u8 Kill_AntiSysTitleInstallv3_pt3_old[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x01 };
84 | const u8 Kill_AntiSysTitleInstallv3_pt3_patch[] = { 0x68, 0xFB, 0x2B, 0x00, 0xDB, 0x10 };
85 |
86 | u32 IOSPATCH_AHBPROT() {
87 | if (AHBPROT_DISABLED) {
88 | write32(MEM_PROT, read32(MEM_PROT) & 0x0000FFFF);
89 | //return apply_patch("set_ahbprot", check_tmd_old, sizeof(check_tmd_old), check_tmd_patch, sizeof(check_tmd_patch), 6);
90 | return apply_patch("es_set_ahbprot", es_set_ahbprot_old, sizeof(es_set_ahbprot_old), es_set_ahbprot_patch, sizeof(es_set_ahbprot_patch), 25);
91 | }
92 | return 0;
93 | }
94 |
95 | u32 IOSPATCH_Apply() {
96 | u32 count = 0;
97 | if (AHBPROT_DISABLED) {
98 | disable_memory_protection();
99 | //count += apply_patch("di_readlimit", di_readlimit_old, sizeof(di_readlimit_old), di_readlimit_patch, sizeof(di_readlimit_patch), 12);
100 | //count += apply_patch("isfs_permissions", isfs_permissions_old, sizeof(isfs_permissions_old), isfs_permissions_patch, sizeof(isfs_permissions_patch), 0);
101 | //count += apply_patch("es_setuid", setuid_old, sizeof(setuid_old), setuid_patch, sizeof(setuid_patch), 0);
102 | //count += apply_patch("es_identify", es_identify_old, sizeof(es_identify_old), es_identify_patch, sizeof(es_identify_patch), 2);
103 | count += apply_patch("hash_check", hash_old, sizeof(hash_old), hash_patch, sizeof(hash_patch), 1);
104 | count += apply_patch("new_hash_check", new_hash_old, sizeof(new_hash_old), hash_patch, sizeof(hash_patch), 1);
105 | count += apply_patch("ES_TitleVersionCheck", ES_TitleVersionCheck_old, sizeof(ES_TitleVersionCheck_old), ES_TitleVersionCheck_patch, sizeof(ES_TitleVersionCheck_patch), 0);
106 | count += apply_patch("ES_TitleDeleteCheck", ES_TitleDeleteCheck_old, sizeof(ES_TitleDeleteCheck_old), ES_TitleDeleteCheck_patch, sizeof(ES_TitleDeleteCheck_patch), 0);
107 |
108 | if((*(vu16*)0xCD8005A0 == 0xCAFE))
109 | {
110 | count += apply_patch("Kill_AntiSysTitleInstallv3_pt1", Kill_AntiSysTitleInstallv3_pt1_old, sizeof(Kill_AntiSysTitleInstallv3_pt1_old), Kill_AntiSysTitleInstallv3_pt1_patch, sizeof(Kill_AntiSysTitleInstallv3_pt1_patch), 0);
111 | count += apply_patch("Kill_AntiSysTitleInstallv3_pt2", Kill_AntiSysTitleInstallv3_pt2_old, sizeof(Kill_AntiSysTitleInstallv3_pt2_old), Kill_AntiSysTitleInstallv3_pt2_patch, sizeof(Kill_AntiSysTitleInstallv3_pt2_patch), 0);
112 | count += apply_patch("Kill_AntiSysTitleInstallv3_pt3", Kill_AntiSysTitleInstallv3_pt3_old, sizeof(Kill_AntiSysTitleInstallv3_pt3_old), Kill_AntiSysTitleInstallv3_pt3_patch, sizeof(Kill_AntiSysTitleInstallv3_pt3_patch), 0);
113 | }
114 | }
115 | return count;
116 | }
117 |
--------------------------------------------------------------------------------
/source/iospatch.h:
--------------------------------------------------------------------------------
1 | // This program is free software: you can redistribute it and/or modify
2 | // it under the terms of the GNU General Public License as published by
3 | // the Free Software Foundation, version 2.0.
4 |
5 | // This program is distributed in the hope that it will be useful,
6 | // but WITHOUT ANY WARRANTY; without even the implied warranty of
7 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8 | // GNU General Public License 2.0 for more details.
9 |
10 | // Copyright (C) 2012 damysteryman
11 |
12 |
13 | #ifndef _IOSPATCH_H
14 | #define _IOSPATCH_H
15 |
16 | #ifdef __cplusplus
17 | extern "C" {
18 | #endif
19 | /* __cplusplus */
20 |
21 | #include
22 |
23 | #define AHBPROT_DISABLED ((*(vu32*)0xcd800064 == 0xFFFFFFFF) ? 1 : 0)
24 |
25 | u32 IOSPATCH_AHBPROT();
26 | u32 IOSPATCH_Apply();
27 |
28 | #ifdef __cplusplus
29 | }
30 | #endif /* __cplusplus */
31 |
32 | #endif /* _IOSPATCH_H */
33 |
--------------------------------------------------------------------------------
/source/libpng/pngu/pngu.h:
--------------------------------------------------------------------------------
1 | /********************************************************************************************
2 |
3 | PNGU Version : 0.2a
4 |
5 | Coder : frontier
6 |
7 | More info : http://frontier-dev.net
8 |
9 | ********************************************************************************************/
10 | #ifndef __PNGU__
11 | #define __PNGU__
12 |
13 | // Return codes
14 | #define PNGU_OK 0
15 | #define PNGU_ODD_WIDTH 1
16 | #define PNGU_ODD_STRIDE 2
17 | #define PNGU_INVALID_WIDTH_OR_HEIGHT 3
18 | #define PNGU_FILE_IS_NOT_PNG 4
19 | #define PNGU_UNSUPPORTED_COLOR_TYPE 5
20 | #define PNGU_NO_FILE_SELECTED 6
21 | #define PNGU_CANT_OPEN_FILE 7
22 | #define PNGU_CANT_READ_FILE 8
23 | #define PNGU_LIB_ERROR 9
24 |
25 | // Color types
26 | #define PNGU_COLOR_TYPE_GRAY 1
27 | #define PNGU_COLOR_TYPE_GRAY_ALPHA 2
28 | #define PNGU_COLOR_TYPE_PALETTE 3
29 | #define PNGU_COLOR_TYPE_RGB 4
30 | #define PNGU_COLOR_TYPE_RGB_ALPHA 5
31 | #define PNGU_COLOR_TYPE_UNKNOWN 6
32 |
33 |
34 | #ifdef __cplusplus
35 | extern "C" {
36 | #endif
37 |
38 | // Types
39 | typedef unsigned char PNGU_u8;
40 | typedef unsigned short PNGU_u16;
41 | typedef unsigned int PNGU_u32;
42 | typedef unsigned long long PNGU_u64;
43 |
44 | typedef struct
45 | {
46 | PNGU_u8 r;
47 | PNGU_u8 g;
48 | PNGU_u8 b;
49 | } PNGUCOLOR;
50 |
51 | typedef struct
52 | {
53 | PNGU_u32 imgWidth; // In pixels
54 | PNGU_u32 imgHeight; // In pixels
55 | PNGU_u32 imgBitDepth; // In bitx
56 | PNGU_u32 imgColorType; // PNGU_COLOR_TYPE_*
57 | PNGU_u32 validBckgrnd; // Non zero if there is a background color
58 | PNGUCOLOR bckgrnd; // Backgroun color
59 | PNGU_u32 numTrans; // Number of transparent colors
60 | PNGUCOLOR *trans; // Transparent colors
61 | } PNGUPROP;
62 |
63 | // Image context, always initialize with SelectImageFrom* and free with ReleaseImageContext
64 | struct _IMGCTX;
65 | typedef struct _IMGCTX *IMGCTX;
66 |
67 |
68 | /****************************************************************************
69 | * Pixel conversion *
70 | ****************************************************************************/
71 |
72 | // Macro to convert RGB8 values to RGB565
73 | #define PNGU_RGB8_TO_RGB565(r,g,b) ( ((((PNGU_u16) r) & 0xF8U) << 8) | ((((PNGU_u16) g) & 0xFCU) << 3) | (((PNGU_u16) b) >> 3) )
74 |
75 | // Macro to convert RGBA8 values to RGB5A3
76 | #define PNGU_RGB8_TO_RGB5A3(r,g,b,a) (PNGU_u16) (((a & 0xE0U) == 0xE0U) ? \
77 | (0x8000U | ((((PNGU_u16) r) & 0xF8U) << 7) | ((((PNGU_u16) g) & 0xF8U) << 2) | (((PNGU_u16) b) >> 3)) : \
78 | (((((PNGU_u16) a) & 0xE0U) << 7) | ((((PNGU_u16) r) & 0xF0U) << 4) | (((PNGU_u16) g) & 0xF0U) | ((((PNGU_u16) b) & 0xF0U) >> 4)))
79 |
80 | // Function to convert two RGB8 values to YCbYCr
81 | PNGU_u32 PNGU_RGB8_TO_YCbYCr (PNGU_u8 r1, PNGU_u8 g1, PNGU_u8 b1, PNGU_u8 r2, PNGU_u8 g2, PNGU_u8 b2);
82 |
83 | // Function to convert an YCbYCr to two RGB8 values.
84 | void PNGU_YCbYCr_TO_RGB8 (PNGU_u32 ycbycr, PNGU_u8 *r1, PNGU_u8 *g1, PNGU_u8 *b1, PNGU_u8 *r2, PNGU_u8 *g2, PNGU_u8 *b2);
85 |
86 |
87 | /****************************************************************************
88 | * Image context handling *
89 | ****************************************************************************/
90 |
91 | // Selects a PNG file, previosly loaded into a buffer, and creates an image context for subsequent procesing.
92 | IMGCTX PNGU_SelectImageFromBuffer (const void *buffer);
93 |
94 | // Selects a PNG file, from any devoptab device, and creates an image context for subsequent procesing.
95 | IMGCTX PNGU_SelectImageFromDevice (const char *filename);
96 |
97 | // Frees resources associated with an image context. Always call this function when you no longer need the IMGCTX.
98 | void PNGU_ReleaseImageContext (IMGCTX ctx);
99 |
100 |
101 | /****************************************************************************
102 | * Miscelaneous *
103 | ****************************************************************************/
104 |
105 | // Retrieves info from selected PNG file, including image dimensions, color format, background and transparency colors.
106 | int PNGU_GetImageProperties (IMGCTX ctx, PNGUPROP *fileproperties);
107 |
108 |
109 | /****************************************************************************
110 | * Image conversion *
111 | ****************************************************************************/
112 |
113 | // Expands selected image into an YCbYCr buffer. You need to specify context, image dimensions,
114 | // destination address and stride in pixels (stride = buffer width - image width).
115 | int PNGU_DecodeToYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
116 |
117 | // Macro for decoding an image inside a buffer at given coordinates.
118 | #define PNGU_DECODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
119 | \
120 | PNGU_DecodeToYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
121 | (coordX) * 2, (bufferWidth) - (imgWidth))
122 |
123 | // Expands selected image into a linear RGB565 buffer. You need to specify context, image dimensions,
124 | // destination address and stride in pixels (stride = buffer width - image width).
125 | int PNGU_DecodeToRGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
126 |
127 | // Macro for decoding an image inside a buffer at given coordinates.
128 | #define PNGU_DECODE_TO_COORDS_RGB565(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
129 | \
130 | PNGU_DecodeToRGB565 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
131 | (coordX) * 2, (bufferWidth) - (imgWidth))
132 |
133 | // Expands selected image into a linear RGBA8 buffer. You need to specify context, image dimensions,
134 | // destination address, stride in pixels and default alpha value, which is used if the source image
135 | // doesn't have an alpha channel.
136 | int PNGU_DecodeToRGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride, PNGU_u8 default_alpha);
137 |
138 | // Macro for decoding an image inside a buffer at given coordinates.
139 | #define PNGU_DECODE_TO_COORDS_RGBA8(ctx,coordX,coordY,imgWidth,imgHeight,default_alpha,bufferWidth,bufferHeight,buffer) \
140 | \
141 | PNGU_DecodeToRGBA8 (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
142 | (coordX) * 2, (bufferWidth) - (imgWidth), default_alpha)
143 |
144 | // Expands selected image into a 4x4 tiled RGB565 buffer. You need to specify context, image dimensions
145 | // and destination address.
146 | int PNGU_DecodeTo4x4RGB565 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer);
147 |
148 | // Expands selected image into a 4x4 tiled RGB5A3 buffer. You need to specify context, image dimensions,
149 | // destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
150 | int PNGU_DecodeTo4x4RGB5A3 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
151 |
152 | // Expands selected image into a 4x4 tiled RGBA8 buffer. You need to specify context, image dimensions,
153 | // destination address and default alpha value, which is used if the source image doesn't have an alpha channel.
154 | int PNGU_DecodeTo4x4RGBA8 (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u8 default_alpha);
155 |
156 | // Encodes an YCbYCr image in PNG format and stores it in the selected device or memory buffer. You need to
157 | // specify context, image dimensions, destination address and stride in pixels (stride = buffer width - image width).
158 | int PNGU_EncodeFromYCbYCr (IMGCTX ctx, PNGU_u32 width, PNGU_u32 height, void *buffer, PNGU_u32 stride);
159 |
160 | // Macro for encoding an image stored into an YCbYCr buffer at given coordinates.
161 | #define PNGU_ENCODE_TO_COORDS_YCbYCr(ctx,coordX,coordY,imgWidth,imgHeight,bufferWidth,bufferHeight,buffer) \
162 | \
163 | PNGU_EncodeFromYCbYCr (ctx, imgWidth, imgHeight, ((void *) buffer) + (coordY) * (bufferWidth) * 2 + \
164 | (coordX) * 2, (bufferWidth) - (imgWidth))
165 |
166 | #ifdef __cplusplus
167 | }
168 | #endif
169 |
170 | #endif
171 |
172 |
--------------------------------------------------------------------------------
/source/menu.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "sys.h"
11 | #include "fat.h"
12 | #include "nand.h"
13 | #include "restart.h"
14 | #include "title.h"
15 | #include "usbstorage.h"
16 | #include "utils.h"
17 | #include "video.h"
18 | #include "wad.h"
19 | #include "wpad.h"
20 | #include
21 | #include "globals.h"
22 | #include "iospatch.h"
23 |
24 | /* FAT device list */
25 | //static fatDevice fdevList[] = {
26 | fatDevice fdevList[] = {
27 | { "sd", "Wii SD Slot", &__io_wiisd },
28 | { "usb", "USB Mass Storage Device", &__io_usbstorage },
29 | { "usb2", "USB 2.0 Mass Storage Device", &__io_wiiums },
30 | { "gcsda", "SD Gecko (Slot A)", &__io_gcsda },
31 | { "gcsdb", "SD Gecko (Slot B)", &__io_gcsdb },
32 | //{ "smb", "SMB share", NULL },
33 | };
34 |
35 | /* NAND device list */
36 | //static nandDevice ndevList[] = {
37 | nandDevice ndevList[] = {
38 | { "Disable", 0, 0x00, 0x00 },
39 | { "SD/SDHC Card", 1, 0xF0, 0xF1 },
40 | { "USB 2.0 Mass Storage Device", 2, 0xF2, 0xF3 },
41 | };
42 |
43 | /* FAT device */
44 | static fatDevice *fdev = NULL;
45 | static nandDevice *ndev = NULL;
46 |
47 | // wiiNinja: Define a buffer holding the previous path names as user
48 | // traverses the directory tree. Max of 10 levels is define at this point
49 | static u8 gDirLevel = 0;
50 | static char gDirList [MAX_DIR_LEVELS][MAX_FILE_PATH_LEN];
51 | static s32 gSeleted[MAX_DIR_LEVELS];
52 | static s32 gStart[MAX_DIR_LEVELS];
53 |
54 | /* Macros */
55 | #define NB_FAT_DEVICES (sizeof(fdevList) / sizeof(fatDevice))
56 | #define NB_NAND_DEVICES (sizeof(ndevList) / sizeof(nandDevice))
57 |
58 | // Local prototypes: wiiNinja
59 | void WaitPrompt (char *prompt);
60 | int PushCurrentDir(char *dirStr, int Selected, int Start);
61 | char *PopCurrentDir(int *Selected, int *Start);
62 | bool IsListFull (void);
63 | char *PeekCurrentDir (void);
64 | u32 WaitButtons(void);
65 | u32 Pad_GetButtons(void);
66 | void WiiLightControl (int state);
67 |
68 | int __Menu_IsGreater(const void *p1, const void *p2)
69 | {
70 | u32 n1 = *(u32 *)p1;
71 | u32 n2 = *(u32 *)p2;
72 |
73 | /* Equal */
74 | if (n1 == n2)
75 | return 0;
76 |
77 | return (n1 > n2) ? 1 : -1;
78 | }
79 |
80 |
81 | int __Menu_EntryCmp(const void *p1, const void *p2)
82 | {
83 | fatFile *f1 = (fatFile *)p1;
84 | fatFile *f2 = (fatFile *)p2;
85 |
86 | /* Compare entries */ // wiiNinja: Include directory
87 | if ((f1->isdir) && !(f2->isdir))
88 | return (-1);
89 | else if (!(f1->isdir) && (f2->isdir))
90 | return (1);
91 | else
92 | return strcasecmp(f1->filename, f2->filename);
93 | }
94 |
95 | static bool __FolderExists(const char *path)
96 | {
97 | DIR *dir;
98 | dir = opendir(path);
99 | if(dir)
100 | {
101 | closedir(dir);
102 | return true;
103 | }
104 | return false;
105 | }
106 |
107 | static size_t __GetFileSizeBytes(const char *path)
108 | {
109 | FILE *f;
110 | size_t size = 0;
111 |
112 | f = fopen(path, "rb");
113 | if(!f) return 0;
114 |
115 | //Get file size
116 | fseek(f, 0, SEEK_END);
117 | size = ftell(f);
118 | fclose(f);
119 |
120 | return size;
121 | }
122 |
123 | char gFileName[MAX_FILE_PATH_LEN];
124 | s32 __Menu_RetrieveList(char *inPath, fatFile **outbuf, u32 *outlen)
125 | {
126 | fatFile *buffer = NULL;
127 | DIR *dir = NULL;
128 | struct dirent *ent = NULL;
129 |
130 | //char dirpath[256], filename[768];
131 | u32 cnt;
132 |
133 | /* Generate dirpath */
134 | //sprintf(dirpath, "%s:" WAD_DIRECTORY, fdev->mount);
135 |
136 | /* Open directory */
137 | dir = opendir(inPath);
138 | if (!dir)
139 | return -1;
140 |
141 | /* Count entries */
142 | for (cnt = 0; ((ent = readdir(dir)) != NULL);) {
143 | cnt++;
144 | }
145 |
146 | if (cnt > 0) {
147 | /* Allocate memory */
148 | buffer = malloc(sizeof(fatFile) * cnt);
149 | if (!buffer) {
150 | closedir(dir);
151 | return -2;
152 | }
153 |
154 | /* Reset directory */
155 | rewinddir(dir);
156 |
157 | /* Get entries */
158 | for (cnt = 0; ((ent = readdir(dir)) != NULL);)
159 | {
160 | bool addFlag = false;
161 | bool isdir = false;
162 | size_t fsize = 0;
163 |
164 | snprintf(gFileName, MAX_FILE_PATH_LEN, "%s/%s", inPath, ent->d_name);
165 | if (__FolderExists(gFileName)) // wiiNinja
166 | {
167 | isdir = true;
168 | // Add only the item ".." which is the previous directory
169 | // AND if we're not at the root directory
170 | if ((strcmp (ent->d_name, "..") == 0) && (gDirLevel > 1))
171 | addFlag = true;
172 | else if (strcmp (ent->d_name, ".") != 0)
173 | addFlag = true;
174 | }
175 | else
176 | {
177 | if(strlen(ent->d_name)>4)
178 | {
179 | if(!strcasecmp(ent->d_name+strlen(ent->d_name)-4, ".wad"))
180 | {
181 | fsize = __GetFileSizeBytes(gFileName);
182 | addFlag = true;
183 | }
184 | }
185 | }
186 |
187 | if (addFlag == true)
188 | {
189 | fatFile *file = &buffer[cnt++];
190 |
191 | /* File name */
192 | strcpy(file->filename, ent->d_name);
193 |
194 | /* File stats */
195 | file->isdir = isdir;
196 | file->fsize = fsize;
197 |
198 | }
199 | }
200 |
201 | /* Sort list */
202 | qsort(buffer, cnt, sizeof(fatFile), __Menu_EntryCmp);
203 | }
204 |
205 | /* Close directory */
206 | closedir(dir);
207 |
208 | /* Set values */
209 | *outbuf = buffer;
210 | *outlen = cnt;
211 |
212 | return 0;
213 | }
214 |
215 |
216 | void Menu_SelectIOS(void)
217 | {
218 | u8 *iosVersion = NULL;
219 | u32 iosCnt;
220 | u8 tmpVersion;
221 |
222 | u32 cnt;
223 | s32 ret, selected = 0;
224 | bool found = false;
225 |
226 | /* Get IOS versions */
227 | ret = Title_GetIOSVersions(&iosVersion, &iosCnt);
228 | if (ret < 0)
229 | return;
230 |
231 | /* Sort list */
232 | qsort(iosVersion, iosCnt, sizeof(u8), __Menu_IsGreater);
233 |
234 | if (gConfig.cIOSVersion < 0)
235 | tmpVersion = CIOS_VERSION;
236 | else
237 | {
238 | tmpVersion = (u8)gConfig.cIOSVersion;
239 | // For debugging only
240 | //printf ("User pre-selected cIOS: %i\n", tmpVersion);
241 | //WaitButtons();
242 | }
243 |
244 | /* Set default version */
245 | for (cnt = 0; cnt < iosCnt; cnt++) {
246 | u8 version = iosVersion[cnt];
247 |
248 | /* Custom IOS available */
249 | //if (version == CIOS_VERSION)
250 | if (version == tmpVersion)
251 | {
252 | selected = cnt;
253 | found = true;
254 | break;
255 | }
256 |
257 | /* Current IOS */
258 | if (version == IOS_GetVersion())
259 | selected = cnt;
260 | }
261 |
262 | /* Ask user for IOS version */
263 | if ((gConfig.cIOSVersion < 0) || (found == false))
264 | {
265 | for (;;)
266 | {
267 | /* Clear console */
268 | Con_Clear();
269 |
270 | printf("\t>> Select IOS version to use: < IOS%d >\n\n", iosVersion[selected]);
271 |
272 | printf("\t Press LEFT/RIGHT to change IOS version.\n\n");
273 |
274 | printf("\t Press A button to continue.\n");
275 | printf("\t Press HOME button to restart.\n\n");
276 |
277 | u32 buttons = WaitButtons();
278 |
279 | /* LEFT/RIGHT buttons */
280 | if (buttons & WPAD_BUTTON_LEFT) {
281 | if ((--selected) <= -1)
282 | selected = (iosCnt - 1);
283 | }
284 | if (buttons & WPAD_BUTTON_RIGHT) {
285 | if ((++selected) >= iosCnt)
286 | selected = 0;
287 | }
288 |
289 | /* HOME button */
290 | if (buttons & WPAD_BUTTON_HOME)
291 | Restart();
292 |
293 | /* A button */
294 | if (buttons & WPAD_BUTTON_A)
295 | break;
296 | }
297 | }
298 |
299 |
300 | u8 version = iosVersion[selected];
301 |
302 | if (IOS_GetVersion() != version) {
303 | /* Shutdown subsystems */
304 | Wpad_Disconnect();
305 | //mload_close();
306 |
307 | /* Load IOS */
308 |
309 | if(!loadIOS(version)) Wpad_Init(), Menu_SelectIOS();
310 |
311 | /* Initialize subsystems */
312 | Wpad_Init();
313 | }
314 | }
315 |
316 | void Menu_FatDevice(void)
317 | {
318 | int ret, selected = 0;
319 |
320 | /* Unmount FAT device */
321 | //if (fdev)
322 | //Fat_Unmount(fdev);
323 | //if (((fdevList[selected].mount[0] == 's') && (ndev->name[0] == 'S')))
324 | //selected++;
325 |
326 | /* Select source device */
327 | if (gConfig.fatDeviceIndex < 0)
328 | {
329 | for (;;) {
330 | /* Clear console */
331 | Con_Clear();
332 |
333 | /* Selected device */
334 | fdev = &fdevList[selected];
335 |
336 | printf("\t>> Select source device: < %s >\n\n", fdev->name);
337 |
338 | printf("\t Press LEFT/RIGHT to change the selected device.\n\n");
339 |
340 | printf("\t Press A button to continue.\n");
341 | printf("\t Press HOME button to restart.\n\n");
342 |
343 | u32 buttons = WaitButtons();
344 |
345 | /* LEFT/RIGHT buttons */
346 | if (buttons & WPAD_BUTTON_LEFT) {
347 | if ((--selected) <= -1)
348 | selected = (NB_FAT_DEVICES - 1);
349 | if ((fdevList[selected].mount[0] == 's') && (ndev->name[0] == 'S'))
350 | selected--;
351 | if ((fdevList[selected].mount[0] == 'u' && fdevList[selected].mount[3] == '2') && (ndev->name[0] == 'U'))
352 | selected--;
353 | if ((selected) <= -1)
354 | selected = (NB_FAT_DEVICES - 1);
355 | }
356 | if (buttons & WPAD_BUTTON_RIGHT) {
357 | if ((++selected) >= NB_FAT_DEVICES)
358 | selected = 0;
359 | if ((fdevList[selected].mount[0] == 's') && (ndev->name[0] == 'S'))
360 | selected++;
361 | if ((fdevList[selected].mount[0] == 'u' && fdevList[selected].mount[3] == '2') && (ndev->name[0] == 'U'))
362 | selected++;
363 | }
364 |
365 | /* HOME button */
366 | if (buttons & WPAD_BUTTON_HOME)
367 | Restart();
368 |
369 | /* A button */
370 | if (buttons & WPAD_BUTTON_A)
371 | break;
372 | }
373 | }
374 | else
375 | {
376 | sleep(5);
377 | fdev = &fdevList[gConfig.fatDeviceIndex];
378 | }
379 |
380 | printf("[+] Mounting %s, please wait...", fdev->name );
381 | fflush(stdout);
382 |
383 | /* Mount FAT device */
384 |
385 | ret = Fat_Mount(fdev);
386 | if (ret < 0) {
387 | printf(" ERROR! (ret = %d)\n", ret);
388 | goto err;
389 | } else
390 | printf(" OK!\n");
391 |
392 | return;
393 |
394 | err:
395 |
396 | if(gConfig.fatDeviceIndex >= 0) gConfig.fatDeviceIndex = -1;
397 | WiiLightControl (WII_LIGHT_OFF);
398 | printf("\n");
399 | printf(" Press any button to continue...\n");
400 |
401 | WaitButtons();
402 |
403 | /* Prompt menu again */
404 | Menu_FatDevice();
405 | }
406 |
407 | void Menu_NandDevice(void)
408 | {
409 | int ret, selected = 0;
410 |
411 | /* Disable NAND emulator */
412 | if (ndev) {
413 | Nand_Unmount(ndev);
414 | Nand_Disable();
415 | }
416 |
417 | /* Select source device */
418 | if (gConfig.nandDeviceIndex < 0)
419 | {
420 | for (;;) {
421 | /* Clear console */
422 | Con_Clear();
423 |
424 | /* Selected device */
425 | ndev = &ndevList[selected];
426 |
427 | printf("\t>> Select NAND emulator device: < %s >\n\n", ndev->name);
428 |
429 | printf("\t Press LEFT/RIGHT to change the selected device.\n\n");
430 |
431 | printf("\t Press A button to continue.\n");
432 | printf("\t Press HOME button to restart.\n\n");
433 |
434 | u32 buttons = WaitButtons();
435 |
436 | /* LEFT/RIGHT buttons */
437 | if (buttons & WPAD_BUTTON_LEFT) {
438 | if ((--selected) <= -1)
439 | selected = (NB_NAND_DEVICES - 1);
440 | }
441 | if (buttons & WPAD_BUTTON_RIGHT) {
442 | if ((++selected) >= NB_NAND_DEVICES)
443 | selected = 0;
444 | }
445 |
446 | /* HOME button */
447 | if (buttons & WPAD_BUTTON_HOME)
448 | Restart();
449 |
450 | /* A button */
451 | if (buttons & WPAD_BUTTON_A)
452 | break;
453 | }
454 | }
455 | else
456 | {
457 | ndev = &ndevList[gConfig.nandDeviceIndex];
458 | }
459 |
460 | /* No NAND device */
461 | if (!ndev->mode)
462 | return;
463 |
464 | printf("[+] Enabling NAND emulator...");
465 | fflush(stdout);
466 |
467 | /* Mount NAND device */
468 | ret = Nand_Mount(ndev);
469 | if (ret < 0) {
470 | printf(" ERROR! (ret = %d)\n", ret);
471 | goto err;
472 | }
473 |
474 | /* Enable NAND emulator */
475 | ret = Nand_Enable(ndev);
476 | if (ret < 0) {
477 | printf(" ERROR! (ret = %d)\n", ret);
478 | goto err;
479 | } else
480 | printf(" OK!\n");
481 |
482 | return;
483 |
484 | err:
485 | printf("\n");
486 | printf(" Press any button to continue...\n");
487 |
488 | WaitButtons();
489 |
490 | /* Prompt menu again */
491 | Menu_NandDevice();
492 | }
493 |
494 | char gTmpFilePath[MAX_FILE_PATH_LEN];
495 | /* Install and/or Uninstall multiple WADs - Leathl */
496 | int Menu_BatchProcessWads(fatFile *files, int fileCount, char *inFilePath, int installCnt, int uninstallCnt)
497 | {
498 | int count;
499 |
500 | for (;;)
501 | {
502 | Con_Clear();
503 |
504 | if ((installCnt > 0) & (uninstallCnt == 0)) {
505 | printf("[+] %d file%s marked for installation.\n", installCnt, (installCnt == 1) ? "" : "s");
506 | printf(" Do you want to proceed?\n");
507 | }
508 | else if ((installCnt == 0) & (uninstallCnt > 0)) {
509 | printf("[+] %d file%s marked for uninstallation.\n", uninstallCnt, (uninstallCnt == 1) ? "" : "s");
510 | printf(" Do you want to proceed?\n");
511 | }
512 | else {
513 | printf("[+] %d file%s marked for installation and %d file%s for uninstallation.\n", installCnt, (installCnt == 1) ? "" : "s", uninstallCnt, (uninstallCnt == 1) ? "" : "s");
514 | printf(" Do you want to proceed?\n");
515 | }
516 |
517 | printf("\n\n Press A to continue.\n");
518 | printf(" Press B to go back to the menu.\n\n");
519 |
520 | u32 buttons = WaitButtons();
521 |
522 | if (buttons & WPAD_BUTTON_A)
523 | break;
524 |
525 | if (buttons & WPAD_BUTTON_B)
526 | return 0;
527 | }
528 |
529 | WiiLightControl (WII_LIGHT_ON);
530 | int errors = 0;
531 | int success = 0;
532 | s32 ret;
533 |
534 | for (count = 0; count < fileCount; count++)
535 | {
536 | fatFile *thisFile = &files[count];
537 |
538 | if ((thisFile->install == 1) | (thisFile->install == 2)) {
539 | int mode = thisFile->install;
540 | Con_Clear();
541 | printf("[+] Opening \"%s\", please wait...\n\n", thisFile->filename);
542 |
543 | sprintf(gTmpFilePath, "%s/%s", inFilePath, thisFile->filename);
544 |
545 | FILE *fp = fopen(gTmpFilePath, "rb");
546 | if (!fp) {
547 | printf(" ERROR!\n");
548 | errors += 1;
549 | continue;
550 | }
551 |
552 | printf("[+] %s WAD, please wait...\n", (mode == 2) ? "Uninstalling" : "Installing");
553 | if (mode == 2) {
554 | ret = Wad_Uninstall(fp);
555 | }
556 | else {
557 | ret = Wad_Install(fp);
558 | }
559 |
560 | if (ret < 0) errors += 1;
561 | else success += 1;
562 |
563 | thisFile->installstate = ret;
564 |
565 | if (fp)
566 | fclose(fp);
567 | }
568 | }
569 |
570 | WiiLightControl (WII_LIGHT_OFF);
571 |
572 | printf("\n");
573 | printf(" %d titles succeeded and %d failed...\n", success, errors);
574 |
575 | if (errors > 0)
576 | {
577 | printf("\n Some operations failed");
578 | printf("\n Press A to list.\n");
579 | printf(" Press B skip.\n");
580 |
581 | u32 buttons = WaitButtons();
582 |
583 | if ((buttons & WPAD_BUTTON_A))
584 | {
585 | Con_Clear();
586 |
587 | int i=0;
588 | for (count = 0; count < fileCount; count++)
589 | {
590 | fatFile *thisFile = &files[count];
591 |
592 | if (thisFile->installstate <0)
593 | {
594 | char str[41];
595 | strncpy(str, thisFile->filename, 40); //Only 40 chars to fit the screen
596 | str[40]=0;
597 | i++;
598 | if(thisFile->installstate == -999) printf(" %s BRICK BLOCKED\n", str);
599 | else if(thisFile->installstate == -998) printf(" %s Skipped\n", str);
600 | else if(thisFile->installstate == -106) printf(" %s Not installed?\n", str);
601 | else if(thisFile->installstate == -1036 ) printf(" %s Needed IOS missing\n", str);
602 | else if(thisFile->installstate == -4100 ) printf(" %s No trucha bug?\n", str);
603 | else printf(" %s error %d\n", str, thisFile->installstate);
604 | if( i == 17 )
605 | {
606 | printf("\n Press any button to continue\n");
607 | WaitButtons();
608 | i = 0;
609 | }
610 | }
611 | }
612 | }
613 | }
614 | printf("\n Press any button to continue...\n");
615 | WaitButtons();
616 |
617 | return 1;
618 | }
619 |
620 | /* File Operations - Leathl */
621 | int Menu_FileOperations(fatFile *file, char *inFilePath)
622 | {
623 | f32 filesize = (file->fsize / MB_SIZE);
624 |
625 | for (;;)
626 | {
627 | Con_Clear();
628 |
629 | printf("[+] WAD Filename : %s\n", file->filename);
630 | printf(" WAD Filesize : %.2f MB\n\n\n", filesize);
631 |
632 |
633 | printf("[+] Select action: < %s WAD >\n\n", "Delete"); //There's yet nothing else than delete
634 |
635 | printf(" Press LEFT/RIGHT to change selected action.\n\n");
636 |
637 | printf(" Press A to continue.\n");
638 | printf(" Press B to go back to the menu.\n\n");
639 |
640 | u32 buttons = WaitButtons();
641 |
642 | /* A button */
643 | if (buttons & WPAD_BUTTON_A)
644 | break;
645 |
646 | /* B button */
647 | if (buttons & WPAD_BUTTON_B)
648 | return 0;
649 | }
650 |
651 | Con_Clear();
652 |
653 | printf("[+] Deleting \"%s\", please wait...\n", file->filename);
654 |
655 | sprintf(gTmpFilePath, "%s/%s", inFilePath, file->filename);
656 | int error = remove(gTmpFilePath);
657 | if (error != 0)
658 | printf(" ERROR!");
659 | else
660 | printf(" Successfully deleted!");
661 |
662 | printf("\n");
663 | printf(" Press any button to continue...\n");
664 |
665 | WaitButtons();
666 |
667 | return !error;
668 | }
669 |
670 | void Menu_WadManage(fatFile *file, char *inFilePath)
671 | {
672 | FILE *fp = NULL;
673 |
674 | //char filepath[128];
675 | f32 filesize;
676 |
677 | u32 mode = 0;
678 |
679 | /* File size in megabytes */
680 | filesize = (file->fsize / MB_SIZE);
681 |
682 | for (;;) {
683 | /* Clear console */
684 | Con_Clear();
685 |
686 | printf("[+] WAD Filename : %s\n", file->filename);
687 | printf(" WAD Filesize : %.2f MB\n\n\n", filesize);
688 |
689 |
690 | printf("[+] Select action: < %s WAD >\n\n", (!mode) ? "Install" : "Uninstall");
691 |
692 | printf(" Press LEFT/RIGHT to change selected action.\n\n");
693 |
694 | printf(" Press A to continue.\n");
695 | printf(" Press B to go back to the menu.\n\n");
696 |
697 | u32 buttons = WaitButtons();
698 |
699 | /* LEFT/RIGHT buttons */
700 | if (buttons & (WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT))
701 | mode ^= 1;
702 |
703 | /* A button */
704 | if (buttons & WPAD_BUTTON_A)
705 | break;
706 |
707 | /* B button */
708 | if (buttons & WPAD_BUTTON_B)
709 | return;
710 | }
711 |
712 | /* Clear console */
713 | Con_Clear();
714 |
715 | printf("[+] Opening \"%s\", please wait...", file->filename);
716 | fflush(stdout);
717 |
718 | /* Generate filepath */
719 | // sprintf(filepath, "%s:" WAD_DIRECTORY "/%s", fdev->mount, file->filename);
720 | sprintf(gTmpFilePath, "%s/%s", inFilePath, file->filename); // wiiNinja
721 |
722 | /* Open WAD */
723 | fp = fopen(gTmpFilePath, "rb");
724 | if (!fp) {
725 | printf(" ERROR!\n");
726 | goto out;
727 | } else
728 | printf(" OK!\n\n");
729 |
730 | printf("[+] %s WAD, please wait...\n", (!mode) ? "Installing" : "Uninstalling");
731 |
732 | /* Do install/uninstall */
733 | WiiLightControl (WII_LIGHT_ON);
734 | if (!mode)
735 | Wad_Install(fp);
736 | else
737 | Wad_Uninstall(fp);
738 | WiiLightControl (WII_LIGHT_OFF);
739 |
740 | out:
741 | /* Close file */
742 | if (fp)
743 | fclose(fp);
744 |
745 | printf("\n");
746 | printf(" Press any button to continue...\n");
747 |
748 | /* Wait for button */
749 | WaitButtons();
750 | }
751 |
752 | void Menu_WadList(void)
753 | {
754 | char str [100];
755 | fatFile *fileList = NULL;
756 | u32 fileCnt;
757 | int ret, selected = 0, start = 0;
758 | char *tmpPath = malloc (MAX_FILE_PATH_LEN);
759 | int installCnt = 0;
760 | int uninstallCnt = 0;
761 |
762 | //fatFile *installFiles = malloc(sizeof(fatFile) * 50);
763 | //int installCount = 0;
764 |
765 | // wiiNinja: check for malloc error
766 | if (tmpPath == NULL)
767 | {
768 | ret = -997; // What am I gonna use here?
769 | printf(" ERROR! Out of memory (ret = %d)\n", ret);
770 | return;
771 | }
772 |
773 | printf("[+] Retrieving file list...");
774 | fflush(stdout);
775 |
776 | gDirLevel = 0;
777 |
778 | // push root dir as base folder
779 | sprintf(tmpPath, "%s:%s", fdev->mount, WAD_DIRECTORY);
780 | PushCurrentDir(tmpPath,0,0);
781 | // if user provides startup directory, try it out first
782 | if (strcmp (WAD_DIRECTORY, gConfig.startupPath) != 0)
783 | {
784 | // replace root dir with provided startup directory
785 | sprintf(tmpPath, "%s:%s", fdev->mount, gConfig.startupPath);
786 | // If the directory can be successfully opened, it must exists
787 | DIR *tmpDirPtr = opendir(tmpPath);
788 | if (tmpDirPtr)
789 | {
790 | closedir (tmpDirPtr);
791 | PushCurrentDir(tmpPath,0,0);
792 | }
793 | else // unable to open provided dir, stick with root dir
794 | sprintf(tmpPath, "%s:%s", fdev->mount, WAD_DIRECTORY);
795 | }
796 |
797 | /* Retrieve filelist */
798 | getList:
799 | if (fileList)
800 | {
801 | free (fileList);
802 | fileList = NULL;
803 | }
804 |
805 | ret = __Menu_RetrieveList(tmpPath, &fileList, &fileCnt);
806 | if (ret < 0) {
807 | printf(" ERROR! (ret = %d)\n", ret);
808 | goto err;
809 | }
810 |
811 | /* No files */
812 | if (!fileCnt) {
813 | printf(" No files found!\n");
814 | goto err;
815 | }
816 |
817 | /* Set install-values to 0 - Leathl */
818 | int counter;
819 | for (counter = 0; counter < fileCnt; counter++) {
820 | fatFile *file = &fileList[counter];
821 | file->install = 0;
822 | }
823 |
824 | for (;;)
825 | {
826 | u32 cnt;
827 | s32 index;
828 |
829 | /* Clear console */
830 | Con_Clear();
831 |
832 | /** Print entries **/
833 | cnt = strlen(tmpPath);
834 | if(cnt>30)
835 | index = cnt-30;
836 | else
837 | index = 0;
838 |
839 | printf("[+] WAD files on [%s]:\n\n", tmpPath+index);
840 |
841 | /* Print entries */
842 | for (cnt = start; cnt < fileCnt; cnt++)
843 | {
844 | fatFile *file = &fileList[cnt];
845 | f32 filesize = file->fsize / MB_SIZE;
846 |
847 | /* Entries per page limit */
848 | if ((cnt - start) >= ENTRIES_PER_PAGE)
849 | break;
850 |
851 | strncpy(str, file->filename, 40); //Only 40 chars to fit the screen
852 | str[40]=0;
853 |
854 | /* Print filename */
855 | //printf("\t%2s %s (%.2f MB)\n", (cnt == selected) ? ">>" : " ", file->filename, filesize);
856 | if (file->isdir) // wiiNinja
857 | printf("\t%2s [%s]\n", (cnt == selected) ? ">>" : " ", str);
858 | else
859 | printf("\t%2s%s%s (%.2f MB)\n", (cnt == selected) ? ">>" : " ", (file->install == 1) ? "+" : ((file->install == 2) ? "-" : " "), str, filesize);
860 |
861 | }
862 |
863 | printf("\n");
864 |
865 | printf("[+] Press A to (un)install.");
866 | if(gDirLevel>1)
867 | printf(" Press B to go up-level DIR.\n");
868 | else
869 | printf(" Press B to select a device.\n");
870 | printf(" Use +/X and -/Y to (un)mark. Press 1/Z/ZR for delete menu.");
871 |
872 | /** Controls **/
873 | u32 buttons = WaitButtons();
874 |
875 | /* DPAD buttons */
876 | if (buttons & WPAD_BUTTON_UP) {
877 | selected--;
878 |
879 | if (selected <= -1)
880 | selected = (fileCnt - 1);
881 | }
882 | if (buttons & WPAD_BUTTON_LEFT) {
883 | selected = selected + ENTRIES_PER_PAGE;
884 |
885 | if (selected >= fileCnt)
886 | selected = 0;
887 | }
888 | if (buttons & WPAD_BUTTON_DOWN) {
889 | selected ++;
890 |
891 | if (selected >= fileCnt)
892 | selected = 0;
893 | }
894 | if (buttons & WPAD_BUTTON_RIGHT) {
895 | selected = selected - ENTRIES_PER_PAGE;
896 |
897 | if (selected <= -1)
898 | selected = (fileCnt - 1);
899 | }
900 |
901 | /* HOME button */
902 | if (buttons & WPAD_BUTTON_HOME)
903 | Restart();
904 |
905 | /* Plus Button - Leathl */
906 | if (buttons & WPAD_BUTTON_PLUS)
907 | {
908 | if(Wpad_TimeButton())
909 | {
910 | installCnt = 0;
911 | int i = 0;
912 | while( i < fileCnt)
913 | {
914 | fatFile *file = &fileList[i];
915 | if (((file->isdir) == false) & (file->install == 0)) {
916 | file->install = 1;
917 |
918 | installCnt += 1;
919 | }
920 | else if (((file->isdir) == false) & (file->install == 1)) {
921 | file->install = 0;
922 |
923 | installCnt -= 1;
924 | }
925 | else if (((file->isdir) == false) & (file->install == 2)) {
926 | file->install = 1;
927 |
928 | installCnt += 1;
929 | uninstallCnt -= 1;
930 | }
931 | i++;
932 | }
933 |
934 | }
935 | else
936 | {
937 | fatFile *file = &fileList[selected];
938 | if (((file->isdir) == false) & (file->install == 0)) {
939 | file->install = 1;
940 |
941 | installCnt += 1;
942 | }
943 | else if (((file->isdir) == false) & (file->install == 1)) {
944 | file->install = 0;
945 |
946 | installCnt -= 1;
947 | }
948 | else if (((file->isdir) == false) & (file->install == 2)) {
949 | file->install = 1;
950 |
951 | installCnt += 1;
952 | uninstallCnt -= 1;
953 | }
954 | selected++;
955 |
956 | if (selected >= fileCnt)
957 | selected = 0;
958 | }
959 | }
960 |
961 | /* Minus Button - Leathl */
962 | if (buttons & WPAD_BUTTON_MINUS)
963 | {
964 | if(Wpad_TimeButton())
965 | {
966 | installCnt = 0;
967 | int i = 0;
968 | while( i < fileCnt)
969 | {
970 | fatFile *file = &fileList[i];
971 | if (((file->isdir) == false) & (file->install == 0)) {
972 | file->install = 2;
973 |
974 | uninstallCnt += 1;
975 | }
976 | else if (((file->isdir) == false) & (file->install == 1)) {
977 | file->install = 2;
978 |
979 | uninstallCnt += 1;
980 | installCnt -= 1;
981 | }
982 | else if (((file->isdir) == false) & (file->install == 2)) {
983 | file->install = 0;
984 |
985 | uninstallCnt -= 1;
986 | }
987 | i++;
988 | }
989 |
990 | }
991 | else
992 | {
993 | fatFile *file = &fileList[selected];
994 | if (((file->isdir) == false) & (file->install == 0)) {
995 | file->install = 2;
996 |
997 | uninstallCnt += 1;
998 | }
999 | else if (((file->isdir) == false) & (file->install == 1)) {
1000 | file->install = 2;
1001 |
1002 | uninstallCnt += 1;
1003 | installCnt -= 1;
1004 | }
1005 | else if (((file->isdir) == false) & (file->install == 2)) {
1006 | file->install = 0;
1007 |
1008 | uninstallCnt -= 1;
1009 | }
1010 | selected++;
1011 |
1012 | if (selected >= fileCnt)
1013 | selected = 0;
1014 | }
1015 | }
1016 |
1017 | /* 1 Button - Leathl */
1018 | if (buttons & WPAD_BUTTON_1)
1019 | {
1020 | fatFile *tmpFile = &fileList[selected];
1021 | char *tmpCurPath = PeekCurrentDir ();
1022 | if (tmpCurPath != NULL) {
1023 | int res = Menu_FileOperations(tmpFile, tmpCurPath);
1024 | if (res != 0)
1025 | goto getList;
1026 | }
1027 | }
1028 |
1029 |
1030 | /* A button */
1031 | if (buttons & WPAD_BUTTON_A)
1032 | {
1033 | fatFile *tmpFile = &fileList[selected];
1034 | char *tmpCurPath;
1035 | if (tmpFile->isdir) // wiiNinja
1036 | {
1037 | if (strcmp (tmpFile->filename, "..") == 0)
1038 | {
1039 | selected = 0;
1040 | start = 0;
1041 |
1042 | // Previous dir
1043 | tmpCurPath = PopCurrentDir(&selected, &start);
1044 | if (tmpCurPath != NULL)
1045 | sprintf(tmpPath, "%s", tmpCurPath);
1046 |
1047 | installCnt = 0;
1048 | uninstallCnt = 0;
1049 |
1050 | goto getList;
1051 | }
1052 | else if (IsListFull () == true)
1053 | {
1054 | WaitPrompt ("Maximum number of directory levels is reached.\n");
1055 | }
1056 | else
1057 | {
1058 | tmpCurPath = PeekCurrentDir ();
1059 | if (tmpCurPath != NULL)
1060 | {
1061 | if(gDirLevel>1)
1062 | sprintf(tmpPath, "%s/%s", tmpCurPath, tmpFile->filename);
1063 | else
1064 | sprintf(tmpPath, "%s%s", tmpCurPath, tmpFile->filename);
1065 | }
1066 | // wiiNinja: Need to PopCurrentDir
1067 | PushCurrentDir (tmpPath, selected, start);
1068 | selected = 0;
1069 | start = 0;
1070 |
1071 | installCnt = 0;
1072 | uninstallCnt = 0;
1073 |
1074 | goto getList;
1075 | }
1076 | }
1077 | else
1078 | {
1079 | //If at least one WAD is marked, goto batch screen - Leathl
1080 | if ((installCnt > 0) | (uninstallCnt > 0)) {
1081 | char *thisCurPath = PeekCurrentDir ();
1082 | if (thisCurPath != NULL) {
1083 | int res = Menu_BatchProcessWads(fileList, fileCnt, thisCurPath, installCnt, uninstallCnt);
1084 |
1085 | if (res == 1) {
1086 | int counter;
1087 | for (counter = 0; counter < fileCnt; counter++) {
1088 | fatFile *temp = &fileList[counter];
1089 | temp->install = 0;
1090 | }
1091 |
1092 | installCnt = 0;
1093 | uninstallCnt = 0;
1094 | }
1095 | }
1096 | }
1097 | //else use standard wadmanage menu - Leathl
1098 | else {
1099 | tmpCurPath = PeekCurrentDir ();
1100 | if (tmpCurPath != NULL)
1101 | Menu_WadManage(tmpFile, tmpCurPath);
1102 | }
1103 | }
1104 | }
1105 |
1106 | /* B button */
1107 | if (buttons & WPAD_BUTTON_B)
1108 | {
1109 | if(gDirLevel<=1)
1110 | {
1111 | return;
1112 | }
1113 |
1114 | char *tmpCurPath;
1115 | selected = 0;
1116 | start = 0;
1117 | // Previous dir
1118 | tmpCurPath = PopCurrentDir(&selected, &start);
1119 | if (tmpCurPath != NULL)
1120 | sprintf(tmpPath, "%s", tmpCurPath);
1121 | goto getList;
1122 | //return;
1123 | }
1124 |
1125 | /** Scrolling **/
1126 | /* List scrolling */
1127 | index = (selected - start);
1128 |
1129 | if (index >= ENTRIES_PER_PAGE)
1130 | start += index - (ENTRIES_PER_PAGE - 1);
1131 | if (index <= -1)
1132 | start += index;
1133 | }
1134 |
1135 | err:
1136 | printf("\n");
1137 | printf(" Press any button to continue...\n");
1138 |
1139 | free (tmpPath);
1140 |
1141 | /* Wait for button */
1142 | WaitButtons();
1143 | }
1144 |
1145 |
1146 | void Menu_Loop(void)
1147 | {
1148 | u8 iosVersion;
1149 | if(AHBPROT_DISABLED)
1150 | IOSPATCH_Apply();
1151 | else
1152 | {
1153 | /* Select IOS menu */
1154 | Menu_SelectIOS();
1155 | }
1156 |
1157 | /* Retrieve IOS version */
1158 | iosVersion = IOS_GetVersion();
1159 |
1160 | ndev = &ndevList[0];
1161 |
1162 | /* NAND device menu */
1163 | if ((iosVersion == CIOS_VERSION || iosVersion == 250) && IOS_GetRevision() >13)
1164 | {
1165 | Menu_NandDevice();
1166 | }
1167 | for (;;) {
1168 | /* FAT device menu */
1169 | Menu_FatDevice();
1170 |
1171 | /* WAD list menu */
1172 | Menu_WadList();
1173 | }
1174 | }
1175 |
1176 | // Start of wiiNinja's added routines
1177 |
1178 | int PushCurrentDir (char *dirStr, int Selected, int Start)
1179 | {
1180 | int retval = 0;
1181 |
1182 | // Store dirStr into the list and increment the gDirLevel
1183 | // WARNING: Make sure dirStr is no larger than MAX_FILE_PATH_LEN
1184 | if (gDirLevel < MAX_DIR_LEVELS)
1185 | {
1186 | strcpy (gDirList [gDirLevel], dirStr);
1187 | gSeleted[gDirLevel]=Selected;
1188 | gStart[gDirLevel]=Start;
1189 | gDirLevel++;
1190 | //if (gDirLevel >= MAX_DIR_LEVELS)
1191 | // gDirLevel = 0;
1192 | }
1193 | else
1194 | retval = -1;
1195 |
1196 | return (retval);
1197 | }
1198 |
1199 | char *PopCurrentDir(int *Selected, int *Start)
1200 | {
1201 | if (gDirLevel > 1)
1202 | gDirLevel--;
1203 | else {
1204 | gDirLevel = 0;
1205 | }
1206 | *Selected = gSeleted[gDirLevel];
1207 | *Start = gStart[gDirLevel];
1208 | return PeekCurrentDir();
1209 | }
1210 |
1211 | bool IsListFull (void)
1212 | {
1213 | if (gDirLevel < MAX_DIR_LEVELS)
1214 | return (false);
1215 | else
1216 | return (true);
1217 | }
1218 |
1219 | char *PeekCurrentDir (void)
1220 | {
1221 | // Return the current path
1222 | if (gDirLevel > 0)
1223 | return (gDirList [gDirLevel-1]);
1224 | else
1225 | return (NULL);
1226 | }
1227 |
1228 | void WaitPrompt (char *prompt)
1229 | {
1230 | printf("\n%s", prompt);
1231 | printf(" Press any button to continue...\n");
1232 |
1233 | /* Wait for button */
1234 | WaitButtons();
1235 | }
1236 |
1237 | u32 Pad_GetButtons(void)
1238 | {
1239 | u32 buttons = 0, cnt;
1240 |
1241 | /* Scan pads */
1242 | PAD_ScanPads();
1243 |
1244 | /* Get pressed buttons */
1245 | //for (cnt = 0; cnt < MAX_WIIMOTES; cnt++)
1246 | for (cnt = 0; cnt < 4; cnt++)
1247 | buttons |= PAD_ButtonsDown(cnt);
1248 |
1249 | return buttons;
1250 | }
1251 |
1252 | u32 WiiDRC_GetButtons(void)
1253 | {
1254 | if(!WiiDRC_Inited() || !WiiDRC_Connected())
1255 | return 0;
1256 |
1257 | /* Scan pads */
1258 | WiiDRC_ScanPads();
1259 |
1260 | /* Get pressed buttons */
1261 | return WiiDRC_ButtonsDown();
1262 | }
1263 |
1264 | // Routine to wait for a button from either the Wiimote or a gamecube
1265 | // controller. The return value will mimic the WPAD buttons to minimize
1266 | // the amount of changes to the original code, that is expecting only
1267 | // Wiimote button presses. Note that the "HOME" button on the Wiimote
1268 | // is mapped to the "SELECT" button on the Gamecube Ctrl. (wiiNinja 5/15/2009)
1269 | u32 WaitButtons(void)
1270 | {
1271 | u32 buttons = 0;
1272 | u32 buttonsGC = 0;
1273 | u32 buttonsDRC = 0;
1274 |
1275 | /* Wait for button pressing */
1276 | while (!buttons && !buttonsGC && !buttonsDRC)
1277 | {
1278 | // Wii buttons
1279 | buttons = Wpad_GetButtons();
1280 |
1281 | // GC buttons
1282 | buttonsGC = Pad_GetButtons();
1283 |
1284 | // DRC buttons
1285 | buttonsDRC = WiiDRC_GetButtons();
1286 |
1287 | VIDEO_WaitVSync();
1288 | }
1289 |
1290 | if(buttons & WPAD_CLASSIC_BUTTON_A)
1291 | buttons |= WPAD_BUTTON_A;
1292 | else if(buttons & WPAD_CLASSIC_BUTTON_B)
1293 | buttons |= WPAD_BUTTON_B;
1294 | else if(buttons & WPAD_CLASSIC_BUTTON_LEFT)
1295 | buttons |= WPAD_BUTTON_LEFT;
1296 | else if(buttons & WPAD_CLASSIC_BUTTON_RIGHT)
1297 | buttons |= WPAD_BUTTON_RIGHT;
1298 | else if(buttons & WPAD_CLASSIC_BUTTON_DOWN)
1299 | buttons |= WPAD_BUTTON_DOWN;
1300 | else if(buttons & WPAD_CLASSIC_BUTTON_UP)
1301 | buttons |= WPAD_BUTTON_UP;
1302 | else if(buttons & WPAD_CLASSIC_BUTTON_HOME)
1303 | buttons |= WPAD_BUTTON_HOME;
1304 | else if(buttons & (WPAD_CLASSIC_BUTTON_X | WPAD_CLASSIC_BUTTON_PLUS))
1305 | buttons |= WPAD_BUTTON_PLUS;
1306 | else if(buttons & (WPAD_CLASSIC_BUTTON_Y | WPAD_CLASSIC_BUTTON_MINUS))
1307 | buttons |= WPAD_BUTTON_MINUS;
1308 | else if(buttons & WPAD_CLASSIC_BUTTON_ZR)
1309 | buttons |= WPAD_BUTTON_1;
1310 |
1311 | if (buttonsGC)
1312 | {
1313 | if(buttonsGC & PAD_BUTTON_A)
1314 | buttons |= WPAD_BUTTON_A;
1315 | else if(buttonsGC & PAD_BUTTON_B)
1316 | buttons |= WPAD_BUTTON_B;
1317 | else if(buttonsGC & PAD_BUTTON_LEFT)
1318 | buttons |= WPAD_BUTTON_LEFT;
1319 | else if(buttonsGC & PAD_BUTTON_RIGHT)
1320 | buttons |= WPAD_BUTTON_RIGHT;
1321 | else if(buttonsGC & PAD_BUTTON_DOWN)
1322 | buttons |= WPAD_BUTTON_DOWN;
1323 | else if(buttonsGC & PAD_BUTTON_UP)
1324 | buttons |= WPAD_BUTTON_UP;
1325 | else if(buttonsGC & PAD_BUTTON_START)
1326 | buttons |= WPAD_BUTTON_HOME;
1327 | else if(buttonsGC & PAD_BUTTON_X)
1328 | buttons |= WPAD_BUTTON_PLUS;
1329 | else if(buttonsGC & PAD_BUTTON_Y)
1330 | buttons |= WPAD_BUTTON_MINUS;
1331 | else if(buttonsGC & PAD_TRIGGER_Z)
1332 | buttons |= WPAD_BUTTON_1;
1333 | }
1334 |
1335 | if (buttonsDRC)
1336 | {
1337 | if(buttonsDRC & WIIDRC_BUTTON_A)
1338 | buttons |= WPAD_BUTTON_A;
1339 | else if(buttonsDRC & WIIDRC_BUTTON_B)
1340 | buttons |= WPAD_BUTTON_B;
1341 | else if(buttonsDRC & WIIDRC_BUTTON_LEFT)
1342 | buttons |= WPAD_BUTTON_LEFT;
1343 | else if(buttonsDRC & WIIDRC_BUTTON_RIGHT)
1344 | buttons |= WPAD_BUTTON_RIGHT;
1345 | else if(buttonsDRC & WIIDRC_BUTTON_DOWN)
1346 | buttons |= WPAD_BUTTON_DOWN;
1347 | else if(buttonsDRC & WIIDRC_BUTTON_UP)
1348 | buttons |= WPAD_BUTTON_UP;
1349 | else if(buttonsDRC & WIIDRC_BUTTON_HOME)
1350 | buttons |= WPAD_BUTTON_HOME;
1351 | else if(buttonsDRC & (WIIDRC_BUTTON_X | WIIDRC_BUTTON_PLUS))
1352 | buttons |= WPAD_BUTTON_PLUS;
1353 | else if(buttonsDRC & (WIIDRC_BUTTON_Y | WIIDRC_BUTTON_MINUS))
1354 | buttons |= WPAD_BUTTON_MINUS;
1355 | else if(buttonsDRC & WIIDRC_BUTTON_ZR)
1356 | buttons |= WPAD_BUTTON_1;
1357 | }
1358 |
1359 | return buttons;
1360 | } // WaitButtons
1361 |
1362 |
1363 | void WiiLightControl (int state)
1364 | {
1365 | switch (state)
1366 | {
1367 | case WII_LIGHT_ON:
1368 | /* Turn on Wii Light */
1369 | WIILIGHT_SetLevel(255);
1370 | WIILIGHT_TurnOn();
1371 | break;
1372 |
1373 | case WII_LIGHT_OFF:
1374 | default:
1375 | /* Turn off Wii Light */
1376 | WIILIGHT_SetLevel(0);
1377 | WIILIGHT_TurnOn();
1378 | WIILIGHT_Toggle();
1379 | break;
1380 | }
1381 | } // WiiLightControl
1382 |
1383 |
--------------------------------------------------------------------------------
/source/menu.h:
--------------------------------------------------------------------------------
1 | #ifndef _MENU_H_
2 | #define _MENU_H_
3 |
4 | /* Prototypes */
5 | void Menu_Loop(void);
6 |
7 | #endif
8 |
9 |
--------------------------------------------------------------------------------
/source/mload.c:
--------------------------------------------------------------------------------
1 | /* mload.c (for PPC) (c) 2009, Hermes
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 | */
17 |
18 | #include "mload.h"
19 |
20 | static const char mload_fs[] ATTRIBUTE_ALIGN(32) = "/dev/mload";
21 |
22 | static s32 mload_fd = -1;
23 |
24 | /*--------------------------------------------------------------------------------------------------------------*/
25 |
26 | // to init/test if the device is running
27 |
28 | int mload_init()
29 | {
30 | int n;
31 |
32 | if(mload_fd>=0) return 0;
33 |
34 | for(n=0;n<10;n++) // try 2.5 seconds
35 | {
36 | mload_fd=IOS_Open(mload_fs, 0);
37 |
38 | if(mload_fd>=0) break;
39 |
40 | usleep(250*1000);
41 | }
42 |
43 | return mload_fd;
44 | }
45 |
46 | /*--------------------------------------------------------------------------------------------------------------*/
47 |
48 | // to close the device (remember call it when rebooting the IOS!)
49 |
50 | int mload_close()
51 | {
52 | int ret;
53 |
54 | if(mload_fd<0) return -1;
55 |
56 | ret=IOS_Close(mload_fd);
57 |
58 | mload_fd=-1;
59 |
60 | return ret;
61 | }
62 |
63 | /*--------------------------------------------------------------------------------------------------------------*/
64 |
65 | // to get the thread id of mload
66 |
67 | int mload_get_thread_id()
68 | {
69 | int ret;
70 | s32 hid = -1;
71 |
72 |
73 | if(mload_init()<0) return -1;
74 |
75 | hid = iosCreateHeap(0x800);
76 |
77 | if(hid<0) return hid;
78 |
79 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_MLOAD_THREAD_ID, ":");
80 |
81 |
82 | return ret;
83 |
84 | }
85 |
86 | /*--------------------------------------------------------------------------------------------------------------*/
87 |
88 | // get the base and the size of the memory readable/writable to load modules
89 |
90 | int mload_get_load_base(u32 *starlet_base, int *size)
91 | {
92 | int ret;
93 | s32 hid = -1;
94 |
95 |
96 | if(mload_init()<0) return -1;
97 |
98 | hid = iosCreateHeap(0x800);
99 |
100 | if(hid<0) return hid;
101 |
102 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_LOAD_BASE, ":ii",starlet_base, size);
103 |
104 |
105 | return ret;
106 |
107 | }
108 |
109 | /*--------------------------------------------------------------------------------------------------------------*/
110 |
111 | // load and run a module from starlet (it need to allocate MEM2 to send the elf file)
112 | // the module must be a elf made with stripios
113 |
114 | int mload_module(void *addr, int len)
115 | {
116 | int ret;
117 | void *buf=NULL;
118 | s32 hid = -1;
119 |
120 | if(mload_init()<0) return -1;
121 |
122 | hid = iosCreateHeap(len+0x800);
123 |
124 | if(hid<0) return hid;
125 |
126 | buf= iosAlloc(hid, len);
127 |
128 | if(!buf) {ret= -1;goto out;}
129 |
130 |
131 | memcpy(buf, addr,len);
132 |
133 | ret = IOS_IoctlvFormat(hid, mload_fd, MLOAD_LOAD_MODULE, ":d", buf, len);
134 |
135 | if(ret<0) goto out;
136 |
137 | ret=IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_MODULE, ":");
138 |
139 | if(ret<0) {ret= -666;goto out;}
140 |
141 | out:
142 |
143 | return ret;
144 |
145 | }
146 |
147 | /*--------------------------------------------------------------------------------------------------------------*/
148 |
149 | // load a module from the PPC
150 | // the module must be a elf made with stripios
151 |
152 | int mload_elf(void *my_elf, data_elf *data_elf)
153 | {
154 | int n,m;
155 | int p;
156 | u8 *adr;
157 | u32 elf=(u32) my_elf;
158 |
159 | if(elf & 3) return -1; // aligned to 4 please!
160 |
161 | elfheader *head=(void *) elf;
162 | elfphentry *entries;
163 |
164 | if(head->ident0!=0x7F454C46) return -1;
165 | if(head->ident1!=0x01020161) return -1;
166 | if(head->ident2!=0x01000000) return -1;
167 |
168 | p=head->phoff;
169 |
170 | data_elf->start=(void *) head->entry;
171 |
172 | for(n=0; nphnum; n++)
173 | {
174 | entries=(void *) (elf+p);
175 | p+=sizeof(elfphentry);
176 |
177 | if(entries->type == 4)
178 | {
179 | adr=(void *) (elf + entries->offset);
180 |
181 | if(getbe32(0)!=0) return -2; // bad info (sure)
182 |
183 | for(m=4; m < entries->memsz; m+=8)
184 | {
185 | switch(getbe32(m))
186 | {
187 | case 0x9:
188 | data_elf->start= (void *) getbe32(m+4);
189 | break;
190 | case 0x7D:
191 | data_elf->prio= getbe32(m+4);
192 | break;
193 | case 0x7E:
194 | data_elf->size_stack= getbe32(m+4);
195 | break;
196 | case 0x7F:
197 | data_elf->stack= (void *) (getbe32(m+4));
198 | break;
199 |
200 | }
201 |
202 | }
203 |
204 | }
205 | else
206 | if(entries->type == 1 && entries->memsz != 0 && entries->vaddr!=0)
207 | {
208 |
209 | if(mload_memset((void *) entries->vaddr, 0, entries->memsz)<0) return -1;
210 | if(mload_seek(entries->vaddr, SEEK_SET)<0) return -1;
211 | if(mload_write((void *) (elf + entries->offset), entries->filesz)<0) return -1;
212 |
213 | }
214 | }
215 |
216 | return 0;
217 | }
218 |
219 | /*--------------------------------------------------------------------------------------------------------------*/
220 |
221 | // run one thread (you can use to load modules or binary files)
222 |
223 | int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority)
224 | {
225 | int ret;
226 | s32 hid = -1;
227 |
228 |
229 | if(mload_init()<0) return -1;
230 |
231 | hid = iosCreateHeap(0x800);
232 |
233 | if(hid<0) return hid;
234 |
235 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_RUN_THREAD, "iiii:", starlet_addr,starlet_top_stack, stack_size, priority);
236 |
237 |
238 | return ret;
239 | }
240 |
241 | /*--------------------------------------------------------------------------------------------------------------*/
242 |
243 | // stops one starlet thread
244 |
245 | int mload_stop_thread(int id)
246 | {
247 | int ret;
248 | s32 hid = -1;
249 |
250 |
251 | if(mload_init()<0) return -1;
252 |
253 | hid = iosCreateHeap(0x800);
254 |
255 | if(hid<0) return hid;
256 |
257 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_STOP_THREAD, "i:", id);
258 |
259 |
260 | return ret;
261 |
262 | }
263 |
264 | /*--------------------------------------------------------------------------------------------------------------*/
265 |
266 | // continue one stopped starlet thread
267 |
268 | int mload_continue_thread(int id)
269 | {
270 | int ret;
271 | s32 hid = -1;
272 |
273 |
274 | if(mload_init()<0) return -1;
275 |
276 | hid = iosCreateHeap(0x800);
277 |
278 | if(hid<0) return hid;
279 |
280 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_CONTINUE_THREAD, "i:", id);
281 |
282 |
283 | return ret;
284 |
285 | }
286 | /*--------------------------------------------------------------------------------------------------------------*/
287 |
288 | // fix starlet address to read/write (uses SEEK_SET, etc as mode)
289 |
290 | int mload_seek(int offset, int mode)
291 | {
292 | if(mload_init()<0) return -1;
293 | return IOS_Seek(mload_fd, offset, mode);
294 | }
295 |
296 | /*--------------------------------------------------------------------------------------------------------------*/
297 |
298 | // read bytes from starlet (it update the offset)
299 |
300 | int mload_read(void* buf, u32 size)
301 | {
302 | if(mload_init()<0) return -1;
303 | return IOS_Read(mload_fd, buf, size);
304 | }
305 |
306 | /*--------------------------------------------------------------------------------------------------------------*/
307 |
308 | // write bytes from starlet (it update the offset)
309 |
310 | int mload_write(const void * buf, u32 size)
311 | {
312 | if(mload_init()<0) return -1;
313 | return IOS_Write(mload_fd, buf, size);
314 | }
315 |
316 | /*--------------------------------------------------------------------------------------------------------------*/
317 |
318 | // fill a block (similar to memset)
319 |
320 | int mload_memset(void *starlet_addr, int set, int len)
321 | {
322 | int ret;
323 | s32 hid = -1;
324 |
325 |
326 | if(mload_init()<0) return -1;
327 |
328 | hid = iosCreateHeap(0x800);
329 |
330 | if(hid<0) return hid;
331 |
332 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_MEMSET, "iii:", starlet_addr, set, len);
333 |
334 |
335 | return ret;
336 | }
337 |
338 | /*--------------------------------------------------------------------------------------------------------------*/
339 |
340 | // get the ehci datas ( ehcmodule.elf uses this address)
341 |
342 | void * mload_get_ehci_data()
343 | {
344 | int ret;
345 | s32 hid = -1;
346 |
347 |
348 | if(mload_init()<0) return NULL;
349 |
350 | hid = iosCreateHeap(0x800);
351 |
352 | if(hid<0) return NULL;
353 |
354 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_GET_EHCI_DATA, ":");
355 | if(ret<0) return NULL;
356 |
357 | return (void *) ret;
358 | }
359 |
360 | /*--------------------------------------------------------------------------------------------------------------*/
361 |
362 | // set the dev/es ioctlv in routine
363 |
364 | int mload_set_ES_ioctlv_vector(void *starlet_addr)
365 | {
366 | int ret;
367 | s32 hid = -1;
368 |
369 |
370 | if(mload_init()<0) return -1;
371 |
372 | hid = iosCreateHeap(0x800);
373 |
374 | if(hid<0) return hid;
375 |
376 | ret= IOS_IoctlvFormat(hid, mload_fd, MLOAD_SET_ES_IOCTLV, "i:", starlet_addr);
377 |
378 |
379 | return ret;
380 | }
381 |
382 |
--------------------------------------------------------------------------------
/source/mload.h:
--------------------------------------------------------------------------------
1 | /* mload.c (for PPC) (c) 2009, Hermes
2 |
3 | This program is free software; you can redistribute it and/or modify
4 | it under the terms of the GNU General Public License as published by
5 | the Free Software Foundation; either version 2 of the License, or
6 | (at your option) any later version.
7 |
8 | This program is distributed in the hope that it will be useful,
9 | but WITHOUT ANY WARRANTY; without even the implied warranty of
10 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 | GNU General Public License for more details.
12 |
13 | You should have received a copy of the GNU General Public License
14 | along with this program; if not, write to the Free Software
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 | */
17 |
18 | #ifndef __MLOAD_H__
19 | #define __MLOAD_H__
20 |
21 |
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include "unistd.h"
28 |
29 | #define MLOAD_MLOAD_THREAD_ID 0x4D4C4400
30 | #define MLOAD_LOAD_MODULE 0x4D4C4480
31 | #define MLOAD_RUN_MODULE 0x4D4C4481
32 | #define MLOAD_RUN_THREAD 0x4D4C4482
33 |
34 | #define MLOAD_STOP_THREAD 0x4D4C4484
35 | #define MLOAD_CONTINUE_THREAD 0x4D4C4485
36 |
37 | #define MLOAD_GET_LOAD_BASE 0x4D4C4490
38 | #define MLOAD_MEMSET 0x4D4C4491
39 |
40 | #define MLOAD_GET_EHCI_DATA 0x4D4C44A0
41 |
42 | #define MLOAD_SET_ES_IOCTLV 0x4D4C44B0
43 |
44 | #ifdef __cplusplus
45 | extern "C" {
46 | #endif
47 |
48 |
49 | // from IOS ELF stripper of neimod
50 |
51 | #define getbe32(x) ((adr[x]<<24) | (adr[x+1]<<16) | (adr[x+2]<<8) | (adr[x+3]))
52 |
53 | typedef struct
54 | {
55 | u32 ident0;
56 | u32 ident1;
57 | u32 ident2;
58 | u32 ident3;
59 | u32 machinetype;
60 | u32 version;
61 | u32 entry;
62 | u32 phoff;
63 | u32 shoff;
64 | u32 flags;
65 | u16 ehsize;
66 | u16 phentsize;
67 | u16 phnum;
68 | u16 shentsize;
69 | u16 shnum;
70 | u16 shtrndx;
71 | } elfheader;
72 |
73 | typedef struct
74 | {
75 | u32 type;
76 | u32 offset;
77 | u32 vaddr;
78 | u32 paddr;
79 | u32 filesz;
80 | u32 memsz;
81 | u32 flags;
82 | u32 align;
83 | } elfphentry;
84 |
85 | typedef struct
86 | {
87 | void *start;
88 | int prio;
89 | void *stack;
90 | int size_stack;
91 | } data_elf;
92 |
93 | /*--------------------------------------------------------------------------------------------------------------*/
94 |
95 | // to init/test if the device is running
96 |
97 | int mload_init();
98 |
99 | /*--------------------------------------------------------------------------------------------------------------*/
100 |
101 | // to close the device (remember call it when rebooting the IOS!)
102 |
103 | int mload_close();
104 |
105 | /*--------------------------------------------------------------------------------------------------------------*/
106 |
107 | // to get the thread id of mload
108 |
109 | int mload_get_thread_id();
110 |
111 | /*--------------------------------------------------------------------------------------------------------------*/
112 |
113 | // get the base and the size of the memory readable/writable to load modules
114 |
115 | int mload_get_load_base(u32 *starlet_base, int *size);
116 |
117 | /*--------------------------------------------------------------------------------------------------------------*/
118 |
119 | // load and run a module from starlet (it need to allocate MEM2 to send the elf file)
120 | // the module must be a elf made with stripios
121 |
122 | int mload_module(void *addr, int len);
123 |
124 | /*--------------------------------------------------------------------------------------------------------------*/
125 |
126 | // load a module from the PPC
127 | // the module must be a elf made with stripios
128 |
129 | int mload_elf(void *my_elf, data_elf *data_elf);
130 |
131 | /*--------------------------------------------------------------------------------------------------------------*/
132 |
133 | // run one thread (you can use to load modules or binary files)
134 |
135 | int mload_run_thread(void *starlet_addr, void *starlet_top_stack, int stack_size, int priority);
136 |
137 | /*--------------------------------------------------------------------------------------------------------------*/
138 |
139 | // stops one starlet thread
140 |
141 | int mload_stop_thread(int id);
142 |
143 | /*--------------------------------------------------------------------------------------------------------------*/
144 |
145 | // continue one stopped starlet thread
146 |
147 | int mload_continue_thread(int id);
148 |
149 | /*--------------------------------------------------------------------------------------------------------------*/
150 |
151 | // fix starlet address to read/write (uses SEEK_SET, etc as mode)
152 |
153 | int mload_seek(int offset, int mode);
154 |
155 | /*--------------------------------------------------------------------------------------------------------------*/
156 |
157 | // read bytes from starlet (it update the offset)
158 |
159 | int mload_read(void* buf, u32 size);
160 |
161 | /*--------------------------------------------------------------------------------------------------------------*/
162 |
163 | // write bytes from starlet (it update the offset)
164 |
165 | int mload_write(const void * buf, u32 size);
166 |
167 | /*--------------------------------------------------------------------------------------------------------------*/
168 |
169 | // fill a block (similar to memset)
170 |
171 | int mload_memset(void *starlet_addr, int set, int len);
172 |
173 | /*--------------------------------------------------------------------------------------------------------------*/
174 |
175 | // get the ehci datas ( ehcmodule.elf uses this address)
176 |
177 | void * mload_get_ehci_data();
178 |
179 | /*--------------------------------------------------------------------------------------------------------------*/
180 |
181 | // set the dev/es ioctlv in routine
182 |
183 | int mload_set_ES_ioctlv_vector(void *starlet_addr);
184 |
185 | /*--------------------------------------------------------------------------------------------------------------*/
186 |
187 |
188 |
189 | #ifdef __cplusplus
190 | }
191 | #endif
192 |
193 |
194 | #endif
195 |
--------------------------------------------------------------------------------
/source/nand.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "nand.h"
5 |
6 | /* Buffer */
7 | static u32 inbuf[8] ATTRIBUTE_ALIGN(32);
8 |
9 |
10 | s32 Nand_Mount(nandDevice *dev)
11 | {
12 | s32 fd, ret;
13 |
14 | /* Open FAT module */
15 | fd = IOS_Open("fat", 0);
16 | if (fd < 0)
17 | return fd;
18 |
19 | /* Mount device */
20 | ret = IOS_Ioctlv(fd, dev->mountCmd, 0, 0, NULL);
21 |
22 | /* Close FAT module */
23 | IOS_Close(fd);
24 |
25 | return ret;
26 | }
27 |
28 | s32 Nand_Unmount(nandDevice *dev)
29 | {
30 | s32 fd, ret;
31 |
32 | /* Open FAT module */
33 | fd = IOS_Open("fat", 0);
34 | if (fd < 0)
35 | return fd;
36 |
37 | /* Unmount device */
38 | ret = IOS_Ioctlv(fd, dev->umountCmd, 0, 0, NULL);
39 |
40 | /* Close FAT module */
41 | IOS_Close(fd);
42 |
43 | return ret;
44 | }
45 |
46 | s32 Nand_Enable(nandDevice *dev)
47 | {
48 | s32 fd, ret;
49 |
50 | /* Open /dev/fs */
51 | fd = IOS_Open("/dev/fs", 0);
52 | if (fd < 0)
53 | return fd;
54 |
55 | /* Set input buffer */
56 | inbuf[0] = dev->mode;
57 |
58 | /* Enable NAND emulator */
59 | ret = IOS_Ioctl(fd, 100, inbuf, sizeof(inbuf), NULL, 0);
60 |
61 | /* Close /dev/fs */
62 | IOS_Close(fd);
63 |
64 | return ret;
65 | }
66 |
67 | s32 Nand_Disable(void)
68 | {
69 | s32 fd, ret;
70 |
71 | /* Open /dev/fs */
72 | fd = IOS_Open("/dev/fs", 0);
73 | if (fd < 0)
74 | return fd;
75 |
76 | /* Set input buffer */
77 | inbuf[0] = 0;
78 |
79 | /* Disable NAND emulator */
80 | ret = IOS_Ioctl(fd, 100, inbuf, sizeof(inbuf), NULL, 0);
81 |
82 | /* Close /dev/fs */
83 | IOS_Close(fd);
84 |
85 | return ret;
86 | }
87 |
--------------------------------------------------------------------------------
/source/nand.h:
--------------------------------------------------------------------------------
1 | #ifndef _NAND_H_
2 | #define _NAND_H_
3 |
4 | /* 'NAND Device' structure */
5 | typedef struct {
6 | /* Device name */
7 | char *name;
8 |
9 | /* Mode value */
10 | u32 mode;
11 |
12 | /* Un/mount command */
13 | u32 mountCmd;
14 | u32 umountCmd;
15 | } nandDevice;
16 |
17 |
18 | /* Prototypes */
19 | s32 Nand_Mount(nandDevice *);
20 | s32 Nand_Unmount(nandDevice *);
21 | s32 Nand_Enable(nandDevice *);
22 | s32 Nand_Disable(void);
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/source/restart.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "nand.h"
5 | #include "sys.h"
6 | #include "wpad.h"
7 | #include "video.h"
8 |
9 |
10 | void Restart(void)
11 | {
12 | Con_Clear ();
13 | printf("\n Restarting Wii...");
14 | fflush(stdout);
15 |
16 | /* Disable NAND emulator */
17 | Nand_Disable();
18 |
19 | /* Load system menu */
20 | Sys_LoadMenu();
21 | }
22 |
23 | void Restart_Wait(void)
24 | {
25 | printf("\n");
26 |
27 | printf(" Press any button to restart...");
28 | fflush(stdout);
29 |
30 | /* Wait for button */
31 | Wpad_WaitButtons();
32 |
33 | /* Restart */
34 | Restart();
35 | }
36 |
37 |
--------------------------------------------------------------------------------
/source/restart.h:
--------------------------------------------------------------------------------
1 | #ifndef _RESTART_H_
2 | #define _RESTART_H_
3 |
4 | /* Prototypes */
5 | void Restart(void);
6 | void Restart_Wait(void);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/source/sha1.c:
--------------------------------------------------------------------------------
1 | /*
2 | SHA-1 in C
3 | By Steve Reid
4 | 100% Public Domain
5 |
6 | Test Vectors (from FIPS PUB 180-1)
7 | "abc"
8 | A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
9 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
10 | 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
11 | A million repetitions of "a"
12 | 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
13 | */
14 |
15 | /* #define LITTLE_ENDIAN * This should be #define'd if true. */
16 | #define SHA1HANDSOFF
17 |
18 | #include
19 | #include
20 | #include "sha1.h"
21 |
22 | #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
23 |
24 | /* blk0() and blk() perform the initial expand. */
25 | /* I got the idea of expanding during the round function from SSLeay */
26 | #ifdef LITTLE_ENDIAN
27 | #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
28 | |(rol(block->l[i],8)&0x00FF00FF))
29 | #else
30 | #define blk0(i) block->l[i]
31 | #endif
32 | #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
33 | ^block->l[(i+2)&15]^block->l[i&15],1))
34 |
35 | /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
36 | #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
37 | #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
38 | #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
39 | #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
40 | #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
41 |
42 | typedef struct {
43 | unsigned long state[5];
44 | unsigned long count[2];
45 | unsigned char buffer[64];
46 | } SHA1_CTX;
47 |
48 |
49 | /* Hash a single 512-bit block. This is the core of the algorithm. */
50 |
51 | void SHA1Transform(unsigned long state[5], unsigned char buffer[64])
52 | {
53 | unsigned long a, b, c, d, e;
54 | typedef union {
55 | unsigned char c[64];
56 | unsigned long l[16];
57 | } CHAR64LONG16;
58 | CHAR64LONG16* block;
59 | #ifdef SHA1HANDSOFF
60 | static unsigned char workspace[64];
61 | block = (CHAR64LONG16*)workspace;
62 | memcpy(block, buffer, 64);
63 | #else
64 | block = (CHAR64LONG16*)buffer;
65 | #endif
66 | /* Copy context->state[] to working vars */
67 | a = state[0];
68 | b = state[1];
69 | c = state[2];
70 | d = state[3];
71 | e = state[4];
72 | /* 4 rounds of 20 operations each. Loop unrolled. */
73 | R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
74 | R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
75 | R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
76 | R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
77 | R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
78 | R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
79 | R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
80 | R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
81 | R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
82 | R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
83 | R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
84 | R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
85 | R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
86 | R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
87 | R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
88 | R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
89 | R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
90 | R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
91 | R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
92 | R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
93 | /* Add the working vars back into context.state[] */
94 | state[0] += a;
95 | state[1] += b;
96 | state[2] += c;
97 | state[3] += d;
98 | state[4] += e;
99 | /* Wipe variables */
100 | a = b = c = d = e = 0;
101 | }
102 |
103 |
104 | /* SHA1Init - Initialize new context */
105 |
106 | void SHA1Init(SHA1_CTX* context)
107 | {
108 | /* SHA1 initialization constants */
109 | context->state[0] = 0x67452301;
110 | context->state[1] = 0xEFCDAB89;
111 | context->state[2] = 0x98BADCFE;
112 | context->state[3] = 0x10325476;
113 | context->state[4] = 0xC3D2E1F0;
114 | context->count[0] = context->count[1] = 0;
115 | }
116 |
117 |
118 | /* Run your data through this. */
119 |
120 | void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
121 | {
122 | unsigned int i, j;
123 |
124 | j = (context->count[0] >> 3) & 63;
125 | if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
126 | context->count[1] += (len >> 29);
127 | if ((j + len) > 63) {
128 | memcpy(&context->buffer[j], data, (i = 64-j));
129 | SHA1Transform(context->state, context->buffer);
130 | for ( ; i + 63 < len; i += 64) {
131 | SHA1Transform(context->state, &data[i]);
132 | }
133 | j = 0;
134 | }
135 | else i = 0;
136 | memcpy(&context->buffer[j], &data[i], len - i);
137 | }
138 |
139 |
140 | /* Add padding and return the message digest. */
141 |
142 | void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
143 | {
144 | unsigned long i, j;
145 | unsigned char finalcount[8];
146 |
147 | for (i = 0; i < 8; i++) {
148 | finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
149 | >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
150 | }
151 | SHA1Update(context, (unsigned char *)"\200", 1);
152 | while ((context->count[0] & 504) != 448) {
153 | SHA1Update(context, (unsigned char *)"\0", 1);
154 | }
155 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
156 | for (i = 0; i < 20; i++) {
157 | digest[i] = (unsigned char)
158 | ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
159 | }
160 | /* Wipe variables */
161 | i = j = 0;
162 | memset(context->buffer, 0, 64);
163 | memset(context->state, 0, 20);
164 | memset(context->count, 0, 8);
165 | memset(&finalcount, 0, 8);
166 | #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
167 | SHA1Transform(context->state, context->buffer);
168 | #endif
169 | }
170 |
171 | void SHA1(unsigned char *ptr, unsigned int size, unsigned char *outbuf) {
172 | SHA1_CTX ctx;
173 |
174 | SHA1Init(&ctx);
175 | SHA1Update(&ctx, ptr, size);
176 | SHA1Final(outbuf, &ctx);
177 | }
178 |
--------------------------------------------------------------------------------
/source/sha1.h:
--------------------------------------------------------------------------------
1 | #ifndef _SHA1_H_
2 | #define _SHA1_H_
3 |
4 | void SHA1(unsigned char *, unsigned int, unsigned char *);
5 |
6 | #endif
7 |
--------------------------------------------------------------------------------
/source/stub.S:
--------------------------------------------------------------------------------
1 | .rodata
2 |
3 | .globl bgData
4 | .balign 32
5 | bgData:
6 | .incbin "../data/background"
7 |
--------------------------------------------------------------------------------
/source/sys.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "sys.h"
7 | #include "mload.h"
8 | #include "ehcmodule_elf.h"
9 |
10 | /* Constants */
11 | #define CERTS_LEN 0x280
12 |
13 | /* Variables */
14 | static const char certs_fs[] ATTRIBUTE_ALIGN(32) = "/sys/cert.sys";
15 |
16 | void __Sys_ResetCallback(void)
17 | {
18 | /* Reboot console */
19 | Sys_Reboot();
20 | }
21 |
22 | void __Sys_PowerCallback(void)
23 | {
24 | /* Poweroff console */
25 | Sys_Shutdown();
26 | }
27 |
28 | bool isIOSstub(u8 ios_number)
29 | {
30 | u32 tmd_size;
31 | tmd_view *ios_tmd;
32 |
33 |
34 | if((boot2version >= 5) && ( ios_number == 202 || ios_number == 222 || ios_number == 223 || ios_number == 224)) return true;
35 |
36 | ES_GetTMDViewSize(0x0000000100000000ULL | ios_number, &tmd_size);
37 | if (!tmd_size)
38 | {
39 | //getting size failed. invalid or fake tmd for sure!
40 | //gprintf("failed to get tmd for ios %d\n",ios_number);
41 | return true;
42 | }
43 | ios_tmd = (tmd_view *)memalign( 32, (tmd_size+31)&(~31) );
44 | if(!ios_tmd)
45 | {
46 | //gprintf("failed to mem align the TMD struct!\n");
47 | return true;
48 | }
49 | memset(ios_tmd , 0, tmd_size);
50 | ES_GetTMDView(0x0000000100000000ULL | ios_number, (u8*)ios_tmd , tmd_size);
51 | //gprintf("IOS %d is rev %d(0x%x) with tmd size of %u and %u contents\n",ios_number,ios_tmd->title_version,ios_tmd->title_version,tmd_size,ios_tmd->num_contents);
52 | /*Stubs have a few things in common:
53 | - title version : it is mostly 65280 , or even better : in hex the last 2 digits are 0.
54 | example : IOS 60 rev 6400 = 0x1900 = 00 = stub
55 | - exception for IOS21 which is active, the tmd size is 592 bytes (or 140 with the views)
56 | - the stub ios' have 1 app of their own (type 0x1) and 2 shared apps (type 0x8001).
57 | eventho the 00 check seems to work fine , we'll only use other knowledge as well cause some
58 | people/applications install an ios with a stub rev >_> ...*/
59 | u8 Version = ios_tmd->title_version;
60 |
61 | if((boot2version >= 5) && (ios_number == 249 || ios_number == 250) && (Version < 18)) return true;
62 | if(( ios_number == 202 || ios_number == 222 || ios_number == 223 || ios_number == 224) && (Version < 4)) return true;
63 | //version now contains the last 2 bytes. as said above, if this is 00, its a stub
64 | if ( Version == 0 )
65 | {
66 | if ( ( ios_tmd->num_contents == 3) && (ios_tmd->contents[0].type == 1 && ios_tmd->contents[1].type == 0x8001 && ios_tmd->contents[2].type == 0x8001) )
67 | {
68 | //gprintf("IOS %d is a stub\n",ios_number);
69 | free(ios_tmd);
70 | return true;
71 | }
72 | else
73 | {
74 | //gprintf("IOS %d is active\n",ios_number);
75 | free(ios_tmd);
76 | return false;
77 | }
78 | }
79 | //gprintf("IOS %d is active\n",ios_number);
80 | free(ios_tmd);
81 | return false;
82 | }
83 |
84 |
85 | bool loadIOS(int ios)
86 | {
87 | if(isIOSstub(ios)) return false;
88 | mload_close();
89 | if(IOS_ReloadIOS(ios)>=0)
90 | {
91 | if (IOS_GetVersion() != 249 && IOS_GetVersion() != 250)
92 | {
93 | if (mload_init() >= 0)
94 | {
95 | data_elf my_data_elf;
96 | mload_elf((void *) ehcmodule_elf, &my_data_elf);
97 | mload_run_thread(my_data_elf.start, my_data_elf.stack, my_data_elf.size_stack, 0x47);
98 | }
99 | }
100 | return true;
101 | }
102 | return false;
103 | }
104 |
105 | void Sys_Init(void)
106 | {
107 | /* Initialize video subsytem */
108 | VIDEO_Init();
109 |
110 | /* Set RESET/POWER button callback */
111 | SYS_SetResetCallback(__Sys_ResetCallback);
112 | SYS_SetPowerCallback(__Sys_PowerCallback);
113 | }
114 |
115 | void Sys_Reboot(void)
116 | {
117 | /* Restart console */
118 | STM_RebootSystem();
119 | }
120 |
121 | void Sys_Shutdown(void)
122 | {
123 | /* Poweroff console */
124 | if(CONF_GetShutdownMode() == CONF_SHUTDOWN_IDLE) {
125 | s32 ret;
126 |
127 | /* Set LED mode */
128 | ret = CONF_GetIdleLedMode();
129 | if(ret >= 0 && ret <= 2)
130 | STM_SetLedMode(ret);
131 |
132 | /* Shutdown to idle */
133 | STM_ShutdownToIdle();
134 | } else {
135 | /* Shutdown to standby */
136 | STM_ShutdownToStandby();
137 | }
138 | }
139 |
140 | void Sys_LoadMenu(void)
141 | {
142 | int HBC = 0;
143 | char * sig = (char *)0x80001804;
144 | if( sig[0] == 'S' &&
145 | sig[1] == 'T' &&
146 | sig[2] == 'U' &&
147 | sig[3] == 'B' &&
148 | sig[4] == 'H' &&
149 | sig[5] == 'A' &&
150 | sig[6] == 'X' &&
151 | sig[7] == 'X')
152 | {
153 | HBC=1; // Exit to HBC
154 | }
155 |
156 | /* Homebrew Channel stub */
157 | if (HBC == 1) {
158 | exit(0);
159 | }
160 | /* Return to the Wii system menu */
161 | SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
162 | }
163 |
164 | s32 Sys_GetCerts(signed_blob **certs, u32 *len)
165 | {
166 | static signed_blob certificates[CERTS_LEN] ATTRIBUTE_ALIGN(32);
167 |
168 | s32 fd, ret;
169 |
170 | /* Open certificates file */
171 | fd = IOS_Open(certs_fs, 1);
172 | if (fd < 0)
173 | return fd;
174 |
175 | /* Read certificates */
176 | ret = IOS_Read(fd, certificates, sizeof(certificates));
177 |
178 | /* Close file */
179 | IOS_Close(fd);
180 |
181 | /* Set values */
182 | if (ret > 0) {
183 | *certs = certificates;
184 | *len = sizeof(certificates);
185 | }
186 |
187 | return ret;
188 | }
189 |
--------------------------------------------------------------------------------
/source/sys.h:
--------------------------------------------------------------------------------
1 | #ifndef _SYS_H_
2 | #define _SYS_H_
3 |
4 | u32 boot2version;
5 | /* Prototypes */
6 | bool isIOSstub(u8 ios_number);
7 | bool loadIOS(int ios);
8 | void Sys_Init(void);
9 | void Sys_Reboot(void);
10 | void Sys_Shutdown(void);
11 | void Sys_LoadMenu(void);
12 | s32 Sys_GetCerts(signed_blob **, u32 *);
13 |
14 | #endif
15 |
--------------------------------------------------------------------------------
/source/title.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include "sha1.h"
9 | #include "utils.h"
10 |
11 |
12 | s32 Title_ZeroSignature(signed_blob *p_sig)
13 | {
14 | u8 *ptr = (u8 *)p_sig;
15 |
16 | /* Fill signature with zeroes */
17 | memset(ptr + 4, 0, SIGNATURE_SIZE(p_sig) - 4);
18 |
19 | return 0;
20 | }
21 |
22 | s32 Title_FakesignTik(signed_blob *p_tik)
23 | {
24 | tik *tik_data = NULL;
25 | u16 fill;
26 |
27 | /* Zero signature */
28 | Title_ZeroSignature(p_tik);
29 |
30 | /* Ticket data */
31 | tik_data = (tik *)SIGNATURE_PAYLOAD(p_tik);
32 |
33 | for (fill = 0; fill < USHRT_MAX; fill++) {
34 | sha1 hash;
35 |
36 | /* Modify ticket padding field */
37 | tik_data->padding = fill;
38 |
39 | /* Calculate hash */
40 | SHA1((u8 *)tik_data, sizeof(tik), hash);
41 |
42 | /* Found valid hash */
43 | if (!hash[0])
44 | return 0;
45 | }
46 |
47 | return -1;
48 | }
49 |
50 | s32 Title_FakesignTMD(signed_blob *p_tmd)
51 | {
52 | tmd *tmd_data = NULL;
53 | u16 fill;
54 |
55 | /* Zero signature */
56 | Title_ZeroSignature(p_tmd);
57 |
58 | /* TMD data */
59 | tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
60 |
61 | for (fill = 0; fill < USHRT_MAX; fill++) {
62 | sha1 hash;
63 |
64 | /* Modify TMD fill field */
65 | tmd_data->fill3 = fill;
66 |
67 | /* Calculate hash */
68 | SHA1((u8 *)tmd_data, TMD_SIZE(tmd_data), hash);
69 |
70 | /* Found valid hash */
71 | if (!hash[0])
72 | return 0;
73 | }
74 |
75 | return -1;
76 | }
77 |
78 | s32 Title_GetList(u64 **outbuf, u32 *outlen)
79 | {
80 | u64 *titles = NULL;
81 |
82 | u32 len, nb_titles;
83 | s32 ret;
84 |
85 | /* Get number of titles */
86 | ret = ES_GetNumTitles(&nb_titles);
87 | if (ret < 0)
88 | return ret;
89 |
90 | /* Calculate buffer lenght */
91 | len = round_up(sizeof(u64) * nb_titles, 32);
92 |
93 | /* Allocate memory */
94 | titles = memalign(32, len);
95 | if (!titles)
96 | return -1;
97 |
98 | /* Get titles */
99 | ret = ES_GetTitles(titles, nb_titles);
100 | if (ret < 0)
101 | goto err;
102 |
103 | /* Set values */
104 | *outbuf = titles;
105 | *outlen = nb_titles;
106 |
107 | return 0;
108 |
109 | err:
110 | /* Free memory */
111 | if (titles)
112 | free(titles);
113 |
114 | return ret;
115 | }
116 |
117 | s32 Title_GetTicketViews(u64 tid, tikview **outbuf, u32 *outlen)
118 | {
119 | tikview *views = NULL;
120 |
121 | u32 nb_views;
122 | s32 ret;
123 |
124 | /* Get number of ticket views */
125 | ret = ES_GetNumTicketViews(tid, &nb_views);
126 | if (ret < 0)
127 | return ret;
128 |
129 | /* Allocate memory */
130 | views = (tikview *)memalign(32, sizeof(tikview) * nb_views);
131 | if (!views)
132 | return -1;
133 |
134 | /* Get ticket views */
135 | ret = ES_GetTicketViews(tid, views, nb_views);
136 | if (ret < 0)
137 | goto err;
138 |
139 | /* Set values */
140 | *outbuf = views;
141 | *outlen = nb_views;
142 |
143 | return 0;
144 |
145 | err:
146 | /* Free memory */
147 | if (views)
148 | free(views);
149 |
150 | return ret;
151 | }
152 |
153 | s32 Title_GetTMD(u64 tid, signed_blob **outbuf, u32 *outlen)
154 | {
155 | void *p_tmd = NULL;
156 |
157 | u32 len;
158 | s32 ret;
159 |
160 | /* Get TMD size */
161 | ret = ES_GetStoredTMDSize(tid, &len);
162 | if (ret < 0)
163 | return ret;
164 |
165 | /* Allocate memory */
166 | p_tmd = memalign(32, round_up(len, 32));
167 | if (!p_tmd)
168 | return -1;
169 |
170 | /* Read TMD */
171 | ret = ES_GetStoredTMD(tid, p_tmd, len);
172 | if (ret < 0)
173 | goto err;
174 |
175 | /* Set values */
176 | *outbuf = p_tmd;
177 | *outlen = len;
178 |
179 | return 0;
180 |
181 | err:
182 | /* Free memory */
183 | if (p_tmd)
184 | free(p_tmd);
185 |
186 | return ret;
187 | }
188 |
189 | s32 Title_GetVersion(u64 tid, u16 *outbuf)
190 | {
191 | signed_blob *p_tmd = NULL;
192 | tmd *tmd_data = NULL;
193 |
194 | u32 len;
195 | s32 ret;
196 |
197 | /* Get title TMD */
198 | ret = Title_GetTMD(tid, &p_tmd, &len);
199 | if (ret < 0)
200 | return ret;
201 |
202 | /* Retrieve TMD info */
203 | tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
204 |
205 | /* Set values */
206 | *outbuf = tmd_data->title_version;
207 |
208 | /* Free memory */
209 | free(p_tmd);
210 |
211 | return 0;
212 | }
213 |
214 | s32 Title_GetSysVersion(u64 tid, u64 *outbuf)
215 | {
216 | signed_blob *p_tmd = NULL;
217 | tmd *tmd_data = NULL;
218 |
219 | u32 len;
220 | s32 ret;
221 |
222 | /* Get title TMD */
223 | ret = Title_GetTMD(tid, &p_tmd, &len);
224 | if (ret < 0)
225 | return ret;
226 |
227 | /* Retrieve TMD info */
228 | tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
229 |
230 | /* Set values */
231 | *outbuf = tmd_data->sys_version;
232 |
233 | /* Free memory */
234 | free(p_tmd);
235 |
236 | return 0;
237 | }
238 |
239 | s32 Title_GetSize(u64 tid, u32 *outbuf)
240 | {
241 | signed_blob *p_tmd = NULL;
242 | tmd *tmd_data = NULL;
243 |
244 | u32 cnt, len, size = 0;
245 | s32 ret;
246 |
247 | /* Get title TMD */
248 | ret = Title_GetTMD(tid, &p_tmd, &len);
249 | if (ret < 0)
250 | return ret;
251 |
252 | /* Retrieve TMD info */
253 | tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
254 |
255 | /* Calculate title size */
256 | for (cnt = 0; cnt < tmd_data->num_contents; cnt++) {
257 | tmd_content *content = &tmd_data->contents[cnt];
258 |
259 | /* Add content size */
260 | size += content->size;
261 | }
262 |
263 | /* Set values */
264 | *outbuf = size;
265 |
266 | /* Free memory */
267 | free(p_tmd);
268 |
269 | return 0;
270 | }
271 |
272 | s32 Title_GetIOSVersions(u8 **outbuf, u32 *outlen)
273 | {
274 | u8 *buffer = NULL;
275 | u64 *list = NULL;
276 |
277 | u32 count, cnt, idx;
278 | s32 ret;
279 |
280 | /* Get title list */
281 | ret = Title_GetList(&list, &count);
282 | if (ret < 0)
283 | return ret;
284 |
285 | /* Count IOS */
286 | for (cnt = idx = 0; idx < count; idx++) {
287 | u32 tidh = (list[idx] >> 32);
288 | u32 tidl = (list[idx] & 0xFFFFFFFF);
289 |
290 | /* Title is IOS */
291 | if ((tidh == 0x1) && (tidl >= 3) && (tidl <= 255))
292 | cnt++;
293 | }
294 |
295 | /* Allocate memory */
296 | buffer = (u8 *)memalign(32, cnt);
297 | if (!buffer) {
298 | ret = -1;
299 | goto out;
300 | }
301 |
302 | /* Copy IOS */
303 | for (cnt = idx = 0; idx < count; idx++) {
304 | u32 tidh = (list[idx] >> 32);
305 | u32 tidl = (list[idx] & 0xFFFFFFFF);
306 |
307 | /* Title is IOS */
308 | if ((tidh == 0x1) && (tidl >= 3) && (tidl <= 255))
309 | buffer[cnt++] = (u8)(tidl & 0xFF);
310 | }
311 |
312 | /* Set values */
313 | *outbuf = buffer;
314 | *outlen = cnt;
315 |
316 | goto out;
317 |
318 | out:
319 | /* Free memory */
320 | if (list)
321 | free(list);
322 |
323 | return ret;
324 | }
325 |
--------------------------------------------------------------------------------
/source/title.h:
--------------------------------------------------------------------------------
1 | #ifndef _TITLE_H_
2 | #define _TITLE_H_
3 |
4 | /* Constants */
5 | #define BLOCK_SIZE 1024
6 |
7 | /* Prototypes */
8 | s32 Title_ZeroSignature(signed_blob *);
9 | s32 Title_FakesignTik(signed_blob *);
10 | s32 Title_FakesignTMD(signed_blob *);
11 | s32 Title_GetList(u64 **, u32 *);
12 | s32 Title_GetTicketViews(u64, tikview **, u32 *);
13 | s32 Title_GetTMD(u64, signed_blob **, u32 *);
14 | s32 Title_GetVersion(u64, u16 *);
15 | s32 Title_GetSysVersion(u64, u64 *);
16 | s32 Title_GetSize(u64, u32 *);
17 | s32 Title_GetIOSVersions(u8 **, u32 *);
18 |
19 | #endif
20 |
--------------------------------------------------------------------------------
/source/usbstorage.c:
--------------------------------------------------------------------------------
1 | /*-------------------------------------------------------------
2 |
3 | usbstorage_starlet.c -- USB mass storage support, inside starlet
4 | Copyright (C) 2009 Kwiirk
5 |
6 | If this driver is linked before libogc, this will replace the original
7 | usbstorage driver by svpe from libogc
8 | This software is provided 'as-is', without any express or implied
9 | warranty. In no event will the authors be held liable for any
10 | damages arising from the use of this software.
11 |
12 | Permission is granted to anyone to use this software for any
13 | purpose, including commercial applications, and to alter it and
14 | redistribute it freely, subject to the following restrictions:
15 |
16 | 1. The origin of this software must not be misrepresented; you
17 | must not claim that you wrote the original software. If you use
18 | this software in a product, an acknowledgment in the product
19 | documentation would be appreciated but is not required.
20 |
21 | 2. Altered source versions must be plainly marked as such, and
22 | must not be misrepresented as being the original software.
23 |
24 | 3. This notice may not be removed or altered from any source
25 | distribution.
26 |
27 | -------------------------------------------------------------*/
28 |
29 | #include
30 | #include
31 | #include
32 | #include
33 |
34 | /* IOCTL commands */
35 | #define UMS_BASE (('U'<<24)|('M'<<16)|('S'<<8))
36 | #define USB_IOCTL_UMS_INIT (UMS_BASE+0x1)
37 | #define USB_IOCTL_UMS_GET_CAPACITY (UMS_BASE+0x2)
38 | #define USB_IOCTL_UMS_READ_SECTORS (UMS_BASE+0x3)
39 | #define USB_IOCTL_UMS_WRITE_SECTORS (UMS_BASE+0x4)
40 | #define USB_IOCTL_UMS_READ_STRESS (UMS_BASE+0x5)
41 | #define USB_IOCTL_UMS_SET_VERBOSE (UMS_BASE+0x6)
42 | #define USB_IOCTL_UMS_UNMOUNT (UMS_BASE+0x10)
43 | #define USB_IOCTL_UMS_WATCHDOG (UMS_BASE+0x80)
44 |
45 | #define WBFS_BASE (('W'<<24)|('F'<<16)|('S'<<8))
46 | #define USB_IOCTL_WBFS_OPEN_DISC (WBFS_BASE+0x1)
47 | #define USB_IOCTL_WBFS_READ_DISC (WBFS_BASE+0x2)
48 | #define USB_IOCTL_WBFS_READ_DEBUG (WBFS_BASE+0x3)
49 | #define USB_IOCTL_WBFS_SET_DEVICE (WBFS_BASE+0x4)
50 | #define USB_IOCTL_WBFS_SET_FRAGLIST (WBFS_BASE+0x5)
51 |
52 | #define UMS_HEAPSIZE 0x1000
53 |
54 | /* Variables */
55 | static char fs[] ATTRIBUTE_ALIGN(32) = "/dev/usb2";
56 | static char fs2[] ATTRIBUTE_ALIGN(32) = "/dev/usb/ehc";
57 | static char fs3[] ATTRIBUTE_ALIGN(32) = "/dev/usb/usb123";
58 |
59 | static s32 hid = -1, fd = -1;
60 | static u32 sector_size;
61 |
62 | s32 USBStorage_GetCapacity(u32 *_sector_size) {
63 | if (fd > 0) {
64 | s32 ret;
65 |
66 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_GET_CAPACITY, ":i", §or_size);
67 |
68 | if (ret && _sector_size)
69 | *_sector_size = sector_size;
70 |
71 | return ret;
72 | }
73 |
74 | return IPC_ENOENT;
75 | }
76 |
77 | s32 USBStorage_Init(void) {
78 | s32 ret;
79 |
80 | /* Already open */
81 | if (fd > 0)
82 | return 0;
83 |
84 | /* Create heap */
85 | if (hid < 0) {
86 | hid = iosCreateHeap(UMS_HEAPSIZE);
87 | if (hid < 0)
88 | return IPC_ENOMEM;
89 | }
90 |
91 | /* Open USB device */
92 | fd = IOS_Open(fs, 0);
93 | if (fd < 0)
94 | fd = IOS_Open(fs2, 0);
95 | if (fd < 0)
96 | fd = IOS_Open(fs3, 0);
97 | if (fd < 0)
98 | return fd;
99 |
100 | /* Initialize USB storage */
101 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_INIT, ":");
102 | if (ret<0) goto err;
103 |
104 | /* Get device capacity */
105 | ret = USBStorage_GetCapacity(NULL);
106 | if (!ret)
107 | goto err;
108 |
109 | return 0;
110 |
111 | err:
112 | /* Close USB device */
113 | if (fd > 0) {
114 | IOS_Close(fd);
115 | fd = -1;
116 | }
117 |
118 | return -1;
119 | }
120 |
121 | /** Hermes **/
122 | s32 USBStorage_Watchdog(u32 on_off) {
123 | if (fd >= 0) {
124 | s32 ret;
125 |
126 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WATCHDOG, "i:", on_off);
127 |
128 | return ret;
129 | }
130 |
131 | return IPC_ENOENT;
132 | }
133 |
134 | s32 USBStorage_Umount(void) {
135 | if (fd >= 0) {
136 | s32 ret;
137 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_UNMOUNT, ":");
138 | return ret;
139 | }
140 |
141 | return IPC_ENOENT;
142 | }
143 |
144 | void USBStorage_Deinit(void) {
145 | /* Close USB device */
146 | if (fd > 0) {
147 | IOS_Close(fd);
148 | fd = -1;
149 | }
150 | }
151 |
152 | s32 USBStorage_ReadSectors(u32 sector, u32 numSectors, void *buffer) {
153 |
154 | // void *buf = (void *)buffer;
155 | u32 len = (sector_size * numSectors);
156 |
157 | s32 ret;
158 |
159 | /* Device not opened */
160 | if (fd < 0)
161 | return fd;
162 |
163 |
164 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_READ_SECTORS, "ii:d", sector, numSectors, buffer, len);
165 | return ret;
166 | }
167 |
168 | s32 USBStorage_WriteSectors(u32 sector, u32 numSectors, const void *buffer) {
169 | u32 len = (sector_size * numSectors);
170 |
171 | s32 ret;
172 |
173 | /* Device not opened */
174 | if (fd < 0)
175 | return fd;
176 |
177 | /* Write data */
178 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_UMS_WRITE_SECTORS, "ii:d", sector, numSectors, buffer, len);
179 |
180 | return ret;
181 | }
182 |
183 | static bool __io_usb_Startup(void)
184 | {
185 | return USBStorage_Init() >= 0;
186 | }
187 |
188 | static bool __io_usb_IsInserted(void)
189 | {
190 | s32 ret;
191 | if (fd < 0) return false;
192 | ret = USBStorage_GetCapacity(NULL);
193 | if (ret == 0) return false;
194 | return true;
195 | }
196 |
197 | bool __io_usb_ReadSectors(u32 sector, u32 count, void *buffer)
198 | {
199 | s32 ret = USBStorage_ReadSectors(sector, count, buffer);
200 | return ret > 0;
201 | }
202 |
203 | bool __io_usb_WriteSectors(u32 sector, u32 count, void *buffer)
204 | {
205 | s32 ret = USBStorage_WriteSectors(sector, count, buffer);
206 | return ret > 0;
207 | }
208 |
209 | static bool __io_usb_ClearStatus(void)
210 | {
211 | return true;
212 | }
213 |
214 | static bool __io_usb_Shutdown(void)
215 | {
216 | // do nothing
217 | return true;
218 | }
219 |
220 | static bool __io_usb_NOP(void)
221 | {
222 | // do nothing
223 | return true;
224 | }
225 |
226 | const DISC_INTERFACE __io_usbstorage_ro = {
227 | DEVICE_TYPE_WII_USB,
228 | FEATURE_MEDIUM_CANREAD | FEATURE_WII_USB,
229 | (FN_MEDIUM_STARTUP) &__io_usb_Startup,
230 | (FN_MEDIUM_ISINSERTED) &__io_usb_IsInserted,
231 | (FN_MEDIUM_READSECTORS) &__io_usb_ReadSectors,
232 | (FN_MEDIUM_WRITESECTORS) &__io_usb_NOP, //&__io_usb_WriteSectors,
233 | (FN_MEDIUM_CLEARSTATUS) &__io_usb_ClearStatus,
234 | (FN_MEDIUM_SHUTDOWN) &__io_usb_Shutdown
235 | };
236 |
237 | s32 USBStorage_WBFS_Open(char *buffer)
238 | {
239 | u32 len = 8;
240 |
241 | s32 ret;
242 |
243 | /* Device not opened */
244 | if (fd < 0)
245 | return fd;
246 |
247 | extern u32 wbfs_part_lba;
248 | u32 part = wbfs_part_lba;
249 |
250 | /* Read data */
251 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_OPEN_DISC, "dd:", buffer, len, &part, 4);
252 |
253 | return ret;
254 | }
255 |
256 | // woffset is in 32bit words, len is in bytes
257 | s32 USBStorage_WBFS_Read(u32 woffset, u32 len, void *buffer)
258 | {
259 | s32 ret;
260 |
261 | USBStorage_Init();
262 | /* Device not opened */
263 | if (fd < 0)
264 | return fd;
265 |
266 | /* Read data */
267 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_READ_DISC, "ii:d", woffset, len, buffer, len);
268 |
269 | return ret;
270 | }
271 |
272 |
273 | s32 USBStorage_WBFS_ReadDebug(u32 off, u32 size, void *buffer)
274 | {
275 | s32 ret;
276 |
277 | USBStorage_Init();
278 | /* Device not opened */
279 | if (fd < 0)
280 | return fd;
281 |
282 | /* Read data */
283 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_READ_DEBUG, "ii:d", off, size, buffer, size);
284 |
285 | return ret;
286 | }
287 |
288 |
289 | s32 USBStorage_WBFS_SetDevice(int dev)
290 | {
291 | s32 ret;
292 | static s32 retval = 0;
293 | retval = 0;
294 | USBStorage_Init();
295 | // Device not opened
296 | if (fd < 0) return fd;
297 | // ioctl
298 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_SET_DEVICE, "i:i", dev, &retval);
299 | if (retval) return retval;
300 | return ret;
301 | }
302 |
303 | s32 USBStorage_WBFS_SetFragList(void *p, int size)
304 | {
305 | s32 ret;
306 | USBStorage_Init();
307 | // Device not opened
308 | if (fd < 0) return fd;
309 | // ioctl
310 | ret = IOS_IoctlvFormat(hid, fd, USB_IOCTL_WBFS_SET_FRAGLIST, "d:", p, size);
311 | return ret;
312 | }
313 |
314 | #define DEVICE_TYPE_WII_UMS (('W'<<24)|('U'<<16)|('M'<<8)|'S')
315 |
316 | bool umsio_Startup() {
317 | return USBStorage_Init() == 0;
318 | }
319 |
320 | bool umsio_IsInserted() {
321 | return true; // allways true
322 | }
323 |
324 | bool umsio_ReadSectors(sec_t sector, sec_t numSectors, u8 *buffer) {
325 | u32 cnt = 0;
326 | s32 ret;
327 | /* Do reads */
328 | while (cnt < numSectors) {
329 | u32 sectors = (numSectors - cnt);
330 |
331 | /* Read sectors is too big */
332 | if (sectors > 32)
333 | sectors = 32;
334 |
335 | /* USB read */
336 | ret = USBStorage_ReadSectors(sector + cnt, sectors, &buffer[cnt*512]);
337 | if (ret < 0)
338 | return false;
339 |
340 | /* Increment counter */
341 | cnt += sectors;
342 | }
343 |
344 | return true;
345 | }
346 |
347 | bool umsio_WriteSectors(sec_t sector, sec_t numSectors, const u8* buffer) {
348 | u32 cnt = 0;
349 | s32 ret;
350 |
351 | /* Do writes */
352 | while (cnt < numSectors) {
353 | u32 sectors = (numSectors - cnt);
354 |
355 | /* Write sectors is too big */
356 | if (sectors > 32)
357 | sectors = 32;
358 |
359 | /* USB write */
360 | ret = USBStorage_WriteSectors(sector + cnt, sectors, &buffer[cnt * 512]);
361 | if (ret < 0)
362 | return false;
363 |
364 | /* Increment counter */
365 | cnt += sectors;
366 | }
367 |
368 | return true;
369 | }
370 |
371 | bool umsio_ClearStatus(void) {
372 | return true;
373 | }
374 |
375 | bool umsio_Shutdown() {
376 | USBStorage_Deinit();
377 | return true;
378 | }
379 |
380 | const DISC_INTERFACE __io_wiiums = {
381 | DEVICE_TYPE_WII_UMS,
382 | FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
383 | (FN_MEDIUM_STARTUP) &umsio_Startup,
384 | (FN_MEDIUM_ISINSERTED) &umsio_IsInserted,
385 | (FN_MEDIUM_READSECTORS) &umsio_ReadSectors,
386 | (FN_MEDIUM_WRITESECTORS) &umsio_WriteSectors,
387 | (FN_MEDIUM_CLEARSTATUS) &umsio_ClearStatus,
388 | (FN_MEDIUM_SHUTDOWN) &umsio_Shutdown
389 | };
390 |
391 | const DISC_INTERFACE __io_wiiums_ro = {
392 | DEVICE_TYPE_WII_UMS,
393 | FEATURE_MEDIUM_CANREAD | FEATURE_MEDIUM_CANWRITE | FEATURE_WII_USB,
394 | (FN_MEDIUM_STARTUP) &umsio_Startup,
395 | (FN_MEDIUM_ISINSERTED) &umsio_IsInserted,
396 | (FN_MEDIUM_READSECTORS) &umsio_ReadSectors,
397 | (FN_MEDIUM_WRITESECTORS) &__io_usb_NOP,
398 | (FN_MEDIUM_CLEARSTATUS) &umsio_ClearStatus,
399 | (FN_MEDIUM_SHUTDOWN) &umsio_Shutdown
400 | };
401 |
--------------------------------------------------------------------------------
/source/usbstorage.h:
--------------------------------------------------------------------------------
1 | #ifndef _USBSTORAGE_H_
2 | #define _USBSTORAGE_H_
3 |
4 | #ifdef __cplusplus
5 | extern "C" {
6 | #endif
7 | /* Prototypes */
8 | s32 USBStorage_GetCapacity(u32 *);
9 | s32 USBStorage_Init(void);
10 | void USBStorage_Deinit(void);
11 | s32 USBStorage_Watchdog(u32 on_off);
12 | s32 USBStorage_ReadSectors(u32, u32, void *);
13 | s32 USBStorage_WriteSectors(u32, u32, const void *);
14 |
15 | s32 USBStorage_WBFS_Open(char *buf_id);
16 | s32 USBStorage_WBFS_Read(u32 woffset, u32 len, void *buffer);
17 | s32 USBStorage_WBFS_ReadDebug(u32 off, u32 size, void *buffer);
18 | s32 USBStorage_WBFS_SetDevice(int dev);
19 | s32 USBStorage_WBFS_SetFragList(void *p, int size);
20 |
21 | extern const DISC_INTERFACE __io_wiiums;
22 | extern const DISC_INTERFACE __io_wiiums_ro;
23 | #ifdef __cplusplus
24 | }
25 | #endif
26 |
27 | #endif
28 |
--------------------------------------------------------------------------------
/source/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef _UTILS_H_
2 | #define _UTILS_H_
3 |
4 | /* Constants */
5 | #define KB_SIZE 1024.0
6 | #define MB_SIZE 1048576.0
7 | #define GB_SIZE 1073741824.0
8 |
9 | /* Macros */
10 | #define round_up(x,n) (-(-(x) & -(n)))
11 |
12 | /* Prototypes */
13 | u32 swap32(u32);
14 |
15 | #endif
16 |
--------------------------------------------------------------------------------
/source/video.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 |
4 | #include "sys.h"
5 | #include "video.h"
6 |
7 | /* Video variables */
8 | static void *framebuffer = NULL;
9 | static GXRModeObj *vmode = NULL;
10 |
11 |
12 | void Con_Init(u32 x, u32 y, u32 w, u32 h)
13 | {
14 | /* Create console in the framebuffer */
15 | CON_InitEx(vmode, x, y, w, h);
16 | }
17 |
18 | void Con_Clear(void)
19 | {
20 | /* Clear console */
21 | printf("\x1b[2J");
22 | fflush(stdout);
23 | }
24 |
25 | void Con_ClearLine(void)
26 | {
27 | int cols, rows;
28 | u32 cnt;
29 |
30 | printf("\r");
31 | fflush(stdout);
32 |
33 | /* Get console metrics */
34 | CON_GetMetrics(&cols, &rows);
35 |
36 | /* Erase line */
37 | for (cnt = 1; cnt < cols; cnt++) {
38 | printf(" ");
39 | fflush(stdout);
40 | }
41 |
42 | printf("\r");
43 | fflush(stdout);
44 | }
45 |
46 | void Con_FgColor(u32 color, u8 bold)
47 | {
48 | /* Set foreground color */
49 | printf("\x1b[%lu;%um", color + 30, bold);
50 | fflush(stdout);
51 | }
52 |
53 | void Con_BgColor(u32 color, u8 bold)
54 | {
55 | /* Set background color */
56 | printf("\x1b[%lu;%um", color + 40, bold);
57 | fflush(stdout);
58 | }
59 |
60 | void Con_FillRow(u32 row, u32 color, u8 bold)
61 | {
62 | int cols, rows;
63 | u32 cnt;
64 |
65 | /* Set color */
66 | printf("\x1b[%lu;%um", color + 40, bold);
67 | fflush(stdout);
68 |
69 | /* Get console metrics */
70 | CON_GetMetrics(&cols, &rows);
71 |
72 | /* Save current row and col */
73 | printf("\x1b[s");
74 | fflush(stdout);
75 |
76 | /* Move to specified row */
77 | printf("\x1b[%lu;0H", row);
78 | fflush(stdout);
79 |
80 | /* Fill row */
81 | for (cnt = 0; cnt < cols; cnt++) {
82 | printf(" ");
83 | fflush(stdout);
84 | }
85 |
86 | /* Load saved row and col */
87 | printf("\x1b[u");
88 | fflush(stdout);
89 |
90 | /* Set default color */
91 | Con_BgColor(0, 0);
92 | Con_FgColor(7, 1);
93 | }
94 |
95 | void Video_Configure(GXRModeObj *rmode)
96 | {
97 | /* Configure the video subsystem */
98 | VIDEO_Configure(rmode);
99 |
100 | /* Setup video */
101 | VIDEO_SetBlack(FALSE);
102 | VIDEO_Flush();
103 | VIDEO_WaitVSync();
104 |
105 | if (rmode->viTVMode & VI_NON_INTERLACE)
106 | VIDEO_WaitVSync();
107 | }
108 |
109 | void Video_SetMode(void)
110 | {
111 | /* Select preferred video mode */
112 | vmode = VIDEO_GetPreferredMode(NULL);
113 |
114 | /* Allocate memory for the framebuffer */
115 | framebuffer = MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode));
116 |
117 | /* Configure the video subsystem */
118 | VIDEO_Configure(vmode);
119 |
120 | /* Setup video */
121 | VIDEO_SetNextFramebuffer(framebuffer);
122 | VIDEO_SetBlack(FALSE);
123 | VIDEO_Flush();
124 | VIDEO_WaitVSync();
125 |
126 | if (vmode->viTVMode & VI_NON_INTERLACE)
127 | VIDEO_WaitVSync();
128 |
129 | /* Clear the screen */
130 | Video_Clear(COLOR_BLACK);
131 | }
132 |
133 | void Video_Clear(s32 color)
134 | {
135 | VIDEO_ClearFrameBuffer(vmode, framebuffer, color);
136 | }
137 |
138 | void Video_DrawPng(IMGCTX ctx, PNGUPROP imgProp, u16 x, u16 y)
139 | {
140 | PNGU_DECODE_TO_COORDS_YCbYCr(ctx, x, y, imgProp.imgWidth, imgProp.imgHeight, vmode->fbWidth, vmode->xfbHeight, framebuffer);
141 | }
142 |
--------------------------------------------------------------------------------
/source/video.h:
--------------------------------------------------------------------------------
1 | #ifndef _VIDEO_H_
2 | #define _VIDEO_H_
3 |
4 | #include "libpng/pngu/pngu.h"
5 |
6 | /* Prototypes */
7 | void Con_Init(u32, u32, u32, u32);
8 | void Con_Clear(void);
9 | void Con_ClearLine(void);
10 | void Con_FgColor(u32, u8);
11 | void Con_BgColor(u32, u8);
12 | void Con_FillRow(u32, u32, u8);
13 |
14 | void Video_Configure(GXRModeObj *);
15 | void Video_SetMode(void);
16 | void Video_Clear(s32);
17 | void Video_DrawPng(IMGCTX, PNGUPROP, u16, u16);
18 |
19 | #endif
20 |
--------------------------------------------------------------------------------
/source/wad-manager.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 |
10 | #include "sys.h"
11 | #include "gui.h"
12 | #include "menu.h"
13 | #include "restart.h"
14 | #include "sys.h"
15 | #include "video.h"
16 | #include "wpad.h"
17 | #include "fat.h"
18 | #include "nand.h"
19 | #include "globals.h"
20 | #include "iospatch.h"
21 |
22 | // Globals
23 | CONFIG gConfig;
24 |
25 | // Prototypes
26 | extern u32 WaitButtons (void);
27 | void CheckPassword (void);
28 | void SetDefaultConfig (void);
29 | int ReadConfigFile (char *configFilePath);
30 | int GetIntParam (char *inputStr);
31 | int GetStartupPath (char *startupPath, char *inputStr);
32 | int GetStringParam (char *outParam, char *inputStr, int maxChars);
33 |
34 | // Default password Up-Down-Left-Right-Up-Down
35 | //#define PASSWORD "UDLRUD"
36 | void CheckPassword (void)
37 | {
38 | char curPassword [11]; // Max 10 characters password, NULL terminated
39 | int count = 0;
40 |
41 | if (strlen (gConfig.password) == 0)
42 | return;
43 |
44 | // Ask user for a password. Press "B" to restart Wii
45 | printf("[+] [Enter Password to Continue]:\n\n");
46 |
47 | printf(">> Press A to continue.\n");
48 | printf(">> Press B button to restart your Wii.\n");
49 |
50 | /* Wait for user answer */
51 | for (;;)
52 | {
53 | u32 buttons = WaitButtons();
54 |
55 | if (buttons & WPAD_BUTTON_A)
56 | {
57 | // A button, validate the pw
58 | curPassword [count] = 0;
59 | //if (strcmp (curPassword, PASSWORD) == 0)
60 | if (strcmp (curPassword, gConfig.password) == 0)
61 | {
62 | printf(">> Password Accepted...\n");
63 | break;
64 | }
65 | else
66 | {
67 | printf ("\n");
68 | printf(">> Incorrect Password. Try again...\n");
69 | printf("[+] [Enter Password to Continue]:\n\n");
70 | printf(">> Press A to continue.\n");
71 | printf(">> Press B button to restart your Wii.\n");
72 | count = 0;
73 | }
74 | }
75 | else if (buttons & WPAD_BUTTON_B)
76 | // B button, restart
77 | Restart();
78 | else
79 | {
80 | if (count < 10)
81 | {
82 | // Other buttons, build the password
83 | if (buttons & WPAD_BUTTON_LEFT)
84 | {
85 | curPassword [count++] = 'L';
86 | printf ("*");
87 | }
88 | else if (buttons & WPAD_BUTTON_RIGHT)
89 | {
90 | curPassword [count++] = 'R';
91 | printf ("*");
92 | }
93 | else if (buttons & WPAD_BUTTON_UP)
94 | {
95 | curPassword [count++] = 'U';
96 | printf ("*");
97 | }
98 | else if (buttons & WPAD_BUTTON_DOWN)
99 | {
100 | curPassword [count++] = 'D';
101 | printf ("*");
102 | }
103 | else if (buttons & WPAD_BUTTON_1)
104 | {
105 | curPassword [count++] = '1';
106 | printf ("*");
107 | }
108 | else if (buttons & WPAD_BUTTON_2)
109 | {
110 | curPassword [count++] = '2';
111 | printf ("*");
112 | }
113 | }
114 | }
115 | }
116 | }
117 |
118 | void Disclaimer(void)
119 | {
120 | /* Print disclaimer */
121 | printf("[+] [DISCLAIMER]:\n\n");
122 |
123 | printf(" THIS APPLICATION COMES WITH NO WARRANTY AT ALL,\n");
124 | printf(" NEITHER EXPRESS NOR IMPLIED.\n");
125 | printf(" I DO NOT TAKE ANY RESPONSIBILITY FOR ANY DAMAGE IN YOUR\n");
126 | printf(" WII CONSOLE BECAUSE OF A IMPROPER USAGE OF THIS SOFTWARE.\n\n");
127 |
128 | printf(">> If you agree, press A button to continue.\n");
129 | printf(">> Otherwise, press B button to restart your Wii.\n");
130 |
131 | /* Wait for user answer */
132 | for (;;) {
133 | //u32 buttons = Wpad_WaitButtons();
134 | u32 buttons = WaitButtons();
135 |
136 | /* A button */
137 | if (buttons & WPAD_BUTTON_A)
138 | break;
139 |
140 | /* B button */
141 | if (buttons & WPAD_BUTTON_B)
142 | Restart();
143 | }
144 | }
145 |
146 | int main(int argc, char **argv)
147 | {
148 | ES_GetBoot2Version(&boot2version);
149 | if(!AHBPROT_DISABLED)
150 | {
151 | if(boot2version < 5)
152 | {
153 | if(!loadIOS(202)) if(!loadIOS(222)) if(!loadIOS(223)) if(!loadIOS(224)) if(!loadIOS(249)) loadIOS(36);
154 | }else{
155 | if(!loadIOS(249)) loadIOS(36);
156 | }
157 | }
158 | /* Initialize subsystems */
159 | Sys_Init();
160 |
161 | /* Set video mode */
162 | Video_SetMode();
163 |
164 | /* Initialize console */
165 | Gui_InitConsole();
166 |
167 | /* Draw background */
168 | Gui_DrawBackground();
169 |
170 | /* Initialize Wiimote and GC Controller */
171 | Wpad_Init();
172 | PAD_Init ();
173 | WiiDRC_Init();
174 | WIILIGHT_Init();
175 |
176 | /* Print disclaimer */
177 | //Disclaimer();
178 |
179 | // Set the defaults
180 | SetDefaultConfig ();
181 |
182 | // Read the config file
183 | ReadConfigFile (WM_CONFIG_FILE_PATH);
184 |
185 | // Check password
186 | CheckPassword ();
187 |
188 | /* Menu loop */
189 | Menu_Loop();
190 |
191 | /* Restart Wii */
192 | Restart_Wait();
193 |
194 | return 0;
195 | }
196 |
197 |
198 | int ReadConfigFile (char *configFilePath)
199 | {
200 | int retval = 0;
201 | FILE *fptr;
202 | char *tmpStr = malloc (MAX_FILE_PATH_LEN);
203 | char tmpOutStr [40], path[128];
204 | int i;
205 |
206 | if (tmpStr == NULL)
207 | return (-1);
208 |
209 | fatDevice *fdev = &fdevList[0];
210 | int ret = Fat_Mount(fdev);
211 | snprintf(path, sizeof(path), "%s%s", fdev->mount, configFilePath);
212 |
213 | if (ret < 0)
214 | {
215 | fdev = &fdevList[2];
216 | ret = Fat_Mount(fdev);
217 | snprintf(path, sizeof(path), "%s%s", fdev->mount, configFilePath);
218 | snprintf(path, sizeof(path), "%s%s", fdev->mount, configFilePath);
219 | }
220 |
221 | if (ret < 0)
222 | {
223 | printf(" ERROR! (ret = %d)\n", ret);
224 | // goto err;
225 | retval = -1;
226 | }
227 | else
228 | {
229 | // Read the file
230 | fptr = fopen (path, "rb");
231 | if (fptr != NULL)
232 | {
233 | // Read the options
234 | char done = 0;
235 |
236 | while (!done)
237 | {
238 | if (fgets (tmpStr, MAX_FILE_PATH_LEN, fptr) == NULL)
239 | done = 1;
240 | else if (isalpha(tmpStr[0]))
241 | {
242 | // Get the password
243 | if (strncmp (tmpStr, "Password", 8) == 0)
244 | {
245 | // Get password
246 | // GetPassword (gConfig.password, tmpStr);
247 | GetStringParam (gConfig.password, tmpStr, MAX_PASSWORD_LENGTH);
248 |
249 | // If password is too long, ignore it
250 | if (strlen (gConfig.password) > 10)
251 | {
252 | gConfig.password [0] = 0;
253 | printf ("Password longer than 10 characters; will be ignored. Press a button...\n");
254 | WaitButtons ();
255 | }
256 | }
257 |
258 | // Get startup path
259 | else if (strncmp (tmpStr, "StartupPath", 11) == 0)
260 | {
261 | // Get startup Path
262 | GetStartupPath (gConfig.startupPath, tmpStr);
263 | }
264 |
265 | // cIOS
266 | else if (strncmp (tmpStr, "cIOSVersion", 11) == 0)
267 | {
268 | // Get cIOSVersion
269 | gConfig.cIOSVersion = (u8)GetIntParam (tmpStr);
270 | }
271 |
272 | // FatDevice
273 | else if (strncmp (tmpStr, "FatDevice", 9) == 0)
274 | {
275 | // Get fatDevice
276 | GetStringParam (tmpOutStr, tmpStr, MAX_FAT_DEVICE_LENGTH);
277 | for (i = 0; i < 5; i++)
278 | {
279 | if (strncmp (fdevList[i].mount, tmpOutStr, 4) == 0)
280 | {
281 | gConfig.fatDeviceIndex = i;
282 | }
283 | }
284 | }
285 |
286 | // NandDevice
287 | else if (strncmp (tmpStr, "NANDDevice", 10) == 0)
288 | {
289 | // Get fatDevice
290 | GetStringParam (tmpOutStr, tmpStr, MAX_NAND_DEVICE_LENGTH);
291 | for (i = 0; i < 3; i++)
292 | {
293 | if (strncmp (ndevList[i].name, tmpOutStr, 2) == 0)
294 | {
295 | gConfig.nandDeviceIndex = i;
296 | }
297 | }
298 | }
299 | }
300 | } // EndWhile
301 |
302 | // Close the config file
303 | fclose (fptr);
304 | }
305 | else
306 | {
307 | // If the wm_config.txt file is not found, just take the default config params
308 | //printf ("Config file is not found\n"); // This is for testing only
309 | //WaitButtons();
310 | }
311 | Fat_Unmount(fdev);
312 | }
313 |
314 | // Free memory
315 | free (tmpStr);
316 |
317 | return (retval);
318 | } // ReadConfig
319 |
320 |
321 | void SetDefaultConfig (void)
322 | {
323 | // Default password is NULL or no password
324 | gConfig.password [0] = 0;
325 |
326 | // Default startup folder
327 | strcpy (gConfig.startupPath, WAD_ROOT_DIRECTORY);
328 |
329 | gConfig.cIOSVersion = CIOS_VERSION_INVALID; // Means that user has to select later
330 | gConfig.fatDeviceIndex = FAT_DEVICE_INDEX_INVALID; // Means that user has to select
331 | gConfig.nandDeviceIndex = NAND_DEVICE_INDEX_INVALID; // Means that user has to select
332 |
333 | } // SetDefaultConfig
334 |
335 |
336 | int GetStartupPath (char *startupPath, char *inputStr)
337 | {
338 | int i = 0;
339 | int len = strlen (inputStr);
340 |
341 | // Find the "="
342 | while ((inputStr [i] != '=') && (i < len))
343 | {
344 | i++;
345 | }
346 | i++;
347 |
348 | // Get to the "/"
349 | while ((inputStr [i] != '/') && (i < len))
350 | {
351 | i++;
352 | }
353 |
354 | // Get the startup Path
355 | int count = 0;
356 | while (isascii(inputStr [i]) && (i < len) && (inputStr [i] != '\n') &&
357 | (inputStr [i] != '\r') && (inputStr [i] != ' '))
358 | {
359 | startupPath [count++] = inputStr [i++];
360 | }
361 | startupPath [count] = 0; // NULL terminate
362 |
363 | return (0);
364 | } // GetStartupPath
365 |
366 | int GetIntParam (char *inputStr)
367 | {
368 | int retval = 0;
369 | int i = 0;
370 | int len = strlen (inputStr);
371 | char outParam [40];
372 |
373 | // Find the "="
374 | while ((inputStr [i] != '=') && (i < len))
375 | {
376 | i++;
377 | }
378 | i++;
379 |
380 | // Get to the first alpha numeric character
381 | while ((isdigit(inputStr [i]) == 0) && (i < len))
382 | {
383 | i++;
384 | }
385 |
386 | // Get the string param
387 | int outCount = 0;
388 | while ((isdigit(inputStr [i])) && (i < len) && (outCount < 40))
389 | {
390 | outParam [outCount++] = inputStr [i++];
391 | }
392 | outParam [outCount] = 0; // NULL terminate
393 | retval = atoi (outParam);
394 |
395 | return (retval);
396 | } // GetIntParam
397 |
398 |
399 | int GetStringParam (char *outParam, char *inputStr, int maxChars)
400 | {
401 | int i = 0;
402 | int len = strlen (inputStr);
403 |
404 | // Find the "="
405 | while ((inputStr [i] != '=') && (i < len))
406 | {
407 | i++;
408 | }
409 | i++;
410 |
411 | // Get to the first alpha character
412 | while ((isalpha(inputStr [i]) == 0) && (i < len))
413 | {
414 | i++;
415 | }
416 |
417 | // Get the string param
418 | int outCount = 0;
419 | while ((isalnum(inputStr [i])) && (i < len) && (outCount < maxChars))
420 | {
421 | outParam [outCount++] = inputStr [i++];
422 | }
423 | outParam [outCount] = 0; // NULL terminate
424 |
425 | return (0);
426 | } // GetStringParam
427 |
--------------------------------------------------------------------------------
/source/wad.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 | #include
6 |
7 | #include "sys.h"
8 | #include "title.h"
9 | #include "utils.h"
10 | #include "video.h"
11 | #include "wad.h"
12 | #include "wpad.h"
13 |
14 | // Turn upper and lower into a full title ID
15 | #define TITLE_ID(x,y) (((u64)(x) << 32) | (y))
16 | // Get upper or lower half of a title ID
17 | #define TITLE_UPPER(x) ((u32)((x) >> 32))
18 | // Turn upper and lower into a full title ID
19 | #define TITLE_LOWER(x) ((u32)(x))
20 |
21 | typedef struct {
22 | int version;
23 | int region;
24 |
25 | } SMRegion;
26 |
27 | SMRegion regionlist[] = {
28 | {33, 'X'},
29 | {128, 'J'}, {97, 'E'}, {130, 'P'},
30 | {162, 'P'},
31 | {192, 'J'}, {193, 'E'}, {194, 'P'},
32 | {224, 'J'}, {225, 'E'}, {226, 'P'},
33 | {256, 'J'}, {257, 'E'}, {258, 'P'},
34 | {288, 'J'}, {289, 'E'}, {290, 'P'},
35 | {352, 'J'}, {353, 'E'}, {354, 'P'}, {326, 'K'},
36 | {384, 'J'}, {385, 'E'}, {386, 'P'},
37 | {390, 'K'},
38 | {416, 'J'}, {417, 'E'}, {418, 'P'},
39 | {448, 'J'}, {449, 'E'}, {450, 'P'}, {454, 'K'},
40 | {480, 'J'}, {481, 'E'}, {482, 'P'}, {486, 'K'},
41 | {512, 'E'}, {513, 'E'}, {514, 'P'}, {518, 'K'},
42 | };
43 |
44 | #define NB_SM (sizeof(regionlist) / sizeof(SMRegion))
45 |
46 | u32 WaitButtons(void);
47 |
48 | u32 be32(const u8 *p)
49 | {
50 | return (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
51 | }
52 |
53 | u64 be64(const u8 *p)
54 | {
55 | return ((u64)be32(p) << 32) | be32(p + 4);
56 | }
57 |
58 | u64 get_title_ios(u64 title) {
59 | s32 ret, fd;
60 | static char filepath[256] ATTRIBUTE_ALIGN(32);
61 |
62 | // Check to see if title exists
63 | if (ES_GetDataDir(title, filepath) >= 0 ) {
64 | u32 tmd_size;
65 | static u8 tmd_buf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
66 |
67 | ret = ES_GetStoredTMDSize(title, &tmd_size);
68 | if (ret < 0){
69 | // If we fail to use the ES function, try reading manually
70 | // This is a workaround added since some IOS (like 21) don't like our
71 | // call to ES_GetStoredTMDSize
72 |
73 | //printf("Error! ES_GetStoredTMDSize: %d\n", ret);
74 |
75 | sprintf(filepath, "/title/%08lx/%08lx/content/title.tmd", TITLE_UPPER(title), TITLE_LOWER(title));
76 |
77 | ret = ISFS_Open(filepath, ISFS_OPEN_READ);
78 | if (ret <= 0)
79 | {
80 | //printf("Error! ISFS_Open (ret = %d)\n", ret);
81 | return 0;
82 | }
83 |
84 | fd = ret;
85 |
86 | ret = ISFS_Seek(fd, 0x184, 0);
87 | if (ret < 0)
88 | {
89 | //printf("Error! ISFS_Seek (ret = %d)\n", ret);
90 | return 0;
91 | }
92 |
93 | ret = ISFS_Read(fd,tmd_buf,8);
94 | if (ret < 0)
95 | {
96 | //printf("Error! ISFS_Read (ret = %d)\n", ret);
97 | return 0;
98 | }
99 |
100 | ret = ISFS_Close(fd);
101 | if (ret < 0)
102 | {
103 | //printf("Error! ISFS_Close (ret = %d)\n", ret);
104 | return 0;
105 | }
106 |
107 | return be64(tmd_buf);
108 |
109 | } else {
110 | // Normal versions of IOS won't have a problem, so we do things the "right" way.
111 |
112 | // Some of this code adapted from bushing's title_lister.c
113 | signed_blob *s_tmd = (signed_blob *)tmd_buf;
114 | ret = ES_GetStoredTMD(title, s_tmd, tmd_size);
115 | if (ret < 0){
116 | //printf("Error! ES_GetStoredTMD: %d\n", ret);
117 | return -1;
118 | }
119 | tmd *t = SIGNATURE_PAYLOAD(s_tmd);
120 | return t->sys_version;
121 | }
122 |
123 |
124 | }
125 | return 0;
126 | }
127 |
128 | int get_sm_region_basic()
129 | {
130 | u32 tmd_size;
131 |
132 | u64 title = TITLE_ID(1, 2);
133 | static u8 tmd_buf[MAX_SIGNED_TMD_SIZE] ATTRIBUTE_ALIGN(32);
134 |
135 | int ret = ES_GetStoredTMDSize(title, &tmd_size);
136 |
137 | // Some of this code adapted from bushing's title_lister.c
138 | signed_blob *s_tmd = (signed_blob *)tmd_buf;
139 | ret = ES_GetStoredTMD(title, s_tmd, tmd_size);
140 | if (ret < 0){
141 | //printf("Error! ES_GetStoredTMD: %d\n", ret);
142 | return -1;
143 | }
144 | tmd *t = SIGNATURE_PAYLOAD(s_tmd);
145 | ret = t->title_version;
146 | int i = 0;
147 | while( i <= NB_SM)
148 | {
149 | if( regionlist[i].version == ret) return regionlist[i].region;
150 | i++;
151 | }
152 | return 0;
153 | }
154 |
155 | /* 'WAD Header' structure */
156 | typedef struct {
157 | /* Header length */
158 | u32 header_len;
159 |
160 | /* WAD type */
161 | u16 type;
162 |
163 | u16 padding;
164 |
165 | /* Data length */
166 | u32 certs_len;
167 | u32 crl_len;
168 | u32 tik_len;
169 | u32 tmd_len;
170 | u32 data_len;
171 | u32 footer_len;
172 | } ATTRIBUTE_PACKED wadHeader;
173 |
174 | /* Variables */
175 | static u8 wadBuffer[BLOCK_SIZE] ATTRIBUTE_ALIGN(32);
176 |
177 |
178 | s32 __Wad_ReadFile(FILE *fp, void *outbuf, u32 offset, u32 len)
179 | {
180 | s32 ret;
181 |
182 | /* Seek to offset */
183 | fseek(fp, offset, SEEK_SET);
184 |
185 | /* Read data */
186 | ret = fread(outbuf, len, 1, fp);
187 | if (ret < 0)
188 | return ret;
189 |
190 | return 0;
191 | }
192 |
193 | s32 __Wad_ReadAlloc(FILE *fp, void **outbuf, u32 offset, u32 len)
194 | {
195 | void *buffer = NULL;
196 | s32 ret;
197 |
198 | /* Allocate memory */
199 | buffer = memalign(32, len);
200 | if (!buffer)
201 | return -1;
202 |
203 | /* Read file */
204 | ret = __Wad_ReadFile(fp, buffer, offset, len);
205 | if (ret < 0) {
206 | free(buffer);
207 | return ret;
208 | }
209 |
210 | /* Set pointer */
211 | *outbuf = buffer;
212 |
213 | return 0;
214 | }
215 |
216 | s32 __Wad_GetTitleID(FILE *fp, wadHeader *header, u64 *tid)
217 | {
218 | signed_blob *p_tik = NULL;
219 | tik *tik_data = NULL;
220 |
221 | u32 offset = 0;
222 | s32 ret;
223 |
224 | /* Ticket offset */
225 | offset += round_up(header->header_len, 64);
226 | offset += round_up(header->certs_len, 64);
227 | offset += round_up(header->crl_len, 64);
228 |
229 | /* Read ticket */
230 | ret = __Wad_ReadAlloc(fp, (void *)&p_tik, offset, header->tik_len);
231 | if (ret < 0)
232 | goto out;
233 |
234 | /* Ticket data */
235 | tik_data = (tik *)SIGNATURE_PAYLOAD(p_tik);
236 |
237 | /* Copy title ID */
238 | *tid = tik_data->titleid;
239 |
240 | out:
241 | /* Free memory */
242 | if (p_tik)
243 | free(p_tik);
244 |
245 | return ret;
246 | }
247 |
248 | void __Wad_FixTicket(signed_blob *p_tik)
249 | {
250 | u8 *data = (u8 *)p_tik;
251 | u8 *ckey = data + 0x1F1;
252 |
253 | /* Check common key */
254 | if (*ckey > 1)
255 | *ckey = 0;
256 |
257 | /* Fakesign ticket */
258 | Title_FakesignTik(p_tik);
259 | }
260 |
261 | s32 Wad_Install(FILE *fp)
262 | {
263 | wadHeader *header = NULL;
264 | signed_blob *p_certs = NULL, *p_crl = NULL, *p_tik = NULL, *p_tmd = NULL;
265 |
266 | tmd *tmd_data = NULL;
267 |
268 | u32 cnt, offset = 0;
269 | int ret;
270 | u64 tid;
271 |
272 | printf("\t\t>> Reading WAD data...");
273 | fflush(stdout);
274 |
275 | ret = __Wad_ReadAlloc(fp, (void *)&header, offset, sizeof(wadHeader));
276 | if (ret >= 0)
277 | offset += round_up(header->header_len, 64);
278 | else
279 | goto err;
280 |
281 | //Don't try to install boot2
282 | __Wad_GetTitleID(fp, header, &tid);
283 |
284 | if (tid == TITLE_ID(1, 1))
285 | {
286 | printf("\n I can't let you do that Dave\n");
287 | ret = -999;
288 | goto out;
289 | }
290 |
291 | /* WAD certificates */
292 | ret = __Wad_ReadAlloc(fp, (void *)&p_certs, offset, header->certs_len);
293 | if (ret >= 0)
294 | offset += round_up(header->certs_len, 64);
295 | else
296 | goto err;
297 |
298 | /* WAD crl */
299 | if (header->crl_len) {
300 | ret = __Wad_ReadAlloc(fp, (void *)&p_crl, offset, header->crl_len);
301 | if (ret < 0)
302 | goto err;
303 | else
304 | offset += round_up(header->crl_len, 64);
305 | }
306 |
307 | /* WAD ticket */
308 | ret = __Wad_ReadAlloc(fp, (void *)&p_tik, offset, header->tik_len);
309 | if (ret < 0)
310 | goto err;
311 | else
312 | offset += round_up(header->tik_len, 64);
313 |
314 | /* WAD TMD */
315 | ret = __Wad_ReadAlloc(fp, (void *)&p_tmd, offset, header->tmd_len);
316 | if (ret < 0)
317 | goto err;
318 | else
319 | offset += round_up(header->tmd_len, 64);
320 |
321 | Con_ClearLine();
322 |
323 | /* Get TMD info */
324 |
325 | tmd_data = (tmd *)SIGNATURE_PAYLOAD(p_tmd);
326 |
327 | if(TITLE_LOWER(tmd_data->sys_version) != 0 && isIOSstub(TITLE_LOWER(tmd_data->sys_version)))
328 | {
329 | printf("\n This Title wants IOS%li but the installed version\n is a stub.\n", TITLE_LOWER(tmd_data->sys_version));
330 | ret = -999;
331 | goto err;
332 | }
333 |
334 | if(get_title_ios(TITLE_ID(1, 2)) == tid)
335 | {
336 | if ( ( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001) )
337 | {
338 | printf("\n I won't install a stub System Menu IOS\n");
339 | ret = -999;
340 | goto err;
341 | }
342 | }
343 |
344 | if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'E')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'P')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'J')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | 'K')))
345 | {
346 | if ( ( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001) )
347 | {
348 | printf("\n I won't install a stub EULA IOS\n");
349 | ret = -999;
350 | goto err;
351 | }
352 | }
353 |
354 | if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'E')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'P')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'J')) || tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | 'K')))
355 | {
356 | if ( ( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001) )
357 | {
358 | printf("\n I won't install a stub rgsel IOS\n");
359 | ret = -999;
360 | goto err;
361 | }
362 | }
363 | if (tid == get_title_ios(TITLE_ID(0x10001, 0x48415858)) || tid == get_title_ios(TITLE_ID(0x10001, 0x4A4F4449)))
364 | {
365 | if ( ( tmd_data->num_contents == 3) && (tmd_data->contents[0].type == 1 && tmd_data->contents[1].type == 0x8001 && tmd_data->contents[2].type == 0x8001) )
366 | {
367 | printf("\n Are you sure you wan't to install a stub HBC IOS?\n");
368 | printf("\n Press A to continue.\n");
369 | printf(" Press B skip.");
370 |
371 | u32 buttons = WaitButtons();
372 |
373 | if (!(buttons & WPAD_BUTTON_A))
374 | {
375 | ret = -998;
376 | goto err;
377 | }
378 | }
379 | }
380 |
381 | if (tid == TITLE_ID(1, 2))
382 | {
383 | if(get_sm_region_basic() == 0)
384 | {
385 | printf("\n Can't get the SM region\n Please check the site for updates\n");
386 | ret = -999;
387 | goto err;
388 | }
389 | int i, ret = -1;
390 | for(i = 0; i <= NB_SM; i++)
391 | {
392 | if( regionlist[i].version == tmd_data->title_version)
393 | {
394 | ret = 1;
395 | break;
396 | }
397 | }
398 | if(ret -1)
399 | {
400 | printf("\n Can't get the SM region\n Please check the site for updates\n");
401 | ret = -999;
402 | goto err;
403 | }
404 | if( get_sm_region_basic() != regionlist[i].region)
405 | {
406 | printf("\n I won't install the wrong regions SM\n");
407 | ret = -999;
408 | goto err;
409 | }
410 | if(tmd_data->title_version < 416)
411 | {
412 | if(boot2version == 4)
413 | {
414 | printf("\n This version of the System Menu\n is not compatible with your Wii\n");
415 | ret = -999;
416 | goto err;
417 | }
418 | }
419 | }
420 |
421 | /* Fix ticket */
422 | __Wad_FixTicket(p_tik);
423 |
424 | printf("\t\t>> Installing ticket...");
425 | fflush(stdout);
426 |
427 | /* Install ticket */
428 | ret = ES_AddTicket(p_tik, header->tik_len, p_certs, header->certs_len, p_crl, header->crl_len);
429 | if (ret < 0)
430 | goto err;
431 |
432 | Con_ClearLine();
433 |
434 | printf("\r\t\t>> Installing title...");
435 | fflush(stdout);
436 |
437 | /* Install title */
438 | ret = ES_AddTitleStart(p_tmd, header->tmd_len, p_certs, header->certs_len, p_crl, header->crl_len);
439 | if (ret < 0)
440 | goto err;
441 |
442 | /* Install contents */
443 | for (cnt = 0; cnt < tmd_data->num_contents; cnt++) {
444 | tmd_content *content = &tmd_data->contents[cnt];
445 |
446 | u32 idx = 0, len;
447 | s32 cfd;
448 |
449 | Con_ClearLine();
450 |
451 | printf("\r\t\t>> Installing content #%02ld...", content->cid);
452 | fflush(stdout);
453 |
454 | /* Encrypted content size */
455 | len = round_up(content->size, 64);
456 |
457 | /* Install content */
458 | cfd = ES_AddContentStart(tmd_data->title_id, content->cid);
459 | if (cfd < 0) {
460 | ret = cfd;
461 | goto err;
462 | }
463 |
464 | /* Install content data */
465 | while (idx < len) {
466 | u32 size;
467 |
468 | /* Data length */
469 | size = (len - idx);
470 | if (size > BLOCK_SIZE)
471 | size = BLOCK_SIZE;
472 |
473 | /* Read data */
474 | ret = __Wad_ReadFile(fp, &wadBuffer, offset, size);
475 | if (ret < 0)
476 | goto err;
477 |
478 | /* Install data */
479 | ret = ES_AddContentData(cfd, wadBuffer, size);
480 | if (ret < 0)
481 | goto err;
482 |
483 | /* Increase variables */
484 | idx += size;
485 | offset += size;
486 | }
487 |
488 | /* Finish content installation */
489 | ret = ES_AddContentFinish(cfd);
490 | if (ret < 0)
491 | goto err;
492 | }
493 |
494 | Con_ClearLine();
495 |
496 | printf("\r\t\t>> Finishing installation...");
497 | fflush(stdout);
498 |
499 | /* Finish title install */
500 | ret = ES_AddTitleFinish();
501 | if (ret >= 0) {
502 | printf(" OK!\n");
503 | goto out;
504 | }
505 |
506 | err:
507 | printf(" ERROR! (ret = %d)\n", ret);
508 |
509 | /* Cancel install */
510 | ES_AddTitleCancel();
511 |
512 | out:
513 | /* Free memory */
514 | if (header)
515 | free(header);
516 | if (p_certs)
517 | free(p_certs);
518 | if (p_crl)
519 | free(p_crl);
520 | if (p_tik)
521 | free(p_tik);
522 | if (p_tmd)
523 | free(p_tmd);
524 |
525 | return ret;
526 | }
527 |
528 | s32 Wad_Uninstall(FILE *fp)
529 | {
530 | wadHeader *header = NULL;
531 | tikview *viewData = NULL;
532 |
533 | u64 tid;
534 | u32 viewCnt;
535 | int ret;
536 |
537 | printf("\t\t>> Reading WAD data...");
538 | fflush(stdout);
539 |
540 | /* WAD header */
541 | ret = __Wad_ReadAlloc(fp, (void *)&header, 0, sizeof(wadHeader));
542 | if (ret < 0) {
543 | printf(" ERROR! (ret = %d)\n", ret);
544 | goto out;
545 | }
546 |
547 | /* Get title ID */
548 | ret = __Wad_GetTitleID(fp, header, &tid);
549 | if (ret < 0) {
550 | printf(" ERROR! (ret = %d)\n", ret);
551 | goto out;
552 | }
553 | //Assorted Checks
554 | if (TITLE_UPPER(tid) == 1 && get_title_ios(TITLE_ID(1, 2)) == 0)
555 | {
556 | printf("\n I can't determine the System Menus IOS\nDeleting system titles is disabled\n");
557 | ret = -999;
558 | goto out;
559 | }
560 | if (tid == TITLE_ID(1, 1))
561 | {
562 | printf("\n I won't try to uninstall boot2\n");
563 | ret = -999;
564 | goto out;
565 | }
566 | if (tid == TITLE_ID(1, 2))
567 | {
568 | printf("\n I won't uninstall the System Menu\n");
569 | ret = -999;
570 | goto out;
571 | }
572 | if(get_title_ios(TITLE_ID(1, 2)) == tid)
573 | {
574 | printf("\n I won't uninstall the System Menus IOS\n");
575 | ret = -999;
576 | goto out;
577 | }
578 | if (tid == get_title_ios(TITLE_ID(0x10001, 0x48415858)) || tid == get_title_ios(TITLE_ID(0x10001, 0x4A4F4449)))
579 | {
580 | printf("\n This is the HBCs IOS, uninstalling will break the HBC!\n");
581 | printf("\n Press A to continue.\n");
582 | printf(" Press B skip.");
583 |
584 | u32 buttons = WaitButtons();
585 |
586 | if (!(buttons & WPAD_BUTTON_A))
587 | {
588 | ret = -998;
589 | goto out;
590 | }
591 | }
592 | if((tid == TITLE_ID(0x10008, 0x48414B00 | 'E') || tid == TITLE_ID(0x10008, 0x48414B00 | 'P') || tid == TITLE_ID(0x10008, 0x48414B00 | 'J') || tid == TITLE_ID(0x10008, 0x48414B00 | 'K')
593 | || (tid == TITLE_ID(0x10008, 0x48414C00 | 'E') || tid == TITLE_ID(0x10008, 0x48414C00 | 'P') || tid == TITLE_ID(0x10008, 0x48414C00 | 'J') || tid == TITLE_ID(0x10008, 0x48414C00 | 'K'))) && get_sm_region_basic() == 0)
594 | {
595 | printf("\n Can't get the SM region\n Please check the site for updates\n");
596 | ret = -999;
597 | goto out;
598 | }
599 | if(tid == TITLE_ID(0x10008, 0x48414B00 | get_sm_region_basic()))
600 | {
601 | printf("\n I won't uninstall the EULA\n");
602 | ret = -999;
603 | goto out;
604 | }
605 | if(tid == TITLE_ID(0x10008, 0x48414C00 | get_sm_region_basic()))
606 | {
607 | printf("\n I won't uninstall rgsel\n");
608 | ret = -999;
609 | goto out;
610 | }
611 | if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414B00 | get_sm_region_basic())))
612 | {
613 | printf("\n I won't uninstall the EULAs IOS\n");
614 | ret = -999;
615 | goto out;
616 | }
617 | if(tid == get_title_ios(TITLE_ID(0x10008, 0x48414C00 | get_sm_region_basic())))
618 | {
619 | printf("\n I won't uninstall the rgsel IOS\n");
620 | ret = -999;
621 | goto out;
622 | }
623 |
624 | Con_ClearLine();
625 |
626 | printf("\t\t>> Deleting tickets...");
627 | fflush(stdout);
628 |
629 | /* Get ticket views */
630 | ret = Title_GetTicketViews(tid, &viewData, &viewCnt);
631 | if (ret < 0)
632 | printf(" ERROR! (ret = %d)\n", ret);
633 |
634 | /* Delete tickets */
635 | if (ret >= 0) {
636 | u32 cnt;
637 |
638 | /* Delete all tickets */
639 | for (cnt = 0; cnt < viewCnt; cnt++) {
640 | ret = ES_DeleteTicket(&viewData[cnt]);
641 | if (ret < 0)
642 | break;
643 | }
644 |
645 | if (ret < 0)
646 | printf(" ERROR! (ret = %d\n", ret);
647 | else
648 | printf(" OK!\n");
649 | }
650 |
651 | printf("\t\t>> Deleting title contents...");
652 | fflush(stdout);
653 |
654 | /* Delete title contents */
655 | ret = ES_DeleteTitleContent(tid);
656 | if (ret < 0)
657 | printf(" ERROR! (ret = %d)\n", ret);
658 | else
659 | printf(" OK!\n");
660 |
661 |
662 | printf("\t\t>> Deleting title...");
663 | fflush(stdout);
664 |
665 | /* Delete title */
666 | ret = ES_DeleteTitle(tid);
667 | if (ret < 0)
668 | printf(" ERROR! (ret = %d)\n", ret);
669 | else
670 | printf(" OK!\n");
671 |
672 | out:
673 | /* Free memory */
674 | if (header)
675 | free(header);
676 | return ret;
677 | }
678 |
--------------------------------------------------------------------------------
/source/wad.h:
--------------------------------------------------------------------------------
1 | #ifndef _WAD_H_
2 | #define _WAD_H_
3 |
4 | /* Prototypes */
5 | s32 Wad_Install(FILE *);
6 | s32 Wad_Uninstall(FILE *);
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/source/wkb.c:
--------------------------------------------------------------------------------
1 | #include "wkb.h"
2 |
3 | /*
4 |
5 | s32 USBKeyboard_Open(const eventcallback cb);
6 | void USBKeyboard_Close(void);
7 |
8 | bool USBKeyboard_IsConnected(void);
9 | s32 USBKeyboard_Scan(void);
10 |
11 | s32 USBKeyboard_SetLed(const USBKeyboard_led led, bool on);
12 | s32 USBKeyboard_ToggleLed(const USBKeyboard_led led);
13 | */
14 |
15 | s32 WkbInit(void)
16 | {
17 | s32 retval = 0;
18 |
19 | retval = USBKeyboard_Initialize();
20 |
21 | return (retval);
22 |
23 | } // WkbInit
24 |
25 | s32 WkbDeInit(void)
26 | {
27 | s32 retval = 0;
28 |
29 | retval = USBKeyboard_Deinitialize();
30 |
31 | return (retval);
32 |
33 | } // WkbDeInit
34 |
35 | u32 WkbWaitKey (void)
36 | {
37 | u32 retval = 0;
38 |
39 | // Stub
40 | return (retval);
41 |
42 | } // WkbWaitKey
43 |
44 | //void Wpad_Disconnect(void);
45 | //u32 Wpad_GetButtons(void);
46 |
47 |
48 |
--------------------------------------------------------------------------------
/source/wkb.h:
--------------------------------------------------------------------------------
1 | #ifndef _WKB_H_
2 | #define _WKB_H_
3 |
4 | //#include
5 | //#include
6 | //#include
7 | //#include
8 | #include // u8, u16, etc...
9 |
10 | #include
11 | #include
12 |
13 | /* Prototypes */
14 | s32 WkbInit(void);
15 | u32 WkbWaitKey (void);
16 | //void Wpad_Disconnect(void);
17 | //u32 Wpad_GetButtons(void);
18 |
19 | #endif
20 |
--------------------------------------------------------------------------------
/source/wpad.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | #include "sys.h"
7 | #include "wpad.h"
8 | //#include "wkb.h"
9 |
10 | /* Constants */
11 | #define MAX_WIIMOTES 4
12 |
13 | int start;
14 |
15 | void __Wpad_PowerCallback(s32 chan)
16 | {
17 | /* Poweroff console */
18 | Sys_Shutdown();
19 | }
20 |
21 |
22 | s32 Wpad_Init(void)
23 | {
24 | s32 ret;
25 |
26 | /* Initialize Wiimote subsystem */
27 | ret = WPAD_Init();
28 | if (ret < 0)
29 | return ret;
30 |
31 | /* Set POWER button callback */
32 | WPAD_SetPowerButtonCallback(__Wpad_PowerCallback);
33 |
34 | return ret;
35 | }
36 |
37 | void Wpad_Disconnect(void)
38 | {
39 | u32 cnt;
40 |
41 | /* Disconnect Wiimotes */
42 | for (cnt = 0; cnt < MAX_WIIMOTES; cnt++)
43 | WPAD_Disconnect(cnt);
44 |
45 | /* Shutdown Wiimote subsystem */
46 | WPAD_Shutdown();
47 | }
48 |
49 | u32 Wpad_GetButtons(void)
50 | {
51 | u32 buttons = 0, cnt;
52 |
53 | /* Scan pads */
54 | WPAD_ScanPads();
55 |
56 | /* Get pressed buttons */
57 | for (cnt = 0; cnt < MAX_WIIMOTES; cnt++)
58 | buttons |= WPAD_ButtonsDown(cnt);
59 |
60 | return buttons;
61 | }
62 |
63 | u32 Wpad_WaitButtons(void)
64 | {
65 | u32 buttons = 0;
66 | /* Wait for button pressing */
67 | while (!buttons) {
68 | buttons = Wpad_GetButtons();
69 | VIDEO_WaitVSync();
70 | }
71 |
72 | return buttons;
73 | }
74 |
75 | u32 Wpad_HeldButtons(void)
76 | {
77 | u32 buttons = 0, cnt;
78 |
79 | /* Scan pads */
80 | WPAD_ScanPads();
81 |
82 | /* Get pressed buttons */
83 | for (cnt = 0; cnt < MAX_WIIMOTES; cnt++)
84 | buttons |= WPAD_ButtonsHeld(cnt);
85 |
86 | return buttons;
87 | }
88 |
89 | bool Wpad_TimeButton(void)
90 | {
91 | u32 buttons = 1;
92 |
93 | time_t start,end;
94 | time (&start);
95 | int dif;
96 | /* Wait for button pressing */
97 | while (buttons) {
98 | buttons = Wpad_HeldButtons();
99 | VIDEO_WaitVSync();
100 | time (&end);
101 | dif = difftime (end,start);
102 | if(dif>=2) return true;
103 | }
104 | return false;
105 | }
--------------------------------------------------------------------------------
/source/wpad.h:
--------------------------------------------------------------------------------
1 | #ifndef _WPAD_H_
2 | #define _WPAD_H_
3 |
4 | #include
5 |
6 | /* Prototypes */
7 | s32 Wpad_Init(void);
8 | void Wpad_Disconnect(void);
9 | u32 Wpad_GetButtons(void);
10 | u32 Wpad_WaitButtons(void);
11 | bool Wpad_TimeButton(void);
12 |
13 | #endif
14 |
--------------------------------------------------------------------------------
/wm_config.txt:
--------------------------------------------------------------------------------
1 | ;Config file format
2 | ;
3 | ;No spaces precedes the keyword on a line
4 | ;
5 | Password=
6 |
7 | ; StartupPath:
8 | StartupPath=/wad
9 |
10 | ; cIOS: 249, 222, whatever
11 | :cIOSVersion=249
12 |
13 | ; FatDevice: sd usb usb2 gcsda gcsdb
14 | :FatDevice=sd
15 |
16 | ; NANDDevice: Disable SD USB
17 | ; Note that WM will prompt for NAND device only if you selected cIOS=249
18 | :NANDDevice=Disable
19 |
20 | : Settings for SMB shares
21 |
22 | :SMBUser=
23 | :SMBPassword=
24 | :SMBShare=
25 | :SMBhostIP=
--------------------------------------------------------------------------------