mirror of
https://github.com/reactos/reactos.git
synced 2025-06-19 19:55:28 +00:00
[IMM32] Rewrite ImmLockIMC (#3975)
- Add Imm32InitContext and Imm32LockIMCEx helper functions. - Re-implement ImmLockIMC function. - Modify CLIENTIMC and INPUTCONTEXTDX structures. CORE-11700
This commit is contained in:
parent
be9a788f8b
commit
b3382d8d24
5 changed files with 212 additions and 37 deletions
|
@ -354,7 +354,7 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
|
||||||
if (!pClientImc)
|
if (!pClientImc)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
if (pClientImc->hImc == NULL)
|
if (pClientImc->hInputContext == NULL)
|
||||||
{
|
{
|
||||||
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
|
pClientImc->dwFlags |= CLIENTIMC_UNKNOWN1;
|
||||||
ImmUnlockClientImc(pClientImc);
|
ImmUnlockClientImc(pClientImc);
|
||||||
|
@ -390,11 +390,11 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
|
||||||
pClientImc->hKL = NULL;
|
pClientImc->hKL = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImmDestroyIMCC(pIC->hPrivate);
|
pIC->hPrivate = ImmDestroyIMCC(pIC->hPrivate);
|
||||||
ImmDestroyIMCC(pIC->hMsgBuf);
|
pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
|
||||||
ImmDestroyIMCC(pIC->hGuideLine);
|
pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
|
||||||
ImmDestroyIMCC(pIC->hCandInfo);
|
pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
|
||||||
ImmDestroyIMCC(pIC->hCompStr);
|
pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
|
||||||
|
|
||||||
Imm32CleanupContextExtra(pIC);
|
Imm32CleanupContextExtra(pIC);
|
||||||
|
|
||||||
|
@ -409,6 +409,182 @@ BOOL APIENTRY Imm32CleanupContext(HIMC hIMC, HKL hKL, BOOL bKeep)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL APIENTRY
|
||||||
|
Imm32InitContext(HIMC hIMC, LPINPUTCONTEXT pIC, PCLIENTIMC pClientImc, HKL hKL, BOOL fSelect)
|
||||||
|
{
|
||||||
|
DWORD dwIndex, cbPrivate;
|
||||||
|
PIMEDPI pImeDpi = NULL;
|
||||||
|
LPCOMPOSITIONSTRING pCS;
|
||||||
|
LPCANDIDATEINFO pCI;
|
||||||
|
LPGUIDELINE pGL;
|
||||||
|
/* NOTE: Windows does recursive call ImmLockIMC here but we don't do so. */
|
||||||
|
|
||||||
|
/* Create IC components */
|
||||||
|
pIC->hCompStr = ImmCreateIMCC(sizeof(COMPOSITIONSTRING));
|
||||||
|
pIC->hCandInfo = ImmCreateIMCC(sizeof(CANDIDATEINFO));
|
||||||
|
pIC->hGuideLine = ImmCreateIMCC(sizeof(GUIDELINE));
|
||||||
|
pIC->hMsgBuf = ImmCreateIMCC(sizeof(UINT));
|
||||||
|
if (!pIC->hCompStr || !pIC->hCandInfo || !pIC->hGuideLine || !pIC->hMsgBuf)
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
/* Initialize IC components */
|
||||||
|
pCS = ImmLockIMCC(pIC->hCompStr);
|
||||||
|
if (!pCS)
|
||||||
|
goto Fail;
|
||||||
|
pCS->dwSize = sizeof(COMPOSITIONSTRING);
|
||||||
|
ImmUnlockIMCC(pIC->hCompStr);
|
||||||
|
|
||||||
|
pCI = ImmLockIMCC(pIC->hCandInfo);
|
||||||
|
if (!pCI)
|
||||||
|
goto Fail;
|
||||||
|
pCI->dwSize = sizeof(CANDIDATEINFO);
|
||||||
|
ImmUnlockIMCC(pIC->hCandInfo);
|
||||||
|
|
||||||
|
pGL = ImmLockIMCC(pIC->hGuideLine);
|
||||||
|
if (!pGL)
|
||||||
|
goto Fail;
|
||||||
|
pGL->dwSize = sizeof(GUIDELINE);
|
||||||
|
ImmUnlockIMCC(pIC->hGuideLine);
|
||||||
|
|
||||||
|
pIC->dwNumMsgBuf = 0;
|
||||||
|
pIC->fOpen = FALSE;
|
||||||
|
pIC->fdwConversion = pIC->fdwSentence = 0;
|
||||||
|
|
||||||
|
for (dwIndex = 0; dwIndex < MAX_CANDIDATEFORM; ++dwIndex)
|
||||||
|
pIC->cfCandForm[dwIndex].dwIndex = IMM_INVALID_CANDFORM;
|
||||||
|
|
||||||
|
/* Get private data size */
|
||||||
|
pImeDpi = ImmLockImeDpi(hKL);
|
||||||
|
if (!pImeDpi)
|
||||||
|
{
|
||||||
|
cbPrivate = sizeof(DWORD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Update CLIENTIMC */
|
||||||
|
pClientImc->uCodePage = pImeDpi->uCodePage;
|
||||||
|
if (ImeDpi_IsUnicode(pImeDpi))
|
||||||
|
pClientImc->dwFlags |= CLIENTIMC_WIDE;
|
||||||
|
|
||||||
|
cbPrivate = pImeDpi->ImeInfo.dwPrivateDataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create private data */
|
||||||
|
pIC->hPrivate = ImmCreateIMCC(cbPrivate);
|
||||||
|
if (!pIC->hPrivate)
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
|
if (pImeDpi)
|
||||||
|
{
|
||||||
|
/* Select the IME */
|
||||||
|
if (fSelect)
|
||||||
|
{
|
||||||
|
if (IS_IME_HKL(hKL))
|
||||||
|
pImeDpi->ImeSelect(hIMC, TRUE);
|
||||||
|
else if (Imm32IsCiceroMode() && !Imm32Is16BitMode() && pImeDpi->CtfImeSelectEx)
|
||||||
|
pImeDpi->CtfImeSelectEx(hIMC, TRUE, hKL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set HKL */
|
||||||
|
pClientImc->hKL = hKL;
|
||||||
|
|
||||||
|
ImmUnlockImeDpi(pImeDpi);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
Fail:
|
||||||
|
if (pImeDpi)
|
||||||
|
ImmUnlockImeDpi(pImeDpi);
|
||||||
|
|
||||||
|
pIC->hMsgBuf = ImmDestroyIMCC(pIC->hMsgBuf);
|
||||||
|
pIC->hGuideLine = ImmDestroyIMCC(pIC->hGuideLine);
|
||||||
|
pIC->hCandInfo = ImmDestroyIMCC(pIC->hCandInfo);
|
||||||
|
pIC->hCompStr = ImmDestroyIMCC(pIC->hCompStr);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPINPUTCONTEXT APIENTRY Imm32LockIMCEx(HIMC hIMC, BOOL fSelect)
|
||||||
|
{
|
||||||
|
HANDLE hIC;
|
||||||
|
LPINPUTCONTEXT pIC = NULL;
|
||||||
|
PCLIENTIMC pClientImc;
|
||||||
|
WORD Word;
|
||||||
|
DWORD dwThreadId;
|
||||||
|
HKL hKL, hNewKL;
|
||||||
|
PIMEDPI pImeDpi = NULL;
|
||||||
|
BOOL bInited;
|
||||||
|
|
||||||
|
pClientImc = ImmLockClientImc(hIMC);
|
||||||
|
if (!pClientImc)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
RtlEnterCriticalSection(&pClientImc->cs);
|
||||||
|
|
||||||
|
if (!pClientImc->hInputContext)
|
||||||
|
{
|
||||||
|
dwThreadId = (DWORD)NtUserQueryInputContext(hIMC, 1);
|
||||||
|
|
||||||
|
if (dwThreadId == GetCurrentThreadId() && Imm32IsCiceroMode() && !Imm32Is16BitMode())
|
||||||
|
{
|
||||||
|
hKL = GetKeyboardLayout(0);
|
||||||
|
Word = LOWORD(hKL);
|
||||||
|
hNewKL = (HKL)(DWORD_PTR)MAKELONG(Word, Word);
|
||||||
|
|
||||||
|
pImeDpi = ImmLockOrLoadImeDpi(hNewKL);
|
||||||
|
if (pImeDpi)
|
||||||
|
{
|
||||||
|
FIXME("We have to do something here\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NtUserQueryInputContext(hIMC, 2))
|
||||||
|
{
|
||||||
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
hIC = LocalAlloc(LHND, sizeof(INPUTCONTEXTDX));
|
||||||
|
if (!hIC)
|
||||||
|
{
|
||||||
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
pClientImc->hInputContext = hIC;
|
||||||
|
|
||||||
|
pIC = LocalLock(pClientImc->hInputContext);
|
||||||
|
if (!pIC)
|
||||||
|
{
|
||||||
|
pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
|
||||||
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
|
||||||
|
hKL = GetKeyboardLayout(dwThreadId);
|
||||||
|
// bInited = Imm32InitContext(hIMC, hKL, fSelect);
|
||||||
|
bInited = Imm32InitContext(hIMC, pIC, pClientImc, hKL, fSelect);
|
||||||
|
LocalUnlock(pClientImc->hInputContext);
|
||||||
|
|
||||||
|
if (!bInited)
|
||||||
|
{
|
||||||
|
pIC = NULL;
|
||||||
|
pClientImc->hInputContext = LocalFree(pClientImc->hInputContext);
|
||||||
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
||||||
|
goto Quit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FIXME("We have to do something here\n");
|
||||||
|
|
||||||
|
RtlLeaveCriticalSection(&pClientImc->cs);
|
||||||
|
pIC = LocalLock(pClientImc->hInputContext);
|
||||||
|
InterlockedIncrement(&pClientImc->cLockObj);
|
||||||
|
|
||||||
|
Quit:
|
||||||
|
ImmUnlockClientImc(pClientImc);
|
||||||
|
return pIC;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ImmDestroyContext (IMM32.@)
|
* ImmDestroyContext (IMM32.@)
|
||||||
*/
|
*/
|
||||||
|
@ -481,7 +657,7 @@ PCLIENTIMC WINAPI ImmLockClientImc(HIMC hImc)
|
||||||
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
|
VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
|
||||||
{
|
{
|
||||||
LONG cLocks;
|
LONG cLocks;
|
||||||
HIMC hImc;
|
HANDLE hInputContext;
|
||||||
|
|
||||||
TRACE("(%p)\n", pClientImc);
|
TRACE("(%p)\n", pClientImc);
|
||||||
|
|
||||||
|
@ -489,9 +665,9 @@ VOID WINAPI ImmUnlockClientImc(PCLIENTIMC pClientImc)
|
||||||
if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_UNKNOWN1))
|
if (cLocks != 0 || !(pClientImc->dwFlags & CLIENTIMC_UNKNOWN1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hImc = pClientImc->hImc;
|
hInputContext = pClientImc->hInputContext;
|
||||||
if (hImc)
|
if (hInputContext)
|
||||||
LocalFree(hImc);
|
LocalFree(hInputContext);
|
||||||
|
|
||||||
RtlDeleteCriticalSection(&pClientImc->cs);
|
RtlDeleteCriticalSection(&pClientImc->cs);
|
||||||
Imm32HeapFree(pClientImc);
|
Imm32HeapFree(pClientImc);
|
||||||
|
@ -925,16 +1101,14 @@ HKL WINAPI ImmInstallIMEW(LPCWSTR lpszIMEFileName, LPCWSTR lpszLayoutText)
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* ImmLockIMC(IMM32.@)
|
* ImmLockIMC(IMM32.@)
|
||||||
*/
|
*
|
||||||
|
* NOTE: This is not ImmLockIMCC. Don't confuse.
|
||||||
|
*/
|
||||||
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
|
LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
|
||||||
{
|
{
|
||||||
InputContextData *data = get_imc_data(hIMC);
|
TRACE("(%p)\n", hIMC);
|
||||||
|
return Imm32LockIMCEx(hIMC, TRUE);
|
||||||
if (!data)
|
|
||||||
return NULL;
|
|
||||||
data->dwLock++;
|
|
||||||
return &data->IMC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -943,15 +1117,13 @@ LPINPUTCONTEXT WINAPI ImmLockIMC(HIMC hIMC)
|
||||||
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
|
BOOL WINAPI ImmUnlockIMC(HIMC hIMC)
|
||||||
{
|
{
|
||||||
PCLIENTIMC pClientImc;
|
PCLIENTIMC pClientImc;
|
||||||
HIMC hClientImc;
|
|
||||||
|
|
||||||
pClientImc = ImmLockClientImc(hIMC);
|
pClientImc = ImmLockClientImc(hIMC);
|
||||||
if (pClientImc == NULL)
|
if (pClientImc == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
hClientImc = pClientImc->hImc;
|
if (pClientImc->hInputContext)
|
||||||
if (hClientImc)
|
LocalUnlock(pClientImc->hInputContext);
|
||||||
LocalUnlock(hClientImc);
|
|
||||||
|
|
||||||
InterlockedDecrement(&pClientImc->cLockObj);
|
InterlockedDecrement(&pClientImc->cLockObj);
|
||||||
ImmUnlockClientImc(pClientImc);
|
ImmUnlockClientImc(pClientImc);
|
||||||
|
|
|
@ -276,7 +276,7 @@ DWORD WINAPI ImmGetIMCCSize(HIMCC imcc)
|
||||||
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
|
DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
|
||||||
{
|
{
|
||||||
DWORD ret;
|
DWORD ret;
|
||||||
HIMC hClientImc;
|
HANDLE hInputContext;
|
||||||
PCLIENTIMC pClientImc;
|
PCLIENTIMC pClientImc;
|
||||||
|
|
||||||
pClientImc = ImmLockClientImc(hIMC);
|
pClientImc = ImmLockClientImc(hIMC);
|
||||||
|
@ -284,9 +284,9 @@ DWORD WINAPI ImmGetIMCLockCount(HIMC hIMC)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
hClientImc = pClientImc->hImc;
|
hInputContext = pClientImc->hInputContext;
|
||||||
if (hClientImc)
|
if (hInputContext)
|
||||||
ret = (LocalFlags(hClientImc) & LMEM_LOCKCOUNT);
|
ret = (LocalFlags(hInputContext) & LMEM_LOCKCOUNT);
|
||||||
|
|
||||||
ImmUnlockClientImc(pClientImc);
|
ImmUnlockClientImc(pClientImc);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -24,15 +24,15 @@ START_TEST(clientimc)
|
||||||
DWORD dwCode;
|
DWORD dwCode;
|
||||||
CLIENTIMC *pClientImc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
CLIENTIMC *pClientImc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLIENTIMC));
|
||||||
|
|
||||||
pClientImc->hImc = (HIMC)ImmCreateIMCC(4);
|
pClientImc->hInputContext = (HANDLE)ImmCreateIMCC(4);
|
||||||
pClientImc->cLockObj = 2;
|
pClientImc->cLockObj = 2;
|
||||||
pClientImc->dwFlags = 0x40;
|
pClientImc->dwFlags = 0x40;
|
||||||
RtlInitializeCriticalSection(&pClientImc->cs);
|
RtlInitializeCriticalSection(&pClientImc->cs);
|
||||||
ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hImc), 4);
|
ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hInputContext), 4);
|
||||||
|
|
||||||
ImmUnlockClientImc(pClientImc);
|
ImmUnlockClientImc(pClientImc);
|
||||||
ok_long(pClientImc->cLockObj, 1);
|
ok_long(pClientImc->cLockObj, 1);
|
||||||
ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hImc), 4);
|
ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hInputContext), 4);
|
||||||
|
|
||||||
dwCode = 0;
|
dwCode = 0;
|
||||||
_SEH2_TRY
|
_SEH2_TRY
|
||||||
|
@ -47,7 +47,7 @@ START_TEST(clientimc)
|
||||||
ok_long(dwCode, STATUS_ACCESS_VIOLATION);
|
ok_long(dwCode, STATUS_ACCESS_VIOLATION);
|
||||||
|
|
||||||
ok_long(pClientImc->cLockObj, 0);
|
ok_long(pClientImc->cLockObj, 0);
|
||||||
ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hImc), 0);
|
ok_long(ImmGetIMCCSize((HIMCC)pClientImc->hInputContext), 0);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, pClientImc);
|
HeapFree(GetProcessHeap(), 0, pClientImc);
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,17 +92,19 @@ typedef struct INPUTCONTEXTDX /* unconfirmed */
|
||||||
INPUTCONTEXT;
|
INPUTCONTEXT;
|
||||||
UINT nVKey;
|
UINT nVKey;
|
||||||
BOOL bNeedsTrans;
|
BOOL bNeedsTrans;
|
||||||
DWORD dwUnknownCat;
|
DWORD dwUnknown1;
|
||||||
DWORD dwUIFlags;
|
DWORD dwUIFlags;
|
||||||
DWORD dwUnknownDog;
|
DWORD dwUnknown2;
|
||||||
void *pUnknownFox;
|
void *pUnknown3;
|
||||||
/* ... */
|
DWORD dwUnknown4;
|
||||||
|
DWORD dwUnknown5;
|
||||||
} INPUTCONTEXTDX, *LPINPUTCONTEXTDX;
|
} INPUTCONTEXTDX, *LPINPUTCONTEXTDX;
|
||||||
|
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
C_ASSERT(offsetof(INPUTCONTEXTDX, nVKey) == 0x140);
|
C_ASSERT(offsetof(INPUTCONTEXTDX, nVKey) == 0x140);
|
||||||
C_ASSERT(offsetof(INPUTCONTEXTDX, bNeedsTrans) == 0x144);
|
C_ASSERT(offsetof(INPUTCONTEXTDX, bNeedsTrans) == 0x144);
|
||||||
C_ASSERT(offsetof(INPUTCONTEXTDX, dwUIFlags) == 0x14c);
|
C_ASSERT(offsetof(INPUTCONTEXTDX, dwUIFlags) == 0x14c);
|
||||||
|
C_ASSERT(sizeof(INPUTCONTEXTDX) == 0x160);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// bits of fdwInit of INPUTCONTEXT
|
// bits of fdwInit of INPUTCONTEXT
|
||||||
|
|
|
@ -1290,21 +1290,22 @@ C_ASSERT(sizeof(IMEDPI) == 0xa8);
|
||||||
/* unconfirmed */
|
/* unconfirmed */
|
||||||
typedef struct tagCLIENTIMC
|
typedef struct tagCLIENTIMC
|
||||||
{
|
{
|
||||||
HIMC hImc;
|
HANDLE hInputContext; /* LocalAlloc'ed LHND */
|
||||||
LONG cLockObj;
|
LONG cLockObj;
|
||||||
DWORD dwFlags;
|
DWORD dwFlags;
|
||||||
DWORD unknown;
|
DWORD unknown;
|
||||||
RTL_CRITICAL_SECTION cs;
|
RTL_CRITICAL_SECTION cs;
|
||||||
DWORD unknown2;
|
UINT uCodePage;
|
||||||
HKL hKL;
|
HKL hKL;
|
||||||
BOOL bUnknown4;
|
BOOL bUnknown4;
|
||||||
} CLIENTIMC, *PCLIENTIMC;
|
} CLIENTIMC, *PCLIENTIMC;
|
||||||
|
|
||||||
#ifndef _WIN64
|
#ifndef _WIN64
|
||||||
C_ASSERT(offsetof(CLIENTIMC, hImc) == 0x0);
|
C_ASSERT(offsetof(CLIENTIMC, hInputContext) == 0x0);
|
||||||
C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4);
|
C_ASSERT(offsetof(CLIENTIMC, cLockObj) == 0x4);
|
||||||
C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8);
|
C_ASSERT(offsetof(CLIENTIMC, dwFlags) == 0x8);
|
||||||
C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10);
|
C_ASSERT(offsetof(CLIENTIMC, cs) == 0x10);
|
||||||
|
C_ASSERT(offsetof(CLIENTIMC, uCodePage) == 0x28);
|
||||||
C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c);
|
C_ASSERT(offsetof(CLIENTIMC, hKL) == 0x2c);
|
||||||
C_ASSERT(sizeof(CLIENTIMC) == 0x34);
|
C_ASSERT(sizeof(CLIENTIMC) == 0x34);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue