Initial standard implementation (read only)

This commit is contained in:
Ernesto Castellotti 2019-02-08 22:51:12 +01:00
parent 75e43cb653
commit bc2a5ffc0b
5 changed files with 451 additions and 0 deletions

114
.gitignore vendored Normal file
View File

@ -0,0 +1,114 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
# C++ objects and libs
*.slo
*.lo
*.o
*.a
*.la
*.lai
*.so
*.dll
*.dylib
# Qt-es
object_script.*.Release
object_script.*.Debug
*_plugin_import.cpp
/.qmake.cache
/.qmake.stash
*.pro.user
*.pro.user.*
*.qbs.user
*.qbs.user.*
*.moc
moc_*.cpp
moc_*.h
qrc_*.cpp
ui_*.h
*.qmlc
*.jsc
Makefile*
*build-*
# Qt unit tests
target_wrapper.*
# QtCreator
*.autosave
# QtCreator Qml
*.qmlproject.user
*.qmlproject.user.*
# QtCreator CMake
CMakeLists.txt.user*
# QtCreator 4.8< compilation database
compile_commands.json
# QtCreator local machine specific files for imported projects
*creator.user*

35
CMakeLists.txt Normal file
View File

@ -0,0 +1,35 @@
cmake_minimum_required(VERSION 2.8.9)
INCLUDE(CheckIncludeFile)
project(Open-USB-Extreme)
include_directories(include)
# check headers
check_include_file("stdint.h" HAVE_STDINT)
if (HAVE_STDINT)
add_definitions(-DHAVE_STDINT)
endif()
check_include_file("stddef.h" HAVE_STDDEF)
if (HAVE_STDDEF)
add_definitions(-DHAVE_STDDEF)
endif()
file(GLOB SOURCES "lib/*.c")
file(GLOB HEADERS "include/*.h")
file(GLOB EXAMPLE_SOURCES "examples/*.c")
set (CMAKE_CXX_STANDARD 89)
#set(CMAKE_C_FLAGS "-Wall -pedantic -Wextra -Werror")
add_library(${PROJECT_NAME} SHARED ${SOURCES})
add_executable(open-usbextreme-example ${EXAMPLE_SOURCES})
target_link_libraries(open-usbextreme-example ${PROJECT_NAME})
install(TARGETS ${PROJECT_NAME}
LIBRARY DESTINATION lib
)
INSTALL(FILES ${HEADERS}
DESTINATION include
)
INSTALL(TARGETS open-usbextreme-example
RUNTIME DESTINATION bin
)

40
examples/example.c Normal file
View File

@ -0,0 +1,40 @@
#include <stdio.h>
#include <stdlib.h>
#include <usbextreme.h>
int main(int argc, char *argv[]) {
if (argc < 2) {
printf("Usage: open-usbextreme-example <path/to/ul.cfg>\n");
return 1;
}
FILE *f = fopen(argv[1], "rb");
fseek(f, 0, SEEK_END);
long fsize = ftell(f);
if (fsize <= 0) {
return 1;
}
unsigned long size = *(unsigned long*) &fsize;
fseek(f, 0, SEEK_SET);
void *data = malloc(size + 1);
fread(data, size, 1, f);
fclose(f);
usb_extreme_headers headers;
if(oue_read_headers(&headers, data, size) <= 0) {
return 1;
}
usb_extreme_filestat filestats[10];
int nstats = oue_read(filestats, headers, 10);
int i;
for(i = 0; i < nstats; i++) {
printf("Game name [%d]: %s\n", filestats[i].offset, filestats[i].name);
}
return 0;
}

119
include/usbextreme.h Normal file
View File

