34#pragma warning(disable : 26812)
35#pragma warning(disable : 6262)
50#if !defined(NTDDI_VERSION) && !defined(_WIN32_WINNT) && !defined(WINVER)
51#define NTDDI_VERSION 0x05010000
52#define _WIN32_WINNT 0x0501
55#ifndef WIN32_LEAN_AND_MEAN
56#define WIN32_LEAN_AND_MEAN
61#define BUFSIZE 64 * 1024
63#define BT8XXEMU_PIPE_OPEN 0xFF02
64#define BT8XXEMU_PIPE_CLOSE 0xFF04
65#define BT8XXEMU_PIPE_ECHO 0xFF10
67#define BT8XXEMU_CALL_VERSION 0x00
68#define BT8XXEMU_CALL_DEFAULTS 0x01
69#define BT8XXEMU_CALL_RUN 0x02
70#define BT8XXEMU_CALL_STOP 0x03
71#define BT8XXEMU_CALL_DESTROY 0x04
72#define BT8XXEMU_CALL_IS_RUNNING 0x05
73#define BT8XXEMU_CALL_TRANSFER 0x06
74#define BT8XXEMU_CALL_CHIP_SELECT 0x07
75#define BT8XXEMU_CALL_HAS_INTERRUPT 0x08
77#define BT8XXEMU_CALL_FLASH_DEFAULTS 0x0101
78#define BT8XXEMU_CALL_FLASH_CREATE 0x0102
79#define BT8XXEMU_CALL_FLASH_DESTROY 0x0104
80#define BT8XXEMU_CALL_FLASH_TRANSFER_SPI4 0x0109
82typedef struct BT8XXEMUC_Remote BT8XXEMUC_Remote;
83struct BT8XXEMUC_Remote
102 wchar_t romFilePath[260];
103 wchar_t otpFilePath[260];
104 wchar_t coprocessorRomFilePath[260];
107} BT8XXEMUC_RemoteEmulatorParameters;
110 wchar_t deviceType[26];
112 wchar_t dataFilePath[260];
113 wchar_t statusFilePath[260];
117} BT8XXEMUC_RemoteFlashParameters;
134 BT8XXEMUC_RemoteEmulatorParameters remoteParams;
138 BT8XXEMUC_RemoteFlashParameters remoteFlashParams;
150#define MESSAGE_SIZE(param) (DWORD)((ptrdiff_t)(void *)(&(data.param)) + (ptrdiff_t)sizeof(data.param) - (ptrdiff_t)(void *)(&data.buffer[0]))
151#define STRING_MESSAGE_SIZE() (DWORD)((ptrdiff_t)(void *)(&data.str[0]) + (ptrdiff_t)strlen(&data.str[0]) + 1 - (ptrdiff_t)(void *)(&data.buffer[0]))
156 params->
Flags = remoteParams->flags;
157 params->
Mode = remoteParams->mode;
160 wcscpy(params->
RomFilePath, remoteParams->romFilePath);
161 wcscpy(params->
OtpFilePath, remoteParams->otpFilePath);
163 params->
UserContext = (
void *)(intptr_t)remoteParams->userContext;
164 assert(remoteParams->flash == 0);
170 remoteParams->flags = params->
Flags;
171 remoteParams->mode = params->
Mode;
174 wcscpy(remoteParams->romFilePath, params->
RomFilePath);
175 wcscpy(remoteParams->otpFilePath, params->
OtpFilePath);
178 remoteParams->flash = (params->
Flash) ? params->
Flash->flash : 0;
181static void BT8XXEMUC_readFlashParams(
BT8XXEMU_FlashParameters *flashParams,
const BT8XXEMUC_RemoteFlashParameters *remoteFlashParams)
183 wcscpy(flashParams->
DeviceType, remoteFlashParams->deviceType);
184 flashParams->
SizeBytes = remoteFlashParams->sizeBytes;
185 wcscpy(flashParams->
DataFilePath, remoteFlashParams->dataFilePath);
186 wcscpy(flashParams->
StatusFilePath, remoteFlashParams->statusFilePath);
187 flashParams->
Persistent = remoteFlashParams->persistent;
188 flashParams->
StdOut = remoteFlashParams->stdOut;
191static void BT8XXEMUC_writeFlashParams(BT8XXEMUC_RemoteFlashParameters *remoteFlashParams,
const BT8XXEMU_FlashParameters *flashParams)
193 wcscpy(remoteFlashParams->deviceType, flashParams->
DeviceType);
194 remoteFlashParams->sizeBytes = flashParams->
SizeBytes;
195 wcscpy(remoteFlashParams->dataFilePath, flashParams->
DataFilePath);
196 wcscpy(remoteFlashParams->statusFilePath, flashParams->
StatusFilePath);
197 remoteFlashParams->persistent = flashParams->
Persistent;
198 remoteFlashParams->stdOut = flashParams->
StdOut;
202static LONG s_AtomicLock = 0;
203static LONG s_RefCount = 0;
207static BT8XXEMUC_Data s_VersionData;
208static int s_PipeNb = 0;
210static void BT8XXEMUC_lockProcessPipe()
212 while (InterlockedExchange(&s_AtomicLock, 1))
216static void BT8XXEMUC_unlockProcessPipe()
218 InterlockedExchange(&s_AtomicLock, 0);
222static bool BT8XXEMUC_openProcess()
224 BT8XXEMUC_lockProcessPipe();
228 char pipeHandle[MAX_PATH];
229 sprintf(pipeHandle,
"\\\\.\\pipe\\bt8xxemus_%i", (
int)GetCurrentProcessId());
231 s_Pipe = CreateNamedPipeA(pipeHandle, PIPE_ACCESS_DUPLEX,
232 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
233 1, BUFSIZE, BUFSIZE, 1000, NULL);
237 BT8XXEMUC_unlockProcessPipe();
241 STARTUPINFO si = { 0 };
242 PROCESS_INFORMATION pi = { 0 };
243 char processCommand[MAX_PATH];
244 sprintf(processCommand,
"bt8xxemus.exe %s", pipeHandle);
245 if (!CreateProcessA(NULL, processCommand, NULL, NULL,
FALSE, 0, NULL, NULL, &si, &pi))
249 BT8XXEMUC_unlockProcessPipe();
253 s_Process = pi.hProcess;
254 s_ProcessThread = pi.hThread;
256 if (!ConnectNamedPipe(s_Pipe, NULL))
260 TerminateProcess(s_Process, EXIT_FAILURE);
261 CloseHandle(s_Process);
263 CloseHandle(s_ProcessThread);
265 BT8XXEMUC_unlockProcessPipe();
271 BT8XXEMUC_unlockProcessPipe();
276static void BT8XXEMUC_closeProcess()
278 BT8XXEMUC_lockProcessPipe();
287 data.messageType = BT8XXEMU_PIPE_CLOSE;
288 len = MESSAGE_SIZE(messageType);
290 if (!WriteFile(s_Pipe, data.buffer, len, &
nb, NULL) || len !=
nb)
294 TerminateProcess(s_Process, EXIT_FAILURE);
295 CloseHandle(s_Process);
297 CloseHandle(s_ProcessThread);
299 BT8XXEMUC_unlockProcessPipe();
306 WaitForSingleObject(s_Process, INFINITE);
307 CloseHandle(s_Process);
309 CloseHandle(s_ProcessThread);
313 BT8XXEMUC_unlockProcessPipe();
319static HANDLE BT8XXEMUC_openPipe()
321 BT8XXEMUC_lockProcessPipe();
329 data.messageType = BT8XXEMU_PIPE_OPEN;
331 sprintf(data.str,
"\\\\.\\pipe\\bt8xxemus_%i_%i", (
int)GetCurrentProcessId(), s_PipeNb);
332 len = STRING_MESSAGE_SIZE();
334 HANDLE pipe = CreateNamedPipeA(data.str, PIPE_ACCESS_DUPLEX,
335 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
336 1, BUFSIZE, BUFSIZE, 1000, NULL);
339 || !WriteFile(s_Pipe, data.buffer, len, &
nb, NULL) || len !=
nb
340 || !ReadFile(s_Pipe, data.buffer, BUFSIZE, &
nb, NULL)
341 || !ConnectNamedPipe(pipe, NULL))
343 BT8XXEMUC_unlockProcessPipe();
347 BT8XXEMUC_unlockProcessPipe();
351static void BT8XXEMUC_lockPipe(BT8XXEMUC_Remote *emulator)
353 while (InterlockedExchange(&emulator->atomicLock, 1))
357static void BT8XXEMUC_unlockPipe(BT8XXEMUC_Remote *emulator)
359 InterlockedExchange(&emulator->atomicLock, 0);
363static void BT8XXEMUC_closePipe(BT8XXEMUC_Remote *emulator)
365 BT8XXEMUC_lockPipe(emulator);
371 data.messageType = BT8XXEMU_PIPE_CLOSE;
372 len = MESSAGE_SIZE(messageType);
373 WriteFile(emulator->pipe, data.buffer, len, &
nb, NULL);
374 CloseHandle(emulator->pipe);
377 BT8XXEMUC_unlockPipe(emulator);
382 if (BT8XXEMUC_openProcess())
384 BT8XXEMUC_lockProcessPipe();
389 s_VersionData.messageType = BT8XXEMU_CALL_VERSION;
395 len = MESSAGE_SIZE(versionApi);
398 if (!WriteFile(s_Pipe, s_VersionData.buffer, len, &
nb, NULL) || len !=
nb
399 || !ReadFile(s_Pipe, s_VersionData.buffer, BUFSIZE, &
nb, NULL))
401 BT8XXEMUC_unlockProcessPipe();
402 BT8XXEMUC_closeProcess();
403 return "BT8XX Emulator Library\nNot Responding";
406 BT8XXEMUC_unlockProcessPipe();
407 BT8XXEMUC_closeProcess();
409 return s_VersionData.str;
412 return "BT8XX Emulator Library\nNot Installed";
417 if (BT8XXEMUC_openProcess())
419 BT8XXEMUC_lockProcessPipe();
425 data.messageType = BT8XXEMU_CALL_DEFAULTS;
428 memset(&data.remoteParams, 0,
sizeof(BT8XXEMUC_RemoteEmulatorParameters));
430 len = MESSAGE_SIZE(mode);
432 if (!WriteFile(s_Pipe, data.buffer, len, &
nb, NULL) || len !=
nb
433 || !ReadFile(s_Pipe, data.buffer, BUFSIZE, &
nb, NULL))
435 BT8XXEMUC_unlockProcessPipe();
436 BT8XXEMUC_closeProcess();
441 BT8XXEMUC_unlockProcessPipe();
442 BT8XXEMUC_closeProcess();
444 BT8XXEMUC_readParams(params, &data.remoteParams);
471 if (BT8XXEMUC_openProcess())
476 BT8XXEMUC_closeProcess();
480 (*emulator)->pipe = BT8XXEMUC_openPipe();
484 BT8XXEMUC_closeProcess();
494 data.messageType = BT8XXEMU_CALL_RUN;
496 BT8XXEMUC_writeParams(&data.remoteParams, params);
497 len = MESSAGE_SIZE(remoteParams);
502 if (!WriteFile((*emulator)->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
503 || !ReadFile((*emulator)->pipe, data.buffer, BUFSIZE, &
nb, NULL))
505 BT8XXEMUC_closePipe(*emulator);
506 BT8XXEMUC_closeProcess();
512 (*emulator)->emulator = data.emulator;
527 BT8XXEMUC_lockPipe(emulator);
533 data.messageType = BT8XXEMU_CALL_STOP;
534 data.emulator = emulator->emulator;
535 len = MESSAGE_SIZE(emulator);
537 if (!WriteFile(emulator->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
538 || !ReadFile(emulator->pipe, data.buffer, BUFSIZE, &
nb, NULL))
543 BT8XXEMUC_unlockPipe(emulator);
548 BT8XXEMUC_lockPipe(emulator);
554 data.messageType = BT8XXEMU_CALL_DESTROY;
555 data.emulator = emulator->emulator;
556 len = MESSAGE_SIZE(emulator);
558 if (!WriteFile(emulator->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
559 || !ReadFile(emulator->pipe, data.buffer, BUFSIZE, &
nb, NULL))
564 BT8XXEMUC_unlockPipe(emulator);
566 BT8XXEMUC_closePipe(emulator);
567 BT8XXEMUC_closeProcess();
573 BT8XXEMUC_lockPipe(emulator);
579 data.messageType = BT8XXEMU_CALL_IS_RUNNING;
580 data.emulator = emulator->emulator;
581 len = MESSAGE_SIZE(emulator);
583 if (!WriteFile(emulator->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
584 || !ReadFile(emulator->pipe, data.buffer, BUFSIZE, &
nb, NULL))
586 BT8XXEMUC_unlockPipe(emulator);
590 BT8XXEMUC_unlockPipe(emulator);
591 return data.isRunning;
596 BT8XXEMUC_lockPipe(emulator);
602 data.messageType = BT8XXEMU_CALL_TRANSFER;
603 data.emulator = emulator->emulator;
605 len = MESSAGE_SIZE(data);
607 if (!WriteFile(emulator->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
608 || !ReadFile(emulator->pipe, data.buffer, BUFSIZE, &
nb, NULL))
610 BT8XXEMUC_unlockPipe(emulator);
614 BT8XXEMUC_unlockPipe(emulator);
620 BT8XXEMUC_lockPipe(emulator);
626 data.messageType = BT8XXEMU_CALL_CHIP_SELECT;
627 data.emulator = emulator->emulator;
628 data.chipSelect = cs;
629 len = MESSAGE_SIZE(chipSelect);
631 if (!WriteFile(emulator->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
632 || !ReadFile(emulator->pipe, data.buffer, BUFSIZE, &
nb, NULL))
637 BT8XXEMUC_unlockPipe(emulator);
642 BT8XXEMUC_lockPipe(emulator);
648 data.messageType = BT8XXEMU_CALL_HAS_INTERRUPT;
649 data.emulator = emulator->emulator;
650 len = MESSAGE_SIZE(emulator);
652 if (!WriteFile(emulator->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
653 || !ReadFile(emulator->pipe, data.buffer, BUFSIZE, &
nb, NULL))
655 BT8XXEMUC_unlockPipe(emulator);
659 BT8XXEMUC_unlockPipe(emulator);
660 return data.hasInterrupt;
665 if (BT8XXEMUC_openProcess())
667 BT8XXEMUC_lockProcessPipe();
673 data.messageType = BT8XXEMU_CALL_FLASH_DEFAULTS;
676 memset(&data.remoteFlashParams, 0,
sizeof(BT8XXEMUC_RemoteFlashParameters));
677 len = MESSAGE_SIZE(remoteFlashParams);
679 if (!WriteFile(s_Pipe, data.buffer, len, &
nb, NULL) || len !=
nb
680 || !ReadFile(s_Pipe, data.buffer, BUFSIZE, &
nb, NULL))
682 BT8XXEMUC_unlockProcessPipe();
683 BT8XXEMUC_closeProcess();
688 BT8XXEMUC_unlockProcessPipe();
689 BT8XXEMUC_closeProcess();
691 BT8XXEMUC_readFlashParams(params, &data.remoteFlashParams);
700 if (BT8XXEMUC_openProcess())
706 flash->pipe = BT8XXEMUC_openPipe();
710 BT8XXEMUC_closeProcess();
719 data.messageType = BT8XXEMU_CALL_FLASH_CREATE;
721 BT8XXEMUC_writeFlashParams(&data.remoteFlashParams, params);
722 len = MESSAGE_SIZE(remoteFlashParams);
724 if (!WriteFile(flash->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
725 || !ReadFile(flash->pipe, data.buffer, BUFSIZE, &
nb, NULL))
727 BT8XXEMUC_closePipe(flash);
728 BT8XXEMUC_closeProcess();
733 flash->flash = data.flash;
743 BT8XXEMUC_lockPipe(flash);
749 data.messageType = BT8XXEMU_CALL_FLASH_DESTROY;
750 data.flash = flash->flash;
751 len = MESSAGE_SIZE(emulator);
753 if (!WriteFile(flash->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
754 || !ReadFile(flash->pipe, data.buffer, BUFSIZE, &
nb, NULL))
759 BT8XXEMUC_unlockPipe(flash);
761 BT8XXEMUC_closePipe(flash);
762 BT8XXEMUC_closeProcess();
768 BT8XXEMUC_lockPipe(flash);
774 data.messageType = BT8XXEMU_CALL_FLASH_TRANSFER_SPI4;
775 data.flash = flash->flash;
776 data.signal = signal;
777 len = MESSAGE_SIZE(signal);
779 if (!WriteFile(flash->pipe, data.buffer, len, &
nb, NULL) || len !=
nb
780 || !ReadFile(flash->pipe, data.buffer, BUFSIZE, &
nb, NULL))
782 BT8XXEMUC_unlockPipe(flash);
786 BT8XXEMUC_unlockPipe(flash);
unsigned long long uint64_t
static ft_uint32_t ft_uint8_t * buffer
static ft_void_t ft_uint32_t ft_size_t nb
#define INVALID_HANDLE_VALUE
BT8XXEMU_API uint8_t BT8XXEMU_Flash_transferSpi4(BT8XXEMU_Flash *flash, uint8_t signal)
BT8XXEMU_API void BT8XXEMU_defaults(uint32_t versionApi, BT8XXEMU_EmulatorParameters *params, BT8XXEMU_EmulatorMode mode)
BT8XXEMU_API void BT8XXEMU_Flash_defaults(uint32_t versionApi, BT8XXEMU_FlashParameters *params)
BT8XXEMU_API int BT8XXEMU_isRunning(BT8XXEMU_Emulator *emulator)
#define BT8XXEMU_VERSION_API
BT8XXEMU_API void BT8XXEMU_stop(BT8XXEMU_Emulator *emulator)
BT8XXEMU_API void BT8XXEMU_Flash_destroy(BT8XXEMU_Flash *flash)
BT8XXEMU_API BT8XXEMU_Flash * BT8XXEMU_Flash_create(uint32_t versionApi, const BT8XXEMU_FlashParameters *params)
BT8XXEMU_API int BT8XXEMU_hasInterrupt(BT8XXEMU_Emulator *emulator)
BT8XXEMU_API uint8_t BT8XXEMU_transfer(BT8XXEMU_Emulator *emulator, uint8_t data)
BT8XXEMU_API void BT8XXEMU_destroy(BT8XXEMU_Emulator *emulator)
BT8XXEMU_API void BT8XXEMU_chipSelect(BT8XXEMU_Emulator *, int cs)
BT8XXEMU_API const char * BT8XXEMU_version()
BT8XXEMU_API void BT8XXEMU_run(uint32_t versionApi, BT8XXEMU_Emulator **emulator, const BT8XXEMU_EmulatorParameters *params)
void(* Close)(BT8XXEMU_Emulator *sender, void *context)
eve_tchar_t OtpFilePath[260]
void(* MCUSleep)(BT8XXEMU_Emulator *sender, void *context, int ms)
BT8XXEMU_EmulatorMode Mode
uint32_t ReduceGraphicsThreads
int(* Graphics)(BT8XXEMU_Emulator *sender, void *context, int output, const argb8888 *buffer, uint32_t hsize, uint32_t vsize, BT8XXEMU_FrameFlags flags)
eve_tchar_t RomFilePath[260]
void(* Log)(BT8XXEMU_Emulator *sender, void *context, BT8XXEMU_LogType type, const char *message)
void(* Main)(BT8XXEMU_Emulator *sender, void *context)
eve_tchar_t CoprocessorRomFilePath[260]
eve_tchar_t DataFilePath[260]
eve_tchar_t DeviceType[26]
eve_tchar_t StatusFilePath[260]