ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

win32.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.