Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

client.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: client.c 00003 * 00004 * Client/Server call related routines. 00005 * 00006 * Copyright (c) 1985 - 1999, Microsoft Corporation 00007 * 00008 * History: 00009 * 04-Dec-1990 SMeans Created. 00010 \**************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 #include "kbd.h" 00016 00017 /* 00018 * NOTE -- this table must match the FNID list in user.h. It provides a WOWCLASS for each FNID. 00019 */ 00020 00021 int aiClassWow[] = { 00022 WOWCLASS_SCROLLBAR, 00023 WOWCLASS_ICONTITLE, 00024 WOWCLASS_MENU, 00025 WOWCLASS_DESKTOP, 00026 WOWCLASS_WIN16, 00027 WOWCLASS_BUTTON, 00028 WOWCLASS_COMBOBOX, 00029 WOWCLASS_COMBOLBOX, 00030 WOWCLASS_DIALOG, 00031 WOWCLASS_EDIT, 00032 WOWCLASS_LISTBOX, 00033 WOWCLASS_MDICLIENT, 00034 WOWCLASS_STATIC, 00035 WOWCLASS_WIN16, // 2A7 00036 WOWCLASS_WIN16, 00037 WOWCLASS_WIN16, 00038 WOWCLASS_WIN16, 00039 WOWCLASS_WIN16, 00040 WOWCLASS_WIN16, 00041 WOWCLASS_WIN16, 00042 WOWCLASS_WIN16, 00043 WOWCLASS_WIN16, // 2b0 00044 WOWCLASS_WIN16, 00045 WOWCLASS_WIN16, 00046 WOWCLASS_WIN16, 00047 WOWCLASS_SWITCHWND 00048 00049 }; 00050 00051 HBITMAP WOWLoadBitmapA(HINSTANCE hmod, LPCSTR lpName, LPBYTE pResData, DWORD cbResData); 00052 HMENU WowServerLoadCreateMenu(HANDLE hMod, LPTSTR lpName, CONST LPMENUTEMPLATE pmt, 00053 DWORD cb, BOOL fCallClient); 00054 DWORD GetFullUserHandle(WORD wHandle); 00055 00056 UINT GetClipboardCodePage(LCID, LCTYPE); 00057 00058 extern HANDLE WOWFindResourceExWCover(HANDLE hmod, LPCWSTR rt, LPCWSTR lpUniName, WORD LangId); 00059 00060 extern BOOL APIENTRY EnableEUDC(); 00061 00062 CONST WCHAR szKLKey[] = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Keyboard Layouts\\"; 00063 CONST WCHAR szKLFile[] = L"Layout File"; 00064 CONST WCHAR szKLAttributes[] = L"Attributes"; 00065 CONST WCHAR szKLId[] = L"Layout ID"; 00066 #define NSZKLKEY (sizeof szKLKey + 16) 00067 00068 00069 CONST LPWSTR pwszKLLibSafety = L"kbdus.dll"; 00070 CONST UINT wKbdLocaleSafety = 0x04090409; 00071 CONST LPWSTR pwszKLLibSafetyJPN = L"kbdjpn.dll"; 00072 CONST UINT wKbdLocaleSafetyJPN = 0x04110411; 00073 CONST LPWSTR pwszKLLibSafetyKOR = L"kbdkor.dll"; 00074 CONST UINT wKbdLocaleSafetyKOR = 0x04120412; 00075 00076 #define CCH_KL_LIBNAME 256 00077 #define CCH_KL_ID 16 00078 00079 BOOL gfLogonProcess; 00080 00081 UNICODE_STRING strRootDirectory; 00082 00083 VOID CheckValidLayoutName( LPWSTR lpszName ); 00084 00085 BOOL WOWModuleUnload(HANDLE hModule) { 00086 return (BOOL)NtUserCallOneParam((ULONG_PTR)hModule, 00087 SFI__WOWMODULEUNLOAD); 00088 } 00089 00090 BOOL WOWCleanup(HANDLE hInstance, DWORD hTaskWow) { 00091 return (BOOL)NtUserCallTwoParam((ULONG_PTR)hInstance, 00092 (ULONG_PTR)hTaskWow, 00093 SFI__WOWCLEANUP); 00094 } 00095 00096 00097 /***************************************************************************\ 00098 * BringWindowToTop (API) 00099 * 00100 * 00101 * History: 00102 * 11-Jul-1991 DarrinM Ported from Win 3.1 sources. 00103 \***************************************************************************/ 00104 00105 BOOL BringWindowToTop( 00106 HWND hwnd) 00107 { 00108 return NtUserSetWindowPos(hwnd, 00109 HWND_TOP, 00110 0, 00111 0, 00112 0, 00113 0, 00114 SWP_NOSIZE | SWP_NOMOVE); 00115 } 00116 00117 HWND ChildWindowFromPoint( 00118 HWND hwndParent, 00119 POINT point) 00120 { 00121 /* 00122 * Cool Hack Alert... Corel Ventura 5.0 00123 * Dies after it calls ChildWindowFromPoint, and 00124 * the combobox doesn't have its edit window at 1,1... 00125 */ 00126 if ((point.x == 1) && (point.y == 1)) { 00127 PCBOX pcCombo; 00128 PWND pwnd; 00129 00130 pwnd = ValidateHwnd(hwndParent); 00131 if (pwnd == NULL) 00132 return NULL; 00133 00134 if (!TestWF(pwnd, WFWIN40COMPAT) && 00135 GETFNID(pwnd) == FNID_COMBOBOX && 00136 TestWindowProcess(pwnd) && 00137 ((pcCombo = ((PCOMBOWND)pwnd)->pcbox) != NULL) && 00138 !(pcCombo->fNoEdit)) { 00139 00140 RIPMSG0(RIP_WARNING, "ChildWindowFromPoint: Combobox @1,1. Returning spwndEdit"); 00141 return HWq(pcCombo->spwndEdit); 00142 } 00143 00144 } 00145 00146 return NtUserChildWindowFromPointEx(hwndParent, point, 0); 00147 } 00148 00149 00150 HICON CopyIcon( 00151 HICON hicon) 00152 { 00153 HICON hIconT = NULL; 00154 ICONINFO ii; 00155 00156 if (GetIconInfo(hicon, &ii)) { 00157 hIconT = CreateIconIndirect(&ii); 00158 00159 DeleteObject(ii.hbmMask); 00160 00161 if (ii.hbmColor != NULL) 00162 DeleteObject(ii.hbmColor); 00163 } 00164 00165 return hIconT; 00166 } 00167 00168 /***************************************************************************\ 00169 * AdjustWindowRect (API) 00170 * 00171 * History: 00172 * 01-Jul-1991 MikeKe Created. 00173 \***************************************************************************/ 00174 00175 BOOL WINAPI AdjustWindowRect( 00176 LPRECT lprc, 00177 DWORD style, 00178 BOOL fMenu) 00179 { 00180 ConnectIfNecessary(); 00181 00182 return _AdjustWindowRectEx(lprc, style, fMenu, 0L); 00183 } 00184 00185 /***************************************************************************\ 00186 * TranslateAcceleratorA/W 00187 * 00188 * Put here so we can check for NULL on client side, and before validation 00189 * for both DOS and NT cases. 00190 * 00191 * 05-29-91 ScottLu Created. 00192 * 01-05-93 IanJa Unicode/ANSI. 00193 \***************************************************************************/ 00194 00195 int WINAPI TranslateAcceleratorW( 00196 HWND hwnd, 00197 HACCEL hAccel, 00198 LPMSG lpMsg) 00199 { 00200 /* 00201 * NULL pwnd is a valid case - since this is called from the center 00202 * of main loops, pwnd == NULL happens all the time, and we shouldn't 00203 * generate a warning because of it. 00204 */ 00205 if (hwnd == NULL) 00206 return FALSE; 00207 00208 /* 00209 * We only need to pass key-down messages to the server, 00210 * everything else ends up returning 0/FALSE from this function. 00211 */ 00212 switch (lpMsg->message) { 00213 00214 case WM_KEYDOWN: 00215 case WM_SYSKEYDOWN: 00216 case WM_CHAR: 00217 case WM_SYSCHAR: 00218 return NtUserTranslateAccelerator(hwnd, hAccel, lpMsg); 00219 00220 default: 00221 return 0; 00222 } 00223 } 00224 00225 int WINAPI TranslateAcceleratorA( 00226 HWND hwnd, 00227 HACCEL hAccel, 00228 LPMSG lpMsg) 00229 { 00230 WPARAM wParamT; 00231 int iT; 00232 00233 /* 00234 * NULL pwnd is a valid case - since this is called from the center 00235 * of main loops, pwnd == NULL happens all the time, and we shouldn't 00236 * generate a warning because of it. 00237 */ 00238 if (hwnd == NULL) 00239 return FALSE; 00240 00241 /* 00242 * We only need to pass key-down messages to the server, 00243 * everything else ends up returning 0/FALSE from this function. 00244 */ 00245 switch (lpMsg->message) { 00246 00247 case WM_KEYDOWN: 00248 case WM_SYSKEYDOWN: 00249 case WM_CHAR: 00250 case WM_SYSCHAR: 00251 wParamT = lpMsg->wParam; 00252 RtlMBMessageWParamCharToWCS(lpMsg->message, &(lpMsg->wParam)); 00253 iT = NtUserTranslateAccelerator(hwnd, hAccel, lpMsg); 00254 lpMsg->wParam = wParamT; 00255 return iT; 00256 00257 default: 00258 return 0; 00259 } 00260 } 00261 00262 /***************************************************************************\ 00263 * Clipboard functions 00264 * 00265 * 11-Oct-1991 mikeke Created. 00266 \***************************************************************************/ 00267 00268 typedef struct _HANDLENODE { 00269 struct _HANDLENODE *pnext; 00270 UINT fmt; 00271 HANDLE handleServer; 00272 HANDLE handleClient; 00273 BOOL fGlobalHandle; 00274 } HANDLENODE; 00275 typedef HANDLENODE *PHANDLENODE; 00276 00277 PHANDLENODE gphn = NULL; 00278 00279 /***************************************************************************\ 00280 * DeleteClientClipboardHandle 00281 * 00282 * 11-Oct-1991 MikeKe Created. 00283 \***************************************************************************/ 00284 00285 BOOL DeleteClientClipboardHandle( 00286 PHANDLENODE phn) 00287 { 00288 LPMETAFILEPICT lpMFP; 00289 00290 UserAssert(phn->handleClient != (HANDLE)0); 00291 00292 switch (phn->fmt) { 00293 case CF_BITMAP: 00294 case CF_DSPBITMAP: 00295 case CF_PALETTE: 00296 // Does nothing (should remove). 00297 // 00298 //GdiDeleteLocalObject((ULONG)hobjDelete); 00299 break; 00300 00301 case CF_METAFILEPICT: 00302 case CF_DSPMETAFILEPICT: 00303 USERGLOBALLOCK(phn->handleClient, lpMFP); 00304 if (lpMFP) { 00305 DeleteMetaFile(lpMFP->hMF); 00306 USERGLOBALUNLOCK(phn->handleClient); 00307 UserGlobalFree(phn->handleClient); 00308 } else { 00309 RIPMSG1(RIP_ERROR,"DeleteClientClipboardHandle, can't lock client handle %#p\n",phn->handleClient); 00310 return FALSE; 00311 } 00312 break; 00313 00314 case CF_ENHMETAFILE: 00315 case CF_DSPENHMETAFILE: 00316 DeleteEnhMetaFile((HENHMETAFILE)phn->handleClient); 00317 break; 00318 00319 default: 00320 //case CF_TEXT: 00321 //case CF_OEMTEXT: 00322 //case CF_UNICODETEXT: 00323 //case CF_LOCALE: 00324 //case CF_DSPTEXT: 00325 //case CF_DIB: 00326 //case CF_DIBV5: 00327 if (phn->fGlobalHandle) { 00328 if (UserGlobalFree(phn->handleClient)) { 00329 RIPMSG1(RIP_WARNING, "CloseClipboard UserGlobalFree(%#p) Failed\n", phn->handleClient); 00330 return FALSE; 00331 } 00332 } else { 00333 UserAssert(GlobalFlags(phn->handleClient) == GMEM_INVALID_HANDLE); 00334 } 00335 break; 00336 } 00337 00338 /* 00339 * Deleted successfully 00340 */ 00341 return TRUE; 00342 00343 } 00344 00345 /***************************************************************************\ 00346 * ClientEmptyClipboard 00347 * 00348 * Empties the client side clipboard list. 00349 * 00350 * 01-15-93 ScottLu Created. 00351 \***************************************************************************/ 00352 00353 void ClientEmptyClipboard(void) 00354 { 00355 PHANDLENODE phnNext; 00356 PHANDLENODE phnT; 00357 00358 RtlEnterCriticalSection(&gcsClipboard); 00359 00360 phnT = gphn; 00361 while (phnT != NULL) { 00362 phnNext = phnT->pnext; 00363 00364 if (phnT->handleClient != (HANDLE)0) 00365 DeleteClientClipboardHandle(phnT); 00366 00367 LocalFree(phnT); 00368 00369 phnT = phnNext; 00370 } 00371 gphn = NULL; 00372 00373 /* 00374 * Tell wow to cleanup it's clipboard stuff 00375 */ 00376 if (pfnWowEmptyClipBoard) { 00377 pfnWowEmptyClipBoard(); 00378 } 00379 00380 RtlLeaveCriticalSection(&gcsClipboard); 00381 } 00382 00383 00384 /***************************************************************************\ 00385 * GetClipboardData 00386 * 00387 * 11-Oct-1991 mikeke Created. 00388 \***************************************************************************/ 00389 00390 HANDLE WINAPI GetClipboardData( 00391 UINT uFmt) 00392 { 00393 HANDLE handleClient; 00394 HANDLE handleServer; 00395 PHANDLENODE phn; 00396 PHANDLENODE phnNew; 00397 GETCLIPBDATA gcd; 00398 00399 /* 00400 * Get the Server's Data; return if there is no data. 00401 */ 00402 if (!(handleServer = NtUserGetClipboardData(uFmt, &gcd))) 00403 return (HANDLE)NULL; 00404 00405 /* 00406 * Handle any translation that must be done for text items. The 00407 * format returned will only differ for text items. Metafile and 00408 * Enhanced-Metafiles are handled through GDI for their converstions. 00409 * And Bitmap color space convertion also nessesary for CF_BITMAP, 00410 * CF_DIB and CF_DIBV5 with color space. 00411 */ 00412 if (uFmt != gcd.uFmtRet) { 00413 00414 LPBYTE lpSrceData = NULL; 00415 LPBYTE lpDestData = NULL; 00416 LPBYTE lptData = NULL; 00417 LPDWORD lpLocale; 00418 DWORD uLocale; 00419 int iSrce; 00420 int iDest; 00421 UINT uCPage; 00422 SETCLIPBDATA scd; 00423 UINT cbNULL = 0; 00424 00425 /* 00426 * Make sure handleServer is server-side memory handle 00427 */ 00428 if ((gcd.uFmtRet == CF_TEXT) || (gcd.uFmtRet == CF_OEMTEXT) || 00429 (gcd.uFmtRet == CF_UNICODETEXT) || 00430 (gcd.uFmtRet == CF_DIB) || (gcd.uFmtRet == CF_DIBV5)) { 00431 00432 lpSrceData = CreateLocalMemHandle(handleServer); 00433 00434 /* 00435 * Allocate space for the converted TEXT data. 00436 */ 00437 if (!(iSrce = (UINT)GlobalSize(lpSrceData))) 00438 goto AbortDummyHandle; 00439 00440 /* 00441 * Only CF_xxxTEXT may have locale information. 00442 */ 00443 if ((gcd.uFmtRet == CF_TEXT) || (gcd.uFmtRet == CF_OEMTEXT) || 00444 (gcd.uFmtRet == CF_UNICODETEXT)) { 00445 00446 /* 00447 * Get the locale out of the parameter-struct. We will 00448 * use this to get the codepage for text-translation. 00449 */ 00450 if (lpLocale = (LPDWORD)CreateLocalMemHandle(gcd.hLocale)) { 00451 00452 uLocale = *lpLocale; 00453 GlobalFree(lpLocale); 00454 } else { 00455 uLocale = 0; 00456 } 00457 00458 /* 00459 * And also, pre-allocate translated buffer in same size as source. 00460 */ 00461 if ((lpDestData = GlobalAlloc(LPTR, iSrce)) == NULL) { 00462 goto AbortDummyHandle; 00463 } 00464 } 00465 00466 switch (uFmt) { 00467 case CF_TEXT: 00468 cbNULL = 1; 00469 if (gcd.uFmtRet == CF_OEMTEXT) { 00470 00471 /* 00472 * CF_OEMTEXT --> CF_TEXT conversion 00473 */ 00474 OemToAnsi((LPSTR)lpSrceData, (LPSTR)lpDestData); 00475 } else { 00476 00477 uCPage = GetClipboardCodePage(uLocale, 00478 LOCALE_IDEFAULTANSICODEPAGE); 00479 00480 /* 00481 * CF_UNICODETEXT --> CF_TEXT conversion 00482 */ 00483 iDest = 0; 00484 if ((iDest = WideCharToMultiByte(uCPage, 00485 (DWORD)0, 00486 (LPWSTR)lpSrceData, 00487 (int)(iSrce / sizeof(WCHAR)), 00488 (LPSTR)NULL, 00489 (int)iDest, 00490 (LPSTR)NULL, 00491 (LPBOOL)NULL)) == 0) { 00492 AbortGetClipData: 00493 UserGlobalFree(lpDestData); 00494 AbortDummyHandle: 00495 UserGlobalFree(lpSrceData); 00496 return NULL; 00497 } 00498 00499 if (!(lptData = GlobalReAlloc( lpDestData, iDest, LPTR | LMEM_MOVEABLE))) 00500 goto AbortGetClipData; 00501 00502 lpDestData = lptData; 00503 00504 if (WideCharToMultiByte(uCPage, 00505 (DWORD)0, 00506 (LPWSTR)lpSrceData, 00507 (int)(iSrce / sizeof(WCHAR)), 00508 (LPSTR)lpDestData, 00509 (int)iDest, 00510 (LPSTR)NULL, 00511 (LPBOOL)NULL) == 0) 00512 goto AbortGetClipData; 00513 } 00514 break; 00515 00516 case CF_OEMTEXT: 00517 cbNULL = 1; 00518 if (gcd.uFmtRet == CF_TEXT) { 00519 00520 /* 00521 * CF_TEXT --> CF_OEMTEXT conversion 00522 */ 00523 AnsiToOem((LPSTR)lpSrceData, (LPSTR)lpDestData); 00524 } else { 00525 00526 uCPage = GetClipboardCodePage(uLocale, 00527 LOCALE_IDEFAULTCODEPAGE); 00528 00529 /* 00530 * CF_UNICODETEXT --> CF_OEMTEXT conversion 00531 */ 00532 iDest = 0; 00533 if ((iDest = WideCharToMultiByte(uCPage, 00534 (DWORD)0, 00535 (LPWSTR)lpSrceData, 00536 (int)(iSrce / sizeof(WCHAR)), 00537 (LPSTR)NULL, 00538 (int)iDest, 00539 (LPSTR)NULL, 00540 (LPBOOL)NULL)) == 0) 00541 goto AbortGetClipData; 00542 00543 if (!(lptData = GlobalReAlloc( lpDestData, iDest, LPTR | LMEM_MOVEABLE))) 00544 goto AbortGetClipData; 00545 00546 lpDestData = lptData; 00547 00548 if (WideCharToMultiByte(uCPage, 00549 (DWORD)0, 00550 (LPWSTR)lpSrceData, 00551 (int)(iSrce / sizeof(WCHAR)), 00552 (LPSTR)lpDestData, 00553 (int)iDest, 00554 (LPSTR)NULL, 00555 (LPBOOL)NULL) == 0) 00556 goto AbortGetClipData; 00557 } 00558 break; 00559 00560 case CF_UNICODETEXT: 00561 cbNULL = 2; 00562 if (gcd.uFmtRet == CF_TEXT) { 00563 00564 uCPage = GetClipboardCodePage(uLocale, 00565 LOCALE_IDEFAULTANSICODEPAGE); 00566 00567 /* 00568 * CF_TEXT --> CF_UNICODETEXT conversion 00569 */ 00570 iDest = 0; 00571 if ((iDest = MultiByteToWideChar(uCPage, 00572 (DWORD)MB_PRECOMPOSED, 00573 (LPSTR)lpSrceData, 00574 (int)iSrce, 00575 (LPWSTR)NULL, 00576 (int)iDest)) == 0) 00577 goto AbortGetClipData; 00578 00579 if (!(lptData = GlobalReAlloc(lpDestData, 00580 iDest * sizeof(WCHAR), LPTR | LMEM_MOVEABLE))) 00581 goto AbortGetClipData; 00582 00583 lpDestData = lptData; 00584 00585 if (MultiByteToWideChar(uCPage, 00586 (DWORD)MB_PRECOMPOSED, 00587 (LPSTR)lpSrceData, 00588 (int)iSrce, 00589 (LPWSTR)lpDestData, 00590 (int)iDest) == 0) 00591 goto AbortGetClipData; 00592 00593 } else { 00594 00595 uCPage = GetClipboardCodePage(uLocale, 00596 LOCALE_IDEFAULTCODEPAGE); 00597 00598 /* 00599 * CF_OEMTEXT --> CF_UNICDOETEXT conversion 00600 */ 00601 iDest = 0; 00602 if ((iDest = MultiByteToWideChar(uCPage, 00603 (DWORD)MB_PRECOMPOSED, 00604 (LPSTR)lpSrceData, 00605 (int)iSrce, 00606 (LPWSTR)NULL, 00607 (int)iDest)) == 0) 00608 goto AbortGetClipData; 00609 00610 if (!(lptData = GlobalReAlloc(lpDestData, 00611 iDest * sizeof(WCHAR), LPTR | LMEM_MOVEABLE))) 00612 goto AbortGetClipData; 00613 00614 lpDestData = lptData; 00615 00616 if (MultiByteToWideChar(uCPage, 00617 (DWORD)MB_PRECOMPOSED, 00618 (LPSTR)lpSrceData, 00619 (int)iSrce, 00620 (LPWSTR)lpDestData, 00621 (int)iDest) == 0) 00622 goto AbortGetClipData; 00623 } 00624 break; 00625 00626 case CF_BITMAP: 00627 if (gcd.uFmtRet == CF_DIBV5) { 00628 00629 /* 00630 * CF_DIBV5 --> CF_BITMAP (sRGB) 00631 * 00632 * The GDI bitmap handle will be returned in handleServer. 00633 */ 00634 if ((handleServer = GdiConvertBitmapV5(lpSrceData,iSrce, 00635 gcd.hPalette,CF_BITMAP)) == NULL) { 00636 00637 /* 00638 * GDI failed to convert. 00639 */ 00640 RIPMSG0(RIP_ERROR, "GetClipboardData: Failed CF_DIBV5 -> CF_BITMAP\n"); 00641 goto AbortDummyHandle; 00642 } 00643 } else { 00644 00645 RIPMSG0(RIP_ERROR, "GetClipboardData: bad conversion request\n"); 00646 goto AbortDummyHandle; 00647 } 00648 break; 00649 00650 case CF_DIB: 00651 if (gcd.uFmtRet == CF_DIBV5) { 00652 00653 /* 00654 * CF_DIBV5 --> CF_DIB (sRGB) 00655 * 00656 * The local memory handle will be returned in lpDestData. 00657 */ 00658 if ((lpDestData = (LPBYTE) GdiConvertBitmapV5(lpSrceData,iSrce, 00659 gcd.hPalette,CF_DIB)) == NULL) { 00660 00661 /* 00662 * GDI failed to convert. 00663 */ 00664 RIPMSG0(RIP_ERROR, "GetClipboardData: Failed CF_DIBV5 -> CF_DIB\n"); 00665 goto AbortDummyHandle; 00666 } 00667 } else { 00668 00669 RIPMSG0(RIP_ERROR, "GetClipboardData: bad conversion request\n"); 00670 goto AbortDummyHandle; 00671 } 00672 break; 00673 } 00674 } 00675 00676 if (lpDestData) { 00677 /* 00678 * Replace the dummy user-mode memory handle with the actual handle. 00679 */ 00680 handleServer = ConvertMemHandle(lpDestData, cbNULL); 00681 if (handleServer == NULL) 00682 goto AbortGetClipData; 00683 } 00684 00685 /* 00686 * Update the server. If that is successfull update the client 00687 */ 00688 RtlEnterCriticalSection(&gcsClipboard); 00689 scd.fGlobalHandle = gcd.fGlobalHandle; 00690 scd.fIncSerialNumber = FALSE; 00691 if (!NtUserSetClipboardData(uFmt, handleServer, &scd)) { 00692 handleServer = NULL; 00693 } 00694 RtlLeaveCriticalSection(&gcsClipboard); 00695 00696 if (lpDestData) 00697 UserGlobalFree(lpDestData); 00698 if (lpSrceData) 00699 UserGlobalFree(lpSrceData); 00700 00701 if (handleServer == NULL) 00702 return NULL; 00703 } 00704 00705 /* 00706 * See if we already have a client side handle; validate the format 00707 * as well because some server objects, metafile for example, are dual mode 00708 * and yield two kinds of client objects enhanced and regular metafiles 00709 */ 00710 handleClient = NULL; 00711 RtlEnterCriticalSection(&gcsClipboard); 00712 00713 phn = gphn; 00714 while (phn) { 00715 if ((phn->handleServer == handleServer) && (phn->fmt == uFmt)) { 00716 handleClient = phn->handleClient; 00717 goto Exit; 00718 } 00719 phn = phn->pnext; 00720 } 00721 00722 /* 00723 * We don't have a handle cached so we'll create one 00724 */ 00725 phnNew = (PHANDLENODE)LocalAlloc(LPTR, sizeof(HANDLENODE)); 00726 if (phnNew == NULL) 00727 goto Exit; 00728 00729 phnNew->handleServer = handleServer; 00730 phnNew->fmt = gcd.uFmtRet; 00731 phnNew->fGlobalHandle = gcd.fGlobalHandle; 00732 00733 switch (uFmt) { 00734 00735 /* 00736 * Misc GDI Handles 00737 */ 00738 case CF_BITMAP: 00739 case CF_DSPBITMAP: 00740 case CF_PALETTE: 00741 phnNew->handleClient = handleServer; 00742 break; 00743 00744 case CF_METAFILEPICT: 00745 case CF_DSPMETAFILEPICT: 00746 phnNew->handleClient = GdiCreateLocalMetaFilePict(handleServer); 00747 break; 00748 00749 case CF_ENHMETAFILE: 00750 case CF_DSPENHMETAFILE: 00751 phnNew->handleClient = GdiCreateLocalEnhMetaFile(handleServer); 00752 break; 00753 00754 /* 00755 * GlobalHandle Cases 00756 */ 00757 case CF_TEXT: 00758 case CF_OEMTEXT: 00759 case CF_UNICODETEXT: 00760 case CF_LOCALE: 00761 case CF_DSPTEXT: 00762 case CF_DIB: 00763 case CF_DIBV5: 00764 phnNew->handleClient = CreateLocalMemHandle(handleServer); 00765 phnNew->fGlobalHandle = TRUE; 00766 break; 00767 00768 default: 00769 /* 00770 * Private Data Format; If this is global data, create a copy of that 00771 * data here on the client. If it isn't global data, it is just a dword 00772 * in which case we just return a dword. If it is global data and 00773 * the server fails to give us that memory, return NULL. If it isn't 00774 * global data, handleClient is just a dword. 00775 */ 00776 if (phnNew->fGlobalHandle) { 00777 phnNew->handleClient = CreateLocalMemHandle(handleServer); 00778 } else { 00779 phnNew->handleClient = handleServer; 00780 } 00781 break; 00782 } 00783 00784 if (phnNew->handleClient == NULL) { 00785 /* 00786 * Something bad happened, gdi didn't give us back a 00787 * handle. Since gdi has logged the error, we'll just 00788 * clean up and return an error. 00789 */ 00790 RIPMSG1(RIP_WARNING, "GetClipboardData unable to convert server handle %#p to client handle\n", handleServer); 00791 00792 LocalFree(phnNew); 00793 goto Exit; 00794 } 00795 00796 #if DBG 00797 /* 00798 * If handleClient came from a GlobalAlloc, then fGlobalHandle must be TRUE. 00799 * Some formats are acutally global handles but require special cleanup. 00800 */ 00801 switch (phnNew->fmt) { 00802 case CF_METAFILEPICT: 00803 case CF_DSPMETAFILEPICT: 00804 break; 00805 00806 default: 00807 UserAssert(phnNew->fGlobalHandle 00808 ^ (GlobalFlags(phnNew->handleClient) == GMEM_INVALID_HANDLE)); 00809 break; 00810 } 00811 #endif 00812 00813 /* 00814 * Cache the new handle by linking it into our list 00815 */ 00816 phnNew->pnext = gphn; 00817 gphn = phnNew; 00818 handleClient = phnNew->handleClient; 00819 00820 Exit: 00821 RtlLeaveCriticalSection(&gcsClipboard); 00822 return handleClient; 00823 } 00824 00825 /***************************************************************************\ 00826 * GetClipboardCodePage (internal) 00827 * 00828 * This routine returns the code-page associated with the given locale. 00829 * 00830 * 24-Aug-1995 ChrisWil Created. 00831 \***************************************************************************/ 00832 00833 #define GETCCP_SIZE 8 00834 00835 UINT GetClipboardCodePage( 00836 LCID uLocale, 00837 LCTYPE uLocaleType) 00838 { 00839 WCHAR wszCodePage[GETCCP_SIZE]; 00840 DWORD uCPage; 00841 00842 if (GetLocaleInfoW(uLocale, uLocaleType, wszCodePage, GETCCP_SIZE)) { 00843 00844 uCPage = (UINT)wcstol(wszCodePage, NULL, 10); 00845 00846 } else { 00847 00848 switch(uLocaleType) { 00849 00850 case LOCALE_IDEFAULTCODEPAGE: 00851 uCPage = CP_OEMCP; 00852 break; 00853 00854 case LOCALE_IDEFAULTANSICODEPAGE: 00855 uCPage = CP_ACP; 00856 break; 00857 00858 default: 00859 uCPage = CP_MACCP; 00860 break; 00861 } 00862 } 00863 00864 return uCPage; 00865 } 00866 00867 /***************************************************************************\ 00868 * SetClipboardData 00869 * 00870 * Stub routine needs to exist on the client side so any global data gets 00871 * allocated DDESHARE. 00872 * 00873 * 05-20-91 ScottLu Created. 00874 \***************************************************************************/ 00875 00876 HANDLE WINAPI SetClipboardData( 00877 UINT wFmt, 00878 HANDLE hMem) 00879 { 00880 PHANDLENODE phnNew; 00881 HANDLE hServer = NULL; 00882 SETCLIPBDATA scd; 00883 BOOL fGlobalHandle = FALSE; 00884 00885 if (hMem != NULL) { 00886 00887 switch(wFmt) { 00888 00889 case CF_BITMAP: 00890 case CF_DSPBITMAP: 00891 case CF_PALETTE: 00892 hServer = hMem; 00893 break; 00894 00895 case CF_METAFILEPICT: 00896 case CF_DSPMETAFILEPICT: 00897 hServer = GdiConvertMetaFilePict(hMem); 00898 break; 00899 00900 case CF_ENHMETAFILE: 00901 case CF_DSPENHMETAFILE: 00902 hServer = GdiConvertEnhMetaFile(hMem); 00903 break; 00904 00905 /* 00906 * Must have a valid hMem (GlobalHandle) 00907 */ 00908 case CF_TEXT: 00909 case CF_OEMTEXT: 00910 case CF_LOCALE: 00911 case CF_DSPTEXT: 00912 hServer = ConvertMemHandle(hMem, 1); 00913 fGlobalHandle = TRUE; 00914 break; 00915 00916 case CF_UNICODETEXT: 00917 hServer = ConvertMemHandle(hMem, 2); 00918 fGlobalHandle = TRUE; 00919 break; 00920 00921 case CF_DIB: 00922 case CF_DIBV5: 00923 hServer = ConvertMemHandle(hMem, 0); 00924 fGlobalHandle = TRUE; 00925 break; 00926 00927 /* 00928 * hMem should have been NULL but Write sends non-null when told 00929 * to render 00930 */ 00931 case CF_OWNERDISPLAY: 00932 // Fall Through; 00933 00934 /* 00935 * May have an hMem (GlobalHandle) or may be private handle\info 00936 */ 00937 default: 00938 if (GlobalFlags(hMem) == GMEM_INVALID_HANDLE) { 00939 hServer = hMem; // No server equivalent; private data 00940 goto SCD_AFTERNULLCHECK; 00941 } else { 00942 fGlobalHandle = TRUE; 00943 hServer = ConvertMemHandle(hMem, 0); 00944 } 00945 break; 00946 } 00947 00948 if (hServer == NULL) { 00949 /* 00950 * Something bad happened, gdi didn't give us back a 00951 * handle. Since gdi has logged the error, we'll just 00952 * clean up and return an error. 00953 */ 00954 RIPMSG0(RIP_WARNING, "SetClipboardData: bad handle\n"); 00955 return NULL; 00956 } 00957 } 00958 00959 SCD_AFTERNULLCHECK: 00960 00961 RtlEnterCriticalSection(&gcsClipboard); 00962 00963 /* 00964 * Update the server if that is successfull update the client 00965 */ 00966 scd.fGlobalHandle = fGlobalHandle; 00967 scd.fIncSerialNumber = TRUE; 00968 00969 if (!NtUserSetClipboardData(wFmt, hServer, &scd)) { 00970 RtlLeaveCriticalSection(&gcsClipboard); 00971 return NULL; 00972 } 00973 00974 /* 00975 * See if we already have a client handle of this type. If so 00976 * delete it. 00977 */ 00978 phnNew = gphn; 00979 while (phnNew) { 00980 if (phnNew->fmt == wFmt) { 00981 if (phnNew->handleClient != NULL) { 00982 DeleteClientClipboardHandle(phnNew); 00983 /* 00984 * Notify WOW to clear its associated cached h16 for this format 00985 * so that OLE32 thunked calls, which bypass the WOW cache will work. 00986 */ 00987 if (pfnWowCBStoreHandle) { 00988 pfnWowCBStoreHandle((WORD)wFmt, 0); 00989 } 00990 } 00991 break; 00992 } 00993 00994 phnNew = phnNew->pnext; 00995 } 00996 00997 /* 00998 * If we aren't re-using an old client cache entry alloc a new one 00999 */ 01000 if (!phnNew) { 01001 phnNew = (PHANDLENODE)LocalAlloc(LPTR, sizeof(HANDLENODE)); 01002 01003 if (phnNew == NULL) { 01004 RIPMSG0(RIP_WARNING, "SetClipboardData: not enough memory\n"); 01005 01006 RtlLeaveCriticalSection(&gcsClipboard); 01007 return NULL; 01008 } 01009 01010 /* 01011 * Link in the newly allocated cache entry 01012 */ 01013 phnNew->pnext = gphn; 01014 gphn = phnNew; 01015 } 01016 01017 phnNew->handleServer = hServer; 01018 phnNew->handleClient = hMem; 01019 phnNew->fmt = wFmt; 01020 phnNew->fGlobalHandle = fGlobalHandle; 01021 01022 RtlLeaveCriticalSection(&gcsClipboard); 01023 01024 return hMem; 01025 } 01026 01027 /**************************************************************************\ 01028 * SetDeskWallpaper 01029 * 01030 * 22-Jul-1991 mikeke Created 01031 * 01-Mar-1992 GregoryW Modified to call SystemParametersInfo. 01032 \**************************************************************************/ 01033 01034 BOOL SetDeskWallpaper( 01035 IN LPCSTR pString OPTIONAL) 01036 { 01037 return SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, (PVOID)pString, TRUE); 01038 } 01039 01040 /***************************************************************************\ 01041 * ReleaseDC (API) 01042 * 01043 * A complete Thank cannot be generated for ReleaseDC because its first 01044 * parameter (hwnd) unnecessary and should be discarded before calling the 01045 * server-side routine _ReleaseDC. 01046 * 01047 * History: 01048 * 03-28-91 SMeans Created. 01049 * 06-17-91 ChuckWh Added support for local DCs. 01050 \***************************************************************************/ 01051 01052 BOOL WINAPI ReleaseDC( 01053 HWND hwnd, 01054 HDC hdc) 01055 { 01056 01057 /* 01058 * NOTE: This is a smart stub that calls _ReleaseDC so there is 01059 * no need for a separate ReleaseDC layer or client-server stub. 01060 * _ReleaseDC has simpler layer and client-server stubs since the 01061 * hwnd can be ignored. 01062 */ 01063 01064 UNREFERENCED_PARAMETER(hwnd); 01065 01066 /* 01067 * Translate the handle. 01068 */ 01069 if (hdc == NULL) 01070 return FALSE; 01071 01072 /* 01073 * call GDI to release user mode DC resources 01074 */ 01075 01076 GdiReleaseDC(hdc); 01077 01078 return (BOOL)NtUserCallOneParam((ULONG_PTR)hdc, SFI__RELEASEDC); 01079 } 01080 01081 int WINAPI 01082 ToAscii( 01083 UINT wVirtKey, 01084 UINT wScanCode, 01085 CONST BYTE *lpKeyState, 01086 LPWORD lpChar, 01087 UINT wFlags 01088 ) 01089 { 01090 WCHAR UnicodeChar[2]; 01091 int cch, retval; 01092 01093 retval = ToUnicode(wVirtKey, wScanCode, lpKeyState, UnicodeChar,2, wFlags); 01094 cch = (retval < 0) ? -retval : retval; 01095 if (cch != 0) { 01096 if (!NT_SUCCESS(RtlUnicodeToMultiByteN( 01097 (LPSTR)lpChar, 01098 (ULONG) sizeof(*lpChar), 01099 (PULONG)&cch, 01100 UnicodeChar, 01101 cch * sizeof(WCHAR)))) { 01102 return 0; 01103 } 01104 } 01105 return (retval < 0) ? -cch : cch; 01106 } 01107 01108 static UINT uCachedCP = 0; 01109 static HKL hCachedHKL = 0; 01110 01111 int WINAPI 01112 ToAsciiEx( 01113 UINT wVirtKey, 01114 UINT wScanCode, 01115 CONST BYTE *lpKeyState, 01116 LPWORD lpChar, 01117 UINT wFlags, 01118 HKL hkl 01119 ) 01120 { 01121 WCHAR UnicodeChar[2]; 01122 int cch, retval; 01123 BOOL fUsedDefaultChar; 01124 01125 retval = ToUnicodeEx(wVirtKey, wScanCode, lpKeyState, UnicodeChar,2, wFlags, hkl); 01126 cch = (retval < 0) ? -retval : retval; 01127 if (cch != 0) { 01128 if (hkl != hCachedHKL) { 01129 DWORD dwCodePage; 01130 if (!GetLocaleInfoW( 01131 HandleToUlong(hkl) & 0xffff, 01132 LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER, 01133 (LPWSTR)&dwCodePage, 01134 sizeof(dwCodePage) / sizeof(WCHAR) 01135 )) { 01136 return 0; 01137 } 01138 uCachedCP = dwCodePage; 01139 hCachedHKL = hkl; 01140 } 01141 if (!WideCharToMultiByte( 01142 uCachedCP, 01143 0, 01144 UnicodeChar, 01145 cch, 01146 (LPSTR)lpChar, 01147 sizeof(*lpChar), 01148 NULL, 01149 &fUsedDefaultChar)) { 01150 return 0; 01151 } 01152 } 01153 return (retval < 0) ? -cch : cch; 01154 } 01155 01156 /**************************************************************************\ 01157 * ScrollDC * 01158 * DrawIcon * 01159 * ExcludeUpdateRgn * 01160 * ValidateRgn * 01161 * DrawFocusRect * 01162 * FrameRect * 01163 * ReleaseDC * 01164 * GetUpdateRgn * 01165 * * 01166 * These USER entry points all need handles translated before the call is * 01167 * passed to the server side handler. * 01168 * * 01169 * History: * 01170 * Mon 17-Jun-1991 22:51:45 -by- Charles Whitmer [chuckwh] * 01171 * Wrote the stubs. The final form of these routines depends strongly on * 01172 * what direction the user stubs take in general. * 01173 \**************************************************************************/ 01174 01175 01176 BOOL WINAPI ScrollDC( 01177 HDC hDC, 01178 int dx, 01179 int dy, 01180 CONST RECT *lprcScroll, 01181 CONST RECT *lprcClip, 01182 HRGN hrgnUpdate, 01183 LPRECT lprcUpdate) 01184 { 01185 if (hDC == NULL) 01186 return FALSE; 01187 01188 /* 01189 * If we're not scrolling, just empty the update region and return. 01190 */ 01191 if (dx == 0 && dy == 0) { 01192 if (hrgnUpdate) 01193 SetRectRgn(hrgnUpdate, 0, 0, 0, 0); 01194 if (lprcUpdate) 01195 SetRectEmpty(lprcUpdate); 01196 return TRUE; 01197 } 01198 01199 return NtUserScrollDC(hDC, dx, dy, lprcScroll, lprcClip, 01200 hrgnUpdate, lprcUpdate); 01201 } 01202 01203 01204 BOOL WINAPI DrawIcon(HDC hdc,int x,int y,HICON hicon) 01205 { 01206 return DrawIconEx(hdc, x, y, hicon, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE ); 01207 } 01208 01209 01210 BOOL DrawIconEx( HDC hdc, int x, int y, HICON hIcon, 01211 int cx, int cy, UINT istepIfAniCur, 01212 HBRUSH hbrFlickerFreeDraw, UINT diFlags) 01213 { 01214 DRAWICONEXDATA did; 01215 HBITMAP hbmT; 01216 BOOL retval = FALSE; 01217 HDC hdcr; 01218 01219 if (diFlags & ~DI_VALID) { 01220 RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, ""); 01221 return(FALSE); 01222 } 01223 01224 if (diFlags & DI_DEFAULTSIZE) { 01225 cx = 0; 01226 cy = 0; 01227 } 01228 01229 if (!IsMetaFile(hdc)) { 01230 hdcr = GdiConvertAndCheckDC(hdc); 01231 if (hdcr == (HDC)0) 01232 return FALSE; 01233 01234 return NtUserDrawIconEx(hdcr, x, y, hIcon, cx, cy, istepIfAniCur, 01235 hbrFlickerFreeDraw, diFlags, FALSE, &did); 01236 } 01237 01238 if (!NtUserDrawIconEx(NULL, 0, 0, hIcon, cx, cy, 0, NULL, 0, TRUE, &did)) { 01239 return FALSE; 01240 } 01241 01242 if (diFlags == 0) 01243 return TRUE; 01244 01245 RtlEnterCriticalSection(&gcsHdc); 01246 01247 /* 01248 * Setup the attributes 01249 */ 01250 if (!cx) 01251 cx = did.cx; 01252 if (!cy) 01253 cy = did.cy / 2; 01254 01255 SetTextColor(hdc, 0x00000000L); 01256 SetBkColor(hdc, 0x00FFFFFFL); 01257 01258 if (diFlags & DI_MASK) { 01259 01260 if (did.hbmMask) { 01261 01262 hbmT = SelectObject(ghdcBits2, did.hbmMask); 01263 StretchBlt(hdc, 01264 x, 01265 y, 01266 cx, 01267 cy, 01268 ghdcBits2, 01269 0, 01270 0, 01271 did.cx, 01272 did.cy / 2, 01273 SRCAND); 01274 SelectObject(ghdcBits2,hbmT); 01275 retval = TRUE; 01276 } 01277 } 01278 01279 if (diFlags & DI_IMAGE) { 01280 01281 if (did.hbmColor != NULL) { 01282 hbmT = SelectObject(ghdcBits2, did.hbmColor); 01283 StretchBlt(hdc, 01284 x, 01285 y, 01286 cx, 01287 cy, 01288 ghdcBits2, 01289 0, 01290 0, 01291 did.cx, 01292 did.cy / 2, 01293 SRCINVERT); 01294 SelectObject(ghdcBits2, hbmT); 01295 retval = TRUE; 01296 } else { 01297 if (did.hbmMask) { 01298 hbmT = SelectObject(ghdcBits2, did.hbmMask); 01299 StretchBlt(hdc, 01300 x, 01301 y, 01302 cx, 01303 cy, 01304 ghdcBits2, 01305 0, 01306 did.cy / 2, 01307 did.cx, 01308 did.cy / 2, 01309 SRCINVERT); 01310 SelectObject(ghdcBits2, hbmT); 01311 retval = TRUE; 01312 } 01313 } 01314 } 01315 RtlLeaveCriticalSection(&gcsHdc); 01316 01317 return retval; 01318 } 01319 01320 01321 01322 BOOL WINAPI ValidateRgn(HWND hWnd,HRGN hRgn) 01323 { 01324 return (BOOL)NtUserCallHwndParamLock(hWnd, (ULONG_PTR)hRgn, 01325 SFI_XXXVALIDATERGN); 01326 } 01327 01328 int WINAPI GetUpdateRgn(HWND hWnd, HRGN hRgn, BOOL bErase) 01329 { 01330 PWND pwnd; 01331 01332 if (hRgn == NULL) { 01333 RIPERR1(ERROR_INVALID_HANDLE, RIP_WARNING, "Invalid region %#p", hRgn); 01334 return ERROR; 01335 } 01336 01337 if ((pwnd = ValidateHwnd(hWnd)) == NULL) { 01338 return ERROR; 01339 } 01340 01341 /* 01342 * Check for the simple case where nothing needs to be done. 01343 */ 01344 if (pwnd->hrgnUpdate == NULL && 01345 !TestWF(pwnd, WFSENDERASEBKGND) && 01346 !TestWF(pwnd, WFSENDNCPAINT) && 01347 !TestWF(pwnd, WFUPDATEDIRTY) && 01348 !TestWF(pwnd, WFPAINTNOTPROCESSED)) { 01349 SetRectRgn(hRgn, 0, 0, 0, 0); 01350 return NULLREGION; 01351 } 01352 01353 return NtUserGetUpdateRgn(hWnd, hRgn, bErase); 01354 } 01355 01356 01357 int WINAPI GetUpdateRect(HWND hWnd, LPRECT lprc, BOOL bErase) 01358 { 01359 PWND pwnd; 01360 01361 if ((pwnd = ValidateHwnd(hWnd)) == NULL) { 01362 return FALSE; 01363 } 01364 01365 /* 01366 * Check for the simple case where nothing needs to be done. 01367 */ 01368 if (pwnd->hrgnUpdate == NULL && 01369 !TestWF(pwnd, WFSENDERASEBKGND) && 01370 !TestWF(pwnd, WFSENDNCPAINT) && 01371 !TestWF(pwnd, WFUPDATEDIRTY) && 01372 !TestWF(pwnd, WFPAINTNOTPROCESSED)) { 01373 if (lprc) 01374 SetRectEmpty(lprc); 01375 return FALSE; 01376 } 01377 01378 return NtUserGetUpdateRect(hWnd, lprc, bErase); 01379 } 01380 01381 01382 /***************************************************************************\ 01383 * ScrollWindow (API) 01384 * 01385 * 01386 * History: 01387 * 18-Jul-1991 DarrinM Ported from Win 3.1 sources. 01388 \***************************************************************************/ 01389 01390 #define SW_FLAG_RC (SW_SCROLLWINDOW | SW_INVALIDATE | SW_ERASE | SW_SCROLLCHILDREN) 01391 #define SW_FLAG_NRC (SW_SCROLLWINDOW | SW_INVALIDATE | SW_ERASE) 01392 01393 BOOL WINAPI 01394 ScrollWindow( 01395 HWND hwnd, 01396 int dx, 01397 int dy, 01398 CONST RECT *prcScroll, 01399 CONST RECT *prcClip) 01400 { 01401 return NtUserScrollWindowEx( 01402 hwnd, 01403 dx, 01404 dy, 01405 prcScroll, 01406 prcClip, 01407 NULL, 01408 NULL, 01409 !IS_PTR(prcScroll) ? SW_FLAG_RC : SW_FLAG_NRC) != ERROR; 01410 } 01411 01412 /***************************************************************************\ 01413 * 01414 * SwitchToThisWindow() 01415 * 01416 \***************************************************************************/ 01417 01418 void WINAPI SwitchToThisWindow( 01419 HWND hwnd, 01420 BOOL fAltTab) 01421 { 01422 (VOID)NtUserCallHwndParamLock(hwnd, fAltTab, SFI_XXXSWITCHTOTHISWINDOW); 01423 } 01424 01425 01426 /***************************************************************************\ 01427 * WaitForInputIdle 01428 * 01429 * Waits for a given process to go idle. 01430 * 01431 * 09-18-91 ScottLu Created. 01432 \***************************************************************************/ 01433 01434 DWORD WaitForInputIdle( 01435 HANDLE hProcess, 01436 DWORD dwMilliseconds) 01437 { 01438 PROCESS_BASIC_INFORMATION processinfo; 01439 ULONG_PTR idProcess; 01440 NTSTATUS status; 01441 /* 01442 * First get the process id from the hProcess. 01443 */ 01444 status = NtQueryInformationProcess(hProcess, ProcessBasicInformation, 01445 &processinfo, sizeof(processinfo), NULL); 01446 if (!NT_SUCCESS(status)) { 01447 if (status == STATUS_OBJECT_TYPE_MISMATCH) { 01448 if ((ULONG_PTR)hProcess & 0x2) { 01449 /* 01450 * WOW Process handles are really semaphore handles. 01451 * CreateProcess ORs in a 0x2 (the low 2 bits of handles 01452 * are not used) so we can identify it more clearly. 01453 */ 01454 idProcess = ((ULONG_PTR)hProcess & ~0x03); 01455 return NtUserWaitForInputIdle(idProcess, dwMilliseconds, TRUE); 01456 } 01457 01458 /* 01459 * VDM (DOS) Process handles are really semaphore handles. 01460 * CreateProcess ORs in a 0x1 (the low 2 bits of handles 01461 * are not used) so we can identify and return immidiately. 01462 */ 01463 if ((ULONG_PTR)hProcess & 0x1) { 01464 return 0; 01465 } 01466 } 01467 01468 RIPERR1(ERROR_INVALID_HANDLE, RIP_WARNING, "WaitForInputIdle invalid process", hProcess); 01469 return (DWORD)-1; 01470 } 01471 idProcess = processinfo.UniqueProcessId; 01472 return NtUserWaitForInputIdle(idProcess, dwMilliseconds, FALSE); 01473 } 01474 01475 DWORD WINAPI MsgWaitForMultipleObjects( 01476 DWORD nCount, 01477 CONST HANDLE *pHandles, 01478 BOOL fWaitAll, 01479 DWORD dwMilliseconds, 01480 DWORD dwWakeMask) 01481 { 01482 return MsgWaitForMultipleObjectsEx(nCount, pHandles, 01483 dwMilliseconds, dwWakeMask, fWaitAll?MWMO_WAITALL:0); 01484 } 01485 01486 DWORD WINAPI MsgWaitForMultipleObjectsEx( 01487 DWORD nCount, 01488 CONST HANDLE *pHandles, 01489 DWORD dwMilliseconds, 01490 DWORD dwWakeMask, 01491 DWORD dwFlags) 01492 { 01493 HANDLE hEventInput; 01494 PHANDLE ph; 01495 DWORD dwIndex; 01496 BOOL ReenterWowScheduler; 01497 PCLIENTINFO pci; 01498 HANDLE rgHandles[ 8 + 1 ]; 01499 BOOL fWaitAll = ((dwFlags & MWMO_WAITALL) != 0); 01500 BOOL fAlertable = ((dwFlags & MWMO_ALERTABLE) != 0); 01501 PCLIENTTHREADINFO pcti; 01502 01503 if (dwFlags & ~MWMO_VALID) { 01504 RIPERR1(ERROR_INVALID_PARAMETER, RIP_ERROR, "MsgWaitForMultipleObjectsEx, invalid flags 0x%08lx\n", dwFlags); 01505 return (DWORD)-1; 01506 } 01507 01508 pci = GetClientInfo(); 01509 if (pci == NULL) 01510 return (DWORD)-1; 01511 01512 /* 01513 * If we have a pcti, see if we can return immediately. 01514 * pcti migth be NULL if this is the first W32 call made by this thread. 01515 */ 01516 01517 pcti = GetClientInfo()->pClientThreadInfo; 01518 if (pcti && (!fWaitAll || !nCount)) { 01519 if (GetInputBits(pcti, LOWORD(dwWakeMask), (dwFlags & MWMO_INPUTAVAILABLE))) { 01520 return nCount; 01521 } 01522 } 01523 01524 /* 01525 * Note -- the wake mask is a WORD, and only 3 flags are defined, so 01526 * they can be combined for the call. 01527 */ 01528 01529 hEventInput = (HANDLE)NtUserCallOneParam(MAKELONG(dwWakeMask, dwFlags), SFI_XXXGETINPUTEVENT); 01530 01531 if (hEventInput == NULL) { 01532 RIPMSG0(RIP_WARNING, "MsgWaitForMultipleObjectsEx, GetInputEvent failed\n"); 01533 return (DWORD)-1; 01534 } 01535 01536 /* 01537 * If needed, allocate a new array of handles that will include 01538 * the input event handle. 01539 */ 01540 ph = rgHandles; 01541 if (pHandles) { 01542 01543 if (nCount > 8) { 01544 ph = (PHANDLE)LocalAlloc(LPTR, sizeof(HANDLE) * (nCount + 1)); 01545 if (ph == NULL) { 01546 NtUserCallNoParam(SFI_CLEARWAKEMASK); 01547 return (DWORD)-1; 01548 } 01549 } 01550 01551 RtlCopyMemory((PVOID)ph, pHandles, sizeof(HANDLE) * nCount); 01552 01553 } else { 01554 // if this isn't Zero, the function parameters are invalid 01555 nCount = 0; 01556 } 01557 01558 ph[nCount] = hEventInput; 01559 01560 01561 /* 01562 * WowApps must exit the Wow scheduler otherwise other tasks 01563 * in this Wow scheduler can't run. The only exception is if 01564 * the timeout is Zero. We pass HEVENT_REMOVEME as the handle so we will go 01565 * into the sleeptask AND return without going to sleep but letting 01566 * other apps run. 01567 */ 01568 if ((pci->dwTIFlags & TIF_16BIT) && dwMilliseconds) { 01569 ReenterWowScheduler = TRUE; 01570 NtUserWaitForMsgAndEvent(HEVENT_REMOVEME); 01571 /* 01572 * If our wait condition is satisfied, make sure we won't wait. 01573 * We must have a pcti now since we just went to the kernel 01574 */ 01575 pcti = GetClientInfo()->pClientThreadInfo; 01576 if (GetInputBits(pcti, LOWORD(dwWakeMask), (dwFlags & MWMO_INPUTAVAILABLE))) { 01577 SetEvent(hEventInput); 01578 } 01579 } else { 01580 ReenterWowScheduler = FALSE; 01581 } 01582 01583 dwIndex = WaitForMultipleObjectsEx(nCount + 1, ph, fWaitAll, dwMilliseconds, fAlertable); 01584 01585 /* 01586 * Clear the wake mask since we're done waiting on these events. 01587 */ 01588 NtUserCallNoParam(SFI_CLEARWAKEMASK); 01589 01590 /* 01591 * If needed reenter the wow scheduler 01592 */ 01593 if (ReenterWowScheduler) { 01594 NtUserCallOneParam(DY_OLDYIELD, SFI_XXXDIRECTEDYIELD); 01595 } 01596 01597 if (ph != rgHandles) { 01598 LocalFree(ph); 01599 } 01600 01601 return dwIndex; 01602 } 01603 01604 /***************************************************************************\ 01605 * GrayString 01606 * 01607 * GrayStingA used to convert the string and call GrayStringW but that 01608 * did not work in a number of special cases such as the app passing in 01609 * a pointer to a zero length string. Eventually GrayStringA had almost as 01610 * much code as GrayStringW so now they are one. 01611 * 01612 * History: 01613 * 06-11-91 JimA Created. 01614 * 06-17-91 ChuckWh Added GDI handle conversion. 01615 * 02-12-92 mikeke Made it completely client side 01616 \***************************************************************************/ 01617 01618 BOOL InnerGrayStringAorW( 01619 HDC hdc, 01620 HBRUSH hbr, 01621 GRAYSTRINGPROC lpfnPrint, 01622 LPARAM lParam, 01623 int cch, 01624 int x, 01625 int y, 01626 int cx, 01627 int cy, 01628 BOOL bAnsi) 01629 { 01630 HBITMAP hbm; 01631 HBITMAP hbmOld; 01632 BOOL fResult; 01633 HFONT hFontSave = NULL; 01634 BOOL fReturn = FALSE; 01635 #ifdef USE_MIRRORING 01636 DWORD dwOldLayout = GDI_ERROR; 01637 #endif 01638 /* 01639 * Win 3.1 tries to calc the size even if we don't know if it is a string. 01640 */ 01641 if (cch == 0) { 01642 01643 try { 01644 01645 cch = bAnsi ? strlen((LPSTR)lParam) : wcslen((LPWSTR)lParam); 01646 01647 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 01648 fReturn = TRUE; 01649 } 01650 01651 if (fReturn) 01652 return FALSE; 01653 } 01654 01655 if (cx == 0 || cy == 0) { 01656 01657 SIZE size; 01658 01659 /* 01660 * We use the caller supplied hdc (instead of hdcBits) since we may be 01661 * graying a font which is different than the system font and we want to 01662 * get the proper text extents. 01663 */ 01664 try { 01665 if (bAnsi) { 01666 GetTextExtentPointA(hdc, (LPSTR)lParam, cch, &size); 01667 } else { 01668 GetTextExtentPointW(hdc, (LPWSTR)lParam, cch, &size); 01669 } 01670 01671 cx = size.cx; 01672 cy = size.cy; 01673 01674 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 01675 fReturn = TRUE; 01676 } 01677 01678 if (fReturn) 01679 return FALSE; 01680 } 01681 01682 UserAssert (ghdcGray != NULL); 01683 01684 RtlEnterCriticalSection(&gcsHdc); 01685 01686 if (gcxGray < cx || gcyGray < cy) { 01687 01688 if ((hbm = CreateBitmap(cx, cy, 1, 1, 0L)) != NULL) { 01689 01690 hbmOld = SelectObject(ghdcGray, hbm); 01691 DeleteObject(hbmOld); 01692 01693 gcxGray = cx; 01694 gcyGray = cy; 01695 01696 } else { 01697 cx = gcxGray; 01698 cy = gcyGray; 01699 } 01700 } 01701 01702 #ifdef USE_MIRRORING 01703 /* 01704 * If the caller hdc is mirrored then mirror ghdcGray. 01705 */ 01706 if (MIRRORED_HDC(hdc)) { 01707 dwOldLayout = SetLayoutWidth(ghdcGray, cx, LAYOUT_RTL); 01708 } 01709 #endif 01710 01711 /* 01712 * Force the ghdcGray font to be the same as hDC; ghdcGray is always 01713 * the system font 01714 */ 01715 hFontSave = SelectObject(hdc, ghFontSys); 01716 01717 if (hFontSave != ghFontSys) { 01718 SelectObject(hdc, hFontSave); 01719 hFontSave = SelectObject(ghdcGray, hFontSave); 01720 } 01721 01722 if (lpfnPrint != NULL) { 01723 PatBlt(ghdcGray, 0, 0, cx, cy, WHITENESS); 01724 fResult = (*lpfnPrint)(ghdcGray, lParam, cch); 01725 } else { 01726 01727 if (bAnsi) { 01728 fResult = TextOutA(ghdcGray, 0, 0, (LPSTR)lParam, cch); 01729 } else { 01730 fResult = TextOutW(ghdcGray, 0, 0, (LPWSTR)lParam, cch); 01731 } 01732 } 01733 01734 if (fResult) 01735 PatBlt(ghdcGray, 0, 0, cx, cy, DESTINATION | PATTERN); 01736 01737 if (fResult || cch == -1) { 01738 01739 HBRUSH hbrSave; 01740 DWORD textColorSave; 01741 DWORD bkColorSave; 01742 01743 textColorSave = SetTextColor(hdc, 0x00000000L); 01744 bkColorSave = SetBkColor(hdc, 0x00FFFFFFL); 01745 01746 hbrSave = SelectObject(hdc, hbr ? hbr : ghbrWindowText); 01747 01748 BitBlt(hdc, 01749 x, 01750 y, 01751 cx, 01752 cy, 01753 ghdcGray, 01754 0, 01755 0, 01756 (((PATTERN ^ DESTINATION) & SOURCE) ^ PATTERN)); 01757 01758 SelectObject(hdc, hbrSave); 01759 01760 /* 01761 * Restore saved colors 01762 */ 01763 SetTextColor(hdc, textColorSave); 01764 SetBkColor(hdc, bkColorSave); 01765 } 01766 01767 SelectObject(ghdcGray, hFontSave); 01768 #ifdef USE_MIRRORING 01769 /* 01770 * Restore ghdcGray layout state. 01771 */ 01772 if (dwOldLayout != GDI_ERROR) { 01773 SetLayoutWidth(ghdcGray, cx, dwOldLayout); 01774 } 01775 #endif 01776 RtlLeaveCriticalSection(&gcsHdc); 01777 01778 return fResult; 01779 } 01780 01781 BOOL GrayStringA( 01782 HDC hdc, 01783 HBRUSH hbr, 01784 GRAYSTRINGPROC lpfnPrint, 01785 LPARAM lParam, 01786 int cch, 01787 int x, 01788 int y, 01789 int cx, 01790 int cy) 01791 { 01792 return (InnerGrayStringAorW(hdc, 01793 hbr, 01794 lpfnPrint, 01795 lParam, 01796 cch, 01797 x, 01798 y, 01799 cx, 01800 cy, 01801 TRUE)); 01802 } 01803 01804 BOOL GrayStringW( 01805 HDC hdc, 01806 HBRUSH hbr, 01807 GRAYSTRINGPROC lpfnPrint, 01808 LPARAM lParam, 01809 int cch, 01810 int x, 01811 int y, 01812 int cx, 01813 int cy) 01814 { 01815 return (InnerGrayStringAorW(hdc, 01816 hbr, 01817 lpfnPrint, 01818 lParam, 01819 cch, 01820 x, 01821 y, 01822 cx, 01823 cy, 01824 FALSE)); 01825 } 01826 01827 01828 /***************************************************************************\ 01829 * GetUserObjectSecurity (API) 01830 * 01831 * Gets the security descriptor of an object 01832 * 01833 * History: 01834 * 07-01-91 JimA Created. 01835 \***************************************************************************/ 01836 01837 BOOL GetUserObjectSecurity( 01838 HANDLE hObject, 01839 PSECURITY_INFORMATION pRequestedInformation, 01840 PSECURITY_DESCRIPTOR pSecurityDescriptor, 01841 DWORD nLength, 01842 LPDWORD lpnLengthRequired) 01843 { 01844 NTSTATUS Status; 01845 01846 Status = NtQuerySecurityObject(hObject, 01847 *pRequestedInformation, 01848 pSecurityDescriptor, 01849 nLength, 01850 lpnLengthRequired); 01851 if (!NT_SUCCESS(Status)) { 01852 RIPNTERR0(Status, RIP_VERBOSE, ""); 01853 return FALSE; 01854 } 01855 return TRUE; 01856 } 01857 01858 01859 /***************************************************************************\ 01860 * SetUserObjectSecurity (API) 01861 * 01862 * Sets the security descriptor of an object 01863 * 01864 * History: 01865 * 07-01-91 JimA Created. 01866 \***************************************************************************/ 01867 01868 BOOL SetUserObjectSecurity( 01869 HANDLE hObject, 01870 PSECURITY_INFORMATION pRequestedInformation, 01871 PSECURITY_DESCRIPTOR pSecurityDescriptor) 01872 { 01873 NTSTATUS Status; 01874 01875 Status = NtSetSecurityObject(hObject, 01876 *pRequestedInformation, 01877 pSecurityDescriptor); 01878 if (!NT_SUCCESS(Status)) { 01879 RIPNTERR0(Status, RIP_VERBOSE, ""); 01880 return FALSE; 01881 } 01882 return TRUE; 01883 } 01884 01885 01886 /***************************************************************************\ 01887 * GetUserObjectInformation (API) 01888 * 01889 * Gets information about an object 01890 * 01891 * History: 01892 \***************************************************************************/ 01893 01894 BOOL GetUserObjectInformationA( 01895 HANDLE hObject, 01896 int nIndex, 01897 PVOID pvInfo, 01898 DWORD nLength, 01899 LPDWORD pnLengthNeeded) 01900 { 01901 PVOID pvInfoW; 01902 DWORD nLengthW; 01903 BOOL fSuccess; 01904 01905 if (nIndex == UOI_NAME || nIndex == UOI_TYPE) { 01906 nLengthW = nLength * sizeof(WCHAR); 01907 pvInfoW = LocalAlloc(LPTR, nLengthW); 01908 fSuccess = NtUserGetObjectInformation(hObject, nIndex, pvInfoW, 01909 nLengthW, pnLengthNeeded); 01910 if (fSuccess) { 01911 if (pnLengthNeeded != NULL) 01912 *pnLengthNeeded /= sizeof(WCHAR); 01913 WCSToMB(pvInfoW, -1, &(PCHAR)pvInfo, nLength, FALSE); 01914 } 01915 LocalFree(pvInfoW); 01916 return fSuccess; 01917 } else { 01918 return NtUserGetObjectInformation(hObject, nIndex, pvInfo, 01919 nLength, pnLengthNeeded); 01920 } 01921 } 01922 01923 BOOL GetWinStationInfo( 01924 WSINFO* pWsInfo) 01925 { 01926 return (BOOL)NtUserCallOneParam((ULONG_PTR)pWsInfo, SFI__GETWINSTATIONINFO); 01927 } 01928 01929 01930 01931 BOOLEAN WinStaQueryInformationW( 01932 HANDLE hServer, 01933 ULONG ulLogonId, 01934 WINSTATIONINFOCLASS WinStationInformationClass, 01935 PVOID pWinStationInformation, 01936 ULONG ulWinStationInformationLength, 01937 PULONG pulReturnLength) 01938 { 01939 PWINSTATIONQUERYINFORMATIONW pfnWinStationQueryInformationW; 01940 HMODULE hwinsta; 01941 BOOLEAN fRet = FALSE; 01942 01943 /* 01944 * Get handle to winsta.dll 01945 */ 01946 if ((hwinsta = LoadLibraryA("WINSTA")) != NULL) { 01947 if ((pfnWinStationQueryInformationW = (PWINSTATIONQUERYINFORMATIONW) 01948 GetProcAddress(hwinsta, "WinStationQueryInformationW")) != NULL) { 01949 01950 /* 01951 * Fetch the WinStation's basic information 01952 */ 01953 fRet = (*pfnWinStationQueryInformationW)(hServer, 01954 ulLogonId, 01955 WinStationInformationClass, 01956 pWinStationInformation, 01957 ulWinStationInformationLength, 01958 pulReturnLength); 01959 } 01960 FreeLibrary(hwinsta); 01961 } 01962 01963 01964 return fRet; 01965 } 01966 01967 /***************************************************************************\ 01968 * GetServerIMEKeyboardLayout 01969 * 01970 * This routine finds HKL matches the IME module name sent from the Hydra 01971 * client at its session startup. 01972 * Hydra server tries to load the same IME module in the client, rather 01973 * than to use the same HKL: that's because, on FE machines, 01974 * the same IME might have different HKL dependent to each system. 01975 * 01976 * If the same IME name is found in registry, then it returns the HKL. 01977 * If it cannot find, return value is 0. 01978 * 01979 * History: 01980 \***************************************************************************/ 01981 01982 ULONG 01983 GetServerIMEKeyboardLayout( 01984 LPTSTR pszImeFileName) 01985 { 01986 BOOL fFound = FALSE; 01987 ULONG wLayoutId; 01988 UNICODE_STRING UnicodeStringKLKey; 01989 UNICODE_STRING UnicodeStringSubKLKey; 01990 UNICODE_STRING UnicodeStringIME; 01991 OBJECT_ATTRIBUTES OA; 01992 HANDLE hKey; 01993 ULONG Index; 01994 WCHAR awchKLRegKey[NSZKLKEY]; 01995 LPWSTR lpszKLRegKey = awchKLRegKey; 01996 NTSTATUS Status; 01997 01998 RtlInitUnicodeString(&UnicodeStringKLKey, szKLKey); 01999 InitializeObjectAttributes(&OA, &UnicodeStringKLKey, OBJ_CASE_INSENSITIVE, NULL, NULL); 02000 02001 if (NT_SUCCESS(NtOpenKey(&hKey, KEY_READ, &OA))) { 02002 02003 for (Index = 0; TRUE; Index++) { 02004 02005 BYTE KeyBuffer[sizeof(KEY_BASIC_INFORMATION) + KL_NAMELENGTH * sizeof(WCHAR)]; 02006 PKEY_BASIC_INFORMATION pKeyInfo; 02007 ULONG ResultLength; 02008 02009 pKeyInfo = (PKEY_BASIC_INFORMATION)KeyBuffer; 02010 Status = NtEnumerateKey(hKey, 02011 Index, 02012 KeyBasicInformation, 02013 pKeyInfo, 02014 sizeof(KeyBuffer), 02015 &ResultLength); 02016 02017 if (NT_SUCCESS(Status)) { 02018 UnicodeStringSubKLKey.Buffer = (PWSTR)&(pKeyInfo->Name[0]); 02019 UnicodeStringSubKLKey.Length = (USHORT)pKeyInfo->NameLength; 02020 UnicodeStringSubKLKey.MaximumLength = (USHORT)pKeyInfo->NameLength; 02021 RtlUnicodeStringToInteger(&UnicodeStringSubKLKey, 16, &wLayoutId); 02022 02023 if (IS_IME_KBDLAYOUT(wLayoutId)) { 02024 02025 HANDLE hSubKey; 02026 02027 wcscpy(lpszKLRegKey, szKLKey); 02028 wcsncat(lpszKLRegKey, UnicodeStringSubKLKey.Buffer, 02029 UnicodeStringSubKLKey.Length / sizeof(WCHAR)); 02030 RtlInitUnicodeString(&UnicodeStringKLKey, lpszKLRegKey); 02031 InitializeObjectAttributes(&OA, &UnicodeStringKLKey, OBJ_CASE_INSENSITIVE, NULL, NULL); 02032 02033 if (NT_SUCCESS(NtOpenKey(&hSubKey, KEY_READ, &OA))) { 02034 /* 02035 * GetIME file name from "HKLM\...<Index>\IME File" 02036 */ 02037 static CONST WCHAR szIMEfile[] = L"IME file"; 02038 struct { 02039 KEY_VALUE_PARTIAL_INFORMATION KeyInfo; 02040 WCHAR awchImeName[CCH_KL_LIBNAME]; 02041 } IMEfile; 02042 LPWSTR pwszIME; 02043 DWORD cbSize; 02044 02045 RtlInitUnicodeString(&UnicodeStringIME, szIMEfile); 02046 02047 Status = NtQueryValueKey(hSubKey, 02048 &UnicodeStringIME, 02049 KeyValuePartialInformation, 02050 &IMEfile, 02051 sizeof IMEfile, 02052 &cbSize); 02053 NtClose(hSubKey); 02054 02055 if (NT_SUCCESS(Status)) { 02056 pwszIME = (LPWSTR)IMEfile.KeyInfo.Data; 02057 pwszIME[CCH_KL_LIBNAME - 1] = L'\0'; 02058 if (!lstrcmpi(pwszIME, pszImeFileName)) { 02059 /* 02060 * IME file name match !! 02061 */ 02062 fFound = TRUE; 02063 break; 02064 } 02065 } 02066 } 02067 } 02068 } 02069 else { 02070 break; 02071 } 02072 } 02073 NtClose(hKey); 02074 } 02075 02076 if (fFound) 02077 return wLayoutId; 02078 02079 return 0; 02080 } 02081 02082 /***************************************************************************\ 02083 * GetRemoteKeyboardLayout 02084 * 02085 * Returns TRUE if the client winstation specified a keyboard layout. 02086 * If TRUE, the LayoutBuf contains the name of the keyboard layout. 02087 * History: 02088 \***************************************************************************/ 02089 02090 BOOL 02091 GetRemoteKeyboardLayout( 02092 PWCHAR LayoutBuf) 02093 { 02094 ULONG KeyboardLayout; 02095 ULONG Length; 02096 WINSTATIONCONFIG ConfigData; 02097 02098 /* 02099 * Skip if this is the main session 02100 */ 02101 if (!ISREMOTESESSION()) { 02102 return FALSE; 02103 } 02104 02105 /* 02106 * Fetch the WinStation's basic information 02107 */ 02108 if (!WinStaQueryInformationW(SERVERNAME_CURRENT, 02109 LOGONID_CURRENT, 02110 WinStationConfiguration, 02111 &ConfigData, 02112 sizeof(ConfigData), 02113 &Length)) { 02114 02115 return FALSE; 02116 } 02117 02118 KeyboardLayout = ConfigData.User.KeyboardLayout; 02119 02120 if (IS_IME_ENABLED()) { 02121 WINSTATIONCLIENTW ClientData; 02122 02123 // Fetch the WinStation's basic information 02124 if (!WinStaQueryInformationW(SERVERNAME_CURRENT, 02125 LOGONID_CURRENT, 02126 WinStationClient, 02127 &ClientData, 02128 sizeof(ClientData), 02129 &Length)) { 02130 return FALSE; 02131 } 02132 02133 if (IS_IME_KBDLAYOUT(ConfigData.User.KeyboardLayout)) { 02134 KeyboardLayout = GetServerIMEKeyboardLayout(ClientData.imeFileName); 02135 } 02136 } 02137 02138 if (KeyboardLayout != 0) { 02139 wsprintfW(LayoutBuf, L"%8.8lx", KeyboardLayout); 02140 return TRUE; 02141 } 02142 02143 return FALSE; 02144 } 02145 02146 /***************************************************************************\ 02147 * CreateWindowStation (API) 02148 * 02149 * Creates a windowstation object 02150 * 02151 * History: 02152 \***************************************************************************/ 02153 02154 HWINSTA CommonCreateWindowStation( 02155 PUNICODE_STRING pstrName, 02156 ACCESS_MASK amRequest, 02157 PSECURITY_ATTRIBUTES lpsa) 02158 { 02159 OBJECT_ATTRIBUTES Obja; 02160 HANDLE hRootDirectory; 02161 HWINSTA hwinstaNew = NULL; 02162 WCHAR pwszKLID[KL_NAMELENGTH]; 02163 HANDLE hKeyboardFile = NULL; 02164 DWORD offTable; 02165 UNICODE_STRING strKLID; 02166 UINT uKbdInputLocale, uFlags; 02167 NTSTATUS Status; 02168 02169 /* 02170 * Load initial keyboard layout. Continue even if 02171 * this fails (esp. important with KLF_INITTIME set) 02172 */ 02173 ULONG KeyboardLayout = 0; 02174 ULONG Length; 02175 WINSTATIONCONFIG ConfigData; 02176 BOOLEAN bResult; 02177 02178 extern BOOL CtxInitUser32(VOID); 02179 02180 hKeyboardFile = NULL; 02181 02182 /* 02183 * Get winstation info 02184 */ 02185 if (ISREMOTESESSION()) { 02186 02187 bResult = WinStaQueryInformationW(SERVERNAME_CURRENT, 02188 LOGONID_CURRENT, 02189 WinStationConfiguration, 02190 &ConfigData, 02191 sizeof(ConfigData), 02192 &Length); 02193 if (bResult) { 02194 KeyboardLayout = ConfigData.User.KeyboardLayout; 02195 02196 if (KeyboardLayout) { 02197 wsprintfW(pwszKLID, L"%8.8lx", KeyboardLayout); 02198 uFlags = KLF_ACTIVATE | KLF_INITTIME; 02199 02200 hKeyboardFile = OpenKeyboardLayoutFile(pwszKLID, 02201 &uFlags, &offTable, &uKbdInputLocale); 02202 02203 RIPMSG0(RIP_WARNING, "OpenKeyboardLayoutFile() failed. Will use the fallback keyboard layout"); 02204 } 02205 } 02206 } 02207 02208 if (hKeyboardFile == NULL) { 02209 02210 GetActiveKeyboardName(pwszKLID); 02211 retry: 02212 uFlags = KLF_ACTIVATE | KLF_INITTIME; 02213 hKeyboardFile = OpenKeyboardLayoutFile(pwszKLID, 02214 &uFlags, &offTable, &uKbdInputLocale); 02215 if (hKeyboardFile == NULL) { 02216 if (wcscmp(pwszKLID, L"00000409")) { 02217 wcscpy(pwszKLID, L"00000409"); 02218 RIPMSG0(RIP_WARNING, "OpendKeyboardLayoutFile() failed: will use the fallback keyboard layout."); 02219 goto retry; 02220 } 02221 uKbdInputLocale = 0x04090409; 02222 } 02223 } 02224 02225 02226 /* 02227 * Finish the rest of the DLL initialization for WinStations. 02228 * Until this point we had no video driver. 02229 * 02230 * clupu: We have to prevent this for NOIO windowstations !!! 02231 */ 02232 if (ISTS()) { 02233 if (!CtxInitUser32()) { 02234 RIPMSG0(RIP_WARNING, "CtxInitUser32 failed"); 02235 goto Exit; 02236 } 02237 } 02238 02239 RtlInitUnicodeString(&strKLID, pwszKLID); 02240 02241 /* 02242 * If a name was specified, open the parent directory. Be sure 02243 * to test the length rather than the buffer because for NULL 02244 * string RtlCreateUnicodeStringFromAsciiz will allocate a 02245 * buffer pointing to an empty string. 02246 */ 02247 if (pstrName->Length != 0) { 02248 InitializeObjectAttributes(&Obja, 02249 (PUNICODE_STRING)&strRootDirectory, 02250 OBJ_CASE_INSENSITIVE, 02251 NULL, NULL); 02252 Status = NtOpenDirectoryObject(&hRootDirectory, 02253 DIRECTORY_CREATE_OBJECT, &Obja); 02254 if (!NT_SUCCESS(Status)) { 02255 RIPNTERR0(Status, RIP_VERBOSE, ""); 02256 goto Exit; 02257 } 02258 } else { 02259 pstrName = NULL; 02260 hRootDirectory = NULL; 02261 } 02262 02263 InitializeObjectAttributes(&Obja, pstrName, 02264 OBJ_CASE_INSENSITIVE | OBJ_OPENIF | 02265 ((lpsa && lpsa->bInheritHandle) ? OBJ_INHERIT : 0), 02266 hRootDirectory, lpsa ? lpsa->lpSecurityDescriptor : NULL); 02267 02268 /* 02269 * NULL hKeyboardFile will let the kernel to utilize 02270 * the kbdnull layout which is a built in as a fallback layout 02271 * in Win32k.sys. 02272 */ 02273 hwinstaNew = NtUserCreateWindowStation( 02274 &Obja, 02275 amRequest, 02276 hKeyboardFile, 02277 offTable, 02278 &strKLID, 02279 uKbdInputLocale); 02280 02281 if (hRootDirectory != NULL) 02282 NtClose(hRootDirectory); 02283 Exit: 02284 if (hKeyboardFile) { 02285 NtClose(hKeyboardFile); 02286 } 02287 02288 return hwinstaNew; 02289 } 02290 02291 HWINSTA CreateWindowStationA( 02292 LPCSTR pwinsta, 02293 DWORD dwReserved, 02294 ACCESS_MASK amRequest, 02295 PSECURITY_ATTRIBUTES lpsa) 02296 { 02297 UNICODE_STRING UnicodeString; 02298 HWINSTA hwinsta; 02299 02300 if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, pwinsta)) 02301 return NULL; 02302 02303 hwinsta = CommonCreateWindowStation(&UnicodeString, amRequest, lpsa); 02304 02305 RtlFreeUnicodeString(&UnicodeString); 02306 02307 return hwinsta; 02308 02309 UNREFERENCED_PARAMETER(dwReserved); 02310 } 02311 02312 HWINSTA CreateWindowStationW( 02313 LPCWSTR pwinsta, 02314 DWORD dwReserved, 02315 ACCESS_MASK amRequest, 02316 PSECURITY_ATTRIBUTES lpsa) 02317 { 02318 UNICODE_STRING strWinSta; 02319 02320 RtlInitUnicodeString(&strWinSta, pwinsta); 02321 02322 return CommonCreateWindowStation(&strWinSta, amRequest, lpsa); 02323 02324 UNREFERENCED_PARAMETER(dwReserved); 02325 } 02326 02327 02328 /***************************************************************************\ 02329 * OpenWindowStation (API) 02330 * 02331 * Opens a windowstation object 02332 * 02333 * History: 02334 \***************************************************************************/ 02335 02336 HWINSTA CommonOpenWindowStation( 02337 CONST UNICODE_STRING *pstrName, 02338 BOOL fInherit, 02339 ACCESS_MASK amRequest) 02340 { 02341 WCHAR awchName[sizeof(WINSTA_NAME) / sizeof(WCHAR)]; 02342 UNICODE_STRING strDefaultName; 02343 OBJECT_ATTRIBUTES ObjA; 02344 HANDLE hRootDirectory; 02345 HWINSTA hwinsta; 02346 NTSTATUS Status; 02347 02348 InitializeObjectAttributes(&ObjA, 02349 (PUNICODE_STRING)&strRootDirectory, 02350 OBJ_CASE_INSENSITIVE, 02351 NULL, NULL); 02352 Status = NtOpenDirectoryObject(&hRootDirectory, 02353 DIRECTORY_TRAVERSE, 02354 &ObjA); 02355 if (!NT_SUCCESS(Status)) { 02356 RIPNTERR0(Status, RIP_VERBOSE, ""); 02357 return NULL; 02358 } 02359 02360 if (pstrName->Length == 0) { 02361 RtlCopyMemory(awchName, WINSTA_NAME, sizeof(WINSTA_NAME)); 02362 RtlInitUnicodeString(&strDefaultName, awchName); 02363 pstrName = &strDefaultName; 02364 } 02365 02366 InitializeObjectAttributes( &ObjA, 02367 (PUNICODE_STRING)pstrName, 02368 OBJ_CASE_INSENSITIVE, 02369 hRootDirectory, 02370 NULL 02371 ); 02372 if (fInherit) 02373 ObjA.Attributes |= OBJ_INHERIT; 02374 02375 hwinsta = NtUserOpenWindowStation(&ObjA, amRequest); 02376 02377 NtClose(hRootDirectory); 02378 02379 return hwinsta; 02380 } 02381 02382 HWINSTA OpenWindowStationA( 02383 LPCSTR pwinsta, 02384 BOOL fInherit, 02385 ACCESS_MASK amRequest) 02386 { 02387 UNICODE_STRING UnicodeString; 02388 HWINSTA hwinsta; 02389 02390 if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, pwinsta)) 02391 return NULL; 02392 02393 hwinsta = CommonOpenWindowStation(&UnicodeString, fInherit, amRequest); 02394 02395 RtlFreeUnicodeString(&UnicodeString); 02396 02397 return hwinsta; 02398 } 02399 02400 HWINSTA OpenWindowStationW( 02401 LPCWSTR pwinsta, 02402 BOOL fInherit, 02403 ACCESS_MASK amRequest) 02404 { 02405 UNICODE_STRING strWinSta; 02406 02407 RtlInitUnicodeString(&strWinSta, pwinsta); 02408 02409 return CommonOpenWindowStation(&strWinSta, fInherit, amRequest); 02410 } 02411 02412 /***************************************************************************\ 02413 * CommonCreateDesktop (API) 02414 * 02415 * Creates a desktop object 02416 * 02417 * History: 02418 \***************************************************************************/ 02419 02420 HDESK CommonCreateDesktop( 02421 PUNICODE_STRING pstrDesktop, 02422 PUNICODE_STRING pstrDevice, 02423 LPDEVMODEW pDevmode, 02424 DWORD dwFlags, 02425 ACCESS_MASK amRequest, 02426 PSECURITY_ATTRIBUTES lpsa) 02427 { 02428 OBJECT_ATTRIBUTES Obja; 02429 HDESK hdesk = NULL; 02430 02431 InitializeObjectAttributes(&Obja, 02432 pstrDesktop, 02433 OBJ_CASE_INSENSITIVE | OBJ_OPENIF | 02434 ((lpsa && lpsa->bInheritHandle) ? OBJ_INHERIT : 0), 02435 NtUserGetProcessWindowStation(), 02436 lpsa ? lpsa->lpSecurityDescriptor : NULL); 02437 02438 hdesk = NtUserCreateDesktop(&Obja, 02439 pstrDevice, 02440 pDevmode, 02441 dwFlags, 02442 amRequest); 02443 02444 return hdesk; 02445 } 02446 02447 /***************************************************************************\ 02448 * CreateDesktopA (API) 02449 * 02450 * Creates a desktop object 02451 * 02452 * History: 02453 \***************************************************************************/ 02454 02455 HDESK CreateDesktopA( 02456 LPCSTR pDesktop, 02457 LPCSTR pDevice, 02458 LPDEVMODEA pDevmode, 02459 DWORD dwFlags, 02460 ACCESS_MASK amRequest, 02461 PSECURITY_ATTRIBUTES lpsa) 02462 { 02463 NTSTATUS Status; 02464 ANSI_STRING AnsiString; 02465 UNICODE_STRING UnicodeDesktop; 02466 UNICODE_STRING UnicodeDevice; 02467 PUNICODE_STRING pUnicodeDevice = NULL; 02468 LPDEVMODEW lpDevModeW = NULL; 02469 HDESK hdesk; 02470 02471 RtlInitAnsiString(&AnsiString, pDesktop); 02472 Status = RtlAnsiStringToUnicodeString(&UnicodeDesktop, &AnsiString, TRUE); 02473 02474 if (!NT_SUCCESS(Status)) { 02475 RIPNTERR1(Status, RIP_VERBOSE, "CreateDesktop fails with Status = 0x%x", Status); 02476 return NULL; 02477 } 02478 02479 if (pDevice) { 02480 02481 pUnicodeDevice = &UnicodeDevice; 02482 RtlInitAnsiString(&AnsiString, pDevice); 02483 Status = RtlAnsiStringToUnicodeString( &UnicodeDevice, &AnsiString, TRUE ); 02484 02485 if (!NT_SUCCESS(Status)) { 02486 RIPNTERR0(Status, RIP_VERBOSE, ""); 02487 RtlFreeUnicodeString(&UnicodeDesktop); 02488 return NULL; 02489 } 02490 } 02491 02492 if (pDevmode) { 02493 02494 lpDevModeW = GdiConvertToDevmodeW(pDevmode); 02495 02496 } 02497 02498 hdesk = CommonCreateDesktop(&UnicodeDesktop, 02499 pUnicodeDevice, 02500 lpDevModeW, 02501 dwFlags, 02502 amRequest, 02503 lpsa); 02504 02505 RtlFreeUnicodeString(&UnicodeDesktop); 02506 if (pDevice) { 02507 RtlFreeUnicodeString(&UnicodeDevice); 02508 } 02509 02510 if (lpDevModeW) { 02511 LocalFree(lpDevModeW); 02512 } 02513 02514 return hdesk; 02515 } 02516 02517 /***************************************************************************\ 02518 * CreateDesktopW (API) 02519 * 02520 * Creates a desktop object 02521 * 02522 * History: 02523 \***************************************************************************/ 02524 02525 HDESK CreateDesktopW( 02526 LPCWSTR pDesktop, 02527 LPCWSTR pDevice, 02528 LPDEVMODEW pDevmode, 02529 DWORD dwFlags, 02530 ACCESS_MASK amRequest, 02531 PSECURITY_ATTRIBUTES lpsa) 02532 { 02533 UNICODE_STRING strDesktop; 02534 UNICODE_STRING strDevice; 02535 02536 RtlInitUnicodeString(&strDesktop, pDesktop); 02537 RtlInitUnicodeString(&strDevice, pDevice); 02538 02539 return CommonCreateDesktop(&strDesktop, 02540 pDevice ? &strDevice : NULL, 02541 pDevmode, 02542 dwFlags, 02543 amRequest, 02544 lpsa); 02545 } 02546 02547 /***************************************************************************\ 02548 * OpenDesktop (API) 02549 * 02550 * Opens a desktop object 02551 * 02552 * History: 02553 \***************************************************************************/ 02554 02555 HDESK CommonOpenDesktop( 02556 PUNICODE_STRING pstrDesktop, 02557 DWORD dwFlags, 02558 BOOL fInherit, 02559 ACCESS_MASK amRequest) 02560 { 02561 OBJECT_ATTRIBUTES ObjA; 02562 02563 InitializeObjectAttributes( &ObjA, 02564 pstrDesktop, 02565 OBJ_CASE_INSENSITIVE, 02566 NtUserGetProcessWindowStation(), 02567 NULL 02568 ); 02569 if (fInherit) 02570 ObjA.Attributes |= OBJ_INHERIT; 02571 02572 return NtUserOpenDesktop(&ObjA, dwFlags, amRequest); 02573 } 02574 02575 HDESK OpenDesktopA( 02576 LPCSTR pdesktop, 02577 DWORD dwFlags, 02578 BOOL fInherit, 02579 ACCESS_MASK amRequest) 02580 { 02581 UNICODE_STRING UnicodeString; 02582 HDESK hdesk; 02583 02584 if (!RtlCreateUnicodeStringFromAsciiz(&UnicodeString, pdesktop)) 02585 return NULL; 02586 02587 hdesk = CommonOpenDesktop(&UnicodeString, dwFlags, fInherit, amRequest); 02588 02589 RtlFreeUnicodeString(&UnicodeString); 02590 02591 return hdesk; 02592 } 02593 02594 HDESK OpenDesktopW( 02595 LPCWSTR pdesktop, 02596 DWORD dwFlags, 02597 BOOL fInherit, 02598 ACCESS_MASK amRequest) 02599 { 02600 UNICODE_STRING strDesktop; 02601 02602 RtlInitUnicodeString(&strDesktop, pdesktop); 02603 02604 return CommonOpenDesktop(&strDesktop, dwFlags, fInherit, amRequest); 02605 } 02606 02607 /***************************************************************************\ 02608 * RegisterClassWOW(API) 02609 * 02610 * History: 02611 * 28-Jul-1992 ChandanC Created. 02612 \***************************************************************************/ 02613 ATOM 02614 WINAPI 02615 RegisterClassWOWA( 02616 WNDCLASSA *lpWndClass, 02617 LPDWORD pdwWOWstuff) 02618 { 02619 WNDCLASSEXA wc; 02620 02621 /* 02622 * On 64-bit plaforms we'll have 32 bits of padding between style and 02623 * lpfnWndProc in WNDCLASS, so start the copy from the first 64-bit 02624 * aligned field and hand copy the rest. 02625 */ 02626 RtlCopyMemory(&(wc.lpfnWndProc), &(lpWndClass->lpfnWndProc), sizeof(WNDCLASSA) - FIELD_OFFSET(WNDCLASSA, lpfnWndProc)); 02627 wc.style = lpWndClass->style; 02628 wc.hIconSm = NULL; 02629 wc.cbSize = sizeof(WNDCLASSEXA); 02630 02631 return RegisterClassExWOWA(&wc, pdwWOWstuff, 0); 02632 } 02633 02634 02635 /**************************************************************************\ 02636 * WowGetDefWindowProcBits - Fills in bit array for WOW 02637 * 02638 * 22-Jul-1991 mikeke Created 02639 \**************************************************************************/ 02640 02641 WORD WowGetDefWindowProcBits( 02642 PBYTE pDefWindowProcBits, 02643 WORD cbDefWindowProcBits) 02644 { 02645 WORD wMaxMsg; 02646 PBYTE pbSrc, pbDst, pbDstEnd; 02647 02648 UNREFERENCED_PARAMETER(cbDefWindowProcBits); 02649 02650 /* 02651 * Merge the bits from gpsi->gabDefWindowMsgs and 02652 * gpsi->gabDefWindowSpecMsgs into WOW's DefWindowProcBits. These two 02653 * indicate which messages must go directly to the server and which 02654 * can be handled with some special code in DefWindowProcWorker. 02655 * Bitwise OR'ing the two gives a bit array with 1 in the bit field 02656 * for each message that must go to user32's DefWindowProc, and 0 02657 * for those that can be returned back to the client immediately. 02658 * 02659 * For speed we assume WOW has zeroed the buffer, in fact it's in 02660 * USER.EXE's code segment and is zeroed in the image. 02661 */ 02662 02663 wMaxMsg = max(gSharedInfo.DefWindowMsgs.maxMsgs, 02664 gSharedInfo.DefWindowSpecMsgs.maxMsgs); 02665 02666 UserAssert((wMaxMsg / 8 + 1) <= cbDefWindowProcBits); 02667 02668 // 02669 // If the above assertion fires, the size of the DWPBits array in 02670 // \nt\private\mvdm\wow16\user\user.asm needs to be increased. 02671 // 02672 02673 /* First copy the bits from DefWindowMsgs */ 02674 02675 RtlCopyMemory( 02676 pDefWindowProcBits, 02677 gSharedInfo.DefWindowMsgs.abMsgs, 02678 gSharedInfo.DefWindowMsgs.maxMsgs / 8 + 1 02679 ); 02680 02681 /* Next OR in the bits from DefWindowSpecMsgs */ 02682 02683 pbSrc = gSharedInfo.DefWindowSpecMsgs.abMsgs; 02684 pbDst = pDefWindowProcBits; 02685 pbDstEnd = pbDst + (gSharedInfo.DefWindowSpecMsgs.maxMsgs / 8 + 1); 02686 02687 while (pbDst < pbDstEnd) 02688 { 02689 *pbDst++ |= *pbSrc++; 02690 } 02691 02692 return wMaxMsg; 02693 } 02694 02695 02696 ULONG_PTR UserRegisterWowHandlers( 02697 APFNWOWHANDLERSIN apfnWowIn, 02698 APFNWOWHANDLERSOUT apfnWowOut) 02699 { 02700 02701 // In'ees 02702 pfnLocalAlloc = apfnWowIn->pfnLocalAlloc; 02703 pfnLocalReAlloc = apfnWowIn->pfnLocalReAlloc; 02704 pfnLocalLock = apfnWowIn->pfnLocalLock; 02705 pfnLocalUnlock = apfnWowIn->pfnLocalUnlock; 02706 pfnLocalSize = apfnWowIn->pfnLocalSize; 02707 pfnLocalFree = apfnWowIn->pfnLocalFree; 02708 pfnGetExpWinVer = apfnWowIn->pfnGetExpWinVer; 02709 pfn16GlobalAlloc = apfnWowIn->pfn16GlobalAlloc; 02710 pfn16GlobalFree = apfnWowIn->pfn16GlobalFree; 02711 pfnWowEmptyClipBoard = apfnWowIn->pfnEmptyCB; 02712 pfnWowEditNextWord = apfnWowIn->pfnWowEditNextWord; 02713 pfnWowCBStoreHandle = apfnWowIn->pfnWowCBStoreHandle; 02714 pfnFindResourceExA = apfnWowIn->pfnFindResourceEx; 02715 pfnLoadResource = apfnWowIn->pfnLoadResource; 02716 pfnLockResource = apfnWowIn->pfnLockResource; 02717 pfnUnlockResource = apfnWowIn->pfnUnlockResource; 02718 pfnFreeResource = apfnWowIn->pfnFreeResource; 02719 pfnSizeofResource = apfnWowIn->pfnSizeofResource; 02720 pfnFindResourceExW = WOWFindResourceExWCover; 02721 pfnWowDlgProcEx = apfnWowIn->pfnWowDlgProcEx; 02722 pfnWowWndProcEx = apfnWowIn->pfnWowWndProcEx; 02723 pfnWowGetProcModule = apfnWowIn->pfnGetProcModule16; 02724 pfnWOWTellWOWThehDlg = apfnWowIn->pfnWOWTellWOWThehDlg; 02725 pfnWowMsgBoxIndirectCallback = apfnWowIn->pfnWowMsgBoxIndirectCallback; 02726 pfnWowIlstrcmp = apfnWowIn->pfnWowIlstrsmp; 02727 02728 // Out'ees 02729 #if DBG 02730 apfnWowOut->dwBldInfo = (WINVER << 16) | 0x80000000; 02731 #else 02732 apfnWowOut->dwBldInfo = (WINVER << 16); 02733 #endif 02734 apfnWowOut->pfnCsCreateWindowEx = _CreateWindowEx; 02735 apfnWowOut->pfnDirectedYield = DirectedYield; 02736 apfnWowOut->pfnFreeDDEData = FreeDDEData; 02737 apfnWowOut->pfnGetClassWOWWords = GetClassWOWWords; 02738 apfnWowOut->pfnInitTask = InitTask; 02739 apfnWowOut->pfnRegisterClassWOWA = RegisterClassWOWA; 02740 apfnWowOut->pfnRegisterUserHungAppHandlers = RegisterUserHungAppHandlers; 02741 apfnWowOut->pfnServerCreateDialog = InternalCreateDialog; 02742 apfnWowOut->pfnServerLoadCreateCursorIcon = WowServerLoadCreateCursorIcon; 02743 apfnWowOut->pfnServerLoadCreateMenu = WowServerLoadCreateMenu; 02744 apfnWowOut->pfnWOWCleanup = WOWCleanup; 02745 apfnWowOut->pfnWOWModuleUnload = WOWModuleUnload; 02746 apfnWowOut->pfnWOWFindWindow = WOWFindWindow; 02747 apfnWowOut->pfnWOWLoadBitmapA = WOWLoadBitmapA; 02748 apfnWowOut->pfnWowWaitForMsgAndEvent = NtUserWaitForMsgAndEvent; 02749 apfnWowOut->pfnYieldTask = NtUserYieldTask; 02750 apfnWowOut->pfnGetFullUserHandle = GetFullUserHandle; 02751 apfnWowOut->pfnGetMenuIndex = NtUserGetMenuIndex; 02752 apfnWowOut->pfnWowGetDefWindowProcBits = WowGetDefWindowProcBits; 02753 apfnWowOut->pfnFillWindow = FillWindow; 02754 apfnWowOut->aiWowClass = aiClassWow; 02755 return (ULONG_PTR)&gSharedInfo; 02756 } 02757 02758 /***************************************************************************\ 02759 * GetEditDS 02760 * 02761 * This is a callback to WOW used to allocate a segment for DS_LOCALEDIT 02762 * edit controls. The segment is disguised to look like a WOW hInstance. 02763 * 02764 * 06-19-92 sanfords Created 02765 \***************************************************************************/ 02766 HANDLE GetEditDS() 02767 { 02768 UserAssert(pfn16GlobalAlloc != NULL); 02769 02770 return((HANDLE)((*pfn16GlobalAlloc)(GHND | GMEM_SHARE, 256))); 02771 } 02772 02773 02774 02775 /***************************************************************************\ 02776 * ReleaseEditDS 02777 * 02778 * This is a callback to WOW used to free a segment for DS_LOCALEDIT 02779 * edit controls. 02780 * 02781 * 06-19-92 sanfords Created 02782 \***************************************************************************/ 02783 VOID ReleaseEditDS( 02784 HANDLE h) 02785 { 02786 UserAssert(pfn16GlobalFree != NULL); 02787 02788 (*pfn16GlobalFree)(LOWORD(HandleToUlong(h))); 02789 } 02790 02791 02792 02793 /***************************************************************************\ 02794 * TellWOWThehDlg 02795 * 02796 * This is a callback to WOW used to inform WOW of the hDlg of a newly 02797 * created dialog window. 02798 * 02799 * 08-31-97 cmjones Created 02800 \***************************************************************************/ 02801 VOID TellWOWThehDlg( 02802 HWND hDlg) 02803 { 02804 UserAssert(pfnWOWTellWOWThehDlg != NULL); 02805 02806 (*pfnWOWTellWOWThehDlg)(hDlg); 02807 } 02808 02809 02810 02811 /***************************************************************************\ 02812 * DispatchMessage 02813 * 02814 * !!! Warning if this function becomes more complicated then look at the 02815 * server code for WrapCallProc 02816 * 02817 * pwnd is threadlocked in the kernel and thus always valid. 02818 * 02819 * 19-Aug-1992 mikeke created 02820 \***************************************************************************/ 02821 02822 LRESULT DispatchClientMessage( 02823 PWND pwnd, 02824 UINT message, 02825 WPARAM wParam, 02826 LPARAM lParam, 02827 ULONG_PTR pfn) 02828 { 02829 HWND hwnd = GetClientInfo()->CallbackWnd.hwnd; 02830 02831 /* 02832 * Assert that the header comment is legit (must be). 02833 * for WM_TIMERs not associated to a window, pwnd can be NULL. So 02834 * don't rip validating the handle. 02835 */ 02836 UserAssert(pwnd == ValidateHwndNoRip(hwnd)); 02837 02838 /* 02839 * Add assert to catch dispatching messages to a thread not associated 02840 * with a desktop. 02841 */ 02842 UserAssert(GetClientInfo()->ulClientDelta != 0); 02843 02844 /* 02845 * More complicate then regular CALLPROC_WOWCHECK() we want to get the 02846 * PWW so wow doesn't have to 02847 */ 02848 02849 /* Bug 234292 - joejo 02850 * Since the called window/dialog proc may have a different calling 02851 * convention, we must wrap the call and, check esp and replace with 02852 * a good esp when the call returns. This is what UserCallWinProc* does. 02853 */ 02854 #ifdef _WIN64 02855 UNREFERENCED_PARAMETER(pwnd); 02856 #endif 02857 02858 return CALLPROC_WOWCHECKPWW((WNDPROC)pfn, hwnd, message, wParam, lParam, &(pwnd->state)); 02859 02860 } 02861 02862 /**************************************************************************\ 02863 * ArrangeIconicWindows 02864 * 02865 * 22-Jul-1991 mikeke Created 02866 \**************************************************************************/ 02867 02868 UINT ArrangeIconicWindows( 02869 HWND hwnd) 02870 { 02871 return (UINT)NtUserCallHwndLock(hwnd, SFI_XXXARRANGEICONICWINDOWS); 02872 } 02873 02874 /**************************************************************************\ 02875 * BeginDeferWindowPos 02876 * 02877 * 22-Jul-1991 mikeke Created 02878 \**************************************************************************/ 02879 02880 HANDLE BeginDeferWindowPos( 02881 int nNumWindows) 02882 { 02883 if (nNumWindows < 0) { 02884 RIPERR1(ERROR_INVALID_PARAMETER, 02885 RIP_WARNING, 02886 "Invalid parameter \"nNumWindows\" (%ld) to BeginDeferWindowPos", 02887 nNumWindows); 02888 02889 return 0; 02890 } 02891 02892 return (HANDLE)NtUserCallOneParam(nNumWindows, SFI__BEGINDEFERWINDOWPOS); 02893 } 02894 02895 /**************************************************************************\ 02896 * EndDeferWindowPos 02897 * 02898 * 22-Jul-1991 mikeke Created 02899 \**************************************************************************/ 02900 02901 BOOL EndDeferWindowPos( 02902 HDWP hWinPosInfo) 02903 { 02904 return NtUserEndDeferWindowPosEx(hWinPosInfo, FALSE); 02905 } 02906 02907 /**************************************************************************\ 02908 * CascadeChildWindows 02909 * 02910 * 22-Jul-1991 mikeke Created 02911 \**************************************************************************/ 02912 02913 BOOL CascadeChildWindows( 02914 HWND hwndParent, 02915 UINT nCode) 02916 { 02917 return (BOOL) CascadeWindows(hwndParent, nCode, NULL, 0, NULL); 02918 } 02919 02920 /**************************************************************************\ 02921 * CloseWindow 02922 * 02923 * 22-Jul-1991 mikeke Created 02924 * 17-Feb-1998 MCostea Use xxxShowWindow instead of xxxCloseWindow 02925 \**************************************************************************/ 02926 02927 BOOL CloseWindow( 02928 HWND hwnd) 02929 { 02930 PWND pwnd; 02931 02932 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 02933 return FALSE; 02934 } 02935 if (!TestWF(pwnd, WFMINIMIZED)) { 02936 NtUserShowWindow(hwnd, SW_SHOWMINIMIZED); 02937 } 02938 return TRUE; 02939 } 02940 02941 /**************************************************************************\ 02942 * CreateMenu 02943 * 02944 * 22-Jul-1991 mikeke Created 02945 \**************************************************************************/ 02946 02947 HMENU CreateMenu() 02948 { 02949 return (HMENU)NtUserCallNoParam(SFI__CREATEMENU); 02950 } 02951 02952 /**************************************************************************\ 02953 * CreatePopupMenu 02954 * 02955 * 22-Jul-1991 mikeke Created 02956 \**************************************************************************/ 02957 02958 HMENU CreatePopupMenu() 02959 { 02960 return (HMENU)NtUserCallNoParam(SFI__CREATEPOPUPMENU); 02961 } 02962 02963 /**************************************************************************\ 02964 * CurrentTaskLock 02965 * 02966 * 21-Apr-1992 jonpa Created 02967 \**************************************************************************/ 02968 #if 0 /* WOW is not using this but they might some day */ 02969 DWORD CurrentTaskLock( 02970 DWORD hlck) 02971 { 02972 return (DWORD)NtUserCallOneParam(hlck, SFI_CURRENTTASKLOCK); 02973 } 02974 #endif 02975 /**************************************************************************\ 02976 * DestroyCaret 02977 * 02978 * 22-Jul-1991 mikeke Created 02979 \**************************************************************************/ 02980 02981 BOOL DestroyCaret() 02982 { 02983 return (BOOL)NtUserCallNoParam(SFI_ZZZDESTROYCARET); 02984 } 02985 02986 /**************************************************************************\ 02987 * DirectedYield 02988 * 02989 * 22-Jul-1991 mikeke Created 02990 \**************************************************************************/ 02991 02992 void DirectedYield( 02993 DWORD dwThreadId) 02994 { 02995 NtUserCallOneParam(dwThreadId, SFI_XXXDIRECTEDYIELD); 02996 } 02997 02998 /**************************************************************************\ 02999 * DrawMenuBar 03000 * 03001 * 22-Jul-1991 mikeke Created 03002 \**************************************************************************/ 03003 03004 BOOL DrawMenuBar( 03005 HWND hwnd) 03006 { 03007 return (BOOL)NtUserCallHwndLock(hwnd, SFI_XXXDRAWMENUBAR); 03008 } 03009 03010 /**************************************************************************\ 03011 * EnableWindow 03012 * 03013 * 22-Jul-1991 mikeke Created 03014 \**************************************************************************/ 03015 03016 BOOL EnableWindow( 03017 HWND hwnd, 03018 BOOL bEnable) 03019 { 03020 return (BOOL)NtUserCallHwndParamLock(hwnd, bEnable, 03021 SFI_XXXENABLEWINDOW); 03022 } 03023 03024 /**************************************************************************\ 03025 * EnumClipboardFormats 03026 * 03027 * 22-Jul-1991 mikeke Created 03028 \**************************************************************************/ 03029 03030 UINT EnumClipboardFormats( 03031 UINT fmt) 03032 { 03033 /* 03034 * So apps can tell if the API failed or just ran out of formats 03035 * we "clear" the last error. 03036 */ 03037 UserSetLastError(ERROR_SUCCESS); 03038 03039 return (UINT)NtUserCallOneParam(fmt, SFI__ENUMCLIPBOARDFORMATS); 03040 } 03041 03042 /**************************************************************************\ 03043 * FlashWindow 03044 * 03045 * 22-Jul-1991 mikeke Created 03046 * 08-Aug-1997 Gerardob Added FlashWindowEx. 03047 * 16-Nov-1997 MCostea Make it use NtUserFlashWindowEx 03048 \**************************************************************************/ 03049 03050 BOOL FlashWindow( 03051 HWND hwnd, 03052 BOOL bInvert) 03053 { 03054 FLASHWINFO fwi = { 03055 sizeof(FLASHWINFO), // cbSize 03056 hwnd, // hwnd 03057 bInvert ? (FLASHW_CAPTION | FLASHW_TRAY) : 0, // flags 03058 1, // uCount 03059 0 // dwTimeout 03060 }; 03061 return (BOOL)NtUserFlashWindowEx(&fwi); 03062 } 03063 03064 /**************************************************************************\ 03065 * GetDialogBaseUnits 03066 * 03067 * 22-Jul-1991 mikeke Created 03068 \**************************************************************************/ 03069 03070 long GetDialogBaseUnits() 03071 { 03072 return MAKELONG(gpsi->cxSysFontChar, gpsi->cySysFontChar); 03073 } 03074 03075 /**************************************************************************\ 03076 * GetInputDesktop 03077 * 03078 * 22-Jul-1991 mikeke Created 03079 \**************************************************************************/ 03080 03081 HDESK GetInputDesktop() 03082 { 03083 return (HDESK)NtUserCallNoParam(SFI_XXXGETINPUTDESKTOP); 03084 } 03085 03086 /***************************************************************************\ 03087 * GetClientKeyboardType 03088 * 03089 * This routine returns the keyboard type sent from the Hydra client. 03090 * Hydra client sends keyboard types at session startup. 03091 * 03092 * Returns the client winstation specified a keyboard type. 03093 * History: 03094 \***************************************************************************/ 03095 03096 BOOL 03097 GetClientKeyboardType(PCLIENTKEYBOARDTYPE KeyboardType) 03098 { 03099 ULONG Length; 03100 WINSTATIONCLIENTW ClientData; 03101 static CLIENTKEYBOARDTYPE ClientKeyboard = { (ULONG)-1, (ULONG)-1, (ULONG)-1 }; 03102 03103 // 03104 // Should be called only if this is a HYDRA remote session. 03105 // 03106 UserAssert(ISREMOTESESSION()); 03107 03108 // Skip if this is the console 03109 if (!ISREMOTESESSION()) { 03110 return FALSE; 03111 } 03112 03113 if (ClientKeyboard.Type == (ULONG)-1) { 03114 03115 // Fetch the WinStation's basic information 03116 if (!WinStaQueryInformationW(SERVERNAME_CURRENT, 03117 LOGONID_CURRENT, 03118 WinStationClient, 03119 &ClientData, 03120 sizeof(ClientData), 03121 &Length)) { 03122 return FALSE; 03123 } 03124 03125 ClientKeyboard.Type = ClientData.KeyboardType; 03126 ClientKeyboard.SubType = ClientData.KeyboardSubType; 03127 ClientKeyboard.FunctionKey = ClientData.KeyboardFunctionKey; 03128 03129 } 03130 03131 *KeyboardType = ClientKeyboard; 03132 03133 return TRUE; 03134 } 03135 03136 03137 /**************************************************************************\ 03138 * GetKeyboardType 03139 * 03140 * 22-Jul-1991 mikeke Created 03141 \**************************************************************************/ 03142 03143 int GetKeyboardType( 03144 int nTypeFlags) 03145 { 03146 if (ISREMOTESESSION()) { 03147 // 03148 // Get keyboard type from Hydra client if this is not the console 03149 // 03150 CLIENTKEYBOARDTYPE KeyboardType; 03151 03152 if (GetClientKeyboardType(&KeyboardType)) { 03153 switch (nTypeFlags) { 03154 case 0: 03155 return KeyboardType.Type; 03156 case 1: 03157 if (KeyboardType.Type == 7) { /* 7 is a Japanese */ 03158 // Because HIWORD has been using private value 03159 // for Japanese keyboard layout. 03160 return LOWORD(KeyboardType.SubType); 03161 } 03162 else 03163 return KeyboardType.SubType; 03164 case 2: 03165 return KeyboardType.FunctionKey; 03166 default: 03167 break; 03168 } 03169 } 03170 return 0; 03171 } 03172 return (int)NtUserCallOneParam(nTypeFlags, SFI__GETKEYBOARDTYPE); 03173 } 03174 03175 /**************************************************************************\ 03176 * GetMessagePos 03177 * 03178 * 22-Jul-1991 mikeke Created 03179 \**************************************************************************/ 03180 03181 DWORD GetMessagePos() 03182 { 03183 return (DWORD)NtUserCallNoParam(SFI__GETMESSAGEPOS); 03184 } 03185 03186 /**************************************************************************\ 03187 * GetQueueStatus 03188 * 03189 * 22-Jul-1991 mikeke Created 03190 \**************************************************************************/ 03191 03192 DWORD GetQueueStatus( 03193 UINT flags) 03194 { 03195 if (flags & ~QS_VALID) { 03196 RIPERR2(ERROR_INVALID_FLAGS, RIP_WARNING, "Invalid flags %x & ~%x != 0", 03197 flags, QS_VALID); 03198 return 0; 03199 } 03200 03201 return (DWORD)NtUserCallOneParam(flags, SFI__GETQUEUESTATUS); 03202 } 03203 03204 /**************************************************************************\ 03205 * KillSystemTimer 03206 * 03207 * 7-Jul-1992 mikehar Created 03208 \**************************************************************************/ 03209 03210 BOOL KillSystemTimer( 03211 HWND hwnd, 03212 UINT nIDEvent) 03213 { 03214 return (BOOL)NtUserCallHwndParam(hwnd, nIDEvent, SFI__KILLSYSTEMTIMER); 03215 } 03216 03217 /**************************************************************************\ 03218 * LoadRemoteFonts 03219 * 02-Dec-1993 -by- Bodin Dresevic [BodinD] 03220 * Wrote it. 03221 \**************************************************************************/ 03222 03223 void LoadRemoteFonts(void) 03224 { 03225 NtUserCallOneParam(TRUE,SFI_XXXLW_LOADFONTS); 03226 03227 /* 03228 * After load remote fonts, let eudc enabled. 03229 */ 03230 EnableEUDC(TRUE); 03231 } 03232 03233 03234 /**************************************************************************\ 03235 * LoadLocalFonts 03236 * 31-Mar-1994 -by- Bodin Dresevic [gerritv] 03237 * Wrote it. 03238 \**************************************************************************/ 03239 03240 void LoadLocalFonts(void) 03241 { 03242 NtUserCallOneParam(FALSE,SFI_XXXLW_LOADFONTS); 03243 } 03244 03245 03246 /**************************************************************************\ 03247 * MessageBeep 03248 * 03249 * 22-Jul-1991 mikeke Created 03250 \**************************************************************************/ 03251 03252 BOOL MessageBeep( 03253 UINT wType) 03254 { 03255 return (BOOL)NtUserCallOneParam(wType, SFI_XXXMESSAGEBEEP); 03256 } 03257 03258 /**************************************************************************\ 03259 * OpenIcon 03260 * 03261 * 22-Jul-1991 mikeke Created 03262 * 17-Feb-1998 MCostea Use xxxShowWindow instead of xxxCloseWindow 03263 \**************************************************************************/ 03264 03265 BOOL OpenIcon( 03266 HWND hwnd) 03267 { 03268 PWND pwnd; 03269 03270 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 03271 return FALSE; 03272 } 03273 if (TestWF(pwnd, WFMINIMIZED)) { 03274 NtUserShowWindow(hwnd, SW_NORMAL); 03275 } 03276 return TRUE; 03277 } 03278 03279 HWND GetShellWindow(void) { 03280 PCLIENTINFO pci; 03281 PWND pwnd; 03282 03283 ConnectIfNecessary(); 03284 03285 pci = GetClientInfo(); 03286 pwnd = pci->pDeskInfo->spwndShell; 03287 if (pwnd != NULL) { 03288 pwnd = (PWND)((KERNEL_ULONG_PTR)pwnd - pci->ulClientDelta); 03289 return HWq(pwnd); 03290 } 03291 return NULL; 03292 } 03293 03294 BOOL SetShellWindow(HWND hwnd) { 03295 return (BOOL)NtUserSetShellWindowEx(hwnd, hwnd); 03296 } 03297 03298 HWND GetProgmanWindow(void) { 03299 PCLIENTINFO pci; 03300 PWND pwnd; 03301 03302 ConnectIfNecessary(); 03303 03304 pci = GetClientInfo(); 03305 pwnd = pci->pDeskInfo->spwndProgman; 03306 if (pwnd != NULL) { 03307 pwnd = (PWND)((KERNEL_ULONG_PTR)pwnd - pci->ulClientDelta); 03308 return HWq(pwnd); 03309 } 03310 return NULL; 03311 } 03312 03313 BOOL SetProgmanWindow( 03314 HWND hwnd) 03315 { 03316 return (BOOL)NtUserCallHwndOpt(hwnd, SFI__SETPROGMANWINDOW); 03317 } 03318 03319 HWND GetTaskmanWindow(void) { 03320 PCLIENTINFO pci; 03321 PWND pwnd; 03322 03323 ConnectIfNecessary(); 03324 03325 pci = GetClientInfo(); 03326 pwnd = pci->pDeskInfo->spwndTaskman; 03327 if (pwnd != NULL) { 03328 pwnd = (PWND)((KERNEL_ULONG_PTR)pwnd - pci->ulClientDelta); 03329 return HWq(pwnd); 03330 } 03331 return NULL; 03332 } 03333 03334 BOOL SetTaskmanWindow( 03335 HWND hwnd) 03336 { 03337 return (BOOL)NtUserCallHwndOpt(hwnd, SFI__SETTASKMANWINDOW); 03338 } 03339 03340 /**************************************************************************\ 03341 * SetWindowContextHelpId 03342 * 03343 * 22-Jul-1991 mikeke Created 03344 \**************************************************************************/ 03345 03346 BOOL SetWindowContextHelpId( 03347 HWND hwnd, 03348 DWORD id) 03349 { 03350 return (BOOL)NtUserCallHwndParam(hwnd, id, SFI__SETWINDOWCONTEXTHELPID); 03351 } 03352 03353 /**************************************************************************\ 03354 * GetWindowContextHelpId 03355 * 03356 * 22-Jul-1991 mikeke Created 03357 \**************************************************************************/ 03358 03359 DWORD GetWindowContextHelpId( 03360 HWND hwnd) 03361 { 03362 return (BOOL)NtUserCallHwnd(hwnd, SFI__GETWINDOWCONTEXTHELPID); 03363 } 03364 03365 void SetWindowState( 03366 PWND pwnd, 03367 UINT flags) 03368 { 03369 if (TestWF(pwnd, flags) != LOBYTE(flags)) 03370 NtUserCallHwndParam(HWq(pwnd), flags, SFI_SETWINDOWSTATE); 03371 } 03372 03373 void ClearWindowState( 03374 PWND pwnd, 03375 UINT flags) 03376 { 03377 if (TestWF(pwnd, flags)) 03378 NtUserCallHwndParam(HWq(pwnd), flags, SFI_CLEARWINDOWSTATE); 03379 } 03380 03381 /**************************************************************************\ 03382 * PostQuitMessage 03383 * 03384 * 22-Jul-1991 mikeke Created 03385 \**************************************************************************/ 03386 03387 VOID PostQuitMessage( 03388 int nExitCode) 03389 { 03390 NtUserCallOneParam(nExitCode, SFI__POSTQUITMESSAGE); 03391 } 03392 03393 /**************************************************************************\ 03394 * REGISTERUSERHUNAPPHANDLERS 03395 * 03396 * 01-Apr-1992 jonpa Created 03397 \**************************************************************************/ 03398 03399 BOOL RegisterUserHungAppHandlers( 03400 PFNW32ET pfnW32EndTask, 03401 HANDLE hEventWowExec) 03402 { 03403 return (BOOL)NtUserCallTwoParam((ULONG_PTR)pfnW32EndTask, 03404 (ULONG_PTR)hEventWowExec, 03405 SFI_XXXREGISTERUSERHUNGAPPHANDLERS); 03406 } 03407 03408 /**************************************************************************\ 03409 * ReleaseCapture 03410 * 03411 * 22-Jul-1991 mikeke Created 03412 \**************************************************************************/ 03413 03414 BOOL ReleaseCapture() 03415 { 03416 return (BOOL)NtUserCallNoParam(SFI_XXXRELEASECAPTURE); 03417 } 03418 03419 /**************************************************************************\ 03420 * ReplyMessage 03421 * 03422 * 22-Jul-1991 mikeke Created 03423 \**************************************************************************/ 03424 03425 BOOL ReplyMessage( 03426 LRESULT pp1) 03427 { 03428 return (BOOL)NtUserCallOneParam(pp1, SFI__REPLYMESSAGE); 03429 } 03430 03431 /**************************************************************************\ 03432 * RegisterSystemThread 03433 * 03434 * 21-Jun-1994 johnc Created 03435 \**************************************************************************/ 03436 03437 VOID RegisterSystemThread( 03438 DWORD dwFlags, DWORD dwReserved) 03439 { 03440 NtUserCallTwoParam(dwFlags, dwReserved, SFI_ZZZREGISTERSYSTEMTHREAD); 03441 } 03442 03443 /**************************************************************************\ 03444 * SetCaretBlinkTime 03445 * 03446 * 22-Jul-1991 mikeke Created 03447 \**************************************************************************/ 03448 03449 BOOL SetCaretBlinkTime( 03450 UINT wMSeconds) 03451 { 03452 return (BOOL)NtUserCallOneParam(wMSeconds, SFI__SETCARETBLINKTIME); 03453 } 03454 03455 /**************************************************************************\ 03456 * SetCaretPos 03457 * 03458 * 22-Jul-1991 mikeke Created 03459 \**************************************************************************/ 03460 03461 BOOL SetCaretPos( 03462 int X, 03463 int Y) 03464 { 03465 return (BOOL)NtUserCallTwoParam(X, Y, SFI_ZZZSETCARETPOS); 03466 } 03467 03468 /**************************************************************************\ 03469 * SetCursorPos 03470 * 03471 * 22-Jul-1991 mikeke Created 03472 \**************************************************************************/ 03473 03474 BOOL SetCursorPos( 03475 int X, 03476 int Y) 03477 { 03478 return (BOOL)NtUserCallTwoParam(X, Y, SFI_ZZZSETCURSORPOS); 03479 } 03480 03481 /**************************************************************************\ 03482 * SetDoubleClickTime 03483 * 03484 * 22-Jul-1991 mikeke Created 03485 \**************************************************************************/ 03486 03487 BOOL SetDoubleClickTime( 03488 UINT cms) 03489 { 03490 return (BOOL)NtUserCallOneParam(cms, SFI__SETDOUBLECLICKTIME); 03491 } 03492 03493 /**************************************************************************\ 03494 * SetForegroundWindow 03495 * 03496 * 22-Jul-1991 mikeke Created 03497 \**************************************************************************/ 03498 03499 BOOL SetForegroundWindow( 03500 HWND hwnd) 03501 { 03502 return NtUserSetForegroundWindow(hwnd); 03503 } 03504 /**************************************************************************\ 03505 * AllowSetForegroundWindow 03506 * 03507 * 28-Jan-1998 GerardoB Created 03508 \**************************************************************************/ 03509 BOOL AllowSetForegroundWindow( 03510 DWORD dwProcessId) 03511 { 03512 return (BOOL)NtUserCallOneParam(dwProcessId, SFI_XXXALLOWSETFOREGROUNDWINDOW); 03513 } 03514 /**************************************************************************\ 03515 * LockSetForegroundWindow 03516 * 03517 * 07-Apr-1998 GerardoB Created 03518 \**************************************************************************/ 03519 BOOL LockSetForegroundWindow( 03520 UINT uLockCode) 03521 { 03522 return (BOOL)NtUserCallOneParam(uLockCode, SFI__LOCKSETFOREGROUNDWINDOW); 03523 } 03524 03525 /**************************************************************************\ 03526 * ShowCursor 03527 * 03528 * 22-Jul-1991 mikeke Created 03529 \**************************************************************************/ 03530 03531 int ShowCursor( 03532 BOOL bShow) 03533 { 03534 return (int)NtUserCallOneParam(bShow, SFI_ZZZSHOWCURSOR); 03535 } 03536 03537 /**************************************************************************\ 03538 * ShowOwnedPopups 03539 * 03540 * 22-Jul-1991 mikeke Created 03541 \**************************************************************************/ 03542 03543 BOOL ShowOwnedPopups( 03544 HWND hwnd, 03545 BOOL fShow) 03546 { 03547 return (BOOL)NtUserCallHwndParamLock(hwnd, fShow, 03548 SFI_XXXSHOWOWNEDPOPUPS); 03549 } 03550 03551 /**************************************************************************\ 03552 * ShowStartGlass 03553 * 03554 * 10-Sep-1992 scottlu Created 03555 \**************************************************************************/ 03556 03557 void ShowStartGlass( 03558 DWORD dwTimeout) 03559 { 03560 NtUserCallOneParam(dwTimeout, SFI_ZZZSHOWSTARTGLASS); 03561 } 03562 03563 /**************************************************************************\ 03564 * SwapMouseButton 03565 * 03566 * 22-Jul-1991 mikeke Created 03567 \**************************************************************************/ 03568 03569 BOOL SwapMouseButton( 03570 BOOL fSwap) 03571 { 03572 return (BOOL)NtUserCallOneParam(fSwap, SFI__SWAPMOUSEBUTTON); 03573 } 03574 03575 /**************************************************************************\ 03576 * TileChildWindows 03577 * 03578 * 22-Jul-1991 mikeke Created 03579 \**************************************************************************/ 03580 03581 BOOL TileChildWindows( 03582 HWND hwndParent, 03583 UINT flags) 03584 { 03585 return (BOOL)TileWindows(hwndParent, flags, NULL, 0, NULL); 03586 } 03587 03588 /**************************************************************************\ 03589 * UnhookWindowsHook 03590 * 03591 * 22-Jul-1991 mikeke Created 03592 \**************************************************************************/ 03593 03594 BOOL UnhookWindowsHook( 03595 int nCode, 03596 HOOKPROC pfnFilterProc) 03597 { 03598 return (BOOL)NtUserCallTwoParam(nCode, (ULONG_PTR)pfnFilterProc, 03599 SFI_ZZZUNHOOKWINDOWSHOOK); 03600 } 03601 03602 /**************************************************************************\ 03603 * UpdateWindow 03604 * 03605 * 22-Jul-1991 mikeke Created 03606 \**************************************************************************/ 03607 03608 BOOL UpdateWindow( 03609 HWND hwnd) 03610 { 03611 PWND pwnd; 03612 03613 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 03614 return FALSE; 03615 } 03616 03617 /* 03618 * Don't need to do anything if this window does not need any painting 03619 * and it has no child windows 03620 */ 03621 if (!NEEDSPAINT(pwnd) && (pwnd->spwndChild == NULL)) { 03622 return TRUE; 03623 } 03624 03625 return (BOOL)NtUserCallHwndLock(hwnd, SFI_XXXUPDATEWINDOW); 03626 } 03627 03628 BOOL RegisterShellHookWindow( 03629 HWND hwnd) 03630 { 03631 return (BOOL)NtUserCallHwnd(hwnd, SFI__REGISTERSHELLHOOKWINDOW); 03632 } 03633 03634 BOOL DeregisterShellHookWindow( 03635 HWND hwnd) 03636 { 03637 return (BOOL)NtUserCallHwnd(hwnd, SFI__DEREGISTERSHELLHOOKWINDOW); 03638 } 03639 03640 /**************************************************************************\ 03641 * UserRealizePalette 03642 * 03643 * 13-Nov-1992 mikeke Created 03644 \**************************************************************************/ 03645 03646 UINT UserRealizePalette( 03647 HDC hdc) 03648 { 03649 return (UINT)NtUserCallOneParam((ULONG_PTR)hdc, SFI_XXXREALIZEPALETTE); 03650 } 03651 03652 /**************************************************************************\ 03653 * WindowFromDC 03654 * 03655 * 22-Jul-1991 mikeke Created 03656 \**************************************************************************/ 03657 03658 HWND WindowFromDC( 03659 HDC hdc) 03660 { 03661 return (HWND)NtUserCallOneParam((ULONG_PTR)hdc, SFI__WINDOWFROMDC); 03662 } 03663 03664 /***************************************************************************\ 03665 * GetWindowRgn 03666 * 03667 * Parameters: 03668 * hwnd -- Window handle 03669 * hrgn -- Region to copy window region into 03670 * 03671 * Returns: 03672 * Region complexity code 03673 * 03674 * Comments: 03675 * hrgn gets returned in window rect coordinates (not client rect) 03676 * 03677 * 30-JUl-1994 ScottLu Created. 03678 \***************************************************************************/ 03679 03680 int GetWindowRgn(HWND hwnd, HRGN hrgn) 03681 { 03682 int code; 03683 PWND pwnd; 03684 03685 if (hrgn == NULL) 03686 return ERROR; 03687 03688 if ((pwnd = ValidateHwnd(hwnd)) == NULL) { 03689 return ERROR; 03690 } 03691 03692 /* 03693 * If there is no region selected into this window, then return error 03694 */ 03695 if (pwnd->hrgnClip == NULL || TestWF(pwnd, WFMAXFAKEREGIONAL)) { 03696 return ERROR; 03697 } 03698 03699 code = CombineRgn(hrgn, pwnd->hrgnClip, NULL, RGN_COPY); 03700 03701 if (code == ERROR) 03702 return ERROR; 03703 03704 /* 03705 * Offset it to window rect coordinates (not client rect coordinates) 03706 */ 03707 if (GETFNID(pwnd) != FNID_DESKTOP) { 03708 code = OffsetRgn(hrgn, -pwnd->rcWindow.left, -pwnd->rcWindow.top); 03709 } 03710 03711 #ifdef USE_MIRRORING 03712 if (TestWF(pwnd, WEFLAYOUTRTL)) { 03713 MirrorRgn(HW(pwnd), hrgn); 03714 } 03715 #endif 03716 03717 return code; 03718 } 03719 03720 /***************************************************************************\ 03721 * GetActiveKeyboardName 03722 * 03723 * Retrieves the active keyboard layout ID from the registry. 03724 * 03725 * 01-11-95 JimA Created. 03726 * 03-06-95 GregoryW Modified to use new registry layout 03727 \***************************************************************************/ 03728 03729 VOID GetActiveKeyboardName( 03730 LPWSTR lpszName) 03731 { 03732 LPTSTR szKbdActive = TEXT("Active"); 03733 LPTSTR szKbdLayout = TEXT("Keyboard Layout"); 03734 LPTSTR szKbdLayoutPreload = TEXT("Keyboard Layout\\Preload"); 03735 NTSTATUS rc; 03736 DWORD cbSize; 03737 HANDLE UserKeyHandle, hKey, hKeyPreload; 03738 OBJECT_ATTRIBUTES ObjA; 03739 UNICODE_STRING UnicodeString; 03740 ULONG CreateDisposition; 03741 struct { 03742 KEY_VALUE_PARTIAL_INFORMATION KeyInfo; 03743 WCHAR KeyLayoutId[KL_NAMELENGTH]; 03744 } KeyValueId; 03745 03746 /* 03747 * Load initial keyboard name ( HKEY_CURRENT_USER\Keyboard Layout\Preload\1 ) 03748 */ 03749 rc = RtlOpenCurrentUser( MAXIMUM_ALLOWED, &UserKeyHandle ); 03750 if (!NT_SUCCESS( rc )) 03751 { 03752 RIPMSG1( RIP_WARNING, "GetActiveKeyboardName - Could NOT open HKEY_CURRENT_USER (%lx).\n", rc ); 03753 wcscpy( lpszName, L"00000409" ); 03754 return; 03755 } 03756 03757 RtlInitUnicodeString( &UnicodeString, szKbdLayoutPreload ); 03758 InitializeObjectAttributes( &ObjA, 03759 &UnicodeString, 03760 OBJ_CASE_INSENSITIVE, 03761 UserKeyHandle, 03762 NULL ); 03763 rc = NtOpenKey( &hKey, 03764 KEY_ALL_ACCESS, 03765 &ObjA ); 03766 if (NT_SUCCESS( rc )) 03767 { 03768 /* 03769 * Query the value from the registry. 03770 */ 03771 RtlInitUnicodeString( &UnicodeString, L"1" ); 03772 03773 rc = NtQueryValueKey( hKey, 03774 &UnicodeString, 03775 KeyValuePartialInformation, 03776 &KeyValueId, 03777 sizeof(KeyValueId), 03778 &cbSize ); 03779 03780 if ( rc == STATUS_BUFFER_OVERFLOW ) { 03781 RIPMSG0(RIP_WARNING, "GetActiveKeyboardName - Buffer overflow."); 03782 rc = STATUS_SUCCESS; 03783 } 03784 if (NT_SUCCESS( rc )) { 03785 wcsncpycch( lpszName, (LPWSTR)KeyValueId.KeyInfo.Data, KL_NAMELENGTH - 1 ); 03786 lpszName[KL_NAMELENGTH - 1] = L'\0'; 03787 } else { 03788 /* 03789 * Error reading value...use default 03790 */ 03791 wcscpy( lpszName, L"00000409" ); 03792 } 03793 03794 NtClose( hKey ); 03795 NtClose( UserKeyHandle ); 03796 if (IS_IME_ENABLED()) { 03797 CheckValidLayoutName( lpszName ); 03798 } 03799 return; 03800 } 03801 03802 /* 03803 * NOTE: The code below is only executed the first time a user logs 03804 * on after an upgrade from NT3.x to NT4.0. 03805 */ 03806 /* 03807 * The Preload key does not exist in the registry. Try reading the 03808 * old registry entry "Keyboard Layout\Active". If it exists, we 03809 * convert it to the new style Preload key. 03810 */ 03811 RtlInitUnicodeString( &UnicodeString, szKbdLayout ); 03812 InitializeObjectAttributes( &ObjA, 03813 &UnicodeString, 03814 OBJ_CASE_INSENSITIVE, 03815 UserKeyHandle, 03816 NULL ); 03817 rc = NtOpenKey( &hKey, 03818 KEY_ALL_ACCESS, 03819 &ObjA ); 03820 03821 NtClose( UserKeyHandle ); 03822 03823 if (!NT_SUCCESS( rc )) 03824 { 03825 RIPMSG1( RIP_WARNING, "GetActiveKeyboardName - Could not determine active keyboard layout (%lx).\n", rc ); 03826 wcscpy( lpszName, L"00000409" ); 03827 return; 03828 } 03829 03830 /* 03831 * Query the value from the registry. 03832 */ 03833 RtlInitUnicodeString( &UnicodeString, szKbdActive ); 03834 03835 rc = NtQueryValueKey( hKey, 03836 &UnicodeString, 03837 KeyValuePartialInformation, 03838 &KeyValueId, 03839 sizeof(KeyValueId), 03840 &cbSize ); 03841 03842 if ( rc == STATUS_BUFFER_OVERFLOW ) { 03843 RIPMSG0(RIP_WARNING, "GetActiveKeyboardName - Buffer overflow."); 03844 rc = STATUS_SUCCESS; 03845 } 03846 if (NT_SUCCESS( rc )) { 03847 wcsncpycch( lpszName, (LPWSTR)KeyValueId.KeyInfo.Data, KL_NAMELENGTH - 1 ); 03848 lpszName[KL_NAMELENGTH - 1] = L'\0'; 03849 } else { 03850 /* 03851 * Error reading value...use default 03852 */ 03853 RIPMSG1( RIP_WARNING, "GetActiveKeyboardName - Could not query active keyboard layout (%lx).\n", rc ); 03854 wcscpy( lpszName, L"00000409" ); 03855 NtClose( hKey ); 03856 return; 03857 } 03858 03859 /* 03860 * if 'Active' keyboard layout is for Japanese/Korean layout. just put 03861 * IME prefix, because user prefer to have keyboard layout with IME as 03862 * default. 03863 */ 03864 if (IS_IME_ENABLED()) { 03865 UINT wLanguageId = (UINT)wcstoul(lpszName, NULL, 16); 03866 03867 /* 03868 * Default keyboard layout values. 03869 * 03870 * [LATER, if needed] 03871 * 03872 * The hard-codeed default value might be wanted 03873 * come from registry or somewhere... 03874 */ 03875 CONST LPWSTR lpszJapaneseDefaultLayout = L"E0010411"; 03876 CONST LPWSTR lpszKoreanDefaultLayout = L"E0010412"; 03877 03878 /* 03879 * Need to mask off hi-word to look up locale ID, because 03880 * NEC PC-9800 Series version of Windows NT 3.5 contains 03881 * bogus value in hi-word. 03882 */ 03883 wLanguageId &= 0x0000FFFF; 03884 03885 if (PRIMARYLANGID(wLanguageId) == LANG_JAPANESE) { 03886 03887 /* 03888 * Set Japanese default layout Id. 03889 */ 03890 wcscpy(lpszName,lpszJapaneseDefaultLayout); 03891 03892 } else if (PRIMARYLANGID(wLanguageId) == LANG_KOREAN) { 03893 03894 /* 03895 * Set Korean default layout Id. 03896 */ 03897 wcscpy(lpszName,lpszKoreanDefaultLayout); 03898 } 03899 } 03900 03901 /* 03902 * We have the Active value. Now create the Preload key. 03903 */ 03904 RtlInitUnicodeString( &UnicodeString, L"Preload" ); 03905 InitializeObjectAttributes( &ObjA, 03906 &UnicodeString, 03907 OBJ_CASE_INSENSITIVE, 03908 hKey, 03909 NULL ); 03910 rc = NtCreateKey( &hKeyPreload, 03911 STANDARD_RIGHTS_WRITE | 03912 KEY_QUERY_VALUE | 03913 KEY_ENUMERATE_SUB_KEYS | 03914 KEY_SET_VALUE | 03915 KEY_CREATE_SUB_KEY, 03916 &ObjA, 03917 0, 03918 NULL, 03919 0, 03920 &CreateDisposition ); 03921 03922 if (!NT_SUCCESS( rc )) 03923 { 03924 RIPMSG1( RIP_WARNING, "GetActiveKeyboardName - Could NOT create Preload key (%lx).\n", rc ); 03925 NtClose( hKey ); 03926 return; 03927 } 03928 03929 /* 03930 * Set the new value entry. 03931 */ 03932 RtlInitUnicodeString( &UnicodeString, L"1" ); 03933 rc = NtSetValueKey( hKeyPreload, 03934 &UnicodeString, 03935 0, 03936 REG_SZ, 03937 lpszName, 03938 (wcslen(lpszName)+1) * sizeof(WCHAR) 03939 ); 03940 03941 if (!NT_SUCCESS( rc )) 03942 { 03943 RIPMSG1( RIP_WARNING, "GetActiveKeyboardName - Could NOT create value entry 1 for Preload key (%lx).\n", rc ); 03944 NtClose( hKey ); 03945 NtClose( hKeyPreload ); 03946 return; 03947 } 03948 03949 /* 03950 * Success: attempt to delete the Active value key. 03951 */ 03952 RtlInitUnicodeString( &UnicodeString, szKbdActive ); 03953 rc = NtDeleteValueKey( hKey, &UnicodeString ); 03954 03955 if (!NT_SUCCESS( rc )) 03956 { 03957 RIPMSG1( RIP_WARNING, "GetActiveKeyboardName - Could NOT delete value key 'Active'.\n", rc ); 03958 } 03959 NtClose( hKey ); 03960 NtClose( hKeyPreload ); 03961 } 03962 03963 03964 /***************************************************************************\ 03965 * LoadPreloadKeyboardLayouts 03966 * 03967 * Loads the keyboard layouts stored under the Preload key in the user's 03968 * registry. The first layout, the default, was already loaded. Start with #2. 03969 * 03970 * 03-06-95 GregoryW Created. 03971 \***************************************************************************/ 03972 03973 // size allows up to 999 preloaded!!!!! 03974 #define NSIZEPRELOAD (4) 03975 03976 VOID LoadPreloadKeyboardLayouts(void) 03977 { 03978 UINT i; 03979 WCHAR szPreLoadee[NSIZEPRELOAD]; 03980 WCHAR lpszName[KL_NAMELENGTH]; 03981 03982 if (!ISREMOTESESSION()) { 03983 /* 03984 * Console doesn't have a client layout, so start from 2. 03985 */ 03986 i = 2; 03987 } else { 03988 /* 03989 * Client might have specified a keyboard layout, if this 03990 * is so, then Preload\1 was not loaded, so start from 1. 03991 */ 03992 i = 1; 03993 } 03994 03995 for (; i < 1000; i++) { 03996 wsprintf(szPreLoadee, L"%d", i ); 03997 if ((GetPrivateProfileStringW( 03998 L"Preload", 03999 szPreLoadee, 04000 L"", // default = NULL 04001 lpszName, // output buffer 04002 KL_NAMELENGTH, 04003 L"keyboardlayout.ini") == -1 ) || (*lpszName == L'\0')) { 04004 break; 04005 } 04006 LoadKeyboardLayoutW(lpszName, KLF_REPLACELANG |KLF_SUBSTITUTE_OK |KLF_NOTELLSHELL); 04007 } 04008 } 04009 04010 04011 /***************************************************************************\ 04012 * OpenKeyboardLayoutFile 04013 * 04014 * Opens a layout file and computes the table offset. 04015 * 04016 * 01-11-95 JimA Moved LoadLibrary code from server. 04017 \***************************************************************************/ 04018 04019 HANDLE OpenKeyboardLayoutFile( 04020 LPWSTR lpszKLName, 04021 PUINT puFlags, 04022 PUINT poffTable, 04023 PUINT pKbdInputLocale) 04024 { 04025 PKBDNLSTABLES (*pfnNls)(); 04026 BOOL (*pfnDriverNT4)(LPWSTR); 04027 BOOL (*pfnDriver)(HKL, LPWSTR, PCLIENTKEYBOARDTYPE, LPVOID); 04028 WCHAR awchRealLayoutFile[MAX_PATH]; 04029 BOOL bMightBeKbdNlsDriver = FALSE; 04030 WCHAR awchKL[KL_NAMELENGTH]; 04031 WCHAR awchKLRegKey[NSZKLKEY]; 04032 LPWSTR lpszKLRegKey = &awchKLRegKey[0]; 04033 PKBDTABLES (*pfn)(); 04034 LPWSTR pwszLib; 04035 LPWSTR pwszId; 04036 HANDLE hLibModule; 04037 WCHAR awchModName[MAX_PATH]; 04038 UNICODE_STRING UnicodeString; 04039 UINT wLayoutId; 04040 UINT wLanguageId; 04041 NTSTATUS Status; 04042 OBJECT_ATTRIBUTES OA; 04043 HANDLE hKey; 04044 DWORD cbSize; 04045 struct { 04046 KEY_VALUE_PARTIAL_INFORMATION KeyInfo; 04047 WCHAR awchLibName[CCH_KL_LIBNAME]; 04048 } KeyFile; 04049 struct { 04050 KEY_VALUE_PARTIAL_INFORMATION KeyInfo; 04051 WCHAR awchId[CCH_KL_ID]; 04052 } KeyId; 04053 struct { 04054 KEY_VALUE_PARTIAL_INFORMATION KeyInfo; 04055 DWORD Attributes; 04056 } KeyAttributes; 04057 04058 wLanguageId = (UINT)wcstoul(lpszKLName, NULL, 16); 04059 /* 04060 * Substitute Layout if required. 04061 */ 04062 if (*puFlags & KLF_SUBSTITUTE_OK) { 04063 GetPrivateProfileStringW( 04064 L"Substitutes", 04065 lpszKLName, 04066 lpszKLName, // default == no change (no substitute found) 04067 awchKL, 04068 sizeof(awchKL)/sizeof(WCHAR), 04069 L"keyboardlayout.ini"); 04070 04071 /* 04072 * #273562 : Flush the registry cache, because the cpanel applet 04073 * destroys and recreates the Substitutes section a lot, which 04074 * would otherwise leave us with STATUS_KEY_DELETED. 04075 */ 04076 WritePrivateProfileStringW(NULL, NULL, NULL, NULL); 04077 04078 awchKL[KL_NAMELENGTH - 1] = L'\0'; 04079 wcscpy(lpszKLName, awchKL); 04080 } 04081 04082 wLayoutId = (UINT)wcstoul(lpszKLName, NULL, 16); 04083 04084 /* 04085 * Get DLL name from the registry, load it, and get the entry point. 04086 */ 04087 pwszLib = NULL; 04088 wcscpy(lpszKLRegKey, szKLKey); 04089 wcscat(lpszKLRegKey, lpszKLName); 04090 RtlInitUnicodeString(&UnicodeString, lpszKLRegKey); 04091 InitializeObjectAttributes(&OA, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 04092 04093 if (NT_SUCCESS(NtOpenKey(&hKey, KEY_READ, &OA))) { 04094 /* 04095 * Read the "Layout File" value. 04096 */ 04097 RtlInitUnicodeString(&UnicodeString, szKLFile); 04098 04099 Status = NtQueryValueKey(hKey, 04100 &UnicodeString, 04101 KeyValuePartialInformation, 04102 &KeyFile, 04103 sizeof(KeyFile), 04104 &cbSize); 04105 04106 if (Status == STATUS_BUFFER_OVERFLOW) { 04107 RIPMSG0(RIP_WARNING, "OpenKeyboardLayoutFile (Layout File) - Buffer overflow."); 04108 Status = STATUS_SUCCESS; 04109 } 04110 if (NT_SUCCESS(Status)) { 04111 pwszLib = (LPWSTR)KeyFile.KeyInfo.Data; 04112 pwszLib[CCH_KL_LIBNAME - 1] = L'\0'; 04113 04114 } 04115 04116 RtlInitUnicodeString(&UnicodeString, szKLAttributes); 04117 Status = NtQueryValueKey(hKey, 04118 &UnicodeString, 04119 KeyValuePartialInformation, 04120 &KeyAttributes, 04121 sizeof(KeyAttributes), 04122 &cbSize); 04123 04124 if (NT_SUCCESS(Status)) { 04125 #if DBG 04126 if ((*((PDWORD)KeyAttributes.KeyInfo.Data) & ~KLF_ATTRMASK) != 0) { 04127 RIPMSG1(RIP_WARNING, 04128 "OpenKeyboardLayoutFile - Unexpected attributes %lx", 04129 *((PDWORD)KeyAttributes.KeyInfo.Data)); 04130 } 04131 #endif 04132 *puFlags |= (*(PDWORD)KeyAttributes.KeyInfo.Data & KLF_ATTRMASK); 04133 } 04134 04135 /* 04136 * If the high word of wLayoutId is 0xE??? then this is an IME based 04137 * keyboard layout. 04138 */ 04139 if (IS_IME_KBDLAYOUT(wLayoutId)) { 04140 wLayoutId = (UINT)HIWORD(wLayoutId); 04141 } else if (HIWORD(wLayoutId)) { 04142 /* 04143 * If the high word of wLayoutId is non-null then read the "Layout ID" value. 04144 * Layout IDs start at 1, increase sequentially and are unique. 04145 */ 04146 RtlInitUnicodeString(&UnicodeString, szKLId); 04147 04148 Status = NtQueryValueKey(hKey, 04149 &UnicodeString, 04150 KeyValuePartialInformation, 04151 &KeyId, 04152 sizeof(KeyId), 04153 &cbSize); 04154 04155 if (Status == STATUS_BUFFER_OVERFLOW) { 04156 RIPMSG0(RIP_WARNING, "OpenKeyboardLayoutFile - Buffer overflow."); 04157 Status = STATUS_SUCCESS; 04158 } 04159 if (NT_SUCCESS(Status)) { 04160 pwszId = (LPWSTR)KeyId.KeyInfo.Data; 04161 pwszId[CCH_KL_ID - 1] = L'\0'; 04162 wLayoutId = (wcstol(pwszId, NULL, 16) & 0x0fff) | 0xf000; 04163 } else { 04164 wLayoutId = (UINT)0xfffe ; // error in layout ID, load separately 04165 } 04166 } 04167 NtClose(hKey); 04168 } else { 04169 /* 04170 * This is a temporary case to allow booting the new multilingual user on top of a 04171 * Daytona registry. 04172 */ 04173 /* 04174 * Get DLL name from the registry, load it, and get the entry point. 04175 */ 04176 pwszLib = NULL; 04177 RtlInitUnicodeString(&UnicodeString, 04178 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Keyboard Layout"); 04179 InitializeObjectAttributes(&OA, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 04180 04181 if (NT_SUCCESS(NtOpenKey(&hKey, KEY_READ, &OA))) { 04182 RtlInitUnicodeString(&UnicodeString, lpszKLName); 04183 04184 Status = NtQueryValueKey(hKey, 04185 &UnicodeString, 04186 KeyValuePartialInformation, 04187 &KeyFile, 04188 sizeof(KeyFile), 04189 &cbSize); 04190 04191 if (Status == STATUS_BUFFER_OVERFLOW) { 04192 RIPMSG0(RIP_WARNING, "OpenKeyboardLayoutFile - Buffer overflow."); 04193 Status = STATUS_SUCCESS; 04194 } 04195 if (NT_SUCCESS(Status)) { 04196 pwszLib = (LPWSTR)KeyFile.KeyInfo.Data; 04197 pwszLib[CCH_KL_LIBNAME - 1] = L'\0'; 04198 } 04199 04200 NtClose(hKey); 04201 } 04202 } 04203 04204 *pKbdInputLocale = (UINT)MAKELONG(LOWORD(wLanguageId),LOWORD(wLayoutId)); 04205 04206 if (pwszLib == NULL) { 04207 if (ISREMOTESESSION() && IS_IME_KBDLAYOUT(wLayoutId)) { 04208 /* 04209 * -- port from HYDRA -- 04210 * Could not find the keyboard KL for FE, so give them some reasonable one. 04211 * If the high word of wLayoutId is 0xE??? then this is an IME based 04212 * keyboard layout. 04213 * And, the safe KL name is KBDJPN.DLL for Japanese. 04214 * or KBDKOR.DLL for Korean 04215 * or KBDUS.DLL for other Far East 04216 */ 04217 if (PRIMARYLANGID(wLanguageId) == LANG_JAPANESE) { 04218 pwszLib = pwszKLLibSafetyJPN; 04219 *pKbdInputLocale = wKbdLocaleSafetyJPN; 04220 } 04221 else if (PRIMARYLANGID(wLanguageId) == LANG_KOREAN) { 04222 pwszLib = pwszKLLibSafetyKOR; 04223 *pKbdInputLocale = wKbdLocaleSafetyKOR; 04224 } 04225 else { 04226 pwszLib = pwszKLLibSafety; 04227 *pKbdInputLocale = MAKELONG(LOWORD(wLanguageId), LOWORD(wLanguageId)); 04228 } 04229 } 04230 else if (*puFlags & KLF_INITTIME) { 04231 pwszLib = pwszKLLibSafety; 04232 *pKbdInputLocale = wKbdLocaleSafety; 04233 } else { 04234 RIPMSG1(RIP_WARNING, "no DLL name for %ws", lpszKLName); 04235 /* 04236 * We're going to use the fallback layout... 04237 * This could happen when IMM32 is trying to unload the IME, 04238 * by making any non IME keyboard layout tentatively active. 04239 */ 04240 pwszLib = pwszKLLibSafety; 04241 *pKbdInputLocale = wKbdLocaleSafety; 04242 // return NULL; 04243 } 04244 } 04245 04246 RetryLoad: 04247 hLibModule = LoadLibraryW(pwszLib); 04248 04249 if (hLibModule == NULL) { 04250 RIPMSG1(RIP_WARNING, "Keyboard Layout: cannot load %ws\n", pwszLib); 04251 /* 04252 * It is OK to fail to load DLL here: 04253 * if this ever happens, the fallback keyboard layout built in 04254 * win32k.sys shall be used. 04255 */ 04256 return NULL; 04257 } 04258 04259 /* 04260 * if the layout driver is not "REAL" layout driver, the driver has 04261 * "3" or "5" entry point, then we call this to get real layout driver.. 04262 * This is neccesary for Japanese and Korean systems. because their 04263 * keyboard layout driver is "KBDJPN.DLL" or "KBDKOR.DLL", but its 04264 * "REAL" driver becomes different depending their keyboard hardware. 04265 */ 04266 04267 /* 04268 * Get the entrypoints. 04269 */ 04270 pfnDriver = (BOOL(*)(HKL, LPWSTR, PCLIENTKEYBOARDTYPE, LPVOID))GetProcAddress(hLibModule, (LPCSTR)5); 04271 pfnDriverNT4 = (BOOL(*)(LPWSTR))GetProcAddress(hLibModule, (LPCSTR)3); 04272 04273 if (pfnDriver || pfnDriverNT4) { 04274 HKL hkl; 04275 CLIENTKEYBOARDTYPE clientKbdType; 04276 PCLIENTKEYBOARDTYPE pClientKbdType = NULL; 04277 04278 RtlInitUnicodeString(&UnicodeString, lpszKLName); 04279 RtlUnicodeStringToInteger(&UnicodeString, 0x10, (PULONG)&hkl); 04280 /* 04281 * When we reach here, the layout DLL may have KBDNLSTABLE 04282 * even if we fail from now on. Our temporary layout 04283 * dll should have the fallback tables for just in case. 04284 */ 04285 bMightBeKbdNlsDriver = TRUE; 04286 04287 if (ISREMOTESESSION() && GetClientKeyboardType(&clientKbdType)) { 04288 pClientKbdType = &clientKbdType; 04289 } 04290 04291 /* 04292 * Call the entry. 04293 * a. NT5 / Hydra (oridinal=5) 04294 * b. NT4 compatible (3) 04295 */ 04296 if ((pfnDriver && pfnDriver(hkl, awchRealLayoutFile, pClientKbdType, NULL)) || 04297 (pfnDriverNT4 && pfnDriverNT4(awchRealLayoutFile))) { 04298 04299 HANDLE hLibModuleNew; 04300 /* 04301 * Try to load "REAL" keyboard layout file. 04302 */ 04303 RIPMSG1(RIP_VERBOSE, "awchRealLayoutFile='%S'\n", awchRealLayoutFile); 04304 if (hLibModuleNew = LoadLibraryW(awchRealLayoutFile)) { 04305 /* 04306 * Set "REAL" layout file name. 04307 */ 04308 pwszLib = awchRealLayoutFile; 04309 /* 04310 * Unload temporary layout driver. 04311 */ 04312 FreeLibrary(hLibModule); 04313 /* 04314 * Updates it. 04315 */ 04316 hLibModule = hLibModuleNew; 04317 } 04318 } 04319 } 04320 04321 /* 04322 * HACK Part 1! Get the pointer to the layout table and 04323 * change it to a virtual offset. The server will then 04324 * use this offset when poking through the file header to 04325 * locate the table within the file. 04326 */ 04327 pfn = (PKBDTABLES(*)())GetProcAddress(hLibModule, (LPCSTR)1); 04328 if (pfn == NULL) { 04329 RIPMSG0(RIP_ERROR, "Keyboard Layout: cannot get proc addr"); 04330 if ((*puFlags & KLF_INITTIME) && (pwszLib != pwszKLLibSafety)) { 04331 pwszLib = pwszKLLibSafety; 04332 goto RetryLoad; 04333 } 04334 return NULL; 04335 } 04336 *poffTable = (UINT)((PBYTE)pfn() - (PBYTE)hLibModule); 04337 04338 if (bMightBeKbdNlsDriver) { 04339 pfnNls = (PKBDNLSTABLES(*)())GetProcAddress(hLibModule, (LPCSTR)2); 04340 if (pfnNls != NULL) { 04341 UINT offNlsTable; 04342 04343 offNlsTable = (UINT)((PBYTE)pfnNls() - (PBYTE)hLibModule); 04344 04345 #if DBG_FE 04346 DbgPrint("USER32:Offset to KBDTABLES = %d (%x)\n",*poffTable,*poffTable); 04347 DbgPrint("USER32:Offset to KBDNLSTABLES = %d (%x)\n",offNlsTable,offNlsTable); 04348 #endif // DBG_FE 04349 04350 /* 04351 * Combine these offsets... 04352 * 04353 * LOWORD(*poffTable) = Offset to KBDTABLES. 04354 * HIWORD(*poffTable) = Offset to KBDNLSTABLES. 04355 */ 04356 *poffTable |= (offNlsTable << 16); 04357 } 04358 } 04359 04360 /* 04361 * Open the dll for read access. 04362 */ 04363 GetModuleFileName(hLibModule, awchModName, sizeof(awchModName)); 04364 FreeLibrary(hLibModule); 04365 return CreateFileW( 04366 awchModName, 04367 GENERIC_READ, 04368 FILE_SHARE_READ, 04369 NULL, 04370 OPEN_EXISTING, 04371 0, 04372 NULL); 04373 } 04374 04375 04376 /***************************************************************************\ 04377 * LoadKeyboardLayoutEx 04378 * 04379 * Loads a keyboard translation table from a dll, replacing the layout associated 04380 * with hkl. This routine is needed to provide Win95 compatibility. 04381 * 04382 * 10-27-95 GregoryW Created. 04383 \***************************************************************************/ 04384 04385 HKL LoadKeyboardLayoutWorker( 04386 HKL hkl, 04387 LPCWSTR lpszKLName, 04388 UINT uFlags, 04389 BOOL fFailSafe) 04390 { 04391 UINT offTable; 04392 UINT KbdInputLocale; 04393 HANDLE hFile; 04394 HKL hKbdLayout; 04395 WCHAR awchKL[KL_NAMELENGTH]; 04396 04397 TAGMSG1(DBGTAG_IMM, "LoadKeyboardLayoutWorker called with KLNAME=%S", lpszKLName); 04398 04399 /* 04400 * If there is a substitute keyboard layout OpenKeyboardLayoutFile returns 04401 * the substitute keyboard layout name to load. 04402 */ 04403 wcsncpy(awchKL, lpszKLName, KL_NAMELENGTH - 1); 04404 awchKL[KL_NAMELENGTH - 1] = L'\0'; 04405 04406 /* 04407 * Open the layout file 04408 */ 04409 hFile = OpenKeyboardLayoutFile(awchKL, &uFlags, &offTable, &KbdInputLocale); 04410 if (hFile == NULL) { 04411 if (!fFailSafe && (uFlags & KLF_FAILSAFE) == 0) { 04412 // If not fail safe mode, just bail to fail. 04413 return NULL; 04414 } 04415 uFlags &= ~KLF_SUBSTITUTE_OK; 04416 if (wcscmp(awchKL, L"00000409")) { 04417 wcscpy(awchKL, L"00000409"); 04418 hFile = OpenKeyboardLayoutFile(awchKL, &uFlags, &offTable, &KbdInputLocale); 04419 } 04420 if (hFile == NULL) { 04421 // It's OK to pass NULL hFile. This lets the win32k prepare and 04422 // allocate the fallback keyboard layout. 04423 // kbdnul, which is a fallback keyboard layout stored in in win32k, will be used: 04424 } 04425 } 04426 04427 /* 04428 * Call the server to read the keyboard tables. Note that 04429 * the server will close the file handle when it is done. 04430 */ 04431 hKbdLayout = _LoadKeyboardLayoutEx(hFile, offTable, hkl, awchKL, KbdInputLocale, uFlags); 04432 NtClose(hFile); 04433 04434 CliImmInitializeHotKeys(ISHK_ADD, (HKL)IntToPtr( KbdInputLocale )); 04435 04436 return hKbdLayout; 04437 } 04438 04439 HKL LoadKeyboardLayoutEx( 04440 HKL hkl, 04441 LPCWSTR lpszKLName, 04442 UINT uFlags) 04443 { 04444 RIPMSG0(RIP_WARNING, "LoadKeyboardLayoutEx is called."); 04445 /* 04446 * NULL hkl is not allowed. 04447 */ 04448 if (hkl == (HKL)NULL) { 04449 return NULL; 04450 } 04451 04452 return LoadKeyboardLayoutWorker(hkl, lpszKLName, uFlags, FALSE); 04453 } 04454 04455 /***************************************************************************\ 04456 * LoadKeyboardLayout 04457 * 04458 * Loads a keyboard translation table from a dll. 04459 * 04460 * 01-09-95 JimA Moved LoadLibrary code from server. 04461 \***************************************************************************/ 04462 04463 HKL LoadKeyboardLayoutW( 04464 LPCWSTR lpszKLName, 04465 UINT uFlags) 04466 { 04467 return LoadKeyboardLayoutWorker(NULL, lpszKLName, uFlags, FALSE); 04468 } 04469 04470 HKL LoadKeyboardLayoutA( 04471 LPCSTR lpszKLName, 04472 UINT uFlags) 04473 { 04474 WCHAR awchKLName[MAX_PATH]; 04475 LPWSTR lpBuffer = awchKLName; 04476 04477 if (!MBToWCS(lpszKLName, -1, &lpBuffer, sizeof(awchKLName), FALSE)) 04478 return (HKL)NULL; 04479 04480 return LoadKeyboardLayoutW(awchKLName, uFlags); 04481 } 04482 04483 BOOL UnloadKeyboardLayout(IN HKL hkl) 04484 { 04485 BOOL fRet = NtUserUnloadKeyboardLayout(hkl); 04486 04487 if (fRet) { 04488 CliImmInitializeHotKeys(ISHK_REMOVE, hkl); 04489 return TRUE; 04490 } 04491 04492 return FALSE; 04493 } 04494 04495 04496 /**************************************************************************\ 04497 * GetKeyboardLayout() 04498 * 04499 * 01-17-95 GregoryW Created 04500 \**************************************************************************/ 04501 04502 HKL GetKeyboardLayout( 04503 DWORD idThread) 04504 { 04505 return (HKL)NtUserCallOneParam(idThread, SFI__GETKEYBOARDLAYOUT); 04506 } 04507 04508 04509 VOID SetDebugErrorLevel(DWORD dwLevel) 04510 { 04511 UNREFERENCED_PARAMETER(dwLevel); 04512 // NtUserCallNoParam(SFI__SETDEBUGERRORLEVEL); 04513 return; 04514 } 04515 04516 VOID CheckValidLayoutName( LPWSTR lpszKLName ) 04517 { 04518 UINT wLayoutId; 04519 WCHAR awchKLRegKey[NSZKLKEY]; 04520 LPWSTR lpszKLRegKey = &awchKLRegKey[0]; 04521 OBJECT_ATTRIBUTES OA; 04522 HANDLE hKey; 04523 UNICODE_STRING UnicodeString; 04524 04525 UserAssert(IS_IME_ENABLED()); 04526 04527 wLayoutId = (UINT)wcstoul(lpszKLName, NULL, 16); 04528 04529 if (IS_IME_KBDLAYOUT(wLayoutId)) { 04530 // 04531 // if it's an IME layout, we need to check if 04532 // the layout name does exist in the HKEY_LOCAL_MACHINE. 04533 // if we've upgraded from NT 3.51 the corresponding 04534 // entry might be lost, because those process-type IMEs that 04535 // are supported on NT 3.51 are not supported NT 4.0 any more. 04536 // 04537 wcscpy(lpszKLRegKey, szKLKey); 04538 wcscat(lpszKLRegKey, lpszKLName); 04539 RtlInitUnicodeString(&UnicodeString, lpszKLRegKey); 04540 InitializeObjectAttributes(&OA, &UnicodeString, OBJ_CASE_INSENSITIVE, NULL, NULL); 04541 04542 if (NT_SUCCESS(NtOpenKey(&hKey, KEY_READ, &OA))) { 04543 NtClose( hKey ); 04544 } else { 04545 // quick'n dirty way to make the fallback name... 04546 lpszKLName[0] = lpszKLName[1] = lpszKLName[2] = lpszKLName[3] = L'0'; 04547 #ifdef LATER 04548 // display a message box to warn user 04549 #endif 04550 } 04551 } 04552 } 04553 04554 #ifdef USE_MIRRORING 04555 /**************************************************************************\ 04556 * GetProcessDefaultLayout 04557 * 04558 * 22-Jan-1998 SamerA Created 04559 \**************************************************************************/ 04560 04561 BOOL WINAPI GetProcessDefaultLayout(DWORD *pdwDefaultLayout) 04562 { 04563 return (BOOL)NtUserCallOneParam((ULONG_PTR)pdwDefaultLayout, 04564 SFI__GETPROCESSDEFAULTLAYOUT); 04565 } 04566 04567 /**************************************************************************\ 04568 * SetProcessDefaultLayout 04569 * 04570 * 22-Jan-1998 SamerA Created 04571 \**************************************************************************/ 04572 04573 BOOL WINAPI SetProcessDefaultLayout( 04574 DWORD dwDefaultLayout) 04575 { 04576 return (BOOL)NtUserCallOneParam(dwDefaultLayout, SFI__SETPROCESSDEFAULTLAYOUT); 04577 } 04578 #endif

Generated on Sat May 15 19:39:24 2004 for test by doxygen 1.3.7