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

getset.c File Reference

#include "precomp.h"

Go to the source code of this file.

Functions

BOOL DefSetText (PWND pwnd, PLARGE_STRING cczpstr)
BOOL FCallerOk (PWND pwnd)
WORD _SetWindowWord (PWND pwnd, int index, WORD value)
ULONG_PTR xxxSetWindowLongPtr (PWND pwnd, int index, ULONG_PTR dwData, BOOL bAnsi)
void xxxHandleOwnerSwitch (PWND pwnd, PWND pwndNewParent, PWND pwndOldParent)
ULONG_PTR xxxSetWindowData (PWND pwnd, int index, ULONG_PTR dwData, BOOL bAnsi)
PCALLPROCDATA FindPCPD (PCALLPROCDATA pCPD, ULONG_PTR dwClientPrevious, WORD wCPDType)
ULONG_PTR GetCPD (PVOID pWndOrCls, DWORD CPDOption, ULONG_PTR dwProc32)
ULONG_PTR MapClientToServerPfn (ULONG_PTR dw)
ULONG DBGGetWindowLong (PWND pwnd, int index)
ULONG_PTR DBGGetWindowLongPtr (PWND pwnd, int index)


Function Documentation

WORD _SetWindowWord PWND  pwnd,
int  index,
WORD  value
 

Definition at line 133 of file ntuser/kernel/getset.c.

References tagBUTN::buttonState, BYTE, CBFNID, tagWND::cbwndExtra, DWORD, tagWND::dwUserData, FALSE, FCallerOk(), FNID_BUTTON, FNID_DIALOG, FNID_MDICLIENT, GETFNID, ProbeAndReadUlong, TestWF, UINT, and WFDIALOGWINDOW.

Referenced by NtUserSetWindowWord().

