Skip to content

Instantly share code, notes, and snippets.

@peterooch
Created August 12, 2018 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save peterooch/7c21a884dc7cd2d7c669b2151c2420ad to your computer and use it in GitHub Desktop.
Save peterooch/7c21a884dc7cd2d7c669b2151c2420ad to your computer and use it in GitHub Desktop.
win32ss/gdi/gdi32/include/gdi32p.h | 5 +++++
win32ss/gdi/gdi32/main/dllmain.c | 1 +
win32ss/gdi/gdi32/misc/misc.c | 19 ++++++++++++++++---
win32ss/gdi/gdi32/objects/utils.c | 5 ++++-
win32ss/user/ntuser/simplecall.c | 11 +++++++++++
win32ss/user/user32/misc/stubs.c | 15 +++++++++++++--
6 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/win32ss/gdi/gdi32/include/gdi32p.h b/win32ss/gdi/gdi32/include/gdi32p.h
index 1b7c51856d..87dc81f025 100644
--- a/win32ss/gdi/gdi32/include/gdi32p.h
+++ b/win32ss/gdi/gdi32/include/gdi32p.h
@@ -66,6 +66,7 @@ extern LPKGCP LpkGetCharacterPlacement;
#define LPK_ETO 1
#define LPK_GCP 2
+#define LPK_INIT 3
/* MACRO ********************************************************************/
@@ -527,6 +528,10 @@ WINAPI
GdiRemoveClientObjLink(
_In_ HGDIOBJ hobj);
+VOID WINAPI GdiInitializeLanguagePack(DWORD InitParam);
+
+VOID WINAPI InitializeLpkHooks(FARPROC *hookfuncs);
+
extern ULONG gcClientObj;
VOID
diff --git a/win32ss/gdi/gdi32/main/dllmain.c b/win32ss/gdi/gdi32/main/dllmain.c
index 0e34df29db..b59dfbe421 100644
--- a/win32ss/gdi/gdi32/main/dllmain.c
+++ b/win32ss/gdi/gdi32/main/dllmain.c
@@ -51,6 +51,7 @@ GdiProcessSetup(VOID)
GdiHandleCache = (PGDIHANDLECACHE)NtCurrentTeb()->ProcessEnvironmentBlock->GdiHandleBuffer;
RtlInitializeCriticalSection(&semLocal);
InitializeCriticalSection(&gcsClientObjLinks);
+ GdiInitializeLanguagePack(0);
}
VOID
diff --git a/win32ss/gdi/gdi32/misc/misc.c b/win32ss/gdi/gdi32/misc/misc.c
index 6675e7335c..b01fb5a8cd 100644
--- a/win32ss/gdi/gdi32/misc/misc.c
+++ b/win32ss/gdi/gdi32/misc/misc.c
@@ -1021,12 +1021,25 @@ GdiRealizationInfo(HDC hdc,
/*
- * @unimplemented
+ * @halfmplemented
*/
VOID WINAPI GdiInitializeLanguagePack(DWORD InitParam)
{
- UNIMPLEMENTED;
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+#ifdef LANGPACK
+ if (!LoadLPK(LPK_INIT)) // no lpk found!
+#endif
+ return;
+
+ /* Should call InitializeLpkHooks with several procedure addresses
+ loaded from lpk.dll but none of them are currently implemented.
+ Then InitializeLpkHooks (in user32) does something with these
+ and ORs a DWORD being used also by ClientThreadSetup and calls
+ NtUserOneParam with parameter 54 which is ONEPARAM_ROUTINE_REGISTERLPK
+ which most likely changes the value of dwLpkEntryPoints in the
+ PROCESSINFO struct */
+
+ gbLpk = TRUE;
+ InitializeLpkHooks(NULL);
}
BOOL
diff --git a/win32ss/gdi/gdi32/objects/utils.c b/win32ss/gdi/gdi32/objects/utils.c
index 432c6e1482..3c4ad05929 100644
--- a/win32ss/gdi/gdi32/objects/utils.c
+++ b/win32ss/gdi/gdi32/objects/utils.c
@@ -417,7 +417,7 @@ EnumLogFontExW2A( LPENUMLOGFONTEXA fontA, CONST ENUMLOGFONTEXW *fontW )
* LPK.DLL loader function
*
* Returns TRUE if a valid parameter was passed and loading was successful,
-* retruns FALSE otherwise.
+* returns FALSE otherwise.
*/
BOOL WINAPI LoadLPK(INT LpkFunctionID)
{
@@ -452,6 +452,9 @@ BOOL WINAPI LoadLPK(INT LpkFunctionID)
return TRUE;
+ case LPK_INIT:
+ return TRUE;
+
default:
FreeLibrary(hLpk);
return FALSE;
diff --git a/win32ss/user/ntuser/simplecall.c b/win32ss/user/ntuser/simplecall.c
index c7ad21fca0..27342be318 100644
--- a/win32ss/user/ntuser/simplecall.c
+++ b/win32ss/user/ntuser/simplecall.c
@@ -402,6 +402,17 @@ NtUserCallOneParam(
Result = (DWORD_PTR)IntAllowSetForegroundWindow(Param);
break;
+ case ONEPARAM_ROUTINE_REGISTERLPK:
+ {
+ PPROCESSINFO ppi;
+
+ ppi = PsGetCurrentProcessWin32Process();
+ ppi->dwLpkEntryPoints = Param;
+ Result = TRUE;
+
+ break;
+ }
+
default:
ERR("Calling invalid routine number 0x%x in NtUserCallOneParam(), Param=0x%x\n",
Routine, Param);
diff --git a/win32ss/user/user32/misc/stubs.c b/win32ss/user/user32/misc/stubs.c
index b73397d44b..4122244c65 100644
--- a/win32ss/user/user32/misc/stubs.c
+++ b/win32ss/user/user32/misc/stubs.c
@@ -416,11 +416,22 @@ BOOL WINAPI EnterReaderModeHelper(HWND hwnd)
}
/*
- * @unimplemented
+ * @halfmplemented
*/
VOID WINAPI InitializeLpkHooks(FARPROC *hookfuncs)
{
- UNIMPLEMENTED;
+ DWORD dwLpkEntryPoints = 4L;
+
+ /* By looking via IDA, this function tests for 4 function procedures and ORs a global DWORD:
+ Function name Assumed Purpose
+ LpkTabbedTextOut, TabbedTextOutA/W ,
+ LpkPSMTextOut, (?) Used by DrawStateW, static controls in user32, menu draw in win32k
+ LpkDrawTextEx, DrawTextEx with BiDi support (somewhat implemented)
+ LpkEditControl, Edit control (which already has full BiDi via usp10)
+ each valid procedure ORs the DWORD with 1, 2, 4, 8 respectively
+ Then ClientThreadSetup checks the value of the DWORD and calls the following call */
+
+ NtUserCallOneParam(dwLpkEntryPoints, ONEPARAM_ROUTINE_REGISTERLPK);
}
/*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment