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

ntstubs.c

Go to the documentation of this file.
00001 /**************************************************************************\ 00002 * Module Name: ntstubs.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * client side API stubs 00007 * 00008 * History: 00009 * 03-19-95 JimA Created. 00010 \**************************************************************************/ 00011 00012 #include "precomp.h" 00013 #pragma hdrstop 00014 00015 #define CLIENTSIDE 1 00016 00017 #include <dbt.h> 00018 00019 #include "ntsend.h" 00020 #include "cfgmgr32.h" 00021 #include "csrhlpr.h" 00022 00023 extern BOOL GetRemoteKeyboardLayout(PWCHAR); 00024 00025 WINUSERAPI 00026 BOOL 00027 WINAPI 00028 SetSysColors( 00029 int cElements, 00030 CONST INT * lpaElements, 00031 CONST COLORREF * lpaRgbValues) 00032 { 00033 00034 return NtUserSetSysColors(cElements, 00035 lpaElements, 00036 lpaRgbValues, 00037 SSCF_NOTIFY | SSCF_FORCESOLIDCOLOR | SSCF_SETMAGICCOLORS); 00038 } 00039 00040 00041 HWND WOWFindWindow( 00042 LPCSTR pClassName, 00043 LPCSTR pWindowName) 00044 { 00045 return InternalFindWindowExA(NULL, NULL, pClassName, pWindowName, FW_16BIT); 00046 } 00047 00048 00049 BOOL UpdatePerUserSystemParameters( 00050 HANDLE hToken, 00051 BOOL bUserLoggedOn) 00052 { 00053 WCHAR pwszKLID[KL_NAMELENGTH]; 00054 00055 BEGINCALL() 00056 00057 /* 00058 * Initialize IME hotkeys before loading keyboard 00059 * layouts. 00060 */ 00061 CliImmInitializeHotKeys(ISHK_INITIALIZE, NULL); 00062 /* 00063 * Load initial keyboard layout. 00064 */ 00065 if (!GetRemoteKeyboardLayout(pwszKLID)) { 00066 GetActiveKeyboardName(pwszKLID); 00067 } 00068 00069 LoadKeyboardLayoutWorker(NULL, pwszKLID, KLF_ACTIVATE | KLF_RESET | KLF_SUBSTITUTE_OK, TRUE); 00070 00071 /* 00072 * Now load the remaining preload keyboard layouts. 00073 */ 00074 LoadPreloadKeyboardLayouts(); 00075 retval = (DWORD)NtUserUpdatePerUserSystemParameters(hToken, bUserLoggedOn); 00076 00077 /* 00078 * Cause the wallpaper to be changed. 00079 */ 00080 SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, 0, 0); 00081 00082 ERRORTRAP(0); 00083 ENDCALL(BOOL); 00084 } 00085 00086 DWORD Event( 00087 PEVENT_PACKET pep) 00088 { 00089 BEGINCALL() 00090 00091 CheckDDECritOut; 00092 00093 retval = (DWORD)NtUserEvent( 00094 pep); 00095 00096 ERRORTRAP(0); 00097 ENDCALL(DWORD); 00098 } 00099 00100 LONG GetClassWOWWords( 00101 HINSTANCE hInstance, 00102 LPCTSTR pString) 00103 { 00104 IN_STRING strClassName; 00105 PCLS pcls; 00106 00107 /* 00108 * Make sure cleanup will work successfully 00109 */ 00110 strClassName.fAllocated = FALSE; 00111 00112 BEGINCALL() 00113 00114 FIRSTCOPYLPSTRW(&strClassName, pString); 00115 00116 pcls = NtUserGetWOWClass(hInstance, strClassName.pstr); 00117 00118 if (pcls == NULL) { 00119 MSGERRORCODE(ERROR_CLASS_DOES_NOT_EXIST); 00120 } 00121 00122 pcls = (PCLS)((PBYTE)pcls - GetClientInfo()->ulClientDelta); 00123 retval = _GetClassData(pcls, NULL, GCLP_WOWWORDS, TRUE); 00124 00125 ERRORTRAP(0); 00126 CLEANUPLPSTRW(strClassName); 00127 ENDCALL(LONG); 00128 } 00129 00130 /***************************************************************************\ 00131 * InitTask 00132 * 00133 * Initialize a WOW task. This is the first call a WOW thread makes to user. 00134 * NtUserInitTask returns NTSTATUS because if the thread fails to convert 00135 * to a GUI thread, STATUS_INVALID_SYSTEM_SERVICE is returned. 00136 * 00137 * 11-03-95 JimA Modified to use NTSTATUS. 00138 \***************************************************************************/ 00139 00140 BOOL InitTask( 00141 UINT wVersion, 00142 DWORD dwAppCompatFlags, 00143 LPCSTR pszModName, 00144 LPCSTR pszBaseFileName, 00145 DWORD hTaskWow, 00146 DWORD dwHotkey, 00147 DWORD idTask, 00148 DWORD dwX, 00149 DWORD dwY, 00150 DWORD dwXSize, 00151 DWORD dwYSize) 00152 { 00153 IN_STRING strModName; 00154 IN_STRING strBaseFileName; 00155 NTSTATUS Status; 00156 00157 /* 00158 * Make sure cleanup will work successfully 00159 */ 00160 strModName.fAllocated = FALSE; 00161 strBaseFileName.fAllocated = FALSE; 00162 00163 BEGINCALL() 00164 00165 FIRSTCOPYLPSTRW(&strModName, pszModName); 00166 COPYLPSTRW(&strBaseFileName, pszBaseFileName); 00167 00168 Status = NtUserInitTask( 00169 wVersion, 00170 dwAppCompatFlags, 00171 strModName.pstr, 00172 strBaseFileName.pstr, 00173 hTaskWow, 00174 dwHotkey, 00175 idTask, 00176 dwX, 00177 dwY, 00178 dwXSize, 00179 dwYSize); 00180 retval = (Status == STATUS_SUCCESS); 00181 00182 CLEANUPLPSTRW(strModName); 00183 CLEANUPLPSTRW(strBaseFileName); 00184 00185 ERRORTRAP(FALSE); 00186 ENDCALL(BOOL); 00187 } 00188 00189 HANDLE ConvertMemHandle( 00190 HANDLE hData, 00191 UINT cbNULL) 00192 { 00193 UINT cbData; 00194 LPBYTE lpData; 00195 00196 BEGINCALL() 00197 00198 if (GlobalFlags(hData) == GMEM_INVALID_HANDLE) { 00199 RIPMSG0(RIP_WARNING, "ConvertMemHandle hMem is not valid\n"); 00200 MSGERROR(); 00201 } 00202 00203 if (!(cbData = (UINT)GlobalSize(hData))) 00204 MSGERROR(); 00205 00206 USERGLOBALLOCK(hData, lpData); 00207 if (lpData == NULL) { 00208 MSGERROR(); 00209 } 00210 00211 /* 00212 * Make sure text formats are NULL terminated. 00213 */ 00214 switch (cbNULL) { 00215 case 2: 00216 lpData[cbData - 2] = 0; 00217 // FALL THROUGH 00218 case 1: 00219 lpData[cbData - 1] = 0; 00220 } 00221 00222 retval = (ULONG_PTR)NtUserConvertMemHandle(lpData, cbData); 00223 00224 USERGLOBALUNLOCK(hData); 00225 00226 ERRORTRAP(NULL); 00227 ENDCALL(HANDLE); 00228 } 00229 00230 HANDLE CreateLocalMemHandle( 00231 HANDLE hMem) 00232 { 00233 UINT cbData; 00234 NTSTATUS Status; 00235 00236 BEGINCALL() 00237 00238 Status = NtUserCreateLocalMemHandle(hMem, NULL, 0, &cbData); 00239 if (Status != STATUS_BUFFER_TOO_SMALL) { 00240 RIPMSG0(RIP_WARNING, "__CreateLocalMemHandle server returned failure\n"); 00241 MSGERROR(); 00242 } 00243 00244 if (!(retval = (ULONG_PTR)GlobalAlloc(GMEM_FIXED, cbData))) 00245 MSGERROR(); 00246 00247 Status = NtUserCreateLocalMemHandle(hMem, (LPBYTE)retval, cbData, NULL); 00248 if (!NT_SUCCESS(Status)) { 00249 RIPMSG0(RIP_WARNING, "__CreateLocalMemHandle server returned failure\n"); 00250 UserGlobalFree((HANDLE)retval); 00251 MSGERROR(); 00252 } 00253 00254 ERRORTRAP(0); 00255 ENDCALL(HANDLE); 00256 } 00257 00258 HHOOK _SetWindowsHookEx( 00259 HANDLE hmod, 00260 LPTSTR pszLib, 00261 DWORD idThread, 00262 int nFilterType, 00263 PROC pfnFilterProc, 00264 DWORD dwFlags) 00265 { 00266 IN_STRING strLib; 00267 00268 /* 00269 * Make sure cleanup will work successfully 00270 */ 00271 strLib.fAllocated = FALSE; 00272 00273 BEGINCALL() 00274 00275 FIRSTCOPYLPWSTROPT(&strLib, pszLib); 00276 00277 retval = (ULONG_PTR)NtUserSetWindowsHookEx( 00278 hmod, 00279 strLib.pstr, 00280 idThread, 00281 nFilterType, 00282 pfnFilterProc, 00283 dwFlags); 00284 00285 ERRORTRAP(0); 00286 CLEANUPLPWSTR(strLib); 00287 ENDCALL(HHOOK); 00288 } 00289 00290 /***************************************************************************\ 00291 * SetWinEventHook 00292 * 00293 * History: 00294 * 1996-09-23 IanJa Created 00295 \***************************************************************************/ 00296 WINUSERAPI 00297 HWINEVENTHOOK 00298 WINAPI 00299 SetWinEventHook( 00300 DWORD eventMin, 00301 DWORD eventMax, 00302 HMODULE hmodWinEventProc, // Must pass this if global! 00303 WINEVENTPROC lpfnWinEventProc, 00304 DWORD idProcess, // Can be zero; all processes 00305 DWORD idThread, // Can be zero; all threads 00306 DWORD dwFlags) 00307 { 00308 UNICODE_STRING str; 00309 PUNICODE_STRING pstr; 00310 WCHAR awchLib[MAX_PATH]; 00311 00312 BEGINCALL() 00313 00314 if ((dwFlags & WINEVENT_INCONTEXT) && (hmodWinEventProc != NULL)) { 00315 /* 00316 * If we're passing an hmod, we need to grab the file name of the 00317 * module while we're still on the client since module handles 00318 * are NOT global. 00319 */ 00320 USHORT cb; 00321 cb = (USHORT)(sizeof(WCHAR) * GetModuleFileNameW(hmodWinEventProc, awchLib, sizeof(awchLib)/sizeof(WCHAR))); 00322 if (cb == 0) { 00323 /* 00324 * hmod is bogus - return NULL. 00325 */ 00326 return NULL; 00327 } 00328 str.Buffer = awchLib; 00329 str.Length = cb - sizeof(UNICODE_NULL); 00330 str.MaximumLength = cb; 00331 pstr = &str; 00332 } else { 00333 pstr = NULL; 00334 } 00335 00336 retval = (ULONG_PTR)NtUserSetWinEventHook( 00337 eventMin, 00338 eventMax, 00339 hmodWinEventProc, 00340 pstr, 00341 lpfnWinEventProc, 00342 idProcess, 00343 idThread, 00344 dwFlags); 00345 00346 ERRORTRAP(0); 00347 ENDCALL(HWINEVENTHOOK); 00348 }; 00349 00350 00351 WINUSERAPI 00352 VOID 00353 WINAPI 00354 NotifyWinEvent( 00355 DWORD dwEvent, 00356 HWND hwnd, 00357 LONG idObject, 00358 LONG idChild) 00359 { 00360 BEGINCALLVOID() 00361 00362 if (FWINABLE()) { 00363 NtUserNotifyWinEvent(dwEvent, hwnd, idObject, idChild); 00364 } 00365 00366 ERRORTRAPVOID(); 00367 ENDCALLVOID(); 00368 } 00369 00370 00371 /***************************************************************************\ 00372 * ThunkedMenuItemInfo 00373 * 00374 * History: 00375 * 07-22-96 GerardoB - Added header and Fixed up for 5.0 00376 \***************************************************************************/ 00377 BOOL ThunkedMenuItemInfo( 00378 HMENU hMenu, 00379 UINT nPosition, 00380 BOOL fByPosition, 00381 BOOL fInsert, 00382 LPMENUITEMINFOW lpmii, 00383 BOOL fAnsi) 00384 { 00385 MENUITEMINFOW mii; 00386 IN_STRING strItem; 00387 00388 /* 00389 * Make sure cleanup will work successfully 00390 */ 00391 strItem.fAllocated = FALSE; 00392 00393 BEGINCALL() 00394 00395 /* 00396 * Make a local copy so we can make changes 00397 */ 00398 mii = *(LPMENUITEMINFO)(lpmii); 00399 00400 strItem.pstr = NULL; 00401 if (mii.fMask & MIIM_BITMAP) { 00402 if (((HBITMAP)LOWORD(HandleToUlong(mii.hbmpItem)) < HBMMENU_MAX) && IS_PTR(mii.hbmpItem)) { 00403 /* 00404 * Looks like the user was trying to insert one of the 00405 * HBMMENU_* bitmaps, but stuffed some data in the HIWORD. 00406 * We know the HIWORD data is invalid because the LOWORD 00407 * handle is below the GDI minimum. 00408 */ 00409 RIPMSG1(RIP_WARNING, "Invalid HIWORD data (0x%04X) for HBMMENU_* bitmap.", HIWORD(HandleToUlong(mii.hbmpItem))); 00410 mii.hbmpItem = (HBITMAP)LOWORD(HandleToUlong(mii.hbmpItem)); 00411 } else if (!IS_PTR(mii.hbmpItem) && (mii.hbmpItem >= HBMMENU_MAX)) { 00412 /* 00413 * The app is passing a 16-bit GDI handle. GDI handles this on the 00414 * client-side, but not on the kernel side. So convert it to 32-bits. 00415 * This fixes bug 201493 in Macromedia Director. 00416 */ 00417 HBITMAP hbmNew = GdiFixUpHandle(mii.hbmpItem); 00418 if (hbmNew) { 00419 RIPMSG2(RIP_WARNING, "Menu bitmap change, fix 16-bit bitmap handle %lx to %lx\n", mii.hbmpItem, hbmNew); 00420 mii.hbmpItem = hbmNew; 00421 } 00422 } 00423 } 00424 00425 if (mii.fMask & MIIM_STRING){ 00426 if (fAnsi) { 00427 FIRSTCOPYLPSTROPTW(&strItem, mii.dwTypeData); 00428 } else { 00429 FIRSTCOPYLPWSTROPT(&strItem, mii.dwTypeData); 00430 } 00431 } 00432 00433 retval = (DWORD)NtUserThunkedMenuItemInfo( 00434 hMenu, 00435 nPosition, 00436 fByPosition, 00437 fInsert, 00438 &mii, 00439 strItem.pstr); 00440 00441 ERRORTRAP(FALSE); 00442 CLEANUPLPSTRW(strItem); 00443 ENDCALL(BOOL); 00444 } 00445 00446 BOOL DrawCaption( 00447 HWND hwnd, 00448 HDC hdc, 00449 CONST RECT *lprc, 00450 UINT flags) 00451 { 00452 HDC hdcr; 00453 BEGINCALL() 00454 00455 if (IsMetaFile(hdc)) 00456 return FALSE; 00457 00458 hdcr = GdiConvertAndCheckDC(hdc); 00459 if (hdcr == (HDC)0) 00460 return FALSE; 00461 00462 retval = (DWORD)NtUserDrawCaption(hwnd, hdcr, lprc, flags); 00463 00464 ERRORTRAP(0); 00465 ENDCALL(BOOL); 00466 } 00467 00468 SHORT GetAsyncKeyState( 00469 int vKey) 00470 { 00471 BEGINCALLCONNECT() 00472 00473 /* 00474 * Asynchronous key state reports the PHYSICAL mouse button, 00475 * regardless of whether the buttons have been swapped or not. 00476 */ 00477 if (((vKey == VK_RBUTTON) || (vKey == VK_LBUTTON)) && SYSMET(SWAPBUTTON)) { 00478 vKey ^= (VK_RBUTTON ^ VK_LBUTTON); 00479 } 00480 00481 /* 00482 * If this is one of the common keys, see if we can pull it out 00483 * of the cache. 00484 */ 00485 if ((UINT)vKey < CVKASYNCKEYCACHE) { 00486 PCLIENTINFO pci = GetClientInfo(); 00487 if ((pci->dwAsyncKeyCache == gpsi->dwAsyncKeyCache) && 00488 !TestKeyRecentDownBit(pci->afAsyncKeyStateRecentDown, vKey)) { 00489 00490 if (TestKeyDownBit(pci->afAsyncKeyState, vKey)) 00491 retval = 0x8000; 00492 else 00493 retval = 0; 00494 00495 return (SHORT)retval; 00496 } 00497 } 00498 00499 retval = (DWORD)NtUserGetAsyncKeyState( 00500 vKey); 00501 00502 ERRORTRAP(0); 00503 ENDCALL(SHORT); 00504 } 00505 00506 SHORT GetKeyState( 00507 int vKey) 00508 { 00509 BEGINCALLCONNECT() 00510 00511 /* 00512 * If this is one of the common keys, see if we can pull it out 00513 * of the cache. 00514 */ 00515 if ((UINT)vKey < CVKKEYCACHE) { 00516 PCLIENTINFO pci = GetClientInfo(); 00517 if (pci->dwKeyCache == gpsi->dwKeyCache) { 00518 retval = 0; 00519 if (TestKeyToggleBit(pci->afKeyState, vKey)) 00520 retval |= 0x0001; 00521 if (TestKeyDownBit(pci->afKeyState, vKey)) { 00522 /* 00523 * Used to be retval |= 0x8000.Fix for bug 28820; Ctrl-Enter 00524 * accelerator doesn't work on Nestscape Navigator Mail 2.0 00525 */ 00526 retval |= 0xff80; // This is what 3.1 returned!!!! 00527 } 00528 00529 return (SHORT)retval; 00530 } 00531 } 00532 00533 retval = (DWORD)NtUserGetKeyState( 00534 vKey); 00535 00536 ERRORTRAP(0); 00537 ENDCALL(SHORT); 00538 } 00539 00540 BOOL OpenClipboard( 00541 HWND hwnd) 00542 { 00543 BOOL fEmptyClient; 00544 00545 BEGINCALL() 00546 00547 retval = (DWORD)NtUserOpenClipboard(hwnd, &fEmptyClient); 00548 00549 if (fEmptyClient) 00550 ClientEmptyClipboard(); 00551 00552 ERRORTRAP(0); 00553 ENDCALL(BOOL); 00554 } 00555 00556 BOOL _PeekMessage( 00557 LPMSG pmsg, 00558 HWND hwnd, 00559 UINT wMsgFilterMin, 00560 UINT wMsgFilterMax, 00561 UINT wRemoveMsg, 00562 BOOL bAnsi) 00563 { 00564 BEGINCALL() 00565 00566 if (bAnsi) { 00567 // 00568 // If we have pushed message for DBCS messaging, we should pass this one 00569 // to Apps at first... 00570 // 00571 GET_DBCS_MESSAGE_IF_EXIST( 00572 PeekMessage,pmsg,wMsgFilterMin,wMsgFilterMax,((wRemoveMsg & PM_REMOVE) ? TRUE:FALSE)); 00573 } 00574 00575 retval = (DWORD)NtUserPeekMessage( 00576 pmsg, 00577 hwnd, 00578 wMsgFilterMin, 00579 wMsgFilterMax, 00580 wRemoveMsg); 00581 00582 if (retval) { 00583 // May have a bit more work to do if this MSG is for an ANSI app 00584 00585 if (bAnsi) { 00586 if (RtlWCSMessageWParamCharToMB(pmsg->message, &(pmsg->wParam))) { 00587 WPARAM dwAnsi = pmsg->wParam; 00588 // 00589 // Build DBCS-ware wParam. (for EM_SETPASSWORDCHAR...) 00590 // 00591 BUILD_DBCS_MESSAGE_TO_CLIENTA_FROM_SERVER( 00592 pmsg,dwAnsi,TRUE,((wRemoveMsg & PM_REMOVE) ? TRUE:FALSE)); 00593 } else { 00594 retval = 0; 00595 } 00596 } else { 00597 // 00598 // Only LOWORD of WPARAM is valid for WM_CHAR.... 00599 // (Mask off DBCS messaging information.) 00600 // 00601 BUILD_DBCS_MESSAGE_TO_CLIENTW_FROM_SERVER(pmsg->message,pmsg->wParam); 00602 } 00603 } 00604 00605 ExitPeekMessage: 00606 00607 ERRORTRAP(0); 00608 ENDCALL(BOOL); 00609 } 00610 00611 00612 LONG_PTR _SetWindowLongPtr( 00613 HWND hwnd, 00614 int nIndex, 00615 LONG_PTR dwNewLong, 00616 BOOL bAnsi) 00617 { 00618 PWND pwnd; 00619 LONG_PTR dwOldLong; 00620 DWORD dwCPDType = 0; 00621 00622 pwnd = ValidateHwnd(hwnd); 00623 00624 if (pwnd == NULL) 00625 return 0; 00626 00627 if (TestWF(pwnd, WFDIALOGWINDOW)) { 00628 switch (nIndex) { 00629 case DWLP_DLGPROC: // See similar case GWL_WNDPROC 00630 00631 /* 00632 * Hide the window proc from other processes 00633 */ 00634 if (!TestWindowProcess(pwnd)) { 00635 RIPERR1(ERROR_ACCESS_DENIED, 00636 RIP_WARNING, 00637 "Access denied to hwnd (%#lx) in _SetWindowLong", 00638 hwnd); 00639 00640 return 0; 00641 } 00642 00643 /* 00644 * Get the old window proc address 00645 */ 00646 dwOldLong = (LONG_PTR)PDLG(pwnd)->lpfnDlg; 00647 00648 /* 00649 * We always store the actual address in the wndproc; We only 00650 * give the CallProc handles to the application 00651 */ 00652 UserAssert(!ISCPDTAG(dwOldLong)); 00653 00654 /* 00655 * May need to return a CallProc handle if there is an 00656 * Ansi/Unicode tranistion 00657 */ 00658 00659 if (bAnsi != ((PDLG(pwnd)->flags & DLGF_ANSI) ? TRUE : FALSE)) { 00660 dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI; 00661 } 00662 00663 /* 00664 * If we detected a transition create a CallProc handle for 00665 * this type of transition and this wndproc (dwOldLong) 00666 */ 00667 if (dwCPDType) { 00668 ULONG_PTR cpd; 00669 00670 cpd = GetCPD(pwnd, dwCPDType | CPD_DIALOG, dwOldLong); 00671 00672 if (cpd) { 00673 dwOldLong = cpd; 00674 } else { 00675 RIPMSG0(RIP_WARNING, "SetWindowLong (DWL_DLGPROC) unable to alloc CPD returning handle\n"); 00676 } 00677 } 00678 00679 /* 00680 * Convert a possible CallProc Handle into a real address. 00681 * The app may have kept the CallProc Handle from some 00682 * previous mixed GetClassinfo or SetWindowLong. 00683 * 00684 * WARNING bAnsi is modified here to represent real type of 00685 * proc rather than if SetWindowLongA or W was called 00686 */ 00687 if (ISCPDTAG(dwNewLong)) { 00688 PCALLPROCDATA pCPD; 00689 if (pCPD = HMValidateHandleNoRip((HANDLE)dwNewLong, TYPE_CALLPROC)) { 00690 dwNewLong = KERNEL_ULONG_PTR_TO_ULONG_PTR(pCPD->pfnClientPrevious); 00691 bAnsi = pCPD->wType & CPD_UNICODE_TO_ANSI; 00692 } 00693 } 00694 00695 /* 00696 * If an app 'unsubclasses' a server-side window proc we need to 00697 * restore everything so SendMessage and friends know that it's 00698 * a server-side proc again. Need to check against client side 00699 * stub addresses. 00700 */ 00701 PDLG(pwnd)->lpfnDlg = (DLGPROC)dwNewLong; 00702 if (bAnsi) { 00703 PDLG(pwnd)->flags |= DLGF_ANSI; 00704 } else { 00705 PDLG(pwnd)->flags &= ~DLGF_ANSI; 00706 } 00707 00708 return dwOldLong; 00709 00710 case DWLP_USER: 00711 #ifdef BUILD_WOW6432 00712 // kernel has special handling of DWLP_USER 00713 nIndex = sizeof(KERNEL_LRESULT) + sizeof(KERNEL_PVOID); 00714 #endif 00715 case DWLP_MSGRESULT: 00716 break; 00717 00718 default: 00719 if (nIndex >= 0 && nIndex < DLGWINDOWEXTRA) { 00720 RIPERR0(ERROR_PRIVATE_DIALOG_INDEX, RIP_VERBOSE, ""); 00721 return 0; 00722 } 00723 } 00724 } 00725 00726 BEGINCALL() 00727 00728 /* 00729 * If this is a listbox window and the listbox structure has 00730 * already been initialized, don't allow the app to override the 00731 * owner draw styles. We need to do this since Windows only 00732 * used the styles in creating the structure, but we also use 00733 * them to determine if strings need to be thunked. 00734 * 00735 */ 00736 00737 if (nIndex == GWL_STYLE && 00738 GETFNID(pwnd) == FNID_LISTBOX && 00739 ((PLBWND)pwnd)->pLBIV != NULL && 00740 (!TestWindowProcess(pwnd) || ((PLBWND)pwnd)->pLBIV->fInitialized)) { 00741 00742 #if DBG 00743 LONG_PTR dwDebugLong = dwNewLong; 00744 #endif 00745 00746 dwNewLong &= ~(LBS_OWNERDRAWFIXED | 00747 LBS_OWNERDRAWVARIABLE | 00748 LBS_HASSTRINGS); 00749 00750 dwNewLong |= pwnd->style & (LBS_OWNERDRAWFIXED | 00751 LBS_OWNERDRAWVARIABLE | 00752 LBS_HASSTRINGS); 00753 00754 #if DBG 00755 if (dwDebugLong != dwNewLong) { 00756 RIPMSG0(RIP_WARNING, "SetWindowLong can't change LBS_OWNERDRAW* or LBS_HASSTRINGS."); 00757 } 00758 #endif 00759 } 00760 00761 00762 retval = (ULONG_PTR)NtUserSetWindowLongPtr( 00763 hwnd, 00764 nIndex, 00765 dwNewLong, 00766 bAnsi); 00767 00768 ERRORTRAP(0); 00769 ENDCALL(LONG_PTR); 00770 } 00771 00772 #ifdef _WIN64 00773 LONG _SetWindowLong( 00774 HWND hwnd, 00775 int nIndex, 00776 LONG dwNewLong, 00777 BOOL bAnsi) 00778 { 00779 PWND pwnd; 00780 00781 pwnd = ValidateHwnd(hwnd); 00782 00783 if (pwnd == NULL) 00784 return 0; 00785 00786 if (TestWF(pwnd, WFDIALOGWINDOW)) { 00787 switch (nIndex) { 00788 case DWLP_DLGPROC: // See similar case GWLP_WNDPROC 00789 RIPERR1(ERROR_INVALID_INDEX, RIP_WARNING, "SetWindowLong: invalid index %d", nIndex); 00790 return 0; 00791 00792 case DWLP_MSGRESULT: 00793 case DWLP_USER: 00794 break; 00795 00796 default: 00797 if (nIndex >= 0 && nIndex < DLGWINDOWEXTRA) { 00798 RIPERR0(ERROR_PRIVATE_DIALOG_INDEX, RIP_VERBOSE, ""); 00799 return 0; 00800 } 00801 } 00802 } 00803 00804 BEGINCALL() 00805 00806 /* 00807 * If this is a listbox window and the listbox structure has 00808 * already been initialized, don't allow the app to override the 00809 * owner draw styles. We need to do this since Windows only 00810 * used the styles in creating the structure, but we also use 00811 * them to determine if strings need to be thunked. 00812 * 00813 */ 00814 00815 if (nIndex == GWL_STYLE && 00816 GETFNID(pwnd) == FNID_LISTBOX && 00817 ((PLBWND)pwnd)->pLBIV != NULL && 00818 (!TestWindowProcess(pwnd) || ((PLBWND)pwnd)->pLBIV->fInitialized)) { 00819 00820 #if DBG 00821 LONG dwDebugLong = dwNewLong; 00822 #endif 00823 00824 dwNewLong &= ~(LBS_OWNERDRAWFIXED | 00825 LBS_OWNERDRAWVARIABLE | 00826 LBS_HASSTRINGS); 00827 00828 dwNewLong |= pwnd->style & (LBS_OWNERDRAWFIXED | 00829 LBS_OWNERDRAWVARIABLE | 00830 LBS_HASSTRINGS); 00831 00832 #if DBG 00833 if (dwDebugLong != dwNewLong) { 00834 RIPMSG0(RIP_WARNING, "SetWindowLong can't change LBS_OWNERDRAW* or LBS_HASSTRINGS."); 00835 } 00836 #endif 00837 } 00838 00839 00840 retval = (DWORD)NtUserSetWindowLong( 00841 hwnd, 00842 nIndex, 00843 dwNewLong, 00844 bAnsi); 00845 00846 ERRORTRAP(0); 00847 ENDCALL(LONG); 00848 } 00849 #endif 00850 00851 BOOL TranslateMessageEx( 00852 CONST MSG *pmsg, 00853 UINT flags) 00854 { 00855 BEGINCALL() 00856 00857 /* 00858 * Don't bother going over to the kernel if this isn't 00859 * key message. 00860 */ 00861 switch (pmsg->message) { 00862 case WM_KEYDOWN: 00863 case WM_KEYUP: 00864 case WM_SYSKEYDOWN: 00865 case WM_SYSKEYUP: 00866 break; 00867 default: 00868 if (pmsg->message & RESERVED_MSG_BITS) { 00869 RIPERR1(ERROR_INVALID_PARAMETER, 00870 RIP_WARNING, 00871 "Invalid parameter \"pmsg->message\" (%ld) to TranslateMessageEx", 00872 pmsg->message); 00873 } 00874 MSGERROR(); 00875 } 00876 00877 retval = (DWORD)NtUserTranslateMessage( 00878 pmsg, 00879 flags); 00880 00881 ERRORTRAP(0); 00882 ENDCALL(BOOL); 00883 } 00884 00885 BOOL TranslateMessage( 00886 CONST MSG *pmsg) 00887 { 00888 // 00889 // IME special key handling 00890 // 00891 if ( LOWORD(pmsg->wParam) == VK_PROCESSKEY ) { 00892 BOOL fResult; 00893 // 00894 // This vkey should be processed by IME 00895 // 00896 fResult = fpImmTranslateMessage( pmsg->hwnd, 00897 pmsg->message, 00898 pmsg->wParam, 00899 pmsg->lParam ); 00900 if ( fResult ) 00901 return fResult; 00902 } 00903 return(TranslateMessageEx(pmsg, 0)); 00904 } 00905 00906 BOOL SetWindowRgn( 00907 HWND hwnd, 00908 HRGN hrgn, 00909 BOOL bRedraw) 00910 { 00911 BEGINCALL() 00912 00913 retval = (DWORD)NtUserSetWindowRgn( 00914 hwnd, 00915 hrgn, 00916 bRedraw); 00917 00918 if (retval) { 00919 DeleteObject(hrgn); 00920 } 00921 00922 ERRORTRAP(0); 00923 ENDCALL(BOOL); 00924 } 00925 00926 BOOL InternalGetWindowText( 00927 HWND hwnd, 00928 LPWSTR pString, 00929 int cchMaxCount) 00930 { 00931 BEGINCALL() 00932 00933 retval = (DWORD)NtUserInternalGetWindowText( 00934 hwnd, 00935 pString, 00936 cchMaxCount); 00937 00938 if (!retval) { 00939 *pString = (WCHAR)0; 00940 } 00941 00942 ERRORTRAP(0); 00943 ENDCALL(BOOL); 00944 } 00945 00946 int ToUnicode( 00947 UINT wVirtKey, 00948 UINT wScanCode, 00949 CONST BYTE *pKeyState, 00950 LPWSTR pwszBuff, 00951 int cchBuff, 00952 UINT wFlags) 00953 { 00954 BEGINCALL() 00955 00956 retval = (DWORD)NtUserToUnicodeEx( 00957 wVirtKey, 00958 wScanCode, 00959 pKeyState, 00960 pwszBuff, 00961 cchBuff, 00962 wFlags, 00963 (HKL)NULL); 00964 00965 if (!retval) { 00966 *pwszBuff = L'\0'; 00967 } 00968 00969 ERRORTRAP(0); 00970 ENDCALL(int); 00971 } 00972 00973 int ToUnicodeEx( 00974 UINT wVirtKey, 00975 UINT wScanCode, 00976 CONST BYTE *pKeyState, 00977 LPWSTR pwszBuff, 00978 int cchBuff, 00979 UINT wFlags, 00980 HKL hkl) 00981 { 00982 BEGINCALL() 00983 00984 retval = (DWORD)NtUserToUnicodeEx( 00985 wVirtKey, 00986 wScanCode, 00987 pKeyState, 00988 pwszBuff, 00989 cchBuff, 00990 wFlags, 00991 hkl); 00992 00993 if (!retval) { 00994 *pwszBuff = L'\0'; 00995 } 00996 00997 ERRORTRAP(0); 00998 ENDCALL(int); 00999 } 01000 01001 #if DBG 01002 VOID DbgWin32HeapFail( 01003 DWORD dwFlags, 01004 BOOL bFail) 01005 { 01006 if ((dwFlags | WHF_VALID) != WHF_VALID) { 01007 RIPMSG1(RIP_WARNING, "Invalid flags for DbgWin32HeapFail %x", dwFlags); 01008 return; 01009 } 01010 01011 if (dwFlags & WHF_CSRSS) { 01012 // Tell csr about it 01013 CsrWin32HeapFail(dwFlags, bFail); 01014 } 01015 01016 NtUserDbgWin32HeapFail(dwFlags, bFail); 01017 } 01018 01019 DWORD DbgWin32HeapStat( 01020 PDBGHEAPSTAT phs, 01021 DWORD dwLen, 01022 DWORD dwFlags) 01023 { 01024 if ((dwFlags | WHF_VALID) != WHF_VALID) { 01025 RIPMSG1(RIP_WARNING, "Invalid flags for DbgWin32HeapFail %x", dwFlags); 01026 return 0; 01027 } 01028 01029 if (dwFlags & WHF_CSRSS) { 01030 return CsrWin32HeapStat(phs, dwLen); 01031 } else if (dwFlags & WHF_DESKTOP) { 01032 return NtUserDbgWin32HeapStat(phs, dwLen); 01033 } 01034 return 0; 01035 } 01036 01037 #endif // DBG 01038 01039 BOOL SetWindowStationUser( 01040 HWINSTA hwinsta, 01041 PLUID pluidUser, 01042 PSID psidUser, 01043 DWORD cbsidUser) 01044 { 01045 LUID luidNone = { 0, 0 }; 01046 01047 01048 BEGINCALL() 01049 01050 retval = (DWORD)NtUserSetWindowStationUser(hwinsta, 01051 pluidUser, 01052 psidUser, 01053 cbsidUser); 01054 01055 /* 01056 * Load global atoms if the logon succeeded 01057 */ 01058 if (retval) { 01059 01060 if (!RtlEqualLuid(pluidUser,&luidNone)) { 01061 /* 01062 * Reset console and load Nls data. 01063 */ 01064 Logon(TRUE); 01065 } else { 01066 /* 01067 * Flush NLS cache. 01068 */ 01069 Logon(FALSE); 01070 } 01071 01072 retval = TRUE; 01073 } 01074 ERRORTRAP(0); 01075 ENDCALL(BOOL); 01076 } 01077 01078 BOOL SetSystemCursor( 01079 HCURSOR hcur, 01080 DWORD id) 01081 { 01082 BEGINCALL() 01083 01084 if (hcur == NULL) { 01085 hcur = (HANDLE)LoadIcoCur(NULL, 01086 MAKEINTRESOURCE(id), 01087 RT_CURSOR, 01088 0, 01089 0, 01090 LR_DEFAULTSIZE); 01091 01092 if (hcur == NULL) 01093 MSGERROR(); 01094 } 01095 01096 retval = (DWORD)NtUserSetSystemCursor(hcur, id); 01097 01098 ERRORTRAP(0); 01099 ENDCALL(BOOL); 01100 } 01101 01102 HCURSOR FindExistingCursorIcon( 01103 LPWSTR pszModName, 01104 LPCWSTR pszResName, 01105 PCURSORFIND pcfSearch) 01106 { 01107 IN_STRING strModName; 01108 IN_STRING strResName; 01109 01110 /* 01111 * Make sure cleanup will work successfully 01112 */ 01113 strModName.fAllocated = FALSE; 01114 strResName.fAllocated = FALSE; 01115 01116 BEGINCALL() 01117 01118 if (pszModName == NULL) 01119 pszModName = szUSER32; 01120 01121 COPYLPWSTR(&strModName, pszModName); 01122 COPYLPWSTRID(&strResName, pszResName); 01123 01124 retval = (ULONG_PTR)NtUserFindExistingCursorIcon(strModName.pstr, 01125 strResName.pstr, 01126 pcfSearch); 01127 01128 ERRORTRAP(0); 01129 01130 CLEANUPLPWSTR(strModName); 01131 CLEANUPLPWSTR(strResName); 01132 01133 ENDCALL(HCURSOR); 01134 } 01135 01136 01137 01138 BOOL _SetCursorIconData( 01139 HCURSOR hCursor, 01140 PCURSORDATA pcur) 01141 { 01142 IN_STRING strModName; 01143 IN_STRING strResName; 01144 01145 /* 01146 * Make sure cleanup will work successfully 01147 */ 01148 strModName.fAllocated = FALSE; 01149 strResName.fAllocated = FALSE; 01150 01151 BEGINCALL() 01152 01153 COPYLPWSTROPT(&strModName, pcur->lpModName); 01154 COPYLPWSTRIDOPT(&strResName, pcur->lpName); 01155 01156 retval = (DWORD)NtUserSetCursorIconData(hCursor, 01157 strModName.pstr, 01158 strResName.pstr, 01159 pcur); 01160 01161 ERRORTRAP(0); 01162 01163 CLEANUPLPWSTR(strModName); 01164 CLEANUPLPWSTR(strResName); 01165 01166 ENDCALL(BOOL); 01167 } 01168 01169 01170 01171 BOOL _DefSetText( 01172 HWND hwnd, 01173 LPCWSTR lpszText, 01174 BOOL bAnsi) 01175 { 01176 LARGE_STRING str; 01177 01178 BEGINCALL() 01179 01180 if (lpszText) { 01181 if (bAnsi) 01182 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&str, 01183 (LPSTR)lpszText, (UINT)-1); 01184 else 01185 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&str, 01186 lpszText, (UINT)-1); 01187 } 01188 01189 retval = (DWORD)NtUserDefSetText( 01190 hwnd, 01191 lpszText ? &str : NULL); 01192 01193 ERRORTRAP(0); 01194 ENDCALL(BOOL); 01195 } 01196 01197 HWND _CreateWindowEx( 01198 DWORD dwExStyle, 01199 LPCTSTR pClassName, 01200 LPCTSTR pWindowName, 01201 DWORD dwStyle, 01202 int x, 01203 int y, 01204 int nWidth, 01205 int nHeight, 01206 HWND hwndParent, 01207 HMENU hmenu, 01208 HANDLE hModule, 01209 LPVOID pParam, 01210 DWORD dwFlags) 01211 { 01212 LARGE_IN_STRING strClassName; 01213 LARGE_STRING strWindowName; 01214 PLARGE_STRING pstrClassName; 01215 PLARGE_STRING pstrWindowName; 01216 DWORD dwExpWinVerAndFlags; 01217 01218 /* 01219 * Make sure cleanup will work successfully 01220 */ 01221 strClassName.fAllocated = FALSE; 01222 01223 /* 01224 * To be compatible with Chicago, we test the validity of 01225 * the ExStyle bits and fail if any invalid bits are found. 01226 * And for backward compatibilty with NT apps, we only fail for 01227 * new apps (post NT 3.1). 01228 */ 01229 01230 // BOGUS 01231 01232 if (dwExStyle & 0x00000800L) { 01233 dwExStyle |= WS_EX_TOOLWINDOW; 01234 dwExStyle &= 0xfffff7ffL; 01235 } 01236 01237 dwExpWinVerAndFlags = (DWORD)(WORD)GETEXPWINVER(hModule); 01238 if ((dwExStyle & ~WS_EX_VALID50) && (dwExpWinVerAndFlags >= VER40) ) { 01239 RIPMSG0(RIP_ERROR, "Invalid 5.0 ExStyle\n"); 01240 return NULL; 01241 } 01242 { 01243 01244 BOOL fMDIchild = FALSE; 01245 MDICREATESTRUCT mdics; 01246 HMENU hSysMenu; 01247 01248 BEGINCALL() 01249 01250 if ((fMDIchild = (BOOL)(dwExStyle & WS_EX_MDICHILD))) { 01251 SHORTCREATE sc; 01252 PWND pwndParent; 01253 01254 pwndParent = ValidateHwnd(hwndParent); 01255 01256 if ((pwndParent == NULL) || (GETFNID(pwndParent) != FNID_MDICLIENT)) { 01257 RIPMSG0(RIP_ERROR, "Invalid parent for MDI child window\n"); 01258 MSGERROR(); 01259 } 01260 01261 mdics.lParam = (LPARAM)pParam; 01262 pParam = &mdics; 01263 mdics.x = sc.x = x; 01264 mdics.y = sc.y = y; 01265 mdics.cx = sc.cx = nWidth; 01266 mdics.cy = sc.cy = nHeight; 01267 mdics.style = sc.style = dwStyle; 01268 mdics.hOwner = hModule; 01269 mdics.szClass = pClassName; 01270 mdics.szTitle = pWindowName; 01271 01272 if (!CreateMDIChild(&sc, &mdics, dwExpWinVerAndFlags, &hSysMenu, pwndParent)) 01273 MSGERROR(); 01274 01275 x = sc.x; 01276 y = sc.y; 01277 nWidth = sc.cx; 01278 nHeight = sc.cy; 01279 dwStyle = sc.style; 01280 hmenu = sc.hMenu; 01281 } 01282 01283 /* 01284 * Set up class and window name. If the window name is an 01285 * ordinal, make it look like a string so the callback thunk 01286 * will be able to ensure it is in the correct format. 01287 */ 01288 pstrWindowName = NULL; 01289 if (dwFlags & CW_FLAGS_ANSI) { 01290 dwExStyle = dwExStyle | WS_EX_ANSICREATOR; 01291 if (IS_PTR(pClassName)) { 01292 RtlCaptureLargeAnsiString(&strClassName, 01293 (PCHAR)pClassName, TRUE); 01294 pstrClassName = (PLARGE_STRING)strClassName.pstr; 01295 } else 01296 pstrClassName = (PLARGE_STRING)pClassName; 01297 01298 if (pWindowName != NULL) { 01299 if (*(PBYTE)pWindowName == 0xff) { 01300 strWindowName.bAnsi = TRUE; 01301 strWindowName.Buffer = (PVOID)pWindowName; 01302 strWindowName.Length = 3; 01303 strWindowName.MaximumLength = 3; 01304 } else 01305 RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&strWindowName, 01306 (LPSTR)pWindowName, (UINT)-1); 01307 pstrWindowName = &strWindowName; 01308 } 01309 } else { 01310 if (IS_PTR(pClassName)) { 01311 RtlInitLargeUnicodeString( 01312 (PLARGE_UNICODE_STRING)&strClassName.strCapture, 01313 pClassName, (UINT)-1); 01314 pstrClassName = (PLARGE_STRING)&strClassName.strCapture; 01315 } else 01316 pstrClassName = (PLARGE_STRING)pClassName; 01317 01318 if (pWindowName != NULL) { 01319 if (pWindowName != NULL && 01320 *(PWORD)pWindowName == 0xffff) { 01321 strWindowName.bAnsi = FALSE; 01322 strWindowName.Buffer = (PVOID)pWindowName; 01323 strWindowName.Length = 4; 01324 strWindowName.MaximumLength = 4; 01325 } else 01326 RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strWindowName, 01327 pWindowName, (UINT)-1); 01328 pstrWindowName = &strWindowName; 01329 } 01330 } 01331 if (dwFlags & CW_FLAGS_DIFFHMOD) { 01332 dwExpWinVerAndFlags |= CW_FLAGS_DIFFHMOD; 01333 } 01334 01335 retval = (ULONG_PTR)NtUserCreateWindowEx( 01336 dwExStyle, 01337 pstrClassName, 01338 pstrWindowName, 01339 dwStyle, 01340 x, 01341 y, 01342 nWidth, 01343 nHeight, 01344 hwndParent, 01345 hmenu, 01346 hModule, 01347 pParam, 01348 dwExpWinVerAndFlags); 01349 01350 // If this is an MDI child, we need to do some more to complete the 01351 // process of creating an MDI child. 01352 if (retval && fMDIchild) { 01353 MDICompleteChildCreation((HWND)retval, hSysMenu, ((dwStyle & WS_VISIBLE) != 0L), (BOOL)((dwStyle & WS_DISABLED)!= 0L)); 01354 } 01355 01356 01357 ERRORTRAP(0); 01358 CLEANUPLPSTRW(strClassName); 01359 ENDCALL(HWND); 01360 } 01361 } 01362 01363 HKL _LoadKeyboardLayoutEx( 01364 HANDLE hFile, 01365 UINT offTable, 01366 HKL hkl, 01367 LPCTSTR pwszKL, 01368 UINT KbdInputLocale, 01369 UINT Flags) 01370 { 01371 IN_STRING strKL; 01372 01373 /* 01374 * Make sure cleanup will work successfully 01375 */ 01376 strKL.fAllocated = FALSE; 01377 01378 BEGINCALL() 01379 01380 FIRSTCOPYLPWSTR(&strKL, pwszKL); 01381 01382 retval = (ULONG_PTR)NtUserLoadKeyboardLayoutEx( 01383 hFile, 01384 offTable, 01385 hkl, 01386 strKL.pstr, 01387 KbdInputLocale, 01388 Flags); 01389 01390 ERRORTRAP(0); 01391 CLEANUPLPWSTR(strKL); 01392 ENDCALL(HKL); 01393 } 01394 01395 VOID mouse_event( 01396 DWORD dwFlags, 01397 DWORD dx, 01398 DWORD dy, 01399 DWORD dwData, 01400 ULONG_PTR dwExtraInfo) 01401 { 01402 INPUT ms; 01403 01404 BEGINCALLVOID() 01405 01406 ms.type = INPUT_MOUSE; 01407 ms.mi.dwFlags = dwFlags; 01408 ms.mi.dx = dx; 01409 ms.mi.dy = dy; 01410 ms.mi.mouseData = dwData; 01411 ms.mi.time = 0; 01412 ms.mi.dwExtraInfo = dwExtraInfo; 01413 01414 NtUserSendInput(1, &ms, sizeof(INPUT)); 01415 01416 ENDCALLVOID() 01417 } 01418 01419 VOID keybd_event( 01420 BYTE bVk, 01421 BYTE bScan, 01422 DWORD dwFlags, 01423 ULONG_PTR dwExtraInfo) 01424 { 01425 INPUT kbd; 01426 01427 BEGINCALLVOID() 01428 01429 kbd.type = INPUT_KEYBOARD; 01430 kbd.ki.dwFlags = dwFlags; 01431 kbd.ki.wVk = bVk; 01432 kbd.ki.wScan = bScan; 01433 kbd.ki.time = 0; 01434 kbd.ki.dwExtraInfo = dwExtraInfo; 01435 01436 NtUserSendInput(1, &kbd, sizeof(INPUT)); 01437 01438 ENDCALLVOID() 01439 } 01440 01441 /* 01442 * Message thunks 01443 */ 01444 MESSAGECALL(fnINWPARAMDBCSCHAR) 01445 { 01446 BEGINCALL() 01447 01448 /* 01449 * The server always expects the characters to be unicode so 01450 * if this was generated from an ANSI routine convert it to Unicode 01451 */ 01452 if (bAnsi) { 01453 01454 /* 01455 * Setup for DBCS Messaging.. 01456 */ 01457 BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(msg,wParam,TRUE); 01458 01459 /* 01460 * Convert DBCS/SBCS to Unicode... 01461 */ 01462 RtlMBMessageWParamCharToWCS(msg, &wParam); 01463 } 01464 01465 retval = (DWORD)NtUserMessageCall( 01466 hwnd, 01467 msg, 01468 wParam, 01469 lParam, 01470 xParam, 01471 xpfnProc, 01472 bAnsi); 01473 01474 ERRORTRAP(0); 01475 ENDCALL(DWORD); 01476 } 01477 01478 MESSAGECALL(fnCOPYGLOBALDATA) 01479 { 01480 PBYTE pData; 01481 BEGINCALL() 01482 01483 if (wParam == 0) { 01484 MSGERROR(); 01485 } 01486 01487 USERGLOBALLOCK((HGLOBAL)lParam, pData); 01488 if (pData == NULL) { 01489 MSGERROR(); 01490 } 01491 retval = (DWORD)NtUserMessageCall( 01492 hwnd, 01493 msg, 01494 wParam, 01495 (LPARAM)pData, 01496 xParam, 01497 xpfnProc, 01498 bAnsi); 01499 USERGLOBALUNLOCK((HGLOBAL)lParam); 01500 UserGlobalFree((HGLOBAL)lParam); 01501 ERRORTRAP(0); 01502 ENDCALL(DWORD); 01503 } 01504 01505 MESSAGECALL(fnINPAINTCLIPBRD) 01506 { 01507 LPPAINTSTRUCT lpps; 01508 01509 BEGINCALL() 01510 01511 USERGLOBALLOCK((HGLOBAL)lParam, lpps); 01512 if (lpps) { 01513 retval = (DWORD)NtUserMessageCall( 01514 hwnd, 01515 msg, 01516 wParam, 01517 (LPARAM)lpps, 01518 xParam, 01519 xpfnProc, 01520 bAnsi); 01521 USERGLOBALUNLOCK((HGLOBAL)lParam); 01522 } else { 01523 RIPMSG1(RIP_WARNING, "MESSAGECALL(fnINPAINTCLIPBRD): USERGLOBALLOCK failed on %p!", lParam); 01524 } 01525 01526 ERRORTRAP(0); 01527 ENDCALL(DWORD); 01528 } 01529 01530 MESSAGECALL(fnINSIZECLIPBRD) 01531 { 01532 LPRECT lprc; 01533 BEGINCALL() 01534 01535 USERGLOBALLOCK((HGLOBAL)lParam, lprc); 01536 if (lprc) { 01537 retval = (DWORD)NtUserMessageCall( 01538 hwnd, 01539 msg, 01540 wParam, 01541 (LPARAM)lprc, 01542 xParam, 01543 xpfnProc, 01544 bAnsi); 01545 USERGLOBALUNLOCK((HGLOBAL)lParam); 01546 } else { 01547 RIPMSG1(RIP_WARNING, "MESSAGECALL(fnINSIZECLIPBRD): USERGLOBALLOCK failed on %p!", lParam); 01548 } 01549 01550 ERRORTRAP(0); 01551 ENDCALL(DWORD); 01552 } 01553 01554 MESSAGECALL(fnINDEVICECHANGE) 01555 { 01556 struct _DEV_BROADCAST_HEADER *pHdr; 01557 PDEV_BROADCAST_PORT_W pPortW = NULL; 01558 PDEV_BROADCAST_PORT_A pPortA; 01559 PDEV_BROADCAST_DEVICEINTERFACE_W pInterfaceW = NULL; 01560 PDEV_BROADCAST_DEVICEINTERFACE_A pInterfaceA; 01561 PDEV_BROADCAST_HANDLE pHandleW = NULL; 01562 PDEV_BROADCAST_HANDLE pHandleA; 01563 01564 LPWSTR lpStr; 01565 int iStr, iSize; 01566 01567 BEGINCALL() 01568 01569 if (!(wParam &0x8000) || !lParam || !bAnsi) 01570 goto shipit; 01571 01572 pHdr = (struct _DEV_BROADCAST_HEADER *)lParam; 01573 switch (pHdr->dbcd_devicetype) { 01574 case DBT_DEVTYP_PORT: 01575 pPortA = (PDEV_BROADCAST_PORT_A)lParam; 01576 iStr = strlen(pPortA->dbcp_name); 01577 iSize = FIELD_OFFSET(DEV_BROADCAST_PORT_W, dbcp_name) + sizeof(WCHAR)*(iStr+1); 01578 pPortW = UserLocalAlloc(0, iSize); 01579 if (pPortW == NULL) 01580 return 0; 01581 RtlCopyMemory(pPortW, pPortA, sizeof(DEV_BROADCAST_PORT_A)); 01582 lpStr = pPortW->dbcp_name; 01583 if (iStr) { 01584 MBToWCS(pPortA->dbcp_name, -1, &lpStr, iStr, FALSE); 01585 lpStr[iStr] = 0; 01586 } else { 01587 lpStr[0] = 0; 01588 } 01589 pPortW->dbcp_size = iSize; 01590 lParam = (LPARAM)pPortW; 01591 bAnsi = FALSE; 01592 break; 01593 01594 case DBT_DEVTYP_DEVICEINTERFACE: 01595 pInterfaceA = (PDEV_BROADCAST_DEVICEINTERFACE_A)lParam; 01596 iStr = strlen(pInterfaceA->dbcc_name); 01597 iSize = FIELD_OFFSET(DEV_BROADCAST_DEVICEINTERFACE_W, dbcc_name) + sizeof(WCHAR)*(iStr+1); 01598 pInterfaceW = UserLocalAlloc(0, iSize); 01599 if (pInterfaceW == NULL) 01600 return 0; 01601 RtlCopyMemory(pInterfaceW, pInterfaceA, sizeof(DEV_BROADCAST_DEVICEINTERFACE_A)); 01602 lpStr = pInterfaceW->dbcc_name; 01603 if (iStr) { 01604 MBToWCS(pInterfaceA->dbcc_name, -1, &lpStr, iStr, FALSE); 01605 lpStr[iStr] = 0; 01606 } else { 01607 lpStr[0] = 0; 01608 } 01609 pInterfaceW->dbcc_size = iSize; 01610 lParam = (LPARAM)pInterfaceW; 01611 bAnsi = FALSE; 01612 break; 01613 01614 case DBT_DEVTYP_HANDLE: 01615 pHandleA = (PDEV_BROADCAST_HANDLE)lParam; 01616 bAnsi = FALSE; 01617 if ((wParam != DBT_CUSTOMEVENT) || (pHandleA->dbch_nameoffset < 0)) break; 01618 iStr = strlen(pHandleA->dbch_data+pHandleA->dbch_nameoffset); 01619 /* 01620 * Calculate size of new structure with UNICODE string instead of Ansi string 01621 */ 01622 01623 iSize = FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_data)+ pHandleA->dbch_nameoffset + sizeof(WCHAR)*(iStr+1); 01624 /* 01625 * Just in case there were an odd number of bytes in the non-text data 01626 */ 01627 if (iSize & 1) iSize++; 01628 pHandleW = UserLocalAlloc(0, iSize); 01629 if (pHandleW == NULL) 01630 return 0; 01631 RtlCopyMemory(pHandleW, pHandleA, FIELD_OFFSET(DEV_BROADCAST_HANDLE, dbch_data)+ pHandleA->dbch_nameoffset); 01632 01633 /* 01634 * Make sure this is even for the UNICODE string. 01635 */ 01636 01637 if (pHandleW->dbch_nameoffset & 1) pHandleW->dbch_nameoffset++; 01638 01639 lpStr = (LPWSTR)(pHandleW->dbch_data+pHandleW->dbch_nameoffset); 01640 if (iStr) { 01641 MBToWCS(pHandleA->dbch_data+pHandleA->dbch_nameoffset, -1, 01642 &lpStr, iStr, FALSE); 01643 } 01644 lpStr[iStr] = 0; 01645 pHandleW->dbch_size = iSize; 01646 lParam = (LPARAM)pHandleW; 01647 01648 break; 01649 } 01650 01651 shipit: 01652 retval = (DWORD)NtUserMessageCall( 01653 hwnd, 01654 msg, 01655 wParam, 01656 lParam, 01657 xParam, 01658 xpfnProc, 01659 bAnsi); 01660 01661 if (pPortW) UserLocalFree(pPortW); 01662 if (pInterfaceW) UserLocalFree(pInterfaceW); 01663 if (pHandleW) UserLocalFree(pHandleW); 01664 01665 ERRORTRAP(0); 01666 ENDCALL(DWORD); 01667 } 01668 01669 MESSAGECALL(fnIMECONTROL) 01670 { 01671 PVOID pvData = NULL; 01672 LPARAM lData = lParam; 01673 01674 BEGINCALL() 01675 01676 /* 01677 * The server always expects the characters to be unicode so 01678 * if this was generated from an ANSI routine convert it to Unicode 01679 */ 01680 if (bAnsi) { 01681 switch (wParam) { 01682 case IMC_GETCOMPOSITIONFONT: 01683 case IMC_GETSOFTKBDFONT: 01684 case IMC_SETCOMPOSITIONFONT: 01685 pvData = UserLocalAlloc(0, sizeof(LOGFONTW)); 01686 if (pvData == NULL) 01687 MSGERROR(); 01688 01689 if (wParam == IMC_SETCOMPOSITIONFONT) { 01690 // Later, we do A/W conversion based on thread hkl/CP. 01691 CopyLogFontAtoW((PLOGFONTW)pvData, (PLOGFONTA)lParam); 01692 } 01693 01694 lData = (LPARAM)pvData; 01695 break; 01696 01697 case IMC_SETSOFTKBDDATA: 01698 { 01699 PSOFTKBDDATA pSoftKbdData; 01700 PWORD pCodeA; 01701 PWSTR pCodeW; 01702 CHAR ch[3]; 01703 DWORD cbSize; 01704 UINT uCount, i; 01705 01706 uCount = ((PSOFTKBDDATA)lParam)->uCount; 01707 01708 cbSize = FIELD_OFFSET(SOFTKBDDATA, wCode[0]) 01709 + uCount * sizeof(WORD) * 256; 01710 01711 pvData = UserLocalAlloc(0, cbSize); 01712 if (pvData == NULL) 01713 MSGERROR(); 01714 01715 pSoftKbdData = (PSOFTKBDDATA)pvData; 01716 01717 pSoftKbdData->uCount = uCount; 01718 01719 ch[2] = (CHAR)'\0'; 01720 01721 pCodeA = &((PSOFTKBDDATA)lParam)->wCode[0][0]; 01722 pCodeW = &pSoftKbdData->wCode[0][0]; 01723 01724 i = uCount * 256; 01725 01726 while (i--) { 01727 if (HIBYTE(*pCodeA)) { 01728 ch[0] = (CHAR)HIBYTE(*pCodeA); 01729 ch[1] = (CHAR)LOBYTE(*pCodeA); 01730 } else { 01731 ch[0] = (CHAR)LOBYTE(*pCodeA); 01732 ch[1] = (CHAR)'\0'; 01733 } 01734 MBToWCSEx(THREAD_CODEPAGE(), (LPSTR)&ch, -1, &pCodeW, 1, FALSE); 01735 pCodeA++; pCodeW++; 01736 } 01737 01738 lData = (LPARAM)pvData; 01739 } 01740 break; 01741 01742 default: 01743 break; 01744 } 01745 } 01746 01747 retval = (DWORD)NtUserMessageCall( 01748 hwnd, 01749 msg, 01750 wParam, 01751 lData, 01752 xParam, 01753 xpfnProc, 01754 bAnsi); 01755 01756 if (bAnsi) { 01757 switch (wParam) { 01758 case IMC_GETCOMPOSITIONFONT: 01759 case IMC_GETSOFTKBDFONT: 01760 CopyLogFontWtoA((PLOGFONTA)lParam, (PLOGFONTW)pvData); 01761 break; 01762 01763 default: 01764 break; 01765 } 01766 } 01767 01768 if (pvData != NULL) 01769 UserLocalFree(pvData); 01770 01771 ERRORTRAP(0); 01772 ENDCALL(DWORD); 01773 } 01774 01775 #ifdef LATER 01776 DWORD CalcCharacterPositionAtoW( 01777 DWORD dwCharPosA, 01778 LPSTR lpszCharStr, 01779 DWORD dwCodePage) 01780 { 01781 DWORD dwCharPosW = 0; 01782 01783 while (dwCharPosA != 0) { 01784 if (IsDBCSLeadByteEx(dwCodePage, *lpszCharStr)) { 01785 if (dwCharPosA >= 2) { 01786 dwCharPosA -= 2; 01787 } 01788 else { 01789 dwCharPosA--; 01790 } 01791 lpszCharStr += 2; 01792 } 01793 else { 01794 dwCharPosA--; 01795 lpszCharStr++; 01796 } 01797 dwCharPosW++; 01798 } 01799 01800 return dwCharPosW; 01801 } 01802 01803 int UnicodeToMultiByteSize(DWORD dwCodePage, LPCWSTR pwstr) 01804 { 01805 char dummy[2], *lpszDummy = dummy; 01806 return WCSToMBEx((WORD)dwCodePage, pwstr, 1, &lpszDummy, sizeof(WCHAR), FALSE); 01807 } 01808 01809 DWORD CalcCharacterPositionWtoA( 01810 DWORD dwCharPosW, 01811 LPWSTR lpwszCharStr, 01812 DWORD dwCodePage) 01813 { 01814 DWORD dwCharPosA = 0; 01815 ULONG MultiByteSize; 01816 01817 while (dwCharPosW != 0) { 01818 MultiByteSize = UnicodeToMultiByteSize(dwCodePage, lpwszCharStr); 01819 if (MultiByteSize == 2) { 01820 dwCharPosA += 2; 01821 } 01822 else { 01823 dwCharPosA++; 01824 } 01825 dwCharPosW--; 01826 lpwszCharStr++; 01827 } 01828 01829 return dwCharPosA; 01830 } 01831 01832 DWORD WINAPI ImmGetReconvertTotalSize(DWORD dwSize, REQ_CALLER eCaller, BOOL bAnsiTarget) 01833 { 01834 if (dwSize < sizeof(RECONVERTSTRING)) { 01835 return 0; 01836 } 01837 if (bAnsiTarget) { 01838 dwSize -= sizeof(RECONVERTSTRING); 01839 if (eCaller == FROM_IME) { 01840 dwSize /= 2; 01841 } else { 01842 dwSize *= 2; 01843 } 01844 dwSize += sizeof(RECONVERTSTRING); 01845 } 01846 return dwSize; 01847 } 01848 01849 DWORD WINAPI ImmReconversionWorker( 01850 LPRECONVERTSTRING lpRecTo, 01851 LPRECONVERTSTRING lpRecFrom, 01852 BOOL bToAnsi, 01853 DWORD dwCodePage) 01854 { 01855 INT i; 01856 DWORD dwSize = 0; 01857 01858 UserAssert(lpRecTo); 01859 UserAssert(lpRecFrom); 01860 01861 if (lpRecFrom->dwVersion != 0 || lpRecTo->dwVersion != 0) { 01862 RIPMSG0(RIP_WARNING, "ImmReconversionWorker: dwVersion in lpRecTo or lpRecFrom is incorrect."); 01863 return 0; 01864 } 01865 // Note: 01866 // In any IME related structures, use the following principal. 01867 // 1) xxxStrOffset is an actual offset, i.e. byte count. 01868 // 2) xxxStrLen is a number of characters, i.e. TCHAR count. 01869 // 01870 // CalcCharacterPositionXtoY() takes TCHAR count so that we 01871 // need to adjust xxxStrOffset if it's being converted. But you 01872 // should be careful, because the actual position of the string 01873 // is always at something like (LPBYTE)lpStruc + lpStruc->dwStrOffset. 01874 // 01875 if (bToAnsi) { 01876 // Convert W to A 01877 lpRecTo->dwStrOffset = sizeof *lpRecTo; 01878 i = WideCharToMultiByte(dwCodePage, 01879 (DWORD)0, 01880 (LPWSTR)((LPSTR)lpRecFrom + lpRecFrom->dwStrOffset), // src 01881 (INT)lpRecFrom->dwStrLen, 01882 (LPSTR)lpRecTo + lpRecTo->dwStrOffset, // dest 01883 (INT)lpRecFrom->dwStrLen * DBCS_CHARSIZE, 01884 (LPSTR)NULL, 01885 (LPBOOL)NULL); 01886 lpRecTo->dwCompStrOffset = 01887 CalcCharacterPositionWtoA(lpRecFrom->dwCompStrOffset / sizeof(WCHAR), 01888 (LPWSTR)((LPBYTE)lpRecFrom + lpRecFrom->dwStrOffset), 01889 dwCodePage) 01890 * sizeof(CHAR); 01891 01892 lpRecTo->dwCompStrLen = 01893 (CalcCharacterPositionWtoA(lpRecFrom->dwCompStrOffset / sizeof(WCHAR) + 01894 lpRecFrom->dwCompStrLen, 01895 (LPWSTR)((LPBYTE)lpRecFrom + lpRecFrom->dwStrOffset), 01896 dwCodePage) 01897 * sizeof(CHAR)) 01898 - lpRecTo->dwCompStrOffset; 01899 01900 lpRecTo->dwTargetStrOffset = 01901 CalcCharacterPositionWtoA(lpRecFrom->dwTargetStrOffset / sizeof(WCHAR), 01902 (LPWSTR)((LPBYTE)lpRecFrom + 01903 lpRecFrom->dwStrOffset), 01904 dwCodePage) 01905 * sizeof(CHAR); 01906 01907 lpRecTo->dwTargetStrLen = 01908 (CalcCharacterPositionWtoA(lpRecFrom->dwTargetStrOffset / sizeof(WCHAR) + 01909 lpRecFrom->dwTargetStrLen, 01910 (LPWSTR)((LPBYTE)lpRecFrom + lpRecFrom->dwStrOffset), 01911 dwCodePage) 01912 * sizeof(CHAR)) 01913 - lpRecTo->dwTargetStrOffset; 01914 01915 ((LPSTR)lpRecTo)[lpRecTo->dwStrOffset + i] = '\0'; 01916 lpRecTo->dwStrLen = i * sizeof(CHAR); 01917 01918 dwSize = sizeof(RECONVERTSTRING) + ((i + 1) * sizeof(CHAR)); 01919 01920 } else { 01921 01922 // AtoW 01923 lpRecTo->dwStrOffset = sizeof *lpRecTo; 01924 i = MultiByteToWideChar(dwCodePage, 01925 (DWORD)MB_PRECOMPOSED, 01926 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset, // src 01927 (INT)lpRecFrom->dwStrLen, 01928 (LPWSTR)((LPSTR)lpRecTo + lpRecTo->dwStrOffset), // dest 01929 (INT)lpRecFrom->dwStrLen); 01930 01931 lpRecTo->dwCompStrOffset = 01932 CalcCharacterPositionAtoW(lpRecFrom->dwCompStrOffset, 01933 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset, 01934 dwCodePage) * sizeof(WCHAR); 01935 01936 lpRecTo->dwCompStrLen = 01937 ((CalcCharacterPositionAtoW(lpRecFrom->dwCompStrOffset + 01938 lpRecFrom->dwCompStrLen, 01939 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset, 01940 dwCodePage) * sizeof(WCHAR)) 01941 - lpRecTo->dwCompStrOffset) / sizeof(WCHAR); 01942 01943 lpRecTo->dwTargetStrOffset = 01944 CalcCharacterPositionAtoW(lpRecFrom->dwTargetStrOffset, 01945 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset, 01946 dwCodePage) * sizeof(WCHAR); 01947 01948 lpRecTo->dwTargetStrLen = 01949 ((CalcCharacterPositionAtoW(lpRecFrom->dwTargetStrOffset + 01950 lpRecFrom->dwTargetStrLen, 01951 (LPSTR)lpRecFrom + lpRecFrom->dwStrOffset, 01952 dwCodePage) * sizeof(WCHAR)) 01953 - lpRecTo->dwTargetStrOffset) / sizeof(WCHAR); 01954 01955 lpRecTo->dwStrLen = i; // Length is TCHAR count. 01956 if (lpRecTo->dwSize >= (DWORD)(lpRecTo->dwStrOffset + (i + 1)* sizeof(WCHAR))) { 01957 LPWSTR lpW = (LPWSTR)((LPSTR)lpRecTo + lpRecTo->dwStrOffset); 01958 lpW[i] = L'\0'; 01959 } 01960 dwSize = sizeof(RECONVERTSTRING) + ((i + 1) * sizeof(WCHAR)); 01961 } 01962 return dwSize; 01963 } 01964 01965 #define GETCOMPOSITIONSTRING(hImc, index, buf, buflen) \ 01966 (bAnsi ? fpImmGetCompositionStringA : fpImmGetCompositionStringW)((hImc), (index), (buf), (buflen)) 01967 01968 MESSAGECALL(fnIMEREQUEST) 01969 { 01970 PVOID pvData = NULL; 01971 LPARAM lData = lParam; 01972 01973 BEGINCALL() 01974 01975 if (!IS_IME_ENABLED()) { 01976 // If IME is not enabled, save time. 01977 MSGERROR(); 01978 } 01979 01980 /* 01981 * The server always expects the characters to be unicode so 01982 * if this was generated from an ANSI routine convert it to Unicode 01983 */ 01984 if (wParam == IMR_QUERYCHARPOSITION) { 01985 // 01986 // Store the UNICODE character count in PrivateIMECHARPOSITION. 01987 // 01988 // No need to save the original dwCharPos, since dwCharPositionA/W are not 01989 // overwritten in the kernel. 01990 // 01991 if (bAnsi) { 01992 ((LPIMECHARPOSITION)lParam)->dwCharPos = ((LPPrivateIMECHARPOSITION)lParam)->dwCharPositionW; 01993 } 01994 } 01995 else if (bAnsi) { 01996 switch (wParam) { 01997 case IMR_COMPOSITIONFONT: 01998 pvData = UserLocalAlloc(0, sizeof(LOGFONTW)); 01999 if (pvData == NULL) 02000 MSGERROR(); 02001 lData = (LPARAM)pvData; 02002 break; 02003 02004 case IMR_CONFIRMRECONVERTSTRING: 02005 case IMR_RECONVERTSTRING: 02006 case IMR_DOCUMENTFEED: 02007 if ((LPVOID)lParam != NULL) { 02008 // IME wants not only the buffer size but the real reconversion information 02009 DWORD dwSize = ImmGetReconvertTotalSize(((LPRECONVERTSTRING)lParam)->dwSize, FROM_IME, FALSE); 02010 LPRECONVERTSTRING lpReconv; 02011 02012 pvData = UserLocalAlloc(0, dwSize + sizeof(WCHAR)); 02013 if (pvData == NULL) { 02014 RIPMSG0(RIP_WARNING, "fnIMEREQUEST: failed to allocate a buffer for reconversion."); 02015 MSGERROR(); 02016 } 02017 lpReconv = (LPRECONVERTSTRING)pvData; 02018 // setup the information in the allocated structure 02019 lpReconv->dwVersion = 0; 02020 lpReconv->dwSize = dwSize; 02021 02022 // 02023 // if it's confirmation message, we need to translate the contents 02024 // 02025 if (wParam == IMR_CONFIRMRECONVERTSTRING) { 02026 ImmReconversionWorker(lpReconv, (LPRECONVERTSTRING)lParam, FALSE, CP_ACP); 02027 } 02028 } 02029 break; 02030 02031 default: 02032 break; 02033 } 02034 } 02035 02036 retval = (DWORD)NtUserMessageCall( 02037 hwnd, 02038 msg, 02039 wParam, 02040 lData, 02041 xParam, 02042 xpfnProc, 02043 bAnsi); 02044 02045 if (bAnsi) { 02046 switch (wParam) { 02047 case IMR_COMPOSITIONFONT: 02048 if (retval) { 02049 CopyLogFontWtoA((PLOGFONTA)lParam, (PLOGFONTW)pvData); 02050 } 02051 break; 02052 02053 case IMR_QUERYCHARPOSITION: 02054 ((LPIMECHARPOSITION)lParam)->dwCharPos = ((LPPrivateIMECHARPOSITION)lParam)->dwCharPositionA; 02055 break; 02056 02057 case IMR_RECONVERTSTRING: 02058 case IMR_DOCUMENTFEED: 02059 // 02060 // Note: by definition, we don't need back-conversion for IMR_CONFIRMRECONVERTSTRING 02061 // 02062 if (retval) { 02063 // IME wants the buffer size 02064 retval = ImmGetReconvertTotalSize((DWORD)retval, FROM_APP, FALSE); 02065 if (retval < sizeof(RECONVERTSTRING)) { 02066 RIPMSG2(RIP_WARNING, "WM_IME_REQUEST(%x): return value from application %d is invalid.", wParam, retval); 02067 retval = 0; 02068 } else if (lParam) { 02069 // We need to perform the A/W conversion of the contents 02070 if (!ImmReconversionWorker((LPRECONVERTSTRING)lParam, (LPRECONVERTSTRING)pvData, TRUE, CP_ACP)) { 02071 MSGERROR(); 02072 } 02073 } 02074 } 02075 break; 02076 } 02077 } 02078 02079 02080 ERRORTRAP(0); 02081 02082 if (pvData != NULL) 02083 UserLocalFree(pvData); 02084 02085 ENDCALL(DWORD); 02086 } 02087 #endif 02088 02089 MESSAGECALL(fnEMGETSEL) 02090 { 02091 PWND pwnd = ValidateHwnd(hwnd); 02092 02093 if (pwnd == NULL) 02094 return 0; 02095 02096 BEGINCALL() 02097 02098 retval = (DWORD)NtUserMessageCall( 02099 hwnd, 02100 msg, 02101 wParam, 02102 lParam, 02103 xParam, 02104 xpfnProc, 02105 bAnsi); 02106 02107 // 02108 // temp for our beta... 02109 // 02110 // !!! THIS CODE SHOULD BE IN KERNEL MODE !!! 02111 // 02112 // to reduce user <-> kernel mode transition... 02113 // 02114 if (bAnsi != ((TestWF(pwnd, WFANSIPROC)) ? TRUE : FALSE)) { 02115 ULONG cchTextLength; 02116 LONG lOriginalLengthW; 02117 LONG lOriginalLengthL; 02118 LONG wParamLocal; 02119 LONG lParamLocal; 02120 02121 if (wParam) { 02122 lOriginalLengthW = *(LONG *)wParam; 02123 } else { 02124 lOriginalLengthW = (LONG)(LOWORD(retval)); 02125 } 02126 02127 if (lParam) { 02128 lOriginalLengthL = *(LONG *)lParam; 02129 } else { 02130 lOriginalLengthL = (LONG)(HIWORD(retval)); 02131 } 02132 02133 cchTextLength = (DWORD)NtUserMessageCall( 02134 hwnd, 02135 WM_GETTEXTLENGTH, 02136 (WPARAM)0, 02137 (LPARAM)0, 02138 xParam, 02139 xpfnProc, 02140 bAnsi); 02141 02142 if (cchTextLength) { 02143 PVOID pvString; 02144 ULONG cbTextLength; 02145 02146 cchTextLength++; 02147 if (!bAnsi) { 02148 cbTextLength = cchTextLength * sizeof(WCHAR); 02149 } else { 02150 cbTextLength = cchTextLength; 02151 } 02152 02153 pvString = UserLocalAlloc(0,cbTextLength); 02154 02155 if (pvString) { 02156 02157 retval = (DWORD)NtUserMessageCall( 02158 hwnd, 02159 WM_GETTEXT, 02160 cchTextLength, 02161 (LPARAM)pvString, 02162 xParam, 02163 xpfnProc, 02164 bAnsi); 02165 02166 if (retval) { 02167 if (bAnsi) { 02168 /* 02169 * ansiString/unicodeLenght -> ansiLength 02170 */ 02171 CalcAnsiStringLengthA(pvString, lOriginalLengthW, &wParamLocal) 02172 CalcAnsiStringLengthA(pvString, lOriginalLengthL, &lParamLocal); 02173 } else { 02174 /* 02175 * unicodeString/ansiLenght -> unicodeLength 02176 */ 02177 CalcUnicodeStringLengthW(pvString, lOriginalLengthW, &wParamLocal); 02178 CalcUnicodeStringLengthW(pvString, lOriginalLengthL, &lParamLocal); 02179 } 02180 02181 retval = (DWORD)(((lParamLocal) << 16) | ((wParamLocal) & 0x0000FFFF)); 02182 02183 if (wParam) { 02184 *(LONG *)wParam = wParamLocal; 02185 } 02186 02187 if (lParam) { 02188 *(LONG *)lParam = lParamLocal; 02189 } 02190 02191 } else { 02192 UserLocalFree(pvString); 02193 MSGERROR(); 02194 } 02195 02196 UserLocalFree(pvString); 02197 02198 } else 02199 MSGERROR(); 02200 } else 02201 MSGERROR(); 02202 } 02203 02204 ERRORTRAP(0); 02205 ENDCALL(DWORD); 02206 } 02207 02208 MESSAGECALL(fnEMSETSEL) 02209 { 02210 PWND pwnd = ValidateHwnd(hwnd); 02211 02212 if (pwnd == NULL) 02213 return 0; 02214 02215 BEGINCALL() 02216 02217 // 02218 // temp for our beta... 02219 // 02220 // !!! THIS CODE SHOULD BE IN KERNEL MODE !!! 02221 // 02222 // to reduce user <-> kernel mode transition... 02223 // 02224 if (bAnsi != ((TestWF(pwnd, WFANSIPROC)) ? TRUE : FALSE)) { 02225 if (((LONG)wParam <= 0) && ((LONG)lParam <=0)) { 02226 // 02227 // if (wParam == 0 or wParam == -1) 02228 // and 02229 // (lParam == 0 or lParam == -1) 02230 // 02231 // In this case, we don't need to convert the value... 02232 // 02233 } else { 02234 ULONG cchTextLength; 02235 LONG lOriginalLengthW = (LONG)wParam; 02236 LONG lOriginalLengthL = (LONG)lParam; 02237 02238 cchTextLength = (DWORD)NtUserMessageCall( 02239 hwnd, 02240 WM_GETTEXTLENGTH, 02241 (WPARAM)0, 02242 (LPARAM)0, 02243 xParam, 02244 xpfnProc, 02245 bAnsi); 02246 02247 if (cchTextLength) { 02248 PVOID pvString; 02249 ULONG cbTextLength; 02250 02251 cchTextLength++; 02252 if (!bAnsi) { 02253 cbTextLength = cchTextLength * sizeof(WCHAR); 02254 } else { 02255 cbTextLength = cchTextLength; 02256 } 02257 02258 pvString = UserLocalAlloc(0,cbTextLength); 02259 02260 if (pvString) { 02261 02262 retval = (DWORD)NtUserMessageCall( 02263 hwnd, 02264 WM_GETTEXT, 02265 cchTextLength, 02266 (LPARAM)pvString, 02267 xParam, 02268 xpfnProc, 02269 bAnsi); 02270 02271 if (retval) { 02272 if ((LONG)retval < lOriginalLengthW) { 02273 lOriginalLengthW = (LONG)retval; 02274 } 02275 if ((LONG)retval < lOriginalLengthL) { 02276 lOriginalLengthL = (LONG)retval; 02277 } 02278 if (bAnsi) { 02279 if (lOriginalLengthW > 0) { 02280 CalcUnicodeStringLengthA(pvString, lOriginalLengthW, &wParam); 02281 } 02282 if(lOriginalLengthL > 0) { 02283 CalcUnicodeStringLengthA(pvString, lOriginalLengthL, &lParam); 02284 } 02285 } else { 02286 if (lOriginalLengthW > 0) { 02287 CalcAnsiStringLengthW(pvString, lOriginalLengthW, &wParam); 02288 } 02289 if(lOriginalLengthL > 0) { 02290 CalcAnsiStringLengthW(pvString, lOriginalLengthL, &lParam); 02291 } 02292 } 02293 } else { 02294 UserLocalFree(pvString); 02295 MSGERROR(); 02296 } 02297 02298 UserLocalFree(pvString); 02299 02300 } else 02301 MSGERROR(); 02302 } else 02303 MSGERROR(); 02304 } 02305 } 02306 02307 retval = (DWORD)NtUserMessageCall( 02308 hwnd, 02309 msg, 02310 wParam, 02311 lParam, 02312 xParam, 02313 xpfnProc, 02314 bAnsi); 02315 02316 ERRORTRAP(0); 02317 ENDCALL(DWORD); 02318 } 02319 02320 MESSAGECALL(fnCBGETEDITSEL) 02321 { 02322 PWND pwnd = ValidateHwnd(hwnd); 02323 02324 if (pwnd == NULL) 02325 return 0; 02326 02327 BEGINCALL() 02328 02329 retval = (DWORD)NtUserMessageCall( 02330 hwnd, 02331 msg, 02332 wParam, 02333 lParam, 02334 xParam, 02335 xpfnProc, 02336 bAnsi); 02337 02338 // 02339 // temp for our beta... 02340 // 02341 // !!! THIS CODE SHOULD BE IN KERNEL MODE !!! 02342 // 02343 // to reduce user <-> kernel mode transition... 02344 // 02345 if (bAnsi != ((TestWF(pwnd, WFANSIPROC)) ? TRUE : FALSE)) { 02346 ULONG cchTextLength; 02347 LONG lOriginalLengthW = *(LONG *)wParam; 02348 LONG lOriginalLengthL = *(LONG *)lParam; 02349 LONG wParamLocal; 02350 LONG lParamLocal; 02351 02352 if (wParam) { 02353 lOriginalLengthW = *(LONG *)wParam; 02354 } else { 02355 lOriginalLengthW = (LONG)(LOWORD(retval)); 02356 } 02357 02358 if (lParam) { 02359 lOriginalLengthL = *(LONG *)lParam; 02360 } else { 02361 lOriginalLengthL = (LONG)(HIWORD(retval)); 02362 } 02363 02364 cchTextLength = (DWORD)NtUserMessageCall( 02365 hwnd, 02366 WM_GETTEXTLENGTH, 02367 (WPARAM)0, 02368 (LPARAM)0, 02369 xParam, 02370 xpfnProc, 02371 bAnsi); 02372 02373 if (cchTextLength) { 02374 PVOID pvString; 02375 ULONG cbTextLength; 02376 02377 cchTextLength++; 02378 if (!bAnsi) { 02379 cbTextLength = cchTextLength * sizeof(WCHAR); 02380 } else { 02381 cbTextLength = cchTextLength; 02382 } 02383 02384 pvString = UserLocalAlloc(0,cbTextLength); 02385 02386 if (pvString) { 02387 02388 retval = (DWORD)NtUserMessageCall( 02389 hwnd, 02390 WM_GETTEXT, 02391 cchTextLength, 02392 (LPARAM)pvString, 02393 xParam, 02394 xpfnProc, 02395 bAnsi); 02396 02397 if (retval) { 02398 if (bAnsi) { 02399 /* 02400 * ansiString/unicodeLenght -> ansiLength 02401 */ 02402 CalcAnsiStringLengthA(pvString, lOriginalLengthW, &wParamLocal); 02403 CalcAnsiStringLengthA(pvString, lOriginalLengthL, &lParamLocal); 02404 } else { 02405 /* 02406 * unicodeString/ansiLenght -> unicodeLength 02407 */ 02408 CalcUnicodeStringLengthW(pvString, lOriginalLengthW, &wParamLocal); 02409 CalcUnicodeStringLengthW(pvString, lOriginalLengthL, &lParamLocal); 02410 } 02411 02412 retval = (DWORD)(((lParamLocal) << 16) | ((wParamLocal) & 0x0000FFFF)); 02413 02414 if (wParam) { 02415 *(LONG *)wParam = wParamLocal; 02416 } 02417 02418 if (lParam) { 02419 *(LONG *)lParam = lParamLocal; 02420 } 02421 02422 } else { 02423 UserLocalFree(pvString); 02424 MSGERROR(); 02425 } 02426 02427 UserLocalFree(pvString); 02428 02429 } else 02430 MSGERROR(); 02431 } else 02432 MSGERROR(); 02433 } 02434 02435 ERRORTRAP(0); 02436 ENDCALL(DWORD); 02437 } 02438 02439 LONG BroadcastSystemMessageWorker( 02440 DWORD dwFlags, 02441 LPDWORD lpdwRecipients, 02442 UINT message, 02443 WPARAM wParam, 02444 LPARAM lParam, 02445 BOOL fAnsi) 02446 { 02447 DWORD dwRecipients; 02448 02449 /* 02450 * Prevent apps from setting hi 16 bits so we can use them internally. 02451 */ 02452 if (message & RESERVED_MSG_BITS) { 02453 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid message (%x) for BroadcastSystemMessage\n", message); 02454 return(0); 02455 } 02456 02457 if (dwFlags & ~BSF_VALID) { 02458 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid dwFlags (%x) for BroadcastSystemMessage\n", dwFlags); 02459 return(0); 02460 } 02461 02462 // 02463 // Check if the message number is in the private message range. 02464 // If so, do not send it to Win4.0 windows. 02465 // (This is required because apps like SimCity broadcast a message 02466 // that has the value 0x500 and that confuses MsgSrvr's 02467 // MSGSRVR_NOTIFY handler. 02468 // 02469 if ((message >= WM_USER) && (message < 0xC000)) 02470 { 02471 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid message (%x) for BroadcastSystemMessage\n", message); 02472 return(0L); 02473 } 02474 02475 if (dwFlags & BSF_FORCEIFHUNG) 02476 dwFlags |= BSF_NOHANG; 02477 02478 // 02479 // If BSF_QUERY or message has a pointer, it can not be posted. 02480 // 02481 if (dwFlags & BSF_QUERY) 02482 { 02483 #if DBG 02484 if (dwFlags & BSF_ASYNC) 02485 { 02486 RIPMSG0(RIP_ERROR, "BroadcastSystemMessage: Can't post queries\n"); 02487 } 02488 #endif 02489 02490 dwFlags &= ~BSF_ASYNC; // Strip the BSF_ASYNC flags. 02491 } 02492 02493 if (dwFlags & BSF_ASYNC) { 02494 if (TESTSYNCONLYMESSAGE(message, wParam)) { 02495 RIPERR0(ERROR_MESSAGE_SYNC_ONLY, RIP_WARNING, "BroadcastSystemMessage: Can't post messages with pointers\n"); 02496 dwFlags &= ~BSF_ASYNC; // Strip the BSF_ASYNC flags. 02497 } 02498 } 02499 02500 02501 // Let us find out who the intended recipients are. 02502 if (lpdwRecipients != NULL) 02503 dwRecipients = *lpdwRecipients; 02504 else 02505 dwRecipients = BSM_ALLCOMPONENTS; 02506 02507 // if they want all components, add the corresponding bits 02508 if ((dwRecipients & BSM_COMPONENTS) == BSM_ALLCOMPONENTS) 02509 dwRecipients |= (BSM_VXDS | BSM_NETDRIVER | BSM_INSTALLABLEDRIVERS | 02510 BSM_APPLICATIONS); 02511 02512 02513 if (dwRecipients & ~BSM_VALID) { 02514 RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid dwRecipients (%x) for BroadcastSystemMessage\n", dwRecipients); 02515 return(0); 02516 } 02517 02518 // 02519 // Check if this is a WM_USERCHANGED message; If so, we want to reload 02520 // the per-user settings before anyone else sees this message. 02521 // 02522 // LATER -- FritzS 02523 // if (uiMessage == WM_USERCHANGED) 02524 // ReloadPerUserSettings(); 02525 02526 02527 // Does this need to be sent to all apps? 02528 if (dwRecipients & BSM_APPLICATIONS) 02529 { 02530 BROADCASTSYSTEMMSGPARAMS bsmParams; 02531 02532 bsmParams.dwFlags = dwFlags; 02533 bsmParams.dwRecipients = dwRecipients; 02534 02535 return (LONG)CsSendMessage(GetDesktopWindow(), message, wParam, lParam, 02536 (ULONG_PTR)&bsmParams, FNID_SENDMESSAGEBSM, fAnsi); 02537 } 02538 02539 return -1; 02540 } 02541 02542 HDEVNOTIFY 02543 RegisterDeviceNotificationWorker( 02544 IN HANDLE hRecipient, 02545 IN LPVOID NotificationFilter, 02546 IN DWORD Flags, 02547 IN BOOL IsAnsi 02548 ) 02549 { 02550 HINSTANCE hLib = NULL; 02551 FARPROC fpRegisterNotification = NULL; 02552 PVOID Context = NULL; 02553 HDEVNOTIFY notifyHandle = NULL; 02554 CONFIGRET Status = CR_SUCCESS; 02555 02556 extern 02557 CONFIGRET 02558 CMP_RegisterNotification(IN HANDLE hRecipient, 02559 IN LPBYTE NotificationFilter, 02560 IN DWORD Flags, 02561 OUT PVOID *Context 02562 ); 02563 02564 UNREFERENCED_PARAMETER(IsAnsi); 02565 02566 try { 02567 // 02568 // load the config manager client dll and retrieve entry pts 02569 // 02570 hLib = LoadLibrary(TEXT("SETUPAPI.DLL")); 02571 if (hLib == NULL) { 02572 goto Clean0; // use last error set by LoadLibrary 02573 } 02574 02575 fpRegisterNotification = GetProcAddress(hLib, "CMP_RegisterNotification"); 02576 if (fpRegisterNotification == NULL) { 02577 goto Clean0; // use last error set by GetProcAddress 02578 } 02579 02580 Status = (CONFIGRET)(fpRegisterNotification)(hRecipient, 02581 NotificationFilter, 02582 Flags, 02583 &Context); 02584 02585 Clean0: 02586 ; 02587 02588 } except(W32ExceptionHandler(FALSE, RIP_WARNING)) { 02589 } 02590 02591 if (hLib != NULL) { 02592 FreeLibrary(hLib); 02593 } 02594 02595 if (Status != CR_SUCCESS) { 02596 02597 // 02598 //Something went wrong, map the CR errors to a 02599 //W32 style error code 02600 // 02601 switch (Status) { 02602 case CR_INVALID_POINTER: 02603 SetLastError (ERROR_INVALID_PARAMETER); 02604 break; 02605 case CR_INVALID_DATA: 02606 SetLastError (ERROR_INVALID_DATA); 02607 break; 02608 case CR_OUT_OF_MEMORY: 02609 SetLastError (ERROR_NOT_ENOUGH_MEMORY); 02610 break; 02611 case CR_FAILURE: 02612 default: 02613 SetLastError (ERROR_SERVICE_SPECIFIC_ERROR); 02614 break; 02615 02616 } 02617 } 02618 02619 if ((Context != NULL) && ((ULONG_PTR)Context != -1)) { 02620 notifyHandle = (HDEVNOTIFY)Context; 02621 } 02622 02623 return notifyHandle; 02624 } 02625 02626 02627 BOOL 02628 UnregisterDeviceNotification( 02629 IN HDEVNOTIFY Handle 02630 ) 02631 { 02632 BOOL status = TRUE; 02633 HINSTANCE hLib = NULL; 02634 FARPROC fpUnregisterNotification = NULL; 02635 CONFIGRET crStatus = CR_SUCCESS; 02636 02637 extern 02638 CONFIGRET 02639 CMP_UnregisterNotification(IN ULONG Context); 02640 02641 try { 02642 // 02643 // load the config manager client dll and retrieve entry pts 02644 // 02645 hLib = LoadLibrary(TEXT("SETUPAPI.DLL")); 02646 if (hLib == NULL) { 02647 status = FALSE; 02648 goto Clean0; // use last error set by LoadLibrary 02649 } 02650 02651 fpUnregisterNotification = GetProcAddress(hLib, "CMP_UnregisterNotification"); 02652 if (fpUnregisterNotification == NULL) { 02653 status = FALSE; 02654 goto Clean0; // use last error set by GetProcAddress 02655 } 02656 02657 crStatus = (CONFIGRET)(fpUnregisterNotification)((ULONG_PTR)Handle); 02658 02659 if (crStatus != CR_SUCCESS) { 02660 status = FALSE; 02661 // 02662 //Something went wrong, map the CR errors to a 02663 //W32 style error code 02664 // 02665 switch (crStatus) { 02666 case CR_INVALID_POINTER: 02667 SetLastError (ERROR_INVALID_PARAMETER); 02668 break; 02669 case CR_INVALID_DATA: 02670 SetLastError (ERROR_INVALID_DATA); 02671 break; 02672 case CR_FAILURE: 02673 default: 02674 SetLastError (ERROR_SERVICE_SPECIFIC_ERROR); 02675 break; 02676 } 02677 } 02678 02679 Clean0: 02680 ; 02681 02682 } except(W32ExceptionHandler(FALSE, RIP_WARNING)) { 02683 status = FALSE; 02684 } 02685 02686 if (hLib != NULL) { 02687 FreeLibrary(hLib); 02688 } 02689 02690 return status; 02691 }

Generated on Sat May 15 19:41:01 2004 for test by doxygen 1.3.7