Browse Source

Quite a lot has happened; I lose track

master
Bottersnike 3 months ago
parent
commit
f02db82030
  1. 15
      .gitignore
  2. 142
      Makefile
  3. 62
      assert_dd_blocks.py
  4. 76
      meson.build
  5. 159
      mxinstaller.py
  6. 307
      src/micetools/dll/comdevice.c
  7. 75
      src/micetools/dll/comdevice.h
  8. 49
      src/micetools/dll/common.h
  9. 13
      src/micetools/dll/devices/_devices.c
  10. 15
      src/micetools/dll/devices/_devices.h
  11. 90
      src/micetools/dll/devices/aime_bd.c
  12. 447
      src/micetools/dll/devices/led_bd.c
  13. 9
      src/micetools/dll/devices/meson.build
  14. 168
      src/micetools/dll/devices/touch_bd.c
  15. 181
      src/micetools/dll/dllmain.c
  16. 146
      src/micetools/dll/drivers/columba.c
  17. 52
      src/micetools/dll/drivers/mx.h
  18. 771
      src/micetools/dll/drivers/mxjvs.c
  19. 702
      src/micetools/dll/drivers/mxsmbus.c
  20. 251
      src/micetools/dll/drivers/mxsram.c
  21. 682
      src/micetools/dll/drivers/mxsuperio.c
  22. 38
      src/micetools/dll/hooks/README.md
  23. 26
      src/micetools/dll/hooks/_hooks.c
  24. 26
      src/micetools/dll/hooks/_hooks.h
  25. 383
      src/micetools/dll/hooks/com.c
  26. 100
      src/micetools/dll/hooks/com.h
  27. 398
      src/micetools/dll/hooks/drive.c
  28. 43
      src/micetools/dll/hooks/drive.h
  29. 621
      src/micetools/dll/hooks/files.c
  30. 170
      src/micetools/dll/hooks/files.h
  31. 202
      src/micetools/dll/hooks/logging.c
  32. 33
      src/micetools/dll/hooks/logging.h
  33. 22
      src/micetools/dll/hooks/meson.build
  34. 218
      src/micetools/dll/hooks/network.c
  35. 76
      src/micetools/dll/hooks/processes.c
  36. 5
      src/micetools/dll/hooks/registry.c
  37. 4
      src/micetools/dll/hooks/registry.h
  38. 51
      src/micetools/dll/meson.build
  39. 85
      src/micetools/dll/smbus.h
  40. 330
      src/micetools/dll/util/log.c
  41. 69
      src/micetools/dll/util/log.h
  42. 46
      src/micetools/dll/w83627uhg.h
  43. 177
      src/micetools/launcher/main.c
  44. 88
      src/micetools/lib/am/amEeprom.c
  45. 13
      src/micetools/lib/am/amEeprom.h
  46. 38
      src/micetools/lib/am/amtimer.c
  47. 16
      src/micetools/lib/am/meson.build
  48. 227
      src/micetools/lib/dmi/dmi.c
  49. 120
      src/micetools/lib/dmi/dmi.h
  50. 1636
      src/micetools/lib/json/json.c
  51. 1
      src/micetools/lib/libpcp/libpcp.c
  52. 46
      src/micetools/lib/libpcp/meson.build
  53. 3
      src/micetools/lib/libpcp/pcp.c
  54. 144
      src/micetools/lib/libpcp/pcp.h
  55. 630
      src/micetools/lib/libpcp/pcpa.c
  56. 152
      src/micetools/lib/libpcp/pcpa.h
  57. 1758
      src/micetools/lib/libpcp/pcpp.c
  58. 182
      src/micetools/lib/libpcp/pcpp.h
  59. 758
      src/micetools/lib/libpcp/pcpt.c
  60. 130
      src/micetools/lib/libpcp/pcpt.h
  61. 87
      src/micetools/lib/libpcp/util.c
  62. 24
      src/micetools/lib/meson.build
  63. 251
      src/micetools/lib/mice/exe.c
  64. 125
      src/micetools/lib/mice/ioctl.h
  65. 456
      src/micetools/lib/mice/patch.c
  66. 16
      src/micetools/meson.build
  67. 4
      src/micetools/miceboot/TrueCrypt.cmd
  68. 150
      src/micetools/miceboot/ewfapi.h
  69. 31
      src/micetools/miceboot/meson.build
  70. 105
      src/micetools/miceboot/mice_ewfapi.h
  71. 8
      src/micetools/miceboot/mxmaster.c
  72. 216
      src/micetools/miceboot/mxprestartup.c
  73. 410
      src/micetools/miceboot/mxstartup.c
  74. 5
      src/micetools/miceboot/truecrypt.c
  75. 154
      src/micetools/micekeychip/callbacks/appboot.c
  76. 222
      src/micetools/micekeychip/callbacks/billing.c
  77. 70
      src/micetools/micekeychip/callbacks/tracedata.c
  78. 52
      src/micetools/micekeychip/meson.build
  79. 315
      src/micetools/micekeychip/mxk.c
  80. 226
      src/micetools/micepatch/main.c
  81. 6
      src/micetools/micetest/main.c
  82. 7
      src/micetools/micetest/meson.build
  83. 29
      src/micetools/util/meson.build
  84. 271
      src/micetools/util/micedump.c
  85. 14
      src/micetools/util/micemonitor.c
  86. 57
      src/micetools/util/micetinker.c
  87. 9
      src/patches/mxgfetcher.patch.json
  88. 107
      src/patches/patches.json

15
.gitignore vendored

