Compare commits

...

2 Commits

Author SHA1 Message Date
Bottersnike 8ca5b1a051
Use handles as an index into the data array 2023-07-14 20:26:25 +01:00
Bottersnike d31316d821
Implement MiceDA 2023-07-14 20:00:52 +01:00
15 changed files with 280 additions and 130 deletions

View File

@ -3,7 +3,7 @@
#define RESERVED_JVS_COM_PORT 4 #define RESERVED_JVS_COM_PORT 4
com_device_t* GetComDevice(HANDLE hFile) { com_device_t* GetComDevice(HANDLE hFile) {
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook == NULL || pHData->hook->com_hook == NULL) return NULL; if (pHData == NULL || pHData->hook == NULL || pHData->hook->com_hook == NULL) return NULL;
return pHData->hook->com_hook->com_device; return pHData->hook->com_hook->com_device;
} }

View File

@ -108,9 +108,13 @@ static void populateActiveResponse() {
} }
} }
for (DWORD i = 0; i < nActiveTouches; i++) { MICE_DA_ITER(g_activeTouches, ACTIVE_TOUCH, i) {
handleOneButton(w, h, activeTouches[i].m_X, activeTouches[i].m_Y); handleOneButton(w, h, i->m_X, i->m_Y);
} } MICE_DA_ITER_END
// for (DWORD i = 0; i < nActiveTouches; i++) {
// handleOneButton(w, h, activeTouches[i].m_X, activeTouches[i].m_Y);
// }
} }
BOOL touch_is_enabled = TRUE; // Default on is important! BOOL touch_is_enabled = TRUE; // Default on is important!

View File

