Leaked source code of windows server 2003
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.
 
 
 
 
 
 

1781 lines
51 KiB

/***************************** Module Header ******************************\
* Module Name: ntcftxt.h
*
* Copyright (c) 1985 - 1999, Microsoft Corporation
*
* Kernel call forward stubs with text arguments
*
* Each function will be created with two flavors Ansi and Unicode
*
* 06-Jan-1992 IanJa Moved from cf.h
* 18-Mar-1995 JimA Ported from cftxt.h
\**************************************************************************/
#ifdef UNICODE
#define IS_ANSI FALSE
#ifndef _UNICODE
#define _UNICODE
#endif
#else
#define IS_ANSI TRUE
#undef _UNICODE
#endif
#include <tchar.h>
#include "ntsend.h"
HWND TEXT_FN(InternalFindWindowEx)(
HWND hwndParent,
HWND hwndChild,
LPCTSTR pClassName,
LPCTSTR pWindowName,
DWORD dwFlag)
{
IN_STRING strClass;
IN_STRING strWindow;
/*
* Make sure cleanup will work successfully
*/
strClass.fAllocated = FALSE;
strWindow.fAllocated = FALSE;
BEGINCALL()
FIRSTCOPYLPTSTRIDOPT(&strClass, pClassName);
COPYLPTSTROPT(&strWindow, pWindowName);
retval = (ULONG_PTR)NtUserFindWindowEx(
hwndParent,
hwndChild,
strClass.pstr,
strWindow.pstr,
dwFlag);
ERRORTRAP(0);
CLEANUPLPTSTR(strClass);
CLEANUPLPTSTR(strWindow);
ENDCALL(HWND);
}
#ifdef UNICODE
FUNCLOG4(LOG_GENERAL, HWND, WINUSERAPI, FindWindowExW, HWND, hwndParent, HWND, hwndChild, LPCTSTR, pClassName, LPCTSTR, pWindowName)
#else
FUNCLOG4(LOG_GENERAL, HWND, WINUSERAPI, FindWindowExA, HWND, hwndParent, HWND, hwndChild, LPCTSTR, pClassName, LPCTSTR, pWindowName)
#endif // UNICODE
HWND FindWindowEx(
HWND hwndParent,
HWND hwndChild,
LPCTSTR pClassName,
LPCTSTR pWindowName)
{
return TEXT_FN(InternalFindWindowEx)(hwndParent, hwndChild, pClassName, pWindowName, FW_BOTH);
}
#ifdef UNICODE
FUNCLOG2(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, FindWindowW, LPCTSTR, pClassName, LPCTSTR, pWindowName)
#else
FUNCLOG2(LOG_GENERAL, HWND, DUMMYCALLINGTYPE, FindWindowA, LPCTSTR, pClassName, LPCTSTR, pWindowName)
#endif // UNICODE
HWND FindWindow(
LPCTSTR pClassName,
LPCTSTR pWindowName)
{
return TEXT_FN(InternalFindWindowEx)(NULL, NULL, pClassName, pWindowName, FW_BOTH);
}
BOOL GetClassInfoEx(
HINSTANCE hmod,
LPCTSTR pszClassName,
LPWNDCLASSEX pwc)
{
IN_STRING strClassName;
LPWSTR pszMenuName;
DWORD Error;
HMODULE hDllMod = NULL;
#ifdef LAZY_CLASS_INIT
LazyInitClasses();
#endif
/*
* Make sure cleanup will work successfully.
*/
strClassName.fAllocated = FALSE;
BEGINCALL_CLASSV()
FIRSTCOPYLPTSTRID(&strClassName, lpClassNameVer);
TryAgain:
retval = (DWORD)NtUserGetClassInfoEx(hmod,
strClassName.pstr,
(LPWNDCLASSEXW)pwc,
&pszMenuName,
IS_ANSI);
/*
* If we failed to find the class specified, let's register it and
* try again.
*/
if (!retval &&
!bRegistered &&
lpDllName != NULL &&
((Error = NtCurrentTeb()->LastErrorValue) == ERROR_CANNOT_FIND_WND_CLASS
|| Error == ERROR_CLASS_DOES_NOT_EXIST)) {
IN_STRING strClassNameNoVer;
FIRSTCOPYLPTSTRID(&strClassNameNoVer, pszClassName);
bRegistered = VersionRegisterClass(strClassNameNoVer.pstr->Buffer, lpDllName, lpActivationContext, &hDllMod);
CLEANUPLPTSTR(strClassNameNoVer);
if (bRegistered) {
goto TryAgain;
}
}
if (!retval && hDllMod != NULL) {
FREE_LIBRARY_SAVE_ERROR(hDllMod);
hDllMod = NULL;
}
if (lpActivationContext != NULL) {
RtlReleaseActivationContext(lpActivationContext);
lpActivationContext = NULL;
}
if (retval) {
/*
* Update these pointers so they point to something real.
* pszMenuName is actually just the pointer the app originally
* passed to us.
*/
pwc->lpszMenuName = (LPTSTR)pszMenuName;
pwc->lpszClassName = pszClassName;
}
ERRORTRAP(0);
CLEANUPLPTSTR(strClassName);
ENDCALL(BOOL);
}
BOOL GetClassInfo(
HINSTANCE hmod,
LPCTSTR pszClassName,
LPWNDCLASS pwc)
{
WNDCLASSEX WndClass;
BOOL retval;
retval = GetClassInfoEx(hmod, pszClassName, &WndClass);
if (retval) {
/*
* Move the info from the WNDCLASSEX to the WNDCLASS structure. On
* 64-bit plaforms we'll have 32 bits of padding between style and
* lpfnWndProc in WNDCLASS, so start the copy from the first 64-bit
* aligned field and hand copy the rest.
*/
RtlCopyMemory(&(pwc->lpfnWndProc),
&(WndClass.lpfnWndProc),
sizeof(WNDCLASS) - FIELD_OFFSET(WNDCLASS, lpfnWndProc));
pwc->style = WndClass.style;
}
return retval;
}
#ifdef UNICODE
FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetClipboardFormatNameW, UINT, wFormat, LPTSTR, pFormatName, int, chMaxCount)
#else
FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetClipboardFormatNameA, UINT, wFormat, LPTSTR, pFormatName, int, chMaxCount)
#endif // UNICODE
int GetClipboardFormatName(
UINT wFormat,
LPTSTR pFormatName,
int chMaxCount)
{
LPWSTR lpszReserve;
BEGINCALL()
#ifdef UNICODE
lpszReserve = pFormatName;
#else
lpszReserve = UserLocalAlloc(0, chMaxCount * sizeof(WCHAR));
if (!lpszReserve) {
return 0;
}
#endif
retval = (DWORD)NtUserGetClipboardFormatName(wFormat,
lpszReserve,
chMaxCount);
#ifndef UNICODE
if (retval) {
/*
* Do not copy out more than the requested byte count 'chMaxCount'.
* Set retval to reflect the number of ANSI bytes.
*/
retval = WCSToMB(lpszReserve,
(UINT)retval,
&pFormatName,
chMaxCount - 1,
FALSE);
pFormatName[retval] = '\0';
}
UserLocalFree(lpszReserve);
#endif
ERRORTRAP(0);
ENDCALL(int);
}
#ifdef UNICODE
FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetKeyNameTextW, LONG, lParam, LPTSTR, pString, int, cchSize)
#else
FUNCLOG3(LOG_GENERAL, int, DUMMYCALLINGTYPE, GetKeyNameTextA, LONG, lParam, LPTSTR, pString, int, cchSize)
#endif // UNICODE
int GetKeyNameText(
LONG lParam,
LPTSTR pString,
int cchSize)
{
LPWSTR lpszReserve;
BEGINCALL()
#ifdef UNICODE
lpszReserve = pString;
#else
lpszReserve = UserLocalAlloc(0, cchSize * sizeof(WCHAR));
if (!lpszReserve) {
return 0;
}
#endif
retval = (DWORD)NtUserGetKeyNameText(
lParam,
lpszReserve,
cchSize);
#ifndef UNICODE
if (retval) {
/*
* Do not copy out more than the requested byte count 'nSize'.
* Set retval to reflect the number of ANSI bytes.
*/
retval = WCSToMB(lpszReserve,
(UINT)retval,
&pString,
cchSize - 1,
FALSE);
}
UserLocalFree(lpszReserve);
((LPSTR)pString)[retval] = '\0';
#endif
ERRORTRAP(0);
ENDCALL(int);
}
#ifdef UNICODE
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, GetMessageW, LPMSG, pmsg, HWND, hwnd, UINT, wMsgFilterMin, UINT, wMsgFilterMax)
#else
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, GetMessageA, LPMSG, pmsg, HWND, hwnd, UINT, wMsgFilterMin, UINT, wMsgFilterMax)
#endif // UNICODE
BOOL APIENTRY GetMessage(
LPMSG pmsg,
HWND hwnd,
UINT wMsgFilterMin,
UINT wMsgFilterMax)
{
BEGINCALL()
/*
* Prevent apps from setting hi 16 bits so we can use them internally.
*/
if ((wMsgFilterMin | wMsgFilterMax) & RESERVED_MSG_BITS) {
/*
* Backward compatability with Win9x where someone is setting
* wMsgFilterMax to -1 to get all the messages.
*/
if (wMsgFilterMax == (UINT)-1 && !(wMsgFilterMin & RESERVED_MSG_BITS)) {
wMsgFilterMax = 0;
} else {
MSGERRORCODE(ERROR_INVALID_PARAMETER);
}
}
#ifndef UNICODE
/*
* If we have pushed message for DBCS messaging, we should pass this one
* to Apps at first...
*/
GET_DBCS_MESSAGE_IF_EXIST(GetMessage, pmsg, wMsgFilterMin, wMsgFilterMax, TRUE);
#endif
retval = (DWORD)NtUserGetMessage(
pmsg,
hwnd,
wMsgFilterMin,
wMsgFilterMax);
#ifndef UNICODE
// 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??? Divide into two messages?? WM_SYSDEADCHAR??
if (RtlWCSMessageWParamCharToMB(pmsg->message, &(pmsg->wParam))) {
WPARAM dwAnsi = pmsg->wParam;
/*
* Build DBCS-ware wParam. (for EM_SETPASSWORDCHAR...)
*/
BUILD_DBCS_MESSAGE_TO_CLIENTA_FROM_SERVER(pmsg, dwAnsi, TRUE, TRUE);
} else {
retval = 0;
}
ExitGetMessage:
#else
/*
* Only LOWORD of WPARAM is valid for WM_CHAR (Unicode)....
* (Mask off DBCS messaging information.)
*/
BUILD_DBCS_MESSAGE_TO_CLIENTW_FROM_SERVER(pmsg->message,pmsg->wParam);
#endif // UNICODE
#if DBG && defined(GENERIC_INPUT)
// TEST PURPOSE ONLY
if (pmsg->message == WM_INPUT) {
TAGMSG3(DBGTAG_PNP, "GetMessage: WM_INPUT, hwnd=%p, wp=%04x, lp=%08x", pmsg->hwnd, pmsg->wParam, pmsg->lParam);
}
#endif // GENERIC_INPUT
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetKeyboardLayoutNameW, LPTSTR, pwszKL)
#else
FUNCLOG1(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, GetKeyboardLayoutNameA, LPTSTR, pwszKL)
#endif // UNICODE
BOOL GetKeyboardLayoutName(
LPTSTR pwszKL)
{
#ifdef UNICODE
UNICODE_STRING str;
PUNICODE_STRING pstr = &str;
#else
PUNICODE_STRING pstr = &NtCurrentTeb()->StaticUnicodeString;
#endif
BEGINCALL()
#ifdef UNICODE
str.MaximumLength = KL_NAMELENGTH * sizeof(WCHAR);
str.Buffer = pwszKL;
#endif
retval = (DWORD)NtUserGetKeyboardLayoutName(pstr);
#ifndef UNICODE
if (retval) {
/*
* Non-zero retval means some text to copy out. Do not copy out
* more than the requested byte count 'chMaxCount'.
*/
WCSToMB(pstr->Buffer, -1, &pwszKL, KL_NAMELENGTH, FALSE);
}
#endif
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG2(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyW, UINT, wCode, UINT, wMapType)
#else
FUNCLOG2(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyA, UINT, wCode, UINT, wMapType)
#endif // UNICODE
UINT MapVirtualKey(
UINT wCode,
UINT wMapType)
{
BEGINCALL()
retval = (DWORD)NtUserMapVirtualKeyEx(
wCode,
wMapType,
0,
FALSE);
#ifndef UNICODE
if ((wMapType == 2) && (retval != 0)) {
WCHAR wch = LOWORD(retval);
retval &= ~0xFFFF;
RtlUnicodeToMultiByteN((LPSTR)&(retval), sizeof(CHAR),
NULL, &wch, sizeof(WCHAR));
}
#endif
ERRORTRAP(0);
ENDCALL(UINT);
}
/**************************************************************************\
* MapVirtualKeyEx
*
* 21-Feb-1995 GregoryW Created
\**************************************************************************/
#ifndef UNICODE
static HKL hMVKCachedHKL = 0;
static UINT uMVKCachedCP = 0;
#endif
#ifdef UNICODE
FUNCLOG3(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyExW, UINT, wCode, UINT, wMapType, HKL, hkl)
#else
FUNCLOG3(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, MapVirtualKeyExA, UINT, wCode, UINT, wMapType, HKL, hkl)
#endif // UNICODE
UINT MapVirtualKeyEx(
UINT wCode,
UINT wMapType,
HKL hkl)
{
BEGINCALL()
retval = (DWORD)NtUserMapVirtualKeyEx(
wCode,
wMapType,
(ULONG_PTR)hkl,
TRUE);
#ifndef UNICODE
if ((wMapType == 2) && (retval != 0)) {
WCHAR wch = LOWORD(retval);
if (hkl != hMVKCachedHKL) {
DWORD dwCodePage;
if (!GetLocaleInfoW(
HandleToUlong(hkl) & 0xffff,
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
(LPWSTR)&dwCodePage,
sizeof(dwCodePage) / sizeof(WCHAR)
)) {
MSGERROR();
}
uMVKCachedCP = dwCodePage;
hMVKCachedHKL = hkl;
}
/*
* Clear low word which contains Unicode character returned from server.
* This preserves the high word which is used to indicate dead key status.
*/
retval = retval & 0xffff0000;
if (!WideCharToMultiByte(
uMVKCachedCP,
0,
&wch,
1,
(LPSTR)&(retval),
1,
NULL,
NULL)) {
MSGERROR();
}
}
#endif
ERRORTRAP(0);
ENDCALL(UINT);
}
#ifdef UNICODE
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostMessageW , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
#else
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostMessageA , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
#endif // UNICODE
BOOL APIENTRY PostMessage(
HWND hwnd,
UINT wMsg,
WPARAM wParam,
LPARAM lParam)
{
BEGINCALL()
switch (wMsg) {
case WM_DROPFILES:
if (GetWindowProcess(hwnd) != GETPROCESSID()) {
/*
* We first send a WM_COPYGLOBALDATA message to get the data into the proper
* context.
*/
HGLOBAL hg;
hg = (HGLOBAL)SendMessage(hwnd, WM_COPYGLOBALDATA,
GlobalSize((HGLOBAL)wParam), wParam);
if (!hg) {
MSGERROR();
}
wParam = (WPARAM)hg;
}
break;
case LB_DIR:
case CB_DIR:
/*
* Make sure this bit is set so the client side string gets
* successfully copied over.
*/
wParam |= DDL_POSTMSGS;
break;
}
#ifndef UNICODE
/*
* Setup DBCS Messaging for WM_CHAR...
*/
BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(wMsg,wParam,TRUE);
RtlMBMessageWParamCharToWCS(wMsg, &wParam);
#endif
retval = (DWORD)NtUserPostMessage(
hwnd,
wMsg,
wParam,
lParam);
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostThreadMessageW, DWORD, idThread, UINT, msg, WPARAM, wParam, LPARAM, lParam)
#else
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, PostThreadMessageA, DWORD, idThread, UINT, msg, WPARAM, wParam, LPARAM, lParam)
#endif // UNICODE
BOOL APIENTRY PostThreadMessage(
DWORD idThread,
UINT msg,
WPARAM wParam,
LPARAM lParam)
{
BEGINCALL()
#ifndef UNICODE
#ifdef FE_SB // PostThreadMessage()
/*
* The server always expects the characters to be unicode so
* if this was generated from an ANSI routine convert it to Unicode
*/
BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(msg,wParam,TRUE);
#endif // FE_SB
RtlMBMessageWParamCharToWCS(msg, &wParam);
#endif
retval = (DWORD)NtUserPostThreadMessage(
idThread,
msg,
wParam,
lParam);
ERRORTRAP(0);
ENDCALL(BOOL);
}
/**************************************************************************\
* StringDuplicate
*
* 03-25-96 GerardoB Added Header.
\**************************************************************************/
#define StringDuplicate TEXT_FN(StringDuplicate)
LPTSTR StringDuplicate(LPCTSTR ptszDup) {
LPTSTR ptsz;
ULONG cb;
cb = (_tcslen(ptszDup) + 1) * sizeof(TCHAR);
ptsz = UserLocalAlloc(0, cb);
if (ptsz != NULL) {
RtlCopyMemory(ptsz, ptszDup, cb);
}
return ptsz;
}
/**************************************************************************\
* InitClsMenuName
*
* 03-22-96 GerardoB Created.
\**************************************************************************/
#define InitClsMenuName TEXT_FN(InitClsMenuName)
BOOL InitClsMenuName (PCLSMENUNAME pcmn, LPCTSTR lpszMenuName, PIN_STRING pstrMenuName)
{
/*
* We check the high-word because this may be a resource-ID.
*/
if (IS_PTR(lpszMenuName)) {
#ifdef UNICODE
if ((pcmn->pwszClientUnicodeMenuName = StringDuplicate(lpszMenuName)) == NULL) {
return FALSE;
}
if (!WCSToMB(lpszMenuName, -1, &(pcmn->pszClientAnsiMenuName), -1, TRUE)) {
pcmn->pszClientAnsiMenuName = NULL;
}
#else
if ((pcmn->pszClientAnsiMenuName = StringDuplicate(lpszMenuName)) == NULL) {
return FALSE;
}
if (!MBToWCS(lpszMenuName, -1, &(pcmn->pwszClientUnicodeMenuName), -1, TRUE)) {
pcmn->pwszClientUnicodeMenuName = NULL;
}
#endif // UNICODE
} else {
/* Copy the ID */
pcmn->pszClientAnsiMenuName = (LPSTR)lpszMenuName;
pcmn->pwszClientUnicodeMenuName = (LPWSTR)lpszMenuName;
}
COPYLPTSTRID(pstrMenuName, lpszMenuName);
pcmn->pusMenuName = pstrMenuName->pstr;
return TRUE;
goto errorexit; /* Keep the compiler happy */
errorexit: /* Used by COPYLPTSTRID */
#ifdef UNICODE
UserLocalFree(pcmn->pwszClientUnicodeMenuName);
pcmn->pwszClientUnicodeMenuName = NULL;
#else
UserLocalFree(pcmn->pszClientAnsiMenuName);
pcmn->pszClientAnsiMenuName = NULL;
#endif
return FALSE;
}
/**************************************************************************\
* SetClassLong
*
* 03-22-96 GerardoB Moved from client\cltxt.h & client\ntstubs.c
\**************************************************************************/
#ifdef UNICODE
FUNCLOG3(LOG_GENERAL, ULONG_PTR, APIENTRY, SetClassLongPtrW, HWND, hwnd, int, nIndex, LONG_PTR, dwNewLong)
#else
FUNCLOG3(LOG_GENERAL, ULONG_PTR, APIENTRY, SetClassLongPtrA, HWND, hwnd, int, nIndex, LONG_PTR, dwNewLong)
#endif // UNICODE
ULONG_PTR APIENTRY SetClassLongPtr(HWND hwnd, int nIndex, LONG_PTR dwNewLong)
{
CLSMENUNAME cmn;
IN_STRING strMenuName;
switch (nIndex) {
case GCLP_MENUNAME:
if (!InitClsMenuName(&cmn, (LPCTSTR) dwNewLong, &strMenuName)) {
RIPERR0(ERROR_INVALID_HANDLE, RIP_WARNING, "SetClassLong: InitClsMenuName failed");
return 0;
}
dwNewLong = (ULONG_PTR) &cmn;
break;
case GCLP_HBRBACKGROUND:
if ((DWORD)dwNewLong > COLOR_ENDCOLORS) {
/*
* Let gdi validate the brush. If it's invalid, then gdi
* will log a warning. No need to rip twice so we'll just
* set the last error.
*/
if (GdiValidateHandle((HBRUSH)dwNewLong) == FALSE) {
RIPERR0(ERROR_INVALID_HANDLE, RIP_VERBOSE, "");
return 0;
}
}
break;
}
BEGINCALL()
retval = (ULONG_PTR)NtUserSetClassLongPtr(hwnd, nIndex, dwNewLong, IS_ANSI);
ERRORTRAP(0);
/* Clean up */
switch (nIndex) {
case GCLP_MENUNAME:
CLEANUPLPTSTR(strMenuName); /* Initialized by InitClsMenuName */
/*
* We free either the old strings (returned by the kernel),
* or the new ones if the kernel call failed
*/
if (IS_PTR(cmn.pszClientAnsiMenuName)) {
UserLocalFree(KPVOID_TO_PVOID(cmn.pszClientAnsiMenuName));
}
if (IS_PTR(cmn.pwszClientUnicodeMenuName)) {
UserLocalFree(KPVOID_TO_PVOID(cmn.pwszClientUnicodeMenuName));
}
break;
}
ENDCALL(ULONG_PTR);
}
#ifdef _WIN64
DWORD APIENTRY SetClassLong(HWND hwnd, int nIndex, LONG dwNewLong)
{
BEGINCALL()
retval = (DWORD)NtUserSetClassLong(hwnd, nIndex, dwNewLong, IS_ANSI);
ERRORTRAP(0);
ENDCALL(DWORD);
}
#endif
/**************************************************************************\
* RegisterClassExWOW
*
* 03-22-96 GerardoB Added Header
\**************************************************************************/
ATOM TEXT_FN(RegisterClassExWOW)(
WNDCLASSEX *lpWndClass,
LPDWORD pdwWOWstuff,
WORD fnid,
DWORD dwFlags)
{
WNDCLASSEX WndClass;
IN_STRING strClassName;
IN_STRING strClassNameVer;
IN_STRING strMenuName;
DWORD dwExpWinVer;
CLSMENUNAME cmn;
TCHAR ClassNameVer[MAX_ATOM_LEN];
LPTSTR lpClassNameVer;
PACTIVATION_CONTEXT lpActivationContext = NULL;
#ifdef LAZY_CLASS_INIT
LazyInitClasses();
#endif
strClassName.fAllocated = 0;
strClassNameVer.fAllocated = 0;
strMenuName.fAllocated = 0;
/*
* Skip validation for our classes
*/
if (fnid != 0) {
/*
* This is a hack to bypass validation for DDE classes
* specifically, allow them to use hmodUser.
*/
if (fnid == FNID_DDE_BIT) {
fnid = 0;
}
dwExpWinVer = VER40;
} else {
if (lpWndClass->cbSize != sizeof(WNDCLASSEX)) {
RIPMSG0(RIP_WARNING, "RegisterClass: Invalid cbSize");
}
if (lpWndClass->cbClsExtra < 0 || lpWndClass->cbWndExtra < 0) {
RIPMSG0(RIP_WARNING, "RegisterClass: invalid cb*Extra");
goto BadParameter;
}
/*
* Validate hInstance
* Don't allow 4.0 apps to use hmodUser
*/
if ((lpWndClass->hInstance == hmodUser)
&& (GetClientInfo()->dwExpWinVer >= VER40)) {
RIPMSG0(RIP_WARNING, "RegisterClass: Cannot use USER's hInstance");
goto BadParameter;
} else if (lpWndClass->hInstance == NULL) {
/*
* For 32 bit apps we need to fix up the hInstance because Win 95 does
* this in their thunk MapHInstLS
*/
lpWndClass->hInstance = GetModuleHandle(NULL);
RIPMSG1(RIP_VERBOSE, "RegisterClass: fixing up NULL hmodule to %#p",
lpWndClass->hInstance);
}
dwExpWinVer = GETEXPWINVER(lpWndClass->hInstance);
/*
* Check for valid style bits and strip if appropriate
*/
if (lpWndClass->style & ~CS_VALID40) {
if (dwExpWinVer > VER31) {
RIPMSG0(RIP_WARNING, "RegisterClass: Invalid class style");
goto BadParameter;
}
/*
* Old application - strip bogus bits and pass through
*/
RIPMSG0(RIP_WARNING, "RegisterClass: Invalid class style, stripping bad styles");
lpWndClass->style &= CS_VALID40;
}
/*
* Validate hbrBackground
*/
if (lpWndClass->hbrBackground > (HBRUSH)COLOR_MAX
&& !GdiValidateHandle(lpWndClass->hbrBackground)) {
RIPMSG1(RIP_WARNING, "RegisterClass: Invalid class brush:%#p", lpWndClass->hbrBackground);
if (dwExpWinVer > VER30) {
goto BadParameter;
}
lpWndClass->hbrBackground = NULL;
}
}
if (!InitClsMenuName(&cmn, lpWndClass->lpszMenuName, &strMenuName)) {
return FALSE;
}
BEGINCALL()
WndClass = *lpWndClass;
#ifndef UNICODE
dwFlags |= CSF_ANSIPROC;
#endif // UNICODE
if (dwExpWinVer > VER31) {
dwFlags |= CSF_WIN40COMPAT;
}
if (GetClientInfo()->dwTIFlags & TIF_16BIT) {
/*
* No Fusion redirection for 16BIT apps.
*/
if (!(GetAppCompatFlags2(VERMAX) & GACF2_FORCEFUSION)) {
dwFlags &= ~CW_FLAGS_VERSIONCLASS;
}
}
if (dwFlags & CSF_VERSIONCLASS) {
lpClassNameVer = (LPTSTR)ClassNameToVersion((LPCWSTR)lpWndClass->lpszClassName, (LPWSTR)ClassNameVer, NULL, NULL, IS_ANSI);
if (lpClassNameVer == NULL) {
RIPMSG0(RIP_WARNING, "RegisterClass: Couldn't resolve class name");
MSGERROR();
}
} else {
lpClassNameVer = (LPTSTR)lpWndClass->lpszClassName;
}
COPYLPTSTRID(&strClassName, (LPTSTR)lpWndClass->lpszClassName);
COPYLPTSTRID(&strClassNameVer, (LPTSTR)lpClassNameVer);
retval = NtUserRegisterClassExWOW(
&WndClass,
strClassName.pstr,
strClassNameVer.pstr,
&cmn,
fnid,
dwFlags,
pdwWOWstuff);
/*
* Return the atom associated with this class or if earlier
* than Win 3.1 convert it to a strict BOOL (some apps check)
*/
if (GETEXPWINVER(lpWndClass->hInstance) < VER31)
retval = !!retval;
ERRORTRAP(0);
CLEANUPLPTSTR(strMenuName); /* Initialized by InitClsMenuName */
CLEANUPLPTSTR(strClassName);
CLEANUPLPTSTR(strClassNameVer);
if (lpActivationContext != NULL) {
RtlReleaseActivationContext(lpActivationContext);
lpActivationContext = NULL;
}
if (!retval) {
if (IS_PTR(cmn.pszClientAnsiMenuName)) {
UserLocalFree(KPVOID_TO_PVOID(cmn.pszClientAnsiMenuName));
}
if (IS_PTR(cmn.pwszClientUnicodeMenuName)) {
UserLocalFree(KPVOID_TO_PVOID(cmn.pwszClientUnicodeMenuName));
}
}
ENDCALL(BOOL);
BadParameter:
RIPERR0(ERROR_INVALID_PARAMETER, RIP_VERBOSE, "RegisterClass: Invalid Parameter");
return FALSE;
}
#ifdef UNICODE
FUNCLOG1(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, RegisterWindowMessageW , LPCTSTR, pString)
#else
FUNCLOG1(LOG_GENERAL, UINT, DUMMYCALLINGTYPE, RegisterWindowMessageA , LPCTSTR, pString)
#endif // UNICODE
UINT RegisterWindowMessage(
LPCTSTR pString)
{
IN_STRING str;
/*
* Make sure cleanup will work successfully
*/
str.fAllocated = FALSE;
BEGINCALL()
FIRSTCOPYLPTSTR(&str, (LPTSTR)pString);
retval = (DWORD)NtUserRegisterWindowMessage(
str.pstr);
ERRORTRAP(0);
CLEANUPLPTSTR(str);
ENDCALL(UINT);
}
#ifdef UNICODE
FUNCLOG2(LOG_GENERAL, HANDLE, DUMMYCALLINGTYPE, RemovePropW , HWND, hwnd, LPCTSTR, pString)
#else
FUNCLOG2(LOG_GENERAL, HANDLE, DUMMYCALLINGTYPE, RemovePropA , HWND, hwnd, LPCTSTR, pString)
#endif // UNICODE
HANDLE RemoveProp(
HWND hwnd,
LPCTSTR pString)
{
ATOM atomProp;
DWORD dwProp;
BEGINCALL()
if (IS_PTR(pString)) {
atomProp = GlobalFindAtom(pString);
if (atomProp == 0)
MSGERROR();
dwProp = MAKELONG(atomProp, TRUE);
} else
dwProp = MAKELONG(PTR_TO_ID(pString), FALSE);
retval = (ULONG_PTR)NtUserRemoveProp(
hwnd,
dwProp);
if (retval != 0 && IS_PTR(pString))
GlobalDeleteAtom(atomProp);
ERRORTRAP(0);
ENDCALL(HANDLE);
}
#ifdef UNICODE
FUNCLOG6(LOG_GENERAL, BOOL, APIENTRY, SendMessageCallbackW, HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam, SENDASYNCPROC, lpResultCallBack, ULONG_PTR, dwData)
#else
FUNCLOG6(LOG_GENERAL, BOOL, APIENTRY, SendMessageCallbackA, HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam, SENDASYNCPROC, lpResultCallBack, ULONG_PTR, dwData)
#endif // UNICODE
BOOL APIENTRY SendMessageCallback(
HWND hwnd,
UINT wMsg,
WPARAM wParam,
LPARAM lParam,
SENDASYNCPROC lpResultCallBack,
ULONG_PTR dwData)
{
SNDMSGCALLBACK smcb;
BEGINCALL()
smcb.dwData = dwData;
smcb.lpResultCallBack = lpResultCallBack;
retval = (DWORD)CsSendMessage(hwnd, wMsg, wParam, lParam,
(ULONG_PTR)&smcb, FNID_SENDMESSAGECALLBACK, IS_ANSI);
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, SendNotifyMessageW , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
#else
FUNCLOG4(LOG_GENERAL, BOOL, APIENTRY, SendNotifyMessageA , HWND, hwnd, UINT, wMsg, WPARAM, wParam, LPARAM, lParam)
#endif // UNICODE
BOOL APIENTRY SendNotifyMessage(
HWND hwnd,
UINT wMsg,
WPARAM wParam,
LPARAM lParam)
{
BEGINCALL()
retval = (DWORD)CsSendMessage(hwnd, wMsg, wParam, lParam,
0L, FNID_SENDNOTIFYMESSAGE, IS_ANSI);
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetPropW , HWND, hwnd, LPCTSTR, pString, HANDLE, hData)
#else
FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, SetPropA , HWND, hwnd, LPCTSTR, pString, HANDLE, hData)
#endif // UNICODE
BOOL SetProp(
HWND hwnd,
LPCTSTR pString,
HANDLE hData)
{
ATOM atomProp;
DWORD dwProp;
BEGINCALL()
if (IS_PTR(pString)) {
atomProp = GlobalAddAtom(pString);
if (atomProp == 0)
MSGERROR();
dwProp = MAKELONG(atomProp, TRUE);
} else
dwProp = MAKELONG(PTR_TO_ID(pString), FALSE);
retval = (DWORD)NtUserSetProp(
hwnd,
dwProp,
hData);
/*
* If it failed, get rid of the atom
*/
if (retval == FALSE && IS_PTR(pString))
GlobalDeleteAtom(atomProp);
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, UnregisterClassW, LPCTSTR, pszClassName, HINSTANCE, hModule)
#else
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, UnregisterClassA, LPCTSTR, pszClassName, HINSTANCE, hModule)
#endif // UNICODE
BOOL UnregisterClass(
LPCTSTR pszClassName,
HINSTANCE hModule)
{
IN_STRING strClassName;
CLSMENUNAME cmn;
/*
* Make sure cleanup will work successfully
*/
strClassName.fAllocated = FALSE;
BEGINCALL_CLASSV()
FIRSTCOPYLPTSTRID(&strClassName, lpClassNameVer);
retval = (DWORD)NtUserUnregisterClass(
strClassName.pstr,
hModule,
&cmn);
/*
* Check explicity for TRUE so we don't get a !FALSE when
* converttogui fails and the NtUser returns a status code intead of bool.
*/
if (retval == TRUE) {
/*
* Free the menu strings if they are not resource IDs
*/
if (IS_PTR(cmn.pszClientAnsiMenuName)) {
UserLocalFree(KPVOID_TO_PVOID(cmn.pszClientAnsiMenuName));
}
if (IS_PTR(cmn.pwszClientUnicodeMenuName)) {
UserLocalFree(KPVOID_TO_PVOID(cmn.pwszClientUnicodeMenuName));
}
}
ERRORTRAP(0);
CLEANUPLPTSTR(strClassName);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG1(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanW , TCHAR, cChar)
#else
FUNCLOG1(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanA , TCHAR, cChar)
#endif // UNICODE
SHORT VkKeyScan(
TCHAR cChar)
{
WCHAR wChar;
BEGINCALL()
#ifdef UNICODE
wChar = cChar;
#else
#ifdef FE_SB // VkKeyScan()
/*
* Return 0xFFFFFFFF for DBCS LeadByte character.
*/
if (IsDBCSLeadByte(cChar)) {
MSGERROR();
}
#endif // FE_SB
RtlMultiByteToUnicodeN((LPWSTR)&(wChar), sizeof(WCHAR), NULL, &cChar, sizeof(CHAR));
#endif // UNICODE
retval = (DWORD)NtUserVkKeyScanEx(
wChar,
0,
FALSE);
ERRORTRAP(-1);
ENDCALL(SHORT);
}
#ifndef UNICODE
static HKL hVKSCachedHKL = 0;
static UINT uVKSCachedCP = 0;
#endif
#ifdef UNICODE
FUNCLOG2(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanExW, TCHAR, cChar, HKL, hkl)
#else
FUNCLOG2(LOG_GENERAL, SHORT, DUMMYCALLINGTYPE, VkKeyScanExA, TCHAR, cChar, HKL, hkl)
#endif // UNICODE
SHORT VkKeyScanEx(
TCHAR cChar,
HKL hkl)
{
WCHAR wChar;
BEGINCALL()
#ifdef UNICODE
wChar = cChar;
#else
if (hkl != hVKSCachedHKL) {
DWORD dwCodePage;
if (!GetLocaleInfoW(
HandleToUlong(hkl) & 0xffff,
LOCALE_IDEFAULTANSICODEPAGE | LOCALE_RETURN_NUMBER,
(LPWSTR)&dwCodePage,
sizeof(dwCodePage) / sizeof(WCHAR)
)) {
MSGERROR();
}
uVKSCachedCP = dwCodePage;
hVKSCachedHKL = hkl;
}
#ifdef FE_SB // VkKeyScanEx()
/*
* Return 0xFFFFFFFF for DBCS LeadByte character.
*/
if (IsDBCSLeadByteEx(uVKSCachedCP,cChar)) {
MSGERROR();
}
#endif // FE_SB
if (!MultiByteToWideChar(
uVKSCachedCP,
0,
&cChar,
1,
&wChar,
1)) {
MSGERROR();
}
#endif // UNICODE
retval = (DWORD)NtUserVkKeyScanEx(
wChar,
(ULONG_PTR)hkl,
TRUE);
ERRORTRAP(-1);
ENDCALL(SHORT);
}
#ifdef UNICODE
FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplayDevicesW, LPCTSTR, lpszDevice, DWORD, iDevNum, PDISPLAY_DEVICE, lpDisplayDevice, DWORD, dwFlags)
#else
FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplayDevicesA, LPCTSTR, lpszDevice, DWORD, iDevNum, PDISPLAY_DEVICE, lpDisplayDevice, DWORD, dwFlags)
#endif // UNICODE
BOOL
EnumDisplayDevices(
LPCTSTR lpszDevice,
DWORD iDevNum,
PDISPLAY_DEVICE lpDisplayDevice,
DWORD dwFlags)
{
UNICODE_STRING UnicodeString;
PUNICODE_STRING pUnicodeString = NULL;
NTSTATUS Status;
DISPLAY_DEVICEW tmpDisplayDevice;
//
// Clear out things to make sure the caller passes in appropriate
// parameters
//
ZeroMemory(((PUCHAR)lpDisplayDevice) + sizeof(DWORD),
lpDisplayDevice->cb - sizeof(DWORD));
tmpDisplayDevice.cb = sizeof(DISPLAY_DEVICEW);
if (lpszDevice) {
#ifdef UNICODE
RtlInitUnicodeString(&UnicodeString, lpszDevice);
#else
ANSI_STRING AnsiString;
UnicodeString = NtCurrentTeb()->StaticUnicodeString;
RtlInitAnsiString(&AnsiString, (LPSTR)lpszDevice);
if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
&AnsiString,
FALSE))) {
return FALSE;
}
#endif
pUnicodeString = &UnicodeString;
}
Status = NtUserEnumDisplayDevices(
pUnicodeString,
iDevNum,
&tmpDisplayDevice,
dwFlags);
if (NT_SUCCESS(Status))
{
#ifndef UNICODE
LPSTR psz;
if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, DeviceString)) {
psz = (LPSTR)&(lpDisplayDevice->DeviceName[0]);
WCSToMB(&(tmpDisplayDevice.DeviceName[0]), -1, &psz, 32, FALSE);
}
if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, StateFlags)) {
psz = (LPSTR)&(lpDisplayDevice->DeviceString[0]);
WCSToMB(&(tmpDisplayDevice.DeviceString[0]), -1, &psz, 128, FALSE);
}
if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, DeviceID)) {
lpDisplayDevice->StateFlags = tmpDisplayDevice.StateFlags;
}
if (lpDisplayDevice->cb >= FIELD_OFFSET(DISPLAY_DEVICE, DeviceKey)) {
psz = (LPSTR)&(lpDisplayDevice->DeviceID[0]);
WCSToMB(&(tmpDisplayDevice.DeviceID[0]), -1, &psz, 128, FALSE);
}
if (lpDisplayDevice->cb >= sizeof(DISPLAY_DEVICE)) {
psz = (LPSTR)&(lpDisplayDevice->DeviceKey[0]);
WCSToMB(&(tmpDisplayDevice.DeviceKey[0]), -1, &psz, 128, FALSE);
}
#else
//
// Copy the contents of the tmpDisplayDevice back to the
// user supplied buffer. Make sure not to overwrite the original
// size field.
//
RtlMoveMemory((PUCHAR)lpDisplayDevice + sizeof(DWORD),
((PUCHAR)&tmpDisplayDevice + sizeof(DWORD)),
lpDisplayDevice->cb - sizeof(DWORD));
#endif
return TRUE;
}
return FALSE;
}
#ifdef UNICODE
FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsW , LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode)
#else
FUNCLOG3(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsA, LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode)
#endif // UNICODE
BOOL EnumDisplaySettings(
LPCTSTR lpszDeviceName,
DWORD iModeNum,
LPDEVMODE lpDevMode)
{
//
// Work-around Win95 problem which does not require the caller
// to initialize these two fields.
//
lpDevMode->dmDriverExtra = 0;
lpDevMode->dmSize = FIELD_OFFSET(DEVMODE, dmICMMethod);
return EnumDisplaySettingsEx(lpszDeviceName, iModeNum, lpDevMode, 0);
}
#ifdef UNICODE
FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsExW, LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode, DWORD, dwFlags)
#else
FUNCLOG4(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, EnumDisplaySettingsExA, LPCTSTR, lpszDeviceName, DWORD, iModeNum, LPDEVMODE, lpDevMode, DWORD, dwFlags)
#endif // UNICODE
BOOL EnumDisplaySettingsEx(
LPCTSTR lpszDeviceName,
DWORD iModeNum,
LPDEVMODE lpDevMode,
DWORD dwFlags)
{
UNICODE_STRING UnicodeString;
PUNICODE_STRING pUnicodeString = NULL;
LPDEVMODEW lpDevModeReserve;
BOOL retval = FALSE;
WORD size = lpDevMode->dmSize;
if (lpszDeviceName) {
#ifdef UNICODE
RtlInitUnicodeString(&UnicodeString, lpszDeviceName);
#else
ANSI_STRING AnsiString;
UnicodeString = NtCurrentTeb()->StaticUnicodeString;
RtlInitAnsiString(&AnsiString, (LPSTR)lpszDeviceName);
if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
&AnsiString,
FALSE))) {
return FALSE;
}
#endif
pUnicodeString = &UnicodeString;
}
/*
* Currently -2 is reserved (undocumented function of the NT api.
* remove the check is win95 implements this.
* -> -1 returns the content of the registry at the time of the call
*
*
* if (iModeNum == (DWORD) -2)
* {
* return FALSE;
* }
*
*
* -1 should return the current DEVMODE for the device.
* This is handled in the kernel part of the function, so we pass it on.
*
*
*
* We will always request a full DEVMODE from the kernel.
* So allocate the space needed
*
*/
lpDevModeReserve = UserLocalAlloc(HEAP_ZERO_MEMORY,
sizeof(DEVMODEW) + lpDevMode->dmDriverExtra);
if (lpDevModeReserve) {
lpDevModeReserve->dmSize = sizeof(DEVMODEW);
lpDevModeReserve->dmDriverExtra = lpDevMode->dmDriverExtra;
/*
* Get the information
*/
retval = (NT_SUCCESS(NtUserEnumDisplaySettings(pUnicodeString,
iModeNum,
lpDevModeReserve,
dwFlags)));
if (retval) {
#ifndef UNICODE
LPSTR psz;
#endif
/*
* return only the amount of information requested.
* For ANSI, this requires a conversion.
*/
/*
* First, copy the driver extra information
*/
if (lpDevMode->dmDriverExtra && lpDevModeReserve->dmDriverExtra) {
RtlMoveMemory(((PUCHAR)lpDevMode) + size,
lpDevModeReserve + 1,
min(lpDevMode->dmDriverExtra,
lpDevModeReserve->dmDriverExtra));
}
#ifndef UNICODE
psz = (LPSTR)&(lpDevMode->dmDeviceName[0]);
retval = WCSToMB(lpDevModeReserve->dmDeviceName,
-1,
&psz,
32,
FALSE);
RtlMoveMemory(&lpDevMode->dmSpecVersion,
&lpDevModeReserve->dmSpecVersion,
min(size, FIELD_OFFSET(DEVMODE,dmFormName)) -
FIELD_OFFSET(DEVMODE,dmSpecVersion));
lpDevMode->dmSize = size;
if (size >= FIELD_OFFSET(DEVMODE,dmFormName)) {
psz = (LPSTR)&(lpDevMode->dmFormName[0]);
retval = WCSToMB(lpDevModeReserve->dmFormName, -1, &psz, 32, FALSE);
}
if (size > FIELD_OFFSET(DEVMODE,dmBitsPerPel)) {
RtlMoveMemory(&lpDevMode->dmBitsPerPel,
&lpDevModeReserve->dmBitsPerPel,
lpDevMode->dmSize +
lpDevMode->dmDriverExtra -
FIELD_OFFSET(DEVMODE,dmBitsPerPel));
}
#else
RtlMoveMemory(lpDevMode, lpDevModeReserve, size);
lpDevMode->dmSize = size;
#endif
if (size != lpDevMode->dmSize) {
RIPMSG0(RIP_WARNING, "EnumDisplaySettings : Error in dmSize");
}
/*
* Don't return invalid field flags to the application
* Add any other new ones here.
*
* We assume apps at least have up to dmDisplayFrenquency for
* now ...
*/
if (size < FIELD_OFFSET(DEVMODE,dmPanningWidth))
lpDevMode->dmFields &= ~DM_PANNINGWIDTH;
if (size < FIELD_OFFSET(DEVMODE,dmPanningHeight))
lpDevMode->dmFields &= ~DM_PANNINGHEIGHT;
}
UserLocalFree(lpDevModeReserve);
}
return retval;
}
#ifdef UNICODE
FUNCLOG2(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsW, LPDEVMODE, lpDevMode, DWORD, dwFlags)
#else
FUNCLOG2(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsA, LPDEVMODE, lpDevMode, DWORD, dwFlags)
#endif // UNICODE
LONG ChangeDisplaySettings(
LPDEVMODE lpDevMode,
DWORD dwFlags)
{
/*
* Compatibility.
*/
if (lpDevMode) {
lpDevMode->dmDriverExtra = 0;
}
return ChangeDisplaySettingsEx(NULL, lpDevMode, NULL, dwFlags, NULL);
}
#ifdef UNICODE
FUNCLOG5(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsExW, LPCTSTR, lpszDeviceName, LPDEVMODE, lpDevMode, HWND, hwnd, DWORD, dwFlags, LPVOID, lParam)
#else
FUNCLOG5(LOG_GENERAL, LONG, DUMMYCALLINGTYPE, ChangeDisplaySettingsExA, LPCTSTR, lpszDeviceName, LPDEVMODE, lpDevMode, HWND, hwnd, DWORD, dwFlags, LPVOID, lParam)
#endif // UNICODE
LONG ChangeDisplaySettingsEx(
LPCTSTR lpszDeviceName,
LPDEVMODE lpDevMode,
HWND hwnd,
DWORD dwFlags,
LPVOID lParam)
{
#ifndef UNICODE
ANSI_STRING AnsiString;
#endif
UNICODE_STRING UnicodeString;
PUNICODE_STRING pUnicodeString = NULL;
LONG status = DISP_CHANGE_FAILED;
LPDEVMODEW lpDevModeW;
if (hwnd != NULL) {
return DISP_CHANGE_BADPARAM;
}
if (lpszDeviceName) {
#ifdef UNICODE
RtlInitUnicodeString(&UnicodeString, lpszDeviceName);
#else
UnicodeString = NtCurrentTeb()->StaticUnicodeString;
RtlInitAnsiString(&AnsiString, (LPSTR)lpszDeviceName);
if (!NT_SUCCESS(RtlAnsiStringToUnicodeString(&UnicodeString,
&AnsiString,
FALSE))) {
return FALSE;
}
#endif
pUnicodeString = &UnicodeString;
}
#ifdef UNICODE
lpDevModeW = lpDevMode;
#else
lpDevModeW = NULL;
if (lpDevMode) {
lpDevModeW = GdiConvertToDevmodeW(lpDevMode);
if (lpDevModeW == NULL) {
return FALSE;
}
}
#endif
status = NtUserChangeDisplaySettings(pUnicodeString,
lpDevModeW,
dwFlags,
lParam);
#ifndef UNICODE
if (lpDevMode) {
UserLocalFree(lpDevModeW);
}
#endif
return status;
}
#ifdef UNICODE
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, CallMsgFilterW , LPMSG, pmsg, int, nCode)
#else
FUNCLOG2(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, CallMsgFilterA , LPMSG, pmsg, int, nCode)
#endif // UNICODE
BOOL CallMsgFilter(
LPMSG pmsg,
int nCode)
{
PCLIENTINFO pci;
MSG msg;
BEGINCALLCONNECT()
/*
* If we're not hooked, don't bother going to the server
*/
pci = GetClientInfo();
if (!IsHooked(pci, (WH_MSGFILTER | WH_SYSMSGFILTER))) {
return FALSE;
}
/*
* Don't allow apps to use the hiword of the message parameter.
*/
if (pmsg->message & RESERVED_MSG_BITS) {
MSGERRORCODE(ERROR_INVALID_PARAMETER);
}
msg = *pmsg;
#ifndef UNICODE
switch (pmsg->message) {
#ifdef FE_SB // CallMsgFilter()
case WM_CHAR:
case EM_SETPASSWORDCHAR:
#ifndef LATER
/*
* we should not return "TRUE" everytime for DBCS leadbyte character...
* but should convert DBCS character to Unicode correctly.. How I can do ??
* then ,finally, we just take what we did in NT 3.51, it means do nothing..
*/
#else
/*
* Build DBCS-aware message.
*/
BUILD_DBCS_MESSAGE_TO_SERVER_FROM_CLIENTA(pmsg->message,pmsg->wParam,TRUE);
/*
* Fall through.....
*/
#endif // LATER
#else
case WM_CHAR:
case EM_SETPASSWORDCHAR:
#endif // FE_SB
case WM_CHARTOITEM:
case WM_DEADCHAR:
case WM_SYSCHAR:
case WM_SYSDEADCHAR:
case WM_MENUCHAR:
#ifdef FE_IME // CallMsgFilter()
case WM_IME_CHAR:
case WM_IME_COMPOSITION:
#endif // FE_IME
RtlMBMessageWParamCharToWCS( msg.message, &(msg.wParam));
break;
}
#endif //!UNICODE
retval = (DWORD)NtUserCallMsgFilter(
&msg,
nCode);
ERRORTRAP(0);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG7(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, DrawCaptionTempW, HWND, hwnd, HDC, hdc, LPCRECT, lprc, HFONT, hFont, HICON, hicon, LPCTSTR, lpText, UINT, flags)
#else
FUNCLOG7(LOG_GENERAL, BOOL, DUMMYCALLINGTYPE, DrawCaptionTempA, HWND, hwnd, HDC, hdc, LPCRECT, lprc, HFONT, hFont, HICON, hicon, LPCTSTR, lpText, UINT, flags)
#endif // UNICODE
BOOL DrawCaptionTemp(
HWND hwnd,
HDC hdc,
LPCRECT lprc,
HFONT hFont,
HICON hicon,
LPCTSTR lpText,
UINT flags)
{
HDC hdcr;
IN_STRING strText;
/*
* Make sure cleanup will work successfully
*/
strText.fAllocated = FALSE;
BEGINCALL()
if (IsMetaFile(hdc)) return FALSE;
hdcr = GdiConvertAndCheckDC(hdc);
if (hdcr == (HDC)0)
return FALSE;
FIRSTCOPYLPTSTRIDOPT(&strText, lpText);
retval = (DWORD)NtUserDrawCaptionTemp(
hwnd,
hdc,
lprc,
hFont,
hicon,
strText.pstr,
flags);
ERRORTRAP(0);
CLEANUPLPTSTR(strText);
ENDCALL(BOOL);
}
#ifdef UNICODE
FUNCLOG3(LOG_GENERAL, UINT, WINUSERAPI, RealGetWindowClassW, HWND, hwnd, LPTSTR, ptszClassName, UINT, cchClassNameMax)
#else
FUNCLOG3(LOG_GENERAL, UINT, WINUSERAPI, RealGetWindowClassA, HWND, hwnd, LPTSTR, ptszClassName, UINT, cchClassNameMax)
#endif // UNICODE
WINUSERAPI UINT WINAPI
RealGetWindowClass(
HWND hwnd,
LPTSTR ptszClassName,
UINT cchClassNameMax)
{
UNICODE_STRING strClassName;
int retval;
strClassName.MaximumLength = (USHORT)(cchClassNameMax * sizeof(WCHAR));
#ifndef UNICODE
strClassName.Buffer = UserLocalAlloc(0, strClassName.MaximumLength);
if (!strClassName.Buffer) {
return 0;
}
#else
strClassName.Buffer = ptszClassName;
#endif
retval = NtUserGetClassName(hwnd, TRUE, &strClassName);
#ifndef UNICODE
if (retval || (cchClassNameMax == 1)) {
/*
* Copy the result
*/
retval = WCSToMB(strClassName.Buffer,
retval,
&ptszClassName,
cchClassNameMax - 1,
FALSE);
ptszClassName[retval] = '\0';
}
UserLocalFree(strClassName.Buffer);
#endif
return retval;
}
WINUSERAPI BOOL WINAPI GetAltTabInfo(
HWND hwnd,
int iItem,
PALTTABINFO pati,
LPTSTR pszItemText,
UINT cchItemText OPTIONAL)
{
BEGINCALL()
retval = (DWORD)NtUserGetAltTabInfo(hwnd,
iItem,
pati,
(LPWSTR)pszItemText,
cchItemText,
IS_ANSI);
ERRORTRAP(0);
ENDCALL(BOOL);
}