@ -1,10 +1,5 @@
dist/
build/
builddir/
srcdir/
.vscode/
# Don't distribute the libpcp sources
src/micetools/lib/libpcp/*.c
# And keep build artifacts out of git!
src/libpcp.lib
dist/
build/
builddir/
srcdir/
.vscode/

142
Makefile

@ -1,63 +1,79 @@
BUILD_DIR := build
BUILD_DIR_32 := $(BUILD_DIR)/build32
BUILD_DIR_64 := $(BUILD_DIR)/build64
DIST_DIR := dist
BUILD_DRIVE := M:
MICE_32 := "$(BUILD_DIR_32)/src\mice.exe"
MICE_64 := "$(BUILD_DIR_64)/src\mice.exe"
VCVARS_32 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat"
VCVARS_64 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat"
# For windows XP:
# VCVARS_32 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" -vcvars_ver=14.16
# VCVARS_64 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" -vcvars_ver=14.16
.ONESHELL:
.PHONY: all
all: mice86 dist
mice86:
[email protected] $(BUILD_DRIVE) .
@cd /D $(BUILD_DRIVE) \
& $(VCVARS_32) \
& meson setup --cross cross-32.ini $(BUILD_DRIVE)\$(BUILD_DIR_32) \
& meson compile -C $(BUILD_DRIVE)\$(BUILD_DIR_32)
@subst $(BUILD_DRIVE) /D
mice64:
[email protected] $(BUILD_DRIVE) .
@cd $(BUILD_DRIVE) \
& $(VCVARS_64) \
& meson setup --cross cross-64.ini $(BUILD_DRIVE)\$(BUILD_DIR_64) \
& meson compile -C $(BUILD_DRIVE)\$(BUILD_DIR_64)
@subst $(BUILD_DRIVE) /D
.PHONY: clean
clean:
@del /S /F /Q $(BUILD_DIR)
@rmdir /S /Q $(BUILD_DIR)
@del /S /F /Q $(DIST_DIR)
@rmdir /S /Q $(DIST_DIR)
.PHONY: dist
dist:
@-mkdir $(DIST_DIR)
@copy /Y "$(BUILD_DIR_32)/src/micetools/micekeychip\micekeychip.exe" "$(DIST_DIR)/micekeychip.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/micepatch\micepatch.exe" "$(DIST_DIR)/micepatch.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/lib/libpcp\libpcp.lib" "$(DIST_DIR)/libpcp.lib"
@copy /Y "$(BUILD_DIR_32)/src/micetools/launcher\mice.exe" "$(DIST_DIR)/mice86.exe"
# @copy /Y "$(BUILD_DIR_32)/src/micetools/launcher\mice.pdb" "$(DIST_DIR)/mice86.pdb"
@copy /Y "$(BUILD_DIR_32)/src/micetools/dll\mice.pdb" "$(DIST_DIR)/mice86.pdb"
@copy /Y "$(BUILD_DIR_32)/src/micetools/dll\mice.dll" "$(DIST_DIR)/mice86.dll"
# @copy /Y "$(BUILD_DIR_64)/src/micetools/launcher\mice.exe" "$(DIST_DIR)/mice64.exe"
# @copy /Y "$(BUILD_DIR_64)/src/micetools/dll\mice.dll" "$(DIST_DIR)/mice64.dll"
@xcopy /E /H /C /R /Q /Y src\system "$(DIST_DIR)\system/*"
@xcopy /E /H /C /R /Q /Y src\tools "$(DIST_DIR)\tools/*"
@xcopy /E /H /C /R /Q /Y src\patches "$(DIST_DIR)\patches/*"
BUILD_DIR := build
BUILD_DIR_32 := $(BUILD_DIR)/build32
BUILD_DIR_64 := $(BUILD_DIR)/build64
DIST_DIR := dist
BUILD_DRIVE := M:
MICE_32 := "$(BUILD_DIR_32)/src\mice.exe"
MICE_64 := "$(BUILD_DIR_64)/src\mice.exe"
VCVARS_32 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat"
VCVARS_64 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat"
# For windows XP:
# VCVARS_32 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars32.bat" -vcvars_ver=14.16
# VCVARS_64 := "C:\\Program Files (x86)\\Microsoft Visual Studio\\2019\\Community\\VC\\Auxiliary\\Build\\vcvars64.bat" -vcvars_ver=14.16
.ONESHELL:
.PHONY: all
all: mice86 dist
mice86:
[email protected] $(BUILD_DRIVE) .
@cd /D $(BUILD_DRIVE) \
& $(VCVARS_32) \
& meson setup --cross cross-32.ini $(BUILD_DRIVE)\$(BUILD_DIR_32) \
& meson compile -C $(BUILD_DRIVE)\$(BUILD_DIR_32)
@subst $(BUILD_DRIVE) /D
mice64:
[email protected] $(BUILD_DRIVE) .
@cd $(BUILD_DRIVE) \
& $(VCVARS_64) \
& meson setup --cross cross-64.ini $(BUILD_DRIVE)\$(BUILD_DIR_64) \
& meson compile -C $(BUILD_DRIVE)\$(BUILD_DIR_64)
@subst $(BUILD_DRIVE) /D
.PHONY: clean
clean:
@del /S /F /Q $(BUILD_DIR)
@rmdir /S /Q $(BUILD_DIR)
@del /S /F /Q $(DIST_DIR)
@rmdir /S /Q $(DIST_DIR)
.PHONY: dist
dist:
@-mkdir $(DIST_DIR) > NUL 2>&1
@-mkdir $(DIST_DIR)\util > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute\Z > NUL 2>&1
@-mkdir $(DIST_DIR)\Execute\S > NUL 2>&1
@copy /Y "$(BUILD_DIR_32)/src/micetools/micekeychip\micekeychip.exe" "$(DIST_DIR)/micekeychip.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/lib/libpcp\libpcp.lib" "$(DIST_DIR)/libpcp.lib"
@copy /Y "$(BUILD_DIR_32)/src/micetools/launcher\mice.exe" "$(DIST_DIR)/mice86.exe"
# @copy /Y "$(BUILD_DIR_32)/src/micetools/launcher\mice.pdb" "$(DIST_DIR)/mice86.pdb"
@copy /Y "$(BUILD_DIR_32)/src/micetools/dll\mice.pdb" "$(DIST_DIR)/mice86.pdb"
@copy /Y "$(BUILD_DIR_32)/src/micetools/dll\mice.dll" "$(DIST_DIR)/mice86.dll"
# @copy /Y "$(BUILD_DIR_64)/src/micetools/launcher\mice.exe" "$(DIST_DIR)/mice64.exe"
# @copy /Y "$(BUILD_DIR_64)/src/micetools/dll\mice.dll" "$(DIST_DIR)/mice64.dll"
@copy /Y "$(BUILD_DIR_32)/src/micetools/miceboot\miceprestartup.exe" "$(DIST_DIR)/Execute/miceprestartup.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/miceboot\micestartup.exe" "$(DIST_DIR)/Execute/micestartup.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/miceboot\TrueCrypt.exe" "$(DIST_DIR)/Execute/TrueCrypt.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/miceboot\mxmaster.exe" "$(DIST_DIR)/Execute/S/mxmaster.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/micepatch\micepatch.exe" "$(DIST_DIR)/util/micepatch.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/util\micedump.exe" "$(DIST_DIR)/util/micedump.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/util\micetinker.exe" "$(DIST_DIR)/util/micetinker.exe"
@copy /Y "$(BUILD_DIR_32)/src/micetools/util\micemonitor.exe" "$(DIST_DIR)/util/micemonitor.exe"
@copy /Y "src/micetools/miceboot\TrueCrypt.cmd" "$(DIST_DIR)/Execute/TrueCrypt.cmd"
@xcopy /E /H /C /R /Q /Y src\system "$(DIST_DIR)\system/*"
@xcopy /E /H /C /R /Q /Y src\tools "$(DIST_DIR)\tools/*"
@xcopy /E /H /C /R /Q /Y src\patches "$(DIST_DIR)\patches/*"

62
assert_dd_blocks.py

@ -0,0 +1,62 @@
MBR_LBA_GAP = 0x3f
BOOT_PARITION_SIZE = 0x300B85
RECOVER_PARTITION_SIZE = 0x300BC4
partitions = [
0x102d83,
0x403947,
0x403947,
0x48ed459,
0x20014aa,
]
ext_offset = 0
offsets = [0] * len(partitions)
extended_base = MBR_LBA_GAP + BOOT_PARITION_SIZE + RECOVER_PARTITION_SIZE
for i in range(len(partitions)):
offsets[i] = ext_offset + extended_base
ext_offset += partitions[i] + MBR_LBA_GAP
# (Start, end, data)
accounted_for = [
(0, 1, True), # MBR
(1, MBR_LBA_GAP, False),
(MBR_LBA_GAP, MBR_LBA_GAP + BOOT_PARITION_SIZE, True),
(MBR_LBA_GAP + BOOT_PARITION_SIZE, MBR_LBA_GAP + BOOT_PARITION_SIZE + RECOVER_PARTITION_SIZE, True),
]
for n, (i, j) in enumerate(zip(offsets, partitions)):
accounted_for.append((
i, i + 1, True
))
if n == 0:
# SBR
accounted_for.append((
i + 1, i + 4, True
))
accounted_for.append((
i + 4, i + MBR_LBA_GAP, False
))
else:
accounted_for.append((
i + 1, i + MBR_LBA_GAP, False
))
accounted_for.append((
i + MBR_LBA_GAP, i + MBR_LBA_GAP + j, True
))
assert accounted_for[-1][1] == 0x77fa1d7
last = 0
for i in accounted_for:
assert i[0] == last
last = i[1]
with open(r"G:\finale_dd\finale_dd.img", "rb") as finale_dd:
for i in accounted_for:
if i[2]:
continue
nbytes = i[1] - i[0]
finale_dd.seek(i[0] * 512)
print(f"Checking at {i[0] * 512:012x}-{i[1] * 512:012x}")
if any(finale_dd.read(nbytes * 512)):
print("!! FAIL")

76
meson.build

@ -1,30 +1,46 @@
project('micetools', 'c', default_options: [
'buildtype=minsize',
# ! Tobble /\ and \/ when building for XP (minsize=normal, static=XP)
# 'b_vscrt=static_from_buildtype',
'warning_level=2',
])
winxp = false
subsystem = 'console,5.01'
if (host_machine.cpu_family() == 'x86')
add_project_arguments('-DMICE_WIN32', language: 'c')
endif
add_project_arguments(
'/DWIN32_LEAN_AND_MEAN', # Strip out headers we don't really need
'/D_WIN32_WINNT=_WIN32_WINNT_WINXP', # hahahahaha I hate it
language: 'c',
)
if winxp
add_project_arguments(
'/D_USING_V140_SDK71_',
'/DSFML_STATIC',
'/DYNAMICBASE:NO',
language: 'c',
)
endif
subdir('assets')
subdir('src')
project('micetools', 'c', default_options: [
'buildtype=minsize',
# ! Toggle /\ and \/ when building for XP (minsize=normal, static=XP)
# 'b_vscrt=static_from_buildtype',
'warning_level=3',
])
winxp = false
subsystem = 'console,5.01'
if (host_machine.cpu_family() == 'x86')
add_project_arguments('-DMICE_WIN32', language: 'c')
endif
add_project_arguments(
'/DWIN32_LEAN_AND_MEAN', # Strip out headers we don't really need
'/D_WIN32_WINNT=_WIN32_WINNT_WINXP', # hahahahaha I hate it
'/wd4706', # assignment within conditional expression
'/wd4214', # windns.h: nonstandard extension used: bit field types other than int
'/wd4201', # ewfapi.h: nameless struct/union
'/wd4200', # zero-sized arrays
'/wd4152', # hooks: function/data pointer conversion in expression
'/wd4100', # basically every hook causes "unreferenced formal parameter"
'/wd4206', # empty C files
'/wd4189', # lots of keychip functions aren't 100% implemented yet
'/we4047', # ... differs in levels of indirection from ...
'/we4057', # ... differs in levels of indirection (slightly) from ...
'/we4024', # ... different types for formal and actual paramter ...
'/we4013', # ... undefined; assuming extern returning int
language: 'c',
)
if winxp
add_project_arguments(
'/D_USING_V140_SDK71_',
'/DSFML_STATIC',
'/DYNAMICBASE:NO',
language: 'c',
)
endif
subdir('assets')
subdir('src')

159
mxinstaller.py

@ -0,0 +1,159 @@
from pprint import pformat, pprint
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(("127.0.0.1", 12121))
slots = [
"original0",
"original1",
"patch0",
"patch1",
"os",
"app_data",
"originalf",
"originalb",
"patchf",
"patchb",
]
"""
slot 0: OS
os result=success&status=complete&id=AAS0&version=4524545&time=00000000000000&segcount=1745&segsize=262144&hw=AAS&instant=0&osver=4524545&ossegcount=0&orgtime=00000000000000&orgversion=4524545
slot 1: original0
original0 result=success&status=complete&id=SDEY&version=65633&time=20181029150736&segcount=65082&segsize=262144&hw=AAS&instant=0&osver=4524545&ossegcount=1745&orgtime=20181029150736&orgversion=65633
slot 2: ??
slot 3: ??
slot 4: ??
original1 result=error&status=error&code=40
patch0 result=success&status=empty
patch1 result=success&status=complete&id=SDEY&version=65634&time=20181116190448&segcount=173&segsize=262144&hw=AAS&instant=0&osver=0&ossegcount=0&orgtime=20181029150736&orgversion=65633
app_data result=invalid_parameter
originalf result=success&status=complete&id=SDEY&version=65633&time=20181029150736&segcount=65082&segsize=262144&hw=AAS&instant=0&osver=4524545&ossegcount=1745&orgtime=20181029150736&orgversion=65633
originalb result=error&status=error&code=40
patchf result=success&status=complete&id=SDEY&version=65634&time=20181116190448&segcount=173&segsize=262144&hw=AAS&instant=0&osver=0&ossegcount=0&orgtime=20181029150736&orgversion=65633
patchb result=success&status=empty
"""
def recv_pcp():
resp = s.recv(4096).decode().strip()
if resp == "?":
raise Exception("PCP Failed")
parts = resp.split("&")
return {i.split("=")[0]: i.split("=")[1] for i in parts}
def send_pcp(request, **kwargs):
req = f"request={request}"
if kwargs:
req += "&" + "&".join(f"{i}={kwargs[i]}" for i in kwargs)
assert s.recv(4096) == b">"
s.send(req.encode() + b"\r\n")
def pcp(request, **kwargs):
send_pcp(request, **kwargs)
ret = recv_pcp()
if ret["result"] != "success" or ret["response"] != request:
raise Exception(f"PCP Failed:\n{pformat(ret)}")
del ret["response"]
del ret["result"]
return ret
print("Query slots:")
for slot in slots:
assert s.recv(4096) == b">"
s.send(f"request=query_slot_status&slot={slot}\r\n".encode())
print(slot.ljust(20), s.recv(4096).decode().strip())
# assert s.recv(4096) == b">"
# s.send(f"request=check&slot={slot}\r\n".encode())
# print(slot.ljust(20), s.recv(4096).decode().strip())
print("-" * 10)
if pcp("query_semaphore_status")["semaphore"] != "1":
print("Unable to get semaphore!")
quit()
gsem = pcp("get_semaphore")
semid = gsem["semid"]
try:
spd = pcp("query_spd")
br = pcp("query_br")
bootslot = pcp("query_sbr_bootslot")
print("=== SPD ===")
order = spd.pop("order")
print(f"--- Order: {order}")
spd = list(spd.items())
spd.sort(key=lambda x: int(x[1]))
for i in spd:
# Values here are uk3 * block_size
print(f" - {(i[0] + ':').ljust(10)} {int(i[1]):016x}")
print(f"--- Bootslot: {bootslot['bootslot']}")
print("=== BR ===")
pprint(br)
quit()
assert s.recv(4096) == b">"
s.send((
b"request=check&"
b"slot=original0&"
b"segoffset=0&"
b"segcount=100000&"
b"force=1&"
b"semid=" + sem + b""
b"\r\n"
))
print(s.recv(4096).decode().strip())
assert s.recv(4096) == b">"
s.send((
b"request=release_semaphore&"
b"semid=" + sem + b""
b"\r\n"
))
print(s.recv(4096).decode().strip())
quit()
# assert s.recv(4096) == b">"
# s.send(b"request=set_sbr_bootslot&bootslot=cd\r\n")
# print(s.recv(4096).decode().strip())
assert s.recv(4096) == b">"
s.send(b"request=query_application_status\r\n")
print(s.recv(4096).decode().strip())
assert s.recv(4096) == b">"
s.send(b"request=query_br\r\n")
print(s.recv(4096).decode().strip())
assert s.recv(4096) == b">"
s.send((
b"request=appdata&"
b"slot=os&"
b"semid=" + sem + b"&"
b"\r\n"
))
# s.send((
# b"request=install&"
# b"slot=patch0&"
# b"segoffset=3&"
# b"id=SDEY&"
# b"version=010061&"
# b"time=20181029150736&"
# b"segcount=fe3a&"
# b"segsize=040000&"
# b"hw=AAS&"
# b"instant=3&"
# b"osver=450a01&"
# b"ossegcount=06d1&"
# b"orgtime=20181029150736&"
# b"orgversion=10061&"
# b"semid=" + sem + b"&"
# b"\r\n"
# ))
print(s.recv(4096).decode().strip())
finally:
pcp("release_semaphore", semid=semid)

307
src/micetools/dll/comdevice.c

@ -1,116 +1,191 @@
#include "comdevice.h"
BOOL DevGetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevSetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevGetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetupComm(void* data, DWORD dwInQueue, DWORD dwOutQueue) { return TRUE; }
BOOL DevPurgeComm(void* data, DWORD dwFlags) {
if (dwFlags & PURGE_RXCLEAR) ringbuf_purge(&((com_device_t*)data)->out);
return TRUE;
}
BOOL DevGetCommModemStatus(void* data, LPDWORD lpModelStat) {
// TODO: JVS SENSE
return TRUE;
}
BOOL DevWaitCommEvent(void* data, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
WaitForSingleObject(((com_device_t*)data)->event, INFINITE);
if (lpOverlapped != NULL) SetEvent(lpOverlapped->hEvent);
return TRUE;
}
BOOL DevClearCommError(void* data, LPDWORD lpErrors, LPCOMSTAT lpStat) {
if (lpErrors != NULL) *lpErrors = 0;
if (lpStat != NULL) {
lpStat->fCtsHold = FALSE;
lpStat->fDsrHold = FALSE;
lpStat->fRlsdHold = FALSE;
lpStat->fXoffHold = FALSE;
lpStat->fXoffSent = FALSE;
lpStat->fEof = FALSE;
lpStat->fTxim = FALSE;
lpStat->fReserved = 0;
lpStat->cbInQue = ringbuf_available(&((com_device_t*)data)->out);
lpStat->cbOutQue = ringbuf_available(&((com_device_t*)data)->in);
}
return TRUE;
}
BOOL DevWriteFile(void* file, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten,
LPOVERLAPPED lpOverlapped) {
if (nNumberOfBytesToWrite > 0xffff) return FALSE;
// Ignore overflow
ringbuf_write(&((com_device_t*)file)->in, lpBuffer, nNumberOfBytesToWrite & 0xffff);
if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nNumberOfBytesToWrite;
return TRUE;
}
BOOL DevReadFile(void* file, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,
LPOVERLAPPED lpOverlapped) {
if (nNumberOfBytesToRead > 0xffff) return FALSE;
// Make sure we have at least one byte to return
// while (!ringbuf_available(&((com_device_t*)file)->out)) {
// WaitForSingleObject(((com_device_t*)file)->event, INFINITE);
// }
short read = ringbuf_read(&((com_device_t*)file)->out, lpBuffer, nNumberOfBytesToRead & 0xffff);
if (lpNumberOfBytesRead) *lpNumberOfBytesRead = read;
if (read != 0) {
// log_info("drf", "%d", read);
// for (int i = 0; i < read; i++) {
// printf("%02x ", ((unsigned char*)lpBuffer)[i]);
// }
// puts("");
}
return TRUE;
}
short comdev_read(com_device_t* com, unsigned char* buffer, short bytes) {
return ringbuf_read(&com->in, buffer, bytes);
}
bool comdev_write(com_device_t* com, unsigned char* buffer, short bytes) {
bool ret = ringbuf_write(&com->out, buffer, bytes);
SetEvent(com->event);
return ret;
}
short comdev_available(com_device_t* com) { return ringbuf_available(&com->in); }
void com_device_thread(com_device_t* com, FnComDeviceThread* thread) {
com->thread = CreateThread(NULL, 0, thread, com, 0, NULL);
}
com_device_t* new_com_device(BYTE port) {
com_device_t* hook = (com_device_t*)malloc(sizeof *hook);
com_hook_t* com = new_com_hook(port);
file_hook_t* file = new_file_hook(com->wName);
file->altFilename = com->wDosName;
com->data = hook;
file->data = hook;
hook->com = com;
hook->file = file;
com->GetCommState = DevGetCommState;
com->SetCommState = DevSetCommState;
com->GetCommTimeouts = DevGetCommTimeouts;
com->SetCommTimeouts = DevSetCommTimeouts;
com->SetupComm = DevSetupComm;
com->PurgeComm = DevPurgeComm;
com->GetCommModemStatus = DevGetCommModemStatus;
com->WaitCommEvent = DevWaitCommEvent;
com->ClearCommError = DevClearCommError;
file->ReadFile = DevReadFile;
file->WriteFile = DevWriteFile;
ringbuf_purge(&hook->in);
ringbuf_purge(&hook->out);
hook->event = CreateEventW(NULL, TRUE, FALSE, hook->com->wName);
hook_file(file);
hook_com(com);
free(com->virtual_handle);
com->virtual_handle = file->virtual_handle;
return hook;
}
#include "comdevice.h"
BOOL DevGetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevSetCommState(void* data, LPDCB lpDCB) { return TRUE; }
BOOL DevGetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetCommTimeouts(void* data, LPCOMMTIMEOUTS lpCommTimeouts) { return TRUE; }
BOOL DevSetupComm(void* data, DWORD dwInQueue, DWORD dwOutQueue) { return TRUE; }
BOOL DevPurgeComm(void* data, DWORD dwFlags) {
if (dwFlags & PURGE_RXCLEAR) ringbuf_purge(&((com_device_t*)data)->out);
return TRUE;
}
BOOL DevGetCommModemStatus(void* data, LPDWORD lpModelStat) {
// TODO: JVS SENSE
return TRUE;
}
BOOL DevWaitCommEvent(void* data, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
WaitForSingleObject(((com_device_t*)data)->event, INFINITE);
if (lpOverlapped != NULL) SetEvent(lpOverlapped->hEvent);
return TRUE;
}
BOOL DevClearCommError(void* data, LPDWORD lpErrors, LPCOMSTAT lpStat) {
if (lpErrors != NULL) *lpErrors = 0;
if (lpStat != NULL) {
lpStat->fCtsHold = FALSE;
lpStat->fDsrHold = FALSE;
lpStat->fRlsdHold = FALSE;
lpStat->fXoffHold = FALSE;
lpStat->fXoffSent = FALSE;
lpStat->fEof = FALSE;
lpStat->fTxim = FALSE;
lpStat->fReserved = 0;
lpStat->cbInQue = ringbuf_available(&((com_device_t*)data)->out);
lpStat->cbOutQue = ringbuf_available(&((com_device_t*)data)->in);
}
return TRUE;
}
BOOL DevWriteFile(void* file, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) {
if (nNumberOfBytesToWrite > 0xffff) return FALSE;
// Ignore overflow
ringbuf_write(&((com_device_t*)file)->in, lpBuffer, nNumberOfBytesToWrite & 0xffff);
if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nNumberOfBytesToWrite;
return TRUE;
}
BOOL DevReadFile(void* file, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) {
if (nNumberOfBytesToRead > 0xffff) return FALSE;
// Make sure we have at least one byte to return
// while (!ringbuf_available(&((com_device_t*)file)->out)) {
// WaitForSingleObject(((com_device_t*)file)->event, INFINITE);
// }
short read = ringbuf_read(&((com_device_t*)file)->out, lpBuffer, nNumberOfBytesToRead & 0xffff);
if (lpNumberOfBytesRead) *lpNumberOfBytesRead = read;
if (read != 0) {
// log_info("drf", "%d", read);
// for (int i = 0; i < read; i++) {
// printf("%02x ", ((LPBYTE)lpBuffer)[i]);
// }
// puts("");
}
return TRUE;
}
short comdev_read_blocking(com_device_t* com, unsigned char* buffer, short bytes) {
while (comdev_available(com) < bytes) SwitchToThread();
return ringbuf_read(&com->in, buffer, bytes);
}
short comdev_read(com_device_t* com, unsigned char* buffer, short bytes) {
return ringbuf_read(&com->in, buffer, bytes);
}
bool comdev_write(com_device_t* com, const unsigned char* buffer, short bytes) {
bool ret = ringbuf_write(&com->out, buffer, bytes);
SetEvent(com->event);
return ret;
}
short comdev_available(com_device_t* com) { return ringbuf_available(&com->in); }
BYTE comdev_peek(com_device_t* com) { return com->in.buffer[com->in.read]; }
BYTE one_byte;
// Read data from a com device, unescaping as we go
void comio_read(com_device_t* com, BYTE* data, BYTE len) {
for (; len; len--) {
comdev_read_blocking(com, &one_byte, 1);
if (one_byte == COMIO_MARK) {
comdev_read_blocking(com, &one_byte, 1);
one_byte++;
}
*(data++) = one_byte;
}
}
// Write data to a com device, escaping as we go
void comio_write(com_device_t* com, BYTE* data, BYTE len) {
for (; len; len--) {
one_byte = *(data++);
if (one_byte == COMIO_MARK || one_byte == COMIO_SYNC) {
BYTE mark = COMIO_MARK;
comdev_write(com, &mark, 1);
one_byte--;
}
comdev_write(com, &one_byte, 1);
}
}
void comio_next_req(com_device_t* com, comio_recv_head_t* head, BYTE* data) {
do {
if (comdev_available(com) < (sizeof *head + 1)) {
SwitchToThread();
continue;
}
comdev_read(com, &one_byte, 1);
if (one_byte != COMIO_SYNC) {
log_error("com", "Garbage on JVS: %02x", one_byte);
continue;
}
break;
} while (1);
comio_read(com, (LPBYTE)head, sizeof *head);
// TODO: Validate the sum? Do we care really?
comio_read(com, data, head->length);
unsigned char sum;
comio_read(com, &sum, 1);
}
void comio_reply(com_device_t* com, comio_recv_head_t* req, BYTE status, BYTE len,
BYTE* data) {
one_byte = COMIO_SYNC;
comdev_write(com, &one_byte, 1);
comio_resp_head_t resp = {
.frame_length = len + sizeof resp,
.src = req->dst,
.seq = req->seq,
.status = status,
.op = req->op,
.length = len,
};
// Header
comio_write(com, (LPBYTE)&resp, sizeof resp);
// Payload
if (len) // If len == 0, we allow data to be null
comio_write(com, data, len);
// Checksum
one_byte = 0;
for (BYTE i = 0; i < sizeof resp; i++)
one_byte += ((LPBYTE)&resp)[i];
for (BYTE i = 0; i < len; i++)
one_byte += data[i];
comio_write(com, &one_byte, 1);
}
void com_device_thread(com_device_t* com, FnComDeviceThread* thread) {
com->thread = CreateThread(NULL, 0, thread, com, 0, NULL);
}
com_device_t* new_com_device(BYTE port) {
com_device_t* hook = (com_device_t*)malloc(sizeof *hook);
com_hook_t* com = new_com_hook(port);
file_hook_t* file = new_file_hook(com->wName);
file->altFilename = com->wDosName;
com->data = hook;
file->data = hook;
hook->com = com;
hook->file = file;
com->GetCommState = DevGetCommState;
com->SetCommState = DevSetCommState;
com->GetCommTimeouts = DevGetCommTimeouts;
com->SetCommTimeouts = DevSetCommTimeouts;
com->SetupComm = DevSetupComm;
com->PurgeComm = DevPurgeComm;
com->GetCommModemStatus = DevGetCommModemStatus;
com->WaitCommEvent = DevWaitCommEvent;
com->ClearCommError = DevClearCommError;
file->ReadFile = DevReadFile;
file->WriteFile = DevWriteFile;
ringbuf_purge(&hook->in);
ringbuf_purge(&hook->out);
hook->event = CreateEventW(NULL, TRUE, FALSE, hook->com->wName);
hook_file(file);
hook_com(com);
return hook;
}

75
src/micetools/dll/comdevice.h

@ -1,23 +1,54 @@
#pragma once
#include "hooks/com.h"
#include "common.h"
#include "hooks/files.h"
typedef struct com_device {
com_hook_t* com;
file_hook_t* file;
ring_buffer_t in;
ring_buffer_t out;
HANDLE event;
HANDLE thread;
} com_device_t;
typedef DWORD(WINAPI FnComDeviceThread)(com_device_t* com);
short comdev_read(com_device_t* com, unsigned char* buffer, short bytes);
bool comdev_write(com_device_t* com, unsigned char* buffer, short bytes);
short comdev_available(com_device_t* com);
void com_device_thread(com_device_t* com, FnComDeviceThread* thread);
#pragma once
#include "common.h"
#include "hooks/com.h"
#include "hooks/files.h"
typedef struct com_device {
com_hook_t* com;
file_hook_t* file;
ring_buffer_t in;
ring_buffer_t out;
HANDLE event;
HANDLE thread;
} com_device_t;
typedef struct {
BYTE frame_length;
BYTE dst;
BYTE seq;
BYTE op;
BYTE length;
} comio_recv_head_t;
typedef struct {
BYTE frame_length;
BYTE src;
BYTE seq;
BYTE op;
BYTE status;
BYTE length;
} comio_resp_head_t;
#define COMIO_SYNC 0xE0
#define COMIO_MARK 0xD0
#define COMIO_STATUS_OK 0
#define COMIO_STATUS_NG 1
typedef DWORD(WINAPI FnComDeviceThread)(com_device_t* com);
short comdev_read_blocking(com_device_t* com, unsigned char* buffer, short bytes);
short comdev_read(com_device_t* com, unsigned char* buffer, short bytes);
bool comdev_write(com_device_t* com, const unsigned char* buffer, short bytes);
short comdev_available(com_device_t* com);
BYTE comdev_peek(com_device_t* com);
void comio_read(com_device_t* com, BYTE* data, BYTE len);
void comio_write(com_device_t* com, BYTE* data, BYTE len);
void comio_next_req(com_device_t* com, comio_recv_head_t* head, BYTE* data);
void comio_reply(com_device_t* com, comio_recv_head_t* req, BYTE status, BYTE len, BYTE* data);
void com_device_thread(com_device_t* com, FnComDeviceThread* thread);
com_device_t* new_com_device(BYTE port);

49
src/micetools/dll/common.h

@ -1,24 +1,25 @@
#pragma once
#include <Windows.h>
#include <Winsock2.h>
#include <initguid.h>
#include <windns.h>
#pragma comment(lib, "Shlwapi.lib")
#include <shlwapi.h>
#pragma comment(lib, "d3d9.lib")
#include <d3d9.h>
#pragma comment(lib, "comctl32.lib")
#include <Iphlpapi.h>
#include <commctrl.h>
#include <memory.h>
#include <setupapi.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../lib/mice/mice.h"
#include "./util/_util.h"
#pragma once
#include <Windows.h>
#include <Winsock2.h>
#include <initguid.h>
#include <windns.h>
#pragma comment(lib, "Shlwapi.lib")
#include <shlwapi.h>
#pragma comment(lib, "d3d9.lib")
#include <d3d9.h>
#pragma comment(lib, "comctl32.lib")
#include <Iphlpapi.h>
#include <commctrl.h>
#include <memory.h>
#include <setupapi.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "../lib/mice/mice.h"
#include "./util/_util.h"

13
src/micetools/dll/devices/_devices.c

@ -1,6 +1,7 @@
#include "_devices.h"
void install_devices() {
install_led_bd();
install_touch_bd();
}
#include "_devices.h"
void install_devices() {
install_led_bd();
install_touch_bd();
install_aime_bd();
}

15
src/micetools/dll/devices/_devices.h

@ -1,8 +1,9 @@
#pragma once
#include "../comdevice.h"
#include "../common.h"
void install_led_bd();
void install_touch_bd();
#pragma once
#include "../comdevice.h"
#include "../common.h"
void install_led_bd();
void install_touch_bd();
void install_aime_bd();
void install_devices();

90
src/micetools/dll/devices/aime_bd.c

@ -0,0 +1,90 @@
#include "_devices.h"
static BYTE read_one(com_device_t* dev) {
while (!comdev_available(dev)) Sleep(50);
BYTE data;
comdev_read(dev, &data, 1);
return data;
}
BYTE extra[0xff];
#define GetFWVersion 0x30
#define GetHWVersion 0x32
#define RadioOn 0x40
#define RadioOff 0x41
#define Poll 0x2
#define MifareSelectTag 0x43
#define Unknown1 0x44 // Present in code, not seen used
#define SetKeyBana 0x50
#define Unknown2 0x51 // Present in code, not seen used
#define ReadBlock 0x52
#define SetKeyAime 0x54
#define Authenticate 0x55
#define Unknown3 0x60 // Present in code, not seen used
#define Unknown4 0x61 // Present in code, not seen used
#define Reset 0x62
#define Unknown5 0x70 // Present in code, not seen used
#define FelicaEncap 0x71
#define LedReset 0xf5
#define LedGetInfo 0xf0
#define LedSetColour 0x81
#define FWVer "TN32MSEC003S F/W Ver1.2"
#define HWVer "TN32MSEC003S H/W Ver3.0"
DWORD WINAPI aime_bd_thread(com_device_t* dev) {
log_warning("aime_bd", "%ls woke up", dev->com->wName);
while (1) {
comio_recv_head_t req;
comio_next_req(dev, &req, extra);
log_info("aime_bd", "(%d) %02x", req.dst, req.op);
if (req.dst == 0x00 || req.dst == 0x01) {
// Aime readers
switch (req.op) {
case Reset:
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
break;
case GetFWVersion:
comio_reply(dev, &req, COMIO_STATUS_OK, sizeof FWVer - 1, (LPBYTE)FWVer);
break;
case GetHWVersion:
comio_reply(dev, &req, COMIO_STATUS_OK, sizeof HWVer - 1, (LPBYTE)HWVer);
break;
case SetKeyAime:
log_info("aime_bd", "Aime key: %.*s", req.length, extra);
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
break;
case SetKeyBana:
log_info("aime_bd", "Bana key: %.*s", req.length, extra);
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
break;
}
} else if (req.dst == 0x08 || req.dst == 0x09) {
// LED sub-boards
switch (req.op) {
case LedReset:
comio_reply(dev, &req, COMIO_STATUS_OK, 0, NULL);
break;
case LedGetInfo:
// TODO: I'm not sure what this actually means.
// 838-15084 is probably a part number
comio_reply(dev, &req, COMIO_STATUS_OK, 9, (BYTE*)"15084\xff\x10\x00\x12");
break;
case LedSetColour:
// No response expected here!
break;
}
}
Sleep(50);
}
}
void install_aime_bd() {
com_device_t* aime = new_com_device(2);
com_device_thread(aime, aime_bd_thread);
}

447
src/micetools/dll/devices/led_bd.c

@ -1,225 +1,222 @@
#include "../hooks/gui.h"
#include "_devices.h"
/*
[0] = e0
[1] = dest?
[2] = dst?
[3] = length
[4] = op code
[...] length-1 bytes
[.] = sum
[0] = e0
[2] = dst?
[1] = dest?
[3] = length
[4] = status
[5] = op
[6] = report
[...]
[.] = sum
OP codes:
3c: FUN_005735c0 (1)
10: FUN_00580c00 (1)
7c: FUN_00580c00 (2)
3c: FUN_00580c00 (1)
39: FUN_00580c00 (4)
3b: FUN_00580c00 (1)
31: FUN_00581350 (5)
32: FUN_005813b0 (8)
33: FUN_00581430 (8) -> something at [16]??
39: FUN_005814b0 (4)
3f: FUN_00581220 (7)
7b: FUN_005812a0 (3)
7c: FUN_00581310 (2)
01: was this just an error?
10:
31: Set button. [button] [r] [g] [b]
0-7 = buttons
8 = woofer
9 = center
32: Set multiple. [00] [idx hi] [idx lo] [r] [g] [b]
33: Fade multiple?. [09] [?] [?] [r] [g] [b]
39: Set body light. [intensity] [-] [-]
3b:
3c: Commit?
3f:
7c:
7b:
initial setup: 7c 0-7, 32, 3c, 39, 3f, 3b
*/
unsigned char COLOURS[10][3];
double positions[10][2] = {
{ 0.337963, 0.470833 }, { 0.469444, 0.619792 }, { 0.469444, 0.828125 }, { 0.337037, 0.977083 },
{ 0.152778, 0.976042 }, { 0.020370, 0.828125 }, { 0.020370, 0.618750 }, { 0.151852, 0.472917 },
{ 0.5, 0.75 }, { 0.5, 0.5 },
};
typedef struct rs232c_recv_head {
BYTE sync;
BYTE src;
BYTE dst;
BYTE length;
BYTE op;
} rs232c_recv_head_t;
static DWORD WINAPI led_bd_thread(com_device_t* dev) {
log_warning("led_bd", "%ls woke up", dev->com->wName);
while (1) {
rs232c_recv_head_t head;
if (comdev_available(dev) < sizeof head) {
// Sleep(100);
continue;
}
comdev_read(dev, (char*)&head, sizeof head);
unsigned char* extra = malloc(head.length);
comdev_read(dev, extra, head.length);
// log_info("led_bd", "Bound %02x->%02x", head.src, head.dst);
switch (head.op) {
case 0x01:
log_warning("led_bd", "01");
comdev_write(dev, "\xe0\x01\x11\x03\x01\x01\x01\x18", 8);
// syn dst src len sts op. rep chk
break;
case 0x10:
log_warning("led_bd", "10");
comdev_write(dev, "\xe0\x01\x11\x03\x01\x10\x01\x27", 8);
// syn dst src len sts op. rep chk
break;
case 0x31:
COLOURS[extra[0]][0] = extra[1];
COLOURS[extra[0]][1] = extra[2];
COLOURS[extra[0]][2] = extra[3];
log_warning("led_bd", "31: %02x = (%02x %02x %02x)", extra[0], extra[1], extra[2], extra[3]);
comdev_write(dev, "\xe0\x01\x11\x03\x01\x31\x01\x48", 8);
// syn dst src len sts op. rep chk
break;
case 0x32:
log_warning("led_bd", "32: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1], extra[2], extra[3],
extra[4], extra[5], extra[6], extra[7]);
for (unsigned char i = extra[2] - 1; i < extra[1]; i++) {
COLOURS[i][0] = extra[3];
COLOURS[i][1] = extra[4];
COLOURS[i][2] = extra[5];
}
comdev_write(dev, "\xe0\x01\x11\x03\x01\x32\x01\x49", 8);
// syn dst src len sts op. rep chk
break;
case 0x33:
log_warning("led_bd", "33: %02x %02x %02x %02x %02x %02x %02x", extra[0], extra[1], extra[2], extra[3],
extra[4], extra[5], extra[6], extra[7]);
comdev_write(dev, "\xe0\x01\x11\x03\x01\x33\x01\x4a", 8);
// syn dst src len sts op. rep chk
COLOURS[extra[0]][0] = extra[extra[5]];
COLOURS[extra[0]][1] = extra[extra[6]];
COLOURS[extra[0]][2] = extra[extra[7]];
break;
case 0x39:
log_warning("led_bd", "39: %02x %02x %02x", extra[0], extra[1], extra[2]);
comdev_write(dev, "\xe0\x01\x11\x03\x01\x39\x01\x50", 8);
// syn dst src len sts op. rep chk
COLOURS[9][0] = extra[0];
COLOURS[9][1] = extra[0];
COLOURS[9][2] = extra[0];
break;
case 0x3b:
log_warning("led_bd", "3b");
comdev_write(dev, "\xe0\x01\x11\x03\x01\x3b\x01\x52", 8);
// syn dst src len sts op. rep chk
break;
case 0x3c:
log_warning("led_bd", "3c (I am %ls)", dev->com->wName);
comdev_write(dev, "\xe0\x01\x11\x03\x01\x3c\x01\x53", 8);
// syn dst src len sts op. rep chk
break;
case 0x3f:
log_warning("led_bd", "3f: %02x %02x %02x %02x %02x %02x", extra[0], extra[1], extra[2], extra[3],
extra[4], extra[5], extra[6]);
comdev_write(dev, "\xe0\x01\x11\x03\x01\x3f\x01\x56", 8);
// syn dst src len sts op. rep chk
break;
case 0x7c:
// extra[0] goes from 0 to 7
// Could this be some sort of calibration for the buttons?
log_warning("led_bd", "7c: %02x", extra[0]);
comdev_write(dev, "\xe0\x01\x11\x04\x01\x7c\x01\x00\x94", 9);
// \/ causes 7b to be used
// comdev_write(dev, "\xe0\x01\x11\x04\x01\x7c\x01\x10\xa4", 9);
// syn dst src len sts op. rep --- chk
break;
case 0x7b:
log_warning("led_bd", "7b: %02x %02x %02x", extra[0], extra[1], extra[2]);
comdev_write(dev, "\xe0\x01\x11\x03\x01\x7b\x01\x92", 8);
// syn dst src len sts op. rep chk
break;
default:
log_error("led_bd", "Unknown op %02x (%d)", head.op, head.length - 1);
break;
}
free(extra);
}
}
static DWORD WINAPI led_null_thread(com_device_t* dev) {
while (1) Sleep(10000000);
}
void led_overlay(IDirect3DDevice9* dev) {
ShowCursor(true);
D3DDEVICE_CREATION_PARAMETERS cparams;
RECT rect;
dev->lpVtbl->GetCreationParameters(dev, &cparams);
GetClientRect(cparams.hFocusWindow, &rect);
if (GetAsyncKeyState(VK_LBUTTON) & 1) {
POINT cursor;
GetCursorPos(&cursor);
// log_info("led_overlay", "x: %d, y: %d", cursor.x, cursor.y);
log_info("led_overlay", "x%: %f, y%: %f", (float)cursor.x / (float)rect.right,
(float)(cursor.y - 26) / (float)rect.bottom);
}
for (unsigned char i = 0; i < 10; i++) {
int x = rect.right * positions[i][0];
int y = rect.bottom * positions[i][1];
draw_rect(dev, x - 25, y - 25, 50, 50, COLOURS[i][0], COLOURS[i][1], COLOURS[i][2]);
}
}
void install_led_bd() {
register_gui_hook(&led_overlay);
com_device_t* com5 = new_com_device(5);
com_device_thread(com5, led_null_thread);
com_device_t* leds_1p = new_com_device(6);
com_device_thread(leds_1p, led_bd_thread);
com_device_t* com7 = new_com_device(7);
com_device_thread(com7, led_null_thread);
com_device_t* leds_2p = new_com_device(8);
com_device_thread(leds_2p, led_bd_thread);
}
#include "../hooks/gui.h"
#include "_devices.h"
/*
[0] = e0
[1] = dest?
[2] = dst?
[3] = length
[4] = op code
[...] length-1 bytes
[.] = sum
[0] = e0
[2] = dst?
[1] = dest?
[3] = length
[4] = status
[5] = op
[6] = report
[...]
[.] = sum
OP codes:
3c: FUN_005735c0 (1)
10: FUN_00580c00 (1)
7c: FUN_00580c00 (2)
3c: FUN_00580c00 (1)
39: FUN_00580c00 (4)
3b: FUN_00580c00 (1)
31: FUN_00581350 (5)
32: FUN_005813b0 (8)
33: FUN_00581430 (8) -> something at [16]??
39: FUN_005814b0 (4)
3f: FUN_00581220 (7)
7b: FUN_005812a0 (3)
7c: FUN_00581310 (2)
01: was this just an error?
10:
31: Set button. [button] [r] [g] [b]
0-7 = buttons
8 = woofer
9 = center
32: Set multiple. [00] [idx hi] [idx lo] [r] [g] [b]
33: Fade multiple?. [09] [?] [?] [r] [g] [b]
39: Set body light. [intensity] [-] [-]
3b:
3c: Commit?
3f:
7c:
7b:
initial setup: 7c 0-7, 32, 3c, 39, 3f, 3b
*/
unsigned char COLOURS[10][3];
double positions[10][2] = {
{ 0.337963, 0.470833 }, { 0.469444, 0.619792 }, { 0.469444, 0.828125 }, { 0.337037, 0.977083 },
{ 0.152778, 0.976042 }, { 0.020370, 0.828125 }, { 0.020370, 0.618750 }, { 0.151852, 0.472917 },
{ 0.5, 0.75 }, { 0.5, 0.5 },
};
typedef struct rs232c_recv_head {
BYTE sync;
BYTE src;
BYTE dst;
BYTE length;
BYTE op;
} rs232c_recv_head_t;