mirror of
https://github.com/modmii/YAWM-ModMii-Edition.git
synced 2024-11-21 23:59:18 +01:00
- Added support for arguments in app launch code
- Added XML stuff to parse the meta.xml file Notes: - To build.. this now requires the mxml lib
This commit is contained in:
parent
da653aee36
commit
40ba5db3b3
2
Makefile
2
Makefile
@ -36,7 +36,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
||||
#---------------------------------------------------------------------------------
|
||||
# any extra libraries we wish to link with the project
|
||||
#---------------------------------------------------------------------------------
|
||||
LIBS := -ltinysmb -lpng -lfat -lwiidrc -lwiiuse -lbte -logc -lm -lz -lwiilight
|
||||
LIBS := -lmxml -ltinysmb -lpng -lfat -lwiidrc -lwiiuse -lbte -logc -lm -lz -lwiilight
|
||||
|
||||
#---------------------------------------------------------------------------------
|
||||
# list of directories containing libraries, this must be the top level containing
|
||||
|
BIN
data/appboot.bin
BIN
data/appboot.bin
Binary file not shown.
@ -2,18 +2,21 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <ogc/machine/processor.h>
|
||||
#include <ogc/lwp_threads.h>
|
||||
|
||||
#include "fat.h"
|
||||
#include "sys.h"
|
||||
#include "wpad.h"
|
||||
#include "appmetadata.h"
|
||||
|
||||
extern void __exception_closeall();
|
||||
|
||||
//struct __argv arguments;
|
||||
//char* m_argv[MAX_ARGV];
|
||||
//u8* m_Buffer = NULL;
|
||||
struct __argv arguments;
|
||||
char* m_argv[256];
|
||||
|
||||
u8* metaBuffer = NULL;
|
||||
u32 metaSize = 0;
|
||||
|
||||
u8* appBuffer = NULL;
|
||||
u32 appSize = 0;
|
||||
@ -45,27 +48,48 @@ bool LoadApp(const char* path)
|
||||
{
|
||||
appBuffer = (u8*)0x92000000;
|
||||
|
||||
FILE* f = fopen(path, "rb");
|
||||
char currentPath[256];
|
||||
snprintf(currentPath, sizeof(currentPath), "%s/boot.dol", path);
|
||||
|
||||
FILE* f = fopen(currentPath, "rb");
|
||||
|
||||
if (f == NULL)
|
||||
return false;
|
||||
{
|
||||
snprintf(currentPath, sizeof(currentPath), "%s/boot.elf", path);
|
||||
f = fopen(currentPath, "rb");
|
||||
|
||||
if (f == NULL)
|
||||
return false;
|
||||
}
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
u32 size = ftell(f);
|
||||
appSize = ftell(f);
|
||||
rewind(f);
|
||||
|
||||
if (size > 0x1000000)
|
||||
if (appSize > 0x1000000)
|
||||
{
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
|
||||
u32 ret = fread(appBuffer, 1, size, f);
|
||||
DCFlushRange(appBuffer, (size + 31) & (~31));
|
||||
u32 ret = fread(appBuffer, 1, appSize, f);
|
||||
DCFlushRange(appBuffer, (appSize + 31) & (~31));
|
||||
|
||||
fclose(f);
|
||||
|
||||
return (ret == size);
|
||||
snprintf(currentPath, sizeof(currentPath), "%s/meta.xml", path);
|
||||
u16 argumentsSize = 0;
|
||||
char* Arguments = LoadArguments(currentPath, &argumentsSize);
|
||||
|
||||
if (Arguments)
|
||||
{
|
||||
*(vu32*)0x91000000 = argumentsSize;
|
||||
memcpy((void*)0x91000020, Arguments, argumentsSize);
|
||||
DCFlushRange((u8*)0x91000020, argumentsSize);
|
||||
free(Arguments);
|
||||
}
|
||||
|
||||
return (ret == appSize);
|
||||
}
|
||||
|
||||
u8* GetApp(u32* size)
|
||||
|
180
source/appmetadata.c
Normal file
180
source/appmetadata.c
Normal file
@ -0,0 +1,180 @@
|
||||
#include <mxml.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "appmetadata.h"
|
||||
|
||||
static char* GetStringValue(mxml_node_t* node, const char* element)
|
||||
{
|
||||
mxml_node_t* elementNode = mxmlFindElement(node, node, element, NULL, NULL, MXML_DESCEND_FIRST);
|
||||
|
||||
if (elementNode)
|
||||
{
|
||||
mxml_node_t* current = elementNode->child;
|
||||
|
||||
while (current && current->type != MXML_OPAQUE)
|
||||
current = mxmlWalkNext(current, elementNode, MXML_NO_DESCEND);
|
||||
|
||||
if (current->type == MXML_OPAQUE)
|
||||
return current->value.opaque;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static char* GetArgumentValue(mxml_node_t* node)
|
||||
{
|
||||
if (node)
|
||||
{
|
||||
mxml_node_t* current = node->child;
|
||||
|
||||
while (current && current->type != MXML_OPAQUE)
|
||||
current = mxmlWalkNext(current, node, MXML_NO_DESCEND);
|
||||
|
||||
if (current->type == MXML_OPAQUE)
|
||||
return current->value.opaque;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct MetaData* LoadMetaData(const char* path)
|
||||
{
|
||||
FILE* f = fopen(path, "rb");
|
||||
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
|
||||
mxml_node_t* meta = mxmlLoadFile(NULL, f, MXML_OPAQUE_CALLBACK);
|
||||
fclose(f);
|
||||
|
||||
if (!meta)
|
||||
return NULL;
|
||||
|
||||
mxml_node_t* app = mxmlFindElement(meta, meta, "app", NULL, NULL, MXML_DESCEND_FIRST);
|
||||
|
||||
if (!app)
|
||||
{
|
||||
mxmlDelete(meta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct MetaData* metaData = (struct MetaData*)malloc(sizeof(struct MetaData));
|
||||
if (!metaData)
|
||||
{
|
||||
mxmlDelete(meta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(metaData, 0, sizeof(struct MetaData));
|
||||
|
||||
metaData->name = strdup(GetStringValue(app, "name"));
|
||||
metaData->coder = strdup(GetStringValue(app, "coder"));
|
||||
metaData->version = strdup(GetStringValue(app, "version"));
|
||||
metaData->shortDescription = strdup(GetStringValue(app, "short_description"));
|
||||
metaData->longDescription = strdup(GetStringValue(app, "long_description"));
|
||||
|
||||
char release[40];
|
||||
memset(release, 0, sizeof(release));
|
||||
snprintf(release, sizeof(release), "%s", GetStringValue(app, "release_date"));
|
||||
|
||||
if (strlen(release) == 14)
|
||||
snprintf(release, sizeof(release), "%c%c/%c%c/%c%c%c%c", release[4], release[5], release[6], release[7], release[0], release[1], release[2], release[3]);
|
||||
else if (strlen(release) == 14)
|
||||
snprintf(release, sizeof(release), "%c%c/%c%c%c%c", release[4], release[5], release[0], release[1], release[2], release[3]);
|
||||
|
||||
metaData->releaseDate = strdup(release);
|
||||
mxmlDelete(meta);
|
||||
|
||||
return metaData;
|
||||
}
|
||||
|
||||
void FreeMetaData(struct MetaData* metaData)
|
||||
{
|
||||
free(metaData->name);
|
||||
free(metaData->coder);
|
||||
free(metaData->version);
|
||||
free(metaData->shortDescription);
|
||||
free(metaData->longDescription);
|
||||
free(metaData->releaseDate);
|
||||
free(metaData);
|
||||
}
|
||||
|
||||
char* LoadArguments(const char* path, u16* length)
|
||||
{
|
||||
FILE* f = fopen(path, "rb");
|
||||
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
|
||||
mxml_node_t* meta = mxmlLoadFile(NULL, f, MXML_OPAQUE_CALLBACK);
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (!meta)
|
||||
return NULL;
|
||||
|
||||
mxml_node_t* app = mxmlFindElement(meta, meta, "app", NULL, NULL, MXML_DESCEND_FIRST);
|
||||
|
||||
if (!app)
|
||||
{
|
||||
mxmlDelete(meta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
app = mxmlFindElement(app, app, "arguments", NULL, NULL, MXML_DESCEND_FIRST);
|
||||
|
||||
if (!app)
|
||||
{
|
||||
mxmlDelete(meta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mxml_node_t* arg;
|
||||
u16 size = 0;
|
||||
|
||||
for (arg = mxmlFindElement(app, app, "arg", NULL, NULL, MXML_DESCEND_FIRST); arg != NULL; arg = mxmlFindElement(arg, app, "arg", NULL, NULL, MXML_NO_DESCEND))
|
||||
{
|
||||
char* current = GetArgumentValue(arg);
|
||||
|
||||
if (current)
|
||||
{
|
||||
if (size > 0)
|
||||
size++;
|
||||
|
||||
size += strlen(current);
|
||||
}
|
||||
}
|
||||
|
||||
if (size == 0 || size > 1024)
|
||||
{
|
||||
mxmlDelete(meta);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size++;
|
||||
char* argStr = malloc(size);
|
||||
size = 0;
|
||||
|
||||
for (arg = mxmlFindElement(app, app, "arg", NULL, NULL, MXML_DESCEND_FIRST); arg != NULL; arg = mxmlFindElement(arg, app, "arg", NULL, NULL, MXML_NO_DESCEND))
|
||||
{
|
||||
char* current = GetArgumentValue(arg);
|
||||
|
||||
if (current)
|
||||
{
|
||||
if (size > 0)
|
||||
{
|
||||
argStr[size] = 0;
|
||||
size++;
|
||||
}
|
||||
|
||||
strcpy(argStr + size, current);
|
||||
size += strlen(current);
|
||||
}
|
||||
}
|
||||
|
||||
argStr[size] = 0;
|
||||
*length = size;
|
||||
|
||||
return argStr;
|
||||
}
|
20
source/appmetadata.h
Normal file
20
source/appmetadata.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef __APPMETADATA_H__
|
||||
#define __APPMETADATA_H__
|
||||
|
||||
#include <gctypes.h>
|
||||
|
||||
struct MetaData
|
||||
{
|
||||
char* name;
|
||||
char* coder;
|
||||
char* version;
|
||||
char* shortDescription;
|
||||
char* longDescription;
|
||||
char* releaseDate;
|
||||
};
|
||||
|
||||
struct MetaData* LoadMetaData(const char* path);
|
||||
void FreeMetaData(struct MetaData* metaData);
|
||||
char* LoadArguments(const char* path, u16* length);
|
||||
|
||||
#endif
|
@ -19,16 +19,11 @@ bool ExecIsElf(void* address)
|
||||
|
||||
u32 LoadElf(void* address)
|
||||
{
|
||||
//u8* strtab = 0;
|
||||
//u8* image;
|
||||
int i;
|
||||
|
||||
struct Elf32_Ehdr* ehdr = (struct Elf32_Ehdr*)address;
|
||||
struct Elf32_Shdr* shdr = (struct Elf32_Shdr*)(address + ehdr->e_shoff + (ehdr->e_shstrndx * sizeof(struct Elf32_Shdr)));
|
||||
|
||||
//if (shdr->sh_type == SHT_STRTAB)
|
||||
// strtab = (u8*)(addr + shdr->sh_offset);
|
||||
|
||||
for (i = 0; i < ehdr->e_shnum; i++)
|
||||
{
|
||||
shdr = (struct Elf32_Shdr*)(address + ehdr->e_shoff + (i * sizeof(struct Elf32_Shdr)));
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
#include "loaddol.h"
|
||||
#include "loadelf.h"
|
||||
#include "utils.h"
|
||||
|
||||
typedef void (*entrypoint)();
|
||||
|
||||
@ -9,6 +10,8 @@ void _main(void)
|
||||
void* buffer = (void*)0x92000000;
|
||||
entrypoint entry;
|
||||
|
||||
u32 argumentsSize = *(vu32*)0x91000000;
|
||||
|
||||
if (ExecIsElf(buffer))
|
||||
entry = (entrypoint)LoadElf(buffer);
|
||||
else
|
||||
@ -17,5 +20,21 @@ void _main(void)
|
||||
if (!entry)
|
||||
return;
|
||||
|
||||
if (argumentsSize > 0)
|
||||
{
|
||||
u32* ptr = (u32*)entry;
|
||||
|
||||
if (ptr[1] == 0x5F617267)
|
||||
{
|
||||
struct Arguments* argv = (struct Arguments*)&ptr[2];
|
||||
|
||||
argv->magic = 0x5F617267;
|
||||
argv->cmdLine = (char*)0x91000020;
|
||||
argv->length = argumentsSize;
|
||||
|
||||
sync_after_write(&ptr[2], 4);
|
||||
}
|
||||
}
|
||||
|
||||
entry();
|
||||
}
|
@ -29,6 +29,14 @@ typedef volatile signed long long vs64;
|
||||
typedef s32 size_t;
|
||||
typedef u32 u_int32_t;
|
||||
|
||||
|
||||
struct Arguments
|
||||
{
|
||||
int magic;
|
||||
char* cmdLine;
|
||||
int length;
|
||||
};
|
||||
|
||||
#define NULL ((void*)0)
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
Loading…
Reference in New Issue
Block a user