@ -0,0 +1,119 @@
#ifndef USBEXTREME_H
#define USBEXTREME_H
#ifndef u8
#if HAVE_STDINT
#include <stdint.h>
typedef uint8_t u8;
typedef uint16_t u16;
#else
#error "u8 and u16 types have not been defined and missing stdint.h, please define your implementation of u8 and u16"
#endif
#endif
#ifndef size_t
#if HAVE_STDDEF
#include <stddef.h>
#else
#error "size_t type has not been defined and missing stddef.h, please define your implementation of size_t"
#endif
#endif
#define USBEXTREME_NAME_LENGTH 32
#define USBEXTREME_ID_LENGTH 15
#define USBEXTREME_NAME_EXT_LENGTH 10
#define USBEXTREME_MAGIC 0x08
typedef enum {
SCECdGDTFUNCFAIL = -1,
SCECdNODISC = 0x00,
SCECdDETCT,
SCECdDETCTCD,
SCECdDETCTDVDS,
SCECdDETCTDVDD,
SCECdUNKNOWN,
SCECdPSCD = 0x10,
SCECdPSCDDA,
SCECdPS2CD,
SCECdPS2CDDA,
SCECdPS2DVD,
SCECdCDDA = 0xFD,
SCECdDVDV,
SCECdIllegalMediaoffset
} SCECdvdMediaType;
typedef enum {
USB_EXTREME_V0 = 0x00,
USB_EXTREME_V1
} usb_extreme_versions;
typedef struct __attribute__((__packed__)) {
u8 empty[6 + USBEXTREME_ID_LENGTH + USBEXTREME_NAME_LENGTH];
u8 magic;
u8 empty2[10];
} usb_extreme_base;
typedef struct __attribute__((__packed__)) {
char name[USBEXTREME_NAME_LENGTH];
char id[USBEXTREME_ID_LENGTH];
u8 n_parts;
u8 type;
u8 empty[4];
u8 magic;
u8 empty2[USBEXTREME_NAME_EXT_LENGTH];
} usb_extreme_v0;
typedef struct __attribute__((__packed__)) {
char name[USBEXTREME_NAME_LENGTH];
char id[USBEXTREME_ID_LENGTH];
u8 n_parts;
u8 type;
u16 size;
u8 video_mode;
u8 usb_extreme_version;
u8 magic;
char name_ext[USBEXTREME_NAME_EXT_LENGTH];
} usb_extreme_v1;
typedef struct {
int offset;
char name[USBEXTREME_NAME_LENGTH + USBEXTREME_NAME_EXT_LENGTH];
SCECdvdMediaType type;
u16 size;
u8 video_mode;
usb_extreme_versions usb_extreme_version;
} usb_extreme_filestat;
typedef struct {
void *first_header;
usb_extreme_base *headers;
int num_headers;
size_t headerslen;
usb_extreme_versions version;
} usb_extreme_headers;
#define USBEXTREME_HEADER_SIZE sizeof(usb_extreme_base)
/* Global headers functions */
int is_oue(const void *headers, const size_t headerslen);
usb_extreme_versions get_version(u8 version);
int oue_point_headers(usb_extreme_base **headers, void *raw_headers, size_t headerslen);
int oue_num_headers(int *num_headers, const void *headers, size_t headerslen);
int oue_version(usb_extreme_versions *version, const void *headers, size_t headerslen);
int oue_read_headers(usb_extreme_headers *headers, void *raw_headers, const size_t headerslen);
/* Read functions */
int oue_read(usb_extreme_filestat *filestats, const usb_extreme_headers headers, const int filestats_nlen);
/* implementation in development
*
int oue_add(usb_extreme_headers *headers, const usb_extreme_filestat filestat);
int oue_edit(usb_extreme_headers *headers, const usb_extreme_filestat filestat);
int oue_remove(usb_extreme_headers *headers, const usb_extreme_filestat filestat);
*/
#endif /* !USBEXTREME_H */

143
lib/usbextreme.c Normal file
View File

