It’s been a bumpy road to get there, but I’ve created a dirent.h for use in hacking the Nintendo Wii. You might ask, “what the heck did you go and do that for?” Perhaps it’s because I’m a good Samaritan who saw the suffering of my fellow Wii h4x0rd00dz and knew that I could ease the pain. Perhaps it’s because I didn’t know C at all, and thought I might learn a thing or two. Or perhaps it’s because when I was trying to compile Super Mario War for the Wii, it was one of the things giving compile errors. Regardless of the reason, the beast has been conquered, and the spoils should be put in your libogc/include directory.
/*
Copyright (c) 2008, dotbatman (nerdfortress.com)
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the nerdfortress.com nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef DIRENT_H
// This has already been included in the project once, so we only need prototypes
static DIR* opendir (const char *path);
static int closedir (DIR *dir);
static struct dirent* readdir (DIR *dir);
static void rewinddir (DIR *dir);
#else // First inclusion
// We don't want to be redefining these functions over and over again.
#define DIRENT_H
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/dir.h>
#include <fat.h>
typedef DIR_ITER dir_t; // For libfat
// This structure can hold all the juicy details for our functions,
// and it doesn't need to follow any standard but having d_name in most cases.
typedef struct dirent
{
DIR_ITER* dirPointer;
char d_name[FILENAME_MAX+1];
} DIR;
static DIR* opendir(const char* path)
{
DIR* dir;
// Check the path yourself. This is just to make sure we don't trip over
// someone elses really bad code (tm).
if (!path || *path == 0)
{
errno = EINVAL;
return NULL;
}
DIR_ITER* dp = diropen(path);
if(!dp)
return NULL; // diropen sets errno for us, so just return NULL.
// Build our DIR struct
dir = (DIR*)malloc(sizeof(DIR));
if(!dir)
{
errno = ENOMEM;
return NULL;
}
dir->dirPointer = dp;
// Return that DIR for use with other functions.
return dir;
}
static int closedir(DIR* dir)
{
int retval;
if (!dir)
{
// Not a good DIR, but thanks for playing... aha ha ha ha.
errno = EBADF;
retval = -1;
} else {
// Pass the DIR_ITER pointer to libfat and shut 'er down.
retval = dirclose(dir->dirPointer);
free(dir); // Clean up after ourselves
}
return retval;
}
static struct dirent* readdir(DIR* dir)
{
// We'll need to store each entry from the listing
char entry[FILENAME_MAX+1];
if (!dir)
{
errno = EBADF; // Bad DIR. No biscuit.
return NULL;
}
if(dirnext(dir->dirPointer, entry, NULL) == 0)
{
strncpy(dir->d_name, entry, FILENAME_MAX);
return dir;
}
// We're all out of files to give you
return NULL;
}
static void rewinddir(DIR* dir)
{
if (dir != NULL)
{
// If you need documentation on this one, you've got bigger problems.
dirreset(dir->dirPointer);
}
}
#endif // DIRENT_H
#ifdef __cplusplus
}
#endif
We found a couple memory-related bugs in the code above…look for an update soon.
Whoops! Good catch. The memory situation is all fixed up. Thanks, Random.
Are you still working on this? Because I just found this post because I thought of porting SMW and googled dirent.h…
Yes, but it’s back-burner until I get a USBGecko. I’ve gotten the source for smw1.7 to compile, but it’s crashing before main is executed and I’m not sure why. If you’d like to try your hand at it, I could send you what I have.
Heh, I’ve also managed to compile the source before I saw your reply and am now stuck at the same problem. I’ll let you know if i find something.
[...] 15, 2009 by Random Good news for SMW fans! Due to the efforts of several diligent game hackers, including our own dotbatman, Super Mario War has finally been ported to the Wii! For now you have to play this on [...]