Use handles as an index into the data array
This commit is contained in:
parent
d31316d821
commit
8ca5b1a051
@ -3,7 +3,7 @@
|
||||
#define RESERVED_JVS_COM_PORT 4
|
||||
|
||||
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;
|
||||
return pHData->hook->com_hook->com_device;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ com_hook_t* new_com_hook(BYTE port) {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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) {
|
||||
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);
|
||||
|
||||
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) {
|
||||
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)
|
||||
return TrueGetCommTimeouts(hFile, lpCommTimeouts);
|
||||
|
||||
@ -72,7 +72,7 @@ BOOL WINAPI FakeGetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
|
||||
BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS 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)
|
||||
return TrueSetCommTimeouts(hFile, lpCommTimeouts);
|
||||
|
||||
@ -87,7 +87,7 @@ BOOL WINAPI FakeSetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts) {
|
||||
BOOL WINAPI FakeSetupComm(HANDLE hFile, DWORD dwInQueue, DWORD 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)
|
||||
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) {
|
||||
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);
|
||||
|
||||
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) {
|
||||
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)
|
||||
return TrueGetCommModemStatus(hFile, lpModelStat);
|
||||
|
||||
@ -131,7 +131,7 @@ BOOL WINAPI FakeGetCommModemStatus(HANDLE hFile, LPDWORD lpModelStat) {
|
||||
BOOL WINAPI FakeWaitCommEvent(HANDLE hFile, LPDWORD lpEvtMask, LPOVERLAPPED lpOverlapped) {
|
||||
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)
|
||||
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) {
|
||||
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)
|
||||
return TrueClearCommError(hFile, lpErrors, lpStat);
|
||||
|
||||
|
@ -5,7 +5,7 @@ typedef struct {
|
||||
size_t partition;
|
||||
} find_index_t;
|
||||
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;
|
||||
|
||||
while (1) {
|
||||
@ -69,7 +69,7 @@ HANDLE WINAPI FakeFindFirstVolumeW(LPWSTR lpszVolumeName, DWORD cchBufferLength)
|
||||
find_index->disk = 0;
|
||||
find_index->partition = 0;
|
||||
HANDLE handle = GetDummyHandle();
|
||||
SetDataForHandle(handle, HDATA_FIND_VOLUME, find_index, TRUE);
|
||||
SetDataForHandle(handle, find_index, TRUE);
|
||||
|
||||
FakeFindNextVolumeW(handle, lpszVolumeName, cchBufferLength);
|
||||
return handle;
|
||||
@ -79,13 +79,13 @@ HANDLE WINAPI FakeFindFirstVolumeA(LPSTR lpszVolumeName, DWORD cchBufferLength)
|
||||
find_index->disk = 0;
|
||||
find_index->partition = 0;
|
||||
HANDLE handle = GetDummyHandle();
|
||||
SetDataForHandle(handle, HDATA_FIND_VOLUME, find_index, TRUE);
|
||||
SetDataForHandle(handle, find_index, TRUE);
|
||||
|
||||
FakeFindNextVolumeA(handle, lpszVolumeName, cchBufferLength);
|
||||
return handle;
|
||||
}
|
||||
BOOL WINAPI FakeFindVolumeClose(HANDLE hFindVolume) {
|
||||
if (RemoveDataForHandle(hFindVolume, HDATA_FIND_VOLUME)) return _CloseHandle(hFindVolume);
|
||||
if (RemoveDataForHandle(hFindVolume)) return _CloseHandle(hFindVolume);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ HANDLE open_hook(file_hook_t* file_hook) {
|
||||
opened->ctx.m_Handle = handle;
|
||||
opened->ctx.m_HookData = file_hook->hook_data;
|
||||
|
||||
SetDataForHandle(handle, HDATA_FILE, opened, TRUE);
|
||||
SetDataForHandle(handle, opened, TRUE);
|
||||
|
||||
return handle;
|
||||
}
|
||||
@ -213,7 +213,7 @@ BOOL WINAPI FakeDeleteFileW(LPCWSTR pszPath) {
|
||||
BOOL WINAPI FakeDeviceIoControl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer,
|
||||
DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize,
|
||||
LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped) {
|
||||
open_hook_t* pHData = GetDataForHandle(hDevice, HDATA_FILE);
|
||||
open_hook_t* pHData = GetDataForHandle(hDevice);
|
||||
if (pHData == NULL) {
|
||||
return TrueDeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer,
|
||||
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 dwMoveMethod) {
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
open_hook_t* pHData = GetDataForHandle(hFile);
|
||||
if (pHData == NULL)
|
||||
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,
|
||||
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod) {
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
open_hook_t* pHData = GetDataForHandle(hFile);
|
||||
if (pHData != NULL) {
|
||||
if (dwMoveMethod == FILE_BEGIN) {
|
||||
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) {
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
open_hook_t* pHData = GetDataForHandle(hFile);
|
||||
if (pHData == NULL) {
|
||||
return TrueGetFileSizeEx(hFile, lpFileSize);
|
||||
}
|
||||
@ -300,7 +300,7 @@ DWORD WINAPI FakeWriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesT
|
||||
lpOverlapped);
|
||||
}
|
||||
|
||||
open_hook_t* pHData = GetDataForHandle(hFile, HDATA_FILE);
|
||||
open_hook_t* pHData = GetDataForHandle(hFile);
|
||||
if (pHData == NULL) {
|
||||
return TrueWriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten,
|
||||
lpOverlapped);
|
||||
@ -327,7 +327,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
|
||||
}
|
||||
// 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) {
|
||||
return TrueReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead,
|
||||
lpOverlapped);
|
||||
@ -348,7 +348,7 @@ BOOL WINAPI FakeReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
|
||||
}
|
||||
|
||||
BOOL WINAPI FakeCloseHandle(HANDLE hObject) {
|
||||
RemoveDataForHandle(hObject, HDATA_ANY);
|
||||
RemoveDataForHandle(hObject);
|
||||
return TrueCloseHandle(hObject);
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,11 @@
|
||||
|
||||
#include "hook.h"
|
||||
|
||||
#define HDATA_FILE 0
|
||||
#define HDATA_FIND_VOLUME 1
|
||||
#define HDATA_ANY 0xFFFFFFFF
|
||||
|
||||
BOOL FileExistsW(const wchar_t* szPath);
|
||||
BOOL FileExistsA(const char* szPath);
|
||||
PVOID GetDataForHandle(HANDLE hObject, DWORD type);
|
||||
void SetDataForHandle(HANDLE hObject, DWORD type, PVOID pData, BOOL isHeap);
|
||||
BOOL RemoveDataForHandle(HANDLE hObject, DWORD type);
|
||||
PVOID GetDataForHandle(HANDLE hObject);
|
||||
void SetDataForHandle(HANDLE hObject, PVOID pData, BOOL isHeap);
|
||||
BOOL RemoveDataForHandle(HANDLE hObject);
|
||||
HANDLE GetDummyHandle();
|
||||
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes);
|
||||
|
||||
|
@ -7,6 +7,9 @@
|
||||
|
||||
#include "../hooks/files.h"
|
||||
|
||||
// Use the second tag bit to indicate a mice handle
|
||||
#define MICE_HANDLE_MASK 0x00000002
|
||||
|
||||
void PrintStack(void) {
|
||||
unsigned int i;
|
||||
void* stack[100];
|
||||
@ -43,70 +46,73 @@ BOOL FileExistsA(const char* szPath) {
|
||||
}
|
||||
|
||||
typedef struct HANDLE_DATA {
|
||||
HANDLE m_Handle;
|
||||
BOOL m_bOccupied;
|
||||
PVOID m_pData;
|
||||
DWORD m_Type;
|
||||
BOOL m_IsOnHeap;
|
||||
} HANDLE_DATA;
|
||||
} HANDLE_DATA, *PHANDLE_DATA;
|
||||
MICE_DA_NEW(g_handleData, HANDLE_DATA)
|
||||
|
||||
PVOID GetDataForHandle(HANDLE hObject, DWORD type) {
|
||||
PVOID GetDataForHandle(HANDLE hObject) {
|
||||
if (hObject == INVALID_HANDLE_VALUE) return NULL;
|
||||
if (!hObject & MICE_HANDLE_MASK) return NULL;
|
||||
|
||||
MICE_DA_ITER(g_handleData, HANDLE_DATA, i) {
|
||||
if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) {
|
||||
return i->m_pData;
|
||||
DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2;
|
||||
PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex);
|
||||
if (found == NULL) return NULL;
|
||||
return found->m_pData;
|
||||
}
|
||||
void SetDataForHandle(HANDLE hObject, PVOID pData, BOOL isHeap) {
|
||||
if (hObject == INVALID_HANDLE_VALUE) return;
|
||||
if (!hObject & MICE_HANDLE_MASK) return;
|
||||
|
||||
DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2;
|
||||
if (dwIndex < g_handleData->m_Length) {
|
||||
PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex);
|
||||
if (found) {
|
||||
found->m_bOccupied = TRUE;
|
||||
if (found->m_IsOnHeap && found->m_pData) free(found->m_pData);
|
||||
found->m_pData = pData;
|
||||
found->m_IsOnHeap = isHeap;
|
||||
return;
|
||||
}
|
||||
}
|
||||
MICE_DA_ITER_END
|
||||
return NULL;
|
||||
}
|
||||
void SetDataForHandle(HANDLE hObject, DWORD type, PVOID pData, BOOL isHeap) {
|
||||
if (hObject == INVALID_HANDLE_VALUE) return;
|
||||
|
||||
HANDLE_DATA newHandleData = {
|
||||
.m_bOccupied = TRUE,
|
||||
.m_pData = pData,
|
||||
.m_IsOnHeap = isHeap,
|
||||
};
|
||||
MiceDAGrowAndSet(g_handleData, dwIndex, &newHandleData);
|
||||
}
|
||||
BOOL RemoveDataForHandle(HANDLE hObject, DWORD type) {
|
||||
if (hObject == INVALID_HANDLE_VALUE) return FALSE;
|
||||
if (!hObject & MICE_HANDLE_MASK) return FALSE;
|
||||
DWORD_PTR dwIndex = (DWORD_PTR)hObject >> 2;
|
||||
|
||||
PHANDLE_DATA found = MiceDAGet(g_handleData, dwIndex);
|
||||
if (found) {
|
||||
if (found->m_IsOnHeap && found->m_pData) free(found->m_pData);
|
||||
found->m_pData = NULL;
|
||||
found->m_bOccupied = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE GetDummyHandle() {
|
||||
MICE_DA_ITER(g_handleData, HANDLE_DATA, i) {
|
||||
if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) {
|
||||
if (i->m_IsOnHeap) free(i->m_pData);
|
||||
i->m_pData = pData;
|
||||
i->m_IsOnHeap = isHeap;
|
||||
return;
|
||||
if (!i->m_bOccupied) {
|
||||
i->m_bOccupied = TRUE;
|
||||
return (HANDLE)((MICE_DA_INDEX(g_handleData) << 2) | MICE_HANDLE_MASK);
|
||||
}
|
||||
}
|
||||
MICE_DA_ITER_END
|
||||
|
||||
HANDLE_DATA newHandleData = {
|
||||
.m_Handle = hObject,
|
||||
.m_pData = pData,
|
||||
.m_IsOnHeap = isHeap,
|
||||
.m_Type = type,
|
||||
.m_bOccupied = TRUE,
|
||||
.m_pData = NULL,
|
||||
.m_IsOnHeap = FALSE,
|
||||
};
|
||||
MiceDAPush(g_handleData, &newHandleData);
|
||||
}
|
||||
BOOL RemoveDataForHandle(HANDLE hObject, DWORD type) {
|
||||
if (hObject == INVALID_HANDLE_VALUE) return FALSE;
|
||||
|
||||
MICE_DA_ITER(g_handleData, HANDLE_DATA, i) {
|
||||
if (i->m_Handle == hObject && (type == HDATA_ANY || i->m_Type == type)) {
|
||||
if (i->m_IsOnHeap) free(i->m_pData);
|
||||
MICE_DA_REMOVE_CURRENT(g_handleData);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
MICE_DA_ITER_END
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
HANDLE GetDummyHandle() {
|
||||
CHAR path[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, path, MAX_PATH);
|
||||
HANDLE hObject =
|
||||
_CreateFileA(path, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (hObject == INVALID_HANDLE_VALUE) {
|
||||
log_error(plfMisc, "Failed to create dummy handle: %03x", GetLastError());
|
||||
}
|
||||
|
||||
return hObject;
|
||||
return (HANDLE)(((g_handleData->m_Length - 1) << 2) | MICE_HANDLE_MASK);
|
||||
}
|
||||
|
||||
void BytesToHex(char* hex_buffer, BYTE* bytes, DWORD nbytes) {
|
||||
|
@ -55,6 +55,15 @@ BOOL MiceDAUnshift(PMICE_DA lpDa, LPVOID lpDst) {
|
||||
}
|
||||
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;
|
||||
|
@ -23,6 +23,7 @@ typedef struct MICE_DA {
|
||||
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);
|
||||
@ -30,6 +31,7 @@ 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);
|
||||
|
Loading…
Reference in New Issue
Block a user