add idmac hooks
This commit is contained in:
parent
1922d7f3a6
commit
3ae24469fa
@ -11,9 +11,12 @@ $(BUILD_DIR_ZIP)/siva.zip:
|
||||
$(BUILD_DIR_ZIP)/siva/sivahook_32.dll
|
||||
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
|
||||
$(BUILD_DIR_64)/sivahook/sivahook.dll \
|
||||
$(BUILD_DIR_64)/idmac_stub/iDmacDrv.dll \
|
||||
$(DIST_DIR)/siva/taitools.ini \
|
||||
$(DIST_DIR)/siva/start.bat \
|
||||
$(BUILD_DIR_ZIP)/siva
|
||||
$(V)mv $(BUILD_DIR_ZIP)/siva/iDmacDrv.dll \
|
||||
$(BUILD_DIR_ZIP)/siva/iDmacDrv64.dll
|
||||
$(V)cp pki/billing.pub \
|
||||
pki/ca.crt \
|
||||
$(BUILD_DIR_ZIP)/siva/DEVICE
|
||||
|
@ -8,64 +8,7 @@
|
||||
|
||||
#include "idmac/idmac.h"
|
||||
#include "idmac/config.h"
|
||||
#include "idmac/ds.h"
|
||||
#include "idmac/eeprom.h"
|
||||
#include "idmac/gpio.h"
|
||||
#include "idmac/jvs.h"
|
||||
#include "idmac/sram.h"
|
||||
|
||||
void ds_config_load(struct ds_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"ds", L"enable", 1, filename);
|
||||
cfg->region = GetPrivateProfileIntW(L"ds", L"region", 1, filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"ds",
|
||||
L"serialNo",
|
||||
L"AAVE-01A99999999",
|
||||
cfg->serial_no,
|
||||
_countof(cfg->serial_no),
|
||||
filename);
|
||||
}
|
||||
|
||||
void eeprom_config_load(struct eeprom_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"eeprom", L"enable", 1, filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"eeprom",
|
||||
L"path",
|
||||
L"DEVICE\\eeprom.bin",
|
||||
cfg->path,
|
||||
_countof(cfg->path),
|
||||
filename);
|
||||
}
|
||||
|
||||
void gpio_config_load(struct gpio_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
wchar_t name[7];
|
||||
size_t i;
|
||||
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"gpio", L"enable", 1, filename);
|
||||
cfg->vk_sw1 = GetPrivateProfileIntW(L"gpio", L"sw1", VK_F1, filename);
|
||||
cfg->vk_sw2 = GetPrivateProfileIntW(L"gpio", L"sw2", VK_F2, filename);
|
||||
|
||||
wcscpy_s(name, _countof(name), L"dipsw0");
|
||||
|
||||
for (i = 0 ; i < 8 ; i++) {
|
||||
name[5] = L'1' + i;
|
||||
cfg->dipsw[i] = GetPrivateProfileIntW(L"gpio", name, 0, filename);
|
||||
}
|
||||
}
|
||||
|
||||
void jvs_config_load(struct jvs_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
@ -75,30 +18,10 @@ void jvs_config_load(struct jvs_config *cfg, const wchar_t *filename)
|
||||
cfg->enable = GetPrivateProfileIntW(L"jvs", L"enable", 1, filename);
|
||||
}
|
||||
|
||||
void sram_config_load(struct sram_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
cfg->enable = GetPrivateProfileIntW(L"sram", L"enable", 1, filename);
|
||||
|
||||
GetPrivateProfileStringW(
|
||||
L"sram",
|
||||
L"path",
|
||||
L"DEVICE\\sram.bin",
|
||||
cfg->path,
|
||||
_countof(cfg->path),
|
||||
filename);
|
||||
}
|
||||
|
||||
void idmac_config_load(struct idmac_config *cfg, const wchar_t *filename)
|
||||
{
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
ds_config_load(&cfg->ds, filename);
|
||||
eeprom_config_load(&cfg->eeprom, filename);
|
||||
gpio_config_load(&cfg->gpio, filename);
|
||||
jvs_config_load(&cfg->jvs, filename);
|
||||
sram_config_load(&cfg->sram, filename);
|
||||
}
|
||||
|
@ -7,15 +7,7 @@
|
||||
#include <stdint.h>
|
||||
|
||||
#include "idmac/idmac.h"
|
||||
#include "idmac/ds.h"
|
||||
#include "idmac/eeprom.h"
|
||||
#include "idmac/gpio.h"
|
||||
#include "idmac/jvs.h"
|
||||
#include "idmac/sram.h"
|
||||
|
||||
void ds_config_load(struct ds_config *cfg, const wchar_t *filename);
|
||||
void eeprom_config_load(struct eeprom_config *cfg, const wchar_t *filename);
|
||||
void gpio_config_load(struct gpio_config *cfg, const wchar_t *filename);
|
||||
void jvs_config_load(struct jvs_config *cfg, const wchar_t *filename);
|
||||
void sram_config_load(struct sram_config *cfg, const wchar_t *filename);
|
||||
void idmac_config_load(struct idmac_config *cfg, const wchar_t *filename);
|
||||
|
214
idmac/ds.c
214
idmac/ds.c
@ -1,214 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <devioctl.h>
|
||||
#include <ntdddisk.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "idmac/ds.h"
|
||||
#include "idmac/nvram.h"
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
#include "util/crc.h"
|
||||
#include "util/dprintf.h"
|
||||
#include "util/str.h"
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
enum {
|
||||
DS_IOCTL_GET_ABI_VERSION = 0x80006000,
|
||||
DS_IOCTL_SETUP = 0x80006004,
|
||||
DS_IOCTL_READ_SECTOR = 0x80006010,
|
||||
};
|
||||
|
||||
struct ds_eeprom {
|
||||
uint32_t crc32;
|
||||
uint8_t unk_04[4];
|
||||
uint8_t region;
|
||||
char serial_no[17];
|
||||
uint8_t unk_1A[6];
|
||||
};
|
||||
|
||||
static_assert(sizeof(struct ds_eeprom) == 0x20, "DS EEPROM size");
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
static HRESULT ds_handle_irp(struct irp *irp);
|
||||
static HRESULT ds_handle_open(struct irp *irp);
|
||||
static HRESULT ds_handle_close(struct irp *irp);
|
||||
static HRESULT ds_handle_ioctl(struct irp *irp);
|
||||
|
||||
static HRESULT ds_ioctl_get_geometry(struct irp *irp);
|
||||
static HRESULT ds_ioctl_get_abi_version(struct irp *irp);
|
||||
static HRESULT ds_ioctl_setup(struct irp *irp);
|
||||
static HRESULT ds_ioctl_read_sector(struct irp *irp);
|
||||
|
||||
static struct ds_eeprom ds_eeprom;
|
||||
static HANDLE ds_fd;
|
||||
|
||||
HRESULT ds_hook_init(const struct ds_config *cfg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
memset(&ds_eeprom, 0, sizeof(ds_eeprom));
|
||||
|
||||
wcstombs_s(
|
||||
NULL,
|
||||
ds_eeprom.serial_no,
|
||||
_countof(ds_eeprom.serial_no),
|
||||
cfg->serial_no,
|
||||
_countof(cfg->serial_no) - 1);
|
||||
|
||||
ds_eeprom.region = cfg->region;
|
||||
ds_eeprom.crc32 = crc32(&ds_eeprom.unk_04, 0x1C, 0);
|
||||
|
||||
hr = iohook_push_handler(ds_handle_irp);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = setupapi_add_phantom_dev(&ds_guid, L"$ds");
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = iohook_open_nul_fd(&ds_fd);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ds_handle_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != ds_fd) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return ds_handle_open(irp);
|
||||
case IRP_OP_CLOSE: return ds_handle_close(irp);
|
||||
case IRP_OP_IOCTL: return ds_handle_ioctl(irp);
|
||||
default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT ds_handle_open(struct irp *irp)
|
||||
{
|
||||
if (!wstr_eq(irp->open_filename, L"$ds")) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
dprintf("DS: Open device\n");
|
||||
irp->fd = ds_fd;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ds_handle_close(struct irp *irp)
|
||||
{
|
||||
dprintf("DS: Close device\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ds_handle_ioctl(struct irp *irp)
|
||||
{
|
||||
switch (irp->ioctl) {
|
||||
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
|
||||
return ds_ioctl_get_geometry(irp);
|
||||
|
||||
case DS_IOCTL_GET_ABI_VERSION:
|
||||
return ds_ioctl_get_abi_version(irp);
|
||||
|
||||
case DS_IOCTL_SETUP:
|
||||
return ds_ioctl_setup(irp);
|
||||
|
||||
case DS_IOCTL_READ_SECTOR:
|
||||
return ds_ioctl_read_sector(irp);
|
||||
|
||||
default:
|
||||
dprintf("DS: Unknown ioctl %08x, write %i read %i\n",
|
||||
irp->ioctl,
|
||||
(int) irp->write.nbytes,
|
||||
(int) irp->read.nbytes);
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT ds_ioctl_get_geometry(struct irp *irp)
|
||||
{
|
||||
DISK_GEOMETRY out;
|
||||
HRESULT hr;
|
||||
|
||||
dprintf("DS: Get geometry\n");
|
||||
|
||||
memset(&out, 0, sizeof(out));
|
||||
out.Cylinders.QuadPart = 1;
|
||||
out.MediaType = 0;
|
||||
out.TracksPerCylinder = 1;
|
||||
out.SectorsPerTrack = 2;
|
||||
out.BytesPerSector = 32;
|
||||
|
||||
hr = iobuf_write(&irp->read, &out, sizeof(out));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("DS: Get geometry failed: %08x\n", (int) hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT ds_ioctl_get_abi_version(struct irp *irp)
|
||||
{
|
||||
return iobuf_write_le16(&irp->read, 256);
|
||||
}
|
||||
|
||||
static HRESULT ds_ioctl_setup(struct irp *irp)
|
||||
{
|
||||
dprintf("DS: Setup IOCTL\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT ds_ioctl_read_sector(struct irp *irp)
|
||||
{
|
||||
struct const_iobuf src;
|
||||
uint32_t sector_no;
|
||||
HRESULT hr;
|
||||
|
||||
hr = iobuf_read_le32(&irp->write, §or_no);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
dprintf("DS: Read sector %08x\n", sector_no);
|
||||
|
||||
src.bytes = (const uint8_t *) &ds_eeprom;
|
||||
src.nbytes = sizeof(ds_eeprom);
|
||||
src.pos = 0;
|
||||
|
||||
iobuf_move(&irp->read, &src);
|
||||
|
||||
return S_OK;
|
||||
}
|
22
idmac/ds.h
22
idmac/ds.h
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct ds_config {
|
||||
bool enable;
|
||||
uint8_t region;
|
||||
wchar_t serial_no[17];
|
||||
};
|
||||
|
||||
DEFINE_GUID(
|
||||
ds_guid,
|
||||
0x279A9F67,
|
||||
0x348F,
|
||||
0x41C9,
|
||||
0xA4, 0xC4, 0xDF, 0xDB, 0x8A, 0xE8, 0xE5, 0xE0);
|
||||
|
||||
HRESULT ds_hook_init(const struct ds_config *cfg);
|
194
idmac/eeprom.c
194
idmac/eeprom.c
@ -1,194 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <ntdef.h>
|
||||
#else
|
||||
#include <winnt.h>
|
||||
#endif
|
||||
#include <devioctl.h>
|
||||
#include <ntdddisk.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "idmac/eeprom.h"
|
||||
#include "idmac/nvram.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/str.h"
|
||||
|
||||
enum {
|
||||
EEPROM_IOCTL_GET_ABI_VERSION = 0x80006000,
|
||||
};
|
||||
|
||||
static HRESULT eeprom_handle_irp(struct irp *irp);
|
||||
static HRESULT eeprom_handle_open(struct irp *irp);
|
||||
static HRESULT eeprom_handle_close(struct irp *irp);
|
||||
static HRESULT eeprom_handle_ioctl(struct irp *irp);
|
||||
static HRESULT eeprom_handle_read(struct irp *irp);
|
||||
static HRESULT eeprom_handle_write(struct irp *irp);
|
||||
|
||||
static HRESULT eeprom_ioctl_get_geometry(struct irp *irp);
|
||||
static HRESULT eeprom_ioctl_get_abi_version(struct irp *irp);
|
||||
|
||||
static struct eeprom_config eeprom_config;
|
||||
static HANDLE eeprom_file;
|
||||
|
||||
HRESULT eeprom_hook_init(const struct eeprom_config *cfg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
memcpy(&eeprom_config, cfg, sizeof(*cfg));
|
||||
|
||||
hr = iohook_push_handler(eeprom_handle_irp);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = setupapi_add_phantom_dev(&eeprom_guid, L"$eeprom");
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT eeprom_handle_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != eeprom_file) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return eeprom_handle_open(irp);
|
||||
case IRP_OP_CLOSE: return eeprom_handle_close(irp);
|
||||
case IRP_OP_IOCTL: return eeprom_handle_ioctl(irp);
|
||||
case IRP_OP_READ: return eeprom_handle_read(irp);
|
||||
case IRP_OP_WRITE: return eeprom_handle_write(irp);
|
||||
default: return iohook_invoke_next(irp);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT eeprom_handle_open(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!wstr_eq(irp->open_filename, L"$eeprom") != 0) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
if (eeprom_file != NULL) {
|
||||
dprintf("EEPROM: Already open\n");
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
|
||||
}
|
||||
|
||||
dprintf("EEPROM: Open device\n");
|
||||
hr = nvram_open_file(&eeprom_file, eeprom_config.path, 0x2000);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
irp->fd = eeprom_file;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT eeprom_handle_close(struct irp *irp)
|
||||
{
|
||||
dprintf("EEPROM: Close device\n");
|
||||
eeprom_file = NULL;
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT eeprom_handle_ioctl(struct irp *irp)
|
||||
{
|
||||
switch (irp->ioctl) {
|
||||
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
|
||||
return eeprom_ioctl_get_geometry(irp);
|
||||
|
||||
case EEPROM_IOCTL_GET_ABI_VERSION:
|
||||
return eeprom_ioctl_get_abi_version(irp);
|
||||
|
||||
default:
|
||||
dprintf("EEPROM: Unknown ioctl %x, write %i read %i\n",
|
||||
irp->ioctl,
|
||||
(int) irp->write.nbytes,
|
||||
(int) irp->read.nbytes);
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT eeprom_ioctl_get_geometry(struct irp *irp)
|
||||
{
|
||||
DISK_GEOMETRY out;
|
||||
HRESULT hr;
|
||||
|
||||
dprintf("EEPROM: Get geometry\n");
|
||||
|
||||
memset(&out, 0, sizeof(out));
|
||||
out.Cylinders.QuadPart = 1;
|
||||
out.MediaType = FixedMedia;
|
||||
out.TracksPerCylinder = 224;
|
||||
out.SectorsPerTrack = 32;
|
||||
out.BytesPerSector = 1;
|
||||
|
||||
hr = iobuf_write(&irp->read, &out, sizeof(out));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("EEPROM: Get geometry failed: %08x\n", (int) hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT eeprom_ioctl_get_abi_version(struct irp *irp)
|
||||
{
|
||||
return iobuf_write_le16(&irp->read, 256);
|
||||
}
|
||||
|
||||
static HRESULT eeprom_handle_read(struct irp *irp)
|
||||
{
|
||||
if (irp->ovl == NULL) {
|
||||
dprintf("EEPROM: Synchronous read..?\n");
|
||||
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
dprintf("EEPROM: Read off %x len %x\n",
|
||||
(int) irp->ovl->Offset,
|
||||
(int) irp->read.nbytes);
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT eeprom_handle_write(struct irp *irp)
|
||||
{
|
||||
if (irp->ovl == NULL) {
|
||||
dprintf("EEPROM: Synchronous write..?\n");
|
||||
|
||||
return E_UNEXPECTED;
|
||||
}
|
||||
|
||||
dprintf("EEPROM: Write off %x len %x\n",
|
||||
(int) irp->ovl->Offset,
|
||||
(int) irp->write.nbytes);
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct eeprom_config {
|
||||
bool enable;
|
||||
wchar_t path[MAX_PATH];
|
||||
};
|
||||
|
||||
DEFINE_GUID(
|
||||
eeprom_guid,
|
||||
0xB7970F0C,
|
||||
0x31C4,
|
||||
0x45FF,
|
||||
0x96, 0x18, 0x0A, 0x24, 0x00, 0x94, 0xB2, 0x71);
|
||||
|
||||
HRESULT eeprom_hook_init(const struct eeprom_config *cfg);
|
228
idmac/gpio.c
228
idmac/gpio.c
@ -1,228 +0,0 @@
|
||||
#include <windows.h>
|
||||
#include <ntstatus.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "idmac/gpio.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/str.h"
|
||||
|
||||
enum {
|
||||
GPIO_IOCTL_SET_LEDS = 0x8000A004,
|
||||
GPIO_IOCTL_GET_PSW = 0x80006008,
|
||||
GPIO_IOCTL_GET_DIPSW = 0x8000600C,
|
||||
GPIO_IOCTL_DESCRIBE = 0x80006014,
|
||||
};
|
||||
|
||||
enum {
|
||||
GPIO_TYPE_NONE = 0,
|
||||
GPIO_TYPE_LED = 1,
|
||||
GPIO_TYPE_DIPSW = 2,
|
||||
GPIO_TYPE_PSW = 3,
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct gpio_port {
|
||||
uint8_t unknown;
|
||||
|
||||
/* Number of distinct instances of this thing..? */
|
||||
uint8_t count;
|
||||
|
||||
/* Type of GPIO port */
|
||||
uint16_t type;
|
||||
};
|
||||
|
||||
struct gpio_ports {
|
||||
uint8_t unknown; /* Maybe a count of valid items in the array idk */
|
||||
struct gpio_port ports[32];
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
static HRESULT gpio_handle_irp(struct irp *irp);
|
||||
static HRESULT gpio_handle_open(struct irp *irp);
|
||||
static HRESULT gpio_handle_close(struct irp *irp);
|
||||
static HRESULT gpio_handle_ioctl(struct irp *irp);
|
||||
|
||||
static HRESULT gpio_ioctl_get_psw(struct irp *irp);
|
||||
static HRESULT gpio_ioctl_get_dipsw(struct irp *irp);
|
||||
static HRESULT gpio_ioctl_describe(struct irp *irp);
|
||||
static HRESULT gpio_ioctl_set_leds(struct irp *irp);
|
||||
|
||||
static const struct gpio_ports gpio_ports = {
|
||||
.ports = {
|
||||
{
|
||||
.type = GPIO_TYPE_LED,
|
||||
.count = 2,
|
||||
}, {
|
||||
.type = GPIO_TYPE_DIPSW,
|
||||
.count = 8,
|
||||
}, {
|
||||
.type = GPIO_TYPE_PSW,
|
||||
.count = 2,
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
static_assert(sizeof(gpio_ports) == 129, "GPIO port map size");
|
||||
|
||||
static HANDLE gpio_fd;
|
||||
static struct gpio_config gpio_config;
|
||||
|
||||
HRESULT gpio_hook_init(const struct gpio_config *cfg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
memcpy(&gpio_config, cfg, sizeof(*cfg));
|
||||
|
||||
hr = iohook_open_nul_fd(&gpio_fd);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = iohook_push_handler(gpio_handle_irp);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = setupapi_add_phantom_dev(&gpio_guid, L"$gpio");
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT gpio_handle_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != gpio_fd) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return gpio_handle_open(irp);
|
||||
case IRP_OP_CLOSE: return gpio_handle_close(irp);
|
||||
case IRP_OP_IOCTL: return gpio_handle_ioctl(irp);
|
||||
default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT gpio_handle_open(struct irp *irp)
|
||||
{
|
||||
if (!wstr_eq(irp->open_filename, L"$gpio")) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
dprintf("GPIO: Open device\n");
|
||||
irp->fd = gpio_fd;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT gpio_handle_close(struct irp *irp)
|
||||
{
|
||||
dprintf("GPIO: Close device\n");
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT gpio_handle_ioctl(struct irp *irp)
|
||||
{
|
||||
switch (irp->ioctl) {
|
||||
case GPIO_IOCTL_SET_LEDS:
|
||||
return gpio_ioctl_set_leds(irp);
|
||||
|
||||
case GPIO_IOCTL_GET_PSW:
|
||||
return gpio_ioctl_get_psw(irp);
|
||||
|
||||
case GPIO_IOCTL_GET_DIPSW:
|
||||
return gpio_ioctl_get_dipsw(irp);
|
||||
|
||||
case GPIO_IOCTL_DESCRIBE:
|
||||
return gpio_ioctl_describe(irp);
|
||||
|
||||
default:
|
||||
dprintf("GPIO: Unknown ioctl %08x, write %i read %i\n",
|
||||
irp->ioctl,
|
||||
(int) irp->write.nbytes,
|
||||
(int) irp->read.nbytes);
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT gpio_ioctl_get_dipsw(struct irp *irp)
|
||||
{
|
||||
uint32_t dipsw;
|
||||
size_t i;
|
||||
|
||||
dipsw = 0;
|
||||
|
||||
for (i = 0 ; i < 8 ; i++) {
|
||||
if (gpio_config.dipsw[i]) {
|
||||
dipsw |= 1 << i;
|
||||
}
|
||||
}
|
||||
|
||||
//dprintf("GPIO: Get dipsw %08x\n", dipsw);
|
||||
|
||||
return iobuf_write_le32(&irp->read, dipsw);
|
||||
}
|
||||
|
||||
static HRESULT gpio_ioctl_get_psw(struct irp *irp)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
result = 0;
|
||||
|
||||
/* Bit 0 == SW1 == Alt. Test */
|
||||
/* Bit 1 == SW2 == Alt. Service */
|
||||
|
||||
if (GetAsyncKeyState(gpio_config.vk_sw1) & 0x8000) {
|
||||
result |= 1 << 0;
|
||||
}
|
||||
|
||||
if (GetAsyncKeyState(gpio_config.vk_sw2) & 0x8000) {
|
||||
result |= 1 << 1;
|
||||
}
|
||||
|
||||
return iobuf_write_le32(&irp->read, result);
|
||||
}
|
||||
|
||||
static HRESULT gpio_ioctl_describe(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
dprintf("GPIO: Describe GPIO ports\n");
|
||||
|
||||
hr = iobuf_write(&irp->read, &gpio_ports, sizeof(gpio_ports));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("GPIO: Describe GPIO ports failed: %08x\n", (int) hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT gpio_ioctl_set_leds(struct irp *irp)
|
||||
{
|
||||
return S_OK;
|
||||
}
|
22
idmac/gpio.h
22
idmac/gpio.h
@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct gpio_config {
|
||||
bool enable;
|
||||
uint8_t vk_sw1;
|
||||
uint8_t vk_sw2;
|
||||
bool dipsw[8];
|
||||
};
|
||||
|
||||
DEFINE_GUID(
|
||||
gpio_guid,
|
||||
0xE9A26688,
|
||||
0xF522,
|
||||
0x44FA,
|
||||
0xBF, 0xEE, 0x59, 0xDD, 0x16, 0x15, 0x56, 0x6C);
|
||||
|
||||
HRESULT gpio_hook_init(const struct gpio_config *cfg);
|
@ -1,8 +1,4 @@
|
||||
#include <windows.h>
|
||||
#include <initguid.h>
|
||||
|
||||
#include "idmac/ds.h"
|
||||
#include "idmac/eeprom.h"
|
||||
#include "idmac/gpio.h"
|
||||
#include "idmac/jvs.h"
|
||||
#include "idmac/sram.h"
|
||||
|
253
idmac/idmac.c
253
idmac/idmac.c
@ -1,13 +1,147 @@
|
||||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "idmac/idmac.h"
|
||||
#include "idmac/ds.h"
|
||||
#include "idmac/eeprom.h"
|
||||
#include "idmac/gpio.h"
|
||||
#include "idmac/jvs.h"
|
||||
#include "idmac/sram.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "hook/table.h"
|
||||
#include "hook/table.h"
|
||||
#include "util/dprintf.h"
|
||||
|
||||
enum IDAMC_IOCTL {
|
||||
DMA_READ = 0xC3502000,
|
||||
DMA_WRITE = 0xC3502004,
|
||||
REGISTER_READ = 0xC3502008,
|
||||
REGISTER_WRITE = 0xC350200C,
|
||||
REGISTER_BUFFER_READ = 0xC3502012,
|
||||
REGISTER_BUFFER_WRITE = 0xC3502016,
|
||||
MEMORY_READ = 0xC3502018,
|
||||
MEMORY_WRITE = 0xC350201C,
|
||||
MEMORY_READ_EXT = 0xC3502080,
|
||||
MEMORY_WRITE_EXT = 0xC3502084,
|
||||
MEMORY_BUFFER_READ = 0xC3502020,
|
||||
MEMORY_BUFFER_WRITE = 0xC3502024,
|
||||
};
|
||||
|
||||
DWORD hook_iDmacDrvOpen(int dev_num, DWORD *dev_handle, DWORD *other_ptr);
|
||||
DWORD hook_iDmacDrvClose(HANDLE a1, DWORD *lp);
|
||||
int hook_iDmacDrvDmaRead(HANDLE a1, LPVOID lp, UINT_PTR ucb, unsigned int *a4);
|
||||
int hook_iDmacDrvDmaWrite(HANDLE a1, void *lp, UINT_PTR ucb, unsigned int *a4);
|
||||
int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, unsigned int *a4);
|
||||
int hook_iDmacDrvRegisterWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
|
||||
int hook_iDmacDrvRegisterBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
|
||||
int hook_iDmacDrvRegisterBufferWrite(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5);
|
||||
int hook_iDmacDrvMemoryRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4);
|
||||
int hook_iDmacDrvMemoryWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
|
||||
int hook_iDmacDrvMemoryBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
|
||||
int hook_iDmacDrvMemoryBufferWrite(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5);
|
||||
int hook_iDmacDrvMemoryReadExt(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6);
|
||||
int hook_iDmacDrvMemoryWriteExt(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp);
|
||||
|
||||
DWORD (*next_iDmacDrvOpen)(int dev_num, DWORD *dev_handle, DWORD *other_ptr);
|
||||
DWORD (*next_iDmacDrvClose)(HANDLE a1, DWORD *lp);
|
||||
int (*next_iDmacDrvDmaRead)(HANDLE a1, LPVOID lp, UINT_PTR ucb, unsigned int *a4);
|
||||
int (*next_iDmacDrvDmaWrite)(HANDLE a1, void *lp, UINT_PTR ucb, unsigned int *a4);
|
||||
int (*next_iDmacDrvRegisterRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, unsigned int *a4);
|
||||
int (*next_iDmacDrvRegisterWrite)(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
|
||||
int (*next_iDmacDrvRegisterBufferRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
|
||||
int (*next_iDmacDrvRegisterBufferWrite)(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5);
|
||||
int (*next_iDmacDrvMemoryRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4);
|
||||
int (*next_iDmacDrvMemoryWrite)(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp);
|
||||
int (*next_iDmacDrvMemoryBufferRead)(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5);
|
||||
int (*next_iDmacDrvMemoryBufferWrite)(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5);
|
||||
int (*next_iDmacDrvMemoryReadExt)(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6);
|
||||
int (*next_iDmacDrvMemoryWriteExt)(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp);
|
||||
|
||||
static const struct hook_symbol idmac_hooks[] = {
|
||||
{
|
||||
.name = "iDmacDrvOpen",
|
||||
.ordinal = 1,
|
||||
.patch = hook_iDmacDrvOpen,
|
||||
.link = (void **) &next_iDmacDrvOpen,
|
||||
},{
|
||||
.name = "iDmacDrvClose",
|
||||
.ordinal = 2,
|
||||
.patch = hook_iDmacDrvClose,
|
||||
.link = (void **) &next_iDmacDrvClose,
|
||||
},{
|
||||
.name = "iDmacDrvDmaRead",
|
||||
.ordinal = 3,
|
||||
.patch = hook_iDmacDrvDmaRead,
|
||||
.link = (void **) &next_iDmacDrvDmaRead,
|
||||
},{
|
||||
.name = "iDmacDrvDmaWrite",
|
||||
.ordinal = 4,
|
||||
.patch = hook_iDmacDrvDmaWrite,
|
||||
.link = (void **) &next_iDmacDrvDmaWrite,
|
||||
},{
|
||||
.name = "iDmacDrvRegisterRead",
|
||||
.ordinal = 5,
|
||||
.patch = hook_iDmacDrvRegisterRead,
|
||||
.link = (void **) &next_iDmacDrvRegisterRead,
|
||||
},{
|
||||
.name = "iDmacDrvRegisterWrite",
|
||||
.ordinal = 6,
|
||||
.patch = hook_iDmacDrvRegisterWrite,
|
||||
.link = (void **) &next_iDmacDrvRegisterWrite,
|
||||
},{
|
||||
.name = "iDmacDrvRegisterBufferRead",
|
||||
.ordinal = 7,
|
||||
.patch = hook_iDmacDrvRegisterBufferRead,
|
||||
.link = (void **) &next_iDmacDrvRegisterBufferRead,
|
||||
},{
|
||||
.name = "iDmacDrvRegisterBufferWrite",
|
||||
.ordinal = 8,
|
||||
.patch = hook_iDmacDrvRegisterBufferWrite,
|
||||
.link = (void **) &next_iDmacDrvRegisterBufferWrite,
|
||||
},{
|
||||
.name = "iDmacDrvMemoryRead",
|
||||
.ordinal = 9,
|
||||
.patch = hook_iDmacDrvMemoryRead,
|
||||
.link = (void **) &next_iDmacDrvMemoryRead,
|
||||
},{
|
||||
.name = "iDmacDrvMemoryWrite",
|
||||
.ordinal = 10,
|
||||
.patch = hook_iDmacDrvMemoryWrite,
|
||||
.link = (void **) &next_iDmacDrvMemoryWrite,
|
||||
},{
|
||||
.name = "iDmacDrvMemoryBufferRead",
|
||||
.ordinal = 11,
|
||||
.patch = hook_iDmacDrvMemoryBufferRead,
|
||||
.link = (void **) &next_iDmacDrvMemoryBufferRead,
|
||||
},{
|
||||
.name = "iDmacDrvMemoryBufferWrite",
|
||||
.ordinal = 12,
|
||||
.patch = hook_iDmacDrvMemoryBufferWrite,
|
||||
.link = (void **) &next_iDmacDrvMemoryBufferWrite,
|
||||
},{
|
||||
.name = "iDmacDrvMemoryReadExt",
|
||||
.ordinal = 13,
|
||||
.patch = hook_iDmacDrvMemoryReadExt,
|
||||
.link = (void **) &next_iDmacDrvMemoryReadExt,
|
||||
},{
|
||||
.name = "iDmacDrvMemoryWriteExt",
|
||||
.ordinal = 14,
|
||||
.patch = hook_iDmacDrvMemoryWriteExt,
|
||||
.link = (void **) &next_iDmacDrvMemoryWriteExt,
|
||||
},
|
||||
};
|
||||
|
||||
void idmac_hook_table_apply(HMODULE target)
|
||||
{
|
||||
hook_table_apply(
|
||||
target,
|
||||
"iDmacDrv64.dll",
|
||||
idmac_hooks,
|
||||
_countof(idmac_hooks)
|
||||
);
|
||||
hook_table_apply(
|
||||
target,
|
||||
"iDmacDrv32.dll",
|
||||
idmac_hooks,
|
||||
_countof(idmac_hooks)
|
||||
);
|
||||
}
|
||||
|
||||
HRESULT idmac_hook_init(const struct idmac_config *cfg, jvs_provider_t jvs)
|
||||
{
|
||||
@ -15,23 +149,7 @@ HRESULT idmac_hook_init(const struct idmac_config *cfg, jvs_provider_t jvs)
|
||||
|
||||
assert(cfg != NULL);
|
||||
|
||||
hr = ds_hook_init(&cfg->ds);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = eeprom_hook_init(&cfg->eeprom);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = gpio_hook_init(&cfg->gpio);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
dprintf("iDmac: Init\n");
|
||||
|
||||
hr = jvs_hook_init(&cfg->jvs, jvs);
|
||||
|
||||
@ -39,11 +157,92 @@ HRESULT idmac_hook_init(const struct idmac_config *cfg, jvs_provider_t jvs)
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = sram_hook_init(&cfg->sram);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
idmac_hook_table_apply(NULL);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
DWORD hook_iDmacDrvOpen(int dev_num, DWORD *dev_handle, DWORD *other_ptr)
|
||||
{
|
||||
dprintf("hook_iDmacDrvOpen: Open device #%X\n", dev_num);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD hook_iDmacDrvClose(HANDLE dev_handle, DWORD *lp)
|
||||
{
|
||||
dprintf("hook_iDmacDrvClose: Close handle %p\n", dev_handle);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvDmaRead(HANDLE a1, LPVOID lp, UINT_PTR ucb, unsigned int *a4)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvDmaRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvDmaWrite(HANDLE a1, void *lp, UINT_PTR ucb, unsigned int *a4)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvDmaWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvRegisterRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, unsigned int *a4)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvRegisterRead: This code should not run!\n");
|
||||
//memset(lp, 0, 0x14);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvRegisterWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvRegisterWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvRegisterBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvRegisterBufferRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvRegisterBufferWrite(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvRegisterBufferWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvMemoryRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvMemoryRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvMemoryWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvMemoryWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvMemoryBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvMemoryBufferRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvMemoryBufferWrite(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvMemoryBufferWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvMemoryReadExt(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvMemoryReadExt: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_iDmacDrvMemoryWriteExt(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp)
|
||||
{
|
||||
//dprintf("hook_iDmacDrvMemoryWriteExt: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,20 +2,14 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include "idmac/ds.h"
|
||||
#include "idmac/eeprom.h"
|
||||
#include "idmac/gpio.h"
|
||||
#include "idmac/jvs.h"
|
||||
#include "idmac/sram.h"
|
||||
|
||||
struct idmac_config {
|
||||
struct ds_config ds;
|
||||
struct eeprom_config eeprom;
|
||||
struct gpio_config gpio;
|
||||
struct jvs_config jvs;
|
||||
struct sram_config sram;
|
||||
};
|
||||
|
||||
HRESULT idmac_hook_init(
|
||||
const struct idmac_config *cfg,
|
||||
jvs_provider_t jvs);
|
||||
|
||||
void idmac_hook_table_apply(HMODULE target);
|
||||
|
152
idmac/jvs.c
152
idmac/jvs.c
@ -12,6 +12,7 @@
|
||||
|
||||
#include "hook/iobuf.h"
|
||||
#include "hook/iohook.h"
|
||||
#include "hooklib/uart.h"
|
||||
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
@ -28,15 +29,12 @@ enum {
|
||||
};
|
||||
|
||||
static HRESULT jvs_handle_irp(struct irp *irp);
|
||||
static HRESULT jvs_handle_open(struct irp *irp);
|
||||
static HRESULT jvs_handle_close(struct irp *irp);
|
||||
static HRESULT jvs_handle_ioctl(struct irp *irp);
|
||||
static HRESULT jvs_handle_irp_locked(struct irp *irp);
|
||||
|
||||
static HRESULT jvs_ioctl_hello(struct irp *irp);
|
||||
static HRESULT jvs_ioctl_sense(struct irp *irp);
|
||||
static HRESULT jvs_ioctl_transact(struct irp *irp);
|
||||
|
||||
static HANDLE jvs_fd;
|
||||
static CRITICAL_SECTION jvs_lock;
|
||||
static struct uart jvs_uart;
|
||||
static uint8_t jvs_written_bytes[516];
|
||||
static uint8_t jvs_readable_bytes[516];
|
||||
static struct jvs_node *jvs_root;
|
||||
static jvs_provider_t jvs_provider;
|
||||
|
||||
@ -50,62 +48,49 @@ HRESULT jvs_hook_init(const struct jvs_config *cfg, jvs_provider_t provider)
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
hr = iohook_push_handler(jvs_handle_irp);
|
||||
InitializeCriticalSection(&jvs_lock);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = setupapi_add_phantom_dev(&jvs_guid, L"$jvs");
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
uart_init(&jvs_uart, 2);
|
||||
jvs_uart.written.bytes = jvs_written_bytes;
|
||||
jvs_uart.written.nbytes = sizeof(jvs_written_bytes);
|
||||
jvs_uart.readable.bytes = jvs_readable_bytes;
|
||||
jvs_uart.readable.nbytes = sizeof(jvs_readable_bytes);
|
||||
|
||||
jvs_provider = provider;
|
||||
|
||||
return S_OK;
|
||||
return iohook_push_handler(jvs_handle_irp);
|
||||
}
|
||||
|
||||
static HRESULT jvs_handle_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != jvs_fd) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return jvs_handle_open(irp);
|
||||
case IRP_OP_CLOSE: return jvs_handle_close(irp);
|
||||
case IRP_OP_IOCTL: return jvs_handle_ioctl(irp);
|
||||
default: return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT jvs_handle_open(struct irp *irp)
|
||||
{
|
||||
struct jvs_node *root;
|
||||
HRESULT hr;
|
||||
|
||||
if (!wstr_eq(irp->open_filename, L"$jvs")) {
|
||||
assert(irp != NULL);
|
||||
|
||||
if (!uart_match_irp(&jvs_uart, irp)) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
if (jvs_fd != NULL) {
|
||||
dprintf("JVS Port: Already open\n");
|
||||
EnterCriticalSection(&jvs_lock);
|
||||
hr = jvs_handle_irp_locked(irp);
|
||||
LeaveCriticalSection(&jvs_lock);
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
|
||||
}
|
||||
|
||||
hr = iohook_open_nul_fd(&jvs_fd);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
dprintf("JVS Port: Open device\n");
|
||||
static HRESULT jvs_handle_irp_locked(struct irp *irp)
|
||||
{
|
||||
#if 0
|
||||
dprintf("\nJVS Port: Outbound frame:\n");
|
||||
dump_const_iobuf(&irp->write);
|
||||
#endif
|
||||
|
||||
struct iobuf req_iobuf;
|
||||
HRESULT hr;
|
||||
struct jvs_node *root;
|
||||
|
||||
if (irp->op == IRP_OP_OPEN) {
|
||||
dprintf("iDmac JVS: Starting backend\n");
|
||||
if (jvs_provider != NULL) {
|
||||
hr = jvs_provider(&root);
|
||||
|
||||
@ -113,86 +98,17 @@ static HRESULT jvs_handle_open(struct irp *irp)
|
||||
jvs_root = root;
|
||||
}
|
||||
}
|
||||
|
||||
irp->fd = jvs_fd;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT jvs_handle_close(struct irp *irp)
|
||||
{
|
||||
dprintf("JVS Port: Close device\n");
|
||||
jvs_fd = NULL;
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT jvs_handle_ioctl(struct irp *irp)
|
||||
{
|
||||
switch (irp->ioctl) {
|
||||
case JVS_IOCTL_HELLO:
|
||||
return jvs_ioctl_hello(irp);
|
||||
|
||||
case JVS_IOCTL_SENSE:
|
||||
return jvs_ioctl_sense(irp);
|
||||
|
||||
case JVS_IOCTL_TRANSACT:
|
||||
return jvs_ioctl_transact(irp);
|
||||
|
||||
default:
|
||||
dprintf("JVS Port: Unknown ioctl %#x\n", irp->ioctl);
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT jvs_ioctl_hello(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
// uuh fucked if i know
|
||||
|
||||
dprintf("JVS Port: Port startup (?)\n");
|
||||
|
||||
iobuf_write_8(&irp->read, 0);
|
||||
hr = iobuf_write_8(&irp->read, 0);
|
||||
hr = uart_handle_irp(&jvs_uart, irp);
|
||||
|
||||
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT jvs_ioctl_sense(struct irp *irp)
|
||||
{
|
||||
uint8_t code;
|
||||
bool sense;
|
||||
|
||||
if (jvs_root != NULL) {
|
||||
sense = jvs_root->sense(jvs_root);
|
||||
|
||||
if (sense) {
|
||||
dprintf("JVS Port: Sense line 2.5 V (address unassigned)\n");
|
||||
code = 3;
|
||||
} else {
|
||||
dprintf("JVS Port: Sense line 0.0 V (address assigned)\n");
|
||||
code = 2;
|
||||
}
|
||||
} else {
|
||||
dprintf("JVS Port: Sense line 5.0 V (no downstream PCB)\n");
|
||||
code = 1;
|
||||
}
|
||||
|
||||
return iobuf_write_8(&irp->read, code);
|
||||
}
|
||||
|
||||
static HRESULT jvs_ioctl_transact(struct irp *irp)
|
||||
{
|
||||
#if 0
|
||||
dprintf("\nJVS Port: Outbound frame:\n");
|
||||
dump_const_iobuf(&irp->write);
|
||||
#endif
|
||||
|
||||
jvs_bus_transact(jvs_root, irp->write.bytes, irp->write.nbytes, &irp->read);
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
dprintf("JVS Port: Inbound frame:\n");
|
||||
dump_iobuf(&irp->read);
|
||||
dprintf("\n");
|
||||
|
@ -6,23 +6,18 @@ idmac_lib = static_library(
|
||||
dependencies : [
|
||||
capnhook.get_variable('hook_dep'),
|
||||
],
|
||||
link_with : [
|
||||
jvs_lib,
|
||||
hooklib_lib,
|
||||
util_lib,
|
||||
],
|
||||
sources : [
|
||||
'idmac.c',
|
||||
'idmac.h',
|
||||
'config.c',
|
||||
'config.h',
|
||||
'ds.c',
|
||||
'ds.h',
|
||||
'eeprom.c',
|
||||
'eeprom.h',
|
||||
'gpio.c',
|
||||
'gpio.h',
|
||||
'guid.c',
|
||||
'jvs.c',
|
||||
'jvs.h',
|
||||
'nvram.c',
|
||||
'nvram.h',
|
||||
'sram.c',
|
||||
'sram.h',
|
||||
],
|
||||
)
|
||||
|
@ -1,81 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "idmac/nvram.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
HRESULT nvram_open_file(HANDLE *out, const wchar_t *path, size_t size)
|
||||
{
|
||||
LARGE_INTEGER cur_size;
|
||||
LARGE_INTEGER pos;
|
||||
HANDLE file;
|
||||
HRESULT hr;
|
||||
BOOL ok;
|
||||
|
||||
assert(out != NULL);
|
||||
assert(path != NULL);
|
||||
|
||||
*out = NULL;
|
||||
|
||||
file = CreateFileW(
|
||||
path,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ,
|
||||
NULL,
|
||||
OPEN_ALWAYS,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("%S: Error opening backing store: %x\n", path, (int) hr);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
ok = GetFileSizeEx(file, &cur_size);
|
||||
|
||||
if (!ok) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("%S: GetFileSizeEx failed: %x\n", path, (int) hr);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (cur_size.QuadPart != (uint64_t) size) {
|
||||
pos.QuadPart = (uint64_t) size;
|
||||
ok = SetFilePointerEx(file, pos, NULL, FILE_BEGIN);
|
||||
|
||||
if (!ok) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("%S: SetFilePointerEx failed: %x\n", path, (int) hr);
|
||||
|
||||
goto end;
|
||||
}
|
||||
|
||||
ok = SetEndOfFile(file);
|
||||
|
||||
if (!ok) {
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
dprintf("%S: SetEndOfFile failed: %x\n", path, (int) hr);
|
||||
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
*out = file;
|
||||
file = INVALID_HANDLE_VALUE;
|
||||
|
||||
hr = S_OK;
|
||||
|
||||
end:
|
||||
if (file != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(file);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
HRESULT nvram_open_file(HANDLE *out, const wchar_t *path, size_t size);
|
160
idmac/sram.c
160
idmac/sram.c
@ -1,160 +0,0 @@
|
||||
#include <windows.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <ntdef.h>
|
||||
#else
|
||||
#include <winnt.h>
|
||||
#endif
|
||||
#include <devioctl.h>
|
||||
#include <ntdddisk.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "idmac/sram.h"
|
||||
#include "idmac/nvram.h"
|
||||
|
||||
#include "hook/iohook.h"
|
||||
|
||||
#include "hooklib/setupapi.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/str.h"
|
||||
|
||||
enum {
|
||||
SRAM_IOCTL_GET_ABI_VERSION = 0x80006000,
|
||||
};
|
||||
|
||||
static HRESULT sram_handle_irp(struct irp *irp);
|
||||
static HRESULT sram_handle_open(struct irp *irp);
|
||||
static HRESULT sram_handle_close(struct irp *irp);
|
||||
static HRESULT sram_handle_ioctl(struct irp *irp);
|
||||
|
||||
static HRESULT sram_ioctl_get_geometry(struct irp *irp);
|
||||
static HRESULT sram_ioctl_get_abi_version(struct irp *irp);
|
||||
|
||||
static struct sram_config sram_config;
|
||||
static HANDLE sram_file;
|
||||
|
||||
HRESULT sram_hook_init(const struct sram_config *cfg)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(cfg != NULL);
|
||||
|
||||
if (!cfg->enable) {
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
memcpy(&sram_config, cfg, sizeof(*cfg));
|
||||
|
||||
hr = iohook_push_handler(sram_handle_irp);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
hr = setupapi_add_phantom_dev(&sram_guid, L"$sram");
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sram_handle_irp(struct irp *irp)
|
||||
{
|
||||
assert(irp != NULL);
|
||||
|
||||
if (irp->op != IRP_OP_OPEN && irp->fd != sram_file) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
switch (irp->op) {
|
||||
case IRP_OP_OPEN: return sram_handle_open(irp);
|
||||
case IRP_OP_CLOSE: return sram_handle_close(irp);
|
||||
case IRP_OP_IOCTL: return sram_handle_ioctl(irp);
|
||||
default: return iohook_invoke_next(irp);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT sram_handle_open(struct irp *irp)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!wstr_eq(irp->open_filename, L"$sram")) {
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
if (sram_file != NULL) {
|
||||
dprintf("SRAM: Already open\n");
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_SHARING_VIOLATION);
|
||||
}
|
||||
|
||||
dprintf("SRAM: Open device\n");
|
||||
hr = nvram_open_file(&sram_file, sram_config.path, 0x80000);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
return hr;
|
||||
}
|
||||
|
||||
irp->fd = sram_file;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT sram_handle_close(struct irp *irp)
|
||||
{
|
||||
dprintf("SRAM: Close device\n");
|
||||
sram_file = NULL;
|
||||
|
||||
return iohook_invoke_next(irp);
|
||||
}
|
||||
|
||||
static HRESULT sram_handle_ioctl(struct irp *irp)
|
||||
{
|
||||
switch (irp->ioctl) {
|
||||
case IOCTL_DISK_GET_DRIVE_GEOMETRY:
|
||||
return sram_ioctl_get_geometry(irp);
|
||||
|
||||
case SRAM_IOCTL_GET_ABI_VERSION:
|
||||
return sram_ioctl_get_abi_version(irp);
|
||||
|
||||
default:
|
||||
dprintf("SRAM: Unknown ioctl %x, write %i read %i\n",
|
||||
irp->ioctl,
|
||||
(int) irp->write.nbytes,
|
||||
(int) irp->read.nbytes);
|
||||
|
||||
return HRESULT_FROM_WIN32(ERROR_INVALID_FUNCTION);
|
||||
}
|
||||
}
|
||||
|
||||
static HRESULT sram_ioctl_get_geometry(struct irp *irp)
|
||||
{
|
||||
DISK_GEOMETRY out;
|
||||
HRESULT hr;
|
||||
|
||||
dprintf("SRAM: Get geometry\n");
|
||||
|
||||
memset(&out, 0, sizeof(out));
|
||||
out.Cylinders.QuadPart = 0x20000;
|
||||
out.MediaType = 0;
|
||||
out.TracksPerCylinder = 1;
|
||||
out.SectorsPerTrack = 1;
|
||||
out.BytesPerSector = 4;
|
||||
|
||||
hr = iobuf_write(&irp->read, &out, sizeof(out));
|
||||
|
||||
if (FAILED(hr)) {
|
||||
dprintf("SRAM: Get geometry failed: %08x\n", (int) hr);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT sram_ioctl_get_abi_version(struct irp *irp)
|
||||
{
|
||||
return iobuf_write_le16(&irp->read, 256);
|
||||
}
|
20
idmac/sram.h
20
idmac/sram.h
@ -1,20 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct sram_config {
|
||||
bool enable;
|
||||
wchar_t path[MAX_PATH];
|
||||
};
|
||||
|
||||
DEFINE_GUID(
|
||||
sram_guid,
|
||||
0x741B5FCA,
|
||||
0x4635,
|
||||
0x4443,
|
||||
0xA7, 0xA0, 0x57, 0xCA, 0x7B, 0x50, 0x6A, 0x49);
|
||||
|
||||
HRESULT sram_hook_init(const struct sram_config *cfg);
|
96
idmac_stub/dllmain.c
Normal file
96
idmac_stub/dllmain.c
Normal file
@ -0,0 +1,96 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
BOOL WINAPI DllMain(HMODULE mod, DWORD cause, void *ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD __cdecl iDmacDrvOpen(int dev_num, DWORD *dev_handle, DWORD *other_ptr)
|
||||
{
|
||||
dprintf("iDmacDrvOpen: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD __cdecl iDmacDrvClose(HANDLE a1, DWORD *lp)
|
||||
{
|
||||
dprintf("iDmacDrvClose: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvDmaRead(HANDLE a1, LPVOID lp, UINT_PTR ucb, unsigned int *a4)
|
||||
{
|
||||
dprintf("iDmacDrvDmaRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvDmaWrite(HANDLE a1, void *lp, UINT_PTR ucb, unsigned int *a4)
|
||||
{
|
||||
dprintf("iDmacDrvDmaWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvRegisterRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, unsigned int *a4)
|
||||
{
|
||||
dprintf("iDmacDrvRegisterRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvRegisterWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp)
|
||||
{
|
||||
dprintf("iDmacDrvRegisterWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvRegisterBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
dprintf("iDmacDrvRegisterBufferRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvRegisterBufferWrite(HANDLE a1, DWORD BytesReturned, void *lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
dprintf("iDmacDrvRegisterBufferWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvMemoryRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, DWORD *a4)
|
||||
{
|
||||
dprintf("iDmacDrvMemoryRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvMemoryWrite(HANDLE a1, DWORD BytesReturned, int a3, DWORD *lp)
|
||||
{
|
||||
dprintf("iDmacDrvMemoryWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvMemoryBufferRead(HANDLE a1, DWORD BytesReturned, LPVOID lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
dprintf("iDmacDrvMemoryBufferRead: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvMemoryBufferWrite(HANDLE a1, unsigned int a2, void *lp, UINT_PTR ucb, DWORD *a5)
|
||||
{
|
||||
dprintf("iDmacDrvMemoryBufferWrite: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvMemoryReadExt(HANDLE a1, DWORD BytesReturned, unsigned int a3, LPVOID lp, int nOutBufferSize, DWORD *a6)
|
||||
{
|
||||
dprintf("iDmacDrvMemoryReadExt: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __cdecl iDmacDrvMemoryWriteExt(HANDLE a1, int a2, unsigned int a3, void *Source, rsize_t DestinationSize, unsigned int *lp)
|
||||
{
|
||||
dprintf("iDmacDrvMemoryWriteExt: This code should not run!\n");
|
||||
return 0;
|
||||
}
|
17
idmac_stub/idmac_stub.def
Normal file
17
idmac_stub/idmac_stub.def
Normal file
@ -0,0 +1,17 @@
|
||||
LIBRARY iDmacDrv
|
||||
|
||||
EXPORTS
|
||||
iDmacDrvOpen @1
|
||||
iDmacDrvClose @2
|
||||
iDmacDrvDmaRead @3
|
||||
iDmacDrvDmaWrite @4
|
||||
iDmacDrvRegisterRead @5
|
||||
iDmacDrvRegisterWrite @6
|
||||
iDmacDrvRegisterBufferRead @7
|
||||
iDmacDrvRegisterBufferWrite @8
|
||||
iDmacDrvMemoryRead @9
|
||||
iDmacDrvMemoryWrite @10
|
||||
iDmacDrvMemoryBufferRead @11
|
||||
iDmacDrvMemoryBufferWrite @12
|
||||
iDmacDrvMemoryReadExt @13
|
||||
iDmacDrvMemoryWriteExt @14
|
14
idmac_stub/meson.build
Normal file
14
idmac_stub/meson.build
Normal file
@ -0,0 +1,14 @@
|
||||
shared_library(
|
||||
'iDmacDrv',
|
||||
name_prefix : '',
|
||||
include_directories: inc,
|
||||
vs_module_defs : 'idmac_stub.def',
|
||||
implicit_include_directories : false,
|
||||
c_pch : '../precompiled.h',
|
||||
link_with : [
|
||||
util_lib,
|
||||
],
|
||||
sources : [
|
||||
'dllmain.c',
|
||||
],
|
||||
)
|
@ -44,7 +44,6 @@ crypt_lib = cc.find_library('crypt32')
|
||||
inc = include_directories('.')
|
||||
capnhook = subproject('capnhook')
|
||||
|
||||
subdir('idmac')
|
||||
subdir('iccard')
|
||||
subdir('board')
|
||||
subdir('hooklib')
|
||||
@ -54,6 +53,9 @@ subdir('util')
|
||||
|
||||
subdir('gfxhook')
|
||||
|
||||
subdir('idmac_stub')
|
||||
subdir('idmac')
|
||||
|
||||
subdir('sivaio')
|
||||
subdir('ll3io')
|
||||
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "idmac/config.h"
|
||||
#include "idmac/ds.h"
|
||||
|
||||
#include "hook/process.h"
|
||||
|
||||
@ -20,14 +19,12 @@ static process_entry_t app_startup;
|
||||
static DWORD CALLBACK app_pre_startup(void)
|
||||
{
|
||||
struct clock_config clock_cfg;
|
||||
struct ds_config ds_cfg;
|
||||
struct ttxsec_config ttxsec_cfg;
|
||||
HRESULT hr;
|
||||
|
||||
dprintf("--- Begin %s ---\n", __func__);
|
||||
|
||||
clock_config_load(&clock_cfg, L".\\taitools.ini");
|
||||
ds_config_load(&ds_cfg, L".\\taitools.ini");
|
||||
ttxsec_config_load(&ttxsec_cfg, L".\\taitools.ini");
|
||||
spike_hook_init(L".\\taitools.ini");
|
||||
|
||||
@ -43,12 +40,6 @@ static DWORD CALLBACK app_pre_startup(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = ds_hook_init(&ds_cfg);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dprintf("--- End %s ---\n", __func__);
|
||||
|
||||
return app_startup();
|
||||
|
@ -38,6 +38,7 @@ void siva_hook_config_load(
|
||||
assert(cfg != NULL);
|
||||
assert(filename != NULL);
|
||||
|
||||
idmac_config_load(&cfg->idmac, filename);
|
||||
platform_config_load(&cfg->platform, filename);
|
||||
siva_dll_config_load(&cfg->dll, filename);
|
||||
gfx_config_load(&cfg->gfx, filename);
|
||||
|
@ -5,11 +5,13 @@
|
||||
#include "sivahook/siva-dll.h"
|
||||
#include "sivahook/touch.h"
|
||||
|
||||
#include "idmac/config.h"
|
||||
#include "platform/config.h"
|
||||
#include "gfxhook/config.h"
|
||||
#include "board/config.h"
|
||||
|
||||
struct siva_hook_config {
|
||||
struct idmac_config idmac;
|
||||
struct platform_config platform;
|
||||
struct siva_dll_config dll;
|
||||
struct gfx_config gfx;
|
||||
|
@ -7,11 +7,14 @@
|
||||
#include "hooklib/serial.h"
|
||||
#include "hooklib/spike.h"
|
||||
|
||||
#include "idmac/idmac.h"
|
||||
|
||||
#include "gfxhook/gfx.h"
|
||||
#include "gfxhook/d3d9.h"
|
||||
#include "gfxhook/d3d11.h"
|
||||
#include "gfxhook/dxgi.h"
|
||||
|
||||
#include "sivahook/reader.h"
|
||||
#include "sivahook/config.h"
|
||||
#include "sivahook/siva-dll.h"
|
||||
#include "sivahook/touch.h"
|
||||
@ -68,6 +71,12 @@ static DWORD CALLBACK siva_pre_startup(void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
hr = idmac_hook_init(&siva_hook_cfg.idmac, siva_reader_init);
|
||||
|
||||
if (FAILED(hr)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
unity_hook_init();
|
||||
/* Initialize debug helpers */
|
||||
|
||||
|
@ -11,10 +11,12 @@ shared_library(
|
||||
],
|
||||
link_with : [
|
||||
gfxhook_lib,
|
||||
jvs_lib,
|
||||
board_lib,
|
||||
hooklib_lib,
|
||||
sivaio_lib,
|
||||
platform_lib,
|
||||
idmac_lib,
|
||||
util_lib,
|
||||
],
|
||||
sources : [
|
||||
@ -27,5 +29,7 @@ shared_library(
|
||||
'unity.h',
|
||||
'touch.c',
|
||||
'touch.h',
|
||||
'reader.c',
|
||||
'reader.h',
|
||||
],
|
||||
)
|
||||
|
44
sivahook/reader.c
Normal file
44
sivahook/reader.c
Normal file
@ -0,0 +1,44 @@
|
||||
#include <windows.h>
|
||||
|
||||
#include "jvs/jvs-bus.h"
|
||||
#include "idmac/jvs.h"
|
||||
#include "board/io3.h"
|
||||
|
||||
#include "sivahook/reader.h"
|
||||
#include "sivahook/siva-dll.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
|
||||
static void carol_jvs_read_switches(void *ctx, struct io3_switch_state *out);
|
||||
static void carol_jvs_read_coin_counter(
|
||||
void *ctx,
|
||||
uint8_t slot_no,
|
||||
uint16_t *out);
|
||||
|
||||
static const struct io3_ops siva_jvs_reader_ops = {
|
||||
.read_switches = carol_jvs_read_switches,
|
||||
.read_coin_counter = carol_jvs_read_coin_counter,
|
||||
};
|
||||
|
||||
static struct io3 siva_jvs_reader;
|
||||
|
||||
HRESULT siva_reader_init(struct jvs_node **out)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
assert(out != NULL);
|
||||
|
||||
dprintf("Siva Nesica Reader: Init\n");
|
||||
|
||||
io3_init(&siva_jvs_reader, NULL, &siva_jvs_reader_ops, NULL);
|
||||
*out = io3_to_jvs_node(&siva_jvs_reader);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static void carol_jvs_read_switches(void *ctx, struct io3_switch_state *out) {}
|
||||
static void carol_jvs_read_coin_counter(
|
||||
void *ctx,
|
||||
uint8_t slot_no,
|
||||
uint16_t *out)
|
||||
{}
|
6
sivahook/reader.h
Normal file
6
sivahook/reader.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
|
||||
#include "jvs/jvs-bus.h"
|
||||
|
||||
HRESULT siva_reader_init(struct jvs_node **out);
|
@ -13,6 +13,7 @@
|
||||
#include "hooklib/reg.h"
|
||||
#include "hook/procaddr.h"
|
||||
|
||||
#include "idmac/idmac.h"
|
||||
#include "platform/cert.h"
|
||||
#include "platform/netenv.h"
|
||||
|
||||
@ -39,7 +40,10 @@ static const wchar_t *target_modules[] = {
|
||||
L"NESiCAReader.dll",
|
||||
};
|
||||
|
||||
static const wchar_t *dep_hooks[] = {};
|
||||
static const wchar_t *dep_hooks[] = {
|
||||
L"iDmacDrv32.dll"
|
||||
L"iDmacDrv64.dll"
|
||||
};
|
||||
|
||||
static const size_t target_modules_len = _countof(target_modules);
|
||||
static const size_t dep_hooks_len = _countof(dep_hooks);
|
||||
@ -113,6 +117,8 @@ static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name)
|
||||
createprocess_hook_insert_hook(result);
|
||||
dns_hook_apply_hooks(result);
|
||||
netenv_hook_apply(result);
|
||||
idmac_hook_table_apply(result);
|
||||
serial_hook_apply_hooks(result);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < dep_hooks_len; i++) {
|
||||
|
Loading…
Reference in New Issue
Block a user