Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

809 lines
25 KiB

  1. #include <windows.h>
  2. #include <windowsx.h>
  3. #ifdef UNDER_CE // stub for CE
  4. #include "stub_ce.h"
  5. #endif // UNDER_CE
  6. #include "imepadsv.h"
  7. #include "cpadcb.h"
  8. #include "cpaddbg.h"
  9. #include "ipoint1.h"
  10. #include "iimecb.h"
  11. #include "imepad.h"
  12. #define Unref(a) UNREFERENCED_PARAMETER(a)
  13. //990812:ToshiaK For Win64. Use Global Alloc/Free Ptr.
  14. #include <windowsx.h>
  15. #define MemAlloc(a) GlobalAllocPtr(GMEM_FIXED, a)
  16. #define MemFree(a) GlobalFreePtr(a)
  17. BOOL IsBadVtbl(IUnkDummy *lpIUnk)
  18. {
  19. #ifdef _DEBUG
  20. BOOL fBad = ::IsBadReadPtr(lpIUnk, sizeof(VOID*)) ||
  21. ::IsBadReadPtr(lpIUnk->lpVtbl, sizeof(VOID*)) ||
  22. ::IsBadCodePtr((FARPROC)lpIUnk->lpVtbl->QueryInterface) ||
  23. ::IsBadCodePtr((FARPROC)lpIUnk->lpVtbl->AddRef) ||
  24. ::IsBadCodePtr((FARPROC)lpIUnk->lpVtbl->Release);
  25. if(fBad) {
  26. DBG(("--> IsBadVtbl HIT HIT HIT\n"));
  27. }
  28. return fBad;
  29. #else
  30. return ::IsBadReadPtr(lpIUnk, sizeof(VOID*)) ||
  31. ::IsBadReadPtr(lpIUnk->lpVtbl, sizeof(VOID*)) ||
  32. ::IsBadCodePtr((FARPROC)lpIUnk->lpVtbl->QueryInterface) ||
  33. ::IsBadCodePtr((FARPROC)lpIUnk->lpVtbl->AddRef) ||
  34. ::IsBadCodePtr((FARPROC)lpIUnk->lpVtbl->Release);
  35. #endif
  36. }
  37. HRESULT __stdcall CImePadCallback::QueryInterface(REFIID riid, void**ppv)
  38. {
  39. if(riid == IID_IUnknown) {
  40. *ppv = static_cast<IImePadCallback *>(this);
  41. }
  42. else if (riid == IID_IImePadCallback) {
  43. *ppv = static_cast<IImePadCallback *>(this);
  44. }
  45. else {
  46. return (*ppv = 0), E_NOINTERFACE;
  47. }
  48. reinterpret_cast<IUnknown*>(*ppv)->AddRef();
  49. return S_OK;
  50. }
  51. ULONG __stdcall
  52. CImePadCallback::AddRef(void)
  53. {
  54. //DBG(("CImePadCallback::AddRef Always return 2\n"));
  55. DBG(("CImePadCallback::AddRef m_cRef[%d] -> [%d]\n", m_cRef, m_cRef+1));
  56. return ::InterlockedIncrement(&m_cRef);
  57. }
  58. ULONG __stdcall
  59. CImePadCallback::Release(void)
  60. {
  61. //Never call delete in it.
  62. DBG(("CImePadCallback::Release (Never Delete) m_cRef[%d] -> [%d]\n", m_cRef, m_cRef-1));
  63. ::InterlockedDecrement(&m_cRef);
  64. return m_cRef;
  65. }
  66. //////////////////////////////////////////////////////////////////
  67. // Function : CImePadCallback::OnStart
  68. // Type : HRESULT __stdcall
  69. // Purpose :
  70. // Args :
  71. // : DWORD dwParam
  72. // Return :
  73. // DATE : Tue Aug 31 16:49:37 1999
  74. // Histroy :
  75. //////////////////////////////////////////////////////////////////
  76. HRESULT __stdcall
  77. CImePadCallback::OnStart(DWORD dwParam)
  78. {
  79. DBG(("OnClose come dwParam[%d]\n", dwParam));
  80. IUnknown *lpUnk;
  81. IImeCallback *lp = NULL;
  82. if(!m_lpCImePadSvr) {
  83. DBG(("-->m_lpCImePadSvr is NULL ?\n"));
  84. return -1;
  85. }
  86. lpUnk = m_lpCImePadSvr->GetIUnkIImeCallback();
  87. if(!lpUnk) {
  88. DBG(("-->IImeCallback does not set\n"));
  89. return -1;
  90. }
  91. #if 0
  92. if(IsBadVtbl((IUnkDummy*)lpUnk)) {
  93. DBG(("lpIUnk is BAD Pointer \n"));
  94. return E_FAIL;
  95. }
  96. #endif
  97. __try {
  98. lpUnk->QueryInterface(IID_IImeCallback, (LPVOID *)&lp);
  99. if(!lp) {
  100. DBG(("-->QuertyInterface Failed\n"));
  101. }
  102. lp->Notify(IMECBNOTIFY_IMEPADOPENED, 0, 0);
  103. lp->Release();
  104. }
  105. __except(EXCEPTION_EXECUTE_HANDLER) {
  106. return E_FAIL;
  107. }
  108. return S_OK;
  109. Unref(dwParam);
  110. }
  111. HRESULT __stdcall CImePadCallback::OnClose(DWORD dwParam)
  112. {
  113. DBG(("OnClose come dwParam[%d]\n", dwParam));
  114. IUnknown *lpUnk;
  115. IImeCallback *lp = NULL;
  116. if(!m_lpCImePadSvr) {
  117. DBG(("-->m_lpCImePadSvr is NULL ?\n"));
  118. return -1;
  119. }
  120. m_lpCImePadSvr->OnIMEPadClose();
  121. lpUnk = m_lpCImePadSvr->GetIUnkIImeCallback();
  122. if(!lpUnk) {
  123. DBG(("-->IImeCallback does not set\n"));
  124. return -1;
  125. }
  126. #if 0
  127. if(IsBadVtbl((IUnkDummy*)lpUnk)) {
  128. DBG(("lpIUnk is BAD Pointer \n"));
  129. return E_FAIL;
  130. }
  131. #endif
  132. __try {
  133. lpUnk->QueryInterface(IID_IImeCallback, (LPVOID *)&lp);
  134. if(!lp) {
  135. DBG(("-->QuertyInterface Failed\n"));
  136. }
  137. lp->Notify(IMECBNOTIFY_IMEPADCLOSED, 0, 0);
  138. lp->Release();
  139. }
  140. __except(EXCEPTION_EXECUTE_HANDLER) {
  141. return E_FAIL;
  142. }
  143. return S_OK;
  144. Unref(dwParam);
  145. }
  146. HRESULT __stdcall
  147. CImePadCallback::OnPing(DWORD dwParam)
  148. {
  149. return S_OK;
  150. Unref(dwParam);
  151. }
  152. typedef struct tagPADCTRL2IPCTRL {
  153. DWORD dwImePadCtrl;
  154. DWORD dwIPointCtrl;
  155. }PADCTL2IPCTRL;
  156. static PADCTL2IPCTRL padCtrl2Ip[]= {
  157. { IMEPADCTRL_CONVERTALL, IPCTRL_CONVERTALL, },
  158. { IMEPADCTRL_DETERMINALL, IPCTRL_DETERMINALL, },
  159. { IMEPADCTRL_DETERMINCHAR, IPCTRL_DETERMINCHAR, },
  160. { IMEPADCTRL_CLEARALL, IPCTRL_CLEARALL, },
  161. { IMEPADCTRL_CARETSET, IPCTRL_CARETSET, },
  162. { IMEPADCTRL_CARETLEFT, IPCTRL_CARETLEFT, },
  163. { IMEPADCTRL_CARETRIGHT, IPCTRL_CARETRIGHT, },
  164. { IMEPADCTRL_CARETTOP, IPCTRL_CARETTOP, },
  165. { IMEPADCTRL_CARETBOTTOM, IPCTRL_CARETBOTTOM, },
  166. { IMEPADCTRL_CARETBACKSPACE, IPCTRL_CARETBACKSPACE, },
  167. { IMEPADCTRL_CARETDELETE, IPCTRL_CARETDELETE, },
  168. { IMEPADCTRL_PHRASEDELETE, IPCTRL_PHRASEDELETE, },
  169. { IMEPADCTRL_INSERTSPACE, IPCTRL_INSERTSPACE, },
  170. { IMEPADCTRL_INSERTFULLSPACE, IPCTRL_INSERTFULLSPACE, },
  171. { IMEPADCTRL_INSERTHALFSPACE, IPCTRL_INSERTHALFSPACE, },
  172. { IMEPADCTRL_ONIME, IPCTRL_ONIME, },
  173. { IMEPADCTRL_OFFIME, IPCTRL_OFFIME, },
  174. { IMEPADCTRL_ONPRECONVERSION, IPCTRL_PRECONVERSION, },
  175. { IMEPADCTRL_PHONETICCANDIDATE, IPCTRL_PHONETICCANDIDATE, },
  176. };
  177. HRESULT __stdcall
  178. CImePadCallback::PassData(long nSize, byte *pByte, DWORD *pdwCharID)
  179. {
  180. DBG(("CImePadCallback::PassData START\n"));
  181. LPIMEDATAHEADER lpImeDataHeader = (LPIMEDATAHEADER)pByte;
  182. HRESULT hr = S_OK;
  183. IUnknown *lpIUnk = NULL;
  184. IImeIPoint1 *lpIImeIPoint = NULL;
  185. DWORD dwCharID = 0;
  186. // Security Fix: Attack surface reduction
  187. if(!pByte) {
  188. return E_FAIL;
  189. }
  190. if(!m_lpCImePadSvr) {
  191. DBG(("m_lpCImePadSvr is NULL Error\n"));
  192. return E_FAIL;
  193. }
  194. lpIUnk = m_lpCImePadSvr->GetIUnkIImeIPoint();
  195. if(!lpIUnk) {
  196. DBG(("lpIUnk is NULL\n"));
  197. return E_FAIL;
  198. }
  199. #if 0
  200. if(IsBadVtbl((IUnkDummy*)lpIUnk)) {
  201. return E_FAIL;
  202. }
  203. #endif
  204. __try {
  205. hr = lpIUnk->QueryInterface(IID_IImeIPoint1, (VOID **)&lpIImeIPoint);
  206. if(hr != S_OK) {
  207. DBG(("QuertyInterface Failed\n"));
  208. return E_FAIL;
  209. }
  210. if(!lpIImeIPoint) {
  211. DBG(("QuertyInterface failed\n"));
  212. return E_FAIL;
  213. }
  214. DBG(("m_hwndIF [0x%08x]\n", m_hwndIF));
  215. switch(lpImeDataHeader->dwDataID) {
  216. case IMEDATAID_CONTROL:
  217. {
  218. LPIMEDATACONTROL lpImeDataCtrl = (LPIMEDATACONTROL)lpImeDataHeader;
  219. for(int i = 0; i < sizeof(padCtrl2Ip)/sizeof(padCtrl2Ip[0]); i++) {
  220. if(lpImeDataCtrl->dwControl == padCtrl2Ip[i].dwImePadCtrl) {
  221. hr = lpIImeIPoint->ControlIME((WORD)padCtrl2Ip[i].dwIPointCtrl,
  222. IPCTRLPARAM_DEFAULT);
  223. //hr = lpIImeIPoint->UpdateContext(TRUE);
  224. break;
  225. }
  226. }
  227. }
  228. break;
  229. case IMEDATAID_STRING:
  230. {
  231. DBG(("--> IMEDATAID_STRING\n"));
  232. LPIMEDATASTRING lpImeDataStr = (LPIMEDATASTRING)lpImeDataHeader;
  233. switch(lpImeDataHeader->dwCmdID) {
  234. case IMECMDID_INSERTSTRING:
  235. {
  236. DBG(("--> IMECMDID_INSERTSTRING START\n"));
  237. LPWSTR lpwstr = (LPWSTR)((LPIMEDATASTRING)lpImeDataHeader)->wChar;
  238. INT len = lpwstr ? lstrlenW(lpwstr) : 0;
  239. DBGW((L"lpwstr [%s] len[%d]\n", lpwstr, len));
  240. BOOL fPreConv = lpImeDataStr->fPreConv;
  241. //990818:ToshiaK for KOTAE #1775.
  242. dwCharID = lpImeDataStr->dwCharID;
  243. hr = lpIImeIPoint->ControlIME(IPCTRL_ONIME, IPCTRLPARAM_DEFAULT);
  244. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION,
  245. fPreConv ? IPCTRLPARAM_ON : IPCTRLPARAM_OFF);
  246. hr = lpIImeIPoint->InsertStringEx(lpwstr,
  247. len,
  248. &dwCharID);
  249. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION, IPCTRLPARAM_ON);
  250. if(pdwCharID) {
  251. *pdwCharID = dwCharID;
  252. }
  253. fPreConv = 0;
  254. DBG(("--> IMECMDID_INSERTSTRING END\n"));
  255. }
  256. break;
  257. case IMECMDID_CHANGESTRING:
  258. {
  259. DBG(("--> IMECMDID_CHANGESTRING\n"));
  260. LPWSTR lpwstr = (LPWSTR)((LPIMEDATASTRING)lpImeDataHeader)->wChar;
  261. INT len = lpwstr ? lstrlenW(lpwstr) : 0;
  262. dwCharID = ((LPIMEDATASTRING)lpImeDataHeader)->dwCharID;
  263. BOOL fPreConv = lpImeDataStr->fPreConv;
  264. hr = lpIImeIPoint->ControlIME(IPCTRL_ONIME, IPCTRLPARAM_DEFAULT);
  265. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION,
  266. fPreConv ? IPCTRLPARAM_ON : IPCTRLPARAM_OFF);
  267. hr = lpIImeIPoint->ReplaceCompString(lpImeDataStr->dwStartPos,
  268. lpImeDataStr->dwDeleteLength,
  269. lpwstr,
  270. len,
  271. &dwCharID);
  272. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION, IPCTRLPARAM_ON);
  273. //hr = lpIImeIPoint->UpdateContext(TRUE);
  274. if(pdwCharID) {
  275. *pdwCharID = dwCharID;
  276. }
  277. hr = (HRESULT)dwCharID;
  278. }
  279. break;
  280. case IMECMDID_DELETESTRING:
  281. {
  282. DBG(("--> IMECMDID_DELETESTRING\n"));
  283. hr = lpIImeIPoint->ControlIME(IPCTRL_ONIME, IPCTRLPARAM_DEFAULT);
  284. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION, IPCTRLPARAM_ON);
  285. hr = lpIImeIPoint->DeleteCompString((DWORD)lpImeDataStr->dwStartPos,
  286. (DWORD)lpImeDataStr->dwDeleteLength);
  287. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION, IPCTRLPARAM_ON);
  288. //hr = lpIImeIPoint->UpdateContext(TRUE);
  289. }
  290. break;
  291. case IMECMDID_INSERTSTRINGINFO:
  292. case IMECMDID_CHANGESTRINGINFO:
  293. {
  294. DBG(("--> IMECMDID_INSERT(Change)STRINGINFO\n"));
  295. LPWSTR lpwstr = (LPWSTR)((LPIMEDATASTRING)lpImeDataHeader)->wChar;
  296. INT len = lpwstr ? lstrlenW(lpwstr) : 0;
  297. dwCharID = ((LPIMEDATASTRING)lpImeDataHeader)->dwCharID;
  298. BOOL fPreConv = lpImeDataStr->fPreConv;
  299. hr = lpIImeIPoint->ControlIME(IPCTRL_ONIME, IPCTRLPARAM_DEFAULT);
  300. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION,
  301. fPreConv ? IPCTRLPARAM_ON : IPCTRLPARAM_OFF);
  302. hr = lpIImeIPoint->ReplaceCompString(lpImeDataStr->dwStartPos,
  303. lpImeDataStr->dwDeleteLength,
  304. lpwstr,
  305. len,
  306. &dwCharID);
  307. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION, IPCTRLPARAM_ON);
  308. if(pdwCharID) {
  309. *pdwCharID = dwCharID;
  310. }
  311. hr = (HRESULT)dwCharID;
  312. }
  313. break;
  314. default:
  315. break;
  316. }
  317. }
  318. break;
  319. case IMEDATAID_STRINGCAND:
  320. {
  321. DBG(("Data ID is IMEDATAID_STRINGCAND\n"));
  322. HRESULT hr;
  323. LPIMEDATASTRINGCAND lpStrCand = (LPIMEDATASTRINGCAND)lpImeDataHeader;
  324. PIPCANDIDATE lpIpCand;
  325. INT textCount, byteCount, i, nSize;
  326. PBYTE p;
  327. textCount = byteCount = 0;
  328. DBG(("--> dwStringCount %d\n", lpStrCand->dwStringCount));
  329. for(i = 0; i < (INT)lpStrCand->dwStringCount; i++) {
  330. DBG(("--> %d offset [%d]\n", i, lpStrCand->dwOffsetString[i]));
  331. textCount++;
  332. LPWSTR lpwstr = (LPWSTR)(((LPBYTE)lpStrCand) + lpStrCand->dwOffsetString[i]);
  333. DBGW((L"--> %d %s\n", i, lpwstr));
  334. byteCount += (lstrlenW(lpwstr)+1) * sizeof(WCHAR);
  335. }
  336. if(textCount == 0) {
  337. return S_OK;
  338. }
  339. dwCharID = lpStrCand->dwCharID;
  340. DWORD dwExInfo = lpStrCand->dwExtraInfoSize;
  341. nSize = sizeof(IPCANDIDATE) + (textCount-1) * sizeof(DWORD) + byteCount + dwExInfo;
  342. lpIpCand = (IPCANDIDATE *)MemAlloc(nSize);
  343. if (lpIpCand == NULL)
  344. return E_OUTOFMEMORY;
  345. lpIpCand->dwSize = nSize;
  346. lpIpCand->dwFlags = lpStrCand->dwInfoMask;
  347. lpIpCand->iSelIndex = lpStrCand->dwSelIndex;
  348. lpIpCand->nCandidate = textCount;
  349. lpIpCand->dwPrivateDataOffset = 0;
  350. lpIpCand->dwPrivateDataSize = 0;
  351. DBG(("lpIpCand[0x%08x] \n", lpIpCand));
  352. DBG(("sizeof(IPCANDIDATE) [%d]\n", sizeof(IPCANDIDATE)));
  353. DBG(("size add [%d]\n", sizeof(DWORD) * (textCount -1)));
  354. DWORD dwOffset = sizeof(IPCANDIDATE)+sizeof(DWORD)*(textCount-1);
  355. p = ((PBYTE)lpIpCand) + dwOffset;
  356. for(i = 0; i < (INT)lpStrCand->dwStringCount; i++) {
  357. LPWSTR lpwstr = (LPWSTR)(((LPBYTE)lpStrCand) + lpStrCand->dwOffsetString[i]);
  358. DWORD dwStrSize = (lstrlenW(lpwstr) + 1) * sizeof(WCHAR);
  359. CopyMemory((LPWSTR)p,
  360. (WCHAR *)lpwstr,
  361. dwStrSize);
  362. lpIpCand->dwOffset[i] = dwOffset;
  363. dwOffset += dwStrSize;
  364. p += dwStrSize;
  365. }
  366. if(dwExInfo > 0) {
  367. lpIpCand->dwPrivateDataSize = dwExInfo;
  368. #ifdef _WIN64
  369. lpIpCand->dwPrivateDataOffset = (DWORD)((DWORD_PTR)p - (DWORD_PTR)lpIpCand);
  370. #else
  371. lpIpCand->dwPrivateDataOffset = (DWORD)p - (DWORD)lpIpCand;
  372. #endif
  373. CopyMemory(p,
  374. (LPBYTE)((LPBYTE)lpStrCand + lpStrCand->dwExtraInfoOffset),
  375. lpStrCand->dwExtraInfoSize);
  376. }
  377. BOOL fPreConv = lpStrCand->fPreConv;
  378. hr = lpIImeIPoint->ControlIME(IPCTRL_ONIME, IPCTRLPARAM_DEFAULT);
  379. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION,
  380. fPreConv ? IPCTRLPARAM_ON : IPCTRLPARAM_OFF);
  381. //----------------------------------------------------------------
  382. //990713: need to set Start position for IPoint.
  383. //----------------------------------------------------------------
  384. DWORD dwInsertPos; // = IPINS_CURRENT; //Default.
  385. DWORD dwLen;
  386. //990823:Toshiak for KOTAE #1779.
  387. //000825:Satori #2123
  388. if(lpStrCand->dwStartPos == IMECMDVALUE_DEFAULT_INSERT_POS) {
  389. dwInsertPos = IPINS_CURRENT; //Set IPoint's value
  390. }
  391. else {
  392. dwInsertPos = lpStrCand->dwStartPos;
  393. }
  394. dwLen = lpStrCand->dwDeleteLength;
  395. switch(lpStrCand->header.dwCmdID) {
  396. case IMECMDID_INSERTSTRINGCANDINFO:
  397. hr = lpIImeIPoint->InsertImeItem(lpIpCand,
  398. dwInsertPos,
  399. &dwCharID);
  400. break;
  401. case IMECMDID_CHANGESTRINGCANDINFO:
  402. hr = lpIImeIPoint->ReplaceImeItem(dwInsertPos,
  403. dwLen,
  404. lpIpCand,
  405. &dwCharID);
  406. break;
  407. default:
  408. break;
  409. }
  410. hr = lpIImeIPoint->ControlIME(IPCTRL_PRECONVERSION, IPCTRLPARAM_ON);
  411. //hr = lpIImeIPoint->UpdateContext(TRUE);
  412. MemFree(lpIpCand);
  413. if(pdwCharID) {
  414. *pdwCharID = dwCharID;
  415. }
  416. }
  417. break;
  418. default:
  419. break;
  420. }
  421. //990630:ToshiaK for #1327.
  422. //In WinWord, if call UpdateContext(TRUE) here,
  423. //Word does NOT repaint composition string.
  424. //once return the SendMessageTimeout() procedure,
  425. //and update context asynchronously.
  426. //in WM_USER_UPDATECONTEXT's lParam, set IImeIPoint interface pointer.
  427. //and message procedure, check it with current iimeipoint.
  428. ::PostMessage(m_hwndIF, WM_USER_UPDATECONTEXT, (WPARAM)0, (LPARAM)lpIImeIPoint);
  429. lpIImeIPoint->Release();
  430. }
  431. __except(EXCEPTION_EXECUTE_HANDLER) {
  432. hr = E_FAIL;
  433. }
  434. return hr;
  435. Unref(nSize);
  436. }
  437. HRESULT STDMETHODCALLTYPE
  438. CImePadCallback::ReceiveData(
  439. /* [in] */ DWORD dwCmdID,
  440. /* [in] */ DWORD dwDataID,
  441. /* [out] */ long __RPC_FAR *pSize,
  442. /* [size_is][size_is][out] */ byte __RPC_FAR *__RPC_FAR *ppByte)
  443. {
  444. DBG(("CImePadCallback::ReceiveData START\n"));
  445. DBG(("-->dwCmdID [0x%08x]\n", dwCmdID));
  446. DBG(("-->dwDataID [0x%08x]\n", dwDataID));
  447. DBG(("-->pSize [0x%08x]\n", pSize));
  448. DBG(("-->ppByte [0x%08x]\n", ppByte));
  449. HRESULT hr = S_OK;
  450. IUnknown *lpIUnk = NULL;
  451. IImeIPoint1 *lpIImeIPoint = NULL;
  452. // Security Fix: Attack surface reduction
  453. if((!ppByte) || (!pSize)) {
  454. return E_FAIL;
  455. }
  456. DBG(("-->Check m_lpCImePadSvr\n"));
  457. if(!m_lpCImePadSvr) {
  458. DBG(("m_lpCImePadSvr is NULL Error\n"));
  459. return E_FAIL;
  460. }
  461. DBG(("-->Check m_fnCoTaskMemAlloc\n"));
  462. if(!m_lpCImePadSvr->m_fnCoTaskMemAlloc ||
  463. !m_lpCImePadSvr->m_fnCoTaskMemFree) {
  464. DBG(("--> OLE32.DLL does NOT EXIST ? Error\n"));
  465. return E_FAIL;
  466. }
  467. lpIUnk = m_lpCImePadSvr->GetIUnkIImeIPoint();
  468. DBG(("-->Check lpIUnk [0x%08x]\n", lpIUnk));
  469. if(!lpIUnk) {
  470. DBG(("lpIUnk is NULL\n"));
  471. return E_FAIL;
  472. }
  473. #if 0
  474. DBG(("-->Check lpIUnk IsBadVtbl[0x%08x]\n", lpIUnk));
  475. if(IsBadVtbl((IUnkDummy*)lpIUnk)) {
  476. DBG(("lpIUnk is BAD Pointer \n"));
  477. return E_FAIL;
  478. }
  479. #endif
  480. __try {
  481. DBG(("-->Call QuertyInterface\n"));
  482. hr = lpIUnk->QueryInterface(IID_IImeIPoint1, (VOID **)&lpIImeIPoint);
  483. if(hr != S_OK) {
  484. DBG(("QuertyInterface Failed\n"));
  485. return E_FAIL;
  486. }
  487. DBG(("--> QueryInterface Success \n"));
  488. if(!lpIImeIPoint) {
  489. DBG(("QuertyInterface failed\n"));
  490. return E_FAIL;
  491. }
  492. LPIMEDATACOMPOSITION lpCompoInfo;
  493. LPIMEDATACOMPOSITION lpCompoTmp;
  494. LPWSTR lpwstrCompo, lpwstr;
  495. DWORD *pdwCharID, *pdw;
  496. DWORD dwSize;
  497. DWORD dwDtnSize;
  498. LPBYTE lpbOutOfBuffer;
  499. switch(dwDataID) {
  500. case IMEDATAID_COMPOSITION:
  501. switch(dwCmdID) {
  502. case IMECMDID_GETCOMPOSITIONINFO:
  503. DBG(("--> IMECMDID_GETCOMPOSITIONINFO\n"));
  504. dwSize = sizeof(IMEDATACOMPOSITION);
  505. lpCompoInfo = (LPIMEDATACOMPOSITION)(*m_lpCImePadSvr->m_fnCoTaskMemAlloc)(dwSize);
  506. if(!lpCompoInfo) {
  507. lpIImeIPoint->Release();
  508. return E_OUTOFMEMORY;
  509. }
  510. hr = lpIImeIPoint->GetAllCompositionInfo(NULL,
  511. NULL,
  512. (INT *)&lpCompoInfo->dwStringCount,
  513. (INT *)&lpCompoInfo->dwCaretPos,
  514. (INT *)&lpCompoInfo->dwUndeterminedStartPos,
  515. (INT *)&lpCompoInfo->dwUndeterminedLength,
  516. (INT *)&lpCompoInfo->dwEditStartPos,
  517. (INT *)&lpCompoInfo->dwEditLength);
  518. lpCompoInfo->header.dwSize = dwSize;
  519. lpCompoInfo->header.dwCmdID = dwCmdID;
  520. lpCompoInfo->header.dwDataID= dwDataID;
  521. lpCompoInfo->dwOffsetString = 0;
  522. lpCompoInfo->dwOffsetCharID = 0;
  523. *pSize = lpCompoInfo->header.dwSize;
  524. *ppByte = (PBYTE)lpCompoInfo;
  525. DBG(("--> IMECMDID_GETCOMPOSITIONINFO END\n"));
  526. break;
  527. case IMECMDID_GETCOMPOSITIONSTRING:
  528. DBG(("--> IMECMDID_GETCOMPOSITIONSTRING START\n"));
  529. lpCompoInfo = (LPIMEDATACOMPOSITION)(*m_lpCImePadSvr->m_fnCoTaskMemAlloc)(sizeof(IMEDATACOMPOSITION));
  530. if(!lpCompoInfo) {
  531. DBG(("-->OutofMemory\n"));
  532. lpIImeIPoint->Release();
  533. return E_OUTOFMEMORY;
  534. }
  535. lpwstrCompo = NULL;
  536. pdwCharID = NULL;
  537. ZeroMemory(lpCompoInfo, sizeof(IMEDATACOMPOSITION));
  538. hr = lpIImeIPoint->GetAllCompositionInfo(&lpwstrCompo,
  539. &pdwCharID,
  540. (INT *)&lpCompoInfo->dwStringCount,
  541. (INT *)&lpCompoInfo->dwCaretPos,
  542. (INT *)&lpCompoInfo->dwUndeterminedStartPos,
  543. (INT *)&lpCompoInfo->dwUndeterminedLength,
  544. (INT *)&lpCompoInfo->dwEditStartPos,
  545. (INT *)&lpCompoInfo->dwEditLength);
  546. DBG(("-->hr [0x%08x]\n", hr));
  547. DBGW((L"-->lpwstrCompo[%s]\n", lpwstrCompo));
  548. dwSize = sizeof(IMEDATACOMPOSITION) +
  549. (lpCompoInfo->dwStringCount+1)*sizeof(WCHAR) +
  550. (lpCompoInfo->dwStringCount) * sizeof(DWORD);
  551. DBG(("-->dwSize [%d]\n", dwSize));
  552. lpCompoTmp = (LPIMEDATACOMPOSITION)(*m_lpCImePadSvr->m_fnCoTaskMemAlloc)(dwSize);
  553. if(!lpCompoTmp) {
  554. DBG(("-->OutofMemory\n"));
  555. lpIImeIPoint->Release();
  556. return E_OUTOFMEMORY;
  557. }
  558. lpCompoTmp->header.dwSize = dwSize;
  559. lpCompoTmp->header.dwCmdID = dwCmdID;
  560. lpCompoTmp->header.dwDataID= dwDataID;
  561. lpCompoTmp->dwStringCount = lpCompoInfo->dwStringCount;
  562. lpCompoTmp->dwCaretPos = lpCompoInfo->dwCaretPos;
  563. lpCompoTmp->dwUndeterminedStartPos = lpCompoInfo->dwUndeterminedStartPos;
  564. lpCompoTmp->dwUndeterminedLength = lpCompoInfo->dwUndeterminedLength;
  565. lpCompoTmp->dwEditStartPos = lpCompoInfo->dwEditStartPos;
  566. lpCompoTmp->dwEditLength = lpCompoInfo->dwEditLength;
  567. lpCompoTmp->dwOffsetString = (DWORD)sizeof(IMEDATACOMPOSITION);
  568. lpwstr = (LPWSTR)((PBYTE)lpCompoTmp + lpCompoTmp->dwOffsetString);
  569. // Security Fix: Dangerous API (CopyMemory)
  570. lpbOutOfBuffer = ((LPBYTE)lpCompoTmp) + dwSize;
  571. dwDtnSize = (DWORD)(lpbOutOfBuffer - ((LPBYTE)lpwstr));
  572. if (dwDtnSize < ((lpCompoTmp->dwStringCount+1) * sizeof(WCHAR)) ) {
  573. lpCompoTmp->dwStringCount = dwDtnSize / sizeof(WCHAR) - 1;
  574. }
  575. //990928:toshiaK for KOTAE #2273
  576. //Need to check lpwstrCompo is NULL or not.
  577. if(lpwstrCompo && lpCompoTmp->dwStringCount > 0) {
  578. CopyMemory(lpwstr,
  579. (WCHAR *)lpwstrCompo,
  580. lpCompoTmp->dwStringCount * sizeof(WCHAR));
  581. }
  582. lpwstr[lpCompoTmp->dwStringCount] = (WCHAR)0x0000;
  583. lpCompoTmp->dwOffsetCharID = (DWORD)(sizeof(IMEDATACOMPOSITION) +
  584. (lpCompoTmp->dwStringCount+1)*sizeof(WCHAR));
  585. //990928:toshiaK for KOTAE #2273
  586. //Need to check pdwCharID is NULL or not.
  587. if(pdwCharID && lpCompoTmp->dwStringCount > 0) {
  588. pdw = (DWORD *)((PBYTE)lpCompoTmp + lpCompoTmp->dwOffsetCharID);
  589. // Security Fix: Dangerous API (CopyMemory)
  590. dwDtnSize = (DWORD)(lpbOutOfBuffer - ((LPBYTE)pdw));
  591. if (dwDtnSize < (lpCompoTmp->dwStringCount * sizeof(DWORD)) ) {
  592. lpCompoTmp->dwStringCount = dwDtnSize / sizeof(DWORD);
  593. }
  594. CopyMemory(pdw, pdwCharID, sizeof(DWORD)*lpCompoTmp->dwStringCount);
  595. }
  596. *pSize = lpCompoTmp->header.dwSize;
  597. *ppByte = (PBYTE)lpCompoTmp;
  598. (*m_lpCImePadSvr->m_fnCoTaskMemFree)(lpCompoInfo);
  599. //990928:toshiaK for KOTAE #2273
  600. if(lpwstrCompo) {
  601. (*m_lpCImePadSvr->m_fnCoTaskMemFree)(lpwstrCompo);
  602. }
  603. //990928:toshiaK for KOTAE #2273
  604. if(pdwCharID) {
  605. (*m_lpCImePadSvr->m_fnCoTaskMemFree)(pdwCharID);
  606. }
  607. DBG(("--> IMECMDID_GETCOMPOSITIONSTRING END\n"));
  608. break;
  609. default:
  610. // Security Fix: Attack surface reduction
  611. hr = S_FALSE;
  612. break;
  613. }
  614. break;
  615. case IMEDATAID_CONVSTATUS:
  616. {
  617. if(dwCmdID != IMECMDID_GETCONVERSIONSTATUS) {
  618. DBG((" --> INVALID CMDID\n"));
  619. // Security Fix: Attack surface reduction
  620. hr = S_FALSE;
  621. break;
  622. }
  623. DBG(("--> IMECMDID_GETCONVERSIONSTATUS\n"));
  624. dwSize = sizeof(IMEDATACONVSTATUS);
  625. LPIMEDATACONVSTATUS lpConvStat;
  626. lpConvStat = (LPIMEDATACONVSTATUS)(*m_lpCImePadSvr->m_fnCoTaskMemAlloc)(dwSize);
  627. if(!lpConvStat) {
  628. DBG(("E_OUTOFMEMORY dwSize [%d]\n", dwSize));
  629. lpIImeIPoint->Release();
  630. return E_OUTOFMEMORY;
  631. }
  632. LPARAM lConv = 0;
  633. LPARAM lSent = 0;
  634. hr = lpIImeIPoint->ControlIME((WORD)IPCTRL_GETCONVERSIONMODE,
  635. (LPARAM)&lConv);
  636. hr = lpIImeIPoint->ControlIME((WORD)IPCTRL_GETSENTENCENMODE,
  637. (LPARAM)&lSent);
  638. lpConvStat->header.dwSize = dwSize;
  639. lpConvStat->header.dwCmdID = IMECMDID_GETCONVERSIONSTATUS;
  640. lpConvStat->header.dwDataID= IMEDATAID_CONVSTATUS;
  641. lpConvStat->dwConversionMode = (DWORD)lConv;
  642. lpConvStat->dwSentenceMode = (DWORD)lSent;
  643. DBG((" --> dwConversionMode[0x%8x]\n", lpConvStat->dwConversionMode));
  644. DBG((" --> dwSentenceMode [0x%8x]\n", lpConvStat->dwSentenceMode));
  645. *pSize = dwSize;
  646. *ppByte = (PBYTE)lpConvStat;
  647. }
  648. break;
  649. case IMEDATAID_APPINFO:
  650. //990816:ToshiaK KOTAE Raid #1757
  651. if(dwCmdID != IMECMDID_GETAPPLHWND) {
  652. DBG((" --> INVALID CMDID\n"));
  653. hr = S_FALSE;
  654. }
  655. else {
  656. IImeCallback *lp = NULL;
  657. IUnknown *lpUnkCB;
  658. lpUnkCB = m_lpCImePadSvr->GetIUnkIImeCallback();
  659. if(!lpUnkCB) {
  660. DBG(("-->IImeCallback does not set\n"));
  661. lpIImeIPoint->Release();
  662. return E_FAIL;
  663. }
  664. #if 0
  665. if(IsBadVtbl((IUnkDummy*)lpUnkCB)) {
  666. DBG(("lpIUnk is BAD Pointer \n"));
  667. lpIImeIPoint->Release();
  668. return E_FAIL;
  669. }
  670. #endif
  671. lpUnkCB->QueryInterface(IID_IImeCallback, (LPVOID *)&lp);
  672. if(!lp) {
  673. DBG(("-->QuertyInterface Failed\n"));
  674. lpIImeIPoint->Release();
  675. return E_FAIL;
  676. }
  677. dwSize = sizeof(IMEDATAAPPLINFO);
  678. LPIMEDATAAPPLINFO lpApplInfo;
  679. lpApplInfo = (LPIMEDATAAPPLINFO)(*m_lpCImePadSvr->m_fnCoTaskMemAlloc)(dwSize);
  680. if(!lpApplInfo) {
  681. DBG(("E_OUTOFMEMORY dwSize [%d]\n", dwSize));
  682. lpIImeIPoint->Release();
  683. return E_OUTOFMEMORY;
  684. }
  685. lpApplInfo->header.dwSize = dwSize;
  686. lpApplInfo->header.dwCmdID = IMECMDID_GETAPPLHWND;
  687. lpApplInfo->header.dwDataID= IMEDATAID_APPINFO;
  688. lpApplInfo->hwndApp = NULL;
  689. lp->GetApplicationHWND(&lpApplInfo->hwndApp);
  690. if(pSize && ppByte) {
  691. *pSize = dwSize;
  692. *ppByte = (PBYTE)lpApplInfo;
  693. }
  694. else {
  695. (*m_lpCImePadSvr->m_fnCoTaskMemFree)(lpApplInfo);
  696. hr = E_FAIL;
  697. }
  698. lp->Release();
  699. }
  700. break;
  701. default:
  702. DBG(("UNKOWN DATAID [0x%08x]\n", dwDataID));
  703. hr = S_FALSE;
  704. break;
  705. }
  706. lpIImeIPoint->Release();
  707. }
  708. __except(EXCEPTION_EXECUTE_HANDLER) {
  709. hr = E_FAIL;
  710. }
  711. DBG(("CImePadCallback::ReceiveData END hr[0x%08x]\n", hr));
  712. return hr;
  713. }
  714. //----------------------------------------------------------------
  715. CImePadCallback::CImePadCallback(HWND hwndIF, LPCImePadSvr lpCImePadSvr)
  716. {
  717. DBG(("######## CImePadCallback::CImePadCallback constructor START ##########\n"));
  718. m_hwndIF = hwndIF;
  719. m_lpCImePadSvr = lpCImePadSvr;
  720. m_cRef = 0;
  721. DBG(("######## CImePadCallback::CImePadCallback constructor END ##########\n"));
  722. }
  723. CImePadCallback::~CImePadCallback()
  724. {
  725. DBG(("######## CImePadCallback::~CImePadCallback destructor START ##########\n"));
  726. m_hwndIF = NULL;
  727. m_lpCImePadSvr = NULL;
  728. DBG(("######## CImePadCallback::~CImePadCallback destructor END ##########\n"));
  729. m_cRef = 0;
  730. }
  731. VOID*
  732. CImePadCallback::operator new( size_t size )
  733. {
  734. LPVOID lp = (LPVOID)MemAlloc(size);
  735. return lp;
  736. }
  737. VOID
  738. CImePadCallback::operator delete( VOID *lp )
  739. {
  740. if(lp) {
  741. MemFree(lp);
  742. }
  743. return;
  744. }