@ -27,7 +27,7 @@ com_hook_t* new_com_hook(BYTE port) {
} }
BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) { BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) {
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
log_misc(plfComm, "GetCommState(0x%p, 0x%p) (%08x)", hFile, lpDCB, hook); log_misc(plfComm, "GetCommState(0x%p, 0x%p) (%08x)", hFile, lpDCB, hook);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommState(hFile, lpDCB); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueGetCommState(hFile, lpDCB);
@ -43,7 +43,7 @@ BOOL WINAPI FakeGetCommState(HANDLE hFile, LPDCB lpDCB) {
BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) { BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) {
log_misc(plfComm, "SetCommState(0x%p, 0x%p)", hFile, lpDCB); log_misc(plfComm, "SetCommState(0x%p, 0x%p)", hFile, lpDCB);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommState(hFile, lpDCB); if (pHData == NULL || pHData->hook->com_hook == NULL) return TrueSetCommState(hFile, lpDCB);
com_hook_t* com_hook = pHData->hook->com_hook; com_hook_t* com_hook = pHData->hook->com_hook;
@ -57,7 +57,7 @@ BOOL WINAPI FakeSetCommState(HANDLE hFile, LPDCB lpDCB) {
BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) { BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
log_misc(plfComm, "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts); log_misc(plfComm, "GetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) if (pHData == NULL || pHData->hook->com_hook == NULL)
return TrueGetCommTimeouts(hFile, lpCommTimeouts); return TrueGetCommTimeouts(hFile, lpCommTimeouts);
@ -72,7 +72,7 @@ BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) { BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
log_misc(plfComm, "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts); log_misc(plfComm, "SetCommTimeouts(0x%p, 0x%p)", hFile, lpCommTimeouts);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) if (pHData == NULL || pHData->hook->com_hook == NULL)
return TrueSetCommTimeouts(hFile, lpCommTimeouts); return TrueSetCommTimeouts(hFile, lpCommTimeouts);
@ -87,7 +87,7 @@ BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) { BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) {
log_misc(plfComm, "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue); log_misc(plfComm, "SetupCom(0x%p, 0x%08x, 0x%08x)", hFile, dwInQueue, dwOutQueue);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) if (pHData == NULL || pHData->hook->com_hook == NULL)
return TrueSetupComm(hFile, dwInQueue, dwOutQueue); return TrueSetupComm(hFile, dwInQueue, dwOutQueue);
@ -102,7 +102,7 @@ BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue) {
BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) { BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) {
log_misc(plfComm, "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags); log_misc(plfComm, "PurgeComm(0x%p, 0x%08x)", hFile, dwFlags);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) return TruePurgeComm(hFile, dwFlags); if (pHData == NULL || pHData->hook->com_hook == NULL) return TruePurgeComm(hFile, dwFlags);
com_hook_t* com_hook = pHData->hook->com_hook; com_hook_t* com_hook = pHData->hook->com_hook;
@ -116,7 +116,7 @@ BOOL WINAPI FakePurgeComm(HANDLE hFile, DWORD dwFlags) {
BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) { BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
log_misc(plfComm, "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat); log_misc(plfComm, "GetCommModemStatus(0x%p, 0x%p)", hFile, lpModelStat);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) if (pHData == NULL || pHData->hook->com_hook == NULL)
return TrueGetCommModemStatus(hFile, lpModelStat); return TrueGetCommModemStatus(hFile, lpModelStat);
@ -131,7 +131,7 @@ BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) { BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
log_misc(plfComm, "WaitCommEvent(0x%p)", hFile); log_misc(plfComm, "WaitCommEvent(0x%p)", hFile);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) if (pHData == NULL || pHData->hook->com_hook == NULL)
return TrueWaitCommEvent(hFile, lpEvtMask, lpOverlapped); return TrueWaitCommEvent(hFile, lpEvtMask, lpOverlapped);
@ -146,7 +146,7 @@ BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOv
BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) { BOOL WINAPI FakeClearCommError(HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat) {
log_trace(plfComm, "ClearCommError(0x%p)", hFile); log_trace(plfComm, "ClearCommError(0x%p)", hFile);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL || pHData->hook->com_hook == NULL) if (pHData == NULL || pHData->hook->com_hook == NULL)
return TrueClearCommError(hFile, lpErrors, lpStat); return TrueClearCommError(hFile, lpErrors, lpStat);

View File

@ -5,7 +5,7 @@ typedef struct {
size_t partition; size_t partition;
} find_index_t; } find_index_t;
disk_volume_t* incrementFindIndex(HANDLE hFindVolume) { disk_volume_t* incrementFindIndex(HANDLE hFindVolume) {
find_index_t* find_index = GetDataForHandle(hFindVolume, HDATA_FIND_VOLUME); find_index_t* find_index = GetDataForHandle(hFindVolume);
if (find_index == NULL) return NULL; if (find_index == NULL) return NULL;
while (1) { while (1) {
@ -69,7 +69,7 @@ HANDLE WINAPI FakeFindFirstVolumeW(LPWSTR lpszVolumeName, DWORD cchBufferLength)
find_index->disk = 0; find_index->disk = 0;
find_index->partition = 0; find_index->partition = 0;
HANDLE handle = GetDummyHandle(); HANDLE handle = GetDummyHandle();
SetDataForHandle(handle, HDATA_FIND_VOLUME, find_index, TRUE); SetDataForHandle(handle, find_index, TRUE);
FakeFindNextVolumeW(handle, lpszVolumeName, cchBufferLength); FakeFindNextVolumeW(handle, lpszVolumeName, cchBufferLength);
return handle; return handle;
@ -79,13 +79,13 @@ HANDLE WINAPI FakeFindFirstVolumeA(LPSTR lpszVolumeName, DWORD cchBufferLength)
find_index->disk = 0; find_index->disk = 0;
find_index->partition = 0; find_index->partition = 0;
HANDLE handle = GetDummyHandle(); HANDLE handle = GetDummyHandle();
SetDataForHandle(handle, HDATA_FIND_VOLUME, find_index, TRUE); SetDataForHandle(handle, find_index, TRUE);
FakeFindNextVolumeA(handle, lpszVolumeName, cchBufferLength); FakeFindNextVolumeA(handle, lpszVolumeName, cchBufferLength);
return handle; return handle;
} }
BOOL WINAPI FakeFindVolumeClose(HANDLE hFindVolume) { BOOL WINAPI FakeFindVolumeClose(HANDLE hFindVolume) {
if (RemoveDataForHandle(hFindVolume, HDATA_FIND_VOLUME)) return _CloseHandle(hFindVolume); if (RemoveDataForHandle(hFindVolume)) return _CloseHandle(hFindVolume);
return FALSE; return FALSE;
} }

View File

@ -30,7 +30,7 @@ HANDLE open_hook(file_hook_t* file_hook) {
opened->ctx.m_Handle = handle; opened->ctx.m_Handle = handle;
opened->ctx.m_HookData = file_hook->hook_data; opened->ctx.m_HookData = file_hook->hook_data;
SetDataForHandle(handle, HDATA_FILE, opened, TRUE); SetDataForHandle(handle, opened, TRUE);
return handle; return handle;
} }
@ -213,7 +213,7 @@ BOOL WINAPI FakeDeleteFileW(LPCWSTR pszPath) {
BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer,
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) { LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hDevice);
if (pHData == NULL) { if (pHData == NULL) {
return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer,
nOutBufferSize, lpBytesReturned, lpOverlapped); nOutBufferSize, lpBytesReturned, lpOverlapped);
@ -239,7 +239,7 @@ BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lp
DWORD WINAPI FakeSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD WINAPI FakeSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh,
DWORD dwMoveMethod) { DWORD dwMoveMethod) {
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL) if (pHData == NULL)
return TrueSetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod); return TrueSetFilePointer(hFile, lDistanceToMove, lpDistanceToMoveHigh, dwMoveMethod);
@ -262,7 +262,7 @@ DWORD WINAPI FakeSetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDist
BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) { PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) {
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData != NULL) { if (pHData != NULL) {
if (dwMoveMethod == FILE_BEGIN) { if (dwMoveMethod == FILE_BEGIN) {
pHData->ctx.m_Pointer = liDistanceToMove; pHData->ctx.m_Pointer = liDistanceToMove;
@ -281,7 +281,7 @@ BOOL WINAPI FakeSetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
} }
DWORD WINAPI FakeGetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) { DWORD WINAPI FakeGetFileSizeEx(HANDLE hFile, PLARGE_INTEGER lpFileSize) {
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL) { if (pHData == NULL) {
return TrueGetFileSizeEx(hFile, lpFileSize); return TrueGetFileSizeEx(hFile, lpFileSize);
} }
@ -300,7 +300,7 @@ DWORD WINAPI FakeWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesT
lpOverlapped); lpOverlapped);
} }
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL) { if (pHData == NULL) {
return TrueWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, return TrueWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten,
lpOverlapped); lpOverlapped);
@ -327,7 +327,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
} }
// log_misc(plfHooks, "ReadFile(%d) %d", hFile, nNumberOfBytesToRead); // log_misc(plfHooks, "ReadFile(%d) %d", hFile, nNumberOfBytesToRead);
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE); open_hook_t* pHData = GetDataForHandle(hFile);
if (pHData == NULL) { if (pHData == NULL) {
return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead,
lpOverlapped); lpOverlapped);
@ -348,7 +348,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
} }
BOOL WINAPI FakeCloseHandle(HANDLE hObject) { BOOL WINAPI FakeCloseHandle(HANDLE hObject) {
RemoveDataForHandle(hObject, HDATA_ANY); RemoveDataForHandle(hObject);
return TrueCloseHandle(hObject); return TrueCloseHandle(hObject);
} }

View File

@ -247,49 +247,25 @@ void register_gui_hook(FnEndScene* end_scene) {
*head = hook; *head = hook;
} }
DWORD nActiveTouches = 0; MICE_DA_NEW(g_activeTouches, ACTIVE_TOUCH)
ACTIVE_TOUCH* activeTouches = NULL;
extern DWORD nActiveTouchesMax = 0;
void SetTouch(UINT id, INT x, INT y, BOOL state) { void SetTouch(UINT id, INT x, INT y, BOOL state) {
if (state) { if (state) {
// If we can just update in place, do MICE_DA_ITER(g_activeTouches, ACTIVE_TOUCH, i) {
for (DWORD i = 0; i < nActiveTouches; i++) { if (i->m_Id == id) {
if (activeTouches[i].m_Id == id) { i->m_X = x;
activeTouches[i].m_X = x; i->m_Y = y;
activeTouches[i].m_Y = y;
return; return;
} }
} }
MICE_DA_ITER_END
// Dynamic array re-allocation ACTIVE_TOUCH touch = { .m_Id = id, .m_X = x, .m_Y = y };
if (nActiveTouches == nActiveTouchesMax) { MiceDAPush(g_activeTouches, &touch);
DWORD newSize = nActiveTouchesMax * 2 + 1;
ACTIVE_TOUCH* newMemory = realloc(activeTouches, sizeof *activeTouches * newSize);
if (newMemory != activeTouches) {
memcpy(newMemory, activeTouches, sizeof *activeTouches * nActiveTouchesMax);
}
activeTouches = newMemory;
nActiveTouchesMax = newSize;
}
// Store into end of DA
activeTouches[nActiveTouches].m_Id = id;
activeTouches[nActiveTouches].m_X = x;
activeTouches[nActiveTouches].m_Y = y;
nActiveTouches++;
} else { } else {
for (DWORD i = 0; i < nActiveTouches; i++) { MICE_DA_ITER(g_activeTouches, ACTIVE_TOUCH, i) {
if (activeTouches[i].m_Id == id) { if (i->m_Id == id) MICE_DA_REMOVE_CURRENT(g_activeTouches);
// Copy backwards
for (DWORD j = i + 1; j < nActiveTouches; j++) {
activeTouches[j - 1].m_Id = activeTouches[j].m_Id;
activeTouches[j - 1].m_X = activeTouches[j].m_X;
activeTouches[j - 1].m_Y = activeTouches[j].m_Y;
}
nActiveTouches--;
}
} }
MICE_DA_ITER_END
} }
} }
@ -413,7 +389,8 @@ void SetupWindowPosition(LPRECT lpRect, DWORD dwStyle) {
// RECT adjustedRect; // RECT adjustedRect;
// memcpy(&adjustedRect, lpRect, sizeof *lpRect); // memcpy(&adjustedRect, lpRect, sizeof *lpRect);
// UnadjustWindowRect(&adjustedRect, dwStyle, FALSE); // UnadjustWindowRect(&adjustedRect, dwStyle, FALSE);
// // We're going to only adjust y, on the assumption x is unchanged, and even if it is // // We're going to only adjust y, on the assumption x is unchanged, and even if it
// is
// // it'll be symmetic. y has the titlebar to worry about. // // it'll be symmetic. y has the titlebar to worry about.
// int outerH = adjustedRect.bottom - adjustedRect.top; // int outerH = adjustedRect.bottom - adjustedRect.top;

View File

@ -48,8 +48,10 @@ typedef struct {
INT m_X; INT m_X;
INT m_Y; INT m_Y;
} ACTIVE_TOUCH; } ACTIVE_TOUCH;
extern DWORD nActiveTouches; // extern DWORD nActiveTouches;
extern ACTIVE_TOUCH* activeTouches; // extern ACTIVE_TOUCH* activeTouches;
extern PMICE_DA g_activeTouches;
BOOL UnadjustWindowRect(LPRECT prc, DWORD dwStyle, BOOL fMenu); BOOL UnadjustWindowRect(LPRECT prc, DWORD dwStyle, BOOL fMenu);
extern HWND mainWindow; extern HWND mainWindow;

