88 changed files with 11499 additions and 5405 deletions
@ -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/ |
||||
|
@ -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/*"
|
||||
|
@ -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") |
@ -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') |
||||
|
@ -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) |
@ -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; |
||||
} |
||||
|
@ -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); |
@ -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" |
||||
|
@ -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(); |
||||
} |
||||
|
@ -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(); |
@ -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); |
||||
} |
@ -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; |
||||