ReactOS.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
May
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
October
September
August
July
June
May
April
March
February
January
2016
December
November
October
September
August
July
June
May
April
March
February
January
2015
December
November
October
September
August
July
June
May
April
March
February
January
2014
December
November
October
September
August
July
June
May
April
March
February
January
2013
December
November
October
September
August
July
June
May
April
March
February
January
2012
December
November
October
September
August
July
June
May
April
March
February
January
2011
December
November
October
September
August
July
June
May
April
March
February
January
2010
December
November
October
September
August
July
June
May
April
March
February
January
2009
December
November
October
September
August
July
June
May
April
March
February
January
2008
December
November
October
September
August
July
June
May
April
March
February
January
2007
December
November
October
September
August
July
June
May
April
March
February
January
2006
December
November
October
September
August
July
June
May
April
March
February
January
2005
December
November
October
September
August
July
June
May
April
March
February
January
2004
December
November
October
September
August
July
June
May
April
March
February
List overview
Download
Ros-diffs
March 2005
----- 2025 -----
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
October 2017
September 2017
August 2017
July 2017
June 2017
May 2017
April 2017
March 2017
February 2017
January 2017
----- 2016 -----
December 2016
November 2016
October 2016
September 2016
August 2016
July 2016
June 2016
May 2016
April 2016
March 2016
February 2016
January 2016
----- 2015 -----
December 2015
November 2015
October 2015
September 2015
August 2015
July 2015
June 2015
May 2015
April 2015
March 2015
February 2015
January 2015
----- 2014 -----
December 2014
November 2014
October 2014
September 2014
August 2014
July 2014
June 2014
May 2014
April 2014
March 2014
February 2014
January 2014
----- 2013 -----
December 2013
November 2013
October 2013
September 2013
August 2013
July 2013
June 2013
May 2013
April 2013
March 2013
February 2013
January 2013
----- 2012 -----
December 2012
November 2012
October 2012
September 2012
August 2012
July 2012
June 2012
May 2012
April 2012
March 2012
February 2012
January 2012
----- 2011 -----
December 2011
November 2011
October 2011
September 2011
August 2011
July 2011
June 2011
May 2011
April 2011
March 2011
February 2011
January 2011
----- 2010 -----
December 2010
November 2010
October 2010
September 2010
August 2010
July 2010
June 2010
May 2010
April 2010
March 2010
February 2010
January 2010
----- 2009 -----
December 2009
November 2009
October 2009
September 2009
August 2009
July 2009
June 2009
May 2009
April 2009
March 2009
February 2009
January 2009
----- 2008 -----
December 2008
November 2008
October 2008
September 2008
August 2008
July 2008
June 2008
May 2008
April 2008
March 2008
February 2008
January 2008
----- 2007 -----
December 2007
November 2007
October 2007
September 2007
August 2007
July 2007
June 2007
May 2007
April 2007
March 2007
February 2007
January 2007
----- 2006 -----
December 2006
November 2006
October 2006
September 2006
August 2006
July 2006
June 2006
May 2006
April 2006
March 2006
February 2006
January 2006
----- 2005 -----
December 2005
November 2005
October 2005
September 2005
August 2005
July 2005
June 2005
May 2005
April 2005
March 2005
February 2005
January 2005
----- 2004 -----
December 2004
November 2004
October 2004
September 2004
August 2004
July 2004
June 2004
May 2004
April 2004
March 2004
February 2004
ros-diffs@reactos.org
26 participants
609 discussions
Start a n
N
ew thread
[weiden] 13975: Alex Ionescu <ionucu@videotron.ca>
by weiden@svn.reactos.com
Alex Ionescu <ionucu(a)videotron.ca> - Fixed formatting mess in ke/dpc.c (which I had made when I wrote it due to MSVC). - Add more comments where needed. - Properly Initialize a Threaded DPC. Thomas Weidenmueller <w3seek(a)reactos.com> - Use Prcb directly in KeInitDpc. Modified: trunk/reactos/ntoskrnl/include/internal/ke.h Modified: trunk/reactos/ntoskrnl/ke/dpc.c Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c _____ Modified: trunk/reactos/ntoskrnl/include/internal/ke.h --- trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-12 19:23:04 UTC (rev 13974) +++ trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-12 19:45:37 UTC (rev 13975) @@ -41,6 +41,7 @@ struct _KTHREAD; struct _KIRQ_TRAPFRAME; struct _KPCR; +struct _KPRCB; struct _KEXCEPTION_FRAME; #define IPI_REQUEST_FUNCTIONCALL 0 @@ -192,7 +193,7 @@ VOID KeInitExceptions(VOID); VOID KeInitInterrupts(VOID); VOID KeInitTimer(VOID); -VOID KeInitDpc(struct _KPCR* Pcr); +VOID KeInitDpc(struct _KPRCB* Prcb); VOID KeInitDispatcher(VOID); VOID KeInitializeDispatcher(VOID); VOID KiInitializeSystemClock(VOID); _____ Modified: trunk/reactos/ntoskrnl/ke/dpc.c --- trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:23:04 UTC (rev 13974) +++ trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:45:37 UTC (rev 13975) @@ -24,22 +24,22 @@ /* TYPES *******************************************************************/ #define MAX_QUANTUM 0x7F -/* GLOBALS ******************************************************************/ /* FUNCTIONS ****************************************************************/ -VOID INIT_FUNCTION -KeInitDpc(PKPCR Pcr) /* * FUNCTION: Initialize DPC handling */ +VOID +INIT_FUNCTION +KeInitDpc(PKPRCB Prcb) { - InitializeListHead(&Pcr->PrcbData.DpcData[0].DpcListHead); - KeInitializeEvent(Pcr->PrcbData.DpcEvent, 0, 0); - KeInitializeSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - Pcr->PrcbData.MaximumDpcQueueDepth = 4; - Pcr->PrcbData.MinimumDpcRate = 3; - Pcr->PrcbData.DpcData[0].DpcQueueDepth = 0; + InitializeListHead(&Prcb->DpcData[0].DpcListHead); + KeInitializeEvent(Prcb->DpcEvent, 0, 0); + KeInitializeSpinLock(&Prcb->DpcData[0].DpcLock); + Prcb->MaximumDpcQueueDepth = 4; + Prcb->MinimumDpcRate = 3; + Prcb->DpcData[0].DpcQueueDepth = 0; } /* @@ -47,9 +47,9 @@ */ VOID STDCALL -KeInitializeThreadedDpc(PKDPC Dpc, - PKDEFERRED_ROUTINE DeferredRoutine, - PVOID DeferredContext) +KeInitializeThreadedDpc(PKDPC Dpc, + PKDEFERRED_ROUTINE DeferredRoutine, + PVOID DeferredContext) /* * FUNCTION: * Initalizes a Threaded DPC and registers the DeferredRoutine for it. @@ -60,24 +60,18 @@ * NOTE: Callers can be running at any IRQL. */ { - DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); - //Dpc->Type = KThreadedDpc; - Dpc->Number= 0; - Dpc->Importance= MediumImportance; - Dpc->DeferredRoutine = DeferredRoutine; - Dpc->DeferredContext = DeferredContext; - Dpc->DpcData = NULL; + DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); + Dpc->Type = ThreadedDpcObject; + Dpc->Number= 0; + Dpc->Importance= MediumImportance; + Dpc->DeferredRoutine = DeferredRoutine; + Dpc->DeferredContext = DeferredContext; + Dpc->DpcData = NULL; } /* * @implemented - */ -VOID -STDCALL -KeInitializeDpc (PKDPC Dpc, - PKDEFERRED_ROUTINE DeferredRoutine, - PVOID DeferredContext) -/* + * * FUNCTION: * Initalizes a DPC and registers the DeferredRoutine for it. * ARGUMENTS: @@ -86,24 +80,24 @@ * DeferredContext = Parameter to be passed to the callback routine. * NOTE: Callers can be running at any IRQL. */ +VOID +STDCALL +KeInitializeDpc(PKDPC Dpc, + PKDEFERRED_ROUTINE DeferredRoutine, + PVOID DeferredContext) { - DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); - Dpc->Type = DpcObject; - Dpc->Number= 0; - Dpc->Importance= MediumImportance; - Dpc->DeferredRoutine = DeferredRoutine; - Dpc->DeferredContext = DeferredContext; - Dpc->DpcData = NULL; + DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); + Dpc->Type = DpcObject; + Dpc->Number= 0; + Dpc->Importance= MediumImportance; + Dpc->DeferredRoutine = DeferredRoutine; + Dpc->DeferredContext = DeferredContext; + Dpc->DpcData = NULL; } /* * @implemented - */ -BOOLEAN STDCALL -KeInsertQueueDpc (PKDPC Dpc, - PVOID SystemArgument1, - PVOID SystemArgument2) -/* + * * FUNCTION: * Queues a DPC for execution when the IRQL of a processor * drops below DISPATCH_LEVEL @@ -155,124 +149,141 @@ * is greater that the target depth or the minimum DPC rate is less than the * target rate. */ +BOOLEAN +STDCALL +KeInsertQueueDpc(PKDPC Dpc, + PVOID SystemArgument1, + PVOID SystemArgument2) { - KIRQL OldIrql; - PKPCR Pcr; + KIRQL OldIrql; + PKPRCB Prcb; - DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n", - Dpc, SystemArgument1, SystemArgument2); + DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n", + Dpc, SystemArgument1, SystemArgument2); - /* Check IRQL and Raise it to HIGH_LEVEL */ - ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL); - KeRaiseIrql(HIGH_LEVEL, &OldIrql); - - /* Check if this is a Thread DPC, which we don't support (yet) */ - //if (Dpc->Type == KThreadedDpc) { - // return FALSE; - // KeLowerIrql(OldIrql); - //} + /* Check IRQL and Raise it to HIGH_LEVEL */ + ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL); + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + /* Check if this is a Thread DPC, which we don't support (yet) */ + if (Dpc->Type == ThreadedDpcObject) { + return FALSE; + KeLowerIrql(OldIrql); + } #ifdef CONFIG_SMP - /* Get the right PCR for this CPU */ - if (Dpc->Number >= MAXIMUM_PROCESSORS) { - ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors); - Pcr = (PKPCR)(KPCR_BASE + (Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE); - } else { - ASSERT (Dpc->Number < KeNumberProcessors); - Pcr = KeGetCurrentKPCR(); - Dpc->Number = KeGetCurrentProcessorNumber(); - } - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + /* Get the right PCR for this CPU */ + if (Dpc->Number >= MAXIMUM_PROCESSORS) { + + ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors); + Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + ((Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE)))->Prcb; + + } else { + + ASSERT (Dpc->Number < KeNumberProcessors); + Prcb = KeGetCurrentPrcb(); + Dpc->Number = KeGetCurrentProcessorNumber(); + } + + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); #else - Pcr = (PKPCR)KPCR_BASE; + Prcb = ((PKPCR)KPCR_BASE)->Prcb; #endif - /* Get the DPC Data */ - if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Pcr->PrcbData.DpcData[0].DpcLock, 0)) { - DPRINT("DPC Already Inserted"); + /* Get the DPC Data */ + if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Prcb->DpcData[0].DpcLock, 0)) { + + DPRINT("DPC Already Inserted"); #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - KeLowerIrql(OldIrql); - return(FALSE); - } - - /* Make sure the lists are free if the Queue is 0 */ - if (Pcr->PrcbData.DpcData[0].DpcQueueDepth == 0) { - ASSERT(IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)); - } else { - ASSERT(!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)); - } + KeLowerIrql(OldIrql); + return(FALSE); + } + + /* Make sure the lists are free if the Queue is 0 */ + if (Prcb->DpcData[0].DpcQueueDepth == 0) { + + ASSERT(IsListEmpty(&Prcb->DpcData[0].DpcListHead)); + } else { + + ASSERT(!IsListEmpty(&Prcb->DpcData[0].DpcListHead)); + } - /* Now we can play with the DPC safely */ - Dpc->SystemArgument1=SystemArgument1; - Dpc->SystemArgument2=SystemArgument2; - Pcr->PrcbData.DpcData[0].DpcQueueDepth++; - Pcr->PrcbData.DpcData[0].DpcCount++; - - /* Insert the DPC into the list. HighImportance DPCs go at the beginning */ - if (Dpc->Importance == HighImportance) { - InsertHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry); - } else { - InsertTailList(&Pcr->PrcbData.DpcData[0].DpcListHead, &Dpc->DpcListEntry); - } - DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); + /* Now we can play with the DPC safely */ + Dpc->SystemArgument1=SystemArgument1; + Dpc->SystemArgument2=SystemArgument2; + Prcb->DpcData[0].DpcQueueDepth++; + Prcb->DpcData[0].DpcCount++; + + /* Insert the DPC into the list. HighImportance DPCs go at the beginning */ + if (Dpc->Importance == HighImportance) { + + InsertHeadList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry); + } else { + + InsertTailList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry); + } + DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); - /* Make sure a DPC isn't executing already and respect rules outlined above. */ - if ((!Pcr->PrcbData.DpcRoutineActive) && (!Pcr->PrcbData.DpcInterruptRequested)) { - -#ifdef CONFIG_SMP - /* Check if this is the same CPU */ - if (Pcr != KeGetCurrentKPCR()) { - /* Send IPI if High Importance */ - if ((Dpc->Importance == HighImportance) || - (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth)) { - if (Dpc->Number >= MAXIMUM_PROCESSORS) { - KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC); - } else { - KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC); - } + /* Make sure a DPC isn't executing already and respect rules outlined above. */ + if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested)) { + +#ifdef CONFIG_SMP + /* Check if this is the same CPU */ + if (Prcb != KeGetCurrentPrcb()) { + + /* Send IPI if High Importance */ + if ((Dpc->Importance == HighImportance) || + (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) { + + if (Dpc->Number >= MAXIMUM_PROCESSORS) { + + KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_REQUEST_DPC); + } else { + + KiIpiSendRequest(1 << Dpc->Number, IPI_REQUEST_DPC); + } - } - } else { - /* Request an Interrupt only if the DPC isn't low priority */ - if ((Dpc->Importance != LowImportance) || - (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) || - (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) { - - /* Request Interrupt */ - HalRequestSoftwareInterrupt(DISPATCH_LEVEL); - Pcr->PrcbData.DpcInterruptRequested = TRUE; - } - } + } + } else { + + /* Request an Interrupt only if the DPC isn't low priority */ + if ((Dpc->Importance != LowImportance) || + (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || + (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { + + /* Request Interrupt */ + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + Prcb->DpcInterruptRequested = TRUE; + } + } #else - DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Pcr->PrcbData.DpcData[0].DpcQueueDepth, Pcr->PrcbData.MaximumDpcQueueDepth, Pcr->PrcbData.DpcRequestRate, Pcr->PrcbData.MinimumDpcRate); - /* Request an Interrupt only if the DPC isn't low priority */ - if ((Dpc->Importance != LowImportance) || - (Pcr->PrcbData.DpcData[0].DpcQueueDepth >= Pcr->PrcbData.MaximumDpcQueueDepth) || - (Pcr->PrcbData.DpcRequestRate < Pcr->PrcbData.MinimumDpcRate)) { - - /* Request Interrupt */ - DPRINT("Requesting Interrupt\n"); - HalRequestSoftwareInterrupt(DISPATCH_LEVEL); - Pcr->PrcbData.DpcInterruptRequested = TRUE; - } + DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Prcb->DpcData[0].DpcQueueDepth, Prcb->MaximumDpcQueueDepth, Prcb->DpcRequestRate, Prcb->MinimumDpcRate); + + /* Request an Interrupt only if the DPC isn't low priority */ + if ((Dpc->Importance != LowImportance) || + (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) || + (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) { + + /* Request Interrupt */ + DPRINT("Requesting Interrupt\n"); + HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + Prcb->DpcInterruptRequested = TRUE; + } #endif - } + } #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - /* Lower IRQL */ - KeLowerIrql(OldIrql); - return(TRUE); + /* Lower IRQL */ + KeLowerIrql(OldIrql); + return(TRUE); } /* * @implemented - */ -BOOLEAN STDCALL -KeRemoveQueueDpc (PKDPC Dpc) -/* + * * FUNCTION: * Removes DPC object from the system dpc queue * ARGUMENTS: @@ -281,33 +292,36 @@ * TRUE if the DPC was in the queue * FALSE otherwise */ +BOOLEAN +STDCALL +KeRemoveQueueDpc(PKDPC Dpc) { - BOOLEAN WasInQueue; - KIRQL OldIrql; - - /* Raise IRQL */ - DPRINT("Removing DPC: %x\n", Dpc); - KeRaiseIrql(HIGH_LEVEL, &OldIrql); + BOOLEAN WasInQueue; + KIRQL OldIrql; + + /* Raise IRQL */ + DPRINT("Removing DPC: %x\n", Dpc); + KeRaiseIrql(HIGH_LEVEL, &OldIrql); #ifdef CONFIG_SMP - KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock); + KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock); #endif - - /* First make sure the DPC lock isn't being held */ - WasInQueue = Dpc->DpcData ? TRUE : FALSE; - if (Dpc->DpcData) { - - /* Remove the DPC */ - ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--; - RemoveEntryList(&Dpc->DpcListEntry); + + /* First make sure the DPC lock isn't being held */ + WasInQueue = Dpc->DpcData ? TRUE : FALSE; + if (Dpc->DpcData) { + + /* Remove the DPC */ + ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--; + RemoveEntryList(&Dpc->DpcListEntry); - } + } #ifdef CONFIG_SMP KiReleaseSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock); #endif - /* Return if the DPC was in the queue or not */ - KeLowerIrql(OldIrql); - return WasInQueue; + /* Return if the DPC was in the queue or not */ + KeLowerIrql(OldIrql); + return WasInQueue; } /* @@ -323,7 +337,8 @@ * Called when deleting a Driver. */ { - if (KeGetCurrentKPCR()->PrcbData.DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL); + /* Request an interrupt if needed */ + if (KeGetCurrentPrcb()->DpcData[0].DpcQueueDepth) HalRequestSoftwareInterrupt(DISPATCH_LEVEL); } /* @@ -332,10 +347,11 @@ BOOLEAN STDCALL KeIsExecutingDpc( - VOID + VOID ) { - return KeGetCurrentKPCR()->PrcbData.DpcRoutineActive; + /* Return if the Dpc Routine is active */ + return KeGetCurrentPrcb()->DpcRoutineActive; } /* @@ -349,39 +365,41 @@ */ VOID STDCALL -KeSetImportanceDpc (IN PKDPC Dpc, - IN KDPC_IMPORTANCE Importance) +KeSetImportanceDpc (IN PKDPC Dpc, + IN KDPC_IMPORTANCE Importance) { - Dpc->Importance = Importance; + /* Set the DPC Importance */ + Dpc->Importance = Importance; } /* + * @implemented + * * FUNCTION: Specifies on which processor the DPC will run * ARGUMENTS: * Dpc = Initalizes DPC * Number = Processor number * RETURNS: None - * - * @implemented */ -VOID STDCALL -KeSetTargetProcessorDpc (IN PKDPC Dpc, - IN CCHAR Number) +VOID +STDCALL +KeSetTargetProcessorDpc(IN PKDPC Dpc, + IN CCHAR Number) { - if (Number >= MAXIMUM_PROCESSORS) - { - Dpc->Number = 0; - } - else - { - ASSERT(Number < KeNumberProcessors); - Dpc->Number = Number + MAXIMUM_PROCESSORS; - } + /* Check how many CPUs are on the system */ + if (Number >= MAXIMUM_PROCESSORS) { + + /* No CPU Number */ + Dpc->Number = 0; + + } else { + + /* Set the Number Specified */ + ASSERT(Number < KeNumberProcessors); + Dpc->Number = Number + MAXIMUM_PROCESSORS; + } } -VOID -STDCALL -KiQuantumEnd(VOID) /* * FUNCTION: * Called when a quantum end occurs to check if priority should be changed @@ -389,152 +407,173 @@ * NOTES: * Called when deleting a Driver. */ +VOID +STDCALL +KiQuantumEnd(VOID) { - PKPRCB Prcb; - PKTHREAD CurrentThread; - KIRQL OldIrql; - PKPROCESS Process; - KPRIORITY OldPriority; - KPRIORITY NewPriority; - - /* Lock dispatcher, get current thread */ - Prcb = &KeGetCurrentKPCR()->PrcbData; - CurrentThread = KeGetCurrentThread(); - OldIrql = KeRaiseIrqlToSynchLevel(); - - /* Get the Thread's Process */ - Process = CurrentThread->ApcState.Process; - - /* Set DPC Event if requested */ - if (Prcb->DpcSetEventRequest) { - KeSetEvent(Prcb->DpcEvent, 0, 0); - } - - /* Check if Quantum expired */ - if (CurrentThread->Quantum <= 0) { - /* Set the new Quantum */ - CurrentThread->Quantum = Process->ThreadQuantum; - - /* Calculate new priority */ - OldPriority = CurrentThread->Priority; - if (OldPriority < LOW_REALTIME_PRIORITY) { - NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1; - if (NewPriority < CurrentThread->BasePriority) { - NewPriority = CurrentThread->BasePriority; - } - CurrentThread->PriorityDecrement = 0; - if (OldPriority != NewPriority) { - /* Set new Priority */ - CurrentThread->Priority = NewPriority; - } else { - /* Queue new thread if none is already */ - if (Prcb->NextThread == NULL) { - /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */ - } else { - /* Make the current thread non-premeptive if a new thread is queued */ - CurrentThread->Preempted = FALSE; - } - } - } else { - /* Set the Quantum back to Maximum */ - //if (CurrentThread->DisableQuantum) { - // CurrentThread->Quantum = MAX_QUANTUM; - //} - } - } - /* Dispatch the Thread */ - KeLowerIrql(DISPATCH_LEVEL); - PsDispatchThread(THREAD_STATE_READY); -} + PKPRCB Prcb; + PKTHREAD CurrentThread; + KIRQL OldIrql; + PKPROCESS Process; + KPRIORITY OldPriority; + KPRIORITY NewPriority; + + /* Lock dispatcher, get current thread */ + Prcb = KeGetCurrentPrcb(); + CurrentThread = KeGetCurrentThread(); + OldIrql = KeRaiseIrqlToSynchLevel(); + + /* Get the Thread's Process */ + Process = CurrentThread->ApcState.Process; + + /* Set DPC Event if requested */ + if (Prcb->DpcSetEventRequest) { + KeSetEvent(Prcb->DpcEvent, 0, 0); + } + + /* Check if Quantum expired */ + if (CurrentThread->Quantum <= 0) { + /* Set the new Quantum */ + CurrentThread->Quantum = Process->ThreadQuantum; + + /* Calculate new priority */ + OldPriority = CurrentThread->Priority; + if (OldPriority < LOW_REALTIME_PRIORITY) { + + /* Set the New Priority and add the Priority Decrement */ + NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1; + + /* Don't go out of bounds */ + if (NewPriority < CurrentThread->BasePriority) NewPriority = CurrentThread->BasePriority; + + /* Reset the priority decrement */ + CurrentThread->PriorityDecrement = 0; + + /* Set a new priority if needed */ + if (OldPriority != NewPriority) { + + /* Set new Priority */ + CurrentThread->Priority = NewPriority; + + } else { + + /* Queue new thread if none is already */ + if (Prcb->NextThread == NULL) { + + /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */ + + } else { + + /* Make the current thread non-premeptive if a new thread is queued */ + CurrentThread->Preempted = FALSE; + } + } + + } else { + /* Set the Quantum back to Maximum */ + //if (CurrentThread->DisableQuantum) { + // CurrentThread->Quantum = MAX_QUANTUM; + //} + } + } + + /* Dispatch the Thread */ + KeLowerIrql(DISPATCH_LEVEL); + PsDispatchThread(THREAD_STATE_READY); +} + /* * @implemented + * + * FUNCTION: + * Called whenever a system interrupt is generated at DISPATCH_LEVEL. + * It delivers queued DPCs and dispatches a new thread if need be. */ VOID STDCALL KiDispatchInterrupt(VOID) -/* - * FUNCTION: - * Called whenever a system interrupt is generated at DISPATCH_LEVEL. - * It delivers queued DPCs and dispatches a new thread if need be. - */ { - PLIST_ENTRY DpcEntry; - PKDPC Dpc; - KIRQL OldIrql; - PKPCR Pcr; + PLIST_ENTRY DpcEntry; + PKDPC Dpc; + KIRQL OldIrql; + PKPRCB Prcb; - DPRINT("Dispatching Interrupts\n"); - ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); + DPRINT("Dispatching Interrupts\n"); + ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); - /* Set DPC Deliver to Active */ - Pcr = KeGetCurrentKPCR(); + /* Set DPC Deliver to Active */ + Prcb = KeGetCurrentPrcb(); - if (Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0) { - /* Raise IRQL */ - KeRaiseIrql(HIGH_LEVEL, &OldIrql); -#ifdef CONFIG_SMP - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + if (Prcb->DpcData[0].DpcQueueDepth > 0) { + /* Raise IRQL */ + KeRaiseIrql(HIGH_LEVEL, &OldIrql); +#ifdef CONFIG_SMP + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); #endif - Pcr->PrcbData.DpcRoutineActive = TRUE; + Prcb->DpcRoutineActive = TRUE; - DPRINT("&Pcr->PrcbData.DpcData[0].DpcListHead: %x\n", &Pcr->PrcbData.DpcData[0].DpcListHead); - /* Loop while we have entries */ - while (!IsListEmpty(&Pcr->PrcbData.DpcData[0].DpcListHead)) { - ASSERT(Pcr->PrcbData.DpcData[0].DpcQueueDepth > 0); - DPRINT("Queue Depth: %x\n", Pcr->PrcbData.DpcData[0].DpcQueueDepth); - - /* Get the DPC call it */ - DpcEntry = RemoveHeadList(&Pcr->PrcbData.DpcData[0].DpcListHead); - Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry); - DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); - Dpc->DpcData = NULL; - Pcr->PrcbData.DpcData[0].DpcQueueDepth--; + DPRINT("&Prcb->DpcData[0].DpcListHead: %x\n", &Prcb->DpcData[0].DpcListHead); + /* Loop while we have entries */ + while (!IsListEmpty(&Prcb->DpcData[0].DpcListHead)) { + + ASSERT(Prcb->DpcData[0].DpcQueueDepth > 0); + DPRINT("Queue Depth: %x\n", Prcb->DpcData[0].DpcQueueDepth); + + /* Get the DPC call it */ + DpcEntry = RemoveHeadList(&Prcb->DpcData[0].DpcListHead); + Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry); + DPRINT("Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink); + Dpc->DpcData = NULL; + Prcb->DpcData[0].DpcQueueDepth--; #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - /* Disable/Enabled Interrupts and Call the DPC */ - KeLowerIrql(OldIrql); - DPRINT("Calling DPC: %x\n", Dpc); - Dpc->DeferredRoutine(Dpc, - Dpc->DeferredContext, - Dpc->SystemArgument1, - Dpc->SystemArgument2); - KeRaiseIrql(HIGH_LEVEL, &OldIrql); - + /* Disable/Enabled Interrupts and Call the DPC */ + KeLowerIrql(OldIrql); + DPRINT("Calling DPC: %x\n", Dpc); + Dpc->DeferredRoutine(Dpc, + Dpc->DeferredContext, + Dpc->SystemArgument1, + Dpc->SystemArgument2); + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + #ifdef CONFIG_SMP - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - /* - * If the dpc routine drops the irql below DISPATCH_LEVEL, - * a thread switch can occur and after the next thread switch - * the execution may start on an other processor. - */ - if (Pcr != KeGetCurrentKPCR()) { - Pcr->PrcbData.DpcRoutineActive = FALSE; - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - Pcr = KeGetCurrentKPCR(); - KiAcquireSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); - Pcr->PrcbData.DpcRoutineActive = TRUE; - } + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); + /* + * If the dpc routine drops the irql below DISPATCH_LEVEL, + * a thread switch can occur and after the next thread switch + * the execution may start on an other processor. + */ + if (Prcb != KeGetCurrentPrcb()) { + + Prcb->DpcRoutineActive = FALSE; + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); + Prcb = KeGetCurrentPrcb(); + KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock); + Prcb->DpcRoutineActive = TRUE; + } #endif - } - /* Clear DPC Flags */ - Pcr->PrcbData.DpcRoutineActive = FALSE; - Pcr->PrcbData.DpcInterruptRequested = FALSE; + } + /* Clear DPC Flags */ + Prcb->DpcRoutineActive = FALSE; + Prcb->DpcInterruptRequested = FALSE; #ifdef CONFIG_SMP - KiReleaseSpinLock(&Pcr->PrcbData.DpcData[0].DpcLock); + KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock); #endif - - /* DPC Dispatching Ended, re-enable interrupts */ - KeLowerIrql(OldIrql); - } - - DPRINT("Checking for Quantum End\n"); - /* If we have Quantum End, call the function */ - if (Pcr->PrcbData.QuantumEnd) { - Pcr->PrcbData.QuantumEnd = FALSE; - KiQuantumEnd(); - } + + /* DPC Dispatching Ended, re-enable interrupts */ + KeLowerIrql(OldIrql); + } + + DPRINT("Checking for Quantum End\n"); + + /* If we have Quantum End, call the function */ + if (Prcb->QuantumEnd) { + + Prcb->QuantumEnd = FALSE; + KiQuantumEnd(); + } } /* EOF */ _____ Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c --- trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-12 19:23:04 UTC (rev 13974) +++ trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-12 19:45:37 UTC (rev 13975) @@ -187,7 +187,7 @@ /* Check FPU/MMX/SSE support. */ KiCheckFPU(); - KeInitDpc(Pcr); + KeInitDpc(Pcr->Prcb); if (Pcr->PrcbData.FeatureBits & X86_FEATURE_SYSCALL) { @@ -262,7 +262,7 @@ /* Mark the end of the exception handler list */ KPCR->Tib.ExceptionList = (PVOID)-1; - KeInitDpc(KPCR); + KeInitDpc(KPCR->Prcb); KeInitExceptions (); KeInitInterrupts ();
20 years, 2 months
1
0
0
0
[weiden] 13974: Alex Ionescu <ionucu@videotron.ca>
by weiden@svn.reactos.com
Alex Ionescu <ionucu(a)videotron.ca> - Removed ke/alert.c and moved its functions where they belong. - Commented and organized KeInitializeThread. - Began switch to true KOBJECT enumeration used in NT. - Implemented KeAlertResumeThread and NtAlertResumeThread. - Harmonized Formatting in ke/kthread.c Modified: trunk/reactos/drivers/storage/floppy/floppy.c Modified: trunk/reactos/include/ddk/ketypes.h Modified: trunk/reactos/ntoskrnl/Makefile Modified: trunk/reactos/ntoskrnl/include/internal/ps.h Deleted: trunk/reactos/ntoskrnl/ke/alert.c Modified: trunk/reactos/ntoskrnl/ke/apc.c Modified: trunk/reactos/ntoskrnl/ke/dpc.c Modified: trunk/reactos/ntoskrnl/ke/kthread.c Modified: trunk/reactos/ntoskrnl/ke/wait.c Modified: trunk/reactos/ntoskrnl/ps/thread.c _____ Modified: trunk/reactos/drivers/storage/floppy/floppy.c --- trunk/reactos/drivers/storage/floppy/floppy.c 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/drivers/storage/floppy/floppy.c 2005-03-12 19:23:04 UTC (rev 13974) @@ -58,7 +58,7 @@ /* Queue thread management */ static KEVENT QueueThreadTerminate; -static PVOID ThreadObject; +static PVOID QueueThreadObject; static VOID NTAPI MotorStopDpcFunc(PKDPC UnusedDpc, @@ -378,8 +378,8 @@ KdPrint(("floppy: unloading\n")); KeSetEvent(&QueueThreadTerminate, 0, FALSE); - KeWaitForSingleObject(ThreadObject, Executive, KernelMode, FALSE, 0); - ObDereferenceObject(ThreadObject); + KeWaitForSingleObject(QueueThreadObject, Executive, KernelMode, FALSE, 0); + ObDereferenceObject(QueueThreadObject); for(i = 0; i < gNumberOfControllers; i++) { @@ -1152,7 +1152,7 @@ return STATUS_INSUFFICIENT_RESOURCES; } - if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &ThreadObject, NULL) != STATUS_SUCCESS) + if(ObReferenceObjectByHandle(ThreadHandle, STANDARD_RIGHTS_ALL, NULL, KernelMode, &QueueThreadObject, NULL) != STATUS_SUCCESS) { KdPrint(("floppy: Unable to reference returned thread handle; failing init\n")); return STATUS_UNSUCCESSFUL; _____ Modified: trunk/reactos/include/ddk/ketypes.h --- trunk/reactos/include/ddk/ketypes.h 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/include/ddk/ketypes.h 2005-03-12 19:23:04 UTC (rev 13974) @@ -36,23 +36,34 @@ struct _DISPATCHER_HEADER; -typedef enum _KERNEL_OBJECTS { - KNotificationEvent = 0, - KSynchronizationEvent = 1, - KMutant = 2, - KProcess = 3, - KQueue = 4, - KSemaphore = 5, - KThread = 6, - KNotificationTimer = 8, - KSynchronizationTimer = 9, - KApc = 18, - KDpc = 19, - KDeviceQueue = 20, - KEventPair = 21, - KInterrupt = 22, - KProfile = 23 -} KERNEL_OBJECTS; +typedef enum _KOBJECTS { + EventNotificationObject = 0, + EventSynchronizationObject = 1, + MutantObject = 2, + ProcessObject = 3, + QueueObject = 4, + SemaphoreObject = 5, + ThreadObject = 6, + GateObject = 7, + TimerNotificationObject = 8, + TimerSynchronizationObject = 9, + Spare2Object = 10, + Spare3Object = 11, + Spare4Object = 12, + Spare5Object = 13, + Spare6Object = 14, + Spare7Object = 15, + Spare8Object = 16, + Spare9Object = 17, + ApcObject = 18, + DpcObject = 19, + DeviceQueueObject = 20, + EventPairObject = 21, + InterruptObject = 22, + ProfileObject = 23, + ThreadedDpcObject = 24, + MaximumKernelObject = 25 +} KOBJECTS; #include <pshpack1.h> _____ Modified: trunk/reactos/ntoskrnl/Makefile --- trunk/reactos/ntoskrnl/Makefile 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/ntoskrnl/Makefile 2005-03-12 19:23:04 UTC (rev 13974) @@ -113,8 +113,7 @@ ke/sem.o \ ke/spinlock.o \ ke/timer.o \ - ke/wait.o \ - ke/alert.o + ke/wait.o # Memory Manager (Mm) OBJECTS_MM = \ _____ Modified: trunk/reactos/ntoskrnl/include/internal/ps.h --- trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/ntoskrnl/include/internal/ps.h 2005-03-12 19:23:04 UTC (rev 13974) @@ -498,7 +498,7 @@ #define PROCESS_PRIO_RT 18 -VOID +VOID STDCALL KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First); NTSTATUS KeReleaseThread(PKTHREAD Thread); _____ Deleted: trunk/reactos/ntoskrnl/ke/alert.c --- trunk/reactos/ntoskrnl/ke/alert.c 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/ntoskrnl/ke/alert.c 2005-03-12 19:23:04 UTC (rev 13974) @@ -1,150 +0,0 @@ -/* $Id:$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/alert.c - * PURPOSE: Alerts - * - * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net) - */ - -/* INCLUDES *****************************************************************/ - -#include <ntoskrnl.h> -#define NDEBUG -#include <internal/debug.h> - -/* GLOBALS *******************************************************************/ - - -/* FUNCTIONS *****************************************************************/ - - -BOOLEAN -STDCALL -KeTestAlertThread(IN KPROCESSOR_MODE AlertMode) -/* - * FUNCTION: Tests whether there are any pending APCs for the current thread - * and if so the APCs will be delivered on exit from kernel mode - */ -{ - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - BOOLEAN OldState; - - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - OldIrql = KeAcquireDispatcherDatabaseLock(); - KiAcquireSpinLock(&Thread->ApcQueueLock); - - OldState = Thread->Alerted[AlertMode]; - - /* If the Thread is Alerted, Clear it */ - if (OldState) { - Thread->Alerted[AlertMode] = FALSE; - } else if ((AlertMode == UserMode) && (!IsListEmpty(&Thread->ApcState.ApcListHead[UserMode]))) { - /* If the mode is User and the Queue isn't empty, set Pending */ - Thread->ApcState.UserApcPending = TRUE; - } - - KiReleaseSpinLock(&Thread->ApcQueueLock); - KeReleaseDispatcherDatabaseLock(OldIrql); - return OldState; -} - - -VOID -KeAlertThread(PKTHREAD Thread, KPROCESSOR_MODE AlertMode) -{ - KIRQL oldIrql; - - - oldIrql = KeAcquireDispatcherDatabaseLock(); - - - /* Return if thread is already alerted. */ - if (Thread->Alerted[AlertMode] == FALSE) - { - if (Thread->State == THREAD_STATE_BLOCKED && - (AlertMode == KernelMode || Thread->WaitMode == AlertMode) && - Thread->Alertable) - { - KiAbortWaitThread(Thread, STATUS_ALERTED); - } - else - { - Thread->Alerted[AlertMode] = TRUE; - } - } - - KeReleaseDispatcherDatabaseLock(oldIrql); - -} - - -/* - * - * NOT EXPORTED - */ -NTSTATUS STDCALL -NtAlertResumeThread(IN HANDLE ThreadHandle, - OUT PULONG SuspendCount) -{ - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); - -} - -/* - * @implemented - * - * EXPORTED - */ -NTSTATUS STDCALL -NtAlertThread (IN HANDLE ThreadHandle) -{ - KPROCESSOR_MODE PreviousMode; - PETHREAD Thread; - NTSTATUS Status; - - PreviousMode = ExGetPreviousMode(); - - Status = ObReferenceObjectByHandle(ThreadHandle, - THREAD_SUSPEND_RESUME, - PsThreadType, - PreviousMode, - (PVOID*)&Thread, - NULL); - if (!NT_SUCCESS(Status)) - { - return(Status); - } - - /* do an alert depending on the processor mode. If some kmode code wants to - enforce a umode alert it should call KeAlertThread() directly. If kmode - code wants to do a kmode alert it's sufficient to call it with Zw or just - use KeAlertThread() directly */ - - KeAlertThread(&Thread->Tcb, PreviousMode); - - ObDereferenceObject(Thread); - return(STATUS_SUCCESS); -} - - -/* - * NOT EXPORTED - */ -NTSTATUS -STDCALL -NtTestAlert(VOID) -{ - KPROCESSOR_MODE PreviousMode; - - PreviousMode = ExGetPreviousMode(); - - /* Check and Alert Thread if needed */ - - return KeTestAlertThread(PreviousMode) ? STATUS_ALERTED : STATUS_SUCCESS; -} - _____ Modified: trunk/reactos/ntoskrnl/ke/apc.c --- trunk/reactos/ntoskrnl/ke/apc.c 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/ntoskrnl/ke/apc.c 2005-03-12 19:23:04 UTC (rev 13974) @@ -58,7 +58,7 @@ /* Set up the basic APC Structure Data */ RtlZeroMemory(Apc, sizeof(KAPC)); - Apc->Type = KApc; + Apc->Type = ApcObject; Apc->Size = sizeof(KAPC); /* Set the Environment */ _____ Modified: trunk/reactos/ntoskrnl/ke/dpc.c --- trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/ntoskrnl/ke/dpc.c 2005-03-12 19:23:04 UTC (rev 13974) @@ -88,7 +88,7 @@ */ { DPRINT("DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine); - Dpc->Type = KDpc; + Dpc->Type = DpcObject; Dpc->Number= 0; Dpc->Importance= MediumImportance; Dpc->DeferredRoutine = DeferredRoutine; _____ Modified: trunk/reactos/ntoskrnl/ke/kthread.c --- trunk/reactos/ntoskrnl/ke/kthread.c 2005-03-12 19:22:30 UTC (rev 13973) +++ trunk/reactos/ntoskrnl/ke/kthread.c 2005-03-12 19:23:04 UTC (rev 13974) @@ -1,11 +1,11 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/kthread.c * PURPOSE: Microkernel thread support * - * PROGRAMMERS: David Welch (welch(a)cwcom.net) + * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net) - Commented, reorganized some stuff, fixed/implemented some functions. + * David Welch (welch(a)cwcom.net) */ /* INCLUDES *****************************************************************/ @@ -16,19 +16,93 @@ /* FUNCTIONS *****************************************************************/ -VOID -KiServiceCheck (VOID) +ULONG +STDCALL +KeAlertResumeThread(IN PKTHREAD Thread) { - PETHREAD Thread; + ULONG PreviousCount; + KIRQL OldIrql; - Thread = PsGetCurrentThread(); + ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); + + /* Lock the Dispatcher Database and the APC Queue */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + KiAcquireSpinLock(&Thread->ApcQueueLock); - if (Thread->Tcb.ServiceTable != KeServiceDescriptorTableShadow) - { - PsInitWin32Thread (Thread); + /* Return if Thread is already alerted. */ + if (Thread->Alerted[KernelMode] == FALSE) { + + /* If it's Blocked, unblock if it we should */ + if (Thread->State == THREAD_STATE_BLOCKED && Thread->Alertable) { + + DPRINT("Aborting Wait\n"); + KiAbortWaitThread(Thread, STATUS_ALERTED); + + } else { + + /* If not, simply Alert it */ + Thread->Alerted[KernelMode] = TRUE; + } + } + + /* Save the old Suspend Count */ + PreviousCount = Thread->SuspendCount; + + /* If the thread is suspended, decrease one of the suspend counts */ + if (PreviousCount) { + + /* Decrease count. If we are now zero, unwait it completely */ + if (--Thread->SuspendCount) { + + /* Signal and satisfy */ + Thread->SuspendSemaphore.Header.SignalState++; + KiDispatcherObjectWake(&Thread->SuspendSemaphore.Header, IO_NO_INCREMENT); + } + } - Thread->Tcb.ServiceTable = KeServiceDescriptorTableShadow; + /* Release Locks and return the Old State */ + KiReleaseSpinLock(&Thread->ApcQueueLock); + KeReleaseDispatcherDatabaseLock(OldIrql); + return PreviousCount; +} + +BOOLEAN +STDCALL +KeAlertThread(PKTHREAD Thread, + KPROCESSOR_MODE AlertMode) +{ + KIRQL OldIrql; + BOOLEAN PreviousState; + + /* Acquire the Dispatcher Database Lock */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Save the Previous State */ + PreviousState = Thread->Alerted[AlertMode]; + + /* Return if Thread is already alerted. */ + if (PreviousState == FALSE) { + + /* If it's Blocked, unblock if it we should */ + if (Thread->State == THREAD_STATE_BLOCKED && + (AlertMode == KernelMode || Thread->WaitMode == AlertMode) && + Thread->Alertable) { + + DPRINT("Aborting Wait\n"); + KiAbortWaitThread(Thread, STATUS_ALERTED); + + } else { + + /* If not, simply Alert it */ + Thread->Alerted[AlertMode] = TRUE; + } } + + /* Release the Dispatcher Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return the old state */ + return PreviousState; } /* @@ -36,28 +110,231 @@ */ VOID STDCALL -KeCapturePersistentThreadState( - IN PVOID CurrentThread, - IN ULONG Setting1, - IN ULONG Setting2, - IN ULONG Setting3, - IN ULONG Setting4, - IN ULONG Setting5, - IN PVOID ThreadState -) +KeCapturePersistentThreadState(IN PVOID CurrentThread, + IN ULONG Setting1, + IN ULONG Setting2, + IN ULONG Setting3, + IN ULONG Setting4, + IN ULONG Setting5, + IN PVOID ThreadState) { - UNIMPLEMENTED; + UNIMPLEMENTED; } +/* + * FUNCTION: Initialize the microkernel state of the thread + */ VOID -KeFreeStackPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address, - PFN_TYPE Page, SWAPENTRY SwapEntry, BOOLEAN Dirty) +STDCALL +KeInitializeThread(PKPROCESS Process, + PKTHREAD Thread, + BOOLEAN First) { - ASSERT(SwapEntry == 0); - if (Page != 0) - { - MmReleasePageMemoryConsumer(MC_NPPOOL, Page); + PVOID KernelStack; + NTSTATUS Status; + extern unsigned int init_stack_top; + extern unsigned int init_stack; + PMEMORY_AREA StackArea; + ULONG i; + PHYSICAL_ADDRESS BoundaryAddressMultiple; + + /* Initialize the Boundary Address */ + BoundaryAddressMultiple.QuadPart = 0; + + /* Initalize the Dispatcher Header */ + KeInitializeDispatcherHeader(&Thread->DispatcherHeader, + ThreadObject, + sizeof(KTHREAD), + FALSE); + InitializeListHead(&Thread->MutantListHead); + + /* If this is isn't the first thread, allocate the Kernel Stack */ + if (!First) { + + PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE]; + KernelStack = NULL; + + MmLockAddressSpace(MmGetKernelAddressSpace()); + Status = MmCreateMemoryArea(NULL, + MmGetKernelAddressSpace(), + MEMORY_AREA_KERNEL_STACK, + &KernelStack, + MM_STACK_SIZE, + 0, + &StackArea, + FALSE, + FALSE, + BoundaryAddressMultiple); + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + + /* Check for Success */ + if (!NT_SUCCESS(Status)) { + + DPRINT1("Failed to create thread stack\n"); + KEBUGCHECK(0); + } + + /* Mark the Stack */ + for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++) { + + Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]); + + /* Check for success */ + if (!NT_SUCCESS(Status)) { + + KEBUGCHECK(0); + } + } + + /* Create a Virtual Mapping for it */ + Status = MmCreateVirtualMapping(NULL, + KernelStack, + PAGE_READWRITE, + Page, + MM_STACK_SIZE / PAGE_SIZE); + + /* Check for success */ + if (!NT_SUCCESS(Status)) { + + KEBUGCHECK(0); + } + + /* Set the Kernel Stack */ + Thread->InitialStack = (PCHAR)KernelStack + MM_STACK_SIZE; + Thread->StackBase = (PCHAR)KernelStack + MM_STACK_SIZE; + Thread->StackLimit = (ULONG_PTR)KernelStack; + Thread->KernelStack = (PCHAR)KernelStack + MM_STACK_SIZE; + + } else { + + /* Use the Initial Stack */ + Thread->InitialStack = (PCHAR)init_stack_top; + Thread->StackBase = (PCHAR)init_stack_top; + Thread->StackLimit = (ULONG_PTR)init_stack; + Thread->KernelStack = (PCHAR)init_stack_top; } + + /* + * Establish the pde's for the new stack and the thread structure within the + * address space of the new process. They are accessed while taskswitching or + * while handling page faults. At this point it isn't possible to call the + * page fault handler for the missing pde's. + */ + MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE); + MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); + + /* Set the Thread to initalized */ + Thread->State = THREAD_STATE_INITIALIZED; + + /* The Native API function will initialize the TEB field later */ + Thread->Teb = NULL; + + /* Initialize stuff to zero */ + Thread->TlsArray = NULL; + Thread->DebugActive = 0; + Thread->Alerted[0] = 0; + Thread->Alerted[1] = 0; + Thread->Iopl = 0; + + /* Set up FPU/NPX Stuff */ + Thread->NpxState = NPX_STATE_INVALID; + Thread->NpxIrql = 0; + + /* Setup APC Fields */ + InitializeListHead(&Thread->ApcState.ApcListHead[0]); + InitializeListHead(&Thread->ApcState.ApcListHead[1]); + Thread->ApcState.Process = Process; + Thread->ApcState.KernelApcInProgress = 0; + Thread->ApcState.KernelApcPending = 0; + Thread->ApcState.UserApcPending = 0; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; + Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; + Thread->ApcStateIndex = OriginalApcEnvironment; + Thread->ApcQueueable = TRUE; + RtlZeroMemory(&Thread->SavedApcState, sizeof(KAPC_STATE)); + KeInitializeSpinLock(&Thread->ApcQueueLock); + + /* Setup Wait Fields */ + Thread->WaitStatus = STATUS_SUCCESS; + Thread->WaitIrql = PASSIVE_LEVEL; + Thread->WaitMode = 0; + Thread->WaitNext = FALSE; + Thread->WaitListEntry.Flink = NULL; + Thread->WaitListEntry.Blink = NULL; + Thread->WaitTime = 0; + Thread->WaitBlockList = NULL; + RtlZeroMemory(Thread->WaitBlock, sizeof(KWAIT_BLOCK) * 4); + RtlZeroMemory(&Thread->Timer, sizeof(KTIMER)); + KeInitializeTimer(&Thread->Timer); + + /* Setup scheduler Fields */ + Thread->BasePriority = Process->BasePriority; + Thread->DecrementCount = 0; + Thread->PriorityDecrement = 0; + Thread->Quantum = Process->ThreadQuantum; + Thread->Saturation = 0; + Thread->Priority = Process->BasePriority; + Thread->UserAffinity = Process->Affinity; + Thread->SystemAffinityActive = 0; + Thread->Affinity = Process->Affinity; + Thread->Preempted = 0; + Thread->ProcessReadyQueue = 0; + Thread->KernelStackResident = 1; + Thread->NextProcessor = 0; + Thread->ContextSwitches = 0; + + /* Setup Queue Fields */ + Thread->Queue = NULL; + Thread->QueueListEntry.Flink = NULL; + Thread->QueueListEntry.Blink = NULL; + + /* Setup Misc Fields */ + Thread->LegoData = 0; + Thread->PowerState = 0; + Thread->ServiceTable = KeServiceDescriptorTable; + Thread->CallbackStack = NULL; + Thread->Win32Thread = NULL; + Thread->TrapFrame = NULL; + Thread->EnableStackSwap = 0; + Thread->LargeStack = 0; + Thread->ResourceIndex = 0; + Thread->PreviousMode = KernelMode; + Thread->KernelTime = 0; + Thread->UserTime = 0; + Thread->AutoAlignment = Process->AutoAlignment; + + /* FIXME OPTIMIZATION OF DOOM. DO NOT ENABLE FIXME */ +#if 0 + Thread->WaitBlock[3].Object = (PVOID)&Thread->Timer; + Thread->WaitBlock[3].Thread = Thread; + Thread->WaitBlock[3].WaitKey = STATUS_TIMEOUT; + Thread->WaitBlock[3].WaitType = WaitAny; + Thread->WaitBlock[3].NextWaitBlock = NULL; + InsertTailList(&Thread->Timer.Header.WaitListHead, + &Thread->WaitBlock[3].WaitListEntry); +#endif + + /* Initialize the Suspend APC */ + KeInitializeApc(&Thread->SuspendApc, + Thread, + OriginalApcEnvironment, + PiSuspendThreadKernelRoutine, + PiSuspendThreadRundownRoutine, + PiSuspendThreadNormalRoutine, + KernelMode, + NULL); + + /* Initialize the Suspend Semaphore */ + KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128); + + /* Insert the Thread into the Process's Thread List */ + InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry); + + /* Set up the Suspend Counts */ + Thread->FreezeCount = 0; + Thread->SuspendCount = 0; + + /* Do x86 specific part */ } /* @@ -65,11 +342,9 @@ */ KPRIORITY STDCALL -KeQueryPriorityThread ( - IN PKTHREAD Thread - ) +KeQueryPriorityThread (IN PKTHREAD Thread) { - return Thread->Priority; + return Thread->Priority; } /* @@ -77,19 +352,29 @@ */ ULONG STDCALL -KeQueryRuntimeThread( - IN PKTHREAD Thread, - OUT PULONG UserTime - ) +KeQueryRuntimeThread(IN PKTHREAD Thread, + OUT PULONG UserTime) { - /* Return the User Time */ - *UserTime = Thread->UserTime; - - /* Return the Kernel Time */ - return Thread->KernelTime; + /* Return the User Time */ + *UserTime = Thread->UserTime; + + /* Return the Kernel Time */ + return Thread->KernelTime; } -NTSTATUS +VOID +KeFreeStackPage(PVOID Context, + MEMORY_AREA* MemoryArea, + PVOID Address, + PFN_TYPE Page, + SWAPENTRY SwapEntry, + BOOLEAN Dirty) +{ + ASSERT(SwapEntry == 0); + if (Page) MmReleasePageMemoryConsumer(MC_NPPOOL, Page); +} + +NTSTATUS KeReleaseThread(PKTHREAD Thread) /* * FUNCTION: Releases the resource allocated for a thread by @@ -123,195 +408,26 @@ */ BOOLEAN STDCALL -KeSetKernelStackSwapEnable( - IN BOOLEAN Enable - ) +KeSetKernelStackSwapEnable(IN BOOLEAN Enable) { - PKTHREAD Thread; - BOOLEAN PreviousState; - - Thread = KeGetCurrentThread(); - - /* Save Old State */ - PreviousState = Thread->EnableStackSwap; - - /* Set New State */ - Thread->EnableStackSwap = Enable; + PKTHREAD Thread = KeGetCurrentThread(); + BOOLEAN PreviousState; + KIRQL OldIrql; + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); - /* Return Old State */ - return PreviousState; -} + /* Save Old State */ + PreviousState = Thread->EnableStackSwap; -VOID -KeInitializeThread(PKPROCESS Process, PKTHREAD Thread, BOOLEAN First) -/* - * FUNCTION: Initialize the microkernel state of the thread - */ -{ - PVOID KernelStack; - NTSTATUS Status; - extern unsigned int init_stack_top; - extern unsigned int init_stack; - PMEMORY_AREA StackArea; - ULONG i; - PHYSICAL_ADDRESS BoundaryAddressMultiple; - - BoundaryAddressMultiple.QuadPart = 0; - - KeInitializeDispatcherHeader(&Thread->DispatcherHeader, - InternalThreadType, - sizeof(ETHREAD), - FALSE); - InitializeListHead(&Thread->MutantListHead); - if (!First) - { - PFN_TYPE Page[MM_STACK_SIZE / PAGE_SIZE]; - KernelStack = NULL; - - MmLockAddressSpace(MmGetKernelAddressSpace()); - Status = MmCreateMemoryArea(NULL, - MmGetKernelAddressSpace(), - MEMORY_AREA_KERNEL_STACK, - &KernelStack, - MM_STACK_SIZE, - 0, - &StackArea, - FALSE, - FALSE, - BoundaryAddressMultiple); - MmUnlockAddressSpace(MmGetKernelAddressSpace()); - - if (!NT_SUCCESS(Status)) - { - DPRINT1("Failed to create thread stack\n"); - KEBUGCHECK(0); - } - for (i = 0; i < (MM_STACK_SIZE / PAGE_SIZE); i++) - { - Status = MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &Page[i]); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - } - Status = MmCreateVirtualMapping(NULL, - KernelStack, - PAGE_READWRITE, - Page, - MM_STACK_SIZE / PAGE_SIZE); - if (!NT_SUCCESS(Status)) - { - KEBUGCHECK(0); - } - Thread->InitialStack = (PCHAR)KernelStack + MM_STACK_SIZE; - Thread->StackBase = (PCHAR)KernelStack + MM_STACK_SIZE; - Thread->StackLimit = (ULONG_PTR)KernelStack; - Thread->KernelStack = (PCHAR)KernelStack + MM_STACK_SIZE; - } - else - { - Thread->InitialStack = (PCHAR)init_stack_top; - Thread->StackBase = (PCHAR)init_stack_top; - Thread->StackLimit = (ULONG_PTR)init_stack; - Thread->KernelStack = (PCHAR)init_stack_top; - } + /* Set New State */ + Thread->EnableStackSwap = Enable; - /* - * Establish the pde's for the new stack and the thread structure within the - * address space of the new process. They are accessed while taskswitching or - * while handling page faults. At this point it isn't possible to call the - * page fault handler for the missing pde's. - */ - - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE); - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); - - /* - * The Native API function will initialize the TEB field later - */ - Thread->Teb = NULL; - Thread->TlsArray = NULL; - Thread->DebugActive = 0; - Thread->State = THREAD_STATE_INITIALIZED; - Thread->Alerted[0] = 0; - Thread->Alerted[1] = 0; - Thread->Iopl = 0; - Thread->NpxState = NPX_STATE_INVALID; - - Thread->Saturation = 0; - Thread->Priority = Process->BasePriority; - InitializeListHead(&Thread->ApcState.ApcListHead[0]); - InitializeListHead(&Thread->ApcState.ApcListHead[1]); - Thread->ApcState.Process = Process; - Thread->ApcState.KernelApcInProgress = 0; - Thread->ApcState.KernelApcPending = 0; - Thread->ApcState.UserApcPending = 0; - Thread->ContextSwitches = 0; - Thread->WaitStatus = STATUS_SUCCESS; - Thread->WaitIrql = PASSIVE_LEVEL; - Thread->WaitMode = 0; - Thread->WaitNext = FALSE; - Thread->WaitBlockList = NULL; - Thread->WaitListEntry.Flink = NULL; - Thread->WaitListEntry.Blink = NULL; - Thread->WaitTime = 0; - Thread->BasePriority = Process->BasePriority; - Thread->DecrementCount = 0; - Thread->PriorityDecrement = 0; - Thread->Quantum = Process->ThreadQuantum; - RtlZeroMemory(Thread->WaitBlock, sizeof(KWAIT_BLOCK)*4); - Thread->LegoData = 0; - Thread->UserAffinity = Process->Affinity; - Thread->SystemAffinityActive = 0; - Thread->PowerState = 0; - Thread->NpxIrql = 0; - Thread->ServiceTable = KeServiceDescriptorTable; - Thread->Queue = NULL; - KeInitializeSpinLock(&Thread->ApcQueueLock); - RtlZeroMemory(&Thread->Timer, sizeof(KTIMER)); - KeInitializeTimer(&Thread->Timer); - Thread->QueueListEntry.Flink = NULL; - Thread->QueueListEntry.Blink = NULL; - Thread->Affinity = Process->Affinity; - Thread->Preempted = 0; - Thread->ProcessReadyQueue = 0; - Thread->KernelStackResident = 1; - Thread->NextProcessor = 0; - Thread->CallbackStack = NULL; - Thread->Win32Thread = NULL; - Thread->TrapFrame = NULL; - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; - Thread->EnableStackSwap = 0; - Thread->LargeStack = 0; - Thread->ResourceIndex = 0; - Thread->PreviousMode = KernelMode; - Thread->KernelTime = 0; - Thread->UserTime = 0; - RtlZeroMemory(&Thread->SavedApcState, sizeof(KAPC_STATE)); - - Thread->ApcStateIndex = OriginalApcEnvironment; - Thread->ApcQueueable = TRUE; - Thread->AutoAlignment = Process->AutoAlignment; - - KeInitializeApc(&Thread->SuspendApc, - Thread, - OriginalApcEnvironment, - PiSuspendThreadKernelRoutine, - PiSuspendThreadRundownRoutine, - PiSuspendThreadNormalRoutine, - KernelMode, - NULL); - KeInitializeSemaphore(&Thread->SuspendSemaphore, 0, 128); - - InsertTailList(&Process->ThreadListHead, - &Thread->ThreadListEntry); - Thread->FreezeCount = 0; - Thread->SuspendCount = 0; - - /* - * Do x86 specific part - */ + /* No, Release Lock */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + /* Return Old State */ + return PreviousState; } /* @@ -321,33 +437,33 @@ STDCALL KeRevertToUserAffinityThread(VOID) { -#ifdef CONFIG_SMP - PKTHREAD CurrentThread; - KIRQL oldIrql; + PKTHREAD CurrentThread = KeGetCurrentThread(); + KIRQL OldIrql; - oldIrql = KeAcquireDispatcherDatabaseLock(); + ASSERT(CurrentThread->SystemAffinityActive != FALSE); + + /* Lock the Dispatcher Database */ + OldIrql = KeAcquireDispatcherDatabaseLock(); - CurrentThread = KeGetCurrentThread(); + /* Return to User Affinity */ + CurrentThread->Affinity = CurrentThread->UserAffinity; - ASSERT(CurrentThread->SystemAffinityActive != FALSE); - - /* Return to User Affinity */ - CurrentThread->Affinity = CurrentThread->UserAffinity; - - /* Disable System Affinity */ - CurrentThread->SystemAffinityActive = FALSE; - - if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) - { - KeReleaseDispatcherDatabaseLock(oldIrql); - } - else - { - CurrentThread->WaitIrql = oldIrql; - PsDispatchThreadNoLock(THREAD_STATE_READY); - KeLowerIrql(oldIrql); - } -#endif + /* Disable System Affinity */ + CurrentThread->SystemAffinityActive = FALSE; + + /* Check if we need to Dispatch a New thread */ + if (CurrentThread->Affinity & (1 << KeGetCurrentProcessorNumber())) { + + /* No, just release */ + KeReleaseDispatcherDatabaseLock(OldIrql); + + } else { + + /* We need to dispatch a new thread */ + CurrentThread->WaitIrql = OldIrql; + PsDispatchThreadNoLock(THREAD_STATE_READY); + KeLowerIrql(OldIrql); + } } /* @@ -355,20 +471,26 @@ */ CCHAR STDCALL -KeSetIdealProcessorThread ( - IN PKTHREAD Thread, - IN CCHAR Processor) +KeSetIdealProcessorThread(IN PKTHREAD Thread, + IN CCHAR Processor) { [truncated at 1000 lines; 369 more skipped]
20 years, 2 months
2
1
0
0
[frik85] 13973: Add registry keys for language support
by frik85@svn.reactos.com
Add registry keys for language support Modified: trunk/reactos/bootdata/hivecls.inf _____ Modified: trunk/reactos/bootdata/hivecls.inf --- trunk/reactos/bootdata/hivecls.inf 2005-03-12 18:15:54 UTC (rev 13972) +++ trunk/reactos/bootdata/hivecls.inf 2005-03-12 19:22:30 UTC (rev 13973) @@ -344,4 +344,133 @@ HKCR,"WinNT\Clsid","",0x00000002,"{8b20cd60-0f29-11cf-abc4-02608c9e7553} " + +; For language support: + +HKCR,"MIME",,0x00000012 +HKCR,"MIME\Database",,0x00000012 +HKCR,"MIME\Database\Rfc1766",,0x00000012 +HKCR,"MIME\Database\Rfc1766","0436",0x00000000,"af;Afrikaans" +HKCR,"MIME\Database\Rfc1766","041C",0x00000000,"sq;Albanian" +HKCR,"MIME\Database\Rfc1766","0001",0x00000000,"ar;Arabic" +HKCR,"MIME\Database\Rfc1766","0401",0x00000000,"ar-sa;Arabic (Saudi Arabia)" +HKCR,"MIME\Database\Rfc1766","0801",0x00000000,"ar-iq;Arabic (Iraq)" +HKCR,"MIME\Database\Rfc1766","0C01",0x00000000,"ar-eg;Arabic (Egypt)" +HKCR,"MIME\Database\Rfc1766","1001",0x00000000,"ar-ly;Arabic (Libya)" +HKCR,"MIME\Database\Rfc1766","1401",0x00000000,"ar-dz;Arabic (Algeria)" +HKCR,"MIME\Database\Rfc1766","1801",0x00000000,"ar-ma;Arabic (Morocco)" +HKCR,"MIME\Database\Rfc1766","1C01",0x00000000,"ar-tn;Arabic (Tunisia)" +HKCR,"MIME\Database\Rfc1766","2001",0x00000000,"ar-om;Arabic (Oman)" +HKCR,"MIME\Database\Rfc1766","2401",0x00000000,"ar-ye;Arabic (Yemen)" +HKCR,"MIME\Database\Rfc1766","2801",0x00000000,"ar-sy;Arabic (Syria)" +HKCR,"MIME\Database\Rfc1766","2C01",0x00000000,"ar-jo;Arabic (Jordan)" +HKCR,"MIME\Database\Rfc1766","3001",0x00000000,"ar-lb;Arabic (Lebanon)" +HKCR,"MIME\Database\Rfc1766","3401",0x00000000,"ar-kw;Arabic (Kuwait)" +HKCR,"MIME\Database\Rfc1766","3801",0x00000000,"ar-ae;Arabic (U.A.E.)" +HKCR,"MIME\Database\Rfc1766","3C01",0x00000000,"ar-bh;Arabic (Bahrain)" +HKCR,"MIME\Database\Rfc1766","4001",0x00000000,"ar-qa;Arabic (Qatar)" +HKCR,"MIME\Database\Rfc1766","042D",0x00000000,"eu;Basque" +HKCR,"MIME\Database\Rfc1766","0402",0x00000000,"bg;Bulgarian" +HKCR,"MIME\Database\Rfc1766","0423",0x00000000,"be;Belarusian" +HKCR,"MIME\Database\Rfc1766","0403",0x00000000,"ca;Catalan" +HKCR,"MIME\Database\Rfc1766","0004",0x00000000,"zh;Chinese" +HKCR,"MIME\Database\Rfc1766","0404",0x00000000,"zh-tw;Chinese (Taiwan)" +HKCR,"MIME\Database\Rfc1766","0804",0x00000000,"zh-cn;Chinese (China)" +HKCR,"MIME\Database\Rfc1766","0C04",0x00000000,"zh-hk;Chinese (Hong Kong SAR)" +HKCR,"MIME\Database\Rfc1766","1004",0x00000000,"zh-sg;Chinese (Singapore)" +HKCR,"MIME\Database\Rfc1766","041A",0x00000000,"hr;Croatian" +HKCR,"MIME\Database\Rfc1766","0405",0x00000000,"cs;Czech" +HKCR,"MIME\Database\Rfc1766","0406",0x00000000,"da;Danish" +HKCR,"MIME\Database\Rfc1766","0413",0x00000000,"nl;Dutch (Netherlands)" +HKCR,"MIME\Database\Rfc1766","0813",0x00000000,"nl-be;Dutch (Belgium)" +HKCR,"MIME\Database\Rfc1766","0009",0x00000000,"en;English" +HKCR,"MIME\Database\Rfc1766","0409",0x00000000,"en-us;English (United States)" +HKCR,"MIME\Database\Rfc1766","0809",0x00000000,"en-gb;English (United Kingdom)" +HKCR,"MIME\Database\Rfc1766","0C09",0x00000000,"en-au;English (Australia)" +HKCR,"MIME\Database\Rfc1766","1009",0x00000000,"en-ca;English (Canada)" +HKCR,"MIME\Database\Rfc1766","1409",0x00000000,"en-nz;English (New Zealand)" +HKCR,"MIME\Database\Rfc1766","1809",0x00000000,"en-ie;English (Ireland)" +HKCR,"MIME\Database\Rfc1766","1C09",0x00000000,"en-za;English (South Africa)" +HKCR,"MIME\Database\Rfc1766","2009",0x00000000,"en-jm;English (Jamaica)" +HKCR,"MIME\Database\Rfc1766","2809",0x00000000,"en-bz;English (Belize)" +HKCR,"MIME\Database\Rfc1766","2C09",0x00000000,"en-tt;English (Trinidad)" +HKCR,"MIME\Database\Rfc1766","0425",0x00000000,"et;Estonian" +HKCR,"MIME\Database\Rfc1766","0438",0x00000000,"fo;Faeroese" +HKCR,"MIME\Database\Rfc1766","0429",0x00000000,"fa;Farsi" +HKCR,"MIME\Database\Rfc1766","040B",0x00000000,"fi;Finnish" +HKCR,"MIME\Database\Rfc1766","040C",0x00000000,"fr;French (France)" +HKCR,"MIME\Database\Rfc1766","080C",0x00000000,"fr-be;French (Belgium)" +HKCR,"MIME\Database\Rfc1766","0C0C",0x00000000,"fr-ca;French (Canada)" +HKCR,"MIME\Database\Rfc1766","100C",0x00000000,"fr-ch;French (Switzerland)" +HKCR,"MIME\Database\Rfc1766","140C",0x00000000,"fr-lu;French (Luxembourg)" +HKCR,"MIME\Database\Rfc1766","043C",0x00000000,"gd;Gaelic" +HKCR,"MIME\Database\Rfc1766","0407",0x00000000,"de;German (Germany)" +HKCR,"MIME\Database\Rfc1766","0807",0x00000000,"de-ch;German (Switzerland)" +HKCR,"MIME\Database\Rfc1766","0C07",0x00000000,"de-at;German (Austria)" +HKCR,"MIME\Database\Rfc1766","1007",0x00000000,"de-lu;German (Luxembourg)" +HKCR,"MIME\Database\Rfc1766","1407",0x00000000,"de-li;German (Liechtenstein)" +HKCR,"MIME\Database\Rfc1766","0408",0x00000000,"el;Greek" +HKCR,"MIME\Database\Rfc1766","040D",0x00000000,"he;Hebrew" +HKCR,"MIME\Database\Rfc1766","0439",0x00000000,"hi;Hindi" +HKCR,"MIME\Database\Rfc1766","040E",0x00000000,"hu;Hungarian" +HKCR,"MIME\Database\Rfc1766","040F",0x00000000,"is;Icelandic" +HKCR,"MIME\Database\Rfc1766","0421",0x00000000,"in;Indonesian" +HKCR,"MIME\Database\Rfc1766","0410",0x00000000,"it;Italian (Italy)" +HKCR,"MIME\Database\Rfc1766","0810",0x00000000,"it-ch;Italian (Switzerland)" +HKCR,"MIME\Database\Rfc1766","0411",0x00000000,"ja;Japanese" +HKCR,"MIME\Database\Rfc1766","0412",0x00000000,"ko;Korean" +HKCR,"MIME\Database\Rfc1766","0426",0x00000000,"lv;Latvian" +HKCR,"MIME\Database\Rfc1766","0427",0x00000000,"lt;Lithuanian" +HKCR,"MIME\Database\Rfc1766","042F",0x00000000,"mk;FYRO Macedonian" +HKCR,"MIME\Database\Rfc1766","043E",0x00000000,"ms;Malay (Malaysia)" +HKCR,"MIME\Database\Rfc1766","043A",0x00000000,"mt;Maltese" +HKCR,"MIME\Database\Rfc1766","0414",0x00000000,"no;Norwegian (Bokmal)" +HKCR,"MIME\Database\Rfc1766","0814",0x00000000,"no;Norwegian (Nynorsk)" +HKCR,"MIME\Database\Rfc1766","0415",0x00000000,"pl;Polish" +HKCR,"MIME\Database\Rfc1766","0416",0x00000000,"pt-br;Portuguese (Brazil)" +HKCR,"MIME\Database\Rfc1766","0816",0x00000000,"pt;Portuguese (Portugal)" +HKCR,"MIME\Database\Rfc1766","0417",0x00000000,"rm;Rhaeto-Romanic" +HKCR,"MIME\Database\Rfc1766","0418",0x00000000,"ro;Romanian" +HKCR,"MIME\Database\Rfc1766","0818",0x00000000,"ro-mo;Romanian (Moldova)" +HKCR,"MIME\Database\Rfc1766","0419",0x00000000,"ru;Russian" +HKCR,"MIME\Database\Rfc1766","0819",0x00000000,"ru-mo;Russian (Moldova)" +HKCR,"MIME\Database\Rfc1766","0C1A",0x00000000,"sr;Serbian (Cyrillic)" +HKCR,"MIME\Database\Rfc1766","081A",0x00000000,"sr;Serbian (Latin)" +HKCR,"MIME\Database\Rfc1766","041B",0x00000000,"sk;Slovak" +HKCR,"MIME\Database\Rfc1766","0424",0x00000000,"sl;Slovenian" +HKCR,"MIME\Database\Rfc1766","042E",0x00000000,"sb;Sorbian" +HKCR,"MIME\Database\Rfc1766","040A",0x00000000,"es;Spanish (Traditional Sort)" +HKCR,"MIME\Database\Rfc1766","080A",0x00000000,"es-mx;Spanish (Mexico)" +HKCR,"MIME\Database\Rfc1766","0C0A",0x00000000,"es;Spanish (International Sort)" +HKCR,"MIME\Database\Rfc1766","100A",0x00000000,"es-gt;Spanish (Guatemala)" +HKCR,"MIME\Database\Rfc1766","140A",0x00000000,"es-cr;Spanish (Costa Rica)" +HKCR,"MIME\Database\Rfc1766","180A",0x00000000,"es-pa;Spanish (Panama)" +HKCR,"MIME\Database\Rfc1766","1C0A",0x00000000,"es-do;Spanish (Dominican Republic)" +HKCR,"MIME\Database\Rfc1766","200A",0x00000000,"es-ve;Spanish (Venezuela)" +HKCR,"MIME\Database\Rfc1766","240A",0x00000000,"es-co;Spanish (Colombia)" +HKCR,"MIME\Database\Rfc1766","280A",0x00000000,"es-pe;Spanish (Peru)" +HKCR,"MIME\Database\Rfc1766","2C0A",0x00000000,"es-ar;Spanish (Argentina)" +HKCR,"MIME\Database\Rfc1766","300A",0x00000000,"es-ec;Spanish (Ecuador)" +HKCR,"MIME\Database\Rfc1766","340A",0x00000000,"es-cl;Spanish (Chile)" +HKCR,"MIME\Database\Rfc1766","380A",0x00000000,"es-uy;Spanish (Uruguay)" +HKCR,"MIME\Database\Rfc1766","3C0A",0x00000000,"es-py;Spanish (Paraguay)" +HKCR,"MIME\Database\Rfc1766","400A",0x00000000,"es-bo;Spanish (Bolivia)" +HKCR,"MIME\Database\Rfc1766","440A",0x00000000,"es-sv;Spanish (El Salvador)" +HKCR,"MIME\Database\Rfc1766","480A",0x00000000,"es-hn;Spanish (Honduras)" +HKCR,"MIME\Database\Rfc1766","4C0A",0x00000000,"es-ni;Spanish (Nicaragua)" +HKCR,"MIME\Database\Rfc1766","500A",0x00000000,"es-pr;Spanish (Puerto Rico)" +HKCR,"MIME\Database\Rfc1766","0430",0x00000000,"sx;Sutu" +HKCR,"MIME\Database\Rfc1766","041D",0x00000000,"sv;Swedish" +HKCR,"MIME\Database\Rfc1766","081D",0x00000000,"sv-fi;Swedish (Finland)" +HKCR,"MIME\Database\Rfc1766","041E",0x00000000,"th;Thai" +HKCR,"MIME\Database\Rfc1766","0431",0x00000000,"ts;Tsonga" +HKCR,"MIME\Database\Rfc1766","0432",0x00000000,"tn;Tswana" +HKCR,"MIME\Database\Rfc1766","041F",0x00000000,"tr;Turkish" +HKCR,"MIME\Database\Rfc1766","0422",0x00000000,"uk;Ukrainian" +HKCR,"MIME\Database\Rfc1766","0420",0x00000000,"ur;Urdu" +HKCR,"MIME\Database\Rfc1766","042A",0x00000000,"vi;Vietnamese" +HKCR,"MIME\Database\Rfc1766","0434",0x00000000,"xh;Xhosa" +HKCR,"MIME\Database\Rfc1766","043D",0x00000000,"ji;Yiddish" +HKCR,"MIME\Database\Rfc1766","0435",0x00000000,"zu;Zulu" + ; EOF
20 years, 2 months
1
0
0
0
[weiden] 13972: Alex Ionescu <ionucu@videotron.ca>
by weiden@svn.reactos.com
Alex Ionescu <ionucu(a)videotron.ca> - Remove branch leftover in debug message. - Uncondtionally enable setting the Window Station Atom Table. Modified: trunk/reactos/subsys/win32k/ntuser/message.c Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c _____ Modified: trunk/reactos/subsys/win32k/ntuser/message.c --- trunk/reactos/subsys/win32k/ntuser/message.c 2005-03-12 18:10:03 UTC (rev 13971) +++ trunk/reactos/subsys/win32k/ntuser/message.c 2005-03-12 18:15:54 UTC (rev 13972) @@ -167,9 +167,9 @@ } } _SEH_HANDLE { - DPRINT1("BOO!\n"); - return 0; + DPRINT1("Exception caught in MsgMemorySize()! Status: 0x%x\n", _SEH_GetExceptionCode()); } _SEH_END; + return 0; } static FASTCALL NTSTATUS _____ Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c --- trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-03-12 18:10:03 UTC (rev 13971) +++ trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-03-12 18:15:54 UTC (rev 13972) @@ -117,9 +117,7 @@ InitializeListHead(&WinSta->DesktopListHead); -#if 1 WinSta->AtomTable = NULL; -#endif Status = RtlCreateAtomTable(37, &WinSta->AtomTable); if (!NT_SUCCESS(Status))
20 years, 2 months
1
0
0
0
[weiden] 13971: Alex Ionescu <ionucu@videotron.ca>
by weiden@svn.reactos.com
Alex Ionescu <ionucu(a)videotron.ca> - Clean up formatting of ke/process.c (which I had messed up at the time due to MSVC) - Acknowledge Blight's work - Implement KeRemoveServiceDescriptorTable - Remove ex/napi.c and move the Tables into ke/process.c Modified: trunk/reactos/include/ddk/kefuncs.h Modified: trunk/reactos/ntoskrnl/Makefile Deleted: trunk/reactos/ntoskrnl/ex/napi.c Modified: trunk/reactos/ntoskrnl/ke/process.c _____ Modified: trunk/reactos/include/ddk/kefuncs.h --- trunk/reactos/include/ddk/kefuncs.h 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/include/ddk/kefuncs.h 2005-03-12 18:10:03 UTC (rev 13971) @@ -720,7 +720,7 @@ BOOLEAN STDCALL KeRemoveSystemServiceTable( - IN PUCHAR Number + IN ULONG TableIndex ); NTSTATUS _____ Modified: trunk/reactos/ntoskrnl/Makefile --- trunk/reactos/ntoskrnl/Makefile 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/ntoskrnl/Makefile 2005-03-12 18:10:03 UTC (rev 13971) @@ -247,7 +247,6 @@ ex/list.o \ ex/lookas.o \ ex/mutant.o \ - ex/napi.o \ ex/power.o \ ex/profile.o \ ex/resource.o \ @@ -438,7 +437,6 @@ $(PATH_TO_TOP)/include/reactos/bugcodes.h \ $(DEP_OBJECTS) $(DEP_FILES) MSG00409.bin bugcodes.rc -ex/napi.o: ex/zw.S $(PATH_TO_TOP)/include/ntdll/napi.h ke/main.o: ke/main.c $(PATH_TO_TOP)/include/reactos/buildno.h _____ Deleted: trunk/reactos/ntoskrnl/ex/napi.c --- trunk/reactos/ntoskrnl/ex/napi.c 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/ntoskrnl/ex/napi.c 2005-03-12 18:10:03 UTC (rev 13971) @@ -1,36 +0,0 @@ -/* $Id:$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ex/napi.c - * PURPOSE: Native API support routines - * - * PROGRAMMERS: David Welch (welch(a)cwcom.net) - */ - -/* INCLUDES *****************************************************************/ - -#include <ntoskrnl.h> -#include <ntdll/napi.h> -#include <internal/debug.h> - -/* GLOBALS ******************************************************************/ - -SSDT_ENTRY -__declspec(dllexport) -KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = -{ - { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT }, - { NULL, NULL, 0, NULL }, - { NULL, NULL, 0, NULL }, - { NULL, NULL, 0, NULL } -}; - -SSDT_ENTRY -KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = -{ - { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT }, - { NULL, NULL, 0, NULL }, - { NULL, NULL, 0, NULL }, - { NULL, NULL, 0, NULL } -}; _____ Modified: trunk/reactos/ntoskrnl/ke/process.c --- trunk/reactos/ntoskrnl/ke/process.c 2005-03-12 17:02:43 UTC (rev 13970) +++ trunk/reactos/ntoskrnl/ke/process.c 2005-03-12 18:10:03 UTC (rev 13971) @@ -1,34 +1,56 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/process.c - * PURPOSE: Microkernel process management + * PURPOSE: Attaching/Detaching and System Call Tables * - * PROGRAMMERS: David Welch (welch(a)cwcom.net) + * PROGRAMMERS: Alex Ionescu (Implemented Attach/Detach and KeRemoveSystemServiceTable) + * Gregor Anich (Bugfixes to Attach Functions) */ /* INCLUDES *****************************************************************/ #include <ntoskrnl.h> +#include <ntdll/napi.h> #define NDEBUG #include <internal/debug.h> +/* GLOBALS *****************************************************************/ + +SSDT_ENTRY +__declspec(dllexport) +KeServiceDescriptorTable[SSDT_MAX_ENTRIES] = { + { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT }, + { NULL, NULL, 0, NULL }, + { NULL, NULL, 0, NULL }, + { NULL, NULL, 0, NULL } +}; + +SSDT_ENTRY +KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] = { + { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT }, + { NULL, NULL, 0, NULL }, + { NULL, NULL, 0, NULL }, + { NULL, NULL, 0, NULL } +}; + /* FUNCTIONS *****************************************************************/ static inline void UpdatePageDirs(PKTHREAD Thread, PKPROCESS Process) { - /* The stack and the thread structure of the current process may be - located in a page which is not present in the page directory of - the process we're attaching to. That would lead to a page fault - when this function returns. However, since the processor can't - call the page fault handler 'cause it can't push EIP on the stack, - this will show up as a stack fault which will crash the entire system. - To prevent this, make sure the page directory of the process we're - attaching to is up-to-date. */ - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE); - MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); + /* + * The stack and the thread structure of the current process may be + * located in a page which is not present in the page directory of + * the process we're attaching to. That would lead to a page fault + * when this function returns. However, since the processor can't + * call the page fault handler 'cause it can't push EIP on the stack, + * this will show up as a stack fault which will crash the entire system. + * To prevent this, make sure the page directory of the process we're + * attaching to is up-to-date. + */ + MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, MM_STACK_SIZE); + MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD)); } /* @@ -38,29 +60,33 @@ STDCALL KeAttachProcess(PKPROCESS Process) { - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); - - DPRINT("KeAttachProcess: %x\n", Process); + KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); - UpdatePageDirs(Thread, Process); + DPRINT("KeAttachProcess: %x\n", Process); - /* Lock Dispatcher */ - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Crash system if DPC is being executed! */ - if (KeIsExecutingDpc()) { - DPRINT1("Invalid attach (Thread is executing a DPC!)\n"); - KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT); - } - - /* Check if the Target Process is already attached */ - if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) { - DPRINT("Process already Attached. Exitting\n"); - KeReleaseDispatcherDatabaseLock(OldIrql); - } else { - KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); - } + /* Make sure that we are in the right page directory */ + UpdatePageDirs(Thread, Process); + + /* Lock Dispatcher */ + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Crash system if DPC is being executed! */ + if (KeIsExecutingDpc()) { + + DPRINT1("Invalid attach (Thread is executing a DPC!)\n"); + KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT); + } + + /* Check if the Target Process is already attached */ + if (Thread->ApcState.Process == Process || Thread->ApcStateIndex != OriginalApcEnvironment) { + + DPRINT("Process already Attached. Exitting\n"); + KeReleaseDispatcherDatabaseLock(OldIrql); + } else { + + KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); + } } VOID @@ -68,52 +94,54 @@ KiAttachProcess(PKTHREAD Thread, PKPROCESS Process, KIRQL ApcLock, PRKAPC_STATE SavedApcState) { - DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState); + DPRINT("KiAttachProcess(Thread: %x, Process: %x, SavedApcState: %x\n", Thread, Process, SavedApcState); - /* Increase Stack Count */ - Process->StackCount++; - - /* Swap the APC Environment */ - KiMoveApcState(&Thread->ApcState, SavedApcState); - - /* Reinitialize Apc State */ - InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]); - InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); - Thread->ApcState.Process = Process; - Thread->ApcState.KernelApcInProgress = FALSE; - Thread->ApcState.KernelApcPending = FALSE; - Thread->ApcState.UserApcPending = FALSE; + /* Increase Stack Count */ + Process->StackCount++; + + /* Swap the APC Environment */ + KiMoveApcState(&Thread->ApcState, SavedApcState); - /* Update Environment Pointers if needed*/ - if (SavedApcState == &Thread->SavedApcState) { - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState; - Thread->ApcStateIndex = AttachedApcEnvironment; - } - - /* Swap the Processes */ - KiSwapProcess(Process, SavedApcState->Process); - - /* Return to old IRQL*/ - KeReleaseDispatcherDatabaseLock(ApcLock); - - DPRINT("KiAttachProcess Completed Sucesfully\n"); + /* Reinitialize Apc State */ + InitializeListHead(&Thread->ApcState.ApcListHead[KernelMode]); + InitializeListHead(&Thread->ApcState.ApcListHead[UserMode]); + Thread->ApcState.Process = Process; + Thread->ApcState.KernelApcInProgress = FALSE; + Thread->ApcState.KernelApcPending = FALSE; + Thread->ApcState.UserApcPending = FALSE; + + /* Update Environment Pointers if needed*/ + if (SavedApcState == &Thread->SavedApcState) { + + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->SavedApcState; + Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->ApcState; + Thread->ApcStateIndex = AttachedApcEnvironment; + } + + /* Swap the Processes */ + KiSwapProcess(Process, SavedApcState->Process); + + /* Return to old IRQL*/ + KeReleaseDispatcherDatabaseLock(ApcLock); + + DPRINT("KiAttachProcess Completed Sucesfully\n"); } VOID STDCALL KiSwapProcess(PKPROCESS NewProcess, PKPROCESS OldProcess) { - //PKPCR Pcr = KeGetCurrentKpcr(); + //PKPCR Pcr = KeGetCurrentKpcr(); - /* Do they have an LDT? */ - if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) { - /* FIXME : SWitch GDT/IDT */ - } - DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart); - Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart); - - /* FIXME: Set IopmOffset in TSS */ + /* Do they have an LDT? */ + if ((NewProcess->LdtDescriptor) || (OldProcess->LdtDescriptor)) { + + /* FIXME : SWitch GDT/IDT */ + } + DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart); + Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart); + + /* FIXME: Set IopmOffset in TSS */ } /* @@ -121,11 +149,10 @@ */ BOOLEAN STDCALL -KeIsAttachedProcess( - VOID - ) +KeIsAttachedProcess(VOID) { - return KeGetCurrentThread()->ApcStateIndex; + /* Return the APC State */ + return KeGetCurrentThread()->ApcStateIndex; } /* @@ -133,36 +160,41 @@ */ VOID STDCALL -KeStackAttachProcess ( - IN PKPROCESS Process, - OUT PRKAPC_STATE ApcState - ) +KeStackAttachProcess(IN PKPROCESS Process, + OUT PRKAPC_STATE ApcState) { - KIRQL OldIrql; - PKTHREAD Thread = KeGetCurrentThread(); + KIRQL OldIrql; + PKTHREAD Thread = KeGetCurrentThread(); - UpdatePageDirs(Thread, Process); + /* Make sure that we are in the right page directory */ + UpdatePageDirs(Thread, Process); - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Crash system if DPC is being executed! */ - if (KeIsExecutingDpc()) { - DPRINT1("Invalid attach (Thread is executing a DPC!)\n"); - KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT); - } - - /* Check if the Target Process is already attached */ - if (Thread->ApcState.Process == Process) { - ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */ - } else { - /* Check if the Current Thread is already attached and call the Internal Function*/ - if (Thread->ApcStateIndex != OriginalApcEnvironment) { - KiAttachProcess(Thread, Process, OldIrql, ApcState); - } else { - KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); - ApcState->Process = NULL; - } - } + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Crash system if DPC is being executed! */ + if (KeIsExecutingDpc()) { + + DPRINT1("Invalid attach (Thread is executing a DPC!)\n"); + KEBUGCHECK(INVALID_PROCESS_ATTACH_ATTEMPT); + } + + /* Check if the Target Process is already attached */ + if (Thread->ApcState.Process == Process) { + + ApcState->Process = (PKPROCESS)1; /* Meaning already attached to the same Process */ + + } else { + + /* Check if the Current Thread is already attached and call the Internal Function*/ + if (Thread->ApcStateIndex != OriginalApcEnvironment) { + + KiAttachProcess(Thread, Process, OldIrql, ApcState); + } else { + + KiAttachProcess(Thread, Process, OldIrql, &Thread->SavedApcState); + ApcState->Process = NULL; + } + } } /* @@ -171,38 +203,39 @@ VOID STDCALL KeDetachProcess (VOID) { - PKTHREAD Thread; - KIRQL OldIrql; + PKTHREAD Thread; + KIRQL OldIrql; - DPRINT("KeDetachProcess()\n"); + DPRINT("KeDetachProcess()\n"); - /* Get Current Thread and Lock */ - Thread = KeGetCurrentThread(); - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Check if it's attached */ - DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex); - - if (Thread->ApcStateIndex == OriginalApcEnvironment) { - DPRINT1("Invalid detach (thread was not attached)\n"); - KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); - } + /* Get Current Thread and Lock */ + Thread = KeGetCurrentThread(); + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Check if it's attached */ + DPRINT("Current ApcStateIndex: %x\n", Thread->ApcStateIndex); + + if (Thread->ApcStateIndex == OriginalApcEnvironment) { + + DPRINT1("Invalid detach (thread was not attached)\n"); + KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); + } - /* Decrease Stack Count */ - Thread->ApcState.Process->StackCount--; - - /* Restore the APC State */ - KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); - Thread->SavedApcState.Process = NULL; - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; - Thread->ApcStateIndex = OriginalApcEnvironment; - - /* Swap Processes */ - KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); + /* Decrease Stack Count */ + Thread->ApcState.Process->StackCount--; + + /* Restore the APC State */ + KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); + Thread->SavedApcState.Process = NULL; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; + Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; + Thread->ApcStateIndex = OriginalApcEnvironment; + + /* Swap Processes */ + KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); - /* Unlock Dispatcher */ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Unlock Dispatcher */ + KeReleaseDispatcherDatabaseLock(OldIrql); } /* @@ -214,55 +247,56 @@ IN PRKAPC_STATE ApcState ) { - KIRQL OldIrql; - PKTHREAD Thread; + KIRQL OldIrql; + PKTHREAD Thread; - /* If the special "We tried to attach to the process already being attached to" flag is there, don't do anything */ - if (ApcState->Process == (PKPROCESS)1) return; - - Thread = KeGetCurrentThread(); - OldIrql = KeAcquireDispatcherDatabaseLock(); - - /* Sorry Buddy, can't help you if you've got APCs or just aren't attached */ - if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) { - DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n"); - KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); - } - - /* Restore the Old APC State if a Process was present */ - if (ApcState->Process) { - KiMoveApcState(ApcState, &Thread->ApcState); - } else { - /* The ApcState parameter is useless, so use the saved data and reset it */ - KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); - Thread->SavedApcState.Process = NULL; - Thread->ApcStateIndex = OriginalApcEnvironment; - Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; - Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; - } + /* + * If the special "We tried to attach to the process already being + * attached to" flag is there, don't do anything + */ + if (ApcState->Process == (PKPROCESS)1) return; + + Thread = KeGetCurrentThread(); + OldIrql = KeAcquireDispatcherDatabaseLock(); + + /* Sorry Buddy, can't help you if you've got APCs or just aren't attached */ + if ((Thread->ApcStateIndex == OriginalApcEnvironment) || (Thread->ApcState.KernelApcInProgress)) { + + DPRINT1("Invalid detach (Thread not Attached, or Kernel APC in Progress!)\n"); + KEBUGCHECK(INVALID_PROCESS_DETACH_ATTEMPT); + } + + /* Restore the Old APC State if a Process was present */ + if (ApcState->Process) { + + KiMoveApcState(ApcState, &Thread->ApcState); + + } else { + + /* The ApcState parameter is useless, so use the saved data and reset it */ + KiMoveApcState(&Thread->SavedApcState, &Thread->ApcState); + Thread->SavedApcState.Process = NULL; + Thread->ApcStateIndex = OriginalApcEnvironment; + Thread->ApcStatePointer[OriginalApcEnvironment] = &Thread->ApcState; + Thread->ApcStatePointer[AttachedApcEnvironment] = &Thread->SavedApcState; + } - /* Swap Processes */ - KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); + /* Swap Processes */ + KiSwapProcess(Thread->ApcState.Process, Thread->ApcState.Process); - /* Return to old IRQL*/ - KeReleaseDispatcherDatabaseLock(OldIrql); + /* Return to old IRQL*/ + KeReleaseDispatcherDatabaseLock(OldIrql); } -/* This function should be used by win32k.sys to add its own user32/gdi32 services - * TableIndex is 0 based - * ServiceCountTable its not used at the moment - */ /* * @implemented */ BOOLEAN STDCALL -KeAddSystemServiceTable ( - PSSDT SSDT, - PULONG ServiceCounterTable, - ULONG NumberOfServices, - PSSPT SSPT, - ULONG TableIndex - ) +KeAddSystemServiceTable(PSSDT SSDT, + PULONG ServiceCounterTable, + ULONG NumberOfServices, + PSSPT SSPT, + ULONG TableIndex) { /* check if descriptor table entry is free */ if ((TableIndex > SSDT_MAX_ENTRIES - 1) || @@ -280,15 +314,37 @@ } /* - * @unimplemented + * @implemented */ BOOLEAN STDCALL -KeRemoveSystemServiceTable( - IN PUCHAR Number -) +KeRemoveSystemServiceTable(IN ULONG TableIndex) { - UNIMPLEMENTED; - return FALSE; + /* Make sure the Index is valid */ + if (TableIndex > SSDT_MAX_ENTRIES - 1) return FALSE; + + /* Is there a Normal Descriptor Table? */ + if (!KeServiceDescriptorTable[TableIndex].SSDT) { + + /* Not with the index, is there a shadow at least? */ + if (!KeServiceDescriptorTableShadow[TableIndex].SSDT) return FALSE; + } + + /* Now clear from the Shadow Table. */ + KeServiceDescriptorTableShadow[TableIndex].SSDT = NULL; + KeServiceDescriptorTableShadow[TableIndex].SSPT = NULL; + KeServiceDescriptorTableShadow[TableIndex].NumberOfServices = 0; + KeServiceDescriptorTableShadow[TableIndex].ServiceCounterTable = NULL; + + /* Check if we should clean from the Master one too */ + if (TableIndex == 1) { + + KeServiceDescriptorTable[TableIndex].SSDT = NULL; + KeServiceDescriptorTable[TableIndex].SSPT = NULL; + KeServiceDescriptorTable[TableIndex].NumberOfServices = 0; + KeServiceDescriptorTable[TableIndex].ServiceCounterTable = NULL; + } + + return TRUE; } /* EOF */
20 years, 2 months
1
0
0
0
[weiden] 13970: Alex Ionescu <ionucu@videotron.ca>
by weiden@svn.reactos.com
Alex Ionescu <ionucu(a)videotron.ca> Fix wrong assertion. Modified: trunk/reactos/ntoskrnl/ke/spinlock.c _____ Modified: trunk/reactos/ntoskrnl/ke/spinlock.c --- trunk/reactos/ntoskrnl/ke/spinlock.c 2005-03-12 16:01:30 UTC (rev 13969) +++ trunk/reactos/ntoskrnl/ke/spinlock.c 2005-03-12 17:02:43 UTC (rev 13970) @@ -178,7 +178,7 @@ * FIXME: This depends on gcc assembling this test to a single load from * the spinlock's value. */ - ASSERT(*SpinLock == 0 || 1); + ASSERT(*SpinLock == 0 || *SpinLock == 1); while ((i = InterlockedExchangeUL(SpinLock, 1)) == 1) {
20 years, 2 months
1
0
0
0
[navaraf] 13969: Alex Ionescu <ionucu@videotron.ca>
by navaraf@svn.reactos.com
Alex Ionescu <ionucu(a)videotron.ca> Various bugcheck code improvements: - Fix bugcheck code and make debugging easier for unhandled exceptions/spinlocks. - Fix a race condition with TAB+B, - Fix irql to be high_level. - Fix calling unsafe function by caching bugcode data. - Fix support for smp by using IPI. - Fix not-breakpointing when no debugger is there. - Implement KeBugCheck callbacks with reason. - Fix callbacks not being called. - Fix proper breakpoint during bugcheck. Filip Navara <xnavara(a)volny.cz> - Move the bugcheck initialization code into Ke (was in Ex on Alex's branch). Modified: trunk/reactos/ntoskrnl/include/internal/debug.h Modified: trunk/reactos/ntoskrnl/include/internal/ke.h Modified: trunk/reactos/ntoskrnl/ke/bug.c Modified: trunk/reactos/ntoskrnl/ke/catch.c Modified: trunk/reactos/ntoskrnl/ke/i386/brkpoint.c Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c Modified: trunk/reactos/ntoskrnl/ke/spinlock.c _____ Modified: trunk/reactos/ntoskrnl/include/internal/debug.h --- trunk/reactos/ntoskrnl/include/internal/debug.h 2005-03-12 14:15:49 UTC (rev 13968) +++ trunk/reactos/ntoskrnl/include/internal/debug.h 2005-03-12 16:01:30 UTC (rev 13969) @@ -38,11 +38,11 @@ /* Assert only on "checked" version */ #ifndef NASSERT #ifdef CONFIG_SMP -#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), KeBugCheck(0); } -#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), KeBugCheck(0); } +#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), DbgBreakPoint(); } +#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d for CPU%d\n", __FILE__,__LINE__, KeGetCurrentKPCR()->ProcessorNumber), DbgBreakPoint(); } #else -#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); } -#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); KeBugCheck(0); } +#define assert(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); DbgBreakPoint(); } +#define ASSERT(x) if (!(x)) {DbgPrint("Assertion "#x" failed at %s:%d\n", __FILE__,__LINE__); DbgBreakPoint(); } #endif #define assertmsg(_c_, _m_) \ _____ Modified: trunk/reactos/ntoskrnl/include/internal/ke.h --- trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-12 14:15:49 UTC (rev 13968) +++ trunk/reactos/ntoskrnl/include/internal/ke.h 2005-03-12 16:01:30 UTC (rev 13969) @@ -196,7 +196,7 @@ VOID KeInitDispatcher(VOID); VOID KeInitializeDispatcher(VOID); VOID KiInitializeSystemClock(VOID); -VOID KeInitializeBugCheck(VOID); +VOID KiInitializeBugCheck(VOID); VOID Phase1Initialization(PVOID Context); VOID KeInit1(PCHAR CommandLine, PULONG LastKernelAddress); _____ Modified: trunk/reactos/ntoskrnl/ke/bug.c --- trunk/reactos/ntoskrnl/ke/bug.c 2005-03-12 14:15:49 UTC (rev 13968) +++ trunk/reactos/ntoskrnl/ke/bug.c 2005-03-12 16:01:30 UTC (rev 13969) @@ -1,200 +1,445 @@ -/* $Id$ - * +/* * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel * FILE: ntoskrnl/ke/bug.c * PURPOSE: Graceful system shutdown if a bug is detected * - * PROGRAMMERS: David Welch (welch(a)cwcom.net) + * PROGRAMMERS: Alex Ionescu - Rewrote Bugcheck Routines and implemented Reason Callbacks. + * David Welch (welch(a)cwcom.net) * Phillip Susi */ /* INCLUDES *****************************************************************/ #include <ntoskrnl.h> -#include <ntos/bootvid.h> +#define NDEBUG #include <internal/debug.h> -#include "../../hal/halx86/include/hal.h" /* GLOBALS ******************************************************************/ static LIST_ENTRY BugcheckCallbackListHead = {NULL,NULL}; +static LIST_ENTRY BugcheckReasonCallbackListHead = {NULL,NULL}; static ULONG InBugCheck; +static PRTL_MESSAGE_RESOURCE_DATA KiBugCodeMessages; +static ULONG KeBugCheckCount = 1; /* FUNCTIONS *****************************************************************/ -VOID INIT_FUNCTION -KeInitializeBugCheck(VOID) +VOID +INIT_FUNCTION +KiInitializeBugCheck(VOID) { - InitializeListHead(&BugcheckCallbackListHead); - InBugCheck = 0; + PRTL_MESSAGE_RESOURCE_DATA BugCheckData; + LDR_RESOURCE_INFO ResourceInfo; + PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; + NTSTATUS Status; + + /* Initialize Callbadk Listhead and State */ + InitializeListHead(&BugcheckCallbackListHead); + InitializeListHead(&BugcheckReasonCallbackListHead); + InBugCheck = 0; + + /* Cache the Bugcheck Message Strings. Prepare the Lookup Data */ + ResourceInfo.Type = 11; + ResourceInfo.Name = 1; + ResourceInfo.Language = 9; + + /* Do the lookup. */ + Status = LdrFindResource_U((PVOID)KERNEL_BASE, + &ResourceInfo, + RESOURCE_DATA_LEVEL, + &ResourceDataEntry); + + /* Make sure it worked */ + if (NT_SUCCESS(Status)) { + + DPRINT1("Found Bugcheck Resource Data!\n"); + + /* Now actually get a pointer to it */ + Status = LdrAccessResource((PVOID)KERNEL_BASE, + ResourceDataEntry, + (PVOID*)&BugCheckData, + NULL); + + /* Make sure it worked */ + if (NT_SUCCESS(Status)) { + + DPRINT1("Got Pointer to Bugcheck Resource Data!\n"); + KiBugCodeMessages = BugCheckData; + } + } } /* * @implemented */ -BOOLEAN STDCALL +BOOLEAN +STDCALL KeDeregisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord) { - /* Check the Current State */ - if (CallbackRecord->State == BufferInserted) { - CallbackRecord->State = BufferEmpty; - RemoveEntryList(&CallbackRecord->Entry); - return TRUE; - } - - /* The callback wasn't registered */ - return FALSE; + KIRQL OldIrql; + BOOLEAN Status = FALSE; + + /* Raise IRQL to High */ + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + /* Check the Current State */ + if (CallbackRecord->State == BufferInserted) { + + /* Reset state and remove from list */ + CallbackRecord->State = BufferEmpty; + RemoveEntryList(&CallbackRecord->Entry); + + Status = TRUE; + } + + /* Lower IRQL and return */ + KeLowerIrql(OldIrql); + return Status; } /* * @implemented */ -BOOLEAN STDCALL +BOOLEAN +STDCALL +KeDeregisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord) +{ + KIRQL OldIrql; + BOOLEAN Status = FALSE; + + /* Raise IRQL to High */ + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + /* Check the Current State */ + if (CallbackRecord->State == BufferInserted) { + + /* Reset state and remove from list */ + CallbackRecord->State = BufferEmpty; + RemoveEntryList(&CallbackRecord->Entry); + + Status = TRUE; + } + + /* Lower IRQL and return */ + KeLowerIrql(OldIrql); + return Status; +} + +/* + * @implemented + */ +BOOLEAN +STDCALL KeRegisterBugCheckCallback(PKBUGCHECK_CALLBACK_RECORD CallbackRecord, - PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, - PVOID Buffer, - ULONG Length, - PUCHAR Component) + PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine, + PVOID Buffer, + ULONG Length, + PUCHAR Component) { + KIRQL OldIrql; + BOOLEAN Status = FALSE; + + /* Raise IRQL to High */ + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + /* Check the Current State first so we don't double-register */ + if (CallbackRecord->State == BufferEmpty) { + + /* Set the Callback Settings and insert into the list */ + CallbackRecord->Length = Length; + CallbackRecord->Buffer = Buffer; + CallbackRecord->Component = Component; + CallbackRecord->CallbackRoutine = CallbackRoutine; + CallbackRecord->State = BufferInserted; + InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry); + + Status = TRUE; + } - /* Check the Current State first so we don't double-register */ - if (CallbackRecord->State == BufferEmpty) { - CallbackRecord->Length = Length; - CallbackRecord->Buffer = Buffer; - CallbackRecord->Component = Component; - CallbackRecord->CallbackRoutine = CallbackRoutine; - CallbackRecord->State = BufferInserted; - InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry); - - return TRUE; - } - - /* The Callback was already registered */ - return(FALSE); + /* Lower IRQL and return */ + KeLowerIrql(OldIrql); + return Status; } -VOID STDCALL -KeBugCheckWithTf(ULONG BugCheckCode, - ULONG BugCheckParameter1, - ULONG BugCheckParameter2, - ULONG BugCheckParameter3, - ULONG BugCheckParameter4, - PKTRAP_FRAME Tf) +/* + * @implemented + */ +BOOLEAN +STDCALL +KeRegisterBugCheckReasonCallback(IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, + IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, + IN KBUGCHECK_CALLBACK_REASON Reason, + IN PUCHAR Component) { - PRTL_MESSAGE_RESOURCE_ENTRY Message; - NTSTATUS Status; - ULONG Mask; - KIRQL OldIrql; + KIRQL OldIrql; + BOOLEAN Status = FALSE; + + /* Raise IRQL to High */ + KeRaiseIrql(HIGH_LEVEL, &OldIrql); + + /* Check the Current State first so we don't double-register */ + if (CallbackRecord->State == BufferEmpty) { + + /* Set the Callback Settings and insert into the list */ + CallbackRecord->Component = Component; + CallbackRecord->CallbackRoutine = CallbackRoutine; + CallbackRecord->State = BufferInserted; + CallbackRecord->Reason = Reason; + InsertTailList(&BugcheckReasonCallbackListHead, &CallbackRecord->Entry); + + Status = TRUE; + } - /* Make sure we're switching back to the blue screen and print messages on it */ - HalReleaseDisplayOwnership(); - if (0 == (KdDebugState & KD_DEBUG_GDB)) - { - KdDebugState |= KD_DEBUG_SCREEN; + /* Lower IRQL and return */ + KeLowerIrql(OldIrql); + return Status; +} + +VOID +STDCALL +KeGetBugMessageText(ULONG BugCheckCode, PANSI_STRING OutputString) +{ + ULONG i; + ULONG IdOffset; + ULONG_PTR MessageEntry; + PCHAR BugCode; + + /* Find the message. This code is based on RtlFindMesssage -- Alex */ + for (i = 0; i < KiBugCodeMessages->NumberOfBlocks; i++) { + + /* Check if the ID Matches */ + if ((BugCheckCode >= KiBugCodeMessages->Blocks[i].LowId) && + (BugCheckCode <= KiBugCodeMessages->Blocks[i].HighId)) { + + /* Get Offset to Entry */ + MessageEntry = (ULONG_PTR)KiBugCodeMessages + KiBugCodeMessages->Blocks[i].OffsetToEntries; + IdOffset = BugCheckCode - KiBugCodeMessages->Blocks[i].LowId; + + /* Get offset to ID */ + for (i = 0; i < IdOffset; i++) { + + /* Advance in the Entries */ + MessageEntry += ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Length; + } + + /* Get the final Code */ + BugCode = ((PRTL_MESSAGE_RESOURCE_ENTRY)MessageEntry)->Text; + + /* Return it in the OutputString */ + if (OutputString) { + + OutputString->Buffer = BugCode; + OutputString->Length = strlen(BugCode) + 1; + OutputString->MaximumLength = strlen(BugCode) + 1; + + } else { + + /* Direct Output to Screen */ + DbgPrint("%s\n", BugCode); + break; + } + } } +} - Ke386DisableInterrupts(); - DebugLogDumpMessages(); +VOID +STDCALL +KiDoBugCheckCallbacks(VOID) +{ + PKBUGCHECK_CALLBACK_RECORD CurrentRecord; + PLIST_ENTRY ListHead; + PLIST_ENTRY NextEntry; + + /* FIXME: Check Checksum and add support for WithReason Callbacks */ + + /* First make sure that the list is Initialized... it might not be */ + ListHead = &BugcheckCallbackListHead; + if (ListHead->Flink && ListHead->Blink) { + + /* Loop the list */ + NextEntry = ListHead->Flink; + while (NextEntry != ListHead) { + + /* Get the Callback Record */ + CurrentRecord = CONTAINING_RECORD(NextEntry, + KBUGCHECK_CALLBACK_RECORD, + Entry); + + /* Make sure it's inserted */ + if (CurrentRecord->State == BufferInserted) { + + /* Call the routine */ + CurrentRecord->State = BufferStarted; + (CurrentRecord->CallbackRoutine)(CurrentRecord->Buffer, + CurrentRecord->Length); + CurrentRecord->State = BufferFinished; + } + + /* Move to next Entry */ + NextEntry = NextEntry->Flink; + } + } +} - if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread()) - { - MmUnlockAddressSpace(MmGetKernelAddressSpace()); +VOID +STDCALL +KeBugCheckWithTf(ULONG BugCheckCode, + ULONG BugCheckParameter1, + ULONG BugCheckParameter2, + ULONG BugCheckParameter3, + ULONG BugCheckParameter4, + PKTRAP_FRAME Tf) +{ + KIRQL OldIrql; + BOOLEAN GotExtendedCrashInfo = FALSE; + PVOID Address = 0; + PLIST_ENTRY CurrentEntry; + MODULE_TEXT_SECTION* CurrentSection = NULL; + extern LIST_ENTRY ModuleTextListHead; + + /* Make sure we're switching back to the blue screen and print messages on it */ + HalReleaseDisplayOwnership(); + if (0 == (KdDebugState & KD_DEBUG_GDB)) KdDebugState |= KD_DEBUG_SCREEN; + + /* Try to find out who did this. For this, we need a Trap Frame. + * Note: Some special BSODs pass the Frame/EIP as a Param. MSDN has the + * info so it eventually needs to be supported. + */ + if (Tf) { + + /* For now, get Address from EIP */ + Address = (PVOID)Tf->Eip; + + /* Try to get information on the module */ + CurrentEntry = ModuleTextListHead.Flink; + while (CurrentEntry != &ModuleTextListHead && CurrentEntry != NULL) { + + /* Get the current Section */ + CurrentSection = CONTAINING_RECORD(CurrentEntry, + MODULE_TEXT_SECTION, + ListEntry); + + /* Check if this is the right one */ + if ((Address != NULL && (Address >= (PVOID)CurrentSection->Base && + Address < (PVOID)(CurrentSection->Base + CurrentSection->Length)))) { + + /* We got it */ + GotExtendedCrashInfo = TRUE; + break; + } + + /* Loop again */ + CurrentEntry = CurrentEntry->Flink; + } } + + /* Raise IRQL to HIGH_LEVEL */ + Ke386DisableInterrupts(); + KeRaiseIrql(HIGH_LEVEL, &OldIrql); - if (KeGetCurrentIrql() < DISPATCH_LEVEL) - { - KeRaiseIrql(DISPATCH_LEVEL, &OldIrql); + /* Disable Interrupts, Dump Debug Messages */ + DebugLogDumpMessages(); + + /* Unload the Kernel Adress Space if we own it */ + if (MmGetKernelAddressSpace()->Lock.Owner == KeGetCurrentThread()) + MmUnlockAddressSpace(MmGetKernelAddressSpace()); + + /* FIXMEs: Use inbv to clear, fill and write to screen. */ + + /* Show the STOP Message */ + DbgPrint("A problem has been detected and ReactOS has been shut down to prevent " + "damage to your computer.\n\n"); + + /* Show the module name of who caused this */ + if (GotExtendedCrashInfo) { + + DbgPrint("The problem seems to be caused by the following file: %S\n\n", CurrentSection->Name); } - DbgPrint("Bug detected (code %x param %x %x %x %x)\n", - BugCheckCode, - BugCheckParameter1, - BugCheckParameter2, - BugCheckParameter3, - BugCheckParameter4); - Status = RtlFindMessage((PVOID)KERNEL_BASE, //0xC0000000, - 11, //RT_MESSAGETABLE, - 0x09, //0x409, - BugCheckCode, - &Message); - if (NT_SUCCESS(Status)) - { - if (Message->Flags == 0) - DbgPrint(" %s\n", Message->Text); - else - DbgPrint(" %S\n", (PWSTR)Message->Text); + /* Find the Bug Code String */ + KeGetBugMessageText(BugCheckCode, NULL); + + /* Show the techincal Data */ + DbgPrint("Technical information:\n\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\n\n", + BugCheckCode, + BugCheckParameter1, + BugCheckParameter2, + BugCheckParameter3, + BugCheckParameter4); + + /* Show the module name and more data of who caused this */ + if (GotExtendedCrashInfo) { + + DbgPrint("*** %S - Address 0x%p base at 0x%p, DateStamp 0x%x\n\n", + CurrentSection->Name, + Address, + CurrentSection->Base, + 0); } - else - { - DbgPrint(" No message text found!\n\n"); - } - Mask = 1 << KeGetCurrentProcessorNumber(); - if (InBugCheck & Mask) - { -#ifdef MP - DbgPrint("Recursive bug check on CPU%d, halting now\n", KeGetCurrentProcessorNumber()); - /* - * FIXME: - * Send an ipi to all other processors which halt them too. - */ -#else - DbgPrint("Recursive bug check halting now\n"); + + /* There can only be one Bugcheck per Bootup */ + if (!InterlockedDecrement(&KeBugCheckCount)) { + +#ifdef CONFIG_SMP + ULONG i; + /* Freeze the other CPUs */ + for (i = 0; i < KeNumberProcessors; i++) { + if (i != KeGetCurrentProcessorNumber()) { + + /* Send the IPI and give them one second to catch up */ + KiIpiSendRequest(1 << i, IPI_REQUEST_FREEZE); + KeStallExecutionProcessor(1000000); + } + } #endif - Ke386HaltProcessor(); - } - /* - * FIXME: - * Use InterlockedOr or InterlockedBitSet. - */ - InBugCheck |= Mask; - if (Tf != NULL) - { - KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2); - } - else - { + + /* Check if we got a Trap Frame */ + if (Tf) { + + /* Dump it */ + KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2); + + } else { + + /* We can only dump the frames */ #if defined(__GNUC__) - KeDumpStackFrames((PULONG)__builtin_frame_address(0)); + KeDumpStackFrames((PULONG)__builtin_frame_address(0)); #elif defined(_MSC_VER) - __asm push ebp - __asm call KeDumpStackFrames - __asm add esp, 4 + __asm push ebp + __asm call KeDumpStackFrames + __asm add esp, 4 #else #error Unknown compiler for inline assembler #endif - } - MmDumpToPagingFile(BugCheckCode, BugCheckParameter1, - BugCheckParameter2, BugCheckParameter3, - BugCheckParameter4, Tf); + } + + /* Call the Callbacks */; + KiDoBugCheckCallbacks(); - if (KdDebuggerEnabled) - { - Ke386EnableInterrupts(); - DbgBreakPointNoBugCheck(); - Ke386DisableInterrupts(); + /* Dump the BSOD to the Paging File */ + MmDumpToPagingFile(BugCheckCode, + BugCheckParameter1, + BugCheckParameter2, + BugCheckParameter3, + BugCheckParameter4, + Tf); + + /* Wake up the Debugger */ + if (KdDebuggerEnabled) { + Ke386EnableInterrupts(); + DbgBreakPointWithStatus(DBG_STATUS_BUGCHECK_SECOND); + Ke386DisableInterrupts(); + } } - for (;;) - { - /* - * FIXME: - * Send an ipi to all other processors which halt them too. - */ - Ke386HaltProcessor(); - } + /* Halt this CPU now */ + for (;;) Ke386HaltProcessor(); } /* * @implemented - */ -VOID STDCALL -KeBugCheckEx(ULONG BugCheckCode, - ULONG BugCheckParameter1, - ULONG BugCheckParameter2, - ULONG BugCheckParameter3, - ULONG BugCheckParameter4) -/* + * * FUNCTION: Brings the system down in a controlled manner when an * inconsistency that might otherwise cause corruption has been detected * ARGUMENTS: @@ -202,23 +447,34 @@ * BugCheckParameter[1-4] = Additional information about bug * RETURNS: Doesn't */ +VOID +STDCALL +KeBugCheckEx(ULONG BugCheckCode, + ULONG BugCheckParameter1, + ULONG BugCheckParameter2, + ULONG BugCheckParameter3, + ULONG BugCheckParameter4) { - KeBugCheckWithTf(BugCheckCode, BugCheckParameter1, BugCheckParameter2, - BugCheckParameter3, BugCheckParameter4, NULL); + /* Call the Trap Frame version without a Trap Frame */ + KeBugCheckWithTf(BugCheckCode, + BugCheckParameter1, + BugCheckParameter2, + BugCheckParameter3, + BugCheckParameter4, + NULL); } /* * @implemented - */ -VOID STDCALL -KeBugCheck(ULONG BugCheckCode) -/* + * * FUNCTION: Brings the system down in a controlled manner when an * inconsistency that might otherwise cause corruption has been detected * ARGUMENTS: * BugCheckCode = Specifies the reason for the bug check * RETURNS: Doesn't */ +VOID STDCALL +KeBugCheck(ULONG BugCheckCode) { KeBugCheckEx(BugCheckCode, 0, 0, 0, 0); } _____ Modified: trunk/reactos/ntoskrnl/ke/catch.c --- trunk/reactos/ntoskrnl/ke/catch.c 2005-03-12 14:15:49 UTC (rev 13968) +++ trunk/reactos/ntoskrnl/ke/catch.c 2005-03-12 16:01:30 UTC (rev 13969) @@ -260,19 +260,6 @@ /* * @unimplemented */ -BOOLEAN -STDCALL -KeDeregisterBugCheckReasonCallback( - IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord - ) -{ - UNIMPLEMENTED; - return FALSE; -} - -/* - * @unimplemented - */ ULONG STDCALL KeGetRecommendedSharedDataAlignment( @@ -283,20 +270,4 @@ return 0; } -/* - * @unimplemented - */ -BOOLEAN -STDCALL -KeRegisterBugCheckReasonCallback( - IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord, - IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine, - IN KBUGCHECK_CALLBACK_REASON Reason, - IN PUCHAR Component - ) -{ - UNIMPLEMENTED; - return FALSE; -} - /* EOF */ _____ Modified: trunk/reactos/ntoskrnl/ke/i386/brkpoint.c --- trunk/reactos/ntoskrnl/ke/i386/brkpoint.c 2005-03-12 14:15:49 UTC (rev 13968) +++ trunk/reactos/ntoskrnl/ke/i386/brkpoint.c 2005-03-12 16:01:30 UTC (rev 13969) @@ -1,4 +1,4 @@ -/* $Id:$ +/* $Id$ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -34,10 +34,10 @@ * @implemented */ #if defined(__GNUC__) -__asm__(".globl _DbgBreakPointNoBugCheck@0\n\t" - "_DbgBreakPointNoBugCheck@0:\n\t" - "int $3\n\t" - "ret\n\t"); + __asm__(".globl _DbgBreakPointNoBugCheck@0\n\t" + "_DbgBreakPointNoBugCheck@0:\n\t" + "int $3\n\t" + "ret\n\t"); #endif /* _____ Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c --- trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-12 14:15:49 UTC (rev 13968) +++ trunk/reactos/ntoskrnl/ke/i386/kernel.c 2005-03-12 16:01:30 UTC (rev 13969) @@ -355,7 +355,7 @@ { PKPCR Pcr = KeGetCurrentKPCR(); - KeInitializeBugCheck(); + KiInitializeBugCheck(); KeInitializeDispatcher(); KiInitializeSystemClock(); _____ Modified: trunk/reactos/ntoskrnl/ke/spinlock.c --- trunk/reactos/ntoskrnl/ke/spinlock.c 2005-03-12 14:15:49 UTC (rev 13968) +++ trunk/reactos/ntoskrnl/ke/spinlock.c 2005-03-12 16:01:30 UTC (rev 13969) @@ -178,11 +178,7 @@ * FIXME: This depends on gcc assembling this test to a single load from * the spinlock's value. */ - if (*SpinLock >= 2) - { - DbgPrint("Lock %x has bad value %x\n", SpinLock, *SpinLock); - KEBUGCHECK(0); - } + ASSERT(*SpinLock == 0 || 1); while ((i = InterlockedExchangeUL(SpinLock, 1)) == 1) { @@ -199,7 +195,7 @@ #endif #else DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i); - KEBUGCHECK(0); + KEBUGCHECKEX(SPIN_LOCK_ALREADY_OWNED, (ULONG)SpinLock, 0, 0, 0); #endif /* CONFIG_SMP */ } } @@ -227,7 +223,7 @@ if (*SpinLock != 1) { DbgPrint("Releasing unacquired spinlock %x\n", SpinLock); - KEBUGCHECK(0); + KEBUGCHECKEX(SPIN_LOCK_NOT_OWNED, (ULONG)SpinLock, 0, 0, 0); } (void)InterlockedExchangeUL(SpinLock, 0); }
20 years, 2 months
1
0
0
0
[navaraf] 13968: Alex Ionescu <ionucu@videotron.ca>
by navaraf@svn.reactos.com
Alex Ionescu <ionucu(a)videotron.ca> Move win32k callbacks to win32k where they belong. Registration is done with Ps function just like on XP+. Also allows non-win32k stuff to manage their own desktops and window stations. Modified: trunk/reactos/include/ddk/defines.h Modified: trunk/reactos/include/ddk/psfuncs.h Modified: trunk/reactos/include/ddk/pstypes.h Modified: trunk/reactos/ntoskrnl/ex/win32k.c Modified: trunk/reactos/ntoskrnl/ps/win32.c Modified: trunk/reactos/subsys/win32k/include/desktop.h Modified: trunk/reactos/subsys/win32k/include/winsta.h Modified: trunk/reactos/subsys/win32k/main/dllmain.c Modified: trunk/reactos/subsys/win32k/ntuser/desktop.c Modified: trunk/reactos/subsys/win32k/ntuser/message.c Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c Modified: trunk/reactos/w32api/include/ddk/ntifs.h Modified: trunk/reactos/w32api/include/ddk/winddk.h Modified: trunk/reactos/w32api/include/winnt.h _____ Modified: trunk/reactos/include/ddk/defines.h --- trunk/reactos/include/ddk/defines.h 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/include/ddk/defines.h 2005-03-12 14:15:49 UTC (rev 13968) @@ -77,6 +77,27 @@ #define HIGH_LEVEL 31 // Highest interrupt level #define SYNCH_LEVEL (IPI_LEVEL-1) // synchronization level +#define WINSTA_ACCESSCLIPBOARD (0x4L) +#define WINSTA_ACCESSGLOBALATOMS (0x20L) +#define WINSTA_CREATEDESKTOP (0x8L) +#define WINSTA_ENUMDESKTOPS (0x1L) +#define WINSTA_ENUMERATE (0x100L) +#define WINSTA_EXITWINDOWS (0x40L) +#define WINSTA_READATTRIBUTES (0x2L) +#define WINSTA_READSCREEN (0x200L) +#define WINSTA_WRITEATTRIBUTES (0x10L) + +#define DF_ALLOWOTHERACCOUNTHOOK (0x1L) +#define DESKTOP_CREATEMENU (0x4L) +#define DESKTOP_CREATEWINDOW (0x2L) +#define DESKTOP_ENUMERATE (0x40L) +#define DESKTOP_HOOKCONTROL (0x8L) +#define DESKTOP_JOURNALPLAYBACK (0x20L) +#define DESKTOP_JOURNALRECORD (0x10L) +#define DESKTOP_READOBJECTS (0x1L) +#define DESKTOP_SWITCHDESKTOP (0x100L) +#define DESKTOP_WRITEOBJECTS (0x80L) + #endif /* __ASM__ */ /* Values returned by KeGetPreviousMode() */ _____ Modified: trunk/reactos/include/ddk/psfuncs.h --- trunk/reactos/include/ddk/psfuncs.h 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/include/ddk/psfuncs.h 2005-03-12 14:15:49 UTC (rev 13968) @@ -360,7 +360,7 @@ VOID STDCALL STDCALL PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback, PW32_THREAD_CALLBACK W32ThreadCallback, - PVOID Param3, + PW32_OBJECT_CALLBACK W32ObjectCallback, PVOID Param4, ULONG W32ThreadSize, ULONG W32ProcessSize); _____ Modified: trunk/reactos/include/ddk/pstypes.h --- trunk/reactos/include/ddk/pstypes.h 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/include/ddk/pstypes.h 2005-03-12 14:15:49 UTC (rev 13968) @@ -66,7 +66,41 @@ typedef NTSTATUS STDCALL_FUNC (*PW32_THREAD_CALLBACK)(struct _ETHREAD *Thread, BOOLEAN Create); + +/* + * Callbacks used for Win32 objects... this define won't be needed after the Object Manager + * rewrite -- Alex + */ +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_PARSE_ROUTINE)(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes); + +typedef VOID STDCALL_FUNC +(*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject); + +typedef PVOID STDCALL_FUNC +(*OBJECT_FIND_ROUTINE)(PVOID WinStaObject, + PWSTR Name, + ULONG Attributes); + +typedef struct _W32_OBJECT_CALLBACK { + OBJECT_CREATE_ROUTINE WinStaCreate; + OBJECT_PARSE_ROUTINE WinStaParse; + OBJECT_DELETE_ROUTINE WinStaDelete; + OBJECT_FIND_ROUTINE WinStaFind; + OBJECT_CREATE_ROUTINE DesktopCreate; + OBJECT_DELETE_ROUTINE DesktopDelete; +} W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK; + typedef struct _STACK_INFORMATION { PVOID BaseAddress; _____ Modified: trunk/reactos/ntoskrnl/ex/win32k.c --- trunk/reactos/ntoskrnl/ex/win32k.c 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/ntoskrnl/ex/win32k.c 2005-03-12 14:15:49 UTC (rev 13968) @@ -5,7 +5,8 @@ * FILE: ntoskrnl/ex/win32k.c * PURPOSE: Executive Win32 subsystem support * - * PROGRAMMERS: Casper S. Hornstrup (chorns(a)users.sourceforge.net) + * PROGRAMMERS: Alex Ionescu (alex(a)relsoft.net) - Moved callbacks to win32k and cleanup. + * Casper S. Hornstrup (chorns(a)users.sourceforge.net) */ #include <ntoskrnl.h> @@ -14,320 +15,160 @@ /* DATA **********************************************************************/ -#define WINSTA_ACCESSCLIPBOARD (0x4L) -#define WINSTA_ACCESSGLOBALATOMS (0x20L) -#define WINSTA_CREATEDESKTOP (0x8L) -#define WINSTA_ENUMDESKTOPS (0x1L) -#define WINSTA_ENUMERATE (0x100L) -#define WINSTA_EXITWINDOWS (0x40L) -#define WINSTA_READATTRIBUTES (0x2L) -#define WINSTA_READSCREEN (0x200L) -#define WINSTA_WRITEATTRIBUTES (0x10L) - -#define DF_ALLOWOTHERACCOUNTHOOK (0x1L) -#define DESKTOP_CREATEMENU (0x4L) -#define DESKTOP_CREATEWINDOW (0x2L) -#define DESKTOP_ENUMERATE (0x40L) -#define DESKTOP_HOOKCONTROL (0x8L) -#define DESKTOP_JOURNALPLAYBACK (0x20L) -#define DESKTOP_JOURNALRECORD (0x10L) -#define DESKTOP_READOBJECTS (0x1L) -#define DESKTOP_SWITCHDESKTOP (0x100L) -#define DESKTOP_WRITEOBJECTS (0x80L) - POBJECT_TYPE EXPORTED ExWindowStationObjectType = NULL; POBJECT_TYPE EXPORTED ExDesktopObjectType = NULL; static GENERIC_MAPPING ExpWindowStationMapping = { - STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | WINSTA_READSCREEN, - STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES, - STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS, - STANDARD_RIGHTS_REQUIRED | WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | - WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | - WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES + + STANDARD_RIGHTS_READ | WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_READATTRIBUTES | WINSTA_READSCREEN, + STANDARD_RIGHTS_WRITE | WINSTA_ACCESSCLIPBOARD | WINSTA_CREATEDESKTOP | WINSTA_WRITEATTRIBUTES, + STANDARD_RIGHTS_EXECUTE | WINSTA_ACCESSGLOBALATOMS | WINSTA_EXITWINDOWS, + STANDARD_RIGHTS_REQUIRED | WINSTA_ACCESSCLIPBOARD | WINSTA_ACCESSGLOBALATOMS | WINSTA_CREATEDESKTOP | + WINSTA_ENUMDESKTOPS | WINSTA_ENUMERATE | WINSTA_EXITWINDOWS | + WINSTA_READATTRIBUTES | WINSTA_READSCREEN | WINSTA_WRITEATTRIBUTES }; static GENERIC_MAPPING ExpDesktopMapping = { - STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS, - STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL | - DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS, - STANDARD_RIGHTS_EXECUTE | DESKTOP_SWITCHDESKTOP, - STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | - DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | - DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS + + STANDARD_RIGHTS_READ | DESKTOP_ENUMERATE | DESKTOP_READOBJECTS, + STANDARD_RIGHTS_WRITE | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_HOOKCONTROL | + DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | DESKTOP_WRITEOBJECTS, + STANDARD_RIGHTS_EXECUTE | DESKTOP_SWITCHDESKTOP, + STANDARD_RIGHTS_REQUIRED | DESKTOP_CREATEMENU | DESKTOP_CREATEWINDOW | DESKTOP_ENUMERATE | + DESKTOP_HOOKCONTROL | DESKTOP_JOURNALPLAYBACK | DESKTOP_JOURNALRECORD | + DESKTOP_READOBJECTS | DESKTOP_SWITCHDESKTOP | DESKTOP_WRITEOBJECTS }; +OBJECT_CREATE_ROUTINE ExpWindowStationObjectCreate = NULL; +OBJECT_PARSE_ROUTINE ExpWindowStationObjectParse = NULL; +OBJECT_DELETE_ROUTINE ExpWindowStationObjectDelete = NULL; +OBJECT_FIND_ROUTINE ExpWindowStationObjectFind = NULL; +OBJECT_CREATE_ROUTINE ExpDesktopObjectCreate = NULL; +OBJECT_DELETE_ROUTINE ExpDesktopObjectDelete = NULL; + /* FUNCTIONS ****************************************************************/ - -NTSTATUS STDCALL +NTSTATUS +STDCALL ExpWinStaObjectCreate(PVOID ObjectBody, - PVOID Parent, - PWSTR RemainingPath, - struct _OBJECT_ATTRIBUTES* ObjectAttributes) + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) { - PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody; - UNICODE_STRING UnicodeString; - NTSTATUS Status; - - if (RemainingPath == NULL) - { - return STATUS_SUCCESS; - } - - if (wcschr((RemainingPath + 1), '\\') != NULL) - { - return STATUS_UNSUCCESSFUL; - } - - RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); - - DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta, &UnicodeString); - - Status = RtlpCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer, NonPagedPool); - if (!NT_SUCCESS(Status)) - { - return Status; - } - - KeInitializeSpinLock(&WinSta->Lock); - - InitializeListHead(&WinSta->DesktopListHead); - -#if 1 - WinSta->AtomTable = NULL; -#endif - - Status = RtlCreateAtomTable(37, &WinSta->AtomTable); - if (!NT_SUCCESS(Status)) - { - RtlFreeUnicodeString(&WinSta->Name); - return Status; - } - - WinSta->SystemMenuTemplate = (HANDLE)0; - - DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name); - - return STATUS_SUCCESS; + /* Call the Registered Callback */ + return ExpWindowStationObjectCreate(ObjectBody, + Parent, + RemainingPath, + ObjectAttributes); } -VOID STDCALL +VOID +STDCALL ExpWinStaObjectDelete(PVOID DeletedObject) { - PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject; - - DPRINT("Deleting window station (0x%X)\n", WinSta); - - RtlDestroyAtomTable(WinSta->AtomTable); - - RtlFreeUnicodeString(&WinSta->Name); + /* Call the Registered Callback */ + ExpWindowStationObjectDelete(DeletedObject); } PVOID +STDCALL ExpWinStaObjectFind(PWINSTATION_OBJECT WinStaObject, - PWSTR Name, - ULONG Attributes) + PWSTR Name, + ULONG Attributes) { - PLIST_ENTRY Current; - PDESKTOP_OBJECT CurrentObject; - - DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name); - - if (Name[0] == 0) - { - return NULL; - } - - Current = WinStaObject->DesktopListHead.Flink; - while (Current != &WinStaObject->DesktopListHead) - { - CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry); - DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name); - if (Attributes & OBJ_CASE_INSENSITIVE) - { - if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0) - { - DPRINT("Found desktop at (0x%X)\n", CurrentObject); - return CurrentObject; - } - } - else - { - if (wcscmp(CurrentObject->Name.Buffer, Name) == 0) - { - DPRINT("Found desktop at (0x%X)\n", CurrentObject); - return CurrentObject; - } - } - Current = Current->Flink; - } - - DPRINT("Returning NULL\n"); - - return NULL; + /* Call the Registered Callback */ + return ExpWindowStationObjectFind(WinStaObject, + Name, + Attributes); } -NTSTATUS STDCALL +NTSTATUS +STDCALL ExpWinStaObjectParse(PVOID Object, - PVOID *NextObject, - PUNICODE_STRING FullPath, - PWSTR *Path, - ULONG Attributes) + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes) { - PVOID FoundObject; - NTSTATUS Status; - PWSTR End; - - DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path); - - *NextObject = NULL; - - if ((Path == NULL) || ((*Path) == NULL)) - { - return STATUS_SUCCESS; - } - - End = wcschr((*Path) + 1, '\\'); - if (End != NULL) - { - DPRINT("Name contains illegal characters\n"); - return STATUS_UNSUCCESSFUL; - } - - FoundObject = ExpWinStaObjectFind(Object, (*Path) + 1, Attributes); - if (FoundObject == NULL) - { - DPRINT("Name was not found\n"); - return STATUS_UNSUCCESSFUL; - } - - Status = ObReferenceObjectByPointer( - FoundObject, - STANDARD_RIGHTS_REQUIRED, - NULL, - UserMode); - - *NextObject = FoundObject; - *Path = NULL; - - return Status; + /* Call the Registered Callback */ + return ExpWindowStationObjectParse(Object, + NextObject, + FullPath, + Path, + Attributes); } -NTSTATUS STDCALL -ExpDesktopObjectCreate(PVOID ObjectBody, - PVOID Parent, - PWSTR RemainingPath, - struct _OBJECT_ATTRIBUTES* ObjectAttributes) +NTSTATUS +STDCALL +ExpDesktopCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) { - PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody; - UNICODE_STRING UnicodeString; - - if (RemainingPath == NULL) - { - return STATUS_SUCCESS; - } - - if (wcschr((RemainingPath + 1), '\\') != NULL) - { - return STATUS_UNSUCCESSFUL; - } - - RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); - - DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString); - - KeInitializeSpinLock(&Desktop->Lock); - - Desktop->WindowStation = (PWINSTATION_OBJECT)Parent; - - /* Put the desktop on the window station's list of associcated desktops */ - ExInterlockedInsertTailList( - &Desktop->WindowStation->DesktopListHead, - &Desktop->ListEntry, - &Desktop->WindowStation->Lock); - - return RtlpCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer, NonPagedPool); + /* Call the Registered Callback */ + return ExpDesktopObjectCreate(ObjectBody, + Parent, + RemainingPath, + ObjectAttributes); } -VOID STDCALL -ExpDesktopObjectDelete(PVOID DeletedObject) +VOID +STDCALL +ExpDesktopDelete(PVOID DeletedObject) { - PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject; - KIRQL OldIrql; - - DPRINT("Deleting desktop (0x%X)\n", Desktop); - - /* Remove the desktop from the window station's list of associcated desktops */ - KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql); - RemoveEntryList(&Desktop->ListEntry); - KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql); - - RtlFreeUnicodeString(&Desktop->Name); + /* Call the Registered Callback */ + ExpDesktopObjectDelete(DeletedObject); } -VOID INIT_FUNCTION +VOID +INIT_FUNCTION ExpWin32kInit(VOID) { - /* Create window station object type */ - ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); - if (ExWindowStationObjectType == NULL) - { - CPRINT("Could not create window station object type\n"); - KEBUGCHECK(0); - } + /* Create window station object type */ + ExWindowStationObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S'); + ExWindowStationObjectType->TotalObjects = 0; + ExWindowStationObjectType->TotalHandles = 0; + ExWindowStationObjectType->PeakObjects = 0; + ExWindowStationObjectType->PeakHandles = 0; + ExWindowStationObjectType->PagedPoolCharge = 0; + ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT); + ExWindowStationObjectType->Mapping = &ExpWindowStationMapping; + ExWindowStationObjectType->Dump = NULL; + ExWindowStationObjectType->Open = NULL; + ExWindowStationObjectType->Close = NULL; + ExWindowStationObjectType->Delete = ExpWinStaObjectDelete; + ExWindowStationObjectType->Parse = ExpWinStaObjectParse; + ExWindowStationObjectType->Security = NULL; + ExWindowStationObjectType->QueryName = NULL; + ExWindowStationObjectType->OkayToClose = NULL; + ExWindowStationObjectType->Create = ExpWinStaObjectCreate; + ExWindowStationObjectType->DuplicationNotify = NULL; + RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation"); + ObpCreateTypeObject(ExWindowStationObjectType); - ExWindowStationObjectType->Tag = TAG('W', 'I', 'N', 'S'); - ExWindowStationObjectType->TotalObjects = 0; - ExWindowStationObjectType->TotalHandles = 0; - ExWindowStationObjectType->PeakObjects = 0; - ExWindowStationObjectType->PeakHandles = 0; - ExWindowStationObjectType->PagedPoolCharge = 0; - ExWindowStationObjectType->NonpagedPoolCharge = sizeof(WINSTATION_OBJECT); - ExWindowStationObjectType->Mapping = &ExpWindowStationMapping; - ExWindowStationObjectType->Dump = NULL; - ExWindowStationObjectType->Open = NULL; - ExWindowStationObjectType->Close = NULL; - ExWindowStationObjectType->Delete = ExpWinStaObjectDelete; - ExWindowStationObjectType->Parse = ExpWinStaObjectParse; - ExWindowStationObjectType->Security = NULL; - ExWindowStationObjectType->QueryName = NULL; - ExWindowStationObjectType->OkayToClose = NULL; - ExWindowStationObjectType->Create = ExpWinStaObjectCreate; - ExWindowStationObjectType->DuplicationNotify = NULL; - RtlInitUnicodeString(&ExWindowStationObjectType->TypeName, L"WindowStation"); - - ObpCreateTypeObject(ExWindowStationObjectType); - - /* Create desktop object type */ - ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); - if (ExDesktopObjectType == NULL) - { - CPRINT("Could not create desktop object type\n"); - KEBUGCHECK(0); - } - - ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K'); - ExDesktopObjectType->TotalObjects = 0; - ExDesktopObjectType->TotalHandles = 0; - ExDesktopObjectType->PeakObjects = 0; - ExDesktopObjectType->PeakHandles = 0; - ExDesktopObjectType->PagedPoolCharge = 0; - ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT); - ExDesktopObjectType->Mapping = &ExpDesktopMapping; - ExDesktopObjectType->Dump = NULL; - ExDesktopObjectType->Open = NULL; - ExDesktopObjectType->Close = NULL; - ExDesktopObjectType->Delete = ExpDesktopObjectDelete; - ExDesktopObjectType->Parse = NULL; - ExDesktopObjectType->Security = NULL; - ExDesktopObjectType->QueryName = NULL; - ExDesktopObjectType->OkayToClose = NULL; - ExDesktopObjectType->Create = ExpDesktopObjectCreate; - ExDesktopObjectType->DuplicationNotify = NULL; - RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop"); - - ObpCreateTypeObject(ExDesktopObjectType); + /* Create desktop object type */ + ExDesktopObjectType = ExAllocatePool(NonPagedPool, sizeof(OBJECT_TYPE)); + ExDesktopObjectType->Tag = TAG('D', 'E', 'S', 'K'); + ExDesktopObjectType->TotalObjects = 0; + ExDesktopObjectType->TotalHandles = 0; + ExDesktopObjectType->PeakObjects = 0; + ExDesktopObjectType->PeakHandles = 0; + ExDesktopObjectType->PagedPoolCharge = 0; + ExDesktopObjectType->NonpagedPoolCharge = sizeof(DESKTOP_OBJECT); + ExDesktopObjectType->Mapping = &ExpDesktopMapping; + ExDesktopObjectType->Dump = NULL; + ExDesktopObjectType->Open = NULL; + ExDesktopObjectType->Close = NULL; + ExDesktopObjectType->Delete = ExpDesktopDelete; + ExDesktopObjectType->Parse = NULL; + ExDesktopObjectType->Security = NULL; + ExDesktopObjectType->QueryName = NULL; + ExDesktopObjectType->OkayToClose = NULL; + ExDesktopObjectType->Create = ExpDesktopCreate; + ExDesktopObjectType->DuplicationNotify = NULL; + RtlInitUnicodeString(&ExDesktopObjectType->TypeName, L"Desktop"); + ObpCreateTypeObject(ExDesktopObjectType); } /* EOF */ _____ Modified: trunk/reactos/ntoskrnl/ps/win32.c --- trunk/reactos/ntoskrnl/ps/win32.c 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/ntoskrnl/ps/win32.c 2005-03-12 14:15:49 UTC (rev 13968) @@ -21,6 +21,13 @@ static ULONG PspWin32ProcessSize = 0; static ULONG PspWin32ThreadSize = 0; +extern OBJECT_CREATE_ROUTINE ExpWindowStationObjectCreate; +extern OBJECT_PARSE_ROUTINE ExpWindowStationObjectParse; +extern OBJECT_DELETE_ROUTINE ExpWindowStationObjectDelete; +extern OBJECT_FIND_ROUTINE ExpWindowStationObjectFind; +extern OBJECT_CREATE_ROUTINE ExpDesktopObjectCreate; +extern OBJECT_DELETE_ROUTINE ExpDesktopObjectDelete; + /* FUNCTIONS ***************************************************************/ PW32THREAD STDCALL @@ -59,7 +66,7 @@ VOID STDCALL PsEstablishWin32Callouts (PW32_PROCESS_CALLBACK W32ProcessCallback, PW32_THREAD_CALLBACK W32ThreadCallback, - PVOID Param3, + PW32_OBJECT_CALLBACK W32ObjectCallback, PVOID Param4, ULONG W32ThreadSize, ULONG W32ProcessSize) @@ -69,9 +76,15 @@ PspWin32ProcessSize = W32ProcessSize; PspWin32ThreadSize = W32ThreadSize; + + ExpWindowStationObjectCreate = W32ObjectCallback->WinStaCreate; + ExpWindowStationObjectParse = W32ObjectCallback->WinStaParse; + ExpWindowStationObjectDelete = W32ObjectCallback->WinStaDelete; + ExpWindowStationObjectFind = W32ObjectCallback->WinStaFind; + ExpDesktopObjectCreate = W32ObjectCallback->DesktopCreate; + ExpDesktopObjectDelete = W32ObjectCallback->DesktopDelete; } - NTSTATUS PsInitWin32Thread (PETHREAD Thread) { _____ Modified: trunk/reactos/subsys/win32k/include/desktop.h --- trunk/reactos/subsys/win32k/include/desktop.h 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/subsys/win32k/include/desktop.h 2005-03-12 14:15:49 UTC (rev 13968) @@ -20,6 +20,16 @@ NTSTATUS FASTCALL CleanupDesktopImpl(VOID); +NTSTATUS +STDCALL +IntDesktopObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + +VOID STDCALL +IntDesktopObjectDelete(PVOID DeletedObject); + VOID FASTCALL IntGetDesktopWorkArea(PDESKTOP_OBJECT Desktop, PRECT Rect); _____ Modified: trunk/reactos/subsys/win32k/include/winsta.h --- trunk/reactos/subsys/win32k/include/winsta.h 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/subsys/win32k/include/winsta.h 2005-03-12 14:15:49 UTC (rev 13968) @@ -23,6 +23,29 @@ NTSTATUS FASTCALL CleanupWindowStationImpl(VOID); +NTSTATUS +STDCALL +IntWinStaObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + +VOID STDCALL +IntWinStaObjectDelete(PVOID DeletedObject); + +PVOID STDCALL +IntWinStaObjectFind(PVOID Object, + PWSTR Name, + ULONG Attributes); + +NTSTATUS +STDCALL +IntWinStaObjectParse(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes); + NTSTATUS FASTCALL IntValidateWindowStationHandle( HWINSTA WindowStation, _____ Modified: trunk/reactos/subsys/win32k/main/dllmain.c --- trunk/reactos/subsys/win32k/main/dllmain.c 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/subsys/win32k/main/dllmain.c 2005-03-12 14:15:49 UTC (rev 13968) @@ -35,11 +35,45 @@ struct _ETHREAD *Thread, BOOLEAN Create); +/* + * Callbacks used for Win32 objects... this define won't be needed after the Object Manager + * rewrite -- Alex + */ +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_CREATE_ROUTINE)(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes); + +typedef NTSTATUS STDCALL_FUNC +(*OBJECT_PARSE_ROUTINE)(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes); + +typedef VOID STDCALL_FUNC +(*OBJECT_DELETE_ROUTINE)(PVOID DeletedObject); + +typedef PVOID STDCALL_FUNC +(*OBJECT_FIND_ROUTINE)(PVOID WinStaObject, + PWSTR Name, + ULONG Attributes); + +typedef struct _W32_OBJECT_CALLBACK { + OBJECT_CREATE_ROUTINE WinStaCreate; + OBJECT_PARSE_ROUTINE WinStaParse; + OBJECT_DELETE_ROUTINE WinStaDelete; + OBJECT_FIND_ROUTINE WinStaFind; + OBJECT_CREATE_ROUTINE DesktopCreate; + OBJECT_DELETE_ROUTINE DesktopDelete; +} W32_OBJECT_CALLBACK, *PW32_OBJECT_CALLBACK; + VOID STDCALL PsEstablishWin32Callouts( PW32_PROCESS_CALLBACK W32ProcessCallback, PW32_THREAD_CALLBACK W32ThreadCallback, - PVOID Param3, + PW32_OBJECT_CALLBACK W32ObjectCallback, PVOID Param4, ULONG W32ThreadSize, ULONG W32ProcessSize); @@ -219,6 +253,7 @@ { NTSTATUS Status; BOOLEAN Result; + W32_OBJECT_CALLBACK Win32kObjectCallbacks; /* * Register user mode call interface @@ -234,14 +269,23 @@ DPRINT1("Adding system services failed!\n"); return STATUS_UNSUCCESSFUL; } - + + /* + * Register Object Manager Callbacks + */ + Win32kObjectCallbacks.WinStaCreate = IntWinStaObjectCreate; + Win32kObjectCallbacks.WinStaParse = IntWinStaObjectParse; + Win32kObjectCallbacks.WinStaDelete = IntWinStaObjectDelete; + Win32kObjectCallbacks.WinStaFind = IntWinStaObjectFind; + Win32kObjectCallbacks.DesktopCreate = IntDesktopObjectCreate; + Win32kObjectCallbacks.DesktopDelete = IntDesktopObjectDelete; /* * Register our per-process and per-thread structures. */ PsEstablishWin32Callouts (Win32kProcessCallback, Win32kThreadCallback, + &Win32kObjectCallbacks, 0, - 0, sizeof(W32THREAD), sizeof(W32PROCESS)); _____ Modified: trunk/reactos/subsys/win32k/ntuser/desktop.c --- trunk/reactos/subsys/win32k/ntuser/desktop.c 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/subsys/win32k/ntuser/desktop.c 2005-03-12 14:15:49 UTC (rev 13968) @@ -66,6 +66,60 @@ return STATUS_SUCCESS; } +/* OBJECT CALLBACKS **********************************************************/ + +NTSTATUS STDCALL +IntDesktopObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) +{ + PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)ObjectBody; + UNICODE_STRING UnicodeString; + + if (RemainingPath == NULL) + { + return STATUS_SUCCESS; + } + + if (wcschr((RemainingPath + 1), '\\') != NULL) + { + return STATUS_UNSUCCESSFUL; + } + + RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); + + DPRINT("Creating desktop (0x%X) Name (%wZ)\n", Desktop, &UnicodeString); + + KeInitializeSpinLock(&Desktop->Lock); + + Desktop->WindowStation = (PWINSTATION_OBJECT)Parent; + + /* Put the desktop on the window station's list of associcated desktops */ + ExInterlockedInsertTailList( + &Desktop->WindowStation->DesktopListHead, + &Desktop->ListEntry, + &Desktop->WindowStation->Lock); + + return RtlCreateUnicodeString(&Desktop->Name, UnicodeString.Buffer); +} + +VOID STDCALL +IntDesktopObjectDelete(PVOID DeletedObject) +{ + PDESKTOP_OBJECT Desktop = (PDESKTOP_OBJECT)DeletedObject; + KIRQL OldIrql; + + DPRINT("Deleting desktop (0x%X)\n", Desktop); + + /* Remove the desktop from the window station's list of associcated desktops */ + KeAcquireSpinLock(&Desktop->WindowStation->Lock, &OldIrql); + RemoveEntryList(&Desktop->ListEntry); + KeReleaseSpinLock(&Desktop->WindowStation->Lock, OldIrql); + + RtlFreeUnicodeString(&Desktop->Name); +} + /* PRIVATE FUNCTIONS **********************************************************/ NTSTATUS FASTCALL _____ Modified: trunk/reactos/subsys/win32k/ntuser/message.c --- trunk/reactos/subsys/win32k/ntuser/message.c 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/subsys/win32k/ntuser/message.c 2005-03-12 14:15:49 UTC (rev 13968) @@ -30,6 +30,7 @@ /* INCLUDES ******************************************************************/ #include <w32k.h> +#include <pseh.h> #define NDEBUG #include <debug.h> @@ -113,6 +114,7 @@ PUNICODE_STRING ClassName; UINT Size; + _SEH_TRY { if (MMS_SIZE_WPARAM == MsgMemoryEntry->Size) { return (UINT) wParam; @@ -163,6 +165,11 @@ { return MsgMemoryEntry->Size; } + } _SEH_HANDLE { + + DPRINT1("BOO!\n"); + return 0; + } _SEH_END; } static FASTCALL NTSTATUS _____ Modified: trunk/reactos/subsys/win32k/ntuser/winsta.c --- trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/subsys/win32k/ntuser/winsta.c 2005-03-12 14:15:49 UTC (rev 13968) @@ -80,6 +80,165 @@ return STATUS_SUCCESS; } +/* OBJECT CALLBACKS **********************************************************/ + +NTSTATUS +STDCALL +IntWinStaObjectCreate(PVOID ObjectBody, + PVOID Parent, + PWSTR RemainingPath, + struct _OBJECT_ATTRIBUTES* ObjectAttributes) +{ + PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)ObjectBody; + UNICODE_STRING UnicodeString; + NTSTATUS Status; + + if (RemainingPath == NULL) + { + return STATUS_SUCCESS; + } + + if (wcschr((RemainingPath + 1), '\\') != NULL) + { + return STATUS_UNSUCCESSFUL; + } + + RtlInitUnicodeString(&UnicodeString, (RemainingPath + 1)); + + DPRINT("Creating window station (0x%X) Name (%wZ)\n", WinSta, &UnicodeString); + + Status = RtlCreateUnicodeString(&WinSta->Name, UnicodeString.Buffer); + if (!NT_SUCCESS(Status)) + { + return Status; + } + + KeInitializeSpinLock(&WinSta->Lock); + + InitializeListHead(&WinSta->DesktopListHead); + +#if 1 + WinSta->AtomTable = NULL; +#endif + + Status = RtlCreateAtomTable(37, &WinSta->AtomTable); + if (!NT_SUCCESS(Status)) + { + RtlFreeUnicodeString(&WinSta->Name); + return Status; + } + + WinSta->SystemMenuTemplate = (HANDLE)0; + + DPRINT("Window station successfully created. Name (%wZ)\n", &WinSta->Name); + + return STATUS_SUCCESS; +} + +VOID STDCALL +IntWinStaObjectDelete(PVOID DeletedObject) +{ + PWINSTATION_OBJECT WinSta = (PWINSTATION_OBJECT)DeletedObject; + + DPRINT("Deleting window station (0x%X)\n", WinSta); + + RtlDestroyAtomTable(WinSta->AtomTable); + + RtlFreeUnicodeString(&WinSta->Name); +} + +PVOID STDCALL +IntWinStaObjectFind(PVOID Object, + PWSTR Name, + ULONG Attributes) +{ + PLIST_ENTRY Current; + PDESKTOP_OBJECT CurrentObject; + PWINSTATION_OBJECT WinStaObject = (PWINSTATION_OBJECT)Object; + + DPRINT("WinStaObject (0x%X) Name (%wS)\n", WinStaObject, Name); + + if (Name[0] == 0) + { + return NULL; + } + + Current = WinStaObject->DesktopListHead.Flink; + while (Current != &WinStaObject->DesktopListHead) + { + CurrentObject = CONTAINING_RECORD(Current, DESKTOP_OBJECT, ListEntry); + DPRINT("Scanning %wZ for %wS\n", &CurrentObject->Name, Name); + if (Attributes & OBJ_CASE_INSENSITIVE) + { + if (_wcsicmp(CurrentObject->Name.Buffer, Name) == 0) + { + DPRINT("Found desktop at (0x%X)\n", CurrentObject); + return CurrentObject; + } + } + else + { + if (wcscmp(CurrentObject->Name.Buffer, Name) == 0) + { + DPRINT("Found desktop at (0x%X)\n", CurrentObject); + return CurrentObject; + } + } + Current = Current->Flink; + } + + DPRINT("Returning NULL\n"); + + return NULL; +} + +NTSTATUS +STDCALL +IntWinStaObjectParse(PVOID Object, + PVOID *NextObject, + PUNICODE_STRING FullPath, + PWSTR *Path, + ULONG Attributes) +{ + PVOID FoundObject; + NTSTATUS Status; + PWSTR End; + + DPRINT("Object (0x%X) Path (0x%X) *Path (%wS)\n", Object, Path, *Path); + + *NextObject = NULL; + + if ((Path == NULL) || ((*Path) == NULL)) + { + return STATUS_SUCCESS; + } + + End = wcschr((*Path) + 1, '\\'); + if (End != NULL) + { + DPRINT("Name contains illegal characters\n"); + return STATUS_UNSUCCESSFUL; + } + + FoundObject = IntWinStaObjectFind(Object, (*Path) + 1, Attributes); + if (FoundObject == NULL) + { + DPRINT("Name was not found\n"); + return STATUS_UNSUCCESSFUL; + } + + Status = ObReferenceObjectByPointer( + FoundObject, + STANDARD_RIGHTS_REQUIRED, + NULL, + UserMode); + + *NextObject = FoundObject; + *Path = NULL; + + return Status; +} + /* PRIVATE FUNCTIONS **********************************************************/ /* _____ Modified: trunk/reactos/w32api/include/ddk/ntifs.h --- trunk/reactos/w32api/include/ddk/ntifs.h 2005-03-12 13:50:48 UTC (rev 13967) +++ trunk/reactos/w32api/include/ddk/ntifs.h 2005-03-12 14:15:49 UTC (rev 13968) @@ -315,6 +315,7 @@ #define TOKEN_ADJUST_PRIVILEGES (0x0020) [truncated at 1000 lines; 102 more skipped]
20 years, 2 months
1
0
0
0
[weiden] 13967: include ctype.h for isalpha()
by weiden@svn.reactos.com
include ctype.h for isalpha() Modified: trunk/reactos/ntoskrnl/dbg/kdb_cli.c Modified: trunk/reactos/ntoskrnl/dbg/kdb_string.c _____ Modified: trunk/reactos/ntoskrnl/dbg/kdb_cli.c --- trunk/reactos/ntoskrnl/dbg/kdb_cli.c 2005-03-12 13:23:09 UTC (rev 13966) +++ trunk/reactos/ntoskrnl/dbg/kdb_cli.c 2005-03-12 13:50:48 UTC (rev 13967) @@ -29,7 +29,9 @@ /* INCLUDES ******************************************************************/ #include <ntoskrnl.h> +#include <ctype.h> #include "kdb.h" + #define NDEBUG #include <internal/debug.h> _____ Modified: trunk/reactos/ntoskrnl/dbg/kdb_string.c --- trunk/reactos/ntoskrnl/dbg/kdb_string.c 2005-03-12 13:23:09 UTC (rev 13966) +++ trunk/reactos/ntoskrnl/dbg/kdb_string.c 2005-03-12 13:50:48 UTC (rev 13967) @@ -28,6 +28,7 @@ /* INCLUDES ******************************************************************/ #include <ntoskrnl.h> +#include <ctype.h> /* FUNCTIONS *****************************************************************/
20 years, 2 months
1
0
0
0
[ekohl] 13966: Implement [in], [out] and [in, out] support for pointers to basic types.
by ekohl@svn.reactos.com
Implement [in], [out] and [in, out] support for pointers to basic types. Modified: trunk/reactos/tools/widl/ChangeLog Modified: trunk/reactos/tools/widl/client.c Modified: trunk/reactos/tools/widl/server.c _____ Modified: trunk/reactos/tools/widl/ChangeLog --- trunk/reactos/tools/widl/ChangeLog 2005-03-12 09:40:07 UTC (rev 13965) +++ trunk/reactos/tools/widl/ChangeLog 2005-03-12 13:23:09 UTC (rev 13966) @@ -1,5 +1,13 @@ ChangeLog +2005-03-12 ekohl + + tools/widl/client.c + tools/widl/server.c + +Implement [in], [out] and [in, out] support for pointers to basic types. + + 2005-03-10 ekohl tools/widl/client.c _____ Modified: trunk/reactos/tools/widl/client.c --- trunk/reactos/tools/widl/client.c 2005-03-12 09:40:07 UTC (rev 13965) +++ trunk/reactos/tools/widl/client.c 2005-03-12 13:23:09 UTC (rev 13966) @@ -61,6 +61,7 @@ func_t *func = iface->funcs; var_t *var; unsigned int type_offset = 2; + int in_attr, out_attr; print_client("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); print_client("{\n"); @@ -79,6 +80,13 @@ while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { + out_attr = is_attr(var->attrs, ATTR_OUT); + in_attr = is_attr(var->attrs, ATTR_IN); + + /* set 'in' attribute if neither 'in' nor 'out' is set */ + if (!out_attr && !in_attr) + in_attr = 1; + if (var->ptr_level == 0) { if (is_base_type(var->type)) @@ -96,7 +104,12 @@ { if (is_base_type(var->type)) { - print_client("0x4d, /* FC_IN_PARAM */\n"); + if (in_attr & !out_attr) + print_client("0x4d, /* FC_IN_PARAM */\n"); + else if (!in_attr & out_attr) + print_client("0x51, /* FC_OUT_PARAM */\n"); + else if (in_attr & out_attr) + print_client("0x50, /* FC_IN_OUT_PARAM */\n"); fprintf(client, "#ifndef _ALPHA_\n"); print_client("0x01,\n"); fprintf(client, "#else\n"); @@ -150,6 +163,7 @@ { func_t *func = iface->funcs; var_t *var; + int out_attr; print_client("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); print_client("{\n"); @@ -168,6 +182,8 @@ while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { + out_attr = is_attr(var->attrs, ATTR_OUT); + if (var->ptr_level > 1) { error("Function '%s' argument '%s': Pointer level %d not supported!\n", @@ -179,7 +195,10 @@ { if (is_base_type(var->type)) { - print_client("0x11, 0x08, /* FC_RP [simple_pointer] */\n"); + if (out_attr) + print_client("0x11, 0x0c, /* FC_RP [allocated_on_stack] [simple_pointer] */\n"); + else + print_client("0x11, 0x08, /* FC_RP [simple_pointer] */\n"); print_client("0x%02x, /* FC_<type> */\n", var->type->type); print_client("0x5c, /* FC_PAD */\n"); } @@ -210,75 +229,80 @@ int last_size = -1; int in_attr; int out_attr; + int nothing_printed = 1; var_t *var; - if (!func->args) + if (func->args) { - fprintf(client, " 0U"); - return; - } + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + for (; var; var = PREV_LINK(var)) + { + out_attr = is_attr(var->attrs, ATTR_OUT); + in_attr = is_attr(var->attrs, ATTR_IN); - var = func->args; - while (NEXT_LINK(var)) var = NEXT_LINK(var); - for (; var; var = PREV_LINK(var)) - { - out_attr = is_attr(var->attrs, ATTR_OUT); - in_attr = is_attr(var->attrs, ATTR_IN); + /* set 'in' attribute if neither 'in' nor 'out' is found */ + if (!out_attr && !in_attr) + in_attr = 1; - /* set 'in' attribute if neither 'in' nor 'out' is found */ - if (!out_attr && !in_attr) - in_attr = 1; + if (!in_attr) + continue; - if (!in_attr) - continue; - - alignment = 0; - switch (var->type->type) - { - case RPC_FC_BYTE: - case RPC_FC_CHAR: - case RPC_FC_SMALL: - size = 1; alignment = 0; - break; + switch (var->type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + size = 1; + alignment = 0; + break; - case RPC_FC_WCHAR: - case RPC_FC_USHORT: - case RPC_FC_SHORT: - size = 2; - if (last_size > 0 && last_size < 2) - alignment += (2 - last_size); - break; + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + size = 2; + if (last_size > 0 && last_size < 2) + alignment += (2 - last_size); + break; - case RPC_FC_ULONG: - case RPC_FC_LONG: - case RPC_FC_FLOAT: - size = 4; - if (last_size > 0 && last_size < 4) - alignment += (4 - last_size); - break; + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + size = 4; + if (last_size > 0 && last_size < 4) + alignment += (4 - last_size); + break; - case RPC_FC_HYPER: - case RPC_FC_DOUBLE: - size = 8; - if (last_size > 0 && last_size < 4) - alignment += (4 - last_size); - break; + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + if (last_size > 0 && last_size < 4) + alignment += (4 - last_size); + break; - case RPC_FC_IGNORE: - size = 0; - break; + case RPC_FC_IGNORE: + size = 0; + break; - default: - error("Unknown/unsupported type!"); - } + default: + error("Unknown/unsupported type!"); + return; + } - if (last_size != -1) - fprintf(client, " +"); - fprintf(client, " %dU", (size == 0) ? 0 : size + alignment); + if (last_size != -1) + fprintf(client, " +"); + fprintf(client, " %dU", (size == 0) ? 0 : size + alignment); + nothing_printed = 0; - last_size = size; + last_size = size; + } } + + if (nothing_printed) + { + fprintf(client, " 0U"); + } } @@ -376,6 +400,137 @@ } +static void unmarshall_out_arguments(func_t *func) +{ + unsigned int alignment; + unsigned int size; + unsigned int last_size = 0; + int out_attr; + var_t *var; + var_t *def; + + def = func->def; + + /* unmarshall the out arguments */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + for (; var; var = PREV_LINK(var)) + { + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr) + continue; + + if (var->ptr_level > 1) + { + error("Function '%s' argument '%s': Pointer level %d not supported!\n", + func->def->name, var->name, var->ptr_level); + return; + } + + alignment = 0; + switch (var->type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + size = 1; + alignment = 0; + break; + + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + size = 2; + if (last_size > 0 && last_size < 2) + alignment = (2 - last_size); + break; + + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + size = 4; + if (last_size > 0 && last_size < 4) + alignment = (4 - last_size); + break; + + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + if (last_size > 0 && last_size < 4) + alignment = (4 - last_size); + break; + + case RPC_FC_IGNORE: + size = 0; + break; + + default: + error("Unknown/unsupported type!"); + } + + if (size != 0) + { + if (var->ptr_level == 1) + { + fprintf(client, "\n"); + if (alignment != 0) + print_client("_StubMsg.Buffer += %u;\n", alignment); + + print_client("*"); + write_name(client, var); + fprintf(client, " = *(("); + write_type(client, var->type, NULL, var->tname); + fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n"); + } + + last_size = size; + } + } + } + + /* unmarshall return value */ + if (!is_void(def->type, NULL)) + { + alignment = 0; + switch (def->type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + size = 4; + if (last_size > 0 && last_size < 4) + alignment = (4 - last_size); + break; + + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + if (last_size > 0 && last_size < 4) + alignment = (4 - last_size); + break; + + default: + error("Unknown/unsupported type!"); + } + + fprintf(client, "\n"); + if (alignment != 0) + print_client("_StubMsg.Buffer += %u;\n", alignment); + print_client("_RetVal = *(("); + write_type(client, def->type, def, def->tname); + fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n"); + } +} + + static void check_pointers(func_t *func) { var_t *var; @@ -408,6 +563,30 @@ } +static int use_return_buffer(func_t *func) +{ + var_t *var; + + if (!is_void(func->def->type, NULL)) + return 1; + + if (!func->args) + return 0; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (is_attr(var->attrs, ATTR_OUT)) + return 1; + + var = PREV_LINK(var); + } + + return 0; +} + + static void write_function_stubs(type_t *iface) { char *implicit_handle = get_attrp(iface->attrs, ATTR_IMPLICIT_HANDLE); @@ -523,11 +702,10 @@ print_client("(unsigned char __RPC_FAR *)_StubMsg.Buffer);\n"); indent--; - /* convert data representation */ - if (!is_void(def->type, NULL)) + if (use_return_buffer(func)) { + /* convert data representation */ fprintf(client, "\n"); - print_client("if ((_RpcMessage.DataRepresentation & 0x0000FFFFUL) != NDR_LOCAL_DATA_REPRESENTATION)\n"); indent++; print_client("NdrConvert(\n"); @@ -535,11 +713,9 @@ print_client("(PMIDL_STUB_MESSAGE)&_StubMsg,\n"); print_client("(PFORMAT_STRING)&__MIDL_ProcFormatString.Format[%u]);\n", proc_offset); indent -= 2; - fprintf(client, "\n"); - print_client("_RetVal = *(("); - write_type(client, def->type, def, def->tname); - fprintf(client, " __RPC_FAR *)_StubMsg.Buffer)++;\n"); + /* unmarshal out arguments */ + unmarshall_out_arguments(func); } /* update proc_offset */ _____ Modified: trunk/reactos/tools/widl/server.c --- trunk/reactos/tools/widl/server.c 2005-03-12 09:40:07 UTC (rev 13965) +++ trunk/reactos/tools/widl/server.c 2005-03-12 13:23:09 UTC (rev 13966) @@ -66,6 +66,7 @@ func_t *func = iface->funcs; var_t *var; unsigned int type_offset = 2; + int in_attr, out_attr; print_server("static const MIDL_PROC_FORMAT_STRING __MIDL_ProcFormatString =\n"); print_server("{\n"); @@ -84,6 +85,13 @@ while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { + out_attr = is_attr(var->attrs, ATTR_OUT); + in_attr = is_attr(var->attrs, ATTR_IN); + + /* set 'in' attribute if neither 'in' nor 'out' is set */ + if (!out_attr && !in_attr) + in_attr = 1; + if (var->ptr_level == 0) { if (is_base_type(var->type)) @@ -101,7 +109,12 @@ { if (is_base_type(var->type)) { - print_server("0x4d, /* FC_IN_PARAM */\n"); + if (in_attr & !out_attr) + print_server("0x4d, /* FC_IN_PARAM */\n"); + else if (!in_attr & out_attr) + print_server("0x51, /* FC_OUT_PARAM */\n"); + else if (in_attr & out_attr) + print_server("0x50, /* FC_IN_OUT_PARAM */\n"); fprintf(server, "#ifndef _ALPHA_\n"); print_server("0x01,\n"); fprintf(server, "#else\n"); @@ -155,6 +168,7 @@ { func_t *func = iface->funcs; var_t *var; + int out_attr; print_server("static const MIDL_TYPE_FORMAT_STRING __MIDL_TypeFormatString =\n"); print_server("{\n"); @@ -173,6 +187,8 @@ while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { + out_attr = is_attr(var->attrs, ATTR_OUT); + if (var->ptr_level > 1) { error("Function '%s' argument '%s': Pointer level %d not supported!\n", @@ -184,7 +200,10 @@ { if (is_base_type(var->type)) { - print_server("0x11, 0x08, /* FC_RP [simple_pointer] */\n"); + if (out_attr) + print_server("0x11, 0x0c, /* FC_RP [allocated_on_stack] [simple_pointer] */\n"); + else + print_server("0x11, 0x08, /* FC_RP [simple_pointer] */\n"); print_server("0x%02x, /* FC_<type> */\n", var->type->type); print_server("0x5c, /* FC_PAD */\n"); } @@ -208,10 +227,75 @@ } -unsigned int get_required_buffer_size(type_t *type) +static void print_message_buffer_size(func_t *func) { - switch(type->type) + unsigned int alignment; + int size; + int last_size = -1; + int in_attr; + int out_attr; + var_t *var; + + if (func->args) { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + for (; var; var = PREV_LINK(var)) + { + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr) + continue; + + alignment = 0; + switch (var->type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + size = 1; + alignment = 0; + break; + + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + size = 2; + if (last_size > 0 && last_size < 2) + alignment += (2 - last_size); + break; + + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + size = 4; + if (last_size > 0 && last_size < 4) + alignment += (4 - last_size); + break; + + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + if (last_size > 0 && last_size < 4) + alignment += (4 - last_size); + break; + + default: + error("Unknown/unsupported type!"); + } + + if (last_size != -1) + fprintf(server, " +"); + fprintf(server, " %dU", (size == 0) ? 0 : size + alignment); + + last_size = size; + } + } + + /* return value size */ + if (!is_void(func->def->type, NULL)) + { + switch(func->def->type->type) + { case RPC_FC_BYTE: case RPC_FC_SMALL: case RPC_FC_CHAR: @@ -221,18 +305,27 @@ case RPC_FC_ULONG: case RPC_FC_LONG: case RPC_FC_FLOAT: - return 4; + size = 4; + if (last_size > 0 && last_size < 4) + alignment += (4 - last_size); + break; case RPC_FC_HYPER: case RPC_FC_DOUBLE: - return 8; + size = 8; + if (last_size > 0 && last_size < 4) + alignment += (4 - last_size); + break; - case RPC_FC_IGNORE: - return 0; + default: + error("Unknown/unsupported type: %s\n", func->def->type->name); + return; + } - default: - error("Unknown/unsupported type: %s\n", type->name); - return 0; + if (last_size != -1) + fprintf(server, " +"); + + fprintf(server, " %dU", (size == 0) ? 0 : size + alignment); } } @@ -266,20 +359,32 @@ } -static void unmarshall_arguments(func_t *func) +static void unmarshall_in_arguments(func_t *func) { unsigned int alignment; unsigned int size; unsigned int last_size = 0; var_t *var; + int in_attr; + int out_attr; if (!func->args) return; var = func->args; while (NEXT_LINK(var)) var = NEXT_LINK(var); - while (var) + for (; var; var = PREV_LINK(var)) { + out_attr = is_attr(var->attrs, ATTR_OUT); + in_attr = is_attr(var->attrs, ATTR_IN); + + /* set 'in' attribute if neither 'in' nor 'out' is set */ + if (!out_attr && !in_attr) + in_attr = 1; + + if (!in_attr) + continue; + alignment = 0; switch (var->type->type) { @@ -355,9 +460,160 @@ last_size = size; } + } +} + +static void marshall_out_arguments(func_t *func) +{ + unsigned int alignment = 0; + unsigned int size = 0; + unsigned int last_size = 0; + var_t *var; + var_t *def; + int out_attr; + + def = func->def; + + /* marshall the out arguments */ + if (func->args) + { + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + for (; var; var = PREV_LINK(var)) + { + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr) + continue; + + alignment = 0; + switch (var->type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + size = 1; + alignment = 0; + break; + + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + size = 2; + if (last_size != 0 && last_size < 2) + alignment = (2 - last_size); + break; + + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + size = 4; + if (last_size != 0 && last_size < 4) + alignment = (4 - last_size); + break; + + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + if (last_size != 0 && last_size < 4) + alignment = (4 - last_size); + break; + + case RPC_FC_IGNORE: + size = 0; + break; + + default: + error("Unknown/unsupported type!"); + } + + if (size != 0) + { + if (alignment != 0) + print_server("_StubMsg.Buffer += %u;\n", alignment); + + if (var->ptr_level == 1) + { + fprintf(server, "\n"); + print_server("*(("); + write_type(server, var->type, NULL, var->tname); + fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = *"); + write_name(server, var); + fprintf(server, ";\n"); + } + else + { + error("Pointer level %d is not supported!\n", var->ptr_level); + return; + } + + last_size = size; + } + } + } + + /* marshall the return value */ + if (!is_void(def->type, NULL)) + { + alignment = 0; + switch (def->type->type) + { + case RPC_FC_BYTE: + case RPC_FC_CHAR: + case RPC_FC_SMALL: + case RPC_FC_WCHAR: + case RPC_FC_USHORT: + case RPC_FC_SHORT: + case RPC_FC_ULONG: + case RPC_FC_LONG: + case RPC_FC_FLOAT: + size = 4; + if (last_size != 0 && last_size < 4) + alignment = (4 - last_size); + break; + + case RPC_FC_HYPER: + case RPC_FC_DOUBLE: + size = 8; + if (last_size != 0 && last_size < 4) + alignment = (4 - last_size); + break; + + default: + error("Unknown/unsupported type!"); + } + + fprintf(server, "\n"); + if (alignment != 0) + print_server("_StubMsg.Buffer += %u;\n", alignment); + print_server("*(("); + write_type(server, def->type, def, def->tname); + fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = _RetVal;\n"); + } +} + + +static int use_return_buffer(func_t *func) +{ + var_t *var; + + if (!is_void(func->def->type, NULL)) + return 1; + + if (!func->args) + return 0; + + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + if (is_attr(var->attrs, ATTR_OUT)) + return 1; + var = PREV_LINK(var); } + + return 0; } @@ -368,6 +624,9 @@ var_t *var; var_t* explicit_handle_var; unsigned int proc_offset = 0; + unsigned int i; + int in_attr; + int out_attr; while (NEXT_LINK(func)) func = NEXT_LINK(func); while (func) @@ -416,10 +675,23 @@ /* declare arguments */ if (func->args) { + i = 0; var = func->args; while (NEXT_LINK(var)) var = NEXT_LINK(var); while (var) { + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr && !in_attr) + in_attr = 1; + if (!in_attr) + { + print_server(""); + write_type(server, var->type, NULL, var->tname); + fprintf(server, " _W%u;\n", i); + i++; + } + print_server(""); write_type(server, var->type, var, var->tname); fprintf(server, " "); @@ -470,7 +742,7 @@ indent -= 2; fprintf(server, "\n"); - unmarshall_arguments(func); + unmarshall_in_arguments(func); } print_server("if (_StubMsg.Buffer > _StubMsg.BufferEnd)\n"); @@ -490,7 +762,33 @@ print_server("RpcEndExcept\n"); fprintf(server, "\n"); + /* assign out arguments */ + if (func->args) + { + i = 0; + var = func->args; + while (NEXT_LINK(var)) var = NEXT_LINK(var); + while (var) + { + in_attr = is_attr(var->attrs, ATTR_IN); + out_attr = is_attr(var->attrs, ATTR_OUT); + if (!out_attr && !in_attr) + in_attr = 1; + if (!in_attr) + { + print_server(""); + write_name(server, var); + fprintf(server, " = &_W%u;\n", i); + i++; + } + var = PREV_LINK(var); + } + + if (i) + fprintf(server, "\n"); + } + /* Call the real server function */ if (!is_void(def->type, NULL)) print_server("_RetVal = "); @@ -524,11 +822,13 @@ fprintf(server, "();\n"); } - /* marshall the return value */ - if (!is_void(def->type, NULL)) + /* allocate and fill the return message buffer */ + if (use_return_buffer(func)) { fprintf(server, "\n"); - print_server("_StubMsg.BufferLength = %uU;\n", get_required_buffer_size(def->type)); + print_server("_StubMsg.BufferLength ="); + print_message_buffer_size(func); + fprintf(server, ";\n"); print_server("_pRpcMessage->BufferLength = _StubMsg.BufferLength;\n"); fprintf(server, "\n"); print_server("_Status = I_RpcGetBuffer(_pRpcMessage);\n"); @@ -538,11 +838,9 @@ indent--; fprintf(server, "\n"); print_server("_StubMsg.Buffer = (unsigned char __RPC_FAR *)_pRpcMessage->Buffer;\n"); - fprintf(server, "\n"); - print_server("*(("); - write_type(server, def->type, def, def->tname); - fprintf(server, " __RPC_FAR *)_StubMsg.Buffer)++ = _RetVal;\n"); + /* marshall the out arguments */ + marshall_out_arguments(func); } indent--;
20 years, 2 months
1
0
0
0
← Newer
1
...
40
41
42
43
44
45
46
...
61
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Results per page:
10
25
50
100
200