add idmac hooks

This commit is contained in:
Hay1tsme 2024-02-20 02:17:12 -05:00
parent 1922d7f3a6
commit 3ae24469fa
30 changed files with 484 additions and 1242 deletions

View File

@ -11,9 +11,12 @@ $(BUILD_DIR_ZIP)/siva.zip:
$(BUILD_DIR_ZIP)/siva/sivahook_32.dll $(BUILD_DIR_ZIP)/siva/sivahook_32.dll
$(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \ $(V)cp $(BUILD_DIR_64)/subprojects/capnhook/inject/inject.exe \
$(BUILD_DIR_64)/sivahook/sivahook.dll \ $(BUILD_DIR_64)/sivahook/sivahook.dll \
$(BUILD_DIR_64)/idmac_stub/iDmacDrv.dll \
$(DIST_DIR)/siva/taitools.ini \ $(DIST_DIR)/siva/taitools.ini \
$(DIST_DIR)/siva/start.bat \ $(DIST_DIR)/siva/start.bat \
$(BUILD_DIR_ZIP)/siva $(BUILD_DIR_ZIP)/siva
$(V)mv $(BUILD_DIR_ZIP)/siva/iDmacDrv.dll \
$(BUILD_DIR_ZIP)/siva/iDmacDrv64.dll
$(V)cp pki/billing.pub \ $(V)cp pki/billing.pub \
pki/ca.crt \ pki/ca.crt \
$(BUILD_DIR_ZIP)/siva/DEVICE $(BUILD_DIR_ZIP)/siva/DEVICE

View File

@ -8,64 +8,7 @@
#include "idmac/idmac.h" #include "idmac/idmac.h"
#include "idmac/config.h" #include "idmac/config.h"
#include "idmac/ds.h"
#include "idmac/eeprom.h"
#include "idmac/gpio.h"
#include "idmac/jvs.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) 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); 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) void idmac_config_load(struct idmac_config *cfg, const wchar_t *filename)
{ {
assert(cfg != NULL); assert(cfg != NULL);
assert(filename != 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); jvs_config_load(&cfg->jvs, filename);
sram_config_load(&cfg->sram, filename);
} }

View File

@ -7,15 +7,7 @@
#include <stdint.h> #include <stdint.h>
#include "idmac/idmac.h" #include "idmac/idmac.h"
#include "idmac/ds.h"
#include "idmac/eeprom.h"
#include "idmac/gpio.h"
#include "idmac/jvs.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 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); void idmac_config_load(struct idmac_config *cfg, const wchar_t *filename);

View File

@ -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, &sector_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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -1,8 +1,4 @@
#include <windows.h> #include <windows.h>
#include <initguid.h> #include <initguid.h>
#include "idmac/ds.h"
#include "idmac/eeprom.h"
#include "idmac/gpio.h"
#include "idmac/jvs.h" #include "idmac/jvs.h"
#include "idmac/sram.h"

View File

@ -1,13 +1,147 @@
#include <windows.h> #include <windows.h>
#include <assert.h>
#include "idmac/idmac.h" #include "idmac/idmac.h"
#include "idmac/ds.h"
#include "idmac/eeprom.h"
#include "idmac/gpio.h"
#include "idmac/jvs.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) 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); assert(cfg != NULL);
hr = ds_hook_init(&cfg->ds); dprintf("iDmac: Init\n");
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;
}
hr = jvs_hook_init(&cfg->jvs, jvs); 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; return hr;
} }
hr = sram_hook_init(&cfg->sram); idmac_hook_table_apply(NULL);
if (FAILED(hr)) {
return hr;
}
return S_OK; 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;
}

View File

@ -2,20 +2,14 @@
#include <windows.h> #include <windows.h>
#include "idmac/ds.h"
#include "idmac/eeprom.h"
#include "idmac/gpio.h"
#include "idmac/jvs.h" #include "idmac/jvs.h"
#include "idmac/sram.h"
struct idmac_config { struct idmac_config {
struct ds_config ds;
struct eeprom_config eeprom;
struct gpio_config gpio;
struct jvs_config jvs; struct jvs_config jvs;
struct sram_config sram;
}; };
HRESULT idmac_hook_init( HRESULT idmac_hook_init(
const struct idmac_config *cfg, const struct idmac_config *cfg,
jvs_provider_t jvs); jvs_provider_t jvs);
void idmac_hook_table_apply(HMODULE target);