View File

@ -2,15 +2,11 @@
#include "hook.h" #include "hook.h"
#define HDATA_FILE 0
#define HDATA_FIND_VOLUME 1
#define HDATA_ANY 0xFFFFFFFF
BOOL FileExistsW(const wchar_t* szPath); BOOL FileExistsW(const wchar_t* szPath);
BOOL FileExistsA(const char* szPath); BOOL FileExistsA(const char* szPath);
PVOID GetDataForHandle(HANDLE hObject, DWORD type); PVOID GetDataForHandle(HANDLE hObject);
void SetDataForHandle(HANDLE hObject, DWORD type, PVOID pData, BOOL isHeap); void SetDataForHandle(HANDLE hObject, PVOID pData, BOOL isHeap);
BOOL RemoveDataForHandle(HANDLE hObject, DWORD type); BOOL RemoveDataForHandle(HANDLE hObject);
HANDLE GetDummyHandle(); HANDLE GetDummyHandle();
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes); void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes);

View File

@ -7,6 +7,9 @@
#include "../hooks/files.h" #include "../hooks/files.h"
// Use the second tag bit to indicate a mice handle
#define MICE_HANDLE_MASK 0x00000002
void PrintStack(void) { void PrintStack(void) {
unsigned int i; unsigned int i;
void* stack[100]; void* stack[100];
@ -42,87 +45,74 @@ BOOL FileExistsA(const char* szPath) {
return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY)); return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
} }
typedef struct _handle_list { typedef struct HANDLE_DATA {
HANDLE m_Handle; BOOL m_bOccupied;
PVOID m_pData; PVOID m_pData;
DWORD m_Type;
BOOL m_IsOnHeap; BOOL m_IsOnHeap;
struct _handle_list* m_Next; } HANDLE_DATA, *PHANDLE_DATA;
} handle_list_t; MICE_DA_NEW(g_handleData, HANDLE_DATA)
handle_list_t handle_list_root = {
.m_Handle = INVALID_HANDLE_VALUE,
.m_pData = NULL,
.m_Type = 0xffffffff,
.m_IsOnHeap = FALSE,
.m_Next = NULL,
};
PVOID GetDataForHandle(HANDLE hObject, DWORD type) { PVOID GetDataForHandle(HANDLE hObject) {
if (hObject == INVALID_HANDLE_VALUE) return NULL; if (hObject == INVALID_HANDLE_VALUE) return NULL;
if (!hObject & MICE_HANDLE_MASK) return NULL;
handle_list_t* head = &handle_list_root; DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2;
while (head) { PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex);
if (head->m_Handle == hObject && (type == HDATA_ANY || head->m_Type == type)) if (found == NULL) return NULL;
return head->m_pData; return found->m_pData;
head = head->m_Next;
}
return NULL;
} }
void SetDataForHandle(HANDLE hObject, DWORD type, PVOID pData, BOOL isHeap) { void SetDataForHandle(HANDLE hObject, PVOID pData, BOOL isHeap) {
if (hObject == INVALID_HANDLE_VALUE) return; if (hObject == INVALID_HANDLE_VALUE) return;
if (!hObject & MICE_HANDLE_MASK) return;
handle_list_t* head = &handle_list_root; DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2;
while (1) { if (dwIndex < g_handleData->m_Length) {
if (head->m_Handle == hObject && (type == HDATA_ANY || head->m_Type == type)) { PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex);
if (head->m_IsOnHeap) free(head->m_pData); if (found) {
head->m_pData = pData; found->m_bOccupied = TRUE;
head->m_IsOnHeap = isHeap; if (found->m_IsOnHeap && found->m_pData) free(found->m_pData);
found->m_pData = pData;
found->m_IsOnHeap = isHeap;
return; return;
} }
if (head->m_Next == NULL) break;
head = head->m_Next;
} }
head->m_Next = malloc(sizeof *head);
head->m_Next->m_Handle = hObject; HANDLE_DATA newHandleData = {
head->m_Next->m_pData = pData; .m_bOccupied = TRUE,
head->m_Next->m_Next = NULL; .m_pData = pData,
head->m_Next->m_IsOnHeap = isHeap; .m_IsOnHeap = isHeap,
head->m_Next->m_Type = type; };
MiceDAGrowAndSet(g_handleData, dwIndex, &newHandleData);
} }
BOOL RemoveDataForHandle(HANDLE hObject, DWORD type) { BOOL RemoveDataForHandle(HANDLE hObject, DWORD type) {
if (hObject == INVALID_HANDLE_VALUE) return FALSE; if (hObject == INVALID_HANDLE_VALUE) return FALSE;
if (!hObject & MICE_HANDLE_MASK) return FALSE;
DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2;
handle_list_t* head = &handle_list_root; PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex);
handle_list_t* previous = &handle_list_root; if (found) {
BOOL ret = FALSE; if (found->m_IsOnHeap && found->m_pData) free(found->m_pData);
while (head) { found->m_pData = NULL;
if (head->m_Handle == hObject && (type == HDATA_ANY || head->m_Type == type)) { found->m_bOccupied = FALSE;
previous->m_Next = head->m_Next;
if (head->m_IsOnHeap) free(head->m_pData);
handle_list_t* next = head->m_Next;
free(head);
head = next;
if (type != HDATA_ANY) return TRUE;
ret = TRUE;
} else {
previous = head;
head = head->m_Next;
}
} }
return ret;
} }
HANDLE GetDummyHandle() { HANDLE GetDummyHandle() {
CHAR path[MAX_PATH]; MICE_DA_ITER(g_handleData, HANDLE_DATA, i) {
GetModuleFileNameA(NULL, path, MAX_PATH); if (!i->m_bOccupied) {
HANDLE hObject = i->m_bOccupied = TRUE;
_CreateFileA(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); return (HANDLE)((MICE_DA_INDEX(g_handleData) << 2) | MICE_HANDLE_MASK);
}
if (hObject == INVALID_HANDLE_VALUE) {
log_error(plfMisc, "Failed to create dummy handle: %03x", GetLastError());
} }
MICE_DA_ITER_END
return hObject; HANDLE_DATA newHandleData = {
.m_bOccupied = TRUE,
.m_pData = NULL,
.m_IsOnHeap = FALSE,
};
MiceDAPush(g_handleData, &newHandleData);
return (HANDLE)(((g_handleData->m_Length - 1) << 2) | MICE_HANDLE_MASK);
} }
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes) { void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes) {

View File

@ -0,0 +1,96 @@
#include "da.h"
#include <malloc.h>
#include <stdlib.h>
static inline void _MiceDAGrow(PMICE_DA lpDa) {
DWORD_PTR newSize = lpDa->m_Capacity * 2 + 1;
if (lpDa->m_Array) {
LPVOID newArray = realloc(lpDa->m_Array, lpDa->m_Size * newSize);
if (newArray != lpDa->m_Array) {
memcpy(newArray, lpDa->m_Array, lpDa->m_Size * lpDa->m_Capacity);
}
lpDa->m_Array = newArray;
} else {
lpDa->m_Array = malloc(lpDa->m_Size * newSize);
}
lpDa->m_Capacity = newSize;
}
BOOL MiceDAPush(PMICE_DA lpDa, LPVOID lpSrc) {
if (!lpDa || !lpSrc) return FALSE;
if (lpDa->m_Capacity == lpDa->m_Length) _MiceDAGrow(lpDa);
_MICE_DA_COPY_INTO_DA(lpDa, lpDa->m_Length, lpSrc);
lpDa->m_Length++;
return TRUE;
}
BOOL MiceDAPop(PMICE_DA lpDa, LPVOID lpDst) {
if (!lpDa) return FALSE;
if (lpDa->m_Length == 0) return FALSE;
lpDa->m_Length--;
if (lpDst) _MICE_DA_COPY_OUTOF_DA(lpDa, lpDa->m_Length, lpDst);
return TRUE;
}
BOOL MiceDAShift(PMICE_DA lpDa, LPVOID lpSrc) {
if (!lpDa || !lpSrc) return FALSE;
if (lpDa->m_Capacity == lpDa->m_Length) _MiceDAGrow(lpDa);
// Copy every value one index forwards
for (DWORD_PTR i = lpDa->m_Length; i; i--) {
memcpy(_MICE_DA_INDEX_P(lpDa, i), _MICE_DA_INDEX_P(lpDa, i + 1), lpDa->m_Size);
}
_MICE_DA_COPY_INTO_DA(lpDa, 0, lpSrc);
lpDa->m_Length++;
return TRUE;
}
BOOL MiceDAUnshift(PMICE_DA lpDa, LPVOID lpDst) {
if (!lpDa) return FALSE;
if (lpDst) _MICE_DA_COPY_OUTOF_DA(lpDa, 0, lpDst);
lpDa->m_Length--;
// Copy every value one index back
for (DWORD_PTR i = 0; i < lpDa->m_Length; i++) {
memcpy(_MICE_DA_INDEX_P(lpDa, i), _MICE_DA_INDEX_P(lpDa, i + 1), lpDa->m_Size);
}
return TRUE;
}
BOOL MiceDAGrowAndSet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue) {
if (!lpDa || !lpValue) return FALSE;
if (dwIndex >= lpDa->m_Length) {
while (dwIndex >= lpDa->m_Capacity) _MiceDAGrow(lpDa);
lpDa->m_Length = dwIndex + 1;
}
_MICE_DA_COPY_INTO_DA(lpDa, dwIndex, lpValue);
return TRUE;
}
BOOL MiceDASet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue) {
if (!lpDa || !lpValue) return FALSE;
if (dwIndex >= lpDa->m_Length) return FALSE;
_MICE_DA_COPY_INTO_DA(lpDa, dwIndex, lpValue);
return TRUE;
}
LPVOID MiceDAGet(PMICE_DA lpDa, DWORD_PTR dwIndex) {
if (!lpDa) NULL;
if (dwIndex >= lpDa->m_Length) return NULL;
return _MICE_DA_INDEX_P(lpDa, dwIndex);
}
BOOL MiceDARemove(PMICE_DA lpDa, DWORD_PTR dwIndex) {
if (!lpDa) return FALSE;
if (dwIndex > lpDa->m_Length) return FALSE;
if (dwIndex == lpDa->m_Length) {
lpDa->m_Length--;
return TRUE;
}
lpDa->m_Length--;
for (DWORD_PTR i = dwIndex; i < lpDa->m_Length; i++) {
memcpy(_MICE_DA_INDEX_P(lpDa, i), _MICE_DA_INDEX_P(lpDa, i + 1), lpDa->m_Size);
}
return TRUE;
}
DWORD_PTR MiceDALength(PMICE_DA lpDa) {
if (!lpDa) _invalid_parameter_noinfo_noreturn();
return lpDa->m_Length;
}

