mirror of
https://github.com/ErnyTech/Open-USB-Extreme
synced 2025-02-11 08:06:48 +01:00
224 lines
5.8 KiB
D
224 lines
5.8 KiB
D
module usbextreme;
|
|
import std.stdint;
|
|
|
|
enum USBEXTREME_NAME_LENGTH = 32;
|
|
enum USBEXTREME_ID_LENGTH = 15;
|
|
enum USBEXTREME_NAME_EXT_LENGTH = 10;
|
|
enum USBEXTREME_MAGIC = 0x08;
|
|
enum USBEXTREME_HEADER_SIZE = usb_extreme_base.sizeof;
|
|
|
|
align(1) struct usb_extreme_base {
|
|
align(1):
|
|
uint8_t[6 + USBEXTREME_ID_LENGTH + USBEXTREME_NAME_LENGTH] empty;
|
|
uint8_t magic;
|
|
uint8_t[10] empty2;
|
|
}
|
|
|
|
align(1) struct usb_extreme_v0 {
|
|
align(1):
|
|
char[USBEXTREME_NAME_LENGTH] name;
|
|
char[USBEXTREME_ID_LENGTH] id;
|
|
uint8_t n_parts;
|
|
uint8_t type;
|
|
uint8_t[4] empty;
|
|
uint8_t magic;
|
|
uint8_t[USBEXTREME_NAME_EXT_LENGTH] empty2;
|
|
}
|
|
|
|
align(1) struct usb_extreme_v1 {
|
|
align(1):
|
|
char[USBEXTREME_NAME_LENGTH] name;
|
|
char[USBEXTREME_ID_LENGTH] id;
|
|
uint8_t n_parts;
|
|
uint8_t type;
|
|
uint16_t size;
|
|
uint8_t video_mode;
|
|
uint8_t usb_extreme_version;
|
|
uint8_t magic;
|
|
char[USBEXTREME_NAME_EXT_LENGTH] name_ext;
|
|
}
|
|
|
|
struct usb_extreme_headers {
|
|
const(void)* first_header;
|
|
const(usb_extreme_base)* headers;
|
|
int num_headers;
|
|
size_t headerslen;
|
|
UsbExtremeVersion oueVersion;
|
|
}
|
|
|
|
struct usb_extreme_filestat {
|
|
int offset;
|
|
char[USBEXTREME_NAME_LENGTH + USBEXTREME_NAME_EXT_LENGTH] name;
|
|
SCECdvdMediaType type;
|
|
uint16_t size;
|
|
uint8_t video_mode;
|
|
UsbExtremeVersion usb_extreme_version;
|
|
}
|
|
|
|
enum UsbExtremeVersion {
|
|
V0 = 0x00,
|
|
V1
|
|
}
|
|
|
|
enum SCECdvdMediaType {
|
|
SCECdGDTFUNCFAIL = -1,
|
|
SCECdNODISC = 0x00,
|
|
SCECdDETCT,
|
|
SCECdDETCTCD,
|
|
SCECdDETCTDVDS,
|
|
SCECdDETCTDVDD,
|
|
SCECdUNKNOWN,
|
|
|
|
SCECdPSCD = 0x10,
|
|
SCECdPSCDDA,
|
|
SCECdPS2CD,
|
|
SCECdPS2CDDA,
|
|
SCECdPS2DVD,
|
|
|
|
SCECdCDDA = 0xFD,
|
|
SCECdDVDV,
|
|
SCECdIllegalMediaoffset
|
|
}
|
|
|
|
extern(C) int isOue(const(void)* headers, size_t headerslen) {
|
|
const headers_oeu = cast(const usb_extreme_base*) headers;
|
|
auto headers_nlen = headerslen / USBEXTREME_HEADER_SIZE;
|
|
|
|
for (auto i = 0; i < headers_nlen; i++) {
|
|
auto header = headers_oeu[i];
|
|
|
|
if (header.magic != USBEXTREME_MAGIC) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
extern(D) UsbExtremeVersion getVersion(uint8_t usbExtremeVersion) {
|
|
switch (usbExtremeVersion) {
|
|
case 0: {
|
|
return UsbExtremeVersion.V0;
|
|
}
|
|
|
|
case 1: {
|
|
return UsbExtremeVersion.V1;
|
|
}
|
|
|
|
default: {
|
|
return UsbExtremeVersion.V1;
|
|
}
|
|
}
|
|
}
|
|
|
|
extern(D) int oueNumHeaders(ref int num_headers, const(void) *headers, size_t headerslen) {
|
|
auto headers_nlen = cast(int) (headerslen / USBEXTREME_HEADER_SIZE);
|
|
|
|
if (!isOue(headers, headerslen)) {
|
|
return -1;
|
|
}
|
|
|
|
num_headers = headers_nlen;
|
|
return headers_nlen;
|
|
}
|
|
|
|
extern(D) int ouePointHeaders(ref const(usb_extreme_base)* headers, const(void)* raw_headers, size_t headerslen) {
|
|
int headers_nlen;
|
|
|
|
if (oueNumHeaders(headers_nlen, raw_headers, headerslen) <= 0) {
|
|
return -1;
|
|
}
|
|
|
|
headers = cast(const(usb_extreme_base)*) raw_headers;
|
|
return headers_nlen;
|
|
}
|
|
|
|
extern(D) int oueHeadersVersion(ref UsbExtremeVersion oueVersion, const(void) *headers, size_t headerslen) {
|
|
auto headers_oeu = cast(usb_extreme_v1*) headers;
|
|
auto headers_nlen = headerslen / USBEXTREME_HEADER_SIZE;
|
|
auto first_version = UsbExtremeVersion.V0;
|
|
int i;
|
|
|
|
if(!isOue(headers, headerslen)) {
|
|
return -1;
|
|
}
|
|
|
|
for(i = 0; i < headers_nlen; i++) {
|
|
auto header = headers_oeu[i];
|
|
|
|
if (i == 0) {
|
|
first_version = getVersion(header.usb_extreme_version);
|
|
} else {
|
|
if (first_version != getVersion(header.usb_extreme_version)) {
|
|
oueVersion = UsbExtremeVersion.V0;
|
|
return -2;
|
|
}
|
|
}
|
|
}
|
|
|
|
oueVersion = first_version;
|
|
return 1;
|
|
}
|
|
|
|
extern(D) int oueReadHeaders(ref usb_extreme_headers headers, const(void)* raw_headers, size_t headerslen) {
|
|
const(usb_extreme_base)* headers_ptr;
|
|
UsbExtremeVersion oueVersion;
|
|
auto num_headers = cast(int) (headerslen / USBEXTREME_HEADER_SIZE);
|
|
usb_extreme_headers headers_temp = {null, null, 0, 0, UsbExtremeVersion.V0};
|
|
|
|
if (ouePointHeaders(headers_ptr, raw_headers, headerslen) <= 0) {
|
|
return -1;
|
|
}
|
|
|
|
if (oueHeadersVersion(oueVersion, 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.oueVersion = oueVersion;
|
|
headers = headers_temp;
|
|
return 1;
|
|
}
|
|
|
|
extern(D) int oueRead(usb_extreme_filestat[] filestat, const(usb_extreme_headers) headers) {
|
|
import core.stdc.string : strncpy, strncat;
|
|
|
|
int offset = cast(int) filestat.length;
|
|
auto headers_full = cast(usb_extreme_v1*) headers.headers;
|
|
usb_extreme_v1 header;
|
|
usb_extreme_filestat filestats_temp = {0, ['0'], SCECdvdMediaType.SCECdNODISC, 0, 0, UsbExtremeVersion.V0};
|
|
uint16_t size = 0;
|
|
uint8_t video_mode = 0;
|
|
uint8_t 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.ptr, header.name.ptr, 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.ptr, header.name_ext.ptr, USBEXTREME_NAME_EXT_LENGTH);
|
|
}
|
|
|
|
filestats_temp.size = size;
|
|
filestats_temp.type = cast(SCECdvdMediaType) header.type;
|
|
filestats_temp.offset = i;
|
|
filestats_temp.video_mode = video_mode;
|
|
filestats_temp.usb_extreme_version = cast(UsbExtremeVersion) usb_extreme_version;
|
|
filestat[i] = filestats_temp;
|
|
offset -= 1;
|
|
}
|
|
|
|
return i;
|
|
}
|