View File

@ -12,6 +12,7 @@
#include "hook/iobuf.h" #include "hook/iobuf.h"
#include "hook/iohook.h" #include "hook/iohook.h"
#include "hooklib/uart.h"
#include "hooklib/setupapi.h" #include "hooklib/setupapi.h"
@ -28,15 +29,12 @@ enum {
}; };
static HRESULT jvs_handle_irp(struct irp *irp); static HRESULT jvs_handle_irp(struct irp *irp);
static HRESULT jvs_handle_open(struct irp *irp); static HRESULT jvs_handle_irp_locked(struct irp *irp);
static HRESULT jvs_handle_close(struct irp *irp);
static HRESULT jvs_handle_ioctl(struct irp *irp);
static HRESULT jvs_ioctl_hello(struct irp *irp); static CRITICAL_SECTION jvs_lock;
static HRESULT jvs_ioctl_sense(struct irp *irp); static struct uart jvs_uart;
static HRESULT jvs_ioctl_transact(struct irp *irp); static uint8_t jvs_written_bytes[516];
static uint8_t jvs_readable_bytes[516];
static HANDLE jvs_fd;
static struct jvs_node *jvs_root; static struct jvs_node *jvs_root;
static jvs_provider_t jvs_provider; static jvs_provider_t jvs_provider;
@ -50,149 +48,67 @@ HRESULT jvs_hook_init(const struct jvs_config *cfg, jvs_provider_t provider)
return S_FALSE; return S_FALSE;
} }
hr = iohook_push_handler(jvs_handle_irp); InitializeCriticalSection(&jvs_lock);
if (FAILED(hr)) { uart_init(&jvs_uart, 2);
return hr; jvs_uart.written.bytes = jvs_written_bytes;
} jvs_uart.written.nbytes = sizeof(jvs_written_bytes);
jvs_uart.readable.bytes = jvs_readable_bytes;
hr = setupapi_add_phantom_dev(&jvs_guid, L"$jvs"); jvs_uart.readable.nbytes = sizeof(jvs_readable_bytes);
if (FAILED(hr)) {
return hr;
}
jvs_provider = provider; jvs_provider = provider;
return S_OK; return iohook_push_handler(jvs_handle_irp);
} }
static HRESULT jvs_handle_irp(struct irp *irp) static HRESULT jvs_handle_irp(struct irp *irp)
{ {
HRESULT hr;
assert(irp != NULL); assert(irp != NULL);
if (irp->op != IRP_OP_OPEN && irp->fd != jvs_fd) { if (!uart_match_irp(&jvs_uart, irp)) {
return iohook_invoke_next(irp); return iohook_invoke_next(irp);
} }
switch (irp->op) { EnterCriticalSection(&jvs_lock);
case IRP_OP_OPEN: return jvs_handle_open(irp); hr = jvs_handle_irp_locked(irp);
case IRP_OP_CLOSE: return jvs_handle_close(irp); LeaveCriticalSection(&jvs_lock);
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")) {
return iohook_invoke_next(irp);
}
if (jvs_fd != NULL) {
dprintf("JVS Port: Already open\n");
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");
if (jvs_provider != NULL) {
hr = jvs_provider(&root);
if (SUCCEEDED(hr)) {
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);
return hr; return hr;
} }
static HRESULT jvs_ioctl_sense(struct irp *irp) static HRESULT jvs_handle_irp_locked(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 #if 0
dprintf("\nJVS Port: Outbound frame:\n"); dprintf("\nJVS Port: Outbound frame:\n");
dump_const_iobuf(&irp->write); dump_const_iobuf(&irp->write);
#endif #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);
if (SUCCEEDED(hr)) {
jvs_root = root;
}
}
}
hr = uart_handle_irp(&jvs_uart, irp);
if (FAILED(hr) || irp->op != IRP_OP_WRITE) {
return hr;
}
jvs_bus_transact(jvs_root, irp->write.bytes, irp->write.nbytes, &irp->read); jvs_bus_transact(jvs_root, irp->write.bytes, irp->write.nbytes, &irp->read);
#if 0 #if 1
dprintf("JVS Port: Inbound frame:\n"); dprintf("JVS Port: Inbound frame:\n");
dump_iobuf(&irp->read); dump_iobuf(&irp->read);
dprintf("\n"); dprintf("\n");
@ -200,9 +116,9 @@ static HRESULT jvs_ioctl_transact(struct irp *irp)
if (irp->read.pos == 0) { if (irp->read.pos == 0) {
/* The un-acked JVS reset command must return ERROR_NO_DATA_DETECTED, /* The un-acked JVS reset command must return ERROR_NO_DATA_DETECTED,
and this error must always be returned asynchronously. And since and this error must always be returned asynchronously. And since
async I/O comes from the NT kernel, we have to return that win32 async I/O comes from the NT kernel, we have to return that win32
error as the equivalent NTSTATUS. */ error as the equivalent NTSTATUS. */
if (irp->ovl == NULL || irp->ovl->hEvent == NULL) { if (irp->ovl == NULL || irp->ovl->hEvent == NULL) {
return HRESULT_FROM_WIN32(ERROR_NO_DATA_DETECTED); return HRESULT_FROM_WIN32(ERROR_NO_DATA_DETECTED);

View File

@ -6,23 +6,18 @@ idmac_lib = static_library(
dependencies : [ dependencies : [
capnhook.get_variable('hook_dep'), capnhook.get_variable('hook_dep'),
], ],
link_with : [
jvs_lib,
hooklib_lib,
util_lib,
],
sources : [ sources : [
'idmac.c', 'idmac.c',
'idmac.h', 'idmac.h',
'config.c', 'config.c',
'config.h', 'config.h',
'ds.c',
'ds.h',
'eeprom.c',
'eeprom.h',
'gpio.c',
'gpio.h',
'guid.c', 'guid.c',
'jvs.c', 'jvs.c',
'jvs.h', 'jvs.h',
'nvram.c',
'nvram.h',
'sram.c',
'sram.h',
], ],
) )

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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
View 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
View 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
View 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',
],
)

View File

@ -44,7 +44,6 @@ crypt_lib = cc.find_library('crypt32')
inc = include_directories('.') inc = include_directories('.')
capnhook = subproject('capnhook') capnhook = subproject('capnhook')
subdir('idmac')
subdir('iccard') subdir('iccard')
subdir('board') subdir('board')
subdir('hooklib') subdir('hooklib')
@ -54,6 +53,9 @@ subdir('util')
subdir('gfxhook') subdir('gfxhook')
subdir('idmac_stub')
subdir('idmac')
subdir('sivaio') subdir('sivaio')
subdir('ll3io') subdir('ll3io')

View File

@ -3,7 +3,6 @@
#include <stdlib.h> #include <stdlib.h>
#include "idmac/config.h" #include "idmac/config.h"
#include "idmac/ds.h"
#include "hook/process.h" #include "hook/process.h"
@ -20,14 +19,12 @@ static process_entry_t app_startup;
static DWORD CALLBACK app_pre_startup(void) static DWORD CALLBACK app_pre_startup(void)
{ {
struct clock_config clock_cfg; struct clock_config clock_cfg;
struct ds_config ds_cfg;
struct ttxsec_config ttxsec_cfg; struct ttxsec_config ttxsec_cfg;
HRESULT hr; HRESULT hr;
dprintf("--- Begin %s ---\n", __func__); dprintf("--- Begin %s ---\n", __func__);
clock_config_load(&clock_cfg, L".\\taitools.ini"); clock_config_load(&clock_cfg, L".\\taitools.ini");
ds_config_load(&ds_cfg, L".\\taitools.ini");
ttxsec_config_load(&ttxsec_cfg, L".\\taitools.ini"); ttxsec_config_load(&ttxsec_cfg, L".\\taitools.ini");
spike_hook_init(L".\\taitools.ini"); spike_hook_init(L".\\taitools.ini");
@ -43,12 +40,6 @@ static DWORD CALLBACK app_pre_startup(void)
goto fail; goto fail;
} }
hr = ds_hook_init(&ds_cfg);
if (FAILED(hr)) {
goto fail;
}
dprintf("--- End %s ---\n", __func__); dprintf("--- End %s ---\n", __func__);
return app_startup(); return app_startup();

View File

@ -38,6 +38,7 @@ void siva_hook_config_load(
assert(cfg != NULL); assert(cfg != NULL);
assert(filename != NULL); assert(filename != NULL);
idmac_config_load(&cfg->idmac, filename);
platform_config_load(&cfg->platform, filename); platform_config_load(&cfg->platform, filename);
siva_dll_config_load(&cfg->dll, filename); siva_dll_config_load(&cfg->dll, filename);
gfx_config_load(&cfg->gfx, filename); gfx_config_load(&cfg->gfx, filename);

View File

@ -5,11 +5,13 @@
#include "sivahook/siva-dll.h" #include "sivahook/siva-dll.h"
#include "sivahook/touch.h" #include "sivahook/touch.h"
#include "idmac/config.h"
#include "platform/config.h" #include "platform/config.h"
#include "gfxhook/config.h" #include "gfxhook/config.h"
#include "board/config.h" #include "board/config.h"
struct siva_hook_config { struct siva_hook_config {
struct idmac_config idmac;
struct platform_config platform; struct platform_config platform;
struct siva_dll_config dll; struct siva_dll_config dll;
struct gfx_config gfx; struct gfx_config gfx;

View File

@ -7,11 +7,14 @@
#include "hooklib/serial.h" #include "hooklib/serial.h"
#include "hooklib/spike.h" #include "hooklib/spike.h"
#include "idmac/idmac.h"
#include "gfxhook/gfx.h" #include "gfxhook/gfx.h"
#include "gfxhook/d3d9.h" #include "gfxhook/d3d9.h"
#include "gfxhook/d3d11.h" #include "gfxhook/d3d11.h"
#include "gfxhook/dxgi.h" #include "gfxhook/dxgi.h"
#include "sivahook/reader.h"
#include "sivahook/config.h" #include "sivahook/config.h"
#include "sivahook/siva-dll.h" #include "sivahook/siva-dll.h"
#include "sivahook/touch.h" #include "sivahook/touch.h"
@ -68,6 +71,12 @@ static DWORD CALLBACK siva_pre_startup(void)
goto fail; goto fail;
} }
hr = idmac_hook_init(&siva_hook_cfg.idmac, siva_reader_init);
if (FAILED(hr)) {
goto fail;
}
unity_hook_init(); unity_hook_init();
/* Initialize debug helpers */ /* Initialize debug helpers */

View File

@ -11,10 +11,12 @@ shared_library(
], ],
link_with : [ link_with : [
gfxhook_lib, gfxhook_lib,
jvs_lib,
board_lib, board_lib,
hooklib_lib, hooklib_lib,
sivaio_lib, sivaio_lib,
platform_lib, platform_lib,
idmac_lib,
util_lib, util_lib,
], ],
sources : [ sources : [
@ -27,5 +29,7 @@ shared_library(
'unity.h', 'unity.h',
'touch.c', 'touch.c',
'touch.h', 'touch.h',
'reader.c',
'reader.h',
], ],
) )

44
sivahook/reader.c Normal file
View 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
View File

@ -0,0 +1,6 @@
#pragma once
#include <windows.h>
#include "jvs/jvs-bus.h"
HRESULT siva_reader_init(struct jvs_node **out);

View File

@ -13,6 +13,7 @@
#include "hooklib/reg.h" #include "hooklib/reg.h"
#include "hook/procaddr.h" #include "hook/procaddr.h"
#include "idmac/idmac.h"
#include "platform/cert.h" #include "platform/cert.h"
#include "platform/netenv.h" #include "platform/netenv.h"
@ -39,7 +40,10 @@ static const wchar_t *target_modules[] = {
L"NESiCAReader.dll", 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 target_modules_len = _countof(target_modules);
static const size_t dep_hooks_len = _countof(dep_hooks); 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); createprocess_hook_insert_hook(result);
dns_hook_apply_hooks(result); dns_hook_apply_hooks(result);
netenv_hook_apply(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++) { for (size_t i = 0; i < dep_hooks_len; i++) {