Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2261 lines
54 KiB

/**************************************************************************\
* Module Name: ntstubs.c
*
* Copyright (c) Microsoft Corp. 1990 All Rights Reserved
*
* client side API stubs
*
* History:
* 03-19-95 JimA Created.
\**************************************************************************/
#include "precomp.h"
#pragma hdrstop
#define CLIENTSIDE 1
#include "ntsend.h"
WINUSERAPI
BOOL
WINAPI
SetSysColors(
int cElements,
CONST INT * lpaElements,
CONST COLORREF * lpaRgbValues)
{
return NtUserSetSysColors(cElements,
lpaElements,
lpaRgbValues,
SSCF_NOTIFY | SSCF_FORCESOLIDCOLOR | SSCF_SETMAGICCOLORS);
}
HWND WOWFindWindow(
LPCSTR pClassName,
LPCSTR pWindowName)
{
IN_STRING strClassName;
IN_STRING strWindowName;
/*
* Make sure cleanup will work successfully
*/
strClassName.fAllocated = FALSE;
strWindowName.fAllocated = FALSE;
BEGINCALL()
FIRSTCOPYLPSTRIDOPTW(&strClassName, pClassName);
COPYLPSTROPTW(&strWindowName, pWindowName);
retval = (DWORD)NtUserWOWFindWindow(
strClassName.pstr,
strWindowName.pstr);
ERRORTRAP(0);
CLEANUPLPSTRW(strClassName);
CLEANUPLPSTRW(strWindowName);
ENDCALL(HWND);
}
BOOL UpdatePerUserSystemParameters(
BOOL bUserLoggedOn)
{
WCHAR pwszKLID[KL_NAMELENGTH];
BEGINCALL()
/*
* Cause the wallpaper to be changed.
*/
SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, 0, 0);
#ifdef FE_IME
/*
* Initialize IME hotkeys before loading keyboard
* layouts.
*/
ImmInitializeHotKeys( bUserLoggedOn );
#endif
/*
* Load initial keyboard layout.
*/
GetActiveKeyboardName(pwszKLID);
LoadKeyboardLayoutW(pwszKLID, KLF_ACTIVATE | KLF_RESET | KLF_SUBSTITUTE_OK);
/*
* Now load the remaining preload keyboard layouts.
*/
LoadPreloadKeyboardLayouts();
retval = (DWORD)NtUserUpdatePerUserSystemParameters(bUserLoggedOn);
ERRORTRAP(0);
ENDCALL(BOOL);
}
DWORD Event(
PEVENT_PACKET pep)
{
BEGINCALL()
CheckDDECritOut;
retval = (DWORD)NtUserEvent(
pep);
ERRORTRAP(0);
ENDCALL(DWORD);
}
BOOL FillWindow(
HWND hwndBrush,
HWND hwndPaint,
HDC hdc,
HBRUSH hbr)
{
FIXUP_HANDLE(hdc);
if (hdc == NULL)
MSGERROR();
BEGINCALL()
retval = (DWORD)NtUserFillWindow(
hwndBrush,
hwndPaint,
hdc,
hbr);
ERRORTRAP(0);
ENDCALL(BOOL);
}
LONG GetClassWOWWords(
HINSTANCE hInstance,
LPCTSTR pString)
{
IN_STRING strClassName;
PCLS pcls;
/*
* Make sure cleanup will work successfully
*/
strClassName.fAllocated = FALSE;
BEGINCALL()
FIRSTCOPYLPSTRW(&strClassName, pString);
pcls = NtUserGetWOWClass(hInstance, strClassName.pstr);
if (pcls == NULL) {
MSGERRORCODE(ERROR_CLASS_DOES_NOT_EXIST);
}
pcls = (PCLS)((PBYTE)pcls - GetClientInfo()->ulClientDelta);
retval = _GetClassData(pcls, NULL, GCL_WOWWORDS, TRUE);
ERRORTRAP(0);
CLEANUPLPSTRW(strClassName);
ENDCALL(LONG);
}
/***************************************************************************\
* InitTask
*
* Initialize a WOW task. This is the first call a WOW thread makes to user.
* NtUserInitTask returns NTSTATUS because if the thread fails to convert
* to a GUI thread, STATUS_INVALID_SYSTEM_SERVICE is returned.
*
* 11-03-95 JimA Modified to use NTSTATUS.
\***************************************************************************/
BOOL InitTask(
UINT wVersion,
LPCSTR pszAppName,
DWORD hTaskWow,
DWORD dwHotkey,
DWORD idTask,
DWORD dwX,
DWORD dwY,
DWORD dwXSize,
DWORD dwYSize,
WORD wShowWindow)
{
IN_STRING strAppName;
NTSTATUS Status;
/*
* Make sure cleanup will work successfully
*/
strAppName.fAllocated = FALSE;
BEGINCALL()
FIRSTCOPYLPSTRW(&strAppName, pszAppName);
Status = NtUserInitTask(
wVersion,
strAppName.pstr,
hTaskWow,
dwHotkey,
idTask,
dwX,
dwY,
dwXSize,
dwYSize,
wShowWindow);
retval = (Status == STATUS_SUCCESS);
CLEANUPLPSTRW(strAppName);
ERRORTRAP(FALSE);
ENDCALL(BOOL);
}
HANDLE ConvertMemHandle(
HANDLE hData,
UINT cbNULL)
{
UINT cbData;
LPBYTE lpData;
BEGINCALL()
if (GlobalFlags(hData) == GMEM_INVALID_HANDLE) {
RIPMSG0(RIP_WARNING, "ConvertMemHandle hMem is not valid\n");
MSGERROR();
}
if (!(cbData = GlobalSize(hData)))
MSGERROR();
USERGLOBALLOCK(hData, lpData);
if (lpData == NULL) {
MSGERROR();
}
/*
* Make sure text formats are NULL terminated.
*/
switch (cbNULL) {
case 2:
lpData[cbData - 2] = 0;
// FALL THROUGH
case 1:
lpData[cbData - 1] = 0;
}
retval = (DWORD)NtUserConvertMemHandle(lpData, cbData);
USERGLOBALUNLOCK(hData);
ERRORTRAP(NULL);
ENDCALL(HANDLE);
}
HANDLE CreateLocalMemHandle(
HANDLE hMem)
{
UINT cbData;
NTSTATUS Status;
BEGINCALL()
Status = NtUserCreateLocalMemHandle(hMem, NULL, 0, &cbData);
if (Status != STATUS_BUFFER_TOO_SMALL) {
RIPMSG0(RIP_WARNING, "__CreateLocalMemHandle server returned failure\n");
MSGERROR();
}
if (!(retval = (DWORD)GlobalAlloc(GMEM_FIXED, cbData)))
MSGERROR();
Status = NtUserCreateLocalMemHandle(hMem, (LPBYTE)retval, cbData, NULL);
if (!NT_SUCCESS(Status)) {
RIPMSG0(RIP_WARNING, "__CreateLocalMemHandle server returned failure\n");
UserGlobalFree((HANDLE)retval);
MSGERROR();
}
ERRORTRAP(0);
ENDCALL(HANDLE);
}
HHOOK _SetWindowsHookEx(
HANDLE hmod,
LPTSTR pszLib,
DWORD idThread,
int nFilterType,
PROC pfnFilterProc,
BOOL bAnsi)
{
IN_STRING strLib;
/*
* Make sure cleanup will work successfully
*/
strLib.fAllocated = FALSE;
BEGINCALL()
FIRSTCOPYLPWSTROPT(&strLib, pszLib);
retval = (DWORD)NtUserSetWindowsHookEx(
hmod,
strLib.pstr,
idThread,
nFilterType,
pfnFilterProc,
bAnsi);
ERRORTRAP(0);
CLEANUPLPWSTR(strLib);
ENDCALL(HHOOK);
}
HACCEL _CreateAcceleratorTable(
LPACCEL paccel,
INT cbElem,
INT nElem)
{
LPACCEL p = NULL, paccelT;
DWORD cbAccel = sizeof(ACCEL) * nElem;
BEGINCALL()
if (cbElem != sizeof(ACCEL)) {
/*
* If the accelerator table is coming from a resource, each
* element has an extra WORD of padding which we strip here
* to conform with the public (and internal) ACCEL structure.
*/
p = paccelT = UserLocalAlloc(0, sizeof(ACCEL) * nElem);
while (nElem-- > 0) {
*paccelT++ = *paccel;
paccel = (LPACCEL)(((PBYTE)paccel) + cbElem);
}
paccel = p;
}
retval = (DWORD)NtUserCreateAcceleratorTable(
paccel, cbAccel);
if (p)
UserLocalFree(p);
ERRORTRAP(0);
ENDCALL(HACCEL);
}
BOOL GetWindowPlacement(
HWND hwnd,
PWINDOWPLACEMENT pwp)
{
#ifdef LATER
if (pwp->length != sizeof(WINDOWPLACEMENT)) {
if (Is400Compat(PtiCurrent()->dwExpWinVer)) {
RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "GetWindowPlacement: invalid length %lX", pwp->length);
return FALSE;
} else {
RIPMSG1(RIP_WARNING, "GetWindowPlacement: invalid length %lX", pwp->length);
pwp->length = sizeof(WINDOWPLACEMENT);
}
}
#endif
BEGINCALL()
retval = (DWORD)NtUserGetWindowPlacement(
hwnd,
pwp);
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef MEMPHIS_MENUS
BOOL ThunkedMenuItemInfo(
HMENU hMenu,
UINT nPosition,
BOOL fByPosition,
BOOL fInsert,
LPMENUITEMINFOW lpmii,
BOOL fAnsi)
{
MENUITEMINFOW mii;
IN_STRING strItem;
/*
* Make sure cleanup will work successfully
*/
strItem.fAllocated = FALSE;
BEGINCALL()
/*
* Make a local copy so we can make changes
*/
mii = *(LPMENUITEMINFO)(lpmii);
strItem.pstr = NULL;
if (mii.fMask & MIIM_BITMAP) {
if (LOWORD(mii.hbmpItem) < MENUHBM_MAX && HIWORD(mii.hbmpItem)) {
/*
* Looks like the user was trying to insert one of the
* MENUHBM_* bitmaps, but stuffed some data in the HIWORD.
* We know the HIWORD data is invalid because the LOWORD
* handle is below the GDI minimum.
*/
RIPMSG1(RIP_WARNING, "Invalid HIWORD data (0x%04X) for MENUHBM_* bitmap.", HIWORD(mii.hbmpItem));
mii.hbmpItem = (HBITMAP)LOWORD(mii.hbmpItem);
}
}
if (mii.fMask & MIIM_STRING){
if (fAnsi) {
FIRSTCOPYLPSTROPTW(&strItem, mii.dwTypeData);
} else {
FIRSTCOPYLPWSTROPT(&strItem, mii.dwTypeData);
}
}
retval = (DWORD)NtUserThunkedMenuItemInfo(
hMenu,
nPosition,
fByPosition,
fInsert,
&mii,
strItem.pstr,
fAnsi);
ERRORTRAP(0);
CLEANUPLPSTRW(strItem);
ENDCALL(BOOL);
}
#else // MEMPHIS_MENUS
BOOL ThunkedMenuItemInfo(
HMENU hMenu,
UINT nPosition,
BOOL fByPosition,
BOOL fInsert,
LPMENUITEMINFOW lpmii,
BOOL fAnsi)
{
MENUITEMINFOW mii;
IN_STRING strItem;
/*
* Make sure cleanup will work successfully
*/
strItem.fAllocated = FALSE;
BEGINCALL()
/*
* Make a local copy so we can make changes
*/
mii = *(LPMENUITEMINFO)(lpmii);
strItem.pstr = NULL;
if (mii.fMask & MIIM_TYPE) {
if (mii.fType & MFT_BITMAP) {
if (LOWORD(mii.dwTypeData) < MENUHBM_MAX && HIWORD(mii.dwTypeData)) {
/*
* Looks like the user was trying to insert one of the
* MENUHBM_* bitmaps, but stuffed some data in the HIWORD.
* We know the HIWORD data is invalid because the LOWORD
* handle is below the GDI minimum.
*/
RIPMSG1(RIP_WARNING, "Invalid HIWORD data (0x%04X) for MENUHBM_* bitmap.", HIWORD(mii.dwTypeData));
mii.dwTypeData = (LPWSTR)LOWORD(mii.dwTypeData);
}
} else if ((mii.fType & MFT_NONSTRING)==0){
if (fAnsi) {
FIRSTCOPYLPSTROPTW(&strItem, mii.dwTypeData);
} else {
FIRSTCOPYLPWSTROPT(&strItem, mii.dwTypeData);
}
}
}
retval = (DWORD)NtUserThunkedMenuItemInfo(
hMenu,
nPosition,
fByPosition,
fInsert,
&mii,
strItem.pstr,
fAnsi);
ERRORTRAP(0);
CLEANUPLPSTRW(strItem);
ENDCALL(BOOL);
}
#endif // MEMPHIS_MENUS
#ifdef MEMPHIS_MENU_WATERMARKS
BOOL ThunkedMenuInfo(
HMENU hMenu,
LPCMENUINFO lpmi,
WORD wAPICode,
BOOL fAnsi)
{
if (!ValidateMENUINFO(lpmi,wAPICode)) {
return FALSE;
}
BEGINCALL()
retval = (DWORD)NtUserThunkedMenuInfo(
hMenu,
lpmi,
wAPICode,
fAnsi);
ERRORTRAP(0);
ENDCALL(BOOL);
}
#endif // MEMPHIS_MENU_WATERMARKS
BOOL DrawCaption(
HWND hwnd,
HDC hdc,
CONST RECT *lprc,
UINT flags)
{
HDC hdcr;
BEGINCALL()
if (IsMetaFile(hdc))
return FALSE;
hdcr = GdiConvertAndCheckDC(hdc);
if (hdcr == (HDC)0)
return FALSE;
retval = (DWORD)NtUserDrawCaption(hwnd, hdcr, lprc, flags);
ERRORTRAP(0);
ENDCALL(BOOL);
}
BOOL PaintDesktop(
HDC hdc)
{
BEGINCALL()
FIXUP_HANDLE(hdc);
retval = (DWORD)NtUserPaintDesktop(
hdc);
ERRORTRAP(0);
ENDCALL(BOOL);
}
SHORT GetAsyncKeyState(
int vKey)
{
BEGINCALLCONNECT()
/*
* If this is one of the common keys, see if we can pull it out
* of the cache.
*/
if ((UINT)vKey < CVKASYNCKEYCACHE) {
PCLIENTINFO pci = GetClientInfo();
if ((pci->dwAsyncKeyCache == gpsi->dwAsyncKeyCache) &&
!TestKeyRecentDownBit(pci->afAsyncKeyStateRecentDown, vKey)) {
if (TestKeyDownBit(pci->afAsyncKeyState, vKey))
retval = 0x8000;
else
retval = 0;
return (SHORT)retval;
}
}
retval = (DWORD)NtUserGetAsyncKeyState(
vKey);
ERRORTRAP(0);
ENDCALL(SHORT);
}
SHORT GetKeyState(
int vKey)
{
BEGINCALLCONNECT()
/*
* If this is one of the common keys, see if we can pull it out
* of the cache.
*/
if ((UINT)vKey < CVKKEYCACHE) {
PCLIENTINFO pci = GetClientInfo();
if (pci->dwKeyCache == gpsi->dwKeyCache) {
retval = 0;
if (TestKeyToggleBit(pci->afKeyState, vKey))
retval |= 0x0001;
if (TestKeyDownBit(pci->afKeyState, vKey)) {
/*
* Used to be retval |= 0x8000.Fix for bug 28820; Ctrl-Enter
* accelerator doesn't work on Nestscape Navigator Mail 2.0
*/
retval |= 0xff80; // This is what 3.1 returned!!!!
}
return (SHORT)retval;
}
}
retval = (DWORD)NtUserGetKeyState(
vKey);
ERRORTRAP(0);
ENDCALL(SHORT);
}
HBRUSH GetControlBrush(
HWND hwnd,
HDC hdc,
UINT msg)
{
BEGINCALL()
FIXUP_HANDLE(hdc);
if (hdc == (HDC)0)
MSGERROR();
retval = (DWORD)NtUserGetControlBrush(hwnd, hdc, msg);
ERRORTRAP(0);
ENDCALL(HBRUSH);
}
HBRUSH GetControlColor(
HWND hwndParent,
HWND hwndCtl,
HDC hdc,
UINT msg)
{
BEGINCALL()
FIXUP_HANDLE(hdc);
retval = (DWORD)NtUserGetControlColor(
hwndParent,
hwndCtl,
hdc,
msg);
ERRORTRAP(0);
ENDCALL(HBRUSH);
}
BOOL OpenClipboard(
HWND hwnd)
{
BOOL fEmptyClient;
BEGINCALL()
retval = (DWORD)NtUserOpenClipboard(hwnd, &fEmptyClient);
if (fEmptyClient)
ClientEmptyClipboard();
ERRORTRAP(0);
ENDCALL(BOOL);
}
static HKL hPMCachedHKL = 0;
static UINT uPMCachedCP = 0;
BOOL _PeekMessage(
LPMSG pmsg,
HWND hwnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax,
UINT wRemoveMsg,
BOOL bAnsi)
{
HKL hkl;
DWORD dwAnsi;
BEGINCALL()
#ifdef FE_SB // _PeekMessage()
if (bAnsi) {
//
// If we have pushed message for DBCS messaging, we should pass this one
// to Apps at first...
//
GET_DBCS_MESSAGE_IF_EXIST(PeekMessage,pmsg,wMsgFilterMin,wMsgFilterMax);
}
#endif // FE_SB
retval = (DWORD)NtUserPeekMessage(
pmsg,
hwnd,
wMsgFilterMin,
wMsgFilterMax,
wRemoveMsg,
&hkl);
if (retval) {
// May have a bit more work to do if this MSG is for an ANSI app
// !!! LATER if the unichar translates into multiple ANSI chars
// !!! then what??? Send two messages?? WM_SYSDEADCHAR??
if (bAnsi) {
#ifdef FE_IME // _PeekMessage()
if ((pmsg->message == WM_CHAR) || (pmsg->message == WM_DEADCHAR) ||
(pmsg->message == WM_IME_CHAR) || (pmsg->message == WM_IME_COMPOSITION)) {
#else
if ((pmsg->message == WM_CHAR) || (pmsg->message == WM_DEADCHAR)) {
#endif // FE_IME
// We need to do per-thread translation on WM_CHAR & WM_DEADCHAR
// messages in order to suppport Win95 multilingual functionality.
if (hkl != hPMCachedHKL) {
DWORD dwCodePage;
if (!GetLocaleInfoW(
(DWORD)hkl & 0xffff,
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
(LPWSTR)&dwCodePage,
sizeof(dwCodePage) / sizeof(WCHAR)
)) {
MSGERROR();
}
uPMCachedCP = dwCodePage;
hPMCachedHKL = hkl;
}
dwAnsi = 0;
if (!WideCharToMultiByte(
uPMCachedCP,
0,
(LPWSTR)&pmsg->wParam,
1,
(LPSTR)&dwAnsi,
2,
NULL,
NULL)) {
pmsg->wParam = (WPARAM)0x00;
retval = 0;
} else {
#ifdef FE_SB // _PeekMessage()
//
// Build DBCS-ware wParam. (for WM_CHAR...)
//
BUILD_DBCS_MESSAGE_TO_CLIENTA_FROM_SERVER(pmsg,dwAnsi,FALSE);
#else
// LATER!!!; in product 2 handle DBCS correctly.
#ifdef DEBUG
if ((dwAnsi == 0) || (dwAnsi > 0xFF)) {
RIPMSG1(RIP_VERBOSE, "msgW -> msgA: char = 0x%.4lX\n", dwAnsi);
}
#endif
pmsg->wParam = (WPARAM)dwAnsi;
#endif // FE_SB
}
} else {
#ifdef FE_SB // _PeekMessage()
if (RtlWCSMessageWParamCharToMB(pmsg->message, (LPDWORD)&(pmsg->wParam))) {
dwAnsi = pmsg->wParam;
//
// Build DBCS-ware wParam. (for EM_SETPASSWORDCHAR...)
//
BUILD_DBCS_MESSAGE_TO_CLIENTA_FROM_SERVER(pmsg,dwAnsi,TRUE);
} else {
retval = 0;
}
#else
if (!RtlWCSMessageWParamCharToMB(pmsg->message, (LPDWORD)&(pmsg->wParam)))
retval = 0;
#endif // FE_SB
}
#ifdef FE_SB // _PeekMessage()
} else {
//
// Only LOWORD of WPARAM is valid for WM_CHAR....
// (Mask off DBCS messaging information.)
//
BUILD_DBCS_MESSAGE_TO_CLIENTW_FROM_SERVER(pmsg->message,pmsg->wParam);
}
#else
}
#endif // FE_SB
}
#ifdef FE_SB // _PeekMessage()
ExitPeekMessage:
#endif // FE_SB
ERRORTRAP(0);
ENDCALL(BOOL);
}
BOOL RegisterHotKey(
HWND hwnd,
int id,
UINT fsModifiers,
UINT vk)
{
BEGINCALL()
if (fsModifiers & ~MOD_VALID)
RIPMSG1(RIP_ERROR, "RegisterHotKey: illegal modifiers %lX", fsModifiers);
retval = (DWORD)NtUserRegisterHotKey(
hwnd,
id,
fsModifiers,
vk);
ERRORTRAP(0);
ENDCALL(BOOL);
}
LONG _SetWindowLong(
HWND hwnd,
int nIndex,
LONG dwNewLong,
BOOL bAnsi)
{
PWND pwnd;
LONG dwOldLong;
DWORD dwCPDType = 0;
pwnd = ValidateHwnd(hwnd);
if (pwnd == NULL)
return 0;
if (TestWF(pwnd, WFDIALOGWINDOW)) {
switch (nIndex) {
case DWL_DLGPROC: // See similar case GWL_WNDGPROC
/*
* Hide the window proc from other processes
*/
if (!TestWindowProcess(pwnd)) {
RIPERR1(ERROR_ACCESS_DENIED,
RIP_WARNING,
"Access denied to hwnd (%#lx) in _SetWindowLong",
hwnd);
return 0;
}
/*
* Get the old window proc address
*/
dwOldLong = (LONG)PDLG(pwnd)->lpfnDlg;
/*
* We always store the actual address in the wndproc; We only
* give the CallProc handles to the application
*/
UserAssert(!ISCPDTAG(dwOldLong));
/*
* May need to return a CallProc handle if there is an
* Ansi/Unicode tranistion
*/
if (bAnsi != ((PDLG(pwnd)->flags & DLGF_ANSI) ? TRUE : FALSE)) {
dwCPDType |= bAnsi ? CPD_ANSI_TO_UNICODE : CPD_UNICODE_TO_ANSI;
}
/*
* If we detected a transition create a CallProc handle for
* this type of transition and this wndproc (dwOldLong)
*/
if (dwCPDType) {
DWORD cpd;
cpd = GetCPD(pwnd, dwCPDType | CPD_DIALOG, dwOldLong);
if (cpd) {
dwOldLong = cpd;
} else {
RIPMSG0(RIP_WARNING, "SetWindowLong (DWL_DLGPROC) unable to alloc CPD returning handle\n");
}
}
/*
* Convert a possible CallProc Handle into a real address.
* The app may have kept the CallProc Handle from some
* previous mixed GetClassinfo or SetWindowLong.
*
* WARNING bAnsi is modified here to represent real type of
* proc rather than if SetWindowLongA or W was called
*/
if (ISCPDTAG(dwNewLong)) {
PCALLPROCDATA pCPD;
if (pCPD = HMValidateHandleNoRip((HANDLE)dwNewLong, TYPE_CALLPROC)) {
dwNewLong = pCPD->pfnClientPrevious;
bAnsi = pCPD->wType & CPD_UNICODE_TO_ANSI;
}
}
/*
* If an app 'unsubclasses' a server-side window proc we need to
* restore everything so SendMessage and friends know that it's
* a server-side proc again. Need to check against client side
* stub addresses.
*/
PDLG(pwnd)->lpfnDlg = (WNDPROC)dwNewLong;
if (bAnsi) {
PDLG(pwnd)->flags |= DLGF_ANSI;
} else {
PDLG(pwnd)->flags &= ~DLGF_ANSI;
}
return dwOldLong;
case DWL_MSGRESULT:
case DWL_USER:
break;
default:
if (nIndex >= 0 && nIndex < DLGWINDOWEXTRA) {
RIPERR0(ERROR_PRIVATE_DIALOG_INDEX, RIP_VERBOSE, "");
return 0;
}
}
}
BEGINCALL()
/*
* If this is a listbox window and the listbox structure has
* already been initialized, don't allow the app to override the
* owner draw styles. We need to do this since Windows only
* used the styles in creating the structure, but we also use
* them to determine if strings need to be thunked.
*
*/
if (nIndex == GWL_STYLE &&
GETFNID(pwnd) == FNID_LISTBOX &&
((PLBWND)pwnd)->pLBIV != NULL &&
(!TestWindowProcess(pwnd) || ((PLBWND)pwnd)->pLBIV->fInitialized)) {
#ifdef DEBUG
LONG dwDebugLong = dwNewLong;
#endif
dwNewLong &= ~(LBS_OWNERDRAWFIXED |
LBS_OWNERDRAWVARIABLE |
LBS_HASSTRINGS);
dwNewLong |= pwnd->style & (LBS_OWNERDRAWFIXED |
LBS_OWNERDRAWVARIABLE |
LBS_HASSTRINGS);
#ifdef DEBUG
if (dwDebugLong != dwNewLong) {
RIPMSG0(RIP_WARNING, "SetWindowLong can't change LBS_OWNERDRAW* or LBS_HASSTRINGS.");
}
#endif
}
retval = (DWORD)NtUserSetWindowLong(
hwnd,
nIndex,
dwNewLong,
bAnsi);
ERRORTRAP(0);
ENDCALL(LONG);
}
BOOL TranslateMessageEx(
CONST MSG *pmsg,
UINT flags)
{
BEGINCALL()
/*
* Don't bother going over to the kernel if this isn't
* key message.
*/
switch (pmsg->message) {
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
break;
default:
if (pmsg->message & RESERVED_MSG_BITS) {
RIPERR1(ERROR_INVALID_PARAMETER,
RIP_WARNING,
"Invalid parameter \"pmsg->message\" (%ld) to TranslateMessageEx",
pmsg->message);
}
MSGERROR();
}
retval = (DWORD)NtUserTranslateMessage(
pmsg,
flags);
ERRORTRAP(0);
ENDCALL(BOOL);
}
BOOL TranslateMessage(
CONST MSG *pmsg)
{
#ifdef FE_IME //@TK
if ( LOWORD(pmsg->wParam) == VK_PROCESSKEY ) {
BOOL fResult;
//
// This vkey should be processed by IME
//
fResult = ImmTranslateMessage( pmsg->hwnd,
pmsg->message,
pmsg->wParam,
pmsg->lParam );
if ( fResult )
return fResult;
}
#endif
return(TranslateMessageEx(pmsg, 0));
}
BOOL RedrawWindow(
HWND hwnd,
CONST RECT *prcUpdate,
HRGN hrgnUpdate,
UINT flags)
{
BEGINCALL()
if (hrgnUpdate != NULL) {
FIXUP_HANDLE(hrgnUpdate);
if (hrgnUpdate == NULL)
MSGERROR();
}
retval = (DWORD)NtUserRedrawWindow(
hwnd,
prcUpdate,
hrgnUpdate,
flags);
ERRORTRAP(0);
ENDCALL(BOOL);
}
BOOL SetWindowRgn(
HWND hwnd,
HRGN hrgn,
BOOL bRedraw)
{
BEGINCALL()
retval = (DWORD)NtUserSetWindowRgn(
hwnd,
hrgn,
bRedraw);
if (retval) {
DeleteObject(hrgn);
}
ERRORTRAP(0);
ENDCALL(BOOL);
}
BOOL InternalGetWindowText(
HWND hwnd,
LPWSTR pString,
int cchMaxCount)
{
BEGINCALL()
retval = (DWORD)NtUserInternalGetWindowText(
hwnd,
pString,
cchMaxCount);
if (!retval) {
*pString = (WCHAR)0;
}
ERRORTRAP(0);
ENDCALL(BOOL);
}
int ToUnicode(
UINT wVirtKey,
UINT wScanCode,
PBYTE pKeyState,
LPWSTR pwszBuff,
int cchBuff,
UINT wFlags)
{
BEGINCALL()
retval = (DWORD)NtUserToUnicodeEx(
wVirtKey,
wScanCode,
pKeyState,
pwszBuff,
cchBuff,
wFlags,
(HKL)NULL);
if (!retval) {
*pwszBuff = L'\0';
}
ERRORTRAP(0);
ENDCALL(int);
}
int ToUnicodeEx(
UINT wVirtKey,
UINT wScanCode,
PBYTE pKeyState,
LPWSTR pwszBuff,
int cchBuff,
UINT wFlags,
HKL hkl)
{
BEGINCALL()
retval = (DWORD)NtUserToUnicodeEx(
wVirtKey,
wScanCode,
pKeyState,
pwszBuff,
cchBuff,
wFlags,
hkl);
if (!retval) {
*pwszBuff = L'\0';
}
ERRORTRAP(0);
ENDCALL(int);
}
BOOL SetWindowStationUser(
HWINSTA hwinsta,
PLUID pluidUser,
PSID psidUser,
DWORD cbsidUser)
{
VOID Logon(BOOL fLogon);
LUID luidNone = { 0, 0 };
BEGINCALL()
retval = (DWORD)NtUserSetWindowStationUser(hwinsta,
pluidUser,
psidUser,
cbsidUser);
/*
* Load global atoms if the logon succeeded
*/
if (retval) {
if (!RtlEqualLuid(pluidUser,&luidNone)) {
/*
* Reset console and load Nls data.
*/
Logon(TRUE);
} else {
/*
* Flush NLS cache.
*/
Logon(FALSE);
}
retval = TRUE;
}
ERRORTRAP(0);
ENDCALL(BOOL);
}
BOOL SetSystemCursor(
HCURSOR hcur,
DWORD id)
{
BEGINCALL()
if (hcur == NULL) {
hcur = (HANDLE)LoadIcoCur(NULL,
MAKEINTRESOURCE(id),
RT_CURSOR,
0,
0,
LR_DEFAULTSIZE);
if (hcur == NULL)
MSGERROR();
}
retval = (DWORD)NtUserSetSystemCursor(hcur, id);
ERRORTRAP(0);
ENDCALL(BOOL);
}
HCURSOR FindExistingCursorIcon(
LPWSTR pszModName,
LPCWSTR pszResName,
PCURSORFIND pcfSearch)
{
IN_STRING strModName;
IN_STRING strResName;
/*
* Make sure cleanup will work successfully
*/
strModName.fAllocated = FALSE;
strResName.fAllocated = FALSE;
BEGINCALL()
if (pszModName == NULL)
pszModName = szUSER32;
COPYLPWSTR(&strModName, pszModName);
COPYLPWSTRID(&strResName, pszResName);
retval = (DWORD)NtUserFindExistingCursorIcon(strModName.pstr,
strResName.pstr,
pcfSearch);
ERRORTRAP(0);
CLEANUPLPWSTR(strModName);
CLEANUPLPWSTR(strResName);
ENDCALL(HCURSOR);
}
BOOL _SetCursorIconData(
HCURSOR hCursor,
PCURSORDATA pcur,
DWORD cbData)
{
IN_STRING strModName;
IN_STRING strResName;
/*
* Make sure cleanup will work successfully
*/
strModName.fAllocated = FALSE;
strResName.fAllocated = FALSE;
BEGINCALL()
COPYLPWSTROPT(&strModName, pcur->lpModName);
COPYLPWSTRIDOPT(&strResName, pcur->lpName);
retval = (DWORD)NtUserSetCursorIconData(hCursor,
strModName.pstr,
strResName.pstr,
pcur,
cbData);
ERRORTRAP(0);
CLEANUPLPWSTR(strModName);
CLEANUPLPWSTR(strResName);
ENDCALL(BOOL);
}
BOOL _DefSetText(
HWND hwnd,
LPCWSTR lpszText,
BOOL bAnsi)
{
LARGE_STRING str;
BEGINCALL()
if (lpszText) {
if (bAnsi)
RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&str,
(LPSTR)lpszText, (UINT)-1);
else
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&str,
lpszText, (UINT)-1);
}
retval = (DWORD)NtUserDefSetText(
hwnd,
lpszText ? &str : NULL);
ERRORTRAP(0);
ENDCALL(BOOL);
}
DWORD _GetListboxString(
HWND hwnd,
UINT msg,
DWORD wParam,
DWORD cch,
LPTSTR pString,
DWORD xParam,
DWORD xpfn,
BOOL bAnsi)
{
BOOL bNotString;
LARGE_STRING str;
BEGINCALL()
str.bAnsi = bAnsi;
if (bAnsi)
str.MaximumLength = cch;
else
str.MaximumLength = cch * sizeof(WCHAR);
str.Buffer = (PVOID)pString;
retval = (DWORD)NtUserGetListboxString(
hwnd,
msg,
wParam,
&str,
xParam,
xpfn,
&bNotString);
if (bNotString) {
if (bAnsi) {
retval = sizeof(DWORD)/sizeof(CHAR); // 4 CHARs just like win3.1
} else {
retval = sizeof(DWORD)/sizeof(WCHAR); // 2 WCHARs
}
}
ERRORTRAP(0);
ENDCALL(DWORD);
}
HWND _CreateWindowEx(
DWORD dwExStyle,
LPCTSTR pClassName,
LPCTSTR pWindowName,
DWORD dwStyle,
int x,
int y,
int nWidth,
int nHeight,
HWND hwndParent,
HMENU hmenu,
HANDLE hModule,
LPVOID pParam,
DWORD dwFlags,
LPDWORD pWOW)
{
LARGE_IN_STRING strClassName;
LARGE_STRING strWindowName;
PLARGE_STRING pstrClassName;
PLARGE_STRING pstrWindowName;
DWORD dwExpWinVerAndFlags;
/*
* Make sure cleanup will work successfully
*/
strClassName.fAllocated = FALSE;
/*
* To be compatible with Chicago, we test the validity of
* the ExStyle bits and fail if any invalid bits are found.
* And for backward compatibilty with NT apps, we only fail for
* new apps (post NT 3.1).
*/
// BOGUS
if (dwExStyle & 0x00000800L) {
dwExStyle |= WS_EX_TOOLWINDOW;
dwExStyle &= 0xfffff7ffL;
}
dwExpWinVerAndFlags = (DWORD)(WORD)GETEXPWINVER(hModule);
if ((dwExStyle & ~WS_EX_VALID40) && (dwExpWinVerAndFlags >= VER40) ) {
RIPMSG0(RIP_ERROR, "Invalid 4.0 ExStyle\n");
return NULL;
}
{
BOOL fMDIchild = FALSE;
MDICREATESTRUCT mdics;
HMENU hSysMenu;
BEGINCALL()
if ((fMDIchild = (BOOL)(dwExStyle & WS_EX_MDICHILD))) {
SHORTCREATE sc;
PWND pwndParent;
pwndParent = ValidateHwnd(hwndParent);
if ((pwndParent == NULL) || (GETFNID(pwndParent) != FNID_MDICLIENT)) {
RIPMSG0(RIP_ERROR, "Invalid parent for MDI child window\n");
MSGERROR();
}
mdics.lParam = (LPARAM)pParam;
pParam = &mdics;
mdics.x = sc.x = x;
mdics.y = sc.y = y;
mdics.cx = sc.cx = nWidth;
mdics.cy = sc.cy = nHeight;
mdics.style = sc.style = dwStyle;
mdics.hOwner = hModule;
mdics.szClass = pClassName;
mdics.szTitle = pWindowName;
if (!CreateMDIChild(&sc, &mdics, dwExpWinVerAndFlags, &hSysMenu, pwndParent))
MSGERROR();
x = sc.x;
y = sc.y;
nWidth = sc.cx;
nHeight = sc.cy;
dwStyle = sc.style;
hmenu = sc.hMenu;
}
/*
* Set up class and window name. If the window name is an
* ordinal, make it look like a string so the callback thunk
* will be able to ensure it is in the correct format.
*/
pstrWindowName = NULL;
if (dwFlags & CW_FLAGS_ANSI) {
dwExStyle = dwExStyle | WS_EX_ANSICREATOR;
if (HIWORD(pClassName)) {
RtlCaptureLargeAnsiString(&strClassName,
(PCHAR)pClassName, (UINT)-1, TRUE);
pstrClassName = (PLARGE_STRING)strClassName.pstr;
} else
pstrClassName = (PLARGE_STRING)pClassName;
if (pWindowName != NULL) {
if (*(PBYTE)pWindowName == 0xff) {
strWindowName.bAnsi = TRUE;
strWindowName.Buffer = (PVOID)pWindowName;
strWindowName.Length = 3;
strWindowName.MaximumLength = 3;
} else
RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&strWindowName,
(LPSTR)pWindowName, (UINT)-1);
pstrWindowName = &strWindowName;
}
} else {
if (HIWORD(pClassName)) {
RtlInitLargeUnicodeString(
(PLARGE_UNICODE_STRING)&strClassName.strCapture,
pClassName, (UINT)-1);
pstrClassName = (PLARGE_STRING)&strClassName.strCapture;
} else
pstrClassName = (PLARGE_STRING)pClassName;
if (pWindowName != NULL) {
if (pWindowName != NULL &&
*(PWORD)pWindowName == 0xffff) {
strWindowName.bAnsi = FALSE;
strWindowName.Buffer = (PVOID)pWindowName;
strWindowName.Length = 4;
strWindowName.MaximumLength = 4;
} else
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&strWindowName,
pWindowName, (UINT)-1);
pstrWindowName = &strWindowName;
}
}
if (dwFlags & CW_FLAGS_DIFFHMOD) {
dwExpWinVerAndFlags |= CW_FLAGS_DIFFHMOD;
}
retval = (DWORD)NtUserCreateWindowEx(
dwExStyle,
pstrClassName,
pstrWindowName,
dwStyle,
x,
y,
nWidth,
nHeight,
hwndParent,
hmenu,
hModule,
pParam,
dwExpWinVerAndFlags,
pWOW);
// If this is an MDI child, we need to do some more to complete the
// process of creating an MDI child.
if (retval && fMDIchild) {
MDICompleteChildCreation((HWND)retval, hSysMenu, ((dwStyle & WS_VISIBLE) != 0L), (BOOL)((dwStyle & WS_DISABLED)!= 0L));
}
ERRORTRAP(0);
CLEANUPLPSTRW(strClassName);
ENDCALL(HWND);
}
}
HKL _LoadKeyboardLayoutEx(
HANDLE hFile,
UINT offTable,
HKL hkl,
LPCTSTR pwszKL,
UINT KbdInputLocale,
UINT Flags)
{
IN_STRING strKL;
/*
* Make sure cleanup will work successfully
*/
strKL.fAllocated = FALSE;
BEGINCALL()
FIRSTCOPYLPWSTR(&strKL, pwszKL);
retval = (DWORD)NtUserLoadKeyboardLayoutEx(
hFile,
offTable,
hkl,
strKL.pstr,
KbdInputLocale,
Flags);
ERRORTRAP(0);
CLEANUPLPWSTR(strKL);
ENDCALL(HKL);
}
int GetKeyboardLayoutList(
int nItems,
HKL *lpBuff)
{
BEGINCALL()
if (!lpBuff) {
nItems = 0;
}
retval = (DWORD)NtUserGetKeyboardLayoutList(nItems, lpBuff);
ERRORTRAP(0);
ENDCALL(int);
}
/*
* Message thunks
*/
MESSAGECALL(fnINWPARAMCHAR)
{
BEGINCALL()
/*
* The server always expects the characters to be unicode so
* if this was generated from an ANSI routine convert it to Unicode
*/
if (bAnsi) {
if (msg == WM_CHARTOITEM || msg == WM_MENUCHAR) {
DWORD dwT = wParam & 0xFFFF; // mask of caret pos
RtlMBMessageWParamCharToWCS(msg, &dwT); // convert key portion
UserAssert(HIWORD(dwT) == 0);
wParam = MAKELONG(LOWORD(dwT),HIWORD(wParam)); // rebuild pos & key wParam
} else {
RtlMBMessageWParamCharToWCS(msg, &wParam);
}
}
retval = (DWORD)NtUserfnDWORD(
hwnd,
msg,
wParam,
lParam,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
#ifdef FE_SB // fnINWPARAMDBCSCHAR()
MESSAGECALL(fnINWPARAMDBCSCHAR)
{
BEGINCALL()
/*
* The server always expects the characters to be unicode so
* if this was generated from an ANSI routine convert it to Unicode
*/
if (bAnsi) {
/*
* Setup for DBCS Messaging..
*/
BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(msg,wParam,TRUE);
/*
* Convert DBCS/SBCS to Unicode...
*/
RtlMBMessageWParamCharToWCS(msg, &wParam);
}
retval = (DWORD)NtUserfnDWORD(
hwnd,
msg,
wParam,
lParam,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
#endif // FE_SB
MESSAGECALL(fnCOPYGLOBALDATA)
{
PBYTE pData;
BEGINCALL()
if (wParam == 0) {
MSGERROR();
}
USERGLOBALLOCK((HGLOBAL)lParam, pData);
retval = (DWORD)NtUserfnCOPYGLOBALDATA(
hwnd,
msg,
wParam,
(LONG)pData,
xParam,
xpfnProc,
bAnsi);
USERGLOBALUNLOCK((HGLOBAL)lParam);
UserGlobalFree((HGLOBAL)lParam);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnPAINT)
{
if (wParam) {
DWORD dwT;
dwT = (DWORD)wParam;
FIXUP_HANDLE((HDC)dwT);
if (dwT) {
wParam = dwT;
}
}
BEGINCALL()
retval = (DWORD)NtUserfnDWORD(
hwnd,
msg,
wParam,
lParam,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINPAINTCLIPBRD)
{
LPPAINTSTRUCT lpps;
PAINTSTRUCT ps;
HDC hdcr = (HDC)0;
USERGLOBALLOCK((HGLOBAL)lParam, lpps);
if (lpps) {
hdcr = lpps->hdc;
FIXUP_HANDLE(hdcr);
}
BEGINCALL()
/*
* Copy the paint structure over as is then grab a server DC
*/
if (lpps) {
ps = *lpps;
if (!(ps.hdc = hdcr))
UserAssert(0);
retval = (DWORD)NtUserfnINPAINTCLIPBRD(
hwnd,
msg,
wParam,
(LPARAM)&ps,
xParam,
xpfnProc,
bAnsi);
USERGLOBALUNLOCK((HGLOBAL)lParam);
} else {
UserAssert(0);
}
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINSIZECLIPBRD)
{
LPRECT lprc;
BEGINCALL()
USERGLOBALLOCK((HGLOBAL)lParam, lprc);
if (lprc) {
retval = (DWORD)NtUserfnINSIZECLIPBRD(
hwnd,
msg,
wParam,
(LPARAM)lprc,
xParam,
xpfnProc,
bAnsi);
USERGLOBALUNLOCK((HGLOBAL)lParam);
} else {
UserAssert(0);
}
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINLPCREATESTRUCT)
{
BEGINCALL()
retval = (DWORD)NtUserfnINLPCREATESTRUCT(
hwnd,
msg,
wParam,
lParam,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINLPMDICREATESTRUCT)
{
LPMDICREATESTRUCT pmdics = (LPMDICREATESTRUCT)lParam;
IN_STRING strClass;
IN_STRING strTitle;
/*
* Make sure cleanup will work successfully
*/
strClass.fAllocated = FALSE;
strTitle.fAllocated = FALSE;
BEGINCALL()
/*
* wParam isn't used... but we use it from the client to the server
* to pass dwExpWinVer.
*/
wParam = GETEXPWINVER(pmdics->hOwner);
if (bAnsi) {
COPYLPSTRIDW(&strClass, pmdics->szClass);
COPYLPSTROPTW(&strTitle, pmdics->szTitle);
} else {
COPYLPWSTRID(&strClass, pmdics->szClass);
COPYLPWSTROPT(&strTitle, pmdics->szTitle);
}
retval = (DWORD)NtUserfnINLPMDICREATESTRUCT(
hwnd,
msg,
wParam,
lParam,
strClass.pstr,
strTitle.pstr,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
CLEANUPLPSTRW(strClass);
CLEANUPLPSTRW(strTitle);
ENDCALL(DWORD);
}
MESSAGECALL(fnINSTRING)
{
LPTSTR pstr = (LPTSTR)lParam;
LARGE_STRING str;
BEGINCALL()
if (bAnsi) {
RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&str,
(LPSTR)pstr, (UINT)-1);
} else {
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&str,
pstr, (UINT)-1);
}
retval = (DWORD)NtUserfnINSTRING(
hwnd,
msg,
wParam,
(LPARAM)&str,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINSTRINGNULL)
{
LPTSTR pstr = (LPTSTR)lParam;
LARGE_STRING str;
BEGINCALL()
if (pstr) {
if (bAnsi) {
RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&str,
(LPSTR)pstr, (UINT)-1);
} else {
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&str,
pstr, (UINT)-1);
}
pstr = (LPTSTR)&str;
}
retval = (DWORD)NtUserfnINSTRINGNULL(
hwnd,
msg,
wParam,
(LPARAM)pstr,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINDEVICECHANGE)
{
VOID *pVar = (VOID *)lParam;
LPTSTR pstr = (LPTSTR)lParam;
BOOL fString = (BOOL)((wParam & 0xc000) == 0xc000);
LARGE_STRING str;
BEGINCALL()
if (pstr && fString) {
if (bAnsi) {
RtlInitLargeAnsiString((PLARGE_ANSI_STRING)&str,
(LPSTR)pstr, (UINT)-1);
} else {
RtlInitLargeUnicodeString((PLARGE_UNICODE_STRING)&str,
pstr, (UINT)-1);
}
pVar = (VOID *)(&str);
}
retval = (DWORD)NtUserfnINDEVICECHANGE(
hwnd,
msg,
wParam,
(LPARAM)(pVar),
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINLPDRAWITEMSTRUCT)
{
LPDRAWITEMSTRUCT pdrawitemstruct = (LPDRAWITEMSTRUCT)lParam;
DRAWITEMSTRUCT drawitemstruct;
HDC hdcr;
hdcr = pdrawitemstruct->hDC;
FIXUP_HANDLE(hdcr);
if (hdcr == (HDC)0)
MSGERROR();
BEGINCALL()
drawitemstruct = *pdrawitemstruct;
drawitemstruct.hDC = hdcr;
retval = (DWORD)NtUserfnINLPDRAWITEMSTRUCT(
hwnd,
msg,
wParam,
(LPARAM)&drawitemstruct,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnWMCTLCOLOR)
{
/*
* In case the app sets some attrs first flush them to the server because
* later we copy the server attrs back to the client side
* Compute Associates Simply Accounting does this
*/
HDC hdcr = (HDC)wParam;
FIXUP_HANDLE (hdcr);
if (hdcr == (HDC)0)
MSGERROR();
BEGINCALL()
// convert the local dc to an engine dc. Also add the dc to the quick lookup
// link so it is easy for a server handle to be converted to a client handle.
// Don't forget to remove this link at the end of this call in order to keep
// the list as short as possible. Usually no more than one long.
wParam = (DWORD)hdcr;
retval = (DWORD)NtUserfnDWORD(
hwnd,
msg,
wParam,
lParam,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnOUTSTRING)
{
LARGE_STRING str;
BEGINCALL()
str.bAnsi = bAnsi;
str.MaximumLength = wParam;
str.Buffer = (PVOID)lParam;
if (!bAnsi) {
str.MaximumLength *= sizeof(WCHAR);
}
retval = (DWORD)NtUserfnOUTSTRING(
hwnd,
msg,
wParam,
(LPARAM)&str,
xParam,
xpfnProc,
bAnsi);
if (!retval) {
/*
* A dialog function returning FALSE means no text to copy out,
* but an empty string also has retval == 0: put a null char in
* pstr for the latter case.
*/
if (wParam != 0) {
if (bAnsi) {
LPSTR pstrA = (LPSTR)lParam;
*pstrA = 0;
} else {
*(LPWSTR)lParam = 0;
}
}
}
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINCNTOUTSTRING)
{
LARGE_STRING str;
WORD cchOriginal;
LPTSTR pstr = (LPTSTR)lParam;
BEGINCALL()
str.bAnsi = bAnsi;
cchOriginal = *(LPWORD)pstr;
str.MaximumLength = cchOriginal;
if (cchOriginal == 0) {
RIPMSG0(RIP_WARNING, "fnINCNTOUTSTRING asking for 0 characters back\n");
MSGERROR();
}
str.Length = 0;
str.Buffer = (LPBYTE)lParam;
if (!bAnsi) {
str.MaximumLength *= sizeof(WCHAR);
}
retval = (DWORD)NtUserfnINCNTOUTSTRING(
hwnd,
msg,
wParam,
(LPARAM)&str,
xParam,
xpfnProc,
bAnsi);
if (!retval) {
/*
* A dialog function returning FALSE means no text to copy out,
* but an empty string also has retval == 0: put a null char in
* pstr for the latter case.
*/
if (bAnsi) {
LPSTR pstrA = (LPSTR)pstr;
*pstrA = 0;
} else {
*pstr = 0;
}
}
ERRORTRAP(0);
ENDCALL(DWORD);
}
MESSAGECALL(fnINCNTOUTSTRINGNULL)
{
LARGE_STRING str;
BEGINCALL()
if (wParam < 2) { // This prevents a possible GP
MSGERROR();
}
str.bAnsi = bAnsi;
str.MaximumLength = wParam;
str.Buffer = (LPBYTE)lParam;
if (!bAnsi) {
str.MaximumLength *= sizeof(WCHAR);
}
*((LPWSTR)str.Buffer) = 0; // mark incase message is not handled
retval = (DWORD)NtUserfnINCNTOUTSTRINGNULL(
hwnd,
msg,
wParam,
(LPARAM)&str,
xParam,
xpfnProc,
bAnsi);
ERRORTRAP(0);
ENDCALL(DWORD);
}
/*
* Hook thunks
*/
DWORD fnHkINLPCBTCREATESTRUCT(
UINT msg,
DWORD wParam,
LPCBT_CREATEWND pcbt,
DWORD xpfnProc,
BOOL bAnsi)
{
LARGE_IN_STRING strName;
IN_STRING strClass;
LPWSTR lpszName;
/*
* Make sure cleanup will work successfully
*/
strName.fAllocated = FALSE;
strClass.fAllocated = FALSE;
BEGINCALLCONNECT();
/*
* Rebase in case lpszName points to desktop memory.
*/
lpszName = (LPWSTR)pcbt->lpcs->lpszName;
if ((PVOID)lpszName > MM_HIGHEST_USER_ADDRESS)
lpszName = (LPWSTR)((PBYTE)lpszName - GetClientInfo()->ulClientDelta);
if (bAnsi) {
FIRSTLARGECOPYLPSTROPTW(&strName, (LPSTR)lpszName);
COPYLPSTRIDW(&strClass, pcbt->lpcs->lpszClass);
} else {
FIRSTLARGECOPYLPWSTROPT(&strName, lpszName);
COPYLPWSTRID(&strClass, pcbt->lpcs->lpszClass);
}
retval = (DWORD)NtUserfnHkINLPCBTCREATESTRUCT(
msg,
wParam,
pcbt,
strName.pstr,
strClass.pstr,
xpfnProc);
ERRORTRAP(0);
CLEANUPLPSTRW(strName);
CLEANUPLPSTRW(strClass);
ENDCALL(DWORD);
}
LONG BroadcastSystemMessageWorker(
DWORD dwFlags,
LPDWORD lpdwRecipients,
UINT message,
WPARAM wParam,
LPARAM lParam,
BOOL fAnsi)
{
DWORD dwRecipients;
/*
* Prevent apps from setting hi 16 bits so we can use them internally.
*/
if (message & RESERVED_MSG_BITS) {
RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid message (%x) for BroadcastSystemMessage\n", message);
return(0);
}
if (dwFlags & ~BSF_VALID) {
RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid dwFlags (%x) for BroadcastSystemMessage\n", dwFlags);
return(0);
}
//
// Check if the message number is in the private message range.
// If so, do not send it to Win4.0 windows.
// (This is required because apps like SimCity broadcast a message
// that has the value 0x500 and that confuses MsgSrvr's
// MSGSRVR_NOTIFY handler.
//
if ((message >= WM_USER) && (message < 0xC000))
{
RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid message (%x) for BroadcastSystemMessage\n", message);
return(0L);
}
if (dwFlags & BSF_FORCEIFHUNG)
dwFlags |= BSF_NOHANG;
//
// If BSF_QUERY or message has a pointer, it can not be posted.
//
if (dwFlags & BSF_QUERY)
{
#ifdef DEBUG
if (dwFlags & BSF_POSTMESSAGE)
{
RIPMSG0(RIP_ERROR, "BroadcastSystemMessage: Can't post queries\n");
}
#endif
dwFlags &= ~(BSF_POSTMESSAGE); // Strip the BSF_POSTMESSAGE flag.
}
if (dwFlags & BSF_POSTMESSAGE) {
if (NtUserCallTwoParam(message, wParam, SFI_ISSYNCONLYMESSAGE)) {
RIPMSG0(RIP_ERROR, "BroadcastSystemMessage: Can't post messages with pointers\n");
dwFlags &= ~(BSF_POSTMESSAGE); // Strip the BSF_POSTMESSAGE flag.
}
}
// Let us find out who the intended recipients are.
if (lpdwRecipients != NULL)
dwRecipients = *lpdwRecipients;
else
dwRecipients = BSM_ALLCOMPONENTS;
// if they want all components, add the corresponding bits
if ((dwRecipients & BSM_COMPONENTS) == BSM_ALLCOMPONENTS)
dwRecipients |= (BSM_VXDS | BSM_NETDRIVER | BSM_INSTALLABLEDRIVERS |
BSM_APPLICATIONS);
if (dwRecipients & ~BSM_VALID) {
RIPERR1(ERROR_INVALID_PARAMETER, RIP_WARNING, "invalid dwRecipients (%x) for BroadcastSystemMessage\n", dwRecipients);
return(0);
}
//
// Check if this is a WM_USERCHANGED message; If so, we want to reload
// the per-user settings before anyone else sees this message.
//
// LATER -- FritzS
// if (uiMessage == WM_USERCHANGED)
// ReloadPerUserSettings();
// Does this need to be sent to all apps?
if (dwRecipients & BSM_APPLICATIONS)
{
BROADCASTSYSTEMMSGPARAMS bsmParams;
bsmParams.dwFlags = dwFlags;
bsmParams.dwRecipients = dwRecipients;
return CsSendMessage(GetDesktopWindow(), message, wParam, lParam,
(DWORD)&bsmParams, FNID_SENDMESSAGEBSM, fAnsi);
}
return -1;
}