00137 { 00138 WORD wOld; 00139 00140 /* 00141 * Don't allow setting of words belonging to a system thread if the caller 00142 * is not a system thread. Same goes for winlogon. 00143 */ 00144 if (!FCallerOk(pwnd)) { 00145 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00146 return 0; 00147 } 00148 00149 /* 00150 * Applications can not set a WORD into a dialog Proc or any of the 00151 * non-public reserved bytes in DLGWINDOWEXTRA (usersrv stores pointers 00152 * theres) 00153 */ 00154 if (TestWF(pwnd, WFDIALOGWINDOW)) { 00155 if (((index >= DWLP_DLGPROC) && (index < DWLP_MSGRESULT)) || 00156 ((index > DWLP_USER+sizeof(LONG_PTR)-sizeof(WORD)) && (index < DLGWINDOWEXTRA))) { 00157 RIPERR3(ERROR_INVALID_INDEX, RIP_WARNING, 00158 "SetWindowWord: Trying to set WORD of a windowproc pwnd=(%#p) index=(%ld) fnid (%lX)", 00159 pwnd, index, (DWORD)pwnd->fnid); 00160 return 0; 00161 } else { 00162 00163 /* 00164 * If this is really a dialog and not some other server class 00165 * where usersrv has stored some data (Windows Compuserve - 00166 * wincim - does this) then store the data now that we have 00167 * verified the index limits. 00168 */ 00169 if (GETFNID(pwnd) == FNID_DIALOG) 00170 goto DoSetWord; 00171 } 00172 } 00173 00174 if (index == GWLP_USERDATA) { 00175 wOld = (WORD)pwnd->dwUserData; 00176 pwnd->dwUserData = MAKELONG(value, HIWORD(pwnd->dwUserData)); 00177 return wOld; 00178 } 00179 00180 // fix for RedShift, they call SetWindowWord 00181 // tn play with the low word of the style dword 00182 if (index == GWL_STYLE) { 00183 wOld = (WORD)pwnd->style; 00184 pwnd->style = MAKELONG(value, HIWORD(pwnd->style)); 00185 return wOld; 00186 } 00187 00188 if (GETFNID(pwnd) != 0) { 00189 if (index >= 0 && 00190 (index < (int)(CBFNID(pwnd->fnid)-sizeof(WND)))) { 00191 switch (GETFNID(pwnd)) { 00192 case FNID_MDICLIENT: 00193 if (index == 0) 00194 break; 00195 goto DoDefault; 00196 00197 case FNID_BUTTON: 00198 /* 00199 * CorelDraw, Direct Access 1.0 and WordPerfect 6.0 do a 00200 * get/set on the first button window word. Allow this 00201 * for compatibility. 00202 */ 00203 if (index == 0) { 00204 /* 00205 * Since we now use a lookaside buffer for the control's 00206 * private data, we need to indirect into this structure. 00207 */ 00208 PBUTN pbutn = ((PBUTNWND)pwnd)->pbutn; 00209 if (!pbutn || (LONG_PTR)pbutn == (LONG_PTR)-1) { 00210 return 0; 00211 } else { 00212 try { 00213 wOld = (WORD)ProbeAndReadUlong(&pbutn->buttonState); 00214 pbutn->buttonState = value; 00215 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00216 wOld = 0; 00217 } 00218 return wOld; 00219 } 00220 } 00221 goto DoDefault; 00222 00223 default: 00224 DoDefault: 00225 RIPERR3(ERROR_INVALID_INDEX, 00226 RIP_WARNING, 00227 "SetWindowWord: Trying to set private server data pwnd=(%#p) index=(%ld) fnid (%lX)", 00228 pwnd, index, (DWORD)pwnd->fnid); 00229 return 0; 00230 break; 00231 } 00232 } 00233 } 00234 00235 DoSetWord: 00236 if ((index < 0) || ((UINT)index + sizeof(WORD) > (UINT)pwnd->cbwndExtra)) { 00237 RIPERR0(ERROR_INVALID_INDEX, RIP_WARNING,"SetWindowWord Fails because of invalid index"); 00238 return 0; 00239 } else { 00240 WORD UNALIGNED *pw; 00241 00242 pw = (WORD UNALIGNED *)((BYTE *)(pwnd + 1) + index); 00243 wOld = *pw; 00244 *pw = value; 00245 return (WORD)wOld; 00246 } 00247 }

ULONG DBGGetWindowLong PWND  pwnd,
int  index
 

Definition at line 999 of file ntuser/kernel/getset.c.

References __GetWindowLong, tagWND::cbwndExtra, DWORD, and UINT.

01000 { 01001 UserAssert(index >= 0); 01002 UserAssert((UINT)index + sizeof(DWORD) <= (UINT)pwnd->cbwndExtra); 01003 return __GetWindowLong(pwnd, index); 01004 }

ULONG_PTR DBGGetWindowLongPtr PWND  pwnd,
int  index
 

Definition at line 1006 of file ntuser/kernel/getset.c.

References __GetWindowLongPtr, tagWND::cbwndExtra, and UINT.

01007 { 01008 UserAssert(index >= 0); 01009 UserAssert((UINT)index + sizeof(ULONG_PTR) <= (UINT)pwnd->cbwndExtra); 01010 return __GetWindowLongPtr(pwnd, index); 01011 }

BOOL DefSetText PWND  pwnd,
PLARGE_STRING  cczpstr
 

Definition at line 28 of file ntuser/kernel/getset.c.

References _LARGE_STRING::bAnsi, BOOL, _LARGE_STRING::Buffer, _LARGE_UNICODE_STRING::Buffer, DesktopAlloc(), DesktopFree, DTAG_TEXT, DWORD, FALSE, tagWND::head, _LARGE_UNICODE_STRING::Length, _LARGE_STRING::Length, _LARGE_UNICODE_STRING::MaximumLength, NT_SUCCESS, NULL, RtlMultiByteToUnicodeN(), tagWND::strName, and TRUE.

Referenced by NtUserDefSetText(), and xxxDefWindowProc().

00031 { 00032 /* 00033 * Note -- string buffer may be on client side. 00034 */ 00035 PDESKTOP pdesk; 00036 DWORD cbString; 00037 BOOL fTranslateOk; 00038 00039 if (pwnd->head.rpdesk == NULL || cczpstr == NULL || cczpstr->Buffer == NULL) { 00040 pwnd->strName.Length = 0; 00041 return TRUE; 00042 } 00043 00044 /* 00045 * Capture the new window name 00046 */ 00047 if (cczpstr->bAnsi) 00048 cbString = (cczpstr->Length + 1) * sizeof(WCHAR); 00049 else 00050 cbString = cczpstr->Length + sizeof(WCHAR); 00051 00052 /* 00053 * If the current buffer is not large enough, 00054 * reallocate it. 00055 */ 00056 pdesk = pwnd->head.rpdesk; 00057 if (pwnd->strName.MaximumLength < cbString) { 00058 if (pwnd->strName.Buffer != NULL) 00059 DesktopFree(pdesk, pwnd->strName.Buffer); 00060 pwnd->strName.Buffer = (LPWSTR)DesktopAlloc(pdesk, cbString, DTAG_TEXT); 00061 pwnd->strName.Length = 0; 00062 if (pwnd->strName.Buffer == NULL) { 00063 pwnd->strName.MaximumLength = 0; 00064 return FALSE; 00065 } 00066 pwnd->strName.MaximumLength = cbString; 00067 } 00068 00069 fTranslateOk = TRUE; 00070 if (cczpstr->Length != 0) { 00071 try { 00072 if (!cczpstr->bAnsi) { 00073 RtlCopyMemory(pwnd->strName.Buffer, cczpstr->Buffer, cbString); 00074 } else { 00075 LPCSTR ccxpszAnsi = (LPCSTR)cczpstr->Buffer; 00076 00077 fTranslateOk = NT_SUCCESS(RtlMultiByteToUnicodeN(pwnd->strName.Buffer, 00078 cbString, &cbString, 00079 (LPSTR)ccxpszAnsi, cbString / sizeof(WCHAR))); 00080 } 00081 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 00082 pwnd->strName.Length = 0; 00083 return FALSE; 00084 } 00085 } 00086 00087 if (fTranslateOk) { 00088 pwnd->strName.Length = cbString - sizeof(WCHAR); 00089 return TRUE; 00090 } else { 00091 pwnd->strName.Length = 0; 00092 return FALSE; 00093 } 00094 }

BOOL FCallerOk PWND  pwnd  ) 
 