@ -0,0 +1,143 @@
#include <usbextreme.h>
#include <string.h>
int is_oue(const void *headers, const size_t headerslen) {
const usb_extreme_base *headers_oeu = headers;
int headers_nlen = (int) (headerslen / USBEXTREME_HEADER_SIZE);
int i;
for(i = 0; i < headers_nlen; i++) {
const usb_extreme_base header = headers_oeu[i];
if (header.magic != USBEXTREME_MAGIC) {
return 0;
}
}
return 1;
}
usb_extreme_versions get_version(u8 version) {
switch (version) {
case 0: {
return USB_EXTREME_V0;
}
case 1: {
return USB_EXTREME_V1;
}
default: {
return USB_EXTREME_V1;
}
}
}
int oue_point_headers(usb_extreme_base **headers, void *raw_headers, size_t headerslen) {
int headers_nlen;
if (oue_num_headers(&headers_nlen, raw_headers, headerslen) <= 0) {
return -1;
}
*headers = raw_headers;
return headers_nlen;
}
int oue_num_headers(int *num_headers, const void *headers, size_t headerslen) {
int headers_nlen = (int) (headerslen / USBEXTREME_HEADER_SIZE);
if (!is_oue(headers, headerslen)) {
return -1;
}
*num_headers = headers_nlen;
return headers_nlen;
}
int oue_version(usb_extreme_versions *version, const void *headers, size_t headerslen) {
const usb_extreme_v1 *headers_oeu = headers;
int headers_nlen = (int) (headerslen / USBEXTREME_HEADER_SIZE);
usb_extreme_versions first_version = USB_EXTREME_V0;
int i;
if(!is_oue(headers, headerslen)) {
return -1;
}
for(i = 0; i < headers_nlen; i++) {
const usb_extreme_v1 header = headers_oeu[i];
if (i == 0) {
first_version = get_version(header.usb_extreme_version);
} else {
if (first_version != get_version(header.usb_extreme_version)) {
*version = USB_EXTREME_V0;
return -2;
}
}
}
*version = first_version;
return 1;
}
int oue_read_headers(usb_extreme_headers *headers, void *raw_headers, const size_t headerslen) {
usb_extreme_base *headers_ptr;
usb_extreme_versions version;
int num_headers = (int) (headerslen / USBEXTREME_HEADER_SIZE);
usb_extreme_headers headers_temp = {NULL, NULL, 0, 0, 0};
if(oue_point_headers(&headers_ptr, raw_headers, headerslen) <= 0) {
return -1;
}
if(oue_version(&version, raw_headers, headerslen) <= 0) {
return -1;
}
headers_temp.first_header = raw_headers;
headers_temp.headers = headers_ptr;
headers_temp.num_headers = num_headers;
headers_temp.headerslen = headerslen;
headers_temp.version = version;
*headers = headers_temp;
return 1;
}
int oue_read(usb_extreme_filestat *filestat, const usb_extreme_headers headers, const int filestats_nlen) {
int offset = filestats_nlen;
usb_extreme_v1 *headers_full = (usb_extreme_v1*) headers.headers;
usb_extreme_v1 header;
usb_extreme_filestat filestats_temp = {0, {'0'}, 0, 0, 0, 0};
u16 size = 0;
u8 video_mode = 0;
u8 usb_extreme_version;
int i;
for(i = 0; i < headers.num_headers; i++) {
if(offset == 0) {
return i;
}
header = headers_full[i];
strncpy(filestats_temp.name, header.name, USBEXTREME_NAME_LENGTH);
usb_extreme_version = header.usb_extreme_version;
if(usb_extreme_version >= 1) {
size = header.size;
video_mode = header.video_mode;
strncat(filestats_temp.name, header.name_ext, USBEXTREME_NAME_EXT_LENGTH);
}
filestats_temp.size = size;
filestats_temp.type = header.type;
filestats_temp.offset = i;
filestats_temp.video_mode = video_mode;
filestats_temp.usb_extreme_version = usb_extreme_version;
filestat[i] = filestats_temp;
offset -= 1;
}
return i;
}