2003-05-18 17:16:18 +00:00
|
|
|
/*
|
|
|
|
* ReactOS W32 Subsystem
|
2005-01-06 23:12:59 +00:00
|
|
|
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 ReactOS Team
|
2003-05-18 17:16:18 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
2009-10-27 10:34:16 +00:00
|
|
|
* 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.,
|
|
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
2003-05-18 17:16:18 +00:00
|
|
|
*/
|
2009-10-03 02:30:47 +00:00
|
|
|
/*
|
1999-05-22 23:55:56 +00:00
|
|
|
* Entry Point for win32k.sys
|
|
|
|
*/
|
2005-06-29 07:09:25 +00:00
|
|
|
|
2004-05-10 17:07:20 +00:00
|
|
|
#include <w32k.h>
|
2005-06-25 20:05:56 +00:00
|
|
|
#include <include/napi.h>
|
2004-11-20 16:46:06 +00:00
|
|
|
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
2002-07-13 21:37:27 +00:00
|
|
|
|
2009-07-13 05:00:17 +00:00
|
|
|
HANDLE hModuleWin;
|
|
|
|
|
2006-04-01 15:25:40 +00:00
|
|
|
PGDI_HANDLE_TABLE INTERNAL_CALL GDIOBJ_iAllocHandleTable(OUT PSECTION_OBJECT *SectionObject);
|
2008-02-26 23:09:20 +00:00
|
|
|
BOOL INTERNAL_CALL GDI_CleanupForProcess (struct _EPROCESS *Process);
|
2006-04-01 15:25:40 +00:00
|
|
|
/* FIXME */
|
|
|
|
PGDI_HANDLE_TABLE GdiHandleTable = NULL;
|
|
|
|
PSECTION_OBJECT GdiTableSection = NULL;
|
2004-12-12 01:40:39 +00:00
|
|
|
|
2006-04-05 08:05:55 +00:00
|
|
|
HANDLE GlobalUserHeap = NULL;
|
|
|
|
PSECTION_OBJECT GlobalUserHeapSection = NULL;
|
|
|
|
|
2008-04-14 10:51:53 +00:00
|
|
|
PSERVERINFO gpsi = NULL; // Global User Server Information.
|
|
|
|
|
2008-06-17 05:33:46 +00:00
|
|
|
HSEMAPHORE hsemDriverMgmt = NULL;
|
|
|
|
|
2008-10-30 10:46:27 +00:00
|
|
|
SHORT gusLanguageID;
|
|
|
|
|
2005-09-05 04:48:20 +00:00
|
|
|
extern ULONG_PTR Win32kSSDT[];
|
|
|
|
extern UCHAR Win32kSSPT[];
|
2002-07-04 19:56:38 +00:00
|
|
|
extern ULONG Win32kNumberOfSysCalls;
|
1999-07-12 23:26:57 +00:00
|
|
|
|
2007-10-19 23:21:45 +00:00
|
|
|
NTSTATUS
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2005-06-26 18:00:22 +00:00
|
|
|
Win32kProcessCallback(struct _EPROCESS *Process,
|
|
|
|
BOOLEAN Create)
|
2003-06-20 16:26:53 +00:00
|
|
|
{
|
2009-07-26 16:17:50 +00:00
|
|
|
PPROCESSINFO Win32Process;
|
2005-09-05 21:19:23 +00:00
|
|
|
DECLARE_RETURN(NTSTATUS);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
DPRINT("Enter Win32kProcessCallback\n");
|
|
|
|
UserEnterExclusive();
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-26 18:00:22 +00:00
|
|
|
/* Get the Win32 Process */
|
|
|
|
Win32Process = PsGetProcessWin32Process(Process);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-26 18:00:22 +00:00
|
|
|
/* Allocate one if needed */
|
|
|
|
if (!Win32Process)
|
|
|
|
{
|
|
|
|
/* FIXME - lock the process */
|
|
|
|
Win32Process = ExAllocatePoolWithTag(NonPagedPool,
|
2009-05-23 00:57:51 +00:00
|
|
|
sizeof(PROCESSINFO),
|
2009-08-24 17:12:25 +00:00
|
|
|
'p23W');
|
2005-06-26 18:00:22 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
if (Win32Process == NULL) RETURN( STATUS_NO_MEMORY);
|
2005-06-26 18:00:22 +00:00
|
|
|
|
2009-05-23 00:57:51 +00:00
|
|
|
RtlZeroMemory(Win32Process, sizeof(PROCESSINFO));
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-26 18:00:22 +00:00
|
|
|
PsSetProcessWin32Process(Process, Win32Process);
|
|
|
|
/* FIXME - unlock the process */
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-06-20 16:26:53 +00:00
|
|
|
if (Create)
|
|
|
|
{
|
2008-04-25 01:42:25 +00:00
|
|
|
SIZE_T ViewSize = 0;
|
2006-04-05 08:05:55 +00:00
|
|
|
LARGE_INTEGER Offset;
|
|
|
|
PVOID UserBase = NULL;
|
|
|
|
NTSTATUS Status;
|
|
|
|
extern PSECTION_OBJECT GlobalUserHeapSection;
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT("Creating W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
2003-06-20 16:26:53 +00:00
|
|
|
|
2006-04-05 08:05:55 +00:00
|
|
|
/* map the global heap into the process */
|
|
|
|
Offset.QuadPart = 0;
|
|
|
|
Status = MmMapViewOfSection(GlobalUserHeapSection,
|
|
|
|
PsGetCurrentProcess(),
|
|
|
|
&UserBase,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
&Offset,
|
|
|
|
&ViewSize,
|
|
|
|
ViewUnmap,
|
|
|
|
SEC_NO_CHANGE,
|
|
|
|
PAGE_EXECUTE_READ); /* would prefer PAGE_READONLY, but thanks to RTL heaps... */
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to map the global heap! 0x%x\n", Status);
|
|
|
|
RETURN(Status);
|
|
|
|
}
|
|
|
|
Win32Process->HeapMappings.Next = NULL;
|
|
|
|
Win32Process->HeapMappings.KernelMapping = (PVOID)GlobalUserHeap;
|
|
|
|
Win32Process->HeapMappings.UserMapping = UserBase;
|
|
|
|
Win32Process->HeapMappings.Count = 1;
|
|
|
|
|
2005-09-24 02:50:02 +00:00
|
|
|
InitializeListHead(&Win32Process->ClassList);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2003-07-31 23:11:38 +00:00
|
|
|
InitializeListHead(&Win32Process->MenuListHead);
|
2003-06-20 16:26:53 +00:00
|
|
|
|
2009-12-28 07:02:32 +00:00
|
|
|
InitializeListHead(&Win32Process->GDIBrushAttrFreeList);
|
|
|
|
InitializeListHead(&Win32Process->GDIDcAttrFreeList);
|
|
|
|
|
2003-12-12 23:49:48 +00:00
|
|
|
InitializeListHead(&Win32Process->PrivateFontListHead);
|
|
|
|
ExInitializeFastMutex(&Win32Process->PrivateFontListLock);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-01-06 23:12:59 +00:00
|
|
|
InitializeListHead(&Win32Process->DriverObjListHead);
|
|
|
|
ExInitializeFastMutex(&Win32Process->DriverObjListLock);
|
|
|
|
|
2003-10-09 06:13:05 +00:00
|
|
|
Win32Process->KeyboardLayout = W32kGetDefaultKeyLayout();
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2005-02-18 01:57:32 +00:00
|
|
|
if(Process->Peb != NULL)
|
|
|
|
{
|
|
|
|
/* map the gdi handle table to user land */
|
2006-04-01 15:25:40 +00:00
|
|
|
Process->Peb->GdiSharedHandleTable = GDI_MapHandleTable(GdiTableSection, Process);
|
2007-11-02 02:56:21 +00:00
|
|
|
Process->Peb->GdiDCAttributeList = GDI_BATCH_LIMIT;
|
2005-02-18 01:57:32 +00:00
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2009-10-06 03:38:23 +00:00
|
|
|
Win32Process->peProcess = Process;
|
2004-05-21 10:09:31 +00:00
|
|
|
/* setup process flags */
|
2009-03-30 03:56:53 +00:00
|
|
|
Win32Process->W32PF_flags = 0;
|
2003-06-20 16:26:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT("Destroying W32 process PID:%d at IRQ level: %lu\n", Process->UniqueProcessId, KeGetCurrentIrql());
|
2003-08-19 11:48:50 +00:00
|
|
|
IntCleanupMenus(Process, Win32Process);
|
2003-12-13 22:38:29 +00:00
|
|
|
IntCleanupCurIcons(Process, Win32Process);
|
2004-11-16 16:29:21 +00:00
|
|
|
CleanupMonitorImpl();
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-24 02:50:02 +00:00
|
|
|
/* no process windows should exist at this point, or the function will assert! */
|
|
|
|
DestroyProcessClasses(Win32Process);
|
2005-01-06 23:12:59 +00:00
|
|
|
|
2008-02-26 23:09:20 +00:00
|
|
|
GDI_CleanupForProcess(Process);
|
2004-12-24 17:45:59 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntGraphicsCheck(FALSE);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2004-05-01 16:43:15 +00:00
|
|
|
/*
|
|
|
|
* Deregister logon application automatically
|
|
|
|
*/
|
|
|
|
if(LogonProcess == Win32Process)
|
|
|
|
{
|
|
|
|
LogonProcess = NULL;
|
|
|
|
}
|
2003-06-20 16:26:53 +00:00
|
|
|
}
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
RETURN( STATUS_SUCCESS);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
|
|
|
UserLeave();
|
|
|
|
DPRINT("Leave Win32kProcessCallback, ret=%i\n",_ret_);
|
|
|
|
END_CLEANUP;
|
2003-06-20 16:26:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-10-19 23:21:45 +00:00
|
|
|
NTSTATUS
|
2008-11-29 22:48:58 +00:00
|
|
|
APIENTRY
|
2005-06-26 18:00:22 +00:00
|
|
|
Win32kThreadCallback(struct _ETHREAD *Thread,
|
2006-05-10 17:47:44 +00:00
|
|
|
PSW32THREADCALLOUTTYPE Type)
|
2003-06-20 16:26:53 +00:00
|
|
|
{
|
2005-06-26 18:00:22 +00:00
|
|
|
struct _EPROCESS *Process;
|
2008-10-16 17:52:38 +00:00
|
|
|
PTHREADINFO Win32Thread;
|
2005-09-05 21:19:23 +00:00
|
|
|
DECLARE_RETURN(NTSTATUS);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
DPRINT("Enter Win32kThreadCallback\n");
|
|
|
|
UserEnterExclusive();
|
2005-06-26 18:00:22 +00:00
|
|
|
|
|
|
|
Process = Thread->ThreadsProcess;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-26 18:00:22 +00:00
|
|
|
/* Get the Win32 Thread */
|
|
|
|
Win32Thread = PsGetThreadWin32Thread(Thread);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-26 18:00:22 +00:00
|
|
|
/* Allocate one if needed */
|
|
|
|
if (!Win32Thread)
|
|
|
|
{
|
|
|
|
/* FIXME - lock the process */
|
|
|
|
Win32Thread = ExAllocatePoolWithTag(NonPagedPool,
|
2008-10-16 17:52:38 +00:00
|
|
|
sizeof(THREADINFO),
|
2009-08-24 17:12:25 +00:00
|
|
|
't23W');
|
2003-06-20 16:26:53 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
if (Win32Thread == NULL) RETURN( STATUS_NO_MEMORY);
|
2005-06-26 18:00:22 +00:00
|
|
|
|
2008-10-16 17:52:38 +00:00
|
|
|
RtlZeroMemory(Win32Thread, sizeof(THREADINFO));
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-06-26 18:00:22 +00:00
|
|
|
PsSetThreadWin32Thread(Thread, Win32Thread);
|
|
|
|
/* FIXME - unlock the process */
|
|
|
|
}
|
2006-05-10 17:47:44 +00:00
|
|
|
if (Type == PsW32ThreadCalloutInitialize)
|
2003-06-20 16:26:53 +00:00
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
HWINSTA hWinSta = NULL;
|
2008-10-18 23:01:57 +00:00
|
|
|
PTEB pTeb;
|
2004-11-20 16:46:06 +00:00
|
|
|
HDESK hDesk = NULL;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PUNICODE_STRING DesktopPath;
|
|
|
|
PRTL_USER_PROCESS_PARAMETERS ProcessParams = (Process->Peb ? Process->Peb->ProcessParameters : NULL);
|
|
|
|
|
|
|
|
DPRINT("Creating W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2006-04-15 10:41:58 +00:00
|
|
|
InitializeListHead(&Win32Thread->WindowListHead);
|
|
|
|
InitializeListHead(&Win32Thread->W32CallbackListHead);
|
2008-10-18 19:54:59 +00:00
|
|
|
InitializeListHead(&Win32Thread->PtiLink);
|
2006-04-15 10:41:58 +00:00
|
|
|
|
2004-11-20 16:46:06 +00:00
|
|
|
/*
|
|
|
|
* inherit the thread desktop and process window station (if not yet inherited) from the process startup
|
|
|
|
* info structure. See documentation of CreateProcess()
|
|
|
|
*/
|
|
|
|
DesktopPath = (ProcessParams ? ((ProcessParams->DesktopInfo.Length > 0) ? &ProcessParams->DesktopInfo : NULL) : NULL);
|
|
|
|
Status = IntParseDesktopPath(Process,
|
|
|
|
DesktopPath,
|
|
|
|
&hWinSta,
|
|
|
|
&hDesk);
|
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
if(hWinSta != NULL)
|
|
|
|
{
|
|
|
|
if(Process != CsrProcess)
|
|
|
|
{
|
|
|
|
HWINSTA hProcessWinSta = (HWINSTA)InterlockedCompareExchangePointer((PVOID)&Process->Win32WindowStation, (PVOID)hWinSta, NULL);
|
|
|
|
if(hProcessWinSta != NULL)
|
|
|
|
{
|
|
|
|
/* our process is already assigned to a different window station, we don't need the handle anymore */
|
|
|
|
NtClose(hWinSta);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NtClose(hWinSta);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-04-09 17:10:25 +00:00
|
|
|
if (hDesk != NULL)
|
2004-11-20 16:46:06 +00:00
|
|
|
{
|
2008-10-17 13:09:56 +00:00
|
|
|
PDESKTOP DesktopObject;
|
2010-01-14 02:52:12 +00:00
|
|
|
Win32Thread->rpdesk = NULL;
|
2005-04-09 17:10:25 +00:00
|
|
|
Status = ObReferenceObjectByHandle(hDesk,
|
|
|
|
0,
|
|
|
|
ExDesktopObjectType,
|
|
|
|
KernelMode,
|
2006-04-05 08:05:55 +00:00
|
|
|
(PVOID*)&DesktopObject,
|
2005-04-09 17:10:25 +00:00
|
|
|
NULL);
|
2004-11-20 16:46:06 +00:00
|
|
|
NtClose(hDesk);
|
2006-04-05 08:05:55 +00:00
|
|
|
if(NT_SUCCESS(Status))
|
|
|
|
{
|
2006-04-15 10:41:58 +00:00
|
|
|
if (!IntSetThreadDesktop(DesktopObject,
|
|
|
|
FALSE))
|
2006-04-05 08:05:55 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Unable to set thread desktop\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2005-04-09 17:10:25 +00:00
|
|
|
{
|
|
|
|
DPRINT1("Unable to reference thread desktop handle 0x%x\n", hDesk);
|
|
|
|
}
|
2004-11-20 16:46:06 +00:00
|
|
|
}
|
|
|
|
}
|
2009-10-03 23:39:30 +00:00
|
|
|
Win32Thread->TIF_flags &= ~TIF_INCLEANUP;
|
2005-09-05 21:19:23 +00:00
|
|
|
co_IntDestroyCaret(Win32Thread);
|
2008-10-18 19:54:59 +00:00
|
|
|
Win32Thread->ppi = PsGetCurrentProcessWin32Process();
|
2008-10-18 23:01:57 +00:00
|
|
|
pTeb = NtCurrentTeb();
|
|
|
|
if (pTeb)
|
2008-11-11 23:11:39 +00:00
|
|
|
{
|
2008-10-18 23:01:57 +00:00
|
|
|
Win32Thread->pClientInfo = (PCLIENTINFO)pTeb->Win32ClientInfo;
|
2008-11-11 23:11:39 +00:00
|
|
|
Win32Thread->pClientInfo->pClientThreadInfo = NULL;
|
|
|
|
}
|
2003-11-18 23:33:31 +00:00
|
|
|
Win32Thread->MessageQueue = MsqCreateMessageQueue(Thread);
|
2003-10-09 06:13:05 +00:00
|
|
|
Win32Thread->KeyboardLayout = W32kGetDefaultKeyLayout();
|
2009-09-13 22:06:58 +00:00
|
|
|
Win32Thread->pEThread = Thread;
|
2003-06-20 16:26:53 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2005-09-07 20:59:26 +00:00
|
|
|
PSINGLE_LIST_ENTRY e;
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT("Destroying W32 thread TID:%d at IRQ level: %lu\n", Thread->Cid.UniqueThread, KeGetCurrentIrql());
|
2003-06-20 16:26:53 +00:00
|
|
|
|
2009-10-03 02:30:47 +00:00
|
|
|
Win32Thread->TIF_flags |= TIF_INCLEANUP;
|
2010-01-28 01:00:09 +00:00
|
|
|
DceFreeThreadDCE(Win32Thread);
|
2003-12-12 14:22:37 +00:00
|
|
|
HOOK_DestroyThreadHooks(Thread);
|
2003-11-03 18:52:21 +00:00
|
|
|
UnregisterThreadHotKeys(Thread);
|
2005-09-07 20:59:26 +00:00
|
|
|
/* what if this co_ func crash in umode? what will clean us up then? */
|
2005-09-05 21:19:23 +00:00
|
|
|
co_DestroyThreadWindows(Thread);
|
2004-04-29 20:26:35 +00:00
|
|
|
IntBlockInput(Win32Thread, FALSE);
|
2004-05-22 16:48:50 +00:00
|
|
|
MsqDestroyMessageQueue(Win32Thread->MessageQueue);
|
2004-05-22 21:12:15 +00:00
|
|
|
IntCleanupThreadCallbacks(Win32Thread);
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2005-09-07 20:59:26 +00:00
|
|
|
/* cleanup user object references stack */
|
|
|
|
e = PopEntryList(&Win32Thread->ReferencesList);
|
|
|
|
while (e)
|
|
|
|
{
|
|
|
|
PUSER_REFERENCE_ENTRY ref = CONTAINING_RECORD(e, USER_REFERENCE_ENTRY, Entry);
|
- Fix SleepEx.
- Put volatile statements in EX_RUNDOWN_REF, IRP, DEVICE_OBJECT, ERESOURCE, FILE_OBJECT, IO_REMOVE_LOCK, WORK_QUEUE_ITEM where required (thanks to Microsoft's changes in the WDK to mark the fields properly).
- Update FILE_OBJECT definition.
- Add some asserts to some I/O functions.
- Add stub support for File Objects created by XP+ Drivers which have File Object Extensions.
- Add some fixes to IopDeleteFile, including proper reference counting for the DO and VPB, as well as cleanup when the file is closed without a handle.
- Fix a bug in IopSecurityFile.
- Queue and unqueue IRPs in all I/O functions.
- Fully support IRP cancellation now.
- Fix critical bugs in NtDeviceIoControlFile and NtDeviceFsControlFile which were causing double queueing of IRPs and freeing of invalid memory, as well as invalid paramter checking for user-mode buffers.
- Add exhaustive validation checks to IoCreateFile, add more failure cases, and validate the EA buffer. Also support IO_ATTACH_DEVICE_API flag.
- Implement IoCreateStreamFileObjectEx and IoCreateStreamFileObjectLite and fix several bugs in the original implementation of IoCreateStreamFileObject.
- Fix a bug in RtlRaiseException.
- Update Io*ShareAccess routines to support XP+ style semantics related to special File Object flags which disable their use.
- Add validation to all Query/Set routines so that information clasess, lengths, buffers and alignment are properly checked.
- Also add an array for the proper acess rights that each query/set operation requires.
- Check backup/restore privileges during I/O File operations.
- Check traverse access during I/O File Operations.
- Check access privileges to the device during I/O file operations.
- Rename IopReferenceDeviceObject and also verify if an exclusive DO is trying to be invalidly opened.
- Support various extra security checks during I/O File/Device Parse Routine.
- Fix a bug during IopCleanupIrp so that we don't dereference the File OBject if this was a create operation.
- Fix some bogus asserts in IofCompleteRequest, and save the IRP Flags before signalling it's event, since the driver might've freed it behind our back.
- Fix a large bug in ObInsertObject which affected the insert of unnamed objects with forced security options (Such as process/threads).
- Fix the creation of the Process/Thread/Job Obejct Types to that security information is forced.
- Remove "Fix PS!!!" messages since the bug is now fixed and these objects now get proper security descriptors.
- Fix another bug in ObInsertObjet which wasn't properly validating user-mode objects and always assumed kernel mode.
- Silence multiple trace/checkpoint messages that have accumulated throughout time for various debugging purposes.
svn path=/trunk/; revision=25118
2006-12-10 18:40:30 +00:00
|
|
|
DPRINT("thread clean: remove reference obj 0x%x\n",ref->obj);
|
2008-02-13 00:46:23 +00:00
|
|
|
UserDereferenceObject(ref->obj);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-07 20:59:26 +00:00
|
|
|
e = PopEntryList(&Win32Thread->ReferencesList);
|
|
|
|
}
|
2006-04-15 10:41:58 +00:00
|
|
|
|
|
|
|
IntSetThreadDesktop(NULL,
|
|
|
|
TRUE);
|
|
|
|
|
2005-12-08 00:14:59 +00:00
|
|
|
PsSetThreadWin32Thread(Thread, NULL);
|
2003-06-20 16:26:53 +00:00
|
|
|
}
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
RETURN( STATUS_SUCCESS);
|
2007-10-19 23:21:45 +00:00
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
CLEANUP:
|
|
|
|
UserLeave();
|
|
|
|
DPRINT("Leave Win32kThreadCallback, ret=%i\n",_ret_);
|
|
|
|
END_CLEANUP;
|
2003-06-20 16:26:53 +00:00
|
|
|
}
|
|
|
|
|
2005-05-14 18:03:31 +00:00
|
|
|
/* Only used in ntuser/input.c KeyboardThreadMain(). If it's
|
|
|
|
not called there anymore, please delete */
|
|
|
|
NTSTATUS
|
|
|
|
Win32kInitWin32Thread(PETHREAD Thread)
|
|
|
|
{
|
|
|
|
PEPROCESS Process;
|
|
|
|
|
|
|
|
Process = Thread->ThreadsProcess;
|
|
|
|
|
|
|
|
if (Process->Win32Process == NULL)
|
|
|
|
{
|
|
|
|
/* FIXME - lock the process */
|
2009-05-23 00:57:51 +00:00
|
|
|
Process->Win32Process = ExAllocatePool(NonPagedPool, sizeof(PROCESSINFO));
|
2005-05-14 18:03:31 +00:00
|
|
|
|
|
|
|
if (Process->Win32Process == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
|
2009-05-23 00:57:51 +00:00
|
|
|
RtlZeroMemory(Process->Win32Process, sizeof(PROCESSINFO));
|
2005-05-14 18:03:31 +00:00
|
|
|
/* FIXME - unlock the process */
|
|
|
|
|
|
|
|
Win32kProcessCallback(Process, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Thread->Tcb.Win32Thread == NULL)
|
|
|
|
{
|
2008-10-16 17:52:38 +00:00
|
|
|
Thread->Tcb.Win32Thread = ExAllocatePool (NonPagedPool, sizeof(THREADINFO));
|
2005-05-14 18:03:31 +00:00
|
|
|
if (Thread->Tcb.Win32Thread == NULL)
|
|
|
|
return STATUS_NO_MEMORY;
|
|
|
|
|
2008-10-16 17:52:38 +00:00
|
|
|
RtlZeroMemory(Thread->Tcb.Win32Thread, sizeof(THREADINFO));
|
2005-05-14 18:03:31 +00:00
|
|
|
|
2006-05-10 17:47:44 +00:00
|
|
|
Win32kThreadCallback(Thread, PsW32ThreadCalloutInitialize);
|
2005-05-14 18:03:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return(STATUS_SUCCESS);
|
|
|
|
}
|
|
|
|
|
2010-01-30 21:12:42 +00:00
|
|
|
C_ASSERT(sizeof(SERVERINFO) <= PAGE_SIZE);
|
2003-06-20 16:26:53 +00:00
|
|
|
|
1999-11-02 08:55:45 +00:00
|
|
|
/*
|
|
|
|
* This definition doesn't work
|
|
|
|
*/
|
2008-11-29 22:48:58 +00:00
|
|
|
NTSTATUS APIENTRY
|
2005-05-16 12:34:01 +00:00
|
|
|
DriverEntry (
|
2001-03-31 15:35:08 +00:00
|
|
|
IN PDRIVER_OBJECT DriverObject,
|
|
|
|
IN PUNICODE_STRING RegistryPath)
|
1999-07-12 23:26:57 +00:00
|
|
|
{
|
2001-06-12 17:51:51 +00:00
|
|
|
NTSTATUS Status;
|
2001-03-31 15:35:08 +00:00
|
|
|
BOOLEAN Result;
|
2006-06-08 19:00:22 +00:00
|
|
|
WIN32_CALLOUTS_FPNS CalloutData = {0};
|
2006-04-05 08:05:55 +00:00
|
|
|
PVOID GlobalUserHeapBase = NULL;
|
2000-02-21 22:44:37 +00:00
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
/*
|
|
|
|
* Register user mode call interface
|
|
|
|
* (system service table index = 1)
|
|
|
|
*/
|
2003-06-20 16:26:53 +00:00
|
|
|
Result = KeAddSystemServiceTable (Win32kSSDT,
|
|
|
|
NULL,
|
|
|
|
Win32kNumberOfSysCalls,
|
|
|
|
Win32kSSPT,
|
|
|
|
1);
|
2001-03-31 15:35:08 +00:00
|
|
|
if (Result == FALSE)
|
2003-06-20 16:26:53 +00:00
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Adding system services failed!\n");
|
2003-06-20 16:26:53 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2009-07-13 05:00:17 +00:00
|
|
|
hModuleWin = MmPageEntireDriver(DriverEntry);
|
2009-09-07 04:55:00 +00:00
|
|
|
DPRINT("Win32k hInstance 0x%x!\n",hModuleWin);
|
2005-06-26 18:00:22 +00:00
|
|
|
/*
|
|
|
|
* Register Object Manager Callbacks
|
|
|
|
*/
|
2006-05-25 20:03:13 +00:00
|
|
|
CalloutData.WindowStationParseProcedure = IntWinStaObjectParse;
|
|
|
|
CalloutData.WindowStationDeleteProcedure = IntWinStaObjectDelete;
|
|
|
|
CalloutData.DesktopDeleteProcedure = IntDesktopObjectDelete;
|
|
|
|
CalloutData.ProcessCallout = Win32kProcessCallback;
|
|
|
|
CalloutData.ThreadCallout = Win32kThreadCallback;
|
2007-10-19 23:21:45 +00:00
|
|
|
CalloutData.BatchFlushRoutine = NtGdiFlushUserBatch;
|
2007-08-23 01:51:22 +00:00
|
|
|
|
2005-06-26 18:00:22 +00:00
|
|
|
/*
|
|
|
|
* Register our per-process and per-thread structures.
|
|
|
|
*/
|
2006-05-10 17:47:44 +00:00
|
|
|
PsEstablishWin32Callouts((PWIN32_CALLOUTS_FPNS)&CalloutData);
|
2005-05-08 02:11:54 +00:00
|
|
|
|
2006-04-05 08:05:55 +00:00
|
|
|
GlobalUserHeap = UserCreateHeap(&GlobalUserHeapSection,
|
|
|
|
&GlobalUserHeapBase,
|
|
|
|
1 * 1024 * 1024); /* FIXME - 1 MB for now... */
|
|
|
|
if (GlobalUserHeap == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to initialize the global heap!\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2010-01-30 21:12:42 +00:00
|
|
|
if (!gpsi)
|
|
|
|
{
|
|
|
|
gpsi = UserHeapAlloc(sizeof(SERVERINFO));
|
|
|
|
if (gpsi)
|
|
|
|
{
|
|
|
|
RtlZeroMemory(gpsi, sizeof(SERVERINFO));
|
|
|
|
DPRINT("Global Server Data -> %x\n", gpsi);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ASSERT(FALSE);
|
|
|
|
}
|
|
|
|
}
|
2006-04-05 08:05:55 +00:00
|
|
|
|
2008-06-17 05:33:46 +00:00
|
|
|
if(!hsemDriverMgmt) hsemDriverMgmt = EngCreateSemaphore();
|
|
|
|
|
2008-10-30 10:46:27 +00:00
|
|
|
GdiHandleTable = GDIOBJ_iAllocHandleTable(&GdiTableSection);
|
|
|
|
if (GdiHandleTable == NULL)
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to initialize the GDI handle table.\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2010-01-30 21:12:42 +00:00
|
|
|
/* Create stock objects, ie. precreated objects commonly
|
|
|
|
used by win32 applications */
|
|
|
|
CreateStockObjects();
|
|
|
|
CreateSysColorObjects();
|
|
|
|
|
|
|
|
InitXlateImpl();
|
|
|
|
InitPDEVImpl();
|
|
|
|
InitLDEVImpl();
|
|
|
|
InitDeviceImpl();
|
|
|
|
|
|
|
|
Status = InitDcImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to initialize Device context implementation!\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2005-09-05 21:19:23 +00:00
|
|
|
Status = InitUserImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to initialize user implementation!\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2005-09-18 23:06:15 +00:00
|
|
|
Status = InitHotkeyImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DPRINT1("Failed to initialize hotkey implementation!\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
Status = InitWindowStationImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize window station implementation!\n");
|
2001-06-12 17:51:51 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2003-11-23 11:39:48 +00:00
|
|
|
Status = InitDesktopImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize desktop implementation!\n");
|
2003-11-23 11:39:48 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2001-06-12 17:51:51 +00:00
|
|
|
Status = InitWindowImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize window implementation!\n");
|
2001-06-12 17:51:51 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
2003-11-03 18:52:21 +00:00
|
|
|
|
2003-07-31 23:11:38 +00:00
|
|
|
Status = InitMenuImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize menu implementation!\n");
|
2003-07-31 23:11:38 +00:00
|
|
|
return STATUS_UNSUCCESSFUL;
|
2003-11-03 18:52:21 +00:00
|
|
|
}
|
|
|
|
|
2002-01-27 01:11:24 +00:00
|
|
|
Status = InitInputImpl();
|
2002-01-13 22:52:08 +00:00
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize input implementation.\n");
|
2002-01-13 22:52:08 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2003-11-24 00:22:53 +00:00
|
|
|
Status = InitKeyboardImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize keyboard implementation.\n");
|
2003-11-24 00:22:53 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2004-11-16 16:29:21 +00:00
|
|
|
Status = InitMonitorImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
DbgPrint("Failed to initialize monitor implementation!\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2002-01-13 22:52:08 +00:00
|
|
|
Status = MsqInitializeImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize message queue implementation.\n");
|
2002-01-13 22:52:08 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2003-04-02 23:19:28 +00:00
|
|
|
Status = InitTimerImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize timer implementation.\n");
|
2003-04-02 23:19:28 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2003-12-07 12:59:34 +00:00
|
|
|
Status = InitAcceleratorImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize accelerator implementation.\n");
|
2003-12-07 12:59:34 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2004-08-08 17:57:34 +00:00
|
|
|
Status = InitGuiCheckImpl();
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
2004-11-20 16:46:06 +00:00
|
|
|
DPRINT1("Failed to initialize GUI check implementation.\n");
|
2004-08-08 17:57:34 +00:00
|
|
|
return(Status);
|
|
|
|
}
|
|
|
|
|
2003-12-03 21:50:50 +00:00
|
|
|
/* Initialize FreeType library */
|
|
|
|
if (! InitFontSupport())
|
|
|
|
{
|
|
|
|
DPRINT1("Unable to initialize font support\n");
|
|
|
|
return STATUS_UNSUCCESSFUL;
|
|
|
|
}
|
|
|
|
|
2008-10-30 10:46:27 +00:00
|
|
|
gusLanguageID = IntGdiGetLanguageID();
|
|
|
|
|
2001-03-31 15:35:08 +00:00
|
|
|
return STATUS_SUCCESS;
|
2000-02-21 22:44:37 +00:00
|
|
|
}
|
2000-02-20 22:52:50 +00:00
|
|
|
|
|
|
|
/* EOF */
|