Definition at line 104 of file ntuser/kernel/getset.c.

References BOOL, FALSE, GETPTI, gpidLogon, PtiCurrent, TIF_CSRSSTHREAD, tagTHREADINFO::TIF_flags, TIF_SYSTEMTHREAD, and TRUE.

Referenced by _SetWindowWord(), and xxxSetWindowLongPtr().

00106 { 00107 PTHREADINFO pti = PtiCurrent(); 00108 00109 if ((GETPTI(pwnd)->TIF_flags & (TIF_SYSTEMTHREAD | TIF_CSRSSTHREAD)) && 00110 !(pti->TIF_flags & (TIF_SYSTEMTHREAD | TIF_CSRSSTHREAD))) { 00111 return FALSE; 00112 } 00113 00114 if (GETPTI(pwnd)->pEThread->Cid.UniqueProcess == gpidLogon && 00115 pti->pEThread->Cid.UniqueProcess != gpidLogon) { 00116 return FALSE; 00117 } 00118 00119 return TRUE; 00120 }

PCALLPROCDATA FindPCPD PCALLPROCDATA  pCPD,
ULONG_PTR  dwClientPrevious,
WORD  wCPDType
 

Definition at line 850 of file ntuser/kernel/getset.c.

References NULL, _CALLPROCDATA::pfnClientPrevious, _CALLPROCDATA::spcpdNext, and _CALLPROCDATA::wType.

Referenced by GetCPD().

00854 { 00855 while (pCPD) { 00856 if ((pCPD->pfnClientPrevious == dwClientPrevious) && 00857 (pCPD->wType == wCPDType)) 00858 return pCPD; 00859 pCPD = pCPD->spcpdNext; 00860 } 00861 00862 return NULL; 00863 }

ULONG_PTR GetCPD PVOID  pWndOrCls,
DWORD  CPDOption,
ULONG_PTR  dwProc32
 

Definition at line 875 of file ntuser/kernel/getset.c.

References BOOL, CALLPROCDATA, CheckCritIn, CPD_ANSI_TO_UNICODE, CPD_CLASS, CPD_DIALOG, CPD_UNICODE_TO_ANSI, CPD_WND, CPD_WNDTOCLS, CSF_ANSIPROC, tagCLS::CSF_flags, FindPCPD(), HMAllocObject(), HW, ISCPDTAG, Lock, MAKE_CPDHANDLE, NtUserGetCPD(), NULL, _CALLPROCDATA::pfnClientPrevious, PtiCurrent, PtoH, tagTHREADINFO::rpdesk, tagCLS::spcpdFirst, _CALLPROCDATA::spcpdNext, TestWF, TYPE_CALLPROC, WFANSIPROC, and _CALLPROCDATA::wType.

Referenced by _GetClassData(), _GetClassInfoEx(), _GetWindowLongPtr(), _SetWindowLongPtr(), GetWindowData(), NtUserGetCPD(), xxxSetClassData(), and xxxSetWindowData().

