Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenwin32.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Kernel 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: ntoskrnl/ps/win32.c 00005 * PURPOSE: Process Manager: Win32K Initialization and Support 00006 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) 00007 */ 00008 00009 /* INCLUDES ****************************************************************/ 00010 00011 #include <ntoskrnl.h> 00012 #include <winerror.h> 00013 #define NDEBUG 00014 #include <debug.h> 00015 00016 /* GLOBALS ******************************************************************/ 00017 00018 PKWIN32_PROCESS_CALLOUT PspW32ProcessCallout = NULL; 00019 PKWIN32_THREAD_CALLOUT PspW32ThreadCallout = NULL; 00020 PGDI_BATCHFLUSH_ROUTINE KeGdiFlushUserBatch = NULL; 00021 extern PKWIN32_PARSEMETHOD_CALLOUT ExpWindowStationObjectParse; 00022 extern PKWIN32_DELETEMETHOD_CALLOUT ExpWindowStationObjectDelete; 00023 extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpWindowStationObjectOkToClose; 00024 extern PKWIN32_OKTOCLOSEMETHOD_CALLOUT ExpDesktopObjectOkToClose; 00025 extern PKWIN32_DELETEMETHOD_CALLOUT ExpDesktopObjectDelete; 00026 extern PKWIN32_POWEREVENT_CALLOUT PopEventCallout; 00027 00028 /* PRIVATE FUNCTIONS *********************************************************/ 00029 00030 NTSTATUS 00031 NTAPI 00032 PsConvertToGuiThread(VOID) 00033 { 00034 ULONG_PTR NewStack; 00035 PVOID OldStack; 00036 PETHREAD Thread = PsGetCurrentThread(); 00037 PEPROCESS Process = PsGetCurrentProcess(); 00038 NTSTATUS Status; 00039 PAGED_CODE(); 00040 00041 /* Validate the previous mode */ 00042 if (KeGetPreviousMode() == KernelMode) return STATUS_INVALID_PARAMETER; 00043 00044 /* If no win32k, crashes later */ 00045 ASSERT(PspW32ProcessCallout != NULL); 00046 00047 /* Make sure win32k is here */ 00048 if (!PspW32ProcessCallout) return STATUS_ACCESS_DENIED; 00049 00050 /* Make sure it's not already win32 */ 00051 if (Thread->Tcb.ServiceTable != KeServiceDescriptorTable) 00052 { 00053 /* We're already a win32 thread */ 00054 return STATUS_ALREADY_WIN32; 00055 } 00056 00057 /* Check if we don't already have a kernel-mode stack */ 00058 if (!Thread->Tcb.LargeStack) 00059 { 00060 /* We don't create one */ 00061 NewStack = (ULONG_PTR)MmCreateKernelStack(TRUE, 0); 00062 if (!NewStack) 00063 { 00064 /* Panic in user-mode */ 00065 NtCurrentTeb()->LastErrorValue = ERROR_NOT_ENOUGH_MEMORY; 00066 return STATUS_NO_MEMORY; 00067 } 00068 00069 /* We're about to switch stacks. Enter a guarded region */ 00070 KeEnterGuardedRegion(); 00071 00072 /* Switch stacks */ 00073 OldStack = KeSwitchKernelStack((PVOID)NewStack, 00074 (PVOID)(NewStack - KERNEL_STACK_SIZE)); 00075 00076 /* Leave the guarded region */ 00077 KeLeaveGuardedRegion(); 00078 00079 /* Delete the old stack */ 00080 MmDeleteKernelStack(OldStack, FALSE); 00081 } 00082 00083 /* This check is bizare. Check out win32k later */ 00084 if (!Process->Win32Process) 00085 { 00086 /* Now tell win32k about us */ 00087 Status = PspW32ProcessCallout(Process, TRUE); 00088 if (!NT_SUCCESS(Status)) return Status; 00089 } 00090 00091 /* Set the new service table */ 00092 Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow; 00093 ASSERT(Thread->Tcb.Win32Thread == 0); 00094 00095 /* Tell Win32k about our thread */ 00096 Status = PspW32ThreadCallout(Thread, PsW32ThreadCalloutInitialize); 00097 if (!NT_SUCCESS(Status)) 00098 { 00099 /* Revert our table */ 00100 Thread->Tcb.ServiceTable = KeServiceDescriptorTable; 00101 } 00102 00103 /* Return status */ 00104 return Status; 00105 } 00106 00107 /* PUBLIC FUNCTIONS **********************************************************/ 00108 00109 /* 00110 * @implemented 00111 */ 00112 VOID 00113 NTAPI 00114 PsEstablishWin32Callouts(IN PWIN32_CALLOUTS_FPNS CalloutData) 00115 { 00116 /* Setup the callback pointers */ 00117 PspW32ProcessCallout = CalloutData->ProcessCallout; 00118 PspW32ThreadCallout = CalloutData->ThreadCallout; 00119 ExpWindowStationObjectParse = CalloutData->WindowStationParseProcedure; 00120 ExpWindowStationObjectDelete = CalloutData->WindowStationDeleteProcedure; 00121 ExpWindowStationObjectOkToClose = CalloutData->WindowStationOkToCloseProcedure; 00122 ExpDesktopObjectOkToClose = CalloutData->DesktopOkToCloseProcedure; 00123 ExpDesktopObjectDelete = CalloutData->DesktopDeleteProcedure; 00124 PopEventCallout = CalloutData->PowerEventCallout; 00125 KeGdiFlushUserBatch = CalloutData->BatchFlushRoutine; 00126 } 00127 00128 NTSTATUS 00129 NTAPI 00130 NtW32Call(IN ULONG RoutineIndex, 00131 IN PVOID Argument, 00132 IN ULONG ArgumentLength, 00133 OUT PVOID* Result, 00134 OUT PULONG ResultLength) 00135 { 00136 PVOID RetResult; 00137 ULONG RetResultLength; 00138 NTSTATUS Status; 00139 ASSERT(KeGetPreviousMode() != KernelMode); 00140 00141 /* Enter SEH for probing */ 00142 _SEH2_TRY 00143 { 00144 /* Probe arguments */ 00145 ProbeForWritePointer(Result); 00146 ProbeForWriteUlong(ResultLength); 00147 } 00148 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00149 { 00150 /* Return the exception code */ 00151 _SEH2_YIELD(return _SEH2_GetExceptionCode()); 00152 } 00153 _SEH2_END; 00154 00155 /* Call kernel function */ 00156 Status = KeUserModeCallback(RoutineIndex, 00157 Argument, 00158 ArgumentLength, 00159 &RetResult, 00160 &RetResultLength); 00161 if (NT_SUCCESS(Status)) 00162 { 00163 /* Enter SEH for write back */ 00164 _SEH2_TRY 00165 { 00166 /* Return results to user mode */ 00167 *Result = RetResult; 00168 *ResultLength = RetResultLength; 00169 } 00170 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00171 { 00172 /* Get the exception code */ 00173 Status = _SEH2_GetExceptionCode(); 00174 } 00175 _SEH2_END; 00176 } 00177 00178 /* Return the result */ 00179 return Status; 00180 } 00181 00182 /* EOF */ Generated on Sat May 26 2012 04:16:07 for ReactOS by
1.7.6.1
|