Difference between revisions of "User:Alvinhochun/Localization/IME/IMM"

From ReactOS Wiki
Jump to: navigation, search
(ReactOS)
 
(7 intermediate revisions by the same user not shown)
Line 1: Line 1:
Operations of IMM under XP.
+
Operations of IMM.
  
== Loading of <code>imm32.dll</code> ==
+
== Windows 2000 ==
 +
Studying from Windows 2000 seems easier since XP has lots of TSF-related code stuffed around.
 +
 
 +
I may not touch TSF code before this has some progress...
 +
 
 +
=== Initialization ===
 +
imm32.dll is loaded by user32.dll, similar to that in XP.
 +
 
 +
=== <code>imm32.dll</code> Functions ===
 +
==== Exported Functions ====
 +
{| class="mw-collapsible mw-collapsed wikitable"
 +
!colspan="4"| Exported Functions in <code>imm32.dll</code>
 +
|-
 +
! Function Name || Documented? || Decl || Remarks
 +
|-
 +
| <code>ImmActivateLayout</code> || No || ||
 +
|-
 +
| <code>ImmAssociateContext</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318171(v=vs.85).aspx Yes] || <pre>HIMC ImmAssociateContext(
 +
  _In_ HWND hWnd,
 +
  _In_ HIMC hIMC
 +
);</pre> ||
 +
|-
 +
| <code>ImmAssociateContextEx</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318172(v=vs.85).aspx Yes] || <pre>BOOL ImmAssociateContextEx(
 +
  _In_ HWND  hWnd,
 +
  _In_ HIMC  hIMC,
 +
  _In_ DWORD dwFlags
 +
);</pre> ||
 +
|-
 +
| <code>ImmCallImeConsoleIME</code> || No || ||
 +
|-
 +
| <code>ImmConfigureIMEA</code><br><code>ImmConfigureIMEW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318173(v=vs.85).aspx Yes] || <pre>BOOL ImmConfigureIME(
 +
  _In_ HKL    hKL,
 +
  _In_ HWND  hWnd,
 +
  _In_ DWORD  dwMode,
 +
  _In_ LPVOID lpData
 +
);</pre> ||
 +
|-
 +
| <code>ImmCreateContext</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318532(v=vs.85).aspx Yes] || <pre>HIMC ImmCreateContext(void);</pre> ||
 +
|-
 +
| <code>ImmCreateIMCC</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms905988.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmCreateSoftKeyboard</code> || No || ||
 +
|-
 +
| <code>ImmDestroyContext</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318533(v=vs.85).aspx Yes] || <pre>BOOL ImmDestroyContext(
 +
  _In_ HIMC hIMC
 +
);</pre> ||
 +
|-
 +
| <code>ImmDestroyIMCC</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms905990.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmDestroySoftKeyboard</code> || No || ||
 +
|-
 +
| <code>ImmDisableIME</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318535(v=vs.85).aspx Yes] || <pre>BOOL ImmDisableIME(
 +
  _In_ DWORD idThread
 +
);</pre> ||
 +
|-
 +
| ''<code>ImmDisableIme</code>'' || ? ||colspan="2"| Direct alias of <code>ImmDisableIME</code>
 +
|-
 +
| <code>ImmEnumInputContext</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318539(v=vs.85).aspx Yes] || <pre>BOOL ImmEnumInputContext(
 +
  _In_ DWORD      idThread,
 +
  _In_ IMCENUMPROC lpfn,
 +
  _In_ LPARAM      lParam
 +
);</pre> ||
 +
|-
 +
| <code>ImmEnumRegisterWordA</code><br><code>ImmEnumRegisterWordW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318542(v=vs.85).aspx Yes] || <pre>UINT ImmEnumRegisterWord(
 +
  _In_    HKL                  hKL,
 +
  _In_    REGISTERWORDENUMPROC lpfnEnumProc,
 +
  _In_opt_ LPCTSTR              lpszReading,
 +
  _In_    DWORD                dwStyle,
 +
  _In_opt_ LPCTSTR              lpszRegister,
 +
  _In_    LPVOID              lpData
 +
);</pre> ||
 +
|-
 +
| <code>ImmEscapeA</code><br><code>ImmEscapeW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318544(v=vs.85).aspx Yes] || <pre>LRESULT ImmEscape(
 +
  _In_    HKL    hKL,
 +
  _In_    HIMC  hIMC,
 +
  _In_    UINT  uEscape,
 +
  _Inout_ LPVOID lpData
 +
);</pre> ||
 +
|-
 +
| <code>ImmFreeLayout</code> || No || ||
 +
|-
 +
| <code>ImmGenerateMessage</code> || No || ||
 +
|-
 +
