00001
00002
00003
00004
00005
00006
00007
00008
00009
00011
00012
#include "precomp.h"
00013
00014
#ifdef HIRO_DEBUG
00015
#define D(x) x
00016
#else
00017 #define D(x)
00018
#endif
00019
00020 #define IME_MENU_FILE_NAME L"ImmMenuInfo"
00021 #define IME_MENU_MAXMEM (128 * 1024) // maximum size of mapped file
00022
00024
00025
00026
00027
00028
00029
00030
00031
00032
00034
00035 typedef struct _IMEMENU_BMP_HEADER {
00036 struct _IMEMENU_BMP_HEADER*
lpNext;
00037 HBITMAP
hBitmap;
00038 LPBYTE
pBits;
00039 BITMAPINFO
bmi;
00040 }
IMEMENU_BMP_HEADER;
00041
00042 typedef struct {
00043 UINT cbSize;
00044 UINT fType;
00045 UINT fState;
00046 UINT wID;
00047 IMEMENU_BMP_HEADER* lpBmpChecked;
00048 IMEMENU_BMP_HEADER* lpBmpUnchecked;
00049 DWORD dwItemData;
00050 WCHAR szString[IMEMENUITEM_STRING_SIZE];
00051 IMEMENU_BMP_HEADER* lpBmpItem;
00052 }
IMEMENU_ITEM;
00053
00054 typedef struct {
00055 DWORD dwVersion;
00056 DWORD dwMemSize;
00057 DWORD dwFlags;
00058 DWORD dwType;
00059 IMEMENU_ITEM* lpImeParentMenu;
00060 IMEMENU_ITEM* lpImeMenu;
00061 DWORD dwSize;
00062 IMEMENU_BMP_HEADER* lpBmp;
00063 IMEMENU_BMP_HEADER* lpBmpNext;
00064 }
IMEMENU_HEADER;
00065
00066
00067
00068 #define CONVTO_OFFSET(x) ((x) = (LPVOID)((x) ? ((LPBYTE)(x) - offset) : NULL))
00069 #define CONVTO_PTR(x) ((x) = (LPVOID)((x) ? ((LPBYTE)(x) + offset) : NULL))
00070
00071
#if DBG
00072
#define CHK_OFFSET(x) if ((ULONG_PTR)(x) >= pHeader->dwMemSize) { \
00073
RIPMSG2(RIP_WARNING, "CHK_OFFSET(%s=%lx) is out of range.", #x, (ULONG_PTR)(x)); \
00074
}
00075
#define CHK_PTR(x) if ((LPVOID)(x) < (LPVOID)pHeader || (LPBYTE)(x) > (LPBYTE)pHeader + pHeader->dwMemSize) { \
00076
if ((x) != NULL) { \
00077
RIPMSG2(RIP_WARNING, "CHK_PTR(%s=%lx) is out of range.", #x, (ULONG_PTR)(x)); \
00078
DebugBreak(); \
00079
} \
00080
}
00081
#else
00082 #define CHK_OFFSET(x)
00083 #define CHK_PTR(x) if ((x) != NULL) { \
00084
if ((LPVOID)(x) < (LPVOID)pHeader || (LPBYTE)(x) > (LPBYTE)pHeader + pHeader->dwMemSize) { \
00085
goto cleanup; \
00086
} \
00087
}
00088
#endif
00089
00090 void ConvertImeMenuItemInfoAtoW(LPIMEMENUITEMINFOA lpA, LPIMEMENUITEMINFOW lpW,
int nCP, BOOL copyBmp)
00091 {
00092
int i;
00093
00094 lpW->cbSize = lpA->cbSize;
00095 lpW->fType = lpA->fType;
00096 lpW->fState = lpA->fState;
00097 lpW->wID = lpA->wID;
00098
if (copyBmp) {
00099 lpW->hbmpChecked = lpA->hbmpChecked;
00100 lpW->hbmpUnchecked = lpA->hbmpUnchecked;
00101 lpW->hbmpItem = lpA->hbmpItem;
00102 }
00103 lpW->dwItemData = lpA->dwItemData;
00104
00105 i = MultiByteToWideChar(nCP,
00106 0,
00107 lpA->szString,
00108 lstrlenA(lpA->szString),
00109 lpW->szString,
00110 IMEMENUITEM_STRING_SIZE);
00111
00112 lpW->szString[i] =
L'\0';
00113 }
00114
00115 void ConvertImeMenuItemInfoWtoA(LPIMEMENUITEMINFOW lpW, LPIMEMENUITEMINFOA lpA,
int nCP)
00116 {
00117
int i;
00118
BOOL bUDC;
00119
00120 lpA->cbSize = lpW->cbSize;
00121 lpA->fType = lpW->fType;
00122 lpA->fState = lpW->fState;
00123 lpA->wID = lpW->wID;
00124 lpA->hbmpChecked = lpW->hbmpChecked;
00125 lpA->hbmpUnchecked = lpW->hbmpUnchecked;
00126 lpA->dwItemData = lpW->dwItemData;
00127 lpA->hbmpItem = lpW->hbmpItem;
00128
00129
00130 i = WideCharToMultiByte(nCP,
00131 0,
00132 lpW->szString,
00133 wcslen(lpW->szString),
00134 lpA->szString,
00135 IMEMENUITEM_STRING_SIZE,
00136 (LPSTR)
NULL,
00137 &bUDC);
00138
00139 lpA->szString[i] =
'\0';
00140 }
00141
00142
00143
#if DBG
00144
void DumpBytes(LPBYTE pb, UINT size)
00145 {
00146
UINT i;
00147
TRACE((
"\npbmi dump:"));
00148
for (i = 0; i < size; ++i) {
00149
TRACE((
"%02X ", pb[i] & 0xff));
00150 }
00151
TRACE((
"\n"));
00152 UNREFERENCED_PARAMETER(pb);
00153 }
00154
#else
00155 #define DumpBytes(a,b)
00156
#endif
00157
00159
00160
00161 IMEMENU_BMP_HEADER*
SaveBitmapToMemory(HDC hDC, HBITMAP hBmp,
IMEMENU_BMP_HEADER* lpBH,
IMEMENU_HEADER* pHeader)
00162 {
00163 HBITMAP hTmpBmp, hBmpOld;
00164
IMEMENU_BMP_HEADER* lpNext =
NULL;
00165 PBITMAPINFO pbmi = &lpBH->
bmi;
00166 ULONG sizBMI;
00167
00168
00169
if (!hBmp) {
00170 RIPMSG0(RIP_WARNING,
"SaveBitmapToMemory: hBmp == NULL");
00171
return NULL;
00172 }
00173 UserAssert(lpBH !=
NULL);
00174
00175
00176
00177
00178
00179
00180 pbmi->bmiHeader.biSize =
sizeof pbmi->bmiHeader;
00181 pbmi->bmiHeader.biBitCount = 0;
00182
if ((GetDIBits(hDC, hBmp, 0, 0, (LPSTR)
NULL, pbmi, DIB_RGB_COLORS)) == 0) {
00183 RIPMSG0(RIP_WARNING,
"SaveBitmapToMemory: failed to GetDIBits(NULL)");
00184
return NULL;
00185 }
00186
00187
00188
00189
00190
00191
00192
switch (pbmi->bmiHeader.biBitCount) {
00193
case 24:
00194 sizBMI =
sizeof(BITMAPINFOHEADER);
00195
break;
00196
case 16:
00197
case 32:
00198 sizBMI =
sizeof(BITMAPINFOHEADER) +
sizeof(
DWORD) * 3;
00199
break;
00200
default:
00201 sizBMI =
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * (1 << pbmi->bmiHeader.biBitCount);
00202
break;
00203
00204 }
00205
00206
00207
00208
00209
if ((LPBYTE)pHeader + pHeader->
dwMemSize < (LPBYTE)lpBH +
sizeof lpBH + sizBMI + pbmi->bmiHeader.biSizeImage) {
00210 RIPMSG0(RIP_WARNING,
"SaveBitmapToMemory: size of bmp image(s) exceed limit ");
00211
return FALSE;
00212 }
00213
00214
00215
00216
00217 lpBH->
pBits = (LPBYTE)pbmi + sizBMI;
00218
00219
00220
00221
00222
00223
00224
if (hTmpBmp = CreateCompatibleBitmap(hDC, pbmi->bmiHeader.biWidth, pbmi->bmiHeader.biHeight)) {
00225 hBmpOld = SelectObject(hDC, hTmpBmp);
00226
if (GetDIBits(hDC, hBmp, 0, pbmi->bmiHeader.biHeight, (LPSTR)lpBH->
pBits, pbmi, DIB_RGB_COLORS) == 0){
00227 SelectObject(hDC, hBmpOld);
00228 RIPMSG0(RIP_WARNING,
"SaveBitmapToMemory: GetDIBits() failed.");
00229
return NULL;
00230 }
00231 lpNext = (
IMEMENU_BMP_HEADER*)((LPBYTE)pbmi + sizBMI + pbmi->bmiHeader.biSizeImage);
00232
00233
DumpBytes((LPBYTE)pbmi,
sizeof *pbmi);
00234 }
else {
00235 RIPMSG0(RIP_WARNING,
"SaveBitmapToMemory: CreateCompatibleBitmap() failed.");
00236
return NULL;
00237 }
00238
00239 SelectObject(hDC, hBmpOld);
00240 DeleteObject(hTmpBmp);
00241
return lpNext;
00242 }
00243
00245
00246
00247
00248
00249
00250
00251
00253
00254 IMEMENU_BMP_HEADER*
DecompileBitmap(
IMEMENU_HEADER* pHeader, HBITMAP hBitmap)
00255 {
00256
IMEMENU_BMP_HEADER* pBmp = pHeader->
lpBmp;
00257 HDC hDC;
00258
00259
00260
while (pBmp) {
00261
if (pBmp->
hBitmap == hBitmap) {
00262
00263
return pBmp;
00264 }
00265 pBmp = pBmp->
lpNext;
00266 }
00267
00268
00269 pBmp = pHeader->
lpBmpNext;
00270 UserAssert(pBmp !=
NULL);
00271
CHK_PTR(pBmp);
00272
if (pBmp ==
NULL) {
00273 RIPMSG1(RIP_WARNING,
"DecompileBitmap: pBmp == NULL in L%d", __LINE__);
00274
return NULL;
00275 }
00276
00277
00278 hDC =
GetDC(
GetDesktopWindow());
00279
if (hDC ==
NULL) {
00280 RIPMSG1(RIP_WARNING,
"DecompileBitmap: hDC == NULL in L%d", __LINE__);
00281
return NULL;
00282 }
00283
00284
00285
00286
00287 pBmp->
lpNext = pHeader->
lpBmp;
00288 pHeader->
lpBmpNext =
SaveBitmapToMemory(hDC, hBitmap, pBmp, pHeader);
00289
if (pHeader->
lpBmpNext ==
NULL) {
00290 RIPMSG1(RIP_WARNING,
"DecompileBitmap: pHeader->lpBmpNext == NULL in L%d", __LINE__);
00291
00292 pHeader->
lpBmpNext = pBmp;
00293 pHeader->
lpBmp = pBmp->
lpNext;
00294 pBmp =
NULL;
00295
goto cleanup;
00296 }
00297
00298
00299 pBmp->
hBitmap = hBitmap;
00300
00301
00302
00303
00304 pHeader->
lpBmp = pBmp;
00305
00306 cleanup:
00307
if (hDC)
00308
ReleaseDC(
GetDesktopWindow(), hDC);
00309
return pBmp;
00310 }
00311
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00324
00325 LRESULT
ImmPutImeMenuItemsIntoMappedFile(HIMC hImc)
00326 {
00327 HANDLE hMap =
NULL;
00328
LPVOID lpMap =
NULL;
00329
IMEMENU_HEADER* pHeader;
00330 LPIMEMENUITEMINFO lpBuf =
NULL;
00331
IMEMENU_ITEM* pMenu;
00332
IMEMENU_BMP_HEADER* pBmp;
00333 LRESULT lRet = 0;
00334 ULONG_PTR offset;
00335
DWORD i;
00336
00337
00338 hMap = OpenFileMapping(FILE_MAP_ALL_ACCESS,
FALSE,
IME_MENU_FILE_NAME);
00339
if (hMap ==
NULL) {
00340 RIPMSG0(RIP_WARNING,
"ImmPutImeMenuItemsIntoMappedFile: cannot open mapped file.");
00341
return 0
L;
00342 }
00343
00344
00345 lpMap = MapViewOfFile(hMap, FILE_MAP_ALL_ACCESS, 0, 0, 0);
00346
if (lpMap ==
NULL) {
00347 RIPMSG0(RIP_WARNING,
"ImmPutImeMenuItemsIntoMappedFile: cannot map view of file.");
00348
goto cleanup;
00349
00350 }
00351
00352 pHeader = (
IMEMENU_HEADER*)lpMap;
00353
00355
00357
if (pHeader->
dwVersion != 1) {
00358 RIPMSG1(RIP_WARNING,
"ImmPutImeMenuItemsIntoMappedFile: dwVersion(%d) does not match.",
00359 pHeader->
dwVersion);
00360
goto cleanup;
00361 }
00362
00364
00365 offset = (ULONG_PTR)pHeader;
00366
CONVTO_PTR(pHeader->
lpImeParentMenu);
00367
CHK_PTR(pHeader->
lpImeParentMenu);
00368 pMenu =
CONVTO_PTR(pHeader->
lpImeMenu);
00369
CHK_PTR(pHeader->
lpImeMenu);
00370
if (pHeader->
dwSize) {
00371 UserAssert(pHeader->
lpImeMenu);
00372 lpBuf =
ImmLocalAlloc(HEAP_ZERO_MEMORY, pHeader->
dwSize *
sizeof(IMEMENUITEMINFOW));
00373
if (lpBuf ==
NULL) {
00374 RIPMSG0(RIP_WARNING,
"ImmPutImeMenuItemsIntoMappedFile: not enough memory for receiver's buffer.");
00375
goto cleanup;
00376 }
00377 }
00378
00379
00380
00381
#if DBG
00382
if (pHeader->
lpImeParentMenu) {
00383 UserAssert(!pHeader->
lpImeParentMenu->
lpBmpChecked &&
00384 !pHeader->
lpImeParentMenu->
lpBmpUnchecked &&
00385 !pHeader->
lpImeParentMenu->
lpBmpItem);
00386 }
00387
#endif
00388
00390
00391 pHeader->
dwSize =
ImmGetImeMenuItemsW(hImc, pHeader->
dwFlags, pHeader->
dwType,
00392 (LPIMEMENUITEMINFOW)pHeader->
lpImeParentMenu, lpBuf,
00393 pHeader->
dwSize *
sizeof(IMEMENUITEMINFOW));
00394
00395
if (pHeader->
dwSize == 0) {
00396
goto cleanup;
00397 }
00399
00400
00401
00402
00403
00404
00405
if (lpBuf) {
00406 LPIMEMENUITEMINFO lpMenuW = lpBuf;
00407
00408 pHeader->
lpBmp =
NULL;
00409
00410 pHeader->
lpBmpNext = (
LPVOID)((LPBYTE)pHeader + (pHeader->
dwSize + 1) *
sizeof(IMEMENUITEMINFOW));
00411
00412
00413
for (i = 0; i < pHeader->
dwSize; ++i, ++pMenu, ++lpMenuW) {
00414 RtlCopyMemory(pMenu, lpMenuW,
sizeof *lpMenuW);
00415
00416
if (lpMenuW->hbmpChecked) {
00417
if ((pMenu->lpBmpChecked =
DecompileBitmap(pHeader, lpMenuW->hbmpChecked)) ==
NULL) {
00418 RIPMSG1(RIP_WARNING,
"ImmPutImeMenuItemsIntoMappedFile: DecompileBitmap Failed in L%d", __LINE__);
00419
goto cleanup;
00420 }
00421 }
00422
if (lpMenuW->hbmpUnchecked) {
00423
if ((pMenu->lpBmpUnchecked =
DecompileBitmap(pHeader, lpMenuW->hbmpUnchecked)) ==
NULL) {
00424 RIPMSG1(RIP_WARNING,
"ImmPutImeMenuItemsIntoMappedFile: DecompileBitmap Failed in L%d", __LINE__);
00425
goto cleanup;
00426 }
00427 }
00428
if (lpMenuW->hbmpItem) {
00429
if ((pMenu->lpBmpItem =
DecompileBitmap(pHeader, lpMenuW->hbmpItem)) ==
NULL) {
00430 RIPMSG1(RIP_WARNING,
"ImmPutImeMenuItemsIntoMappedFile: DecompileBitmap Failed in L%d", __LINE__);
00431
goto cleanup;
00432 }
00433 }
00434 }
00435
00437
00438
00439
00440
00441 pMenu = pHeader->
lpImeMenu;
00442
CONVTO_OFFSET(pHeader->
lpImeMenu);
00443
00444
D(pHeader->
lpImeParentMenu =
NULL);
00445
00446
00447
for (i = 0; i < pHeader->
dwSize; ++i, ++pMenu) {
00448
TRACE((
"ImmPutImeMenuItemsIntoMappedFile: convertiong '%S'\n", pMenu->szString));
00449
CONVTO_OFFSET(pMenu->lpBmpChecked);
00450
CONVTO_OFFSET(pMenu->lpBmpUnchecked);
00451
TRACE((
"ImmPutImeMenuItemsIntoMappedFile: before conversion (%#lx)\n", pMenu->lpBmpItem));
00452
CONVTO_OFFSET(pMenu->lpBmpItem);
00453
TRACE((
"ImmPutImeMenuItemsIntoMappedFile: after conversion (%#lx)\n", pMenu->lpBmpItem));
00454
00455
00456
CHK_OFFSET(pMenu->lpBmpChecked);
00457
CHK_OFFSET(pMenu->lpBmpChecked);
00458
CHK_OFFSET(pMenu->lpBmpItem);
00459 }
00460
00461
00462
00463
00464 pBmp = pHeader->
lpBmp;
00465
CONVTO_OFFSET(pHeader->
lpBmp);
00466
CHK_OFFSET(pHeader->
lpBmp);
00467
00468
D(pHeader->
lpBmpNext =
NULL);
00469
00470
00471
00472
00473
while (pBmp) {
00474
IMEMENU_BMP_HEADER* ptBmp = pBmp->
lpNext;
00475
CONVTO_OFFSET(pBmp->
pBits);
00476
CONVTO_OFFSET(pBmp->
lpNext);
00477
CHK_OFFSET(pBmp->
lpNext);
00478 pBmp = ptBmp;
00479 }
00480
00481
00482
00484 }
00485
00486
00487
00488
00489 lRet = 1;
00490
00491 cleanup:
00492
if (lpBuf)
00493
ImmLocalFree(lpBuf);
00494
if (lpMap)
00495 UnmapViewOfFile(lpMap);
00496
if (hMap)
00497 CloseHandle(hMap);
00498
return lRet;
00499 }
00500
00501
00503
00504
00505
00507
00508 HBITMAP
InternalImeMenuCreateBitmap(
IMEMENU_BMP_HEADER* lpBH)
00509 {
00510 HDC hDC;
00511
00512
if (lpBH ==
NULL) {
00513 RIPMSG1(RIP_WARNING,
"InternalImeMenuCreateBitmap: lpBH == NULL in L%d", __LINE__);
00514
return NULL;
00515 }
00516
if (lpBH->
pBits ==
NULL) {
00517 RIPMSG1(RIP_WARNING,
"InternalImeMenuCreateBitmap: lpBH->pBits == NULL in L%d", __LINE__);
00518
return NULL;
00519 }
00520
00521
if (lpBH->
hBitmap) {
00522
TRACE((
"InternalImeMenuCreateBitmap: lpBH->hBitmap != NULL. will return it.\n"));
00523
return lpBH->
hBitmap;
00524 }
00525
00526
if (hDC =
GetDC(
GetDesktopWindow())) {
00527 HDC hMyDC = CreateCompatibleDC(hDC);
00528
if (hMyDC) {
00529
00530 lpBH->
hBitmap = CreateDIBitmap(hDC, &lpBH->
bmi.bmiHeader, CBM_INIT,
00531 lpBH->
pBits, &lpBH->
bmi, DIB_RGB_COLORS);
00532
if (lpBH->
hBitmap ==
NULL) {
00533
DWORD dwErr = GetLastError();
00534 RIPMSG1(RIP_WARNING,
"InternalImeMenuCreateBitmap: CreateDIBitmap Failed. Last error=%#x\n", dwErr);
00535 }
00536 DeleteDC(hMyDC);
00537 }
00538
else {
00539 RIPMSG0(RIP_WARNING,
"InternalImeMenuCreateBitmap: CreateCompatibleDC failed.");
00540 }
00541
00542
ReleaseDC(
GetDesktopWindow(), hDC);
00543 }
00544
else {
00545 RIPMSG0(RIP_WARNING,
"InternalImeMenuCreateBitmap: couldn't get Desktop DC.");
00546 }
00547
return lpBH->
hBitmap;
00548 }
00549
00551
00552
00553
00554
00555
00556
00557
00559
00560 DWORD ImmGetImeMenuItemsInterProcess(HIMC hImc,
00561 DWORD dwFlags,
00562 DWORD dwType,
00563 LPIMEMENUITEMINFOW lpParentMenu,
00564 LPIMEMENUITEMINFOW lpMenu,
00565 DWORD dwSize)
00566 {
00567 HWND hwnd;
00568 HANDLE hMemFile =
NULL;
00569
DWORD dwRet = 0;
00570 LPBYTE lpMap =
NULL;
00571
IMEMENU_HEADER* pHeader;
00572
IMEMENU_ITEM* pMenuItem;
00573
IMEMENU_BMP_HEADER* pBmpHeader;
00574
DWORD i;
00575 ULONG_PTR offset;
00576
00577
00578
00579
00580
00581 hwnd = (HWND)
NtUserQueryInputContext(hImc,
InputContextDefaultImeWindow);
00582
if (hwnd ==
NULL || !
IsWindow(hwnd)) {
00583 RIPMSG1(RIP_WARNING,
"ImmGetImeMenuItemsInterProcess: hwnd(%lx) is not a valid window.", hwnd);
00584
return 0;
00585 }
00586
00587 RtlEnterCriticalSection(&
gcsImeDpi);
00588
00589
00590 hMemFile = CreateFileMapping((HANDLE)~0,
NULL, PAGE_READWRITE,
00591 0,
IME_MENU_MAXMEM,
IME_MENU_FILE_NAME);
00592
if (hMemFile ==
NULL) {
00593 RIPMSG0(RIP_WARNING,
"ImmGetImeMenuItemsInterProcess: cannot allocate memory mapped file.");
00594
goto cleanup;
00595 }
00596
00597 lpMap = (LPBYTE)MapViewOfFile(hMemFile, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
00598
if (lpMap ==
NULL) {
00599 RIPMSG0(RIP_WARNING,
"ImmGetImeMenuItemsInterProcess: cannot map view of memory mapped file.");
00600
goto cleanup;
00601 }
00602
00603
00604
00605
00606 pHeader = (
IMEMENU_HEADER*)lpMap;
00607 RtlZeroMemory(pHeader,
sizeof *pHeader);
00608 pHeader->dwVersion = 1;
00609 pHeader->dwMemSize =
IME_MENU_MAXMEM;
00610 pHeader->dwSize = dwSize /
sizeof(IMEMENUITEMINFOW);
00611 RIPMSG1(RIP_WARNING,
"ImmGetImeMenuItemsInterProcess: pHeader->dwSize=%ld", pHeader->dwSize);
00612 pHeader->dwFlags =
dwFlags;
00613 pHeader->dwType = dwType;
00614
00615
00616
00617
00618
00619
if ((dwSize && lpMenu) || lpParentMenu) {
00620
00621
if (lpParentMenu) {
00622
IMEMENU_ITEM* pPMenu =
00623 pHeader->lpImeParentMenu = (
IMEMENU_ITEM*)&pHeader[1];
00624
00625 RtlCopyMemory(pPMenu, lpParentMenu,
sizeof(IMEMENUITEMINFOW));
00626
00627
00628
00629 pPMenu->
lpBmpChecked = pPMenu->
lpBmpUnchecked = pPMenu->
lpBmpItem =
NULL;
00630 pHeader->lpImeMenu = pHeader->lpImeParentMenu + 1;
00631 }
00632
else {
00633 pHeader->lpImeParentMenu =
NULL;
00634 pHeader->lpImeMenu = (
LPVOID)&pHeader[1];
00635 }
00636
00637 offset = (ULONG_PTR)lpMap;
00638
CONVTO_OFFSET(pHeader->lpImeParentMenu);
00639
CONVTO_OFFSET(pHeader->lpImeMenu);
00640 }
00641
00642
00643
00644
00646
if (!
SendMessage(hwnd, WM_IME_SYSTEM, IMS_GETIMEMENU, (LPARAM)hImc)) {
00647
00648
goto cleanup;
00649 }
00651
00652
00653 dwSize = pHeader->dwSize;
00654
00655
if (lpMenu) {
00657
00659 pMenuItem =
CONVTO_PTR(pHeader->lpImeMenu);
00660
CHK_PTR(pMenuItem);
00661
00662
00663
00664
00665
00666
for (i = 0; i < dwSize; ++i, ++pMenuItem) {
00667
CONVTO_PTR(pMenuItem->
lpBmpChecked);
00668
CONVTO_PTR(pMenuItem->
lpBmpUnchecked);
00669
CONVTO_PTR(pMenuItem->
lpBmpItem);
00670
00671
00672
00673
CHK_PTR(pMenuItem->
lpBmpChecked);
00674
CHK_PTR(pMenuItem->
lpBmpUnchecked);
00675
CHK_PTR(pMenuItem->
lpBmpItem);
00676 }
00677
00678
00679
00680
00681 pBmpHeader =
CONVTO_PTR(pHeader->lpBmp);
00682
00683
00684
00685
00686
while (pBmpHeader) {
00687 pBmpHeader->
hBitmap =
NULL;
00688
00689
CONVTO_PTR(pBmpHeader->
pBits);
00690
CHK_PTR(pBmpHeader->
pBits);
00691
00692
00693 pBmpHeader =
CONVTO_PTR(pBmpHeader->
lpNext);
00694
CHK_PTR(pBmpHeader);
00695 }
00696
00697
00698
00699
00700 pMenuItem = pHeader->lpImeMenu;
00701
for (i = 0; i < dwSize; ++i, ++pMenuItem, ++lpMenu) {
00702 lpMenu->
cbSize = pMenuItem->cbSize;
00703 lpMenu->fType = pMenuItem->fType;
00704 lpMenu->fState = pMenuItem->fState;
00705 lpMenu->wID = pMenuItem->wID;
00706 lpMenu->dwItemData = pMenuItem->dwItemData;
00707 wcscpy(lpMenu->szString, pMenuItem->szString);
00708
00709
00710
00711
if (pMenuItem->lpBmpChecked) {
00712 lpMenu->hbmpChecked =
InternalImeMenuCreateBitmap(pMenuItem->lpBmpChecked);
00713 }
00714
else {
00715 lpMenu->hbmpChecked =
NULL;
00716 }
00717
if (pMenuItem->lpBmpUnchecked) {
00718 lpMenu->hbmpUnchecked =
InternalImeMenuCreateBitmap(pMenuItem->lpBmpUnchecked);
00719 }
00720
else {
00721 lpMenu->hbmpUnchecked =
NULL;
00722 }
00723
if (pMenuItem->lpBmpItem) {
00724 lpMenu->hbmpItem =
InternalImeMenuCreateBitmap(pMenuItem->lpBmpItem);
00725 }
00726
else {
00727 lpMenu->hbmpItem =
NULL;
00728 }
00729 }
00730 }
00731
00732
00733 cleanup:
00734
if (lpMap) {
00735 UnmapViewOfFile(lpMap);
00736 }
00737 RtlLeaveCriticalSection(&
gcsImeDpi);
00738
00739
if (hMemFile) {
00740 CloseHandle(hMemFile);
00741 }
00742
00743
return dwSize;
00744 }
00745
00747
00748
00749
00750
00751
00752
00753
00754
00755
00757
00758
00759 DWORD ImmGetImeMenuItemsWorker(HIMC hIMC,
00760 DWORD dwFlags,
00761 DWORD dwType,
00762 LPVOID lpImeParentMenu,
00763 LPVOID lpImeMenu,
00764 DWORD dwSize,
00765 BOOL bAnsiOrigin)
00766 {
00767
BOOL bAnsiIme =
IsAnsiIMC(hIMC);
00768
DWORD dwRet = 0;
00769 LPINPUTCONTEXT lpInputContext;
00770
DWORD dwThreadId;
00771
PIMEDPI pImeDpi =
NULL;
00772
LPVOID lpImePTemp = lpImeParentMenu;
00773
LPVOID lpImeTemp = lpImeMenu;
00774 IMEMENUITEMINFOA imiiParentA;
00775 IMEMENUITEMINFOW imiiParentW;
00776
00777
00778
00779
00780 {
00781
DWORD dwProcessId =
GetInputContextProcess(hIMC);
00782
if (dwProcessId == 0) {
00783 RIPMSG0(RIP_WARNING,
"ImmGetImeMenuItemsWorker: dwProcessId == 0");
00784
return 0;
00785 }
00786
if (dwProcessId !=
GetCurrentProcessId()) {
00787
00788
00789
00790
TRACE((
"ImmGetImeMenuItemsWorker: Inter process.\n"));
00791
if (bAnsiOrigin) {
00792
00793
00794
00795 RIPMSG0(RIP_WARNING,
"ImmGetImeMenuItemsWorker: interprocess getmenu is not allowed for ANSI caller.");
00796
return 0;
00797 }
00798
return ImmGetImeMenuItemsInterProcess(hIMC,
dwFlags, dwType, lpImeParentMenu,
00799 lpImeMenu, dwSize);
00800 }
00801 }
00802
00803
00804
00805
00806
00807
if (hIMC ==
NULL || (lpInputContext =
ImmLockIMC(hIMC)) ==
NULL) {
00808 RIPMSG2(RIP_WARNING,
"ImmGetImeMenuItemsWorker: illegal hIMC(%#lx) in L%d", hIMC, __LINE__);
00809
return 0;
00810 }
00811
00812 dwThreadId =
GetInputContextThread(hIMC);
00813
if (dwThreadId == 0) {
00814 RIPMSG1(RIP_WARNING,
"ImmGetImeMenuItemsWorker: dwThreadId = 0 in L%d", __LINE__);
00815
goto cleanup;
00816 }
00817
if ((pImeDpi =
ImmLockImeDpi(
GetKeyboardLayout(dwThreadId))) ==
NULL) {
00818 RIPMSG1(RIP_WARNING,
"ImmGetImeMenuItemWorker: pImeDpi == NULL in L%d.", __LINE__);
00819
goto cleanup;
00820 }
00821
00822
#if 0 // NT: we don't keep version info in ImeDpi
00823
if (pImeDpi->dwWinVersion <= IMEVER_0310) {
00824 RIPMSG1(RIP_WARNING,
"GetImeMenuItems: OldIME does not support this. %lx", hIMC);
00825
goto cleanup;
00826 }
00827
#endif
00828
00829
00830
00831
00832
if (pImeDpi->
pfn.
ImeGetImeMenuItems) {
00833
LPVOID lpNewBuf =
NULL;
00834
00835
TRACE((
"ImmGetImeMenuItemsWorker: IME has menu callback.\n"));
00836
00837
if (bAnsiIme != bAnsiOrigin) {
00838
00839
00840
00841
if (bAnsiOrigin) {
00842
00843
00844
if (lpImeParentMenu) {
00845
00846 lpImePTemp = (
LPVOID)&imiiParentW;
00847
ConvertImeMenuItemInfoAtoW((LPIMEMENUITEMINFOA)lpImeParentMenu,
00848 (LPIMEMENUITEMINFOW)lpImePTemp,
00849 CP_ACP,
TRUE);
00850 }
00851
if (lpImeMenu) {
00852
00853
DWORD dwNumBuffer = dwSize /
sizeof(IMEMENUITEMINFOA);
00854 dwSize = dwNumBuffer *
sizeof(IMEMENUITEMINFOW);
00855
if (dwSize == 0) {
00856 RIPMSG0(RIP_WARNING,
"ImmGetImeMenuItemsWorker: (AtoW) dwSize is 0.");
00857
goto cleanup;
00858 }
00859 lpImeTemp = lpNewBuf =
ImmLocalAlloc(0, dwSize);
00860
TRACE((
"ImmGetImeMenuItemsWorker: for UNICODE IME memory allocated %d bytes. lpNewBuf=%#x\n", dwSize, lpNewBuf));
00861
if (lpNewBuf ==
NULL) {
00862 RIPMSG1(RIP_WARNING,
"ImmGetImeMenuItemsWorker: cannot alloc lpNewBuf in L%d", __LINE__);
00863
goto cleanup;
00864 }
00865 }
00866 }
00867
else {
00868
00869
00870
if (lpImeParentMenu) {
00871
00872 lpImePTemp = (
LPVOID)&imiiParentA;
00873
ConvertImeMenuItemInfoWtoA((LPIMEMENUITEMINFOW)lpImeParentMenu,
00874 (LPIMEMENUITEMINFOA)lpImePTemp,
00875 pImeDpi->
dwCodePage);
00876 }
00877
if (lpImeMenu) {
00878
00879
DWORD dwNumBuffer = dwSize /
sizeof(IMEMENUITEMINFOW);
00880 dwSize = dwNumBuffer /
sizeof(IMEMENUITEMINFOA);
00881
if (dwSize == 0) {
00882 RIPMSG0(RIP_WARNING,
"ImmGetImeMenuItemsWorker: (WtoA) dwSize is 0.");
00883
goto cleanup;
00884 }
00885 lpImeTemp = lpNewBuf =
ImmLocalAlloc(0, dwSize);
00886 RIPMSG2(RIP_WARNING,
"ImmGetImeMenuItemsWorker: for ANSI IME memory allocated %d bytes. lpNewBuf=%#x", dwSize, lpNewBuf);
00887
if (lpNewBuf ==
NULL) {
00888 RIPMSG1(RIP_WARNING,
"ImmGetImeMenuItemsWorker: cannot alloc lpNewBuf in L%d", __LINE__);
00889
goto cleanup;
00890 }
00891 }
00892 }
00893 }
00894
00896 dwRet = pImeDpi->
pfn.
ImeGetImeMenuItems(hIMC,
dwFlags, dwType, lpImePTemp, lpImeTemp, dwSize);
00898
00899
00900
00901
00902
00903
00904
00905
if (dwRet && bAnsiIme != bAnsiOrigin && lpImeTemp) {
00906
if (bAnsiOrigin) {
00907
00908
00909 LPIMEMENUITEMINFOW lpW = (LPIMEMENUITEMINFOW)lpImeTemp;
00910 LPIMEMENUITEMINFOA lpA = (LPIMEMENUITEMINFOA)lpImeMenu;
00911
DWORD i;
00912
00913
for (i = 0; i < dwRet; ++i) {
00914
ConvertImeMenuItemInfoWtoA((LPIMEMENUITEMINFOW)lpW++,
00915 (LPIMEMENUITEMINFOA)lpA++,
00916 CP_ACP);
00917 }
00918 }
00919
else {
00920
00921
00922 LPIMEMENUITEMINFOA lpA = (LPIMEMENUITEMINFOA)lpImeTemp;
00923 LPIMEMENUITEMINFOW lpW = (LPIMEMENUITEMINFOW)lpImeMenu;
00924
DWORD i;
00925
00926
for (i = 0; i < dwSize; i++) {
00927
ConvertImeMenuItemInfoAtoW((LPIMEMENUITEMINFOA)lpA++,
00928 (LPIMEMENUITEMINFOW)lpW++,
00929 pImeDpi->
dwCodePage,
00930
TRUE);
00931 }
00932 }
00933 }
00934
00935
00936
if (lpNewBuf)
00937
ImmLocalFree(lpNewBuf);
00938 }
00939
00940 cleanup:
00941
if (pImeDpi) {
00942
ImmUnlockImeDpi(pImeDpi);
00943 }
00944
00945
if (hIMC !=
NULL) {
00946
ImmUnlockIMC(hIMC);
00947 }
00948
00949
return dwRet;
00950 }
00951
00952
00953 DWORD WINAPI
ImmGetImeMenuItemsA(
00954 HIMC hIMC,
00955 DWORD dwFlags,
00956 DWORD dwType,
00957 LPIMEMENUITEMINFOA lpImeParentMenu,
00958 LPIMEMENUITEMINFOA lpImeMenu,
00959 DWORD dwSize)
00960 {
00961
return ImmGetImeMenuItemsWorker(hIMC,
dwFlags, dwType,
00962 (
LPVOID)lpImeParentMenu,
00963 (
LPVOID)lpImeMenu, dwSize,
TRUE );
00964 }
00965
00966
00967 DWORD WINAPI
ImmGetImeMenuItemsW(
00968 HIMC hIMC,
00969 DWORD dwFlags,
00970 DWORD dwType,
00971 LPIMEMENUITEMINFOW lpImeParentMenu,
00972 LPIMEMENUITEMINFOW lpImeMenu,
00973 DWORD dwSize)
00974 {
00975
return ImmGetImeMenuItemsWorker(hIMC,
dwFlags, dwType,
00976 (
LPVOID)lpImeParentMenu,
00977 (
LPVOID)lpImeMenu, dwSize,
FALSE );
00978 }