00879 { 00880 PCALLPROCDATA pCPD; 00881 PCLS pcls; 00882 #if DBG 00883 BOOL bAnsiProc; 00884 #endif 00885 00886 PTHREADINFO ptiCurrent; 00887 00888 if (CPDOption & (CPD_WND | CPD_DIALOG)) { 00889 UserAssert(!(CPDOption & (CPD_CLASS | CPD_WNDTOCLS))); 00890 pcls = ((PWND)pWndOrCls)->pcls; 00891 00892 #if DBG 00893 if (CPDOption & CPD_WND) { 00894 bAnsiProc = !!(TestWF(pWndOrCls, WFANSIPROC)); 00895 } else { 00896 /* 00897 * We'll assume the client-side dialog box code knows 00898 * what it's doing, since we can't check it from here. 00899 */ 00900 bAnsiProc = !!(CPDOption & CPD_UNICODE_TO_ANSI); 00901 } 00902 #endif 00903 } else { 00904 UserAssert(CPDOption & (CPD_CLASS | CPD_WNDTOCLS)); 00905 if (CPDOption & CPD_WNDTOCLS) 00906 pcls = ((PWND)pWndOrCls)->pcls; 00907 else 00908 pcls = pWndOrCls; 00909 #if DBG 00910 bAnsiProc = !!(pcls->CSF_flags & CSF_ANSIPROC); 00911 #endif 00912 } 00913 00914 #if DBG 00915 /* 00916 * We should never have a CallProc handle as the calling address 00917 */ 00918 UserAssert(!ISCPDTAG(dwProc32)); 00919 00920 if (CPDOption & CPD_UNICODE_TO_ANSI) { 00921 UserAssert(bAnsiProc); 00922 } else if (CPDOption & CPD_ANSI_TO_UNICODE) { 00923 UserAssert(!bAnsiProc); 00924 } 00925 00926 #endif // DBG 00927 00928 /* 00929 * See if we already have a CallProc Handle that represents this 00930 * transition 00931 */ 00932 pCPD = FindPCPD(pcls->spcpdFirst, dwProc32, (WORD)CPDOption); 00933 00934 if (pCPD) { 00935 return MAKE_CPDHANDLE(PtoH(pCPD)); 00936 } 00937 00938 CheckCritIn(); 00939 00940 ptiCurrent = PtiCurrent(); 00941 00942 pCPD = HMAllocObject(ptiCurrent, 00943 ptiCurrent->rpdesk, 00944 TYPE_CALLPROC, 00945 sizeof(CALLPROCDATA)); 00946 if (pCPD == NULL) { 00947 RIPMSG0(RIP_WARNING, "GetCPD unable to alloc CALLPROCDATA\n"); 00948 return 0; 00949 } 00950 00951 /* 00952 * Link in the new CallProcData to the class list. 00953 * Note -- these pointers are locked because WOWCleanup can come in 00954 * and delete objects, so we need to keep the pointers locked. 00955 */ 00956 Lock(&pCPD->spcpdNext, pcls->spcpdFirst); 00957 Lock(&pcls->spcpdFirst, pCPD); 00958 00959 /* 00960 * Initialize the CPD 00961 */ 00962 pCPD->pfnClientPrevious = dwProc32; 00963 pCPD->wType = (WORD)CPDOption; 00964 00965 return MAKE_CPDHANDLE(PtoH(pCPD)); 00966 }

ULONG_PTR MapClientToServerPfn ULONG_PTR  dw  ) 
 

Definition at line 978 of file ntuser/kernel/getset.c.

References tagSERVERINFO::apfnClientA, tagSERVERINFO::apfnClientW, FNID_WNDPROCEND, FNID_WNDPROCSTART, gpsi, and STOCID.

Referenced by InternalRegisterClassEx(), xxxSetClassData(), and xxxSetWindowData().

00980 { 00981 ULONG_PTR *pdw; 00982 int i; 00983 00984 pdw = (ULONG_PTR *)&gpsi->apfnClientW; 00985 for (i = FNID_WNDPROCSTART; i <= FNID_WNDPROCEND; i++, pdw++) { 00986 if (*pdw == dw) 00987 return (ULONG_PTR)STOCID(i); 00988 } 00989 00990 pdw = (ULONG_PTR *)&gpsi->apfnClientA; 00991 for (i = FNID_WNDPROCSTART; i <= FNID_WNDPROCEND; i++, pdw++) { 00992 if (*pdw == dw) 00993 return (ULONG_PTR)STOCID(i); 00994 } 00995 00996 return 0; 00997 }

void xxxHandleOwnerSwitch PWND  pwnd,
PWND  pwndNewParent,
PWND  pwndOldParent
 

Definition at line 499 of file ntuser/kernel/getset.c.

References CheckLock, FALSE, GETPTI, IsTrayWindow(), NULL, PostShellHookMessages(), PtoH, TRUE, xxxCallHook(), and zzzAttachThreadInput().

Referenced by xxxSetWindowData().

00500 { 00501 CheckLock(pwnd); 00502 CheckLock(pwndNewParent); 00503 CheckLock(pwndOldParent); 00504 00505 if ((pwndOldParent != NULL) && 00506 (GETPTI(pwndOldParent) != GETPTI(pwnd))) { 00507 00508 /* 00509 * See if it needs to be unattached. 00510 */ 00511 if ((pwndNewParent == NULL) || 00512 (GETPTI(pwndNewParent) == GETPTI(pwnd)) || 00513 (GETPTI(pwndNewParent) != GETPTI(pwndOldParent))) { 00514 00515 zzzAttachThreadInput(GETPTI(pwnd), GETPTI(pwndOldParent), FALSE); 00516 } 00517 } 00518 00519 /* 00520 * See if it needs to be attached. 00521 */ 00522 if ((pwndNewParent != NULL) && 00523 (GETPTI(pwndNewParent) != GETPTI(pwnd)) && 00524 ((pwndOldParent == NULL) || 00525 (GETPTI(pwndNewParent) != GETPTI(pwndOldParent)))) { 00526 00527 zzzAttachThreadInput(GETPTI(pwnd), GETPTI(pwndNewParent), TRUE); 00528 } 00529 00530 /* 00531 * Post hook messages for tray-windows. 00532 */ 00533 if (IsTrayWindow(pwnd)) { 00534 00535 HWND hw = PtoH(pwnd); 00536 00537 /* 00538 * If we're setting the owner and it's changing from owned 00539 * to unowned or vice-versa, notify the tray. 00540 */ 00541 if ((pwndOldParent != NULL) && (pwndNewParent == NULL)) { 00542 xxxCallHook(HSHELL_WINDOWCREATED, 00543 (WPARAM)hw, 00544 (LONG)0, 00545 WH_SHELL); 00546 PostShellHookMessages(HSHELL_WINDOWCREATED, (LPARAM)hw); 00547 00548 } else if ((pwndOldParent == NULL) && (pwndNewParent != NULL)) { 00549 xxxCallHook(HSHELL_WINDOWDESTROYED, 00550 (WPARAM)hw, 00551 (LONG)0, 00552 WH_SHELL); 00553 PostShellHookMessages(HSHELL_WINDOWDESTROYED, (LPARAM)hw); 00554 } 00555 } 00556 }

ULONG_PTR xxxSetWindowData PWND  pwnd,
int  index,
ULONG_PTR  dwData,
BOOL  bAnsi
 

Definition at line 568 of file ntuser/kernel/getset.c.

References BOOL, CheckLock, ClrWF, CPD_ANSI_TO_UNICODE, CPD_UNICODE_TO_ANSI, CPD_WND, DWORD, tagWND::dwUserData, FALSE, FNID_DELETED_BIT, FNID_EDIT, GetCPD(), GETFNID, GETPTI, HMValidateHandleNoRip(), HW, ISCPDTAG, IsWinEventNotifyDeferredOK, Lock, LockWndMenu(), tagWND::lpfnWndProc, MapClientNeuterToClientPfn(), MapClientToServerPfn(), MapServerToClientPfn(), NULL, tagWND::pcls, _CALLPROCDATA::pfnClientPrevious, PpiCurrent, PtoH, PWNDDESKTOP, SetWF, tagWND::spmenu, tagWND::spwndOwner, tagWND::spwndParent, TestWF, TestwndChild, ThreadLock, ThreadUnlock, TRUE, TYPE_CALLPROC, Unlock, UnlockWndMenu(), ValidateHmenu(), ValidateHwnd, ValidateOwnerDepth(), WFANSIPROC, WFSERVERSIDEPROC, WNDPROC_PWND, _CALLPROCDATA::wType, xxxClientWOWGetProcModule(), xxxDefWindowProc(), xxxHandleOwnerSwitch(), xxxSetParent(), and xxxSetWindowStyle().

Referenced by xxxSetWindowLongPtr().

00573 { 00574 ULONG_PTR dwT; 00575 ULONG_PTR dwOld; 00576 PMENU pmenu; 00577 PWND *ppwnd; 00578 PWND pwndNewParent; 00579 PWND pwndOldParent; 00580 BOOL fTopOwner; 00581 TL tlpwndOld; 00582 TL tlpwndNew; 00583 DWORD dwCPDType = 0; 00584 00585 CheckLock(pwnd); 00586 UserAssert(IsWinEventNotifyDeferredOK()); 00587 00588 switch (index) { 00589 case GWLP_USERDATA: 00590 dwOld = pwnd->dwUserData; 00591 pwnd->dwUserData = dwData; 00592 break; 00593 00594 case GWL_EXSTYLE: 00595 case GWL_STYLE: 00596 dwOld = xxxSetWindowStyle(pwnd, index, (DWORD)dwData); 00597 break; 00598 00599 case GWLP_ID: 00600 /* 00601 * Win95 does a TestWF(pwnd, WFCHILD) here, but we'll do the same 00602 * check we do everywhere else or it'll cause us trouble. 00603 */ 00604 if (TestwndChild(pwnd)) { 00605 00606 /* 00607 * pwnd->spmenu is an id in this case. 00608 */ 00609 dwOld = (ULONG_PTR)pwnd->spmenu; 00610 pwnd->spmenu = (struct tagMENU *)dwData; 00611 } else { 00612 dwOld = 0; 00613 if (pwnd->spmenu != NULL) 00614 dwOld = (ULONG_PTR)PtoH(pwnd->spmenu); 00615 00616 if (dwData == 0) { 00617 UnlockWndMenu(pwnd, &pwnd->spmenu); 00618 } else { 00619 pmenu = ValidateHmenu((HANDLE)dwData); 00620 if (pmenu != NULL) { 00621 LockWndMenu(pwnd, &pwnd->spmenu, pmenu); 00622 } else { 00623 00624 /* 00625 * Menu is invalid, so don't set a new one! 00626 */ 00627 dwOld = 0; 00628 } 00629 } 00630 } 00631 break; 00632 00633 case GWLP_HINSTANCE: 00634 dwOld = (ULONG_PTR)pwnd->hModule; 00635 pwnd->hModule = (HANDLE)dwData; 00636 break; 00637 00638 case GWLP_WNDPROC: // See similar case DWLP_DLGPROC 00639 00640 /* 00641 * Hide the window proc from other processes 00642 */ 00643 if (PpiCurrent() != GETPTI(pwnd)->ppi) { 00644 RIPERR1(ERROR_ACCESS_DENIED, RIP_WARNING, 00645 "SetWindowLong: Window owned by another process %#p", pwnd); 00646 return 0; 00647 } 00648 00649 /* 00650 * If the window has been zombized by a DestroyWindow but is still 00651 * around because the window was locked don't let anyone change 00652 * the window proc from DefWindowProc! 00653 * 00654 * !!! LATER long term move this test into the ValidateHWND; kind of 00655 * !!! LATER close to shipping for that 00656 */ 00657 if (pwnd->fnid & FNID_DELETED_BIT) { 00658 UserAssert(pwnd->lpfnWndProc == xxxDefWindowProc); 00659 RIPERR1(ERROR_ACCESS_DENIED, RIP_WARNING, 00660 "SetWindowLong: Window is a zombie %#p", pwnd); 00661 return 0; 00662 } 00663 00664 /* 00665 * If the application (client) subclasses a window that has a server - 00666 * side window proc we must return an address that the client can call: 00667 * this client-side wndproc expectes Unicode or ANSI depending on bAnsi 00668 */ 00669 00670 if (TestWF(pwnd, WFSERVERSIDEPROC)) { 00671 dwOld = MapServerToClientPfn((ULONG_PTR)pwnd->lpfnWndProc, bAnsi); 00672 00673 /* 00674 * If we don't have a client side address (like for the DDEMLMon 00675 * window) then blow off the subclassing. 00676 */ 00677 if (dwOld == 0) { 00678 RIPMSG0(RIP_WARNING, "SetWindowLong: subclass server only window"); 00679 return(0); 00680 } 00681 00682 ClrWF(pwnd, WFSERVERSIDEPROC); 00683 } else { 00684 /* 00685 * Keep edit control behavior compatible with NT 3.51. 00686 */ 00687 if (GETFNID(pwnd) == FNID_EDIT) { 00688 dwOld = (ULONG_PTR)pwnd->lpfnWndProc; 00689 } else { 00690 dwOld = MapClientNeuterToClientPfn(pwnd->pcls, (ULONG_PTR)pwnd->lpfnWndProc, bAnsi); 00691 } 00692 00693 /* 00694 * If the client mapping didn't change the window proc then see if 00695 * we need a callproc handle. 00696 */ 00697 if (dwOld == (ULONG_PTR)pwnd->lpfnWndProc) { 00698 /* 00699 * May need to return a CallProc handle if there is an Ansi/Unicode mismatch 00700 */ 00701 if (bAnsi != (TestWF(pwnd, WFANSIPROC) ? TRUE : FALSE)) { 00702 dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI; 00703 } 00704 } 00705 00706 UserAssert(!ISCPDTAG(dwOld)); 00707 00708 if (dwCPDType) { 00709 ULONG_PTR cpd; 00710 00711 cpd = GetCPD(pwnd, dwCPDType | CPD_WND, dwOld); 00712 00713 if (cpd) { 00714 dwOld = cpd; 00715 } else { 00716 RIPMSG0(RIP_WARNING, "SetWindowLong unable to alloc CPD returning handle\n"); 00717 } 00718 } 00719 } 00720 00721 /* 00722 * Convert a possible CallProc Handle into a real address. They may 00723 * have kept the CallProc Handle from some previous mixed GetClassinfo 00724 * or SetWindowLong. 00725 * 00726 * WARNING bAnsi is modified here to represent real type of 00727 * proc rather than if SetWindowLongA or W was called 00728 * 00729 */ 00730 if (ISCPDTAG(dwData)) { 00731 PCALLPROCDATA pCPD; 00732 if (pCPD = HMValidateHandleNoRip((HANDLE)dwData, TYPE_CALLPROC)) { 00733 dwData = pCPD->pfnClientPrevious; 00734 bAnsi = pCPD->wType & CPD_UNICODE_TO_ANSI; 00735 } 00736 } 00737 00738 /* 00739 * If an app 'unsubclasses' a server-side window proc we need to 00740 * restore everything so SendMessage and friends know that it's 00741 * a server-side proc again. Need to check against client side 00742 * stub addresses. 00743 */ 00744 if ((dwT = MapClientToServerPfn(dwData)) != 0) { 00745 pwnd->lpfnWndProc = (WNDPROC_PWND)dwT; 00746 SetWF(pwnd, WFSERVERSIDEPROC); 00747 ClrWF(pwnd, WFANSIPROC); 00748 } else { 00749 pwnd->lpfnWndProc = (WNDPROC_PWND)MapClientNeuterToClientPfn(pwnd->pcls, dwData, bAnsi); 00750 if (bAnsi) { 00751 SetWF(pwnd, WFANSIPROC); 00752 } else { 00753 ClrWF(pwnd, WFANSIPROC); 00754 } 00755 00756 pwnd->hMod16 = xxxClientWOWGetProcModule(pwnd->lpfnWndProc); 00757 00758 } 00759 00760 break; 00761 00762 case GWLP_HWNDPARENT: 00763 /* 00764 * Special case for pre-1.1 versions of Windows 00765 * Set/GetWindowWord(GWW_HWNDPARENT) needs to be mapped 00766 * to the hwndOwner for top level windows. 00767 */ 00768 fTopOwner = FALSE; 00769 if (pwnd->spwndParent == PWNDDESKTOP(pwnd)) { 00770 ppwnd = &pwnd->spwndOwner; 00771 fTopOwner = TRUE; 00772 } else { 00773 ppwnd = &pwnd->spwndParent; 00774 } 00775 00776 00777 /* 00778 * If we're a topmost, then we're only changing the owner 00779 * relationship. Otherwise, we are doing a relinking of the 00780 * parent/child relationship. 00781 */ 00782 pwndOldParent = *ppwnd; 00783 pwndNewParent = ValidateHwnd((HWND)dwData); 00784 00785 if ((pwndNewParent == NULL) && dwData) { 00786 RIPERR1(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "Set GWL_HWNDPARENT, invalid hwndParent %#p", dwData); 00787 return 0; 00788 } 00789 00790 dwOld = (ULONG_PTR)HW(*ppwnd); 00791 00792 ThreadLock(pwndNewParent, &tlpwndNew); 00793 00794 if (fTopOwner) { 00795 00796 ThreadLock(pwndOldParent, &tlpwndOld); 00797 00798 xxxHandleOwnerSwitch(pwnd, pwndNewParent, pwndOldParent); 00799 00800 if (ValidateOwnerDepth(pwnd, pwndNewParent)) { 00801 00802 /* 00803 * Set the owner. 00804 */ 00805 if (pwndNewParent) { 00806 Lock(ppwnd, pwndNewParent); 00807 } else { 00808 Unlock(ppwnd); 00809 } 00810 } else { 00811 00812 /* 00813 * Undo the switch and set last error. 00814 */ 00815 xxxHandleOwnerSwitch(pwnd, pwndOldParent, pwndNewParent); 00816 RIPERR0(ERROR_INVALID_PARAMETER, RIP_ERROR, "Detected loop in owner chain"); 00817 dwOld = 0; 00818 } 00819 00820 ThreadUnlock(&tlpwndOld); 00821 00822 } else { 00823 if (!xxxSetParent(pwnd, pwndNewParent)) { 00824 dwOld = 0; 00825 } 00826 } 00827 00828 ThreadUnlock(&tlpwndNew); 00829 break; 00830 00831 default: 00832 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00833 return 0; 00834 } 00835 00836 return dwOld; 00837 }

ULONG_PTR xxxSetWindowLongPtr PWND  pwnd,
int  index,
ULONG_PTR  dwData,
BOOL  bAnsi
 

Definition at line 260 of file ntuser/kernel/getset.c.

References BYTE, CBFNID, tagWND::cbwndExtra, DWORD, FCallerOk(), FNID_BUTTON, FNID_COMBOBOX, FNID_COMBOLISTBOX, FNID_DIALOG, FNID_EDIT, FNID_IME, FNID_LISTBOX, FNID_MDICLIENT, FNID_STATIC, GETFNID, GETPTI, GWLP_MDIDATA, PpiCurrent, TestWF, UINT, WFDESTROYED, WFDIALOGWINDOW, and xxxSetWindowData().

00265 { 00266 ULONG_PTR dwOld; 00267 DWORD dwCPDType = 0; 00268 00269 /* 00270 * Hide the window proc from other processes 00271 */ 00272 #if DBG 00273 if (PpiCurrent() != GETPTI(pwnd)->ppi) { 00274 RIPMSG0(RIP_WARNING, "Setting cross process windowlong; win95 would fail"); 00275 } 00276 #endif 00277 00278 /* 00279 * CheckLock(pwnd); The only case that leaves the critical section is 00280 * where xxxSetWindowData is called, which does this. Saves us some locks. 00281 * 00282 * 00283 * Don't allow setting of words belonging to a system thread if the caller 00284 * is not a system thread. Same goes for winlogon. 00285 */ 00286 if (!FCallerOk(pwnd)) { 00287 RIPERR0(ERROR_INVALID_INDEX, RIP_VERBOSE, ""); 00288 return 0; 00289 } 00290 00291 /* 00292 * If it's a dialog window, only a few indices are permitted. 00293 */ 00294 if (GETFNID(pwnd) != 0) { 00295 if (TestWF(pwnd, WFDIALOGWINDOW)) { 00296 switch (index) { 00297 case DWLP_MSGRESULT: 00298 dwOld = (ULONG_PTR)((PDIALOG)(pwnd))->resultWP; 00299 ((PDIALOG)(pwnd))->resultWP = (LONG_PTR)dwData; 00300 return dwOld; 00301 00302 case DWLP_USER: 00303 dwOld = (ULONG_PTR)((PDIALOG)(pwnd))->unused; 00304 ((PDIALOG)(pwnd))->unused = (LONG_PTR)dwData; 00305 return dwOld; 00306 00307 default: 00308 if (index >= 0 && index < DLGWINDOWEXTRA) { 00309 RIPERR0(ERROR_PRIVATE_DIALOG_INDEX, RIP_VERBOSE, ""); 00310 return 0; 00311 } 00312 } 00313 } else { 00314 if (index >= 0 && 00315 (index < (int)(CBFNID(pwnd->fnid)-sizeof(WND)))) { 00316 switch (GETFNID(pwnd)) { 00317 case FNID_BUTTON: 00318 case FNID_COMBOBOX: 00319 case FNID_COMBOLISTBOX: 00320 case FNID_DIALOG: 00321 case FNID_LISTBOX: 00322 case FNID_STATIC: 00323 case FNID_EDIT: 00324 #ifdef FE_IME 00325 case FNID_IME: 00326 #endif 00327 /* 00328 * Allow the 0 index for controls to be set if it's 00329 * still NULL or the window is being destroyed. This 00330 * is where controls store their private data. 00331 */ 00332 if (index == 0) { 00333 dwOld = *((PULONG_PTR)(pwnd + 1)); 00334 if (dwOld == 0 || TestWF(pwnd, WFDESTROYED)) 00335 goto SetData; 00336 } 00337 break; 00338 00339 case FNID_MDICLIENT: 00340 /* 00341 * Allow the 0 index (which is reserved) to be set/get. 00342 * Quattro Pro 1.0 uses this index! 00343 * 00344 * Allow the 4 index to be set if it's still NULL or 00345 * the window is being destroyed. This is where we 00346 * store our private data. 00347 */ 00348 #ifndef _WIN64 00349 if (index == 0) { 00350 goto SetData; 00351 } 00352 #endif 00353 if (index == GWLP_MDIDATA) { 00354 dwOld = *((PULONG_PTR)(pwnd + 1)); 00355 if (dwOld == 0 || TestWF(pwnd, WFDESTROYED)) 00356 goto SetData; 00357 } 00358 break; 00359 } 00360 00361 RIPERR3(ERROR_INVALID_INDEX, 00362 RIP_WARNING, 00363 "SetWindowLongPtr: Trying to set private server data pwnd=(%#p) index=(%ld) FNID=(%lX)", 00364 pwnd, index, (DWORD)pwnd->fnid); 00365 return 0; 00366 } 00367 } 00368 } 00369 00370 if (index < 0) { 00371 return xxxSetWindowData(pwnd, index, dwData, bAnsi); 00372 } else { 00373 if ((UINT)index + sizeof(ULONG_PTR) > (UINT)pwnd->cbwndExtra) { 00374 RIPERR3(ERROR_INVALID_INDEX, 00375 RIP_WARNING, 00376 "SetWindowLongPtr: Index %d too big for cbWndExtra %d on pwnd %#p", 00377 index, pwnd->cbwndExtra, pwnd); 00378 return 0; 00379 } else { 00380 ULONG_PTR UNALIGNED *pudw; 00381 00382 SetData: 00383 pudw = (ULONG_PTR UNALIGNED *)((BYTE *)(pwnd + 1) + index); 00384 dwOld = *pudw; 00385 *pudw = dwData; 00386 return dwOld; 00387 } 00388 } 00389 }


Generated on Sat May 15 19:43:54 2004 for test by doxygen 1.3.7