| <code>ImmGetCandidateListA</code><br><code>ImmGetCandidateListW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318545(v=vs.85).aspx Yes] || <pre>DWORD ImmGetCandidateList(
 +
  _In_      HIMC            hIMC,
 +
  _In_      DWORD          dwIndex,
 +
  _Out_opt_ LPCANDIDATELIST lpCandList,
 +
  _In_      DWORD          dwBufLen
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetCandidateListCountA</code><br><code>ImmGetCandidateListCountW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318547(v=vs.85).aspx Yes] || <pre>DWORD ImmGetCandidateListCount(
 +
  _In_  HIMC    hIMC,
 +
  _Out_ LPDWORD lpdwListCount
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetCandidateWindow</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318549(v=vs.85).aspx Yes] || <pre>BOOL ImmGetCandidateWindow(
 +
  _In_  HIMC            hIMC,
 +
  _In_  DWORD          dwIndex,
 +
  _Out_ LPCANDIDATEFORM lpCandidate
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetCompositionFontA</code><br><code>ImmGetCompositionFontW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318551(v=vs.85).aspx Yes] || <pre>BOOL ImmGetCompositionFont(
 +
  _In_  HIMC      hIMC,
 +
  _Out_ LPLOGFONT lplf
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetCompositionStringA</code><br><code>ImmGetCompositionStringW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318553(v=vs.85).aspx Yes] || <pre>LONG ImmGetCompositionString(
 +
  _In_      HIMC  hIMC,
 +
  _In_      DWORD  dwIndex,
 +
  _Out_opt_ LPVOID lpBuf,
 +
  _In_      DWORD  dwBufLen
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetCompositionWindow</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318556(v=vs.85).aspx Yes] || <pre>BOOL ImmGetCompositionWindow(
 +
  _In_  HIMC              hIMC,
 +
  _Out_ LPCOMPOSITIONFORM lpCompForm
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetContext</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318558(v=vs.85).aspx Yes] || <pre>HIMC ImmGetContext(
 +
  _In_ HWND hWnd
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetConversionListA</code><br><code>ImmGetConversionListW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318559(v=vs.85).aspx Yes] || <pre>DWORD ImmGetConversionList(
 +
  _In_  HKL            hKL,
 +
  _In_  HIMC            hIMC,
 +
  _In_  LPCTSTR        lpSrc,
 +
  _Out_ LPCANDIDATELIST lpDst,
 +
  _In_  DWORD          dwBufLen,
 +
  _In_  UINT            uFlag
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetConversionStatus</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318560(v=vs.85).aspx Yes] || <pre>BOOL ImmGetConversionStatus(
 +
  _In_      HIMC    hIMC,
 +
  _Out_opt_ LPDWORD lpfdwConversion,
 +
  _Out_opt_ LPDWORD lpfdwSentence
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetDefaultIMEWnd</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318561(v=vs.85).aspx Yes] || <pre>HWND ImmGetDefaultIMEWnd(
 +
  _In_ HWND hWnd
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetDescriptionA</code><br><code>ImmGetDescriptionW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318562(v=vs.85).aspx Yes] || <pre>UINT ImmGetDescription(
 +
  _In_      HKL    hKL,
 +
  _Out_opt_ LPTSTR lpszDescription,
 +
  _In_      UINT  uBufLen
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetGuideLineA</code><br><code>ImmGetGuideLineW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318563(v=vs.85).aspx Yes] || <pre>DWORD ImmGetGuideLine(
 +
  _In_      HIMC  hIMC,
 +
  _In_      DWORD  dwIndex,
 +
  _Out_opt_ LPTSTR lpBuf,
 +
  _In_      DWORD  dwBufLen
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetHotKey</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906010.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmGetIMCCLockCount</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906011.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmGetIMCCSize</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906012.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmGetIMCLockCount</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906013.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmGetIMEFileNameA</code><br><code>ImmGetIMEFileNameW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318564(v=vs.85).aspx Yes] || <pre>UINT ImmGetIMEFileName(
 +
  _In_      HKL    hKL,
 +
  _Out_opt_ LPTSTR lpszFileName,
 +
  _In_      UINT  uBufLen
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetImeInfoEx</code> || No || ||
 +
|-
 +
| <code>ImmGetImeMenuItemsA</code><br><code>ImmGetImeMenuItemsW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318565(v=vs.85).aspx Yes] || <pre>DWORD ImmGetImeMenuItems(
 +
  _In_      HIMC              hIMC,
 +
  _In_      DWORD            dwFlags,
 +
  _In_      DWORD            dwType,
 +
  _Out_opt_ LPIMEMENUITEMINFO lpImeParentMenu,
 +
  _Out_opt_ LPIMEMENUITEMINFO lpImeMenu,
 +
  _In_      DWORD            dwSize
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetOpenStatus</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318566(v=vs.85).aspx Yes] || <pre>BOOL ImmGetOpenStatus(
 +
  _In_ HIMC hIMC
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetProperty</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318567(v=vs.85).aspx Yes] || <pre>DWORD ImmGetProperty(
 +
  _In_ HKL  hKL,
 +
  _In_ DWORD fdwIndex
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetRegisterWordStyleA</code><br><code>ImmGetRegisterWordStyleW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318568(v=vs.85).aspx Yes] || <pre>UINT ImmGetRegisterWordStyle(
 +
  _In_  HKL        hKL,
 +
  _In_  UINT      nItem,
 +
  _Out_ LPSTYLEBUF lpStyleBuf
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetStatusWindowPos</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318569(v=vs.85).aspx Yes] || <pre>BOOL ImmGetStatusWindowPos(
 +
  _In_  HIMC    hIMC,
 +
  _Out_ LPPOINT lpptPos
 +
);</pre> ||
 +
|-
 +
| <code>ImmGetVirtualKey</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318570(v=vs.85).aspx Yes] || <pre>UINT ImmGetVirtualKey(
 +
  _In_ HWND hWnd
 +
);</pre> ||
 +
|-
 +
| <code>ImmIMPGetIMEA</code><br><code>ImmIMPGetIMEW</code> || No || ||
 +
|-
 +
| <code>ImmIMPQueryIMEA</code><br><code>ImmIMPQueryIMEW</code> || No || ||
 +
|-
 +
| <code>ImmIMPSetIMEA</code><br><code>ImmIMPSetIMEW</code> || No || ||
 +
|-
 +
| <code>ImmInstallIMEA</code><br><code>ImmInstallIMEW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318571(v=vs.85).aspx Yes] || <pre>HKL ImmInstallIME(
 +
  _In_ LPCTSTR lpszIMEFileName,
 +
  _In_ LPCTSTR lpszLayoutText
 +
);</pre> ||
 +
|-
 +
| <code>ImmIsIME</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318572(v=vs.85).aspx Yes] || <pre>BOOL ImmIsIME(
 +
  _In_ HKL hKL
 +
);</pre> ||
 +
|-
 +
| <code>ImmIsUIMessageA</code><br><code>ImmIsUIMessageW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318573(v=vs.85).aspx Yes] || <pre>BOOL ImmIsUIMessage(
 +
  _In_ HWND  hWndIME,
 +
  _In_ UINT  msg,
 +
  _In_ WPARAM wParam,
 +
  _In_ LPARAM lParam
 +
);</pre> ||
 +
|-
 +
| <code>ImmLoadIME</code> || No || ||
 +
|-
 +
| <code>ImmLoadLayout</code> || No || ||
 +
|-
 +
| <code>ImmLockClientImc</code> || No || ||
 +
|-
 +
| <code>ImmLockIMC</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906023.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmLockIMCC</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906024.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmLockImeDpi</code> || No || ||
 +
|-
 +
| <code>ImmNotifyIME</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318574(v=vs.85).aspx Yes] || <pre>BOOL ImmNotifyIME(
 +
  _In_ HIMC  hIMC,
 +
  _In_ DWORD dwAction,
 +
  _In_ DWORD dwIndex,
 +
  _In_ DWORD dwValue
 +
);</pre> ||
 +
|-
 +
| <code>ImmPenAuxInput</code> || No || ||
 +
|-
 +
| <code>ImmProcessKey</code> || No || ||
 +
