2003-11-19 12:33:32 +00:00
|
|
|
/*
|
|
|
|
* ReactOS kernel
|
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
2007-10-23 08:27:48 +00:00
|
|
|
/*
|
2003-11-19 12:33:32 +00:00
|
|
|
* PROJECT: ReactOS user32.dll
|
|
|
|
* FILE: lib/user32/misc/misc.c
|
|
|
|
* PURPOSE: Misc
|
|
|
|
* PROGRAMMER: Thomas Weidenmueller (w3seek@users.sourceforge.net)
|
|
|
|
* UPDATE HISTORY:
|
|
|
|
* 19-11-2003 Created
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES ******************************************************************/
|
|
|
|
|
2005-06-19 18:06:53 +00:00
|
|
|
#include <user32.h>
|
2006-06-26 13:16:43 +00:00
|
|
|
|
|
|
|
#include <wine/debug.h>
|
2003-11-19 12:33:32 +00:00
|
|
|
|
2007-10-23 08:27:48 +00:00
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(user32);
|
|
|
|
|
2003-11-19 12:33:32 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2004-05-01 16:43:15 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-07-08 14:36:18 +00:00
|
|
|
RegisterLogonProcess(DWORD dwProcessId, BOOL bRegister)
|
2004-05-01 16:43:15 +00:00
|
|
|
{
|
2004-07-08 14:36:18 +00:00
|
|
|
return NtUserCallTwoParam(dwProcessId,
|
2010-01-05 19:26:32 +00:00
|
|
|
(DWORD_PTR)bRegister,
|
2004-07-08 14:36:18 +00:00
|
|
|
TWOPARAM_ROUTINE_REGISTERLOGONPROC);
|
2004-05-01 16:43:15 +00:00
|
|
|
}
|
2004-07-12 20:09:35 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2004-07-12 20:09:35 +00:00
|
|
|
SetLogonNotifyWindow (HWND Wnd, HWINSTA WinSta)
|
|
|
|
{
|
|
|
|
/* Maybe we should call NtUserSetLogonNotifyWindow and let that one inform CSRSS??? */
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
CSR_API_MESSAGE Request;
|
|
|
|
ULONG CsrRequest;
|
2004-07-12 20:09:35 +00:00
|
|
|
NTSTATUS Status;
|
|
|
|
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
CsrRequest = MAKE_CSR_API(SET_LOGON_NOTIFY_WINDOW, CSR_GUI);
|
2004-07-12 20:09:35 +00:00
|
|
|
Request.Data.SetLogonNotifyWindowRequest.LogonNotifyWindow = Wnd;
|
|
|
|
|
|
|
|
Status = CsrClientCallServer(&Request,
|
Large change to modify NTDLL'S CSR Functions to be compatible with NT. They are external and we should at least try to match the number of arguments (one vs eight? come on!). Because this is also the direction that Emanuele wants to be taking, the whole external calling interface was modified to be more compatible with NT (although internally it still isn't, and does not have a reason to be). API Names are now generated by a macro from the Server ID, like Emanuele and I noticed from traces, and I've entirely removed the concept of a reply structure. CSRSS uses full-duplex one-way structures, not dual-strutures (this would've been incompatible with the external interface anyways). I don't seem to have introduced any new bugs (console-ROS works great for me, as does the GUI), but there is still a chance some obscure bug might happen, so please bear with me, I had to hand-edit over 250 calls. Also, this now allows full removal of ntdll headers and the next commits will clean this up
svn path=/trunk/; revision=16213
2005-06-22 04:02:32 +00:00
|
|
|
NULL,
|
|
|
|
CsrRequest,
|
|
|
|
sizeof(CSR_API_MESSAGE));
|
|
|
|
if (!NT_SUCCESS(Status) || !NT_SUCCESS(Status = Request.Status))
|
2004-07-12 20:09:35 +00:00
|
|
|
{
|
|
|
|
SetLastError(RtlNtStatusToDosError(Status));
|
|
|
|
return(FALSE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(TRUE);
|
|
|
|
}
|
2004-11-20 15:55:45 +00:00
|
|
|
|
|
|
|
/*
|
2004-12-06 02:23:05 +00:00
|
|
|
* @implemented
|
2004-11-20 15:55:45 +00:00
|
|
|
*/
|
|
|
|
BOOL WINAPI
|
2004-12-06 02:23:05 +00:00
|
|
|
UpdatePerUserSystemParameters(
|
|
|
|
DWORD dwReserved,
|
|
|
|
BOOL bEnable)
|
2004-11-20 15:55:45 +00:00
|
|
|
{
|
2004-12-06 08:41:38 +00:00
|
|
|
return NtUserUpdatePerUserSystemParameters(dwReserved, bEnable);
|
2004-11-20 15:55:45 +00:00
|
|
|
}
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2009-08-16 21:44:59 +00:00
|
|
|
PTHREADINFO
|
2006-04-05 08:05:55 +00:00
|
|
|
GetW32ThreadInfo(VOID)
|
|
|
|
{
|
2009-08-16 21:44:59 +00:00
|
|
|
PTHREADINFO ti;
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2009-08-16 21:44:59 +00:00
|
|
|
ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
|
2006-04-05 08:05:55 +00:00
|
|
|
if (ti == NULL)
|
|
|
|
{
|
2009-08-16 21:44:59 +00:00
|
|
|
/* create the THREADINFO structure */
|
2006-04-05 08:05:55 +00:00
|
|
|
NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
|
2009-08-16 21:44:59 +00:00
|
|
|
ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
|
2006-04-05 08:05:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return ti;
|
|
|
|
}
|
|
|
|
|
2006-07-09 00:16:51 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* GetUserObjectSecurity
|
|
|
|
*
|
|
|
|
* Retrieves security information for user object specified
|
|
|
|
* with handle 'hObject'. Descriptor returned in self-relative
|
|
|
|
* format.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* 1) hObject - handle to an object to retrieve information for
|
|
|
|
* 2) pSecurityInfo - type of information to retrieve
|
|
|
|
* 3) pSecurityDescriptor - buffer which receives descriptor
|
|
|
|
* 4) dwLength - size, in bytes, of buffer 'pSecurityDescriptor'
|
|
|
|
* 5) pdwLengthNeeded - reseives actual size of descriptor
|
|
|
|
*
|
|
|
|
* Return Vaules:
|
|
|
|
* TRUE on success
|
|
|
|
* FALSE on failure, call GetLastError() for more information
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
GetUserObjectSecurity(
|
|
|
|
IN HANDLE hObject,
|
|
|
|
IN PSECURITY_INFORMATION pSecurityInfo,
|
|
|
|
OUT PSECURITY_DESCRIPTOR pSecurityDescriptor,
|
|
|
|
IN DWORD dwLength,
|
|
|
|
OUT PDWORD pdwLengthNeeded
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DWORD dwWin32Error;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
|
|
|
|
Status = NtQuerySecurityObject(
|
|
|
|
hObject, // Object Handle
|
|
|
|
*pSecurityInfo, // Security Information
|
|
|
|
pSecurityDescriptor,// Security Descriptor
|
|
|
|
dwLength, // Buffer Length
|
|
|
|
pdwLengthNeeded // Actual Length
|
|
|
|
);
|
|
|
|
|
|
|
|
if ( ! NT_SUCCESS( Status ) ) {
|
|
|
|
dwWin32Error = RtlNtStatusToDosError( Status );
|
|
|
|
NtCurrentTeb()->LastErrorValue = dwWin32Error;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* SetUserObjectSecurity
|
|
|
|
*
|
|
|
|
* Sets new security descriptor to user object specified by
|
|
|
|
* handle 'hObject'. Descriptor must be in self-relative format.
|
|
|
|
*
|
|
|
|
* Arguments:
|
|
|
|
* 1) hObject - handle to an object to set information for
|
|
|
|
* 2) pSecurityInfo - type of information to apply
|
|
|
|
* 3) pSecurityDescriptor - buffer which descriptor to set
|
|
|
|
*
|
|
|
|
* Return Vaules:
|
|
|
|
* TRUE on success
|
|
|
|
* FALSE on failure, call GetLastError() for more information
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
|
|
|
WINAPI
|
|
|
|
SetUserObjectSecurity(
|
|
|
|
IN HANDLE hObject,
|
|
|
|
IN PSECURITY_INFORMATION pSecurityInfo,
|
|
|
|
IN PSECURITY_DESCRIPTOR pSecurityDescriptor
|
|
|
|
)
|
|
|
|
{
|
|
|
|
DWORD dwWin32Error;
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
|
|
|
|
Status = NtSetSecurityObject(
|
|
|
|
hObject, // Object Handle
|
|
|
|
*pSecurityInfo, // Security Information
|
|
|
|
pSecurityDescriptor // Security Descriptor
|
|
|
|
);
|
|
|
|
|
|
|
|
if ( ! NT_SUCCESS( Status ) ) {
|
|
|
|
dwWin32Error = RtlNtStatusToDosError( Status );
|
|
|
|
NtCurrentTeb()->LastErrorValue = dwWin32Error;
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2006-07-09 00:16:51 +00:00
|
|
|
EndTask(
|
|
|
|
HWND hWnd,
|
|
|
|
BOOL fShutDown,
|
|
|
|
BOOL fForce)
|
|
|
|
{
|
|
|
|
SendMessageW(hWnd, WM_CLOSE, 0, 0);
|
|
|
|
|
|
|
|
if (IsWindow(hWnd))
|
|
|
|
{
|
|
|
|
if (fForce)
|
2009-01-11 12:37:54 +00:00
|
|
|
return DestroyWindow(hWnd);
|
2006-07-09 00:16:51 +00:00
|
|
|
else
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-09-24 02:42:17 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOL
|
2008-11-30 11:42:05 +00:00
|
|
|
WINAPI
|
2007-09-24 02:42:17 +00:00
|
|
|
IsGUIThread(
|
|
|
|
BOOL bConvert)
|
|
|
|
{
|
2009-08-16 21:44:59 +00:00
|
|
|
PTHREADINFO ti = (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo;
|
2007-09-24 02:42:17 +00:00
|
|
|
if (ti == NULL)
|
|
|
|
{
|
|
|
|
if(bConvert)
|
|
|
|
{
|
2007-09-24 02:58:22 +00:00
|
|
|
NtUserGetThreadState(THREADSTATE_GETTHREADINFO);
|
2009-08-16 21:44:59 +00:00
|
|
|
if ((PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo) return TRUE;
|
2007-09-24 02:42:17 +00:00
|
|
|
else
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2009-03-31 22:02:29 +00:00
|
|
|
BOOL
|
|
|
|
FASTCALL
|
2009-07-22 05:23:08 +00:00
|
|
|
TestWindowProcess(PWND Wnd)
|
2009-03-31 22:02:29 +00:00
|
|
|
{
|
2009-08-16 21:44:59 +00:00
|
|
|
if (Wnd->head.pti == (PTHREADINFO)NtCurrentTeb()->Win32ThreadInfo)
|
2009-03-31 22:02:29 +00:00
|
|
|
return TRUE;
|
|
|
|
else
|
2009-07-26 01:59:08 +00:00
|
|
|
return (NtUserQueryWindow(Wnd->head.h, QUERY_WINDOW_UNIQUE_PROCESS_ID) ==
|
2010-06-27 22:19:17 +00:00
|
|
|
(DWORD_PTR)NtCurrentTeb()->ClientId.UniqueProcess );
|
2009-03-31 22:02:29 +00:00
|
|
|
}
|
|
|
|
|
2007-09-25 14:42:51 +00:00
|
|
|
BOOL
|
|
|
|
FASTCALL
|
|
|
|
IsMetaFile(HDC hDc)
|
|
|
|
{
|
|
|
|
DWORD Type = GetObjectType((HGDIOBJ) hDc);
|
|
|
|
switch(Type)
|
|
|
|
{
|
|
|
|
case OBJ_METADC:
|
|
|
|
case OBJ_METAFILE:
|
|
|
|
case OBJ_ENHMETADC:
|
|
|
|
case OBJ_ENHMETAFILE:
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2007-09-20 14:26:43 +00:00
|
|
|
PUSER_HANDLE_ENTRY
|
|
|
|
FASTCALL
|
|
|
|
GetUser32Handle(HANDLE handle)
|
|
|
|
{
|
2007-11-15 05:42:44 +00:00
|
|
|
INT Index;
|
|
|
|
USHORT generation;
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2010-06-27 22:19:17 +00:00
|
|
|
Index = (((UINT_PTR)handle & 0xffff) - FIRST_USER_HANDLE) >> 1;
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-11-15 05:42:44 +00:00
|
|
|
if (Index < 0 || Index >= gHandleTable->nb_handles)
|
|
|
|
return NULL;
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-11-15 05:42:44 +00:00
|
|
|
if (!gHandleEntries[Index].type || !gHandleEntries[Index].ptr)
|
|
|
|
return NULL;
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2010-06-27 22:19:17 +00:00
|
|
|
generation = (UINT_PTR)handle >> 16;
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-11-15 05:42:44 +00:00
|
|
|
if (generation == gHandleEntries[Index].generation || !generation || generation == 0xffff)
|
|
|
|
return &gHandleEntries[Index];
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-11-15 05:42:44 +00:00
|
|
|
return NULL;
|
2007-09-20 14:26:43 +00:00
|
|
|
}
|
|
|
|
|
2007-11-15 03:08:46 +00:00
|
|
|
/*
|
|
|
|
* Decide whether an object is located on the desktop or shared heap
|
|
|
|
*/
|
2008-07-29 18:53:46 +00:00
|
|
|
static const BOOL g_ObjectHeapTypeShared[VALIDATE_TYPE_EVENT + 1] =
|
2007-11-15 03:08:46 +00:00
|
|
|
{
|
|
|
|
FALSE, /* VALIDATE_TYPE_FREE (not used) */
|
2010-10-23 05:36:12 +00:00
|
|
|
FALSE, /* VALIDATE_TYPE_WIN */
|
2010-01-15 13:47:25 +00:00
|
|
|
TRUE, /* VALIDATE_TYPE_MENU FALSE */
|
2007-11-15 03:08:46 +00:00
|
|
|
TRUE, /* VALIDATE_TYPE_CURSOR */
|
|
|
|
TRUE, /* VALIDATE_TYPE_MWPOS */
|
2010-10-23 05:36:12 +00:00
|
|
|
FALSE, /* VALIDATE_TYPE_HOOK */
|
2007-11-15 03:08:46 +00:00
|
|
|
FALSE, /* (not used) */
|
2010-10-23 05:36:12 +00:00
|
|
|
FALSE, /* VALIDATE_TYPE_CALLPROC */
|
2007-11-15 05:42:44 +00:00
|
|
|
TRUE, /* VALIDATE_TYPE_ACCEL */
|
2007-11-15 03:08:46 +00:00
|
|
|
FALSE, /* (not used) */
|
|
|
|
FALSE, /* (not used) */
|
|
|
|
FALSE, /* (not used) */
|
2008-07-29 18:53:46 +00:00
|
|
|
TRUE, /* VALIDATE_TYPE_MONITOR */
|
|
|
|
FALSE, /* (not used) */
|
|
|
|
FALSE, /* (not used) */
|
|
|
|
TRUE /* VALIDATE_TYPE_EVENT */
|
2007-11-15 03:08:46 +00:00
|
|
|
};
|
|
|
|
|
2007-09-20 14:26:43 +00:00
|
|
|
//
|
|
|
|
// Validate Handle and return the pointer to the object.
|
|
|
|
//
|
|
|
|
PVOID
|
|
|
|
FASTCALL
|
|
|
|
ValidateHandle(HANDLE handle, UINT uType)
|
|
|
|
{
|
2007-11-15 03:08:46 +00:00
|
|
|
PVOID ret;
|
2007-11-15 05:42:44 +00:00
|
|
|
PUSER_HANDLE_ENTRY pEntry;
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2008-07-29 18:53:46 +00:00
|
|
|
ASSERT(uType <= VALIDATE_TYPE_EVENT);
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-11-15 05:42:44 +00:00
|
|
|
pEntry = GetUser32Handle(handle);
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-11-15 03:08:46 +00:00
|
|
|
if (pEntry && uType == 0)
|
|
|
|
uType = pEntry->type;
|
|
|
|
|
2007-09-20 14:26:43 +00:00
|
|
|
// Must have an entry and must be the same type!
|
2010-01-15 13:47:25 +00:00
|
|
|
if ( (!pEntry) ||
|
|
|
|
(pEntry->type != uType) ||
|
|
|
|
!pEntry->ptr ||
|
|
|
|
(pEntry->flags & HANDLEENTRY_INDESTROY) )
|
2007-09-20 14:26:43 +00:00
|
|
|
{
|
|
|
|
switch ( uType )
|
|
|
|
{ // Test (with wine too) confirms these results!
|
|
|
|
case VALIDATE_TYPE_WIN:
|
|
|
|
SetLastError(ERROR_INVALID_WINDOW_HANDLE);
|
|
|
|
break;
|
|
|
|
case VALIDATE_TYPE_MENU:
|
|
|
|
SetLastError(ERROR_INVALID_MENU_HANDLE);
|
|
|
|
break;
|
|
|
|
case VALIDATE_TYPE_CURSOR:
|
|
|
|
SetLastError(ERROR_INVALID_CURSOR_HANDLE);
|
|
|
|
break;
|
|
|
|
case VALIDATE_TYPE_MWPOS:
|
|
|
|
SetLastError(ERROR_INVALID_DWP_HANDLE);
|
|
|
|
break;
|
|
|
|
case VALIDATE_TYPE_HOOK:
|
|
|
|
SetLastError(ERROR_INVALID_HOOK_HANDLE);
|
|
|
|
break;
|
|
|
|
case VALIDATE_TYPE_ACCEL:
|
|
|
|
SetLastError(ERROR_INVALID_ACCEL_HANDLE);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
SetLastError(ERROR_INVALID_HANDLE);
|
2007-11-15 03:08:46 +00:00
|
|
|
break;
|
2007-09-20 14:26:43 +00:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-11-15 03:08:46 +00:00
|
|
|
if (g_ObjectHeapTypeShared[uType])
|
|
|
|
ret = SharedPtrToUser(pEntry->ptr);
|
|
|
|
else
|
|
|
|
ret = DesktopPtrToUser(pEntry->ptr);
|
2007-09-20 14:26:43 +00:00
|
|
|
|
2007-11-15 03:08:46 +00:00
|
|
|
return ret;
|
|
|
|
}
|
2007-11-15 05:42:44 +00:00
|
|
|
|
2007-11-16 09:03:51 +00:00
|
|
|
//
|
|
|
|
// Validate Handle and return the pointer to the object.
|
|
|
|
//
|
|
|
|
PVOID
|
|
|
|
FASTCALL
|
|
|
|
ValidateHandleNoErr(HANDLE handle, UINT uType)
|
|
|
|
{
|
|
|
|
PVOID ret;
|
|
|
|
PUSER_HANDLE_ENTRY pEntry;
|
|
|
|
|
2008-07-29 18:53:46 +00:00
|
|
|
ASSERT(uType <= VALIDATE_TYPE_EVENT);
|
2007-11-16 09:03:51 +00:00
|
|
|
|
|
|
|
pEntry = GetUser32Handle(handle);
|
|
|
|
|
|
|
|
if (pEntry && uType == 0)
|
|
|
|
uType = pEntry->type;
|
|
|
|
|
|
|
|
// Must have an entry and must be the same type!
|
|
|
|
if ( (!pEntry) || (pEntry->type != uType) || !pEntry->ptr )
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (g_ObjectHeapTypeShared[uType])
|
|
|
|
ret = SharedPtrToUser(pEntry->ptr);
|
|
|
|
else
|
|
|
|
ret = DesktopPtrToUser(pEntry->ptr);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2007-11-15 05:42:44 +00:00
|
|
|
//
|
2007-11-15 19:42:41 +00:00
|
|
|
// Validate a callproc handle and return the pointer to the object.
|
2007-11-15 05:42:44 +00:00
|
|
|
//
|
2009-07-25 00:41:22 +00:00
|
|
|
PCALLPROCDATA
|
2007-11-15 05:42:44 +00:00
|
|
|
FASTCALL
|
|
|
|
ValidateCallProc(HANDLE hCallProc)
|
|
|
|
{
|
2009-07-25 00:41:22 +00:00
|
|
|
PUSER_HANDLE_ENTRY pEntry;
|
2007-11-15 05:42:44 +00:00
|
|
|
|
2009-07-25 00:41:22 +00:00
|
|
|
PCALLPROCDATA CallProc = ValidateHandle(hCallProc, VALIDATE_TYPE_CALLPROC);
|
|
|
|
|
|
|
|
pEntry = GetUser32Handle(hCallProc);
|
|
|
|
|
|
|
|
if (CallProc != NULL && pEntry->ppi == g_ppi)
|
|
|
|
return CallProc;
|
|
|
|
|
|
|
|
return NULL;
|
2007-11-15 05:42:44 +00:00
|
|
|
}
|
2007-11-15 19:42:41 +00:00
|
|
|
|
2010-01-15 13:47:25 +00:00
|
|
|
|
2007-11-15 19:42:41 +00:00
|
|
|
//
|
|
|
|
// Validate a window handle and return the pointer to the object.
|
|
|
|
//
|
2009-07-22 05:23:08 +00:00
|
|
|
PWND
|
2007-11-15 19:42:41 +00:00
|
|
|
FASTCALL
|
|
|
|
ValidateHwnd(HWND hwnd)
|
|
|
|
{
|
2009-07-22 05:23:08 +00:00
|
|
|
PWND Wnd;
|
2008-10-14 21:03:20 +00:00
|
|
|
PCLIENTINFO ClientInfo = GetWin32ClientInfo();
|
2007-11-15 19:42:41 +00:00
|
|
|
ASSERT(ClientInfo != NULL);
|
|
|
|
|
|
|
|
/* See if the window is cached */
|
2008-10-14 21:03:20 +00:00
|
|
|
if (hwnd == ClientInfo->CallbackWnd.hWnd)
|
2010-10-11 03:41:41 +00:00
|
|
|
return ClientInfo->CallbackWnd.pWnd;
|
2007-11-15 19:42:41 +00:00
|
|
|
|
2007-11-16 08:03:04 +00:00
|
|
|
Wnd = ValidateHandle((HANDLE)hwnd, VALIDATE_TYPE_WIN);
|
2007-11-16 09:03:51 +00:00
|
|
|
if (Wnd != NULL)
|
|
|
|
{
|
|
|
|
return Wnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Validate a window handle and return the pointer to the object.
|
|
|
|
//
|
2009-07-22 05:23:08 +00:00
|
|
|
PWND
|
2007-11-16 09:03:51 +00:00
|
|
|
FASTCALL
|
|
|
|
ValidateHwndNoErr(HWND hwnd)
|
|
|
|
{
|
2009-07-22 05:23:08 +00:00
|
|
|
PWND Wnd;
|
2008-10-14 21:03:20 +00:00
|
|
|
PCLIENTINFO ClientInfo = GetWin32ClientInfo();
|
2007-11-16 09:03:51 +00:00
|
|
|
ASSERT(ClientInfo != NULL);
|
|
|
|
|
|
|
|
/* See if the window is cached */
|
2008-10-14 21:03:20 +00:00
|
|
|
if (hwnd == ClientInfo->CallbackWnd.hWnd)
|
2010-10-11 03:41:41 +00:00
|
|
|
return ClientInfo->CallbackWnd.pWnd;
|
2007-11-16 09:03:51 +00:00
|
|
|
|
|
|
|
Wnd = ValidateHandleNoErr((HANDLE)hwnd, VALIDATE_TYPE_WIN);
|
2007-11-15 19:42:41 +00:00
|
|
|
if (Wnd != NULL)
|
|
|
|
{
|
|
|
|
return Wnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
2007-11-16 08:03:04 +00:00
|
|
|
|
2009-07-22 05:23:08 +00:00
|
|
|
PWND
|
2007-11-16 08:03:04 +00:00
|
|
|
FASTCALL
|
|
|
|
GetThreadDesktopWnd(VOID)
|
|
|
|
{
|
2010-01-14 00:43:54 +00:00
|
|
|
PWND Wnd = GetThreadDesktopInfo()->spwnd;
|
2007-11-16 08:03:04 +00:00
|
|
|
if (Wnd != NULL)
|
|
|
|
Wnd = DesktopPtrToUser(Wnd);
|
|
|
|
return Wnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Validate a window handle and return the pointer to the object.
|
|
|
|
//
|
2009-07-22 05:23:08 +00:00
|
|
|
PWND
|
2007-11-16 08:03:04 +00:00
|
|
|
FASTCALL
|
|
|
|
ValidateHwndOrDesk(HWND hwnd)
|
|
|
|
{
|
|
|
|
if (hwnd == HWND_DESKTOP)
|
|
|
|
return GetThreadDesktopWnd();
|
|
|
|
|
|
|
|
return ValidateHwnd(hwnd);
|
|
|
|
}
|
2009-01-12 02:46:45 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
DWORD WINAPI WCSToMBEx(WORD CodePage,LPWSTR UnicodeString,LONG UnicodeSize,LPSTR *MBString,LONG MBSize,BOOL Allocate)
|
|
|
|
{
|
|
|
|
DWORD Size;
|
|
|
|
if (UnicodeSize == -1)
|
|
|
|
{
|
|
|
|
UnicodeSize = wcslen(UnicodeString)+1;
|
|
|
|
}
|
|
|
|
if (MBSize == -1)
|
|
|
|
{
|
|
|
|
if (!Allocate)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
MBSize = UnicodeSize * 2;
|
|
|
|
}
|
|
|
|
if (Allocate)
|
|
|
|
{
|
|
|
|
LPSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, MBSize);
|
|
|
|
if (SafeString == NULL)
|
|
|
|
return 0;
|
|
|
|
*MBString = SafeString;
|
|
|
|
}
|
|
|
|
if (CodePage == 0)
|
|
|
|
{
|
|
|
|
RtlUnicodeToMultiByteN(*MBString,MBSize,&Size,UnicodeString,UnicodeSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
WideCharToMultiByte(CodePage,0,UnicodeString,UnicodeSize,*MBString,MBSize,0,0);
|
|
|
|
}
|
|
|
|
return UnicodeSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
DWORD WINAPI MBToWCSEx(WORD CodePage,LPSTR MBString,LONG MBSize,LPWSTR *UnicodeString,LONG UnicodeSize,BOOL Allocate)
|
|
|
|
{
|
|
|
|
DWORD Size;
|
|
|
|
if (MBSize == -1)
|
|
|
|
{
|
|
|
|
MBSize = strlen(MBString)+1;
|
|
|
|
}
|
|
|
|
if (UnicodeSize == -1)
|
|
|
|
{
|
|
|
|
if (!Allocate)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
UnicodeSize = MBSize;
|
|
|
|
}
|
|
|
|
if (Allocate)
|
|
|
|
{
|
|
|
|
LPWSTR SafeString = RtlAllocateHeap(GetProcessHeap(), 0, UnicodeSize);
|
|
|
|
if (SafeString == NULL)
|
|
|
|
return 0;
|
|
|
|
*UnicodeString = SafeString;
|
|
|
|
}
|
|
|
|
UnicodeSize *= sizeof(WCHAR);
|
|
|
|
if (CodePage == 0)
|
|
|
|
{
|
|
|
|
RtlMultiByteToUnicodeN(*UnicodeString,UnicodeSize,&Size,MBString,MBSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
Size = MultiByteToWideChar(CodePage,0,MBString,MBSize,*UnicodeString,UnicodeSize);
|
|
|
|
}
|
|
|
|
return Size;
|
|
|
|
}
|