View File

@ -0,0 +1,37 @@
#include <Windows.h>
typedef struct MICE_DA {
DWORD_PTR m_Capacity;
DWORD_PTR m_Length;
DWORD_PTR m_Size;
LPVOID m_Array;
} MICE_DA, *PMICE_DA;
#define MICE_DA_NEW(name, type) \
MICE_DA __mda##name = { \
.m_Capacity = 0, .m_Length = 0, .m_Size = sizeof(type), .m_Array = NULL \
}; \
PMICE_DA name = &__mda##name;
#define _MICE_DA_INDEX_P(lpDa, index) \
(LPVOID)((DWORD_PTR)((lpDa)->m_Array) + (index) * (lpDa)->m_Size)
#define _MICE_DA_COPY_INTO_DA(lpDa, index, value) \
memcpy(_MICE_DA_INDEX_P((lpDa), (index)), (value), (lpDa)->m_Size)
#define _MICE_DA_COPY_OUTOF_DA(lpDa, index, value) \
memcpy((value), _MICE_DA_INDEX_P((lpDa), (index)), (lpDa)->m_Size)
#define MICE_DA_ITER(lpDa, type, name) \
for (DWORD_PTR __mdaI##lpDa = 0; __mdaI##lpDa < (lpDa)->m_Length; __mdaI##lpDa++) { \
type* name = (type*)_MICE_DA_INDEX_P((lpDa), __mdaI##lpDa);
#define MICE_DA_ITER_END }
#define MICE_DA_INDEX(lpDa) (__mdaI##lpDa)
#define MICE_DA_REMOVE_CURRENT(lpDa) MiceDARemove((lpDa), __mdaI##lpDa)
BOOL MiceDAPush(PMICE_DA lpDa, LPVOID lpSrc);
BOOL MiceDAPop(PMICE_DA lpDa, LPVOID lpDst);
BOOL MiceDAShift(PMICE_DA lpDa, LPVOID lpSrc);
BOOL MiceDAUnshift(PMICE_DA lpDa, LPVOID lpDst);
BOOL MiceDASet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue);
BOOL MiceDAGrowAndSet(PMICE_DA lpDa, DWORD_PTR dwIndex, LPVOID lpValue);
LPVOID MiceDAGet(PMICE_DA lpDa, DWORD_PTR dwIndex);
BOOL MiceDARemove(PMICE_DA lpDa, DWORD_PTR dwIndex);
DWORD_PTR MiceDALength(PMICE_DA lpDa);

View File

@ -14,6 +14,7 @@ mice_lib = static_library(
'dmi.c', 'dmi.c',
'ipc.c', 'ipc.c',
'serial.c', 'serial.c',
'da.c',
], ],
link_with: [ link_with: [
inih.get_variable('lib_inih'), inih.get_variable('lib_inih'),

View File

@ -13,6 +13,7 @@
#include "log.h" #include "log.h"
#include "patch.h" #include "patch.h"
#include "ringbuf.h" #include "ringbuf.h"
#include "da.h"
#define SRAM_PATH MiceIpcRelativePath("sram.bin") #define SRAM_PATH MiceIpcRelativePath("sram.bin")

View File

@ -91,3 +91,13 @@ executable(
amSram, amSram,
], ],
) )
executable(
'mice_test',
win_subsystem: subsystem,
sources: [
'test.c',
],
link_with: [
mice_lib
],
)

36
src/micetools/util/test.c Normal file
View File

@ -0,0 +1,36 @@
#include <stdio.h>
#include "../lib/mice/mice.h"
MICE_DA_NEW(testDa, int)
int main(int argc, char** argv) {
printf("length = %d\n", MiceDALength(testDa));
for (int i = 0; i < 10; i++) MiceDAPush(testDa, &i);
printf("length = %d\n", MiceDALength(testDa));
for (int i = 0; i < 10; i++) printf("[%d]: %d\n", i, *(int*)MiceDAGet(testDa, i));
MICE_DA_ITER(testDa, int, test) {
printf("iter: %d\n", *test);
} MICE_DA_ITER_END
puts("Pop");
MiceDAPop(testDa, NULL);
MICE_DA_ITER(testDa, int, test) {
printf("iter: %d\n", *test);
} MICE_DA_ITER_END
puts("Unshift");
MiceDAUnshift(testDa, NULL);
MICE_DA_ITER(testDa, int, test) {
printf("iter: %d\n", *test);
} MICE_DA_ITER_END
puts("Remove 1");
MiceDARemove(testDa, 1);
MICE_DA_ITER(testDa, int, test) {
printf("iter: %d\n", *test);
} MICE_DA_ITER_END
return 0;
}