|-
 +
| <code>ImmPutImeMenuItemsIntoMappedFile</code> || No || ||
 +
|-
 +
| <code>ImmRegisterClient</code> || No || ||
 +
|-
 +
| <code>ImmRegisterWordA</code><br><code>ImmRegisterWordW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318575(v=vs.85).aspx Yes] || <pre>BOOL ImmRegisterWord(
 +
  _In_ HKL    hKL,
 +
  _In_ LPCTSTR lpszReading,
 +
  _In_ DWORD  dwStyle,
 +
  _In_ LPCTSTR lpszRegister
 +
);</pre> ||
 +
|-
 +
| <code>ImmReleaseContext</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318576(v=vs.85).aspx Yes] || <pre>BOOL ImmReleaseContext(
 +
  _In_ HWND hWnd,
 +
  _In_ HIMC hIMC
 +
);</pre> ||
 +
|-
 +
| <code>ImmRequestMessageA</code><br><code>ImmRequestMessageW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318577(v=vs.85).aspx Yes] || <pre>LRESULT ImmRequestMessage(
 +
  _In_ HIMC  hIMC,
 +
  _In_ WPARAM wParam,
 +
  _In_ LPARAM lParam
 +
);</pre> ||
 +
|-
 +
| <code>ImmReSizeIMCC</code> || No || ||
 +
|-
 +
| <code>ImmSendIMEMessageExA</code><br><code>ImmSendIMEMessageExW</code> || No || ||
 +
|-
 +
| <code>ImmSendMessageToActiveDefImeWndW</code> || No || ||
 +
|-
 +
| <code>ImmSetActiveContext</code> || No || ||
 +
|-
 +
| <code>ImmSetActiveContextConsoleIME</code> || No || ||
 +
|-
 +
| <code>ImmSetCandidateWindow</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318578(v=vs.85).aspx Yes] || <pre>BOOL ImmSetCandidateWindow(
 +
  _In_ HIMC            hIMC,
 +
  _In_ LPCANDIDATEFORM lpCandidate
 +
);</pre> ||
 +
|-
 +
| <code>ImmSetCompositionFontA</code><br><code>ImmSetCompositionFontW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318579(v=vs.85).aspx Yes] || <pre>BOOL ImmSetCompositionFont(
 +
  _In_ HIMC      hIMC,
 +
  _In_ LPLOGFONT lplf
 +
);</pre> ||
 +
|-
 +
| <code>ImmSetCompositionStringA</code><br><code>ImmSetCompositionStringW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318580(v=vs.85).aspx Yes] || <pre>BOOL ImmSetCompositionString(
 +
  _In_    HIMC  hIMC,
 +
  _In_    DWORD  dwIndex,
 +
  _In_opt_ LPVOID lpComp,
 +
  _In_    DWORD  dwCompLen,
 +
  _In_opt_ LPVOID lpRead,
 +
  _In_    DWORD  dwReadLen
 +
);</pre> ||
 +
|-
 +
| <code>ImmSetCompositionWindow</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318581(v=vs.85).aspx Yes] || <pre>BOOL ImmSetCompositionWindow(
 +
  _In_ HIMC              hIMC,
 +
  _In_ LPCOMPOSITIONFORM lpCompForm
 +
);</pre> ||
 +
|-
 +
| <code>ImmSetConversionStatus</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318584(v=vs.85).aspx Yes] || <pre>BOOL ImmSetConversionStatus(
 +
  _In_ HIMC  hIMC,
 +
  _In_ DWORD fdwConversion,
 +
  _In_ DWORD fdwSentence
 +
);</pre> ||
 +
|-
 +
| <code>ImmSetHotKey</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906034.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmSetOpenStatus</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318586(v=vs.85).aspx Yes] || <pre>BOOL ImmSetOpenStatus(
 +
  _In_ HIMC hIMC,
 +
  _In_ BOOL fOpen
 +
);</pre> ||
 +
|-
 +
| <code>ImmSetStatusWindowPos</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318587(v=vs.85).aspx Yes] || <pre>BOOL ImmSetStatusWindowPos(
 +
  _In_ HIMC    hIMC,
 +
  _In_ LPPOINT lpptPos
 +
);</pre> ||
 +
|-
 +
| <code>ImmShowSoftKeyboard</code> || No || ||
 +
|-
 +
| <code>ImmSimulateHotKey</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318589(v=vs.85).aspx Yes] || <pre>BOOL ImmSimulateHotKey(
 +
  _In_ HWND  hWnd,
 +
  _In_ DWORD dwHotKeyID
 +
);</pre> ||
 +
|-
 +
| <code>ImmSystemHandler</code> || No || ||
 +
|-
 +
| <code>ImmTranslateMessage</code> || No || ||
 +
|-
 +
| <code>ImmUnlockClientImc</code> || No || ||
 +
|-
 +
| <code>ImmUnlockIMC</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906039.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmUnlockIMCC</code> || No* || || [https://msdn.microsoft.com/en-us/library/ms906040.aspx Same name for WinCE5]
 +
|-
 +
| <code>ImmUnlockImeDpi</code> || No || ||
 +
|-
 +
| <code>ImmUnregisterWordA</code><br><code>ImmUnregisterWordW</code> || [https://msdn.microsoft.com/en-us/library/windows/desktop/dd318591(v=vs.85).aspx Yes] || <pre>BOOL ImmUnregisterWord(
 +
  _In_ HKL    hKL,
 +
  _In_ LPCTSTR lpszReading,
 +
  _In_ DWORD  dwStyle,
 +
  _In_ LPCTSTR lpszUnregister
 +
);</pre> ||
 +
|-
 +
| <code>ImmWINNLSEnableIME</code> || No || ||
 +
|-
 +
| <code>ImmWINNLSGetEnableStatus</code> || No || ||
 +
|-
 +
| <code>ImmWINNLSGetIMEHotkey</code> || No || ||
 +
|}
 +
 
 +
==== Documented Functions ====
 +
===== <code>ImmCreateContext</code> =====
 +
This calls [[#NtUserCreateInputContext|<code>NtUserCreateInputContext</code>]].
 +
 
 +
''TODO''
 +
 
 +
===== <code>ImmGetContext</code> =====
 +
[https://msdn.microsoft.com/en-us/library/windows/desktop/dd318558%28v=vs.85%29.aspx <code>HIMC WINAPI ImmGetContext(HWND hWnd)</code>]
 +
 
 +
"The application must call ImmReleaseContext when it is finished with the input context[,]" says MSDN. However, given the behaviour of ImmReleaseContext, it really does nothing.
 +
 
 +
This performs a NULL check and then call [[#ImmGetSaveContext|<code>ImmGetSaveContext(hWnd, 2)</code>]].
 +
 
 +
===== <code>ImmReleaseContext</code> =====
 +
[https://msdn.microsoft.com/en-us/library/windows/desktop/dd318576(v=vs.85).aspx <code>BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)</code>]
 +
 
 +
Always returns <code>TRUE</code>. (Just checked that even Windows 7 does this too.)
 +
 
 +
==== Undocumented Functions ====
 +
===== <code>ImmRegisterClient</code> =====
 +
<code>int WINAPI ImmRegisterClient(_some_struct(size 0x3E) *arg1, HINSTANCE arg2);</code>
 +
 
 +
This function doesn't really seem to register anything, but only initialize some variables. Something like:
 +
* gSharedInfo = *arg1;
 +
* gpsi = first byte of gSharedInfo;
 +
* return ImmInitializeGlobals(arg2);
 +
 
 +
This is called within user32.dll too.
 +
 
 +
===== <code>ImmInitializeGlobals</code> =====
 +
<code>int ImmInitializeGlobals(HINSTANCE arg1);</code>
 +
 
 +
* Stores arg1 to ghInst if not NULL
 +
* if not initialized already (gfInitialized == 0), then:
 +
** RtlInitializeCriticalSection(&gcsImeDpi)
 +
** gHighestUserAddress = SYSTEM_BASIC_INFORMATION.MaximumUserModeAddress (no idea what it is used for yet)
 +
** gfInitialized = 1
 +
 
 +
===== <code>ImmGetSaveContext</code> =====
 +
<code>HIMC __stdcall ImmGetSaveContext(HWND hWnd, char arg2);</code>
 +
 
 +
* If gpsi == 0 || !(gpsi->_byte_at_offset_2 & 8) then return NULL
 +
* If hWnd is NULL then get HIMC by NtUserGetThreadState(4)
 +
* Else:
 +
** Gets PWND by HMValidateHandle(hWnd, 1)
 +
** If window not owned by current process then return NULL
 +
** Gets HIMC from PWND->hImc
 +
** If NULL and arg2 has bit 0 set then try to get hIMC by NtUserQueryWindow(hWnd, 8)
 +
* _some_struct *ret = ImmLockClientImc(HIMC)
 +
* If ret is NULL then return NULL
 +
* If arg2 has bit 1 set and byte at offset 8 of ret has bit 7 set then ImmUnlockClientImc and return NULL
 +
* ImmUnlockClientImc and return HIMC
 +
 
 +
From this, it appears that each thread and window has its default IME context. It is possible that each window uses the context of the thread it is created in.
 +
 
 +
Also, debugging notepad shows that ImmCreateContext is never called to create them.
 +
 
 +
=== Kernel Functions ===
 +
==== <code>NtUserCreateInputContext</code> ====
 +
<code>DWORD APIENTRY NtUserCreateInputContext(void *dwUnknown1);</code>
 +
 
 +
From <code>ImmCreateContext</code>: return value of <code>ImmLocalAlloc(8, 0x2c)</code> is passed as the first parameter, so it is probably a pointer.
 +
 
 +
This appears to call <code>EnterCrit</code> and then call <code>win32k!CreateInputContext</code>.
 +
 
 +
''TODO''
 +
 
 +
==== <code>CreateInputContext</code> ====
 +
<code>int __stdcall CreateInputContext(void *arg1);</code>
 +
 
 +
This is known to be called by <code>NtUserCreateInputContext</code>, and also by <code>xxxCreateThreadInfo</code>.
 +
 
 +
<pre>
 +
bd032cb4 a005df13 win32k!CreateInputContext
 +
bd032d0c a005d594 win32k!xxxCreateThreadInfo+0x5d9
 +
bd032d20 a005d4c7 win32k!UserThreadCallout+0x9d
 +
bd032d3c 80496f4c win32k!W32pThreadCallout+0x3b
 +
bd032d54 8046140e nt!PsConvertToGuiThread+0xad
 +
bd032ddc 80465b62 nt!KiBBTUnexpectedRange+0xc
 +
00000000 00000000 nt!KiThreadStartup+0x16
 +
</pre>
 +
 
 +
Seems that the thread IME context is created when a UI thread is created?
 +
 
 +
Not called when a window is created.
 +
 
 +
''TODO''
 +
 
 +
== Loading of <code>imm32.dll</code> (XP) ==
 
IMM32 is loaded by <code>user32.dll</code> from <code>_InitializeImmEntryTable</code>. It loads the library (if not already) and fill in a structure of function pointers <code>gImmApiEntries</code>. This function is supposed to be called in the DllMain of USER32 but the relevant code is currently commented out.
 
IMM32 is loaded by <code>user32.dll</code> from <code>_InitializeImmEntryTable</code>. It loads the library (if not already) and fill in a structure of function pointers <code>gImmApiEntries</code>. This function is supposed to be called in the DllMain of USER32 but the relevant code is currently commented out.
  
 
In ReactOS, the related functions are located under <code>win32ss\user\user32\misc\imm.c</code>. The functions it loads is different from that of Windows XP.
 
In ReactOS, the related functions are located under <code>win32ss\user\user32\misc\imm.c</code>. The functions it loads is different from that of Windows XP.
  
A simple trace (hopefully I got it correct):
+
A simple trace (some information is omitted) (hopefully I got it correct):
  
 
* user32!DllMain
 
* user32!DllMain
Line 27: Line 470:
 
As of {{rev|67617}}, attempting to load IMM from user32 crashes:
 
As of {{rev|67617}}, attempting to load IMM from user32 crashes:
  
<pre>
+
<div class="mw-collapsible mw-collapsed">
 +
Stack trace (click "Expand" to show):
 +
<pre class="mw-collapsible-content">
 
f9af5b1c f9baa0e6 00000000 00000000 00000059 win32k!EngpCreatePDEV+0xf8 [d:\reactos\src\win32ss\gdi\eng\pdevobj.c @ 331]
 
f9af5b1c f9baa0e6 00000000 00000000 00000059 win32k!EngpCreatePDEV+0xf8 [d:\reactos\src\win32ss\gdi\eng\pdevobj.c @ 331]
 
f9af5b3c f9c2cc84 00000000 ffffffff 00000000 win32k!EngpGetPDEV+0x96 [d:\reactos\src\win32ss\gdi\eng\pdevobj.c @ 572]
 
f9af5b3c f9c2cc84 00000000 ffffffff 00000000 win32k!EngpGetPDEV+0x96 [d:\reactos\src\win32ss\gdi\eng\pdevobj.c @ 572]
Line 66: Line 511:
 
0021fff4 00000000 7ffdf000 ec0100ed 00000000 csrss!NtProcessStartup+0x399 [d:\reactos\src\lib\sdk\nt\entry_point.c @ 199]
 
0021fff4 00000000 7ffdf000 ec0100ed 00000000 csrss!NtProcessStartup+0x399 [d:\reactos\src\lib\sdk\nt\entry_point.c @ 199]
 
</pre>
 
</pre>
 +
</div>
  
 
It seems to attempt to load a cursor on <code>IMM_RegisterIMEClass</code> which seems to cause problems in gdi code.
 
It seems to attempt to load a cursor on <code>IMM_RegisterIMEClass</code> which seems to cause problems in gdi code.
  
 
Perhaps <code>IMM_RegisterIMEClass</code> may not need to be called there?
 
Perhaps <code>IMM_RegisterIMEClass</code> may not need to be called there?
 +
 +
<hr>
 +
Attempted to sync Wine 1.7.37 ({{JIRA|9685}}), seems to not crash anymore.
 +
 +
<hr>
 +
Got most of the imm32 winetest running after hacks, but the test ends prematurely at line 1008 (on my local tree).

Latest revision as of 14:57, 13 May 2015

Operations of IMM.

Windows 2000

Studying from Windows 2000 seems easier since XP has lots of TSF-related code stuffed around.

I may not touch TSF code before this has some progress...

Initialization

imm32.dll is loaded by user32.dll, similar to that in XP.

imm32.dll Functions

Exported Functions

Exported Functions in imm32.dll
Function Name Documented? Decl Remarks
ImmActivateLayout No
ImmAssociateContext Yes
HIMC ImmAssociateContext(
  _In_ HWND hWnd,
  _In_ HIMC hIMC
);
ImmAssociateContextEx Yes
BOOL ImmAssociateContextEx(
  _In_ HWND  hWnd,
  _In_ HIMC  hIMC,
  _In_ DWORD dwFlags
);
ImmCallImeConsoleIME No
ImmConfigureIMEA
ImmConfigureIMEW
Yes
BOOL ImmConfigureIME(
  _In_ HKL    hKL,
  _In_ HWND   hWnd,
  _In_ DWORD  dwMode,
  _In_ LPVOID lpData
);
ImmCreateContext Yes
HIMC ImmCreateContext(void);
ImmCreateIMCC No* Same name for WinCE5
ImmCreateSoftKeyboard No
ImmDestroyContext Yes
BOOL ImmDestroyContext(
  _In_ HIMC hIMC
);
ImmDestroyIMCC No* Same name for WinCE5
ImmDestroySoftKeyboard No
ImmDisableIME Yes
BOOL ImmDisableIME(
  _In_ DWORD idThread
);
ImmDisableIme ? Direct alias of ImmDisableIME
ImmEnumInputContext Yes
BOOL ImmEnumInputContext(
  _In_ DWORD       idThread,
  _In_ IMCENUMPROC lpfn,
  _In_ LPARAM      lParam
);
ImmEnumRegisterWordA
ImmEnumRegisterWordW
Yes
UINT ImmEnumRegisterWord(
  _In_     HKL                  hKL,
  _In_     REGISTERWORDENUMPROC lpfnEnumProc,
  _In_opt_ LPCTSTR              lpszReading,
  _In_     DWORD                dwStyle,
  _In_opt_ LPCTSTR              lpszRegister,
  _In_     LPVOID               lpData
);
ImmEscapeA
ImmEscapeW
Yes
LRESULT ImmEscape(
  _In_    HKL    hKL,
  _In_    HIMC   hIMC,
  _In_    UINT   uEscape,
  _Inout_ LPVOID lpData
);
ImmFreeLayout No
ImmGenerateMessage No
ImmGetCandidateListA
ImmGetCandidateListW
Yes
DWORD ImmGetCandidateList(
  _In_      HIMC            hIMC,
  _In_      DWORD           dwIndex,
  _Out_opt_ LPCANDIDATELIST lpCandList,
  _In_      DWORD           dwBufLen
);
ImmGetCandidateListCountA
ImmGetCandidateListCountW
Yes
DWORD ImmGetCandidateListCount(
  _In_  HIMC    hIMC,
  _Out_ LPDWORD lpdwListCount
);
ImmGetCandidateWindow Yes
BOOL ImmGetCandidateWindow(
  _In_  HIMC            hIMC,
  _In_  DWORD           dwIndex,
  _Out_ LPCANDIDATEFORM lpCandidate
);
ImmGetCompositionFontA
ImmGetCompositionFontW
Yes
BOOL ImmGetCompositionFont(
  _In_  HIMC      hIMC,
  _Out_ LPLOGFONT lplf
);
ImmGetCompositionStringA
ImmGetCompositionStringW
Yes
LONG ImmGetCompositionString(
  _In_      HIMC   hIMC,
  _In_      DWORD  dwIndex,
  _Out_opt_ LPVOID lpBuf,
  _In_      DWORD  dwBufLen
);
ImmGetCompositionWindow Yes
BOOL ImmGetCompositionWindow(
  _In_  HIMC              hIMC,
  _Out_ LPCOMPOSITIONFORM lpCompForm
);
ImmGetContext Yes
HIMC ImmGetContext(
  _In_ HWND hWnd
);
ImmGetConversionListA
ImmGetConversionListW
Yes
DWORD ImmGetConversionList(
  _In_  HKL             hKL,
  _In_  HIMC            hIMC,
  _In_  LPCTSTR         lpSrc,
  _Out_ LPCANDIDATELIST lpDst,
  _In_  DWORD           dwBufLen,
  _In_  UINT            uFlag
);
ImmGetConversionStatus Yes
BOOL ImmGetConversionStatus(
  _In_      HIMC    hIMC,
  _Out_opt_ LPDWORD lpfdwConversion,
  _Out_opt_ LPDWORD lpfdwSentence
);
ImmGetDefaultIMEWnd Yes
HWND ImmGetDefaultIMEWnd(
  _In_ HWND hWnd
);
ImmGetDescriptionA
ImmGetDescriptionW
Yes
UINT ImmGetDescription(
  _In_      HKL    hKL,
  _Out_opt_ LPTSTR lpszDescription,
  _In_      UINT   uBufLen
);
ImmGetGuideLineA
ImmGetGuideLineW
Yes
DWORD ImmGetGuideLine(
  _In_      HIMC   hIMC,
  _In_      DWORD  dwIndex,
  _Out_opt_ LPTSTR lpBuf,
  _In_      DWORD  dwBufLen
);
ImmGetHotKey No* Same name for WinCE5
ImmGetIMCCLockCount No* Same name for WinCE5
ImmGetIMCCSize No* Same name for WinCE5
ImmGetIMCLockCount No* Same name for WinCE5
ImmGetIMEFileNameA
ImmGetIMEFileNameW
Yes
UINT ImmGetIMEFileName(
  _In_      HKL    hKL,
  _Out_opt_ LPTSTR lpszFileName,
  _In_      UINT   uBufLen
);
ImmGetImeInfoEx No
ImmGetImeMenuItemsA
ImmGetImeMenuItemsW
Yes
DWORD ImmGetImeMenuItems(
  _In_      HIMC              hIMC,
  _In_      DWORD             dwFlags,
  _In_      DWORD             dwType,
  _Out_opt_ LPIMEMENUITEMINFO lpImeParentMenu,
  _Out_opt_ LPIMEMENUITEMINFO lpImeMenu,
  _In_      DWORD             dwSize
);
ImmGetOpenStatus Yes
BOOL ImmGetOpenStatus(
  _In_ HIMC hIMC
);
ImmGetProperty Yes
DWORD ImmGetProperty(
  _In_ HKL   hKL,
  _In_ DWORD fdwIndex
);
ImmGetRegisterWordStyleA
ImmGetRegisterWordStyleW
Yes
UINT ImmGetRegisterWordStyle(
  _In_  HKL        hKL,
  _In_  UINT       nItem,
  _Out_ LPSTYLEBUF lpStyleBuf
);
ImmGetStatusWindowPos Yes
BOOL ImmGetStatusWindowPos(
  _In_  HIMC    hIMC,
  _Out_ LPPOINT lpptPos
);
ImmGetVirtualKey Yes
UINT ImmGetVirtualKey(
  _In_ HWND hWnd
);
ImmIMPGetIMEA
ImmIMPGetIMEW
No
ImmIMPQueryIMEA
ImmIMPQueryIMEW
No
ImmIMPSetIMEA
ImmIMPSetIMEW
No
ImmInstallIMEA
ImmInstallIMEW
Yes
HKL ImmInstallIME(
  _In_ LPCTSTR lpszIMEFileName,
  _In_ LPCTSTR lpszLayoutText
);
ImmIsIME Yes
BOOL ImmIsIME(
  _In_ HKL hKL
);
ImmIsUIMessageA
ImmIsUIMessageW
Yes
BOOL ImmIsUIMessage(
  _In_ HWND   hWndIME,
  _In_ UINT   msg,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);
ImmLoadIME No
ImmLoadLayout No
ImmLockClientImc No
ImmLockIMC No* Same name for WinCE5
ImmLockIMCC No* Same name for WinCE5
ImmLockImeDpi No
ImmNotifyIME Yes
BOOL ImmNotifyIME(
  _In_ HIMC  hIMC,
  _In_ DWORD dwAction,
  _In_ DWORD dwIndex,
  _In_ DWORD dwValue
);
ImmPenAuxInput No
ImmProcessKey No
ImmPutImeMenuItemsIntoMappedFile No
ImmRegisterClient No
ImmRegisterWordA
ImmRegisterWordW
Yes
BOOL ImmRegisterWord(
  _In_ HKL     hKL,
  _In_ LPCTSTR lpszReading,
  _In_ DWORD   dwStyle,
  _In_ LPCTSTR lpszRegister
);
ImmReleaseContext Yes
BOOL ImmReleaseContext(
  _In_ HWND hWnd,
  _In_ HIMC hIMC
);
ImmRequestMessageA
ImmRequestMessageW
Yes
LRESULT ImmRequestMessage(
  _In_ HIMC   hIMC,
  _In_ WPARAM wParam,
  _In_ LPARAM lParam
);
ImmReSizeIMCC No
ImmSendIMEMessageExA
ImmSendIMEMessageExW
No
ImmSendMessageToActiveDefImeWndW No
ImmSetActiveContext No
ImmSetActiveContextConsoleIME No
ImmSetCandidateWindow Yes
BOOL ImmSetCandidateWindow(
  _In_ HIMC            hIMC,
  _In_ LPCANDIDATEFORM lpCandidate
);
ImmSetCompositionFontA
ImmSetCompositionFontW
Yes
BOOL ImmSetCompositionFont(
  _In_ HIMC      hIMC,
  _In_ LPLOGFONT lplf
);
ImmSetCompositionStringA
ImmSetCompositionStringW
Yes
BOOL ImmSetCompositionString(
  _In_     HIMC   hIMC,
  _In_     DWORD  dwIndex,
  _In_opt_ LPVOID lpComp,
  _In_     DWORD  dwCompLen,
  _In_opt_ LPVOID lpRead,
  _In_     DWORD  dwReadLen
);
ImmSetCompositionWindow Yes
BOOL ImmSetCompositionWindow(
  _In_ HIMC              hIMC,
  _In_ LPCOMPOSITIONFORM lpCompForm
);
ImmSetConversionStatus Yes
BOOL ImmSetConversionStatus(
  _In_ HIMC  hIMC,
  _In_ DWORD fdwConversion,
  _In_ DWORD fdwSentence
);
ImmSetHotKey No* Same name for WinCE5
ImmSetOpenStatus Yes
BOOL ImmSetOpenStatus(
  _In_ HIMC hIMC,
  _In_ BOOL fOpen
);
ImmSetStatusWindowPos Yes
BOOL ImmSetStatusWindowPos(
  _In_ HIMC    hIMC,
  _In_ LPPOINT lpptPos
);
ImmShowSoftKeyboard No
ImmSimulateHotKey Yes
BOOL ImmSimulateHotKey(
  _In_ HWND  hWnd,
  _In_ DWORD dwHotKeyID
);
ImmSystemHandler No
ImmTranslateMessage No
ImmUnlockClientImc No
ImmUnlockIMC No* Same name for WinCE5
ImmUnlockIMCC No* Same name for WinCE5
ImmUnlockImeDpi No
ImmUnregisterWordA
ImmUnregisterWordW
Yes
BOOL ImmUnregisterWord(
  _In_ HKL     hKL,
  _In_ LPCTSTR lpszReading,
  _In_ DWORD   dwStyle,
  _In_ LPCTSTR lpszUnregister
);
ImmWINNLSEnableIME No
ImmWINNLSGetEnableStatus No
ImmWINNLSGetIMEHotkey No

Documented Functions

ImmCreateContext

This calls NtUserCreateInputContext.

TODO

ImmGetContext

HIMC WINAPI ImmGetContext(HWND hWnd)

"The application must call ImmReleaseContext when it is finished with the input context[,]" says MSDN. However, given the behaviour of ImmReleaseContext, it really does nothing.

This performs a NULL check and then call ImmGetSaveContext(hWnd, 2).

ImmReleaseContext

BOOL WINAPI ImmReleaseContext(HWND hWnd, HIMC hIMC)

Always returns TRUE. (Just checked that even Windows 7 does this too.)

Undocumented Functions

ImmRegisterClient

int WINAPI ImmRegisterClient(_some_struct(size 0x3E) *arg1, HINSTANCE arg2);

This function doesn't really seem to register anything, but only initialize some variables. Something like:

  • gSharedInfo = *arg1;
  • gpsi = first byte of gSharedInfo;
  • return ImmInitializeGlobals(arg2);

This is called within user32.dll too.

ImmInitializeGlobals

int ImmInitializeGlobals(HINSTANCE arg1);

  • Stores arg1 to ghInst if not NULL
  • if not initialized already (gfInitialized == 0), then:
    • RtlInitializeCriticalSection(&gcsImeDpi)
    • gHighestUserAddress = SYSTEM_BASIC_INFORMATION.MaximumUserModeAddress (no idea what it is used for yet)
    • gfInitialized = 1
ImmGetSaveContext

HIMC __stdcall ImmGetSaveContext(HWND hWnd, char arg2);

  • If gpsi == 0 || !(gpsi->_byte_at_offset_2 & 8) then return NULL
  • If hWnd is NULL then get HIMC by NtUserGetThreadState(4)
  • Else:
    • Gets PWND by HMValidateHandle(hWnd, 1)
    • If window not owned by current process then return NULL
    • Gets HIMC from PWND->hImc
    • If NULL and arg2 has bit 0 set then try to get hIMC by NtUserQueryWindow(hWnd, 8)
  • _some_struct *ret = ImmLockClientImc(HIMC)
  • If ret is NULL then return NULL
  • If arg2 has bit 1 set and byte at offset 8 of ret has bit 7 set then ImmUnlockClientImc and return NULL
  • ImmUnlockClientImc and return HIMC

From this, it appears that each thread and window has its default IME context. It is possible that each window uses the context of the thread it is created in.

Also, debugging notepad shows that ImmCreateContext is never called to create them.

Kernel Functions

NtUserCreateInputContext

DWORD APIENTRY NtUserCreateInputContext(void *dwUnknown1);

From ImmCreateContext: return value of ImmLocalAlloc(8, 0x2c) is passed as the first parameter, so it is probably a pointer.

This appears to call EnterCrit and then call win32k!CreateInputContext.

TODO

CreateInputContext

int __stdcall CreateInputContext(void *arg1);

This is known to be called by NtUserCreateInputContext, and also by xxxCreateThreadInfo.

bd032cb4 a005df13 win32k!CreateInputContext
bd032d0c a005d594 win32k!xxxCreateThreadInfo+0x5d9
bd032d20 a005d4c7 win32k!UserThreadCallout+0x9d
bd032d3c 80496f4c win32k!W32pThreadCallout+0x3b
bd032d54 8046140e nt!PsConvertToGuiThread+0xad
bd032ddc 80465b62 nt!KiBBTUnexpectedRange+0xc
00000000 00000000 nt!KiThreadStartup+0x16

Seems that the thread IME context is created when a UI thread is created?

Not called when a window is created.

TODO

Loading of imm32.dll (XP)

IMM32 is loaded by user32.dll from _InitializeImmEntryTable. It loads the library (if not already) and fill in a structure of function pointers gImmApiEntries. This function is supposed to be called in the DllMain of USER32 but the relevant code is currently commented out.

In ReactOS, the related functions are located under win32ss\user\user32\misc\imm.c. The functions it loads is different from that of Windows XP.

A simple trace (some information is omitted) (hopefully I got it correct):

  • user32!DllMain
    • user32!_InitializeImmEntryTable
      • GetModuleHandle (and fail)
      • LoadLibrary(imm32.dll)
        • imm32!DllMain
          • imm32!ImmInitializeGlobals
          • user32!User32InitializeImmEntryTable
            • user32!_InitializeImmEntryTable
              • GetProcAddress and fill in the function table
            • imm32!ImmRegisterClient
              • imm32!ImmInitializeGlobals
    • imm32!ImmRegisterClient
      • imm32!ImmInitializeGlobals

TODO: Log all calls to Imm* functions with stack traces.

ReactOS

As of r67617, attempting to load IMM from user32 crashes:

Stack trace (click "Expand" to show):

f9af5b1c f9baa0e6 00000000 00000000 00000059 win32k!EngpCreatePDEV+0xf8 [d:\reactos\src\win32ss\gdi\eng\pdevobj.c @ 331]
f9af5b3c f9c2cc84 00000000 ffffffff 00000000 win32k!EngpGetPDEV+0x96 [d:\reactos\src\win32ss\gdi\eng\pdevobj.c @ 572]
f9af5b58 f9c2b515 00000000 00000000 00000000 win32k!GreOpenDCW+0x44 [d:\reactos\src\win32ss\gdi\ntgdi\dclife.c @ 641]
f9af5cec 80513ec9 00000000 00000000 00000000 win32k!NtGdiOpenDCW+0x1b5 [d:\reactos\src\win32ss\gdi\ntgdi\dclife.c @ 752]
f9af5d1c 80513a41 f9c2b360 0021edb8 00000020 nt!KiSystemCallTrampoline+0x19 [d:\reactos\src\ntoskrnl\include\internal\i386\ke.h @ 725]
f9af5d5c 80403e03 0021ee0c 7c92cf6e badb0d00 nt!KiSystemServiceHandler+0x221 [d:\reactos\src\ntoskrnl\ke\i386\traphdlr.c @ 1716]
f9af5d5c 7c92cf6e 0021ee0c 7c92cf6e badb0d00 nt!KiFastCallEntry+0x8c
0021edac 77bd7e47 77bb8b16 0021ede0 00000000 ntdll!KiFastSystemCallRet
0021edb0 77bb8b16 0021ede0 00000000 00000000 gdi32!ZwGdiOpenDCW+0xc
0021ee0c 77bb7648 00000000 00000000 00000001 gdi32!IntCreateDICW+0x1d6 [d:\reactos\src\win32ss\gdi\gdi32\objects\dc.c @ 69]
0021ee20 77a58455 77a92be8 00000000 00000000 gdi32!CreateICW+0x18 [d:\reactos\src\win32ss\gdi\gdi32\objects\dc.c @ 222]
0021ee98 77a5bc4c 77ad0d50 00000000 00000020 user32!LookupIconIdFromDirectoryEx+0x115 [d:\reactos\src\win32ss\user\user32\windows\cursoricon.c @ 2236]
0021ef6c 77a58298 77a20000 00007f00 00000020 user32!CURSORICON_LoadImageW+0x30c [d:\reactos\src\win32ss\user\user32\windows\cursoricon.c @ 1529]
0021ef94 77a57ef2 00000000 00007f00 00000002 user32!LoadImageW+0xd8 [d:\reactos\src\win32ss\user\user32\windows\cursoricon.c @ 2189]
0021efb4 75e26cd7 00000000 00007f00 00004000 user32!LoadCursorW+0x72 [d:\reactos\src\win32ss\user\user32\windows\cursoricon.c @ 2086]
0021efec 75e26d7f 00000001 0021f010 75e2994e IMM32!IMM_RegisterIMEClass+0x37 [d:\reactos\src\dll\win32\imm32\imm.c @ 390]
0021eff8 75e2994e 75e20000 00000001 00000000 IMM32!DllMain+0x8f [d:\reactos\src\dll\win32\imm32\imm.c @ 407]
0021f010 75e29a09 75e20000 00000001 00000000 IMM32!__DllMainCRTStartup+0xae [d:\reactos\src\lib\sdk\crt\startup\crtdll.c @ 201]
0021f024 7c928774 75e20000 00000001 00000000 IMM32!DllMainCRTStartup+0x29 [d:\reactos\src\lib\sdk\crt\startup\crtdll.c @ 171]
0021f038 7c925194 75e299e0 75e20000 00000001 ntdll!LdrpCallInitRoutine+0x14 [d:\reactos\src\dll\ntdll\ldr\ldrutils.c @ 217]
0021f0ec 7c928f6d 00000000 003a0043 0052005c ntdll!LdrpRunInitializeRoutines+0x434 [d:\reactos\src\dll\ntdll\ldr\ldrinit.c @ 814]
0021f330 7c9235b2 00000000 002249f0 0021f5ac ntdll!LdrpLoadDll+0x30d [d:\reactos\src\dll\ntdll\ldr\ldrutils.c @ 2580]
0021f57c 77d8a52e 002249f0 0021f5ac 0021f5a0 ntdll!LdrLoadDll+0x282 [d:\reactos\src\dll\ntdll\ldr\ldrapi.c @ 400]
0021f5dc 77d8a312 0021f5fc 00000000 00000000 kernel32!LoadLibraryExW+0x1ce [d:\reactos\src\dll\win32\kernel32\client\loader.c @ 366]
0021f5f0 77a4fe18 0021f5fc 003a0043 0052005c kernel32!LoadLibraryW+0x12 [d:\reactos\src\dll\win32\kernel32\client\loader.c @ 181]
0021f808 77a4f6f4 0021f944 77a4e000 19650412 user32!IntInitializeImmEntryTable+0xe8 [d:\reactos\src\win32ss\user\user32\misc\imm.c @ 86]
0021f810 77a4e000 19650412 00050000 00000000 user32!InitializeImmEntryTable+0x14 [d:\reactos\src\win32ss\user\user32\misc\imm.c @ 188]
0021f944 7c928774 77a20000 00000001 00000000 user32!DllMain+0xa0 [d:\reactos\src\win32ss\user\user32\misc\dllmain.c @ 536]
0021f958 7c925194 77a4df60 77a20000 00000001 ntdll!LdrpCallInitRoutine+0x14 [d:\reactos\src\dll\ntdll\ldr\ldrutils.c @ 217]
0021fa0c 7c928f6d 00000000 00690077 0073006e ntdll!LdrpRunInitializeRoutines+0x434 [d:\reactos\src\dll\ntdll\ldr\ldrinit.c @ 814]
0021fc50 7c9235b2 00000000 00000000 00000000 ntdll!LdrpLoadDll+0x30d [d:\reactos\src\dll\ntdll\ldr\ldrutils.c @ 2580]
0021fe9c 10005b87 00000000 00000000 0021fecc ntdll!LdrLoadDll+0x282 [d:\reactos\src\dll\ntdll\ldr\ldrapi.c @ 400]
0021fefc 1000448b 002209eb 002209f2 00000003 csrsrv!CsrLoadServerDll+0xa7 [d:\reactos\src\subsystems\win32\csrsrv\server.c @ 147]
0021ff5c 10002ba8 0000000a 00220f48 00000000 csrsrv!CsrParseServerCommandLine+0x4fb [d:\reactos\src\subsystems\win32\csrsrv\init.c @ 683]
0021ff70 004010a1 0000000a 00220f48 0000000d csrsrv!CsrServerInitialization+0x188 [d:\reactos\src\subsystems\win32\csrsrv\init.c @ 1013]
0021ff88 00401579 0000000a 00220f48 00220f74 csrss!_main+0x81 [d:\reactos\src\subsystems\win32\csrss\csrss.c @ 75]
0021fff4 00000000 7ffdf000 ec0100ed 00000000 csrss!NtProcessStartup+0x399 [d:\reactos\src\lib\sdk\nt\entry_point.c @ 199]

It seems to attempt to load a cursor on IMM_RegisterIMEClass which seems to cause problems in gdi code.

Perhaps IMM_RegisterIMEClass may not need to be called there?


Attempted to sync Wine 1.7.37 (CORE-9685), seems to not crash anymore.


Got most of the imm32 winetest running after hacks, but the test ends prematurely at line 1008 (on my local tree).