Bemanitools v5.26 release
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
libs += ezusb
|
||||
|
||||
libs_ezusb := \
|
||||
|
||||
src_ezusb := \
|
||||
ezusb.c \
|
||||
util.c \
|
||||
@@ -0,0 +1,122 @@
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
#include "ezusb/ezusb.h"
|
||||
#include "ezusb/ezusbsys2.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
|
||||
static bool ezusb_reset(HANDLE handle, bool hold)
|
||||
{
|
||||
VENDOR_OR_CLASS_REQUEST_CONTROL req;
|
||||
DWORD outpkt;
|
||||
|
||||
/* fml...I can't believe these values are correct. according to
|
||||
the documentation they are wrong D: */
|
||||
|
||||
req.direction = 0xA0;
|
||||
|
||||
if (hold) {
|
||||
req.requestType = 0x00;
|
||||
} else {
|
||||
req.requestType = 0x84;
|
||||
}
|
||||
|
||||
req.recepient = 0x92;
|
||||
|
||||
req.requestTypeReservedBits = 0x7F;
|
||||
req.request = 0x00;
|
||||
req.value = 0x0001;
|
||||
|
||||
if (hold) {
|
||||
req.index = 0x0100;
|
||||
} else {
|
||||
/* release */
|
||||
req.index = 0x0000;
|
||||
}
|
||||
|
||||
if (!DeviceIoControl(handle, IOCTL_Ezusb_VENDOR_REQUEST, &req,
|
||||
sizeof(req), &req, sizeof(req), &outpkt, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ezusb_write_firmware(HANDLE handle, const void* buffer,
|
||||
uint16_t ram_offset, uint32_t size)
|
||||
{
|
||||
ANCHOR_DOWNLOAD_CONTROL req;
|
||||
DWORD outpkt;
|
||||
|
||||
req.Offset = ram_offset;
|
||||
|
||||
if (!DeviceIoControl(handle, IOCTL_EZUSB_ANCHOR_DOWNLOAD, &req,
|
||||
sizeof(req), (void*) buffer, size, &outpkt, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HANDLE ezusb_open(const char* path)
|
||||
{
|
||||
log_assert(path);
|
||||
|
||||
return CreateFileA(path, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
|
||||
OPEN_EXISTING, 0, NULL);
|
||||
}
|
||||
|
||||
bool ezusb_get_ident(HANDLE handle, struct ezusb_ident* ident)
|
||||
{
|
||||
USB_DEVICE_DESCRIPTOR desc;
|
||||
DWORD outpkt;
|
||||
|
||||
log_assert(handle);
|
||||
log_assert(handle != INVALID_HANDLE_VALUE);
|
||||
log_assert(ident);
|
||||
|
||||
if (!DeviceIoControl(handle, IOCTL_Ezusb_GET_DEVICE_DESCRIPTOR, &desc,
|
||||
sizeof(desc), &desc, sizeof(desc), &outpkt, NULL)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(ident->name, 0, sizeof(ident->name));
|
||||
ident->vid = desc.idVendor;
|
||||
ident->pid = desc.idProduct;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ezusb_download_firmware(HANDLE handle, struct ezusb_firmware* fw)
|
||||
{
|
||||
log_assert(handle);
|
||||
log_assert(handle != INVALID_HANDLE_VALUE);
|
||||
log_assert(fw);
|
||||
|
||||
if (!ezusb_reset(handle, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (uint16_t i = 0; i < fw->segment_count; i++) {
|
||||
if (!ezusb_write_firmware(handle, fw->segments[i]->data,
|
||||
fw->segments[i]->offset, fw->segments[i]->size)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ezusb_reset(handle, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ezusb_close(HANDLE handle)
|
||||
{
|
||||
log_assert(handle);
|
||||
log_assert(handle != INVALID_HANDLE_VALUE);
|
||||
|
||||
CloseHandle(handle);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Module for fundamental communication with a legacy Ezusb board, e.g.
|
||||
* IIDX C02 IO.
|
||||
*
|
||||
* This module does not implement any sort of higher level protocol which is
|
||||
* required by the games to exchange data with the device, e.g. getting input
|
||||
* states of keys and setting light outputs. Further modules are utilizing this
|
||||
* base layer to implement higher level communication.
|
||||
*
|
||||
* Note: This module requires the old "cyusb" driver which is NOT compatible
|
||||
* with anything newer than WinXP and does not support 64-bit systems. The newer
|
||||
* "cyusb3" driver does NOT work with this.
|
||||
*
|
||||
* @author icex2
|
||||
*/
|
||||
#ifndef EZUSB_H
|
||||
#define EZUSB_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "ezusb/util.h"
|
||||
|
||||
static const GUID EZUSB_GUID = {0xAE18AA60, 0x7F6A, 0x11D4,
|
||||
{0x97, 0xDD, 0x00, 0x01, 0x02, 0x29, 0xB9, 0x59}};
|
||||
|
||||
/* Used by IIDX instead of scanning for the device */
|
||||
/* static const char* EZUSB_DEFAULT_PATHS[6] = {
|
||||
"\\\\.\\Ezusb-0",
|
||||
"\\\\.\\Ezusb-1",
|
||||
"\\\\.\\Ezusb-2",
|
||||
"\\\\.\\Ezusb-3",
|
||||
"\\\\.\\Ezusb-4",
|
||||
"\\\\.\\Ezusb-5"
|
||||
}; */
|
||||
|
||||
#define EZUSB_DEVICE_PATH "\\\\.\\Ezusb-0"
|
||||
|
||||
/**
|
||||
* Open a connected Ezusb device. Using the old "ezusb" driver on WinXP,
|
||||
* the driver exposes the device to one of the following paths:
|
||||
* \\\\.\\Ezusb-0
|
||||
* \\\\.\\Ezusb-1
|
||||
* \\\\.\\Ezusb-2
|
||||
* \\\\.\\Ezusb-3
|
||||
* \\\\.\\Ezusb-4
|
||||
* \\\\.\\Ezusb-5
|
||||
*
|
||||
* Where \\\\.\\Ezusb-X is used if slot X-1 is still occupied, e.g. when
|
||||
* flashing the device and after a usb re-enumerate.
|
||||
*
|
||||
* @param device_path Path to the Ezusb device.
|
||||
* @return A valid handle to the device on success, INVALID_HANDLE_VALUE on
|
||||
* error.
|
||||
*/
|
||||
HANDLE ezusb_open(const char* path);
|
||||
|
||||
/**
|
||||
* Get identifier information of the device.
|
||||
*
|
||||
* @param handle Valid device handle.
|
||||
* @param ident Pointer to memory to write the identifier information to.
|
||||
* @return True if successful and identifier information was written to the
|
||||
* the struct, false on error.
|
||||
*/
|
||||
bool ezusb_get_ident(HANDLE handle, struct ezusb_ident* ident);
|
||||
|
||||
/**
|
||||
* Download a firmware to the ezusb device.
|
||||
*
|
||||
* @param handle Valid device handle.
|
||||
* @param fw Firmware to write to the target ezusb device.
|
||||
* @return True on success, false on failure.
|
||||
*/
|
||||
bool ezusb_download_firmware(HANDLE handle, struct ezusb_firmware* fw);
|
||||
|
||||
/**
|
||||
* Close an opened ezusb device handle.
|
||||
*
|
||||
* @param handle Valid handle to close.
|
||||
*/
|
||||
void ezusb_close(HANDLE handle);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,39 @@
|
||||
#ifndef EZUSB_EZUSBSYS2_H
|
||||
#define EZUSB_EZUSBSYS2_H
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <usb100.h>
|
||||
|
||||
#include "ezusbsys.h"
|
||||
|
||||
/* can't seem to #include the requisite DDK headers from usermode code,
|
||||
so we have to redefine these macros here */
|
||||
|
||||
#ifndef CTL_CODE
|
||||
#define CTL_CODE( DeviceType, Function, Method, Access ) ( \
|
||||
((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method) \
|
||||
)
|
||||
#endif
|
||||
|
||||
#ifndef FILE_DEVICE_UNKNOWN
|
||||
#define FILE_DEVICE_UNKNOWN 0x00000022
|
||||
#endif
|
||||
|
||||
#ifndef METHOD_BUFFERED
|
||||
#define METHOD_BUFFERED 0
|
||||
#endif
|
||||
|
||||
#ifndef METHOD_IN_DIRECT
|
||||
#define METHOD_IN_DIRECT 1
|
||||
#endif
|
||||
|
||||
#ifndef METHOD_OUT_DIRECT
|
||||
#define METHOD_OUT_DIRECT 2
|
||||
#endif
|
||||
|
||||
#ifndef FILE_ANY_ACCESS
|
||||
#define FILE_ANY_ACCESS 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,167 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ezusb/util.h"
|
||||
|
||||
#include "util/log.h"
|
||||
#include "util/crc.h"
|
||||
#include "util/fs.h"
|
||||
#include "util/mem.h"
|
||||
|
||||
struct ezusb_firmware* ezusb_firmware_load(const char* file)
|
||||
{
|
||||
void* buffer;
|
||||
size_t buffer_size;
|
||||
struct ezusb_firmware* fw;
|
||||
size_t pos;
|
||||
|
||||
log_assert(file);
|
||||
|
||||
pos = 0;
|
||||
|
||||
if (!file_load(file, &buffer, &buffer_size, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fw = xmalloc(sizeof(struct ezusb_firmware));
|
||||
|
||||
fw->crc = ((struct ezusb_firmware*) buffer)->crc;
|
||||
fw->segment_count = ((struct ezusb_firmware*) buffer)->segment_count;
|
||||
|
||||
pos += sizeof(uint16_t) * 2;
|
||||
|
||||
fw->segments = xmalloc(
|
||||
sizeof(struct ezusb_firmware_segment) * fw->segment_count);
|
||||
|
||||
for (uint16_t i = 0; i < fw->segment_count; i++) {
|
||||
uint16_t size = *((uint16_t*) (buffer + pos));
|
||||
pos += sizeof(uint16_t);
|
||||
|
||||
uint16_t offset = *((uint16_t*) (buffer + pos));
|
||||
pos += sizeof(uint16_t);
|
||||
|
||||
fw->segments[i] = xmalloc(sizeof(uint16_t) * 2 + size);
|
||||
|
||||
fw->segments[i]->size = size;
|
||||
fw->segments[i]->offset = offset;
|
||||
memcpy(fw->segments[i]->data, buffer + pos, size);
|
||||
pos += size;
|
||||
}
|
||||
|
||||
return fw;
|
||||
}
|
||||
|
||||
bool ezusb_firmware_save(const char* file, struct ezusb_firmware* fw)
|
||||
{
|
||||
size_t size;
|
||||
void* buffer;
|
||||
size_t pos;
|
||||
bool res;
|
||||
|
||||
log_assert(file);
|
||||
log_assert(fw);
|
||||
|
||||
size = 0;
|
||||
pos = 0;
|
||||
|
||||
for (uint16_t i = 0; i < fw->segment_count; i++) {
|
||||
size += fw->segments[i]->size + sizeof(uint16_t) * 2;
|
||||
}
|
||||
|
||||
size += sizeof(uint16_t) * 2;
|
||||
|
||||
buffer = xmalloc(size);
|
||||
|
||||
((struct ezusb_firmware*) buffer)->crc = fw->crc;
|
||||
((struct ezusb_firmware*) buffer)->segment_count = fw->segment_count;
|
||||
|
||||
pos += sizeof(uint16_t) * 2;
|
||||
|
||||
for (uint16_t i = 0; i < fw->segment_count; i++) {
|
||||
memcpy(buffer + pos, fw->segments[i],
|
||||
sizeof(uint16_t) * 2 + fw->segments[i]->size);
|
||||
pos += sizeof(uint16_t) * 2 + fw->segments[i]->size;
|
||||
}
|
||||
|
||||
res = file_save(file, buffer, size);
|
||||
free(buffer);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
struct ezusb_firmware* ezusb_firmware_alloc()
|
||||
{
|
||||
struct ezusb_firmware* fw;
|
||||
|
||||
fw = xmalloc(sizeof(struct ezusb_firmware));
|
||||
|
||||
fw->crc = 0;
|
||||
fw->segment_count = 0;
|
||||
fw->segments = NULL;
|
||||
|
||||
return fw;
|
||||
}
|
||||
|
||||
struct ezusb_firmware_segment* ezusb_firmware_segment_alloc(uint16_t offset,
|
||||
uint16_t size, void* data)
|
||||
{
|
||||
struct ezusb_firmware_segment* seg;
|
||||
|
||||
log_assert(size > 0);
|
||||
log_assert(data);
|
||||
|
||||
seg = xmalloc(sizeof(uint16_t) * 2 + size);
|
||||
|
||||
seg->offset = offset;
|
||||
seg->size = size;
|
||||
memcpy(seg->data, data, size);
|
||||
|
||||
return seg;
|
||||
}
|
||||
|
||||
void ezusb_firmware_add_segment(struct ezusb_firmware* fw,
|
||||
struct ezusb_firmware_segment* segment)
|
||||
{
|
||||
struct ezusb_firmware_segment** tmp;
|
||||
|
||||
log_assert(fw);
|
||||
log_assert(segment);
|
||||
|
||||
fw->segment_count++;
|
||||
|
||||
tmp = xrealloc(fw->segments,
|
||||
sizeof(struct ezusb_firmware_segment*) * fw->segment_count);
|
||||
|
||||
if (tmp != NULL) {
|
||||
fw->segments = tmp;
|
||||
}
|
||||
|
||||
fw->segments[fw->segment_count - 1] = segment;
|
||||
}
|
||||
|
||||
uint16_t ezusb_firmware_crc(struct ezusb_firmware* fw)
|
||||
{
|
||||
uint16_t crc;
|
||||
|
||||
log_assert(fw);
|
||||
|
||||
crc = 0;
|
||||
|
||||
for (uint16_t i = 0; i < fw->segment_count; i++) {
|
||||
crc = crc16(fw->segments[i],
|
||||
sizeof(uint16_t) * 2 + fw->segments[i]->size, crc);
|
||||
}
|
||||
|
||||
return crc;
|
||||
}
|
||||
|
||||
void ezusb_firmware_free(struct ezusb_firmware* fw)
|
||||
{
|
||||
log_assert(fw);
|
||||
|
||||
for (uint16_t i = 0; i < fw->segment_count; i++) {
|
||||
free(fw->segments[i]);
|
||||
}
|
||||
|
||||
free(fw);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Utility module for ezusb1 (legacy) and ezusb2 (FX2) device handling.
|
||||
*
|
||||
* @author icex2
|
||||
*/
|
||||
#ifndef EZUSB_UTIL_H
|
||||
#define EZUSB_UTIL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Struct with identifier information of the board.
|
||||
*/
|
||||
struct ezusb_ident {
|
||||
char name[256];
|
||||
uint16_t pid;
|
||||
uint16_t vid;
|
||||
};
|
||||
|
||||
/**
|
||||
* A single segment of the firmware.
|
||||
*/
|
||||
struct ezusb_firmware_segment {
|
||||
uint16_t size;
|
||||
uint16_t offset;
|
||||
uint8_t data[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Ezusb firmware struct. Holds the firmware separated into segments.
|
||||
*/
|
||||
struct ezusb_firmware {
|
||||
uint16_t crc;
|
||||
uint16_t segment_count;
|
||||
struct ezusb_firmware_segment** segments;
|
||||
};
|
||||
|
||||
/**
|
||||
* Load a firmware binary file into memory.
|
||||
*
|
||||
* @oaram file Path to firmware binary file.
|
||||
* @return Valid firmware structure on success, NULL on failure.
|
||||
*/
|
||||
struct ezusb_firmware* ezusb_firmware_load(const char* file);
|
||||
|
||||
/**
|
||||
* Save the in-memory firmware to a file.
|
||||
*
|
||||
* @param file Target file to save to.
|
||||
* @param fw Valid firmware structure to store to disk.
|
||||
* @return True on success, false on error.
|
||||
*/
|
||||
bool ezusb_firmware_save(const char* file, struct ezusb_firmware* fw);
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new (empty = no segments) ezusb firmware structure.
|
||||
*
|
||||
* @return Allocated and initialized structure.
|
||||
*/
|
||||
struct ezusb_firmware* ezusb_firmware_alloc();
|
||||
|
||||
/**
|
||||
* Allocate and initialize a new firmware segment.
|
||||
*
|
||||
* @param offset Offset of the segment.
|
||||
* @param size Size of the segment
|
||||
* @param data Pointer to a buffer with firmware data of at least the
|
||||
* specified size.
|
||||
* @return Allocated and initialized structure.
|
||||
*/
|
||||
struct ezusb_firmware_segment* ezusb_firmware_segment_alloc(uint16_t offset,
|
||||
uint16_t size, void* data);
|
||||
|
||||
/**
|
||||
* Add a segment to a firmware structure.
|
||||
*
|
||||
* @param fw Valid firmware structure to add the segment to.
|
||||
* @param segment Valid segment to add to the end of the segment list of the
|
||||
* firmware.
|
||||
*/
|
||||
void ezusb_firmware_add_segment(struct ezusb_firmware* fw,
|
||||
struct ezusb_firmware_segment* segment);
|
||||
|
||||
/**
|
||||
* Calculate the checksum of the provided firmware.
|
||||
*
|
||||
* @param fw Firmware to checksum.
|
||||
* @return CRC16 of firmware.
|
||||
*/
|
||||
uint16_t ezusb_firmware_crc(struct ezusb_firmware* fw);
|
||||
|
||||
/**
|
||||
* Free a previously allocated firmware structure (also cleans up all
|
||||
* referenced segments).
|
||||
*
|
||||
* @param fw Firmware struct to free.
|
||||
*/
|
||||
void ezusb_firmware_free(struct ezusb_firmware* fw);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user