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
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
November 2014
----- 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
18 participants
373 discussions
Start a n
N
ew thread
[tfaber] 65265: [IPHLPAPI] - Fix MSVC build
by tfaber@svn.reactos.org
Author: tfaber Date: Wed Nov 5 16:31:13 2014 New Revision: 65265 URL:
http://svn.reactos.org/svn/reactos?rev=65265&view=rev
Log: [IPHLPAPI] - Fix MSVC build Modified: trunk/reactos/dll/win32/iphlpapi/address.c Modified: trunk/reactos/dll/win32/iphlpapi/address.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/iphlpapi/address…
============================================================================== --- trunk/reactos/dll/win32/iphlpapi/address.c [iso-8859-1] (original) +++ trunk/reactos/dll/win32/iphlpapi/address.c [iso-8859-1] Wed Nov 5 16:31:13 2014 @@ -330,7 +330,8 @@ if (InterfacesList[i].tei_entity == IF_ENTITY) { - BYTE EntryBuffer[FIELD_OFFSET(IFEntry, if_descr[MAX_ADAPTER_DESCRIPTION_LENGTH + 1])]; + BYTE EntryBuffer[FIELD_OFFSET(IFEntry, if_descr) + + RTL_FIELD_SIZE(IFEntry, if_descr[0]) * (MAX_ADAPTER_DESCRIPTION_LENGTH + 1)]; IFEntry* Entry = (IFEntry*)EntryBuffer; /* Remember we got one */
10 years, 1 month
1
0
0
0
[hbelusca] 65264: [FAST486] - Fix another typo (addendum to r65263). - Whitespace fixes.
by hbelusca@svn.reactos.org
Author: hbelusca Date: Wed Nov 5 12:45:47 2014 New Revision: 65264 URL:
http://svn.reactos.org/svn/reactos?rev=65264&view=rev
Log: [FAST486] - Fix another typo (addendum to r65263). - Whitespace fixes. Modified: trunk/reactos/lib/fast486/common.c trunk/reactos/lib/fast486/extraops.c trunk/reactos/lib/fast486/opgroups.c Modified: trunk/reactos/lib/fast486/common.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=6…
============================================================================== --- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Wed Nov 5 12:45:47 2014 @@ -700,9 +700,9 @@ } if (!Fast486ReadDescriptorEntry(State, - NewTss.Ldtr, - &Valid, - (PFAST486_GDT_ENTRY)&GdtEntry)) + NewTss.Ldtr, + &Valid, + (PFAST486_GDT_ENTRY)&GdtEntry)) { /* Exception occurred */ return FALSE; Modified: trunk/reactos/lib/fast486/extraops.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/extraops.c?rev…
============================================================================== --- trunk/reactos/lib/fast486/extraops.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/extraops.c [iso-8859-1] Wed Nov 5 12:45:47 2014 @@ -1689,7 +1689,7 @@ for (i = 0; i < DataSize; i++) { - if(Value & (1 << i)) + if (Value & (1 << i)) { /* Save the bit number */ BitNumber = i; @@ -1758,7 +1758,7 @@ for (i = DataSize - 1; i >= 0; i--) { - if(Value & (1 << i)) + if (Value & (1 << i)) { /* Save the bit number */ BitNumber = i; Modified: trunk/reactos/lib/fast486/opgroups.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opgroups.c?rev…
============================================================================== --- trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] Wed Nov 5 12:45:47 2014 @@ -1765,10 +1765,10 @@ return; } - if (Fast486ReadDescriptorEntry(State, - Selector, - &Valid, - (PFAST486_GDT_ENTRY)&GdtEntry)) + if (!Fast486ReadDescriptorEntry(State, + Selector, + &Valid, + (PFAST486_GDT_ENTRY)&GdtEntry)) { /* Exception occurred */ return; @@ -1848,9 +1848,9 @@ } if (!Fast486ReadDescriptorEntry(State, - Selector, - &Valid, - (PFAST486_GDT_ENTRY)&GdtEntry)) + Selector, + &Valid, + (PFAST486_GDT_ENTRY)&GdtEntry)) { /* Exception occurred */ return;
10 years, 1 month
1
0
0
0
[aandrejevic] 65263: [FAST486] Fix two typos.
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Wed Nov 5 04:58:40 2014 New Revision: 65263 URL:
http://svn.reactos.org/svn/reactos?rev=65263&view=rev
Log: [FAST486] Fix two typos. Modified: trunk/reactos/lib/fast486/common.c trunk/reactos/lib/fast486/opgroups.c Modified: trunk/reactos/lib/fast486/common.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=6…
============================================================================== --- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Wed Nov 5 04:58:40 2014 @@ -699,7 +699,7 @@ return FALSE; } - if (Fast486ReadDescriptorEntry(State, + if (!Fast486ReadDescriptorEntry(State, NewTss.Ldtr, &Valid, (PFAST486_GDT_ENTRY)&GdtEntry)) Modified: trunk/reactos/lib/fast486/opgroups.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opgroups.c?rev…
============================================================================== --- trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] Wed Nov 5 04:58:40 2014 @@ -1847,7 +1847,7 @@ return; } - if (Fast486ReadDescriptorEntry(State, + if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, (PFAST486_GDT_ENTRY)&GdtEntry))
10 years, 1 month
1
0
0
0
[aandrejevic] 65262: [FAST486] Allow direct calls/jumps to TSS selectors in Fast486ProcessGate.
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Wed Nov 5 00:50:11 2014 New Revision: 65262 URL:
http://svn.reactos.org/svn/reactos?rev=65262&view=rev
Log: [FAST486] Allow direct calls/jumps to TSS selectors in Fast486ProcessGate. Modified: trunk/reactos/lib/fast486/common.inl Modified: trunk/reactos/lib/fast486/common.inl URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.inl?rev…
============================================================================== --- trunk/reactos/lib/fast486/common.inl [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.inl [iso-8859-1] Wed Nov 5 00:50:11 2014 @@ -702,25 +702,37 @@ return FALSE; } - if (Descriptor.Signature == FAST486_TASK_GATE_SIGNATURE) - { - /* Task gate */ - - Fast486TaskSwitch(State, - Call ? FAST486_TASK_CALL : FAST486_TASK_JUMP, - ((PFAST486_IDT_ENTRY)&Descriptor)->Selector); - - return FALSE; - } - else if (Descriptor.Signature == FAST486_CALL_GATE_SIGNATURE) - { - /* Call gate */ - - // TODO: NOT IMPLEMENTED - UNIMPLEMENTED; - } - - return TRUE; + switch (Descriptor.Signature) + { + case FAST486_TASK_GATE_SIGNATURE: + { + Fast486TaskSwitch(State, + Call ? FAST486_TASK_CALL : FAST486_TASK_JUMP, + ((PFAST486_IDT_ENTRY)&Descriptor)->Selector); + + return FALSE; + } + + case FAST486_TSS_SIGNATURE: + { + Fast486TaskSwitch(State, + Call ? FAST486_TASK_CALL : FAST486_TASK_JUMP, + Selector); + + return FALSE; + } + + case FAST486_CALL_GATE_SIGNATURE: + { + // TODO: NOT IMPLEMENTED + UNIMPLEMENTED; + } + + default: + { + return TRUE; + } + } } FORCEINLINE
10 years, 1 month
1
0
0
0
[aandrejevic] 65261: [FAST486] Fix the paging exception code.
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Wed Nov 5 00:27:43 2014 New Revision: 65261 URL:
http://svn.reactos.org/svn/reactos?rev=65261&view=rev
Log: [FAST486] Fix the paging exception code. Modified: trunk/reactos/lib/fast486/common.inl Modified: trunk/reactos/lib/fast486/common.inl URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.inl?rev…
============================================================================== --- trunk/reactos/lib/fast486/common.inl [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.inl [iso-8859-1] Wed Nov 5 00:27:43 2014 @@ -175,7 +175,7 @@ /* Exception */ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_PF, - TableEntry.Value & 0x07); + TableEntry.Present | (State->Cpl ? 0x04 : 0)); return FALSE; } @@ -244,7 +244,7 @@ /* Exception */ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_PF, - TableEntry.Value & 0x07); + TableEntry.Present | 0x02 | (State->Cpl ? 0x04 : 0)); return FALSE; }
10 years, 1 month
1
0
0
0
[aandrejevic] 65260: [FAST486] - Move the descriptor reading logic into a separate function. - Implement hardware task switching and task gates. - Flush the TLB when reloading CR3.
by aandrejevic@svn.reactos.org
Author: aandrejevic Date: Tue Nov 4 22:58:02 2014 New Revision: 65260 URL:
http://svn.reactos.org/svn/reactos?rev=65260&view=rev
Log: [FAST486] - Move the descriptor reading logic into a separate function. - Implement hardware task switching and task gates. - Flush the TLB when reloading CR3. Modified: trunk/reactos/include/reactos/libs/fast486/fast486.h trunk/reactos/lib/fast486/common.c trunk/reactos/lib/fast486/common.h trunk/reactos/lib/fast486/common.inl trunk/reactos/lib/fast486/extraops.c trunk/reactos/lib/fast486/opcodes.c trunk/reactos/lib/fast486/opgroups.c Modified: trunk/reactos/include/reactos/libs/fast486/fast486.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/fast4…
============================================================================== --- trunk/reactos/include/reactos/libs/fast486/fast486.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/libs/fast486/fast486.h [iso-8859-1] Tue Nov 4 22:58:02 2014 @@ -75,14 +75,15 @@ #define FAST486_DR4_RESERVED 0xFFFF1FF0 #define FAST486_DR5_RESERVED 0x0000DC00 -#define FAST486_IDT_TASK_GATE 0x5 -#define FAST486_IDT_INT_GATE 0x6 -#define FAST486_IDT_TRAP_GATE 0x7 -#define FAST486_IDT_INT_GATE_32 0xE -#define FAST486_IDT_TRAP_GATE_32 0xF - -#define FAST486_LDT_SIGNATURE 0x02 -#define FAST486_TSS_SIGNATURE 0x09 +#define FAST486_LDT_SIGNATURE 0x02 +#define FAST486_TASK_GATE_SIGNATURE 0x05 +#define FAST486_IDT_INT_GATE 0x06 +#define FAST486_IDT_TRAP_GATE 0x07 +#define FAST486_TSS_SIGNATURE 0x09 +#define FAST486_BUSY_TSS_SIGNATURE 0x0B +#define FAST486_CALL_GATE_SIGNATURE 0x0C +#define FAST486_IDT_INT_GATE_32 0x0E +#define FAST486_IDT_TRAP_GATE_32 0x0F #define FAST486_PREFIX_SEG (1 << 0) #define FAST486_PREFIX_OPSIZE (1 << 1) @@ -270,7 +271,6 @@ USHORT Selector; ULONG Base; ULONG Limit; - BOOLEAN Busy; } FAST486_TASK_REG, *PFAST486_TASK_REG; #include <pshpack1.h> Modified: trunk/reactos/lib/fast486/common.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.c?rev=6…
============================================================================== --- trunk/reactos/lib/fast486/common.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.c [iso-8859-1] Tue Nov 4 22:58:02 2014 @@ -274,6 +274,12 @@ FAST486_TSS Tss; USHORT OldSs = State->SegmentRegs[FAST486_REG_SS].Selector; ULONG OldEsp = State->GeneralRegs[FAST486_REG_ESP].Long; + + if (GateType == FAST486_TASK_GATE_SIGNATURE) + { + /* Task call */ + return Fast486TaskSwitch(State, FAST486_TASK_CALL, IdtEntry->Selector); + } if (GateSize != (State->SegmentRegs[FAST486_REG_CS].Size)) { @@ -484,4 +490,306 @@ State->ExceptionCount = 0; } +BOOLEAN +FASTCALL +Fast486TaskSwitch(PFAST486_STATE State, FAST486_TASK_SWITCH_TYPE Type, USHORT Selector) +{ + ULONG NewTssAddress; + ULONG NewTssLimit; + FAST486_TSS OldTss; + FAST486_TSS NewTss; + FAST486_SYSTEM_DESCRIPTOR NewTssDescriptor; + + /* Read the old TSS */ + if (!Fast486ReadLinearMemory(State, + State->TaskReg.Base, + &OldTss, + sizeof(OldTss))) + { + /* Exception occurred */ + return FALSE; + } + + /* If this is a task return, use the linked previous selector */ + if (Type == FAST486_TASK_RETURN) Selector = LOWORD(OldTss.Link); + + /* Make sure the entry exists in the GDT (not LDT!) */ + if ((GET_SEGMENT_INDEX(Selector) == 0) + || (Selector & SEGMENT_TABLE_INDICATOR) + || GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) + { + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, Selector); + return FALSE; + } + + /* Get the TSS descriptor from the GDT */ + if (!Fast486ReadLinearMemory(State, + State->Gdtr.Address + GET_SEGMENT_INDEX(Selector), + &NewTssDescriptor, + sizeof(NewTssDescriptor))) + { + /* Exception occurred */ + return FALSE; + } + + if (!NewTssDescriptor.Present) + { + /* Incoming task TSS not present */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector); + return FALSE; + } + + /* Calculate the linear address of the new TSS */ + NewTssAddress = NewTssDescriptor.Base; + NewTssAddress |= NewTssDescriptor.BaseMid << 16; + NewTssAddress |= NewTssDescriptor.BaseHigh << 24; + + /* Calculate the limit of the new TSS */ + NewTssLimit = NewTssDescriptor.Limit | (NewTssDescriptor.LimitHigh << 16); + if (NewTssDescriptor.Granularity) NewTssLimit <<= 12; + + if (NewTssLimit < sizeof(FAST486_TSS)) + { + /* TSS limit too small */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, Selector); + } + + /* + * The incoming task shouldn't be busy if we're executing it as a + * new task, and it should be busy if we're returning to it. + */ + if (((NewTssDescriptor.Signature != FAST486_TSS_SIGNATURE) + || (Type == FAST486_TASK_RETURN)) + && ((NewTssDescriptor.Signature != FAST486_BUSY_TSS_SIGNATURE) + || (Type != FAST486_TASK_RETURN))) + { + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + return FALSE; + } + + /* Read the new TSS */ + if (!Fast486ReadLinearMemory(State, + NewTssAddress, + &NewTss, + sizeof(NewTss))) + { + /* Exception occurred */ + return FALSE; + } + + if (Type != FAST486_TASK_CALL) + { + /* Clear the busy bit of the outgoing task */ + FAST486_SYSTEM_DESCRIPTOR OldTssDescriptor; + + if (!Fast486ReadLinearMemory(State, + State->Gdtr.Address + + GET_SEGMENT_INDEX(State->TaskReg.Selector), + &OldTssDescriptor, + sizeof(OldTssDescriptor))) + { + /* Exception occurred */ + return FALSE; + } + + OldTssDescriptor.Signature = FAST486_TSS_SIGNATURE; + + if (!Fast486WriteLinearMemory(State, + State->Gdtr.Address + + GET_SEGMENT_INDEX(State->TaskReg.Selector), + &OldTssDescriptor, + sizeof(OldTssDescriptor))) + { + /* Exception occurred */ + return FALSE; + } + } + else + { + /* Store the link */ + NewTss.Link = State->TaskReg.Selector; + } + + /* Save the current task into the TSS */ + OldTss.Cr3 = State->ControlRegisters[FAST486_REG_CR3]; + OldTss.Eip = State->InstPtr.Long; + OldTss.Eflags = State->Flags.Long; + OldTss.Eax = State->GeneralRegs[FAST486_REG_EAX].Long; + OldTss.Ecx = State->GeneralRegs[FAST486_REG_ECX].Long; + OldTss.Edx = State->GeneralRegs[FAST486_REG_EDX].Long; + OldTss.Ebx = State->GeneralRegs[FAST486_REG_EBX].Long; + OldTss.Esp = State->GeneralRegs[FAST486_REG_ESP].Long; + OldTss.Ebp = State->GeneralRegs[FAST486_REG_EBP].Long; + OldTss.Esi = State->GeneralRegs[FAST486_REG_ESI].Long; + OldTss.Edi = State->GeneralRegs[FAST486_REG_EDI].Long; + OldTss.Es = State->SegmentRegs[FAST486_REG_ES].Selector; + OldTss.Cs = State->SegmentRegs[FAST486_REG_CS].Selector; + OldTss.Ss = State->SegmentRegs[FAST486_REG_SS].Selector; + OldTss.Ds = State->SegmentRegs[FAST486_REG_DS].Selector; + OldTss.Fs = State->SegmentRegs[FAST486_REG_FS].Selector; + OldTss.Gs = State->SegmentRegs[FAST486_REG_GS].Selector; + OldTss.Ldtr = State->Ldtr.Selector; + + /* Write back the old TSS */ + if (!Fast486WriteLinearMemory(State, + State->TaskReg.Base, + &OldTss, + sizeof(OldTss))) + { + /* Exception occurred */ + return FALSE; + } + + /* Mark the new task as busy */ + NewTssDescriptor.Signature = FAST486_BUSY_TSS_SIGNATURE; + + /* Write back the new TSS descriptor */ + if (!Fast486WriteLinearMemory(State, + State->Gdtr.Address + GET_SEGMENT_INDEX(Selector), + &NewTssDescriptor, + sizeof(NewTssDescriptor))) + { + /* Exception occurred */ + return FALSE; + } + + /* Set the task switch bit */ + State->ControlRegisters[FAST486_REG_CR0] |= FAST486_CR0_TS; + + /* Load the task register with the new values */ + State->TaskReg.Selector = Selector; + State->TaskReg.Base = NewTssAddress; + State->TaskReg.Limit = NewTssLimit; + + /* Change the page directory */ + State->ControlRegisters[FAST486_REG_CR3] = NewTss.Cr3; + + /* Flush the TLB */ + if (State->Tlb) RtlZeroMemory(State->Tlb, NUM_TLB_ENTRIES * sizeof(ULONG)); + +#ifndef FAST486_NO_PREFETCH + /* Context switching invalidates the prefetch */ + State->PrefetchValid = FALSE; +#endif + + /* Load the registers */ + State->InstPtr.Long = State->SavedInstPtr.Long = NewTss.Eip; + State->Flags.Long = NewTss.Eflags; + State->GeneralRegs[FAST486_REG_EAX].Long = NewTss.Eax; + State->GeneralRegs[FAST486_REG_ECX].Long = NewTss.Ecx; + State->GeneralRegs[FAST486_REG_EDX].Long = NewTss.Edx; + State->GeneralRegs[FAST486_REG_EBX].Long = NewTss.Ebx; + State->GeneralRegs[FAST486_REG_ESP].Long = NewTss.Esp; + State->GeneralRegs[FAST486_REG_EBP].Long = NewTss.Ebp; + State->GeneralRegs[FAST486_REG_ESI].Long = NewTss.Esi; + State->GeneralRegs[FAST486_REG_EDI].Long = NewTss.Edi; + + /* Set the NT flag if nesting */ + if (Type == FAST486_TASK_CALL) State->Flags.Nt = TRUE; + + if (GET_SEGMENT_INDEX(NewTss.Ldtr) != 0) + { + BOOLEAN Valid; + FAST486_SYSTEM_DESCRIPTOR GdtEntry; + + if (NewTss.Ldtr & SEGMENT_TABLE_INDICATOR) + { + /* This selector doesn't point to the GDT */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewTss.Ldtr); + return FALSE; + } + + if (Fast486ReadDescriptorEntry(State, + NewTss.Ldtr, + &Valid, + (PFAST486_GDT_ENTRY)&GdtEntry)) + { + /* Exception occurred */ + return FALSE; + } + + if (!Valid) + { + /* Invalid selector */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewTss.Ldtr); + return FALSE; + } + + if (GdtEntry.Signature != FAST486_LDT_SIGNATURE) + { + /* This is not an LDT descriptor */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewTss.Ldtr); + return FALSE; + } + + if (!GdtEntry.Present) + { + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_TS, NewTss.Ldtr); + return FALSE; + } + + /* Update the LDTR */ + State->Ldtr.Selector = NewTss.Ldtr; + State->Ldtr.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24); + State->Ldtr.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16); + if (GdtEntry.Granularity) State->Ldtr.Limit <<= 12; + } + else + { + /* The LDT of this task is empty */ + RtlZeroMemory(&State->Ldtr, sizeof(State->Ldtr)); + } + + /* Load the new segments */ + if (!Fast486LoadSegmentInternal(State, + FAST486_REG_CS, + NewTss.Cs, + FAST486_EXCEPTION_TS)) + { + return FALSE; + } + + if (!Fast486LoadSegmentInternal(State, + FAST486_REG_SS, + NewTss.Ss, + FAST486_EXCEPTION_TS)) + { + return FALSE; + } + + if (!Fast486LoadSegmentInternal(State, + FAST486_REG_ES, + NewTss.Es, + FAST486_EXCEPTION_TS)) + { + return FALSE; + } + + if (!Fast486LoadSegmentInternal(State, + FAST486_REG_DS, + NewTss.Ds, + FAST486_EXCEPTION_TS)) + { + return FALSE; + } + + if (!Fast486LoadSegmentInternal(State, + FAST486_REG_FS, + NewTss.Fs, + FAST486_EXCEPTION_TS)) + { + return FALSE; + } + + if (!Fast486LoadSegmentInternal(State, + FAST486_REG_GS, + NewTss.Gs, + FAST486_EXCEPTION_TS)) + { + return FALSE; + } + + return TRUE; +} + /* EOF */ Modified: trunk/reactos/lib/fast486/common.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.h?rev=6…
============================================================================== --- trunk/reactos/lib/fast486/common.h [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.h [iso-8859-1] Tue Nov 4 22:58:02 2014 @@ -69,6 +69,7 @@ #define GET_ADDR_PDE(x) ((x) >> 22) #define GET_ADDR_PTE(x) (((x) >> 12) & 0x3FF) #define INVALID_TLB_FIELD 0xFFFFFFFF +#define NUM_TLB_ENTRIES 0x100000 typedef struct _FAST486_MOD_REG_RM { @@ -80,6 +81,13 @@ ULONG MemoryAddress; }; } FAST486_MOD_REG_RM, *PFAST486_MOD_REG_RM; + +typedef enum _FAST486_TASK_SWITCH_TYPE +{ + FAST486_TASK_JUMP, + FAST486_TASK_CALL, + FAST486_TASK_RETURN +} FAST486_TASK_SWITCH_TYPE, *PFAST486_TASK_SWITCH_TYPE; #include <pshpack1.h> @@ -166,6 +174,15 @@ ULONG ErrorCode ); +BOOLEAN +FASTCALL +Fast486TaskSwitch +( + PFAST486_STATE State, + FAST486_TASK_SWITCH_TYPE Type, + USHORT Selector +); + /* INLINED FUNCTIONS **********************************************************/ #include "common.inl" Modified: trunk/reactos/lib/fast486/common.inl URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/common.inl?rev…
============================================================================== --- trunk/reactos/lib/fast486/common.inl [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/common.inl [iso-8859-1] Tue Nov 4 22:58:02 2014 @@ -426,11 +426,68 @@ FORCEINLINE BOOLEAN FASTCALL -Fast486LoadSegment(PFAST486_STATE State, - FAST486_SEG_REGS Segment, - USHORT Selector) +Fast486ReadDescriptorEntry(PFAST486_STATE State, + USHORT Selector, + PBOOLEAN EntryValid, + PFAST486_GDT_ENTRY Entry) +{ + if (!(Selector & SEGMENT_TABLE_INDICATOR)) + { + /* Make sure the GDT contains the entry */ + if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) + { + *EntryValid = FALSE; + return TRUE; + } + + /* Read the GDT */ + if (!Fast486ReadLinearMemory(State, + State->Gdtr.Address + + GET_SEGMENT_INDEX(Selector), + Entry, + sizeof(*Entry))) + { + /* Exception occurred */ + *EntryValid = FALSE; + return FALSE; + } + } + else + { + /* Make sure the LDT contains the entry */ + if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1)) + { + *EntryValid = FALSE; + return TRUE; + } + + /* Read the LDT */ + if (!Fast486ReadLinearMemory(State, + State->Ldtr.Base + + GET_SEGMENT_INDEX(Selector), + Entry, + sizeof(*Entry))) + { + /* Exception occurred */ + *EntryValid = FALSE; + return FALSE; + } + } + + *EntryValid = TRUE; + return TRUE; +} + +FORCEINLINE +BOOLEAN +FASTCALL +Fast486LoadSegmentInternal(PFAST486_STATE State, + FAST486_SEG_REGS Segment, + USHORT Selector, + FAST486_EXCEPTIONS Exception) { PFAST486_SEG_REG CachedDescriptor; + BOOLEAN Valid; FAST486_GDT_ENTRY GdtEntry; ASSERT(Segment < FAST486_NUM_SEG_REGS); @@ -441,45 +498,16 @@ /* Check for protected mode */ if ((State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) && !State->Flags.Vm) { - if (!(Selector & SEGMENT_TABLE_INDICATOR)) - { - /* Make sure the GDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) - { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); - return FALSE; - } - - /* Read the GDT */ - if (!Fast486ReadLinearMemory(State, - State->Gdtr.Address - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return FALSE; - } - } - else - { - /* Make sure the LDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1)) - { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); - return FALSE; - } - - /* Read the LDT */ - if (!Fast486ReadLinearMemory(State, - State->Ldtr.Base - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return FALSE; - } + if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry)) + { + /* Exception occurred */ + return FALSE; + } + + if (!Valid) + { + /* Invalid selector */ + Fast486ExceptionWithErrorCode(State, Exception, Selector); } if (Segment == FAST486_REG_SS) @@ -488,27 +516,27 @@ if (GET_SEGMENT_INDEX(Selector) == 0) { - Fast486Exception(State, FAST486_EXCEPTION_GP); + Fast486Exception(State, Exception); return FALSE; } if (!GdtEntry.SystemType) { /* This is a special descriptor */ - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } if (GdtEntry.Executable || !GdtEntry.ReadWrite) { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } if ((GET_SEGMENT_RPL(Selector) != Fast486GetCurrentPrivLevel(State)) || (GET_SEGMENT_RPL(Selector) != GdtEntry.Dpl)) { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } @@ -529,55 +557,53 @@ if (GET_SEGMENT_INDEX(Selector) == 0) { - Fast486Exception(State, FAST486_EXCEPTION_GP); + Fast486Exception(State, Exception); return FALSE; } if (!GdtEntry.SystemType) { - // TODO: Call/interrupt/task gates NOT IMPLEMENTED! - UNIMPLEMENTED; - } - else - { - if (!GdtEntry.Present) + /* Must be a segment descriptor */ + Fast486ExceptionWithErrorCode(State, Exception, Selector); + } + + if (!GdtEntry.Present) + { + Fast486ExceptionWithErrorCode(State, Exception, Selector); + return FALSE; + } + + if (!GdtEntry.Executable) + { + Fast486ExceptionWithErrorCode(State, Exception, Selector); + return FALSE; + } + + if (GdtEntry.DirConf) + { + /* Conforming Code Segment */ + + if (GdtEntry.Dpl > Fast486GetCurrentPrivLevel(State)) { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector); + /* Must be accessed from lower-privileged code */ + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } - - if (!GdtEntry.Executable) + } + else + { + /* Regular code segment */ + + if ((GET_SEGMENT_RPL(Selector) > Fast486GetCurrentPrivLevel(State)) + || (Fast486GetCurrentPrivLevel(State) != GdtEntry.Dpl)) { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } - - if (GdtEntry.DirConf) - { - /* Conforming Code Segment */ - - if (GdtEntry.Dpl > Fast486GetCurrentPrivLevel(State)) - { - /* Must be accessed from lower-privileged code */ - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); - return FALSE; - } - } - else - { - /* Regular code segment */ - - if ((GET_SEGMENT_RPL(Selector) > Fast486GetCurrentPrivLevel(State)) - || (Fast486GetCurrentPrivLevel(State) != GdtEntry.Dpl)) - { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); - return FALSE; - } - } - - /* Update CPL */ - State->Cpl = GET_SEGMENT_RPL(Selector); - } + } + + /* Update CPL */ + State->Cpl = GET_SEGMENT_RPL(Selector); } else { @@ -588,20 +614,20 @@ if (!GdtEntry.SystemType) { /* This is a special descriptor */ - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } if ((GET_SEGMENT_RPL(Selector) > GdtEntry.Dpl) || (Fast486GetCurrentPrivLevel(State) > GdtEntry.Dpl)) { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } if (!GdtEntry.Present) { - Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_NP, Selector); + Fast486ExceptionWithErrorCode(State, Exception, Selector); return FALSE; } } @@ -642,6 +668,64 @@ FORCEINLINE BOOLEAN FASTCALL +Fast486LoadSegment(PFAST486_STATE State, + FAST486_SEG_REGS Segment, + USHORT Selector) +{ + return Fast486LoadSegmentInternal(State, + Segment, + Selector, + FAST486_EXCEPTION_GP); +} + +FORCEINLINE +BOOLEAN +FASTCALL +Fast486ProcessGate(PFAST486_STATE State, USHORT Selector, ULONG Offset, BOOLEAN Call) +{ + BOOLEAN Valid; + FAST486_SYSTEM_DESCRIPTOR Descriptor; + + if (!Fast486ReadDescriptorEntry(State, + Selector, + &Valid, + (PFAST486_GDT_ENTRY)&Descriptor)) + { + /* Exception occurred */ + return FALSE; + } + + if (!Valid) + { + /* Invalid selector */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); + return FALSE; + } + + if (Descriptor.Signature == FAST486_TASK_GATE_SIGNATURE) + { + /* Task gate */ + + Fast486TaskSwitch(State, + Call ? FAST486_TASK_CALL : FAST486_TASK_JUMP, + ((PFAST486_IDT_ENTRY)&Descriptor)->Selector); + + return FALSE; + } + else if (Descriptor.Signature == FAST486_CALL_GATE_SIGNATURE) + { + /* Call gate */ + + // TODO: NOT IMPLEMENTED + UNIMPLEMENTED; + } + + return TRUE; +} + +FORCEINLINE +BOOLEAN +FASTCALL Fast486FetchByte(PFAST486_STATE State, PUCHAR Data) { Modified: trunk/reactos/lib/fast486/extraops.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/extraops.c?rev…
============================================================================== --- trunk/reactos/lib/fast486/extraops.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/extraops.c [iso-8859-1] Tue Nov 4 22:58:02 2014 @@ -320,6 +320,7 @@ { BOOLEAN OperandSize, AddressSize; FAST486_MOD_REG_RM ModRegRm; + BOOLEAN Valid; USHORT Selector; FAST486_GDT_ENTRY GdtEntry; DWORD AccessRights; @@ -368,45 +369,16 @@ } } - if (!(Selector & SEGMENT_TABLE_INDICATOR)) - { - /* Check if the GDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) - { - State->Flags.Zf = FALSE; - return; - } - - /* Read the GDT */ - if (!Fast486ReadLinearMemory(State, - State->Gdtr.Address - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return; - } - } - else - { - /* Check if the LDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1)) - { - State->Flags.Zf = FALSE; - return; - } - - /* Read the LDT */ - if (!Fast486ReadLinearMemory(State, - State->Ldtr.Base - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return; - } + if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry)) + { + /* Exception occurred */ + return; + } + + if (!Valid) + { + State->Flags.Zf = FALSE; + return; } /* Privilege check */ @@ -432,6 +404,7 @@ { BOOLEAN OperandSize, AddressSize; FAST486_MOD_REG_RM ModRegRm; + BOOLEAN Valid; USHORT Selector; ULONG Limit; FAST486_GDT_ENTRY GdtEntry; @@ -480,45 +453,16 @@ } } - if (!(Selector & SEGMENT_TABLE_INDICATOR)) - { - /* Check if the GDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) - { - State->Flags.Zf = FALSE; - return; - } - - /* Read the GDT */ - if (!Fast486ReadLinearMemory(State, - State->Gdtr.Address - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return; - } - } - else - { - /* Check if the LDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1)) - { - State->Flags.Zf = FALSE; - return; - } - - /* Read the LDT */ - if (!Fast486ReadLinearMemory(State, - State->Ldtr.Base - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return; - } + if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry)) + { + /* Exception occurred */ + return; + } + + if (!Valid) + { + State->Flags.Zf = FALSE; + return; } /* Privilege check */ @@ -690,6 +634,12 @@ /* Changing CR0 or CR3 can interfere with prefetching (because of paging) */ State->PrefetchValid = FALSE; #endif + + if (State->Tlb && (ModRegRm.Register == (INT)FAST486_REG_CR3)) + { + /* Flush the TLB */ + RtlZeroMemory(State->Tlb, NUM_TLB_ENTRIES * sizeof(ULONG)); + } /* Load a value to the control register */ State->ControlRegisters[ModRegRm.Register] = Value; Modified: trunk/reactos/lib/fast486/opcodes.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opcodes.c?rev=…
============================================================================== --- trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opcodes.c [iso-8859-1] Tue Nov 4 22:58:02 2014 @@ -4079,6 +4079,15 @@ return; } + if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) + { + if (!Fast486ProcessGate(State, Segment, Offset, TRUE)) + { + /* Gate processed or exception occurred */ + return; + } + } + /* Push the current code segment selector */ if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector)) { @@ -4537,6 +4546,17 @@ NO_LOCK_PREFIX(); TOGGLE_OPSIZE(Size); + + /* Check if this is a nested task return */ + if (State->Flags.Nt && (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE)) + { + /* Clear the NT flag of the current task */ + State->Flags.Nt = FALSE; + + /* Switch to the old task */ + Fast486TaskSwitch(State, FAST486_TASK_RETURN, 0); + return; + } /* Pop EIP */ if (!Fast486StackPop(State, &InstPtr)) @@ -4597,14 +4617,6 @@ return; } - if (State->Flags.Nt) - { - /* Nested task return */ - - UNIMPLEMENTED; - return; - } - if (NewFlags.Vm) { /* Return to VM86 mode */ @@ -5019,6 +5031,15 @@ { /* Exception occurred */ return; + } + + if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) + { + if (!Fast486ProcessGate(State, Segment, Offset, FALSE)) + { + /* Gate processed or exception occurred */ + return; + } } /* Load the new CS */ Modified: trunk/reactos/lib/fast486/opgroups.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/fast486/opgroups.c?rev…
============================================================================== --- trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] (original) +++ trunk/reactos/lib/fast486/opgroups.c [iso-8859-1] Tue Nov 4 22:58:02 2014 @@ -1420,6 +1420,15 @@ return; } + if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) + { + if (!Fast486ProcessGate(State, Selector, Value, TRUE)) + { + /* Gate processed or exception occurred */ + return; + } + } + /* Push the current value of CS */ if (!Fast486StackPush(State, State->SegmentRegs[FAST486_REG_CS].Selector)) { @@ -1473,6 +1482,15 @@ return; } + if (State->ControlRegisters[FAST486_REG_CR0] & FAST486_CR0_PE) + { + if (!Fast486ProcessGate(State, Selector, Value, FALSE)) + { + /* Gate processed or exception occurred */ + return; + } + } + /* Load the new code segment */ if (!Fast486LoadSegment(State, FAST486_REG_CS, Selector)) { @@ -1712,6 +1730,7 @@ /* LLDT */ case 2: { + BOOLEAN Valid; USHORT Selector; FAST486_SYSTEM_DESCRIPTOR GdtEntry; @@ -1739,21 +1758,26 @@ return; } - /* Make sure the GDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) - { + if (Selector & SEGMENT_TABLE_INDICATOR) + { + /* This selector doesn't point to the GDT */ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); return; } - /* Read the GDT */ - if (!Fast486ReadLinearMemory(State, - State->Gdtr.Address - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ + if (Fast486ReadDescriptorEntry(State, + Selector, + &Valid, + (PFAST486_GDT_ENTRY)&GdtEntry)) + { + /* Exception occurred */ + return; + } + + if (!Valid) + { + /* Invalid selector */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); return; } @@ -1788,6 +1812,7 @@ /* LTR */ case 3: { + BOOLEAN Valid; USHORT Selector; FAST486_SYSTEM_DESCRIPTOR GdtEntry; @@ -1815,21 +1840,26 @@ return; } - /* Make sure the GDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) - { + if (Selector & SEGMENT_TABLE_INDICATOR) + { + /* This selector doesn't point to the GDT */ Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); return; } - /* Read the GDT */ - if (!Fast486ReadLinearMemory(State, - State->Gdtr.Address - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ + if (Fast486ReadDescriptorEntry(State, + Selector, + &Valid, + (PFAST486_GDT_ENTRY)&GdtEntry)) + { + /* Exception occurred */ + return; + } + + if (!Valid) + { + /* Invalid selector */ + Fast486ExceptionWithErrorCode(State, FAST486_EXCEPTION_GP, Selector); return; } @@ -1857,7 +1887,6 @@ State->TaskReg.Base = GdtEntry.Base | (GdtEntry.BaseMid << 16) | (GdtEntry.BaseHigh << 24); State->TaskReg.Limit = GdtEntry.Limit | (GdtEntry.LimitHigh << 16); if (GdtEntry.Granularity) State->TaskReg.Limit <<= 12; - State->TaskReg.Busy = TRUE; break; } @@ -1867,6 +1896,7 @@ case 5: { USHORT Selector; + BOOLEAN Valid; FAST486_GDT_ENTRY GdtEntry; /* Not recognized in real mode or virtual 8086 mode */ @@ -1893,47 +1923,17 @@ return; } - if (!(Selector & SEGMENT_TABLE_INDICATOR)) - { - /* Make sure the GDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Gdtr.Size + 1)) - { - /* Clear ZF */ - State->Flags.Zf = FALSE; - return; - } - - /* Read the GDT */ - if (!Fast486ReadLinearMemory(State, - State->Gdtr.Address - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return; - } - } - else - { - /* Make sure the LDT contains the entry */ - if (GET_SEGMENT_INDEX(Selector) >= (State->Ldtr.Limit + 1)) - { - /* Clear ZF */ - State->Flags.Zf = FALSE; - return; - } - - /* Read the LDT */ - if (!Fast486ReadLinearMemory(State, - State->Ldtr.Base - + GET_SEGMENT_INDEX(Selector), - &GdtEntry, - sizeof(GdtEntry))) - { - /* Exception occurred */ - return; - } + if (!Fast486ReadDescriptorEntry(State, Selector, &Valid, &GdtEntry)) + { + /* Exception occurred */ + return; + } + + if (!Valid) + { + /* Clear ZF */ + State->Flags.Zf = FALSE; + return; } /* Set ZF if it is valid and accessible */
10 years, 1 month
1
0
0
0
[tfaber] 65259: [NTOS:SE] - Implement ACL inheritance for SeAssignSecurityEx CORE-8745 #resolve
by tfaber@svn.reactos.org
Author: tfaber Date: Tue Nov 4 22:44:50 2014 New Revision: 65259 URL:
http://svn.reactos.org/svn/reactos?rev=65259&view=rev
Log: [NTOS:SE] - Implement ACL inheritance for SeAssignSecurityEx CORE-8745 #resolve Modified: trunk/reactos/ntoskrnl/include/internal/se.h trunk/reactos/ntoskrnl/se/acl.c trunk/reactos/ntoskrnl/se/sd.c Modified: trunk/reactos/ntoskrnl/include/internal/se.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/include/internal/se.h [iso-8859-1] Tue Nov 4 22:44:50 2014 @@ -489,6 +489,32 @@ ); NTSTATUS +SepPropagateAcl( + _Out_writes_bytes_opt_(DaclLength) PACL AclDest, + _Inout_ PULONG AclLength, + _In_reads_bytes_(AclSource->AclSize) PACL AclSource, + _In_ PSID Owner, + _In_ PSID Group, + _In_ BOOLEAN IsInherited, + _In_ BOOLEAN IsDirectoryObject, + _In_ PGENERIC_MAPPING GenericMapping); + +PACL +SepSelectAcl( + _In_opt_ PACL ExplicitAcl, + _In_ BOOLEAN ExplicitPresent, + _In_ BOOLEAN ExplicitDefaulted, + _In_opt_ PACL ParentAcl, + _In_opt_ PACL DefaultAcl, + _Out_ PULONG AclLength, + _In_ PSID Owner, + _In_ PSID Group, + _Out_ PBOOLEAN AclPresent, + _Out_ PBOOLEAN IsInherited, + _In_ BOOLEAN IsDirectoryObject, + _In_ PGENERIC_MAPPING GenericMapping); + +NTSTATUS NTAPI SeDefaultObjectMethod( PVOID Object, Modified: trunk/reactos/ntoskrnl/se/acl.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/acl.c?rev=6525…
============================================================================== --- trunk/reactos/ntoskrnl/se/acl.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/acl.c [iso-8859-1] Tue Nov 4 22:44:50 2014 @@ -367,4 +367,280 @@ } } +BOOLEAN +SepShouldPropagateAce( + _In_ UCHAR AceFlags, + _Out_ PUCHAR NewAceFlags, + _In_ BOOLEAN IsInherited, + _In_ BOOLEAN IsDirectoryObject) +{ + if (!IsInherited) + { + *NewAceFlags = AceFlags; + return TRUE; + } + + if (!IsDirectoryObject) + { + if (AceFlags & OBJECT_INHERIT_ACE) + { + *NewAceFlags = AceFlags & ~VALID_INHERIT_FLAGS; + return TRUE; + } + return FALSE; + } + + if (AceFlags & NO_PROPAGATE_INHERIT_ACE) + { + if (AceFlags & CONTAINER_INHERIT_ACE) + { + *NewAceFlags = AceFlags & ~VALID_INHERIT_FLAGS; + return TRUE; + } + return FALSE; + } + + if (AceFlags & CONTAINER_INHERIT_ACE) + { + *NewAceFlags = CONTAINER_INHERIT_ACE | (AceFlags & OBJECT_INHERIT_ACE) | (AceFlags & ~VALID_INHERIT_FLAGS); + return TRUE; + } + + if (AceFlags & OBJECT_INHERIT_ACE) + { + *NewAceFlags = INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE | (AceFlags & ~VALID_INHERIT_FLAGS); + return TRUE; + } + + return FALSE; +} + +NTSTATUS +SepPropagateAcl( + _Out_writes_bytes_opt_(DaclLength) PACL AclDest, + _Inout_ PULONG AclLength, + _In_reads_bytes_(AclSource->AclSize) PACL AclSource, + _In_ PSID Owner, + _In_ PSID Group, + _In_ BOOLEAN IsInherited, + _In_ BOOLEAN IsDirectoryObject, + _In_ PGENERIC_MAPPING GenericMapping) +{ + ACCESS_MASK Mask; + PACCESS_ALLOWED_ACE AceSource; + PACCESS_ALLOWED_ACE AceDest; + PUCHAR CurrentDest; + PUCHAR CurrentSource; + ULONG i; + ULONG Written; + UCHAR AceFlags; + USHORT AceSize; + USHORT AceCount = 0; + PSID Sid; + BOOLEAN WriteTwoAces; + + if (AclSource->AclRevision != ACL_REVISION) + { + NT_ASSERT(AclSource->AclRevision == ACL_REVISION); + return STATUS_UNKNOWN_REVISION; + } + + NT_ASSERT(AclSource->AclSize % sizeof(ULONG) == 0); + NT_ASSERT(AclSource->Sbz1 == 0); + NT_ASSERT(AclSource->Sbz2 == 0); + + Written = 0; + if (*AclLength >= Written + sizeof(ACL)) + { + RtlCopyMemory(AclDest, + AclSource, + sizeof(ACL)); + } + Written += sizeof(ACL); + + CurrentDest = (PUCHAR)(AclDest + 1); + CurrentSource = (PUCHAR)(AclSource + 1); + for (i = 0; i < AclSource->AceCount; i++) + { + NT_ASSERT((ULONG_PTR)CurrentDest % sizeof(ULONG) == 0); + NT_ASSERT((ULONG_PTR)CurrentSource % sizeof(ULONG) == 0); + AceDest = (PACCESS_ALLOWED_ACE)CurrentDest; + AceSource = (PACCESS_ALLOWED_ACE)CurrentSource; + + /* These all have the same structure */ + NT_ASSERT(AceSource->Header.AceType == ACCESS_ALLOWED_ACE_TYPE || + AceSource->Header.AceType == ACCESS_DENIED_ACE_TYPE || + AceSource->Header.AceType == SYSTEM_AUDIT_ACE_TYPE); + + NT_ASSERT(AceSource->Header.AceSize % sizeof(ULONG) == 0); + NT_ASSERT(AceSource->Header.AceSize >= sizeof(*AceSource)); + if (!SepShouldPropagateAce(AceSource->Header.AceFlags, + &AceFlags, + IsInherited, + IsDirectoryObject)) + { + CurrentSource += AceSource->Header.AceSize; + continue; + } + + /* FIXME: filter out duplicate ACEs */ + AceSize = AceSource->Header.AceSize; + Mask = AceSource->Mask; + Sid = (PSID)&AceSource->SidStart; + NT_ASSERT(AceSize >= FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(Sid)); + + WriteTwoAces = FALSE; + /* Map effective ACE to specific rights */ + if (!(AceFlags & INHERIT_ONLY_ACE)) + { + RtlMapGenericMask(&Mask, GenericMapping); + Mask &= GenericMapping->GenericAll; + + if (IsInherited) + { + if (RtlEqualSid(Sid, SeCreatorOwnerSid)) + Sid = Owner; + else if (RtlEqualSid(Sid, SeCreatorGroupSid)) + Sid = Group; + AceSize = FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(Sid); + + /* + * A generic container ACE becomes two ACEs: + * - a specific effective ACE with no inheritance flags + * - an inherit-only ACE that keeps the generic rights + */ + if (IsDirectoryObject && + (AceFlags & CONTAINER_INHERIT_ACE) && + (Mask != AceSource->Mask || Sid != (PSID)&AceSource->SidStart)) + { + WriteTwoAces = TRUE; + } + } + } + + while (1) + { + if (*AclLength >= Written + AceSize) + { + AceDest->Header.AceType = AceSource->Header.AceType; + AceDest->Header.AceFlags = WriteTwoAces ? AceFlags & ~VALID_INHERIT_FLAGS + : AceFlags; + AceDest->Header.AceSize = AceSize; + AceDest->Mask = Mask; + RtlCopySid(AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart), + (PSID)&AceDest->SidStart, + Sid); + } + Written += AceSize; + + AceCount++; + CurrentDest += AceSize; + + if (!WriteTwoAces) + break; + + /* Second ACE keeps all the generics from the source ACE */ + WriteTwoAces = FALSE; + AceDest = (PACCESS_ALLOWED_ACE)CurrentDest; + AceSize = AceSource->Header.AceSize; + Mask = AceSource->Mask; + Sid = (PSID)&AceSource->SidStart; + AceFlags |= INHERIT_ONLY_ACE; + } + + CurrentSource += AceSource->Header.AceSize; + } + + if (*AclLength >= sizeof(ACL)) + { + AclDest->AceCount = AceCount; + AclDest->AclSize = Written; + } + + if (Written > *AclLength) + { + *AclLength = Written; + return STATUS_BUFFER_TOO_SMALL; + } + *AclLength = Written; + return STATUS_SUCCESS; +} + +PACL +SepSelectAcl( + _In_opt_ PACL ExplicitAcl, + _In_ BOOLEAN ExplicitPresent, + _In_ BOOLEAN ExplicitDefaulted, + _In_opt_ PACL ParentAcl, + _In_opt_ PACL DefaultAcl, + _Out_ PULONG AclLength, + _In_ PSID Owner, + _In_ PSID Group, + _Out_ PBOOLEAN AclPresent, + _Out_ PBOOLEAN IsInherited, + _In_ BOOLEAN IsDirectoryObject, + _In_ PGENERIC_MAPPING GenericMapping) +{ + PACL Acl; + NTSTATUS Status; + + *AclPresent = TRUE; + if (ExplicitPresent && !ExplicitDefaulted) + { + Acl = ExplicitAcl; + } + else + { + if (ParentAcl) + { + *IsInherited = TRUE; + *AclLength = 0; + Status = SepPropagateAcl(NULL, + AclLength, + ParentAcl, + Owner, + Group, + *IsInherited, + IsDirectoryObject, + GenericMapping); + NT_ASSERT(Status == STATUS_BUFFER_TOO_SMALL); + + /* Use the parent ACL only if it's not empty */ + if (*AclLength != sizeof(ACL)) + return ParentAcl; + } + + if (ExplicitPresent) + { + Acl = ExplicitAcl; + } + else if (DefaultAcl) + { + Acl = DefaultAcl; + } + else + { + *AclPresent = FALSE; + Acl = NULL; + } + } + + *IsInherited = FALSE; + *AclLength = 0; + if (Acl) + { + /* Get the length */ + Status = SepPropagateAcl(NULL, + AclLength, + Acl, + Owner, + Group, + *IsInherited, + IsDirectoryObject, + GenericMapping); + NT_ASSERT(Status == STATUS_BUFFER_TOO_SMALL); + } + return Acl; +} + /* EOF */ Modified: trunk/reactos/ntoskrnl/se/sd.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/se/sd.c?rev=65259…
============================================================================== --- trunk/reactos/ntoskrnl/se/sd.c [iso-8859-1] (original) +++ trunk/reactos/ntoskrnl/se/sd.c [iso-8859-1] Tue Nov 4 22:44:50 2014 @@ -1109,7 +1109,6 @@ return STATUS_SUCCESS; } - /* * @implemented */ @@ -1140,12 +1139,20 @@ ULONG Current; PSID Owner = NULL; PSID Group = NULL; + PACL ExplicitAcl; + BOOLEAN ExplicitPresent; + BOOLEAN ExplicitDefaulted; + PACL ParentAcl; PACL Dacl = NULL; PACL Sacl = NULL; + BOOLEAN DaclIsInherited; + BOOLEAN SaclIsInherited; + BOOLEAN DaclPresent; + BOOLEAN SaclPresent; + NTSTATUS Status; DBG_UNREFERENCED_PARAMETER(ObjectType); DBG_UNREFERENCED_PARAMETER(AutoInheritFlags); - DBG_UNREFERENCED_PARAMETER(GenericMapping); UNREFERENCED_PARAMETER(PoolType); PAGED_CODE(); @@ -1180,7 +1187,6 @@ DPRINT("Use token owner sid!\n"); Owner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid; } - OwnerLength = RtlLengthSid(Owner); NT_ASSERT(OwnerLength % sizeof(ULONG) == 0); @@ -1199,56 +1205,77 @@ SeUnlockSubjectContext(SubjectContext); return STATUS_INVALID_PRIMARY_GROUP; } - GroupLength = RtlLengthSid(Group); NT_ASSERT(GroupLength % sizeof(ULONG) == 0); /* Inherit the DACL */ + DaclLength = 0; + ExplicitAcl = NULL; + ExplicitPresent = FALSE; + ExplicitDefaulted = FALSE; if (ExplicitDescriptor != NULL && - (ExplicitDescriptor->Control & SE_DACL_PRESENT) && - !(ExplicitDescriptor->Control & SE_DACL_DEFAULTED)) - { - DPRINT("Use explicit DACL!\n"); - Dacl = SepGetDaclFromDescriptor(ExplicitDescriptor); + (ExplicitDescriptor->Control & SE_DACL_PRESENT)) + { + ExplicitAcl = SepGetDaclFromDescriptor(ExplicitDescriptor); + ExplicitPresent = TRUE; + if (ExplicitDescriptor->Control & SE_DACL_DEFAULTED) + ExplicitDefaulted = TRUE; + } + ParentAcl = NULL; + if (ParentDescriptor != NULL && + (ParentDescriptor->Control & SE_DACL_PRESENT)) + { + ParentAcl = SepGetDaclFromDescriptor(ParentDescriptor); + } + Dacl = SepSelectAcl(ExplicitAcl, + ExplicitPresent, + ExplicitDefaulted, + ParentAcl, + Token->DefaultDacl, + &DaclLength, + Owner, + Group, + &DaclPresent, + &DaclIsInherited, + IsDirectoryObject, + GenericMapping); + if (DaclPresent) Control |= SE_DACL_PRESENT; - } - else if (ParentDescriptor != NULL && - (ParentDescriptor->Control & SE_DACL_PRESENT)) - { - DPRINT("Use parent DACL!\n"); - /* FIXME: Inherit */ - Dacl = SepGetDaclFromDescriptor(ParentDescriptor); - Control |= SE_DACL_PRESENT; - } - else if (Token->DefaultDacl) - { - DPRINT("Use token default DACL!\n"); - Dacl = Token->DefaultDacl; - Control |= SE_DACL_PRESENT; - } - - DaclLength = (Dacl != NULL) ? Dacl->AclSize : 0; NT_ASSERT(DaclLength % sizeof(ULONG) == 0); /* Inherit the SACL */ + SaclLength = 0; + ExplicitAcl = NULL; + ExplicitPresent = FALSE; + ExplicitDefaulted = FALSE; if (ExplicitDescriptor != NULL && - (ExplicitDescriptor->Control & SE_SACL_PRESENT) && - !(ExplicitDescriptor->Control & SE_SACL_DEFAULTED)) - { - DPRINT("Use explicit SACL!\n"); - Sacl = SepGetSaclFromDescriptor(ExplicitDescriptor); + (ExplicitDescriptor->Control & SE_SACL_PRESENT)) + { + ExplicitAcl = SepGetSaclFromDescriptor(ExplicitDescriptor); + ExplicitPresent = TRUE; + if (ExplicitDescriptor->Control & SE_SACL_DEFAULTED) + ExplicitDefaulted = TRUE; + } + ParentAcl = NULL; + if (ParentDescriptor != NULL && + (ParentDescriptor->Control & SE_SACL_PRESENT)) + { + ParentAcl = SepGetSaclFromDescriptor(ParentDescriptor); + } + Sacl = SepSelectAcl(ExplicitAcl, + ExplicitPresent, + ExplicitDefaulted, + ParentAcl, + NULL, + &SaclLength, + Owner, + Group, + &SaclPresent, + &SaclIsInherited, + IsDirectoryObject, + GenericMapping); + if (SaclPresent) Control |= SE_SACL_PRESENT; - } - else if (ParentDescriptor != NULL && - (ParentDescriptor->Control & SE_SACL_PRESENT)) - { - DPRINT("Use parent SACL!\n"); - /* FIXME: Inherit */ - Sacl = SepGetSaclFromDescriptor(ParentDescriptor); - Control |= SE_SACL_PRESENT; - } - - SaclLength = (Sacl != NULL) ? Sacl->AclSize : 0; NT_ASSERT(SaclLength % sizeof(ULONG) == 0); /* Allocate and initialize the new security descriptor */ @@ -1279,14 +1306,30 @@ if (SaclLength != 0) { - RtlCopyMemory((PUCHAR)Descriptor + Current, Sacl, SaclLength); + Status = SepPropagateAcl((PACL)((PUCHAR)Descriptor + Current), + &SaclLength, + Sacl, + Owner, + Group, + SaclIsInherited, + IsDirectoryObject, + GenericMapping); + NT_ASSERT(Status == STATUS_SUCCESS); Descriptor->Sacl = Current; Current += SaclLength; } if (DaclLength != 0) { - RtlCopyMemory((PUCHAR)Descriptor + Current, Dacl, DaclLength); + Status = SepPropagateAcl((PACL)((PUCHAR)Descriptor + Current), + &DaclLength, + Dacl, + Owner, + Group, + DaclIsInherited, + IsDirectoryObject, + GenericMapping); + NT_ASSERT(Status == STATUS_SUCCESS); Descriptor->Dacl = Current; Current += DaclLength; }
10 years, 1 month
1
0
0
0
[tfaber] 65258: [KMTESTS:SE] - Add a test for SeAssignSecurity[Ex] CORE-8745
by tfaber@svn.reactos.org
Author: tfaber Date: Tue Nov 4 22:42:15 2014 New Revision: 65258 URL:
http://svn.reactos.org/svn/reactos?rev=65258&view=rev
Log: [KMTESTS:SE] - Add a test for SeAssignSecurity[Ex] CORE-8745 Added: trunk/rostests/kmtests/ntos_se/SeHelpers.c (with props) trunk/rostests/kmtests/ntos_se/SeInheritance.c (with props) trunk/rostests/kmtests/ntos_se/se.h (with props) Modified: trunk/rostests/kmtests/CMakeLists.txt trunk/rostests/kmtests/kmtest_drv/testlist.c Modified: trunk/rostests/kmtests/CMakeLists.txt URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/CMakeLists.txt?re…
============================================================================== --- trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] (original) +++ trunk/rostests/kmtests/CMakeLists.txt [iso-8859-1] Tue Nov 4 22:42:15 2014 @@ -71,6 +71,8 @@ ntos_ob/ObType.c ntos_ob/ObTypes.c ntos_ps/PsNotify.c + ntos_se/SeHelpers.c + ntos_se/SeInheritance.c ntos_se/SeQueryInfoToken.c ${COMMON_SOURCE} Modified: trunk/rostests/kmtests/kmtest_drv/testlist.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/kmtest_drv/testli…
============================================================================== --- trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/kmtest_drv/testlist.c [iso-8859-1] Tue Nov 4 22:42:15 2014 @@ -50,6 +50,7 @@ KMT_TESTFUNC Test_ObTypeNoClean; KMT_TESTFUNC Test_ObTypes; KMT_TESTFUNC Test_PsNotify; +KMT_TESTFUNC Test_SeInheritance; KMT_TESTFUNC Test_SeQueryInfoToken; KMT_TESTFUNC Test_RtlAvlTree; KMT_TESTFUNC Test_RtlException; @@ -107,6 +108,7 @@ { "-ObTypeNoClean", Test_ObTypeNoClean }, { "ObTypes", Test_ObTypes }, { "PsNotify", Test_PsNotify }, + { "SeInheritance", Test_SeInheritance }, { "-SeQueryInfoToken", Test_SeQueryInfoToken }, { "RtlAvlTreeKM", Test_RtlAvlTree }, { "RtlExceptionKM", Test_RtlException }, Added: trunk/rostests/kmtests/ntos_se/SeHelpers.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_se/SeHelpers…
============================================================================== --- trunk/rostests/kmtests/ntos_se/SeHelpers.c (added) +++ trunk/rostests/kmtests/ntos_se/SeHelpers.c [iso-8859-1] Tue Nov 4 22:42:15 2014 @@ -0,0 +1,194 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Kernel-Mode Test Suite Helper functions for Se tests + * PROGRAMMER: Thomas Faber <thomas.faber(a)reactos.org> + */ + +#include <kmt_test.h> +#include "se.h" + +NTSTATUS +RtlxAddAuditAccessAceEx( + _Inout_ PACL Acl, + _In_ ULONG Revision, + _In_ ULONG Flags, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid, + _In_ BOOLEAN Success, + _In_ BOOLEAN Failure) +{ + NTSTATUS Status; + USHORT AceSize; + PSYSTEM_AUDIT_ACE Ace; + + if (Success) Flags |= SUCCESSFUL_ACCESS_ACE_FLAG; + if (Failure) Flags |= FAILED_ACCESS_ACE_FLAG; + + AceSize = FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + RtlLengthSid(Sid); + Ace = ExAllocatePoolWithTag(PagedPool, AceSize, 'cAmK'); + if (!Ace) + return STATUS_INSUFFICIENT_RESOURCES; + Ace->Header.AceType = SYSTEM_AUDIT_ACE_TYPE; + Ace->Header.AceFlags = Flags; + Ace->Header.AceSize = AceSize; + Ace->Mask = AccessMask; + Status = RtlCopySid(AceSize - FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart), + (PSID)&Ace->SidStart, + Sid); + ASSERT(NT_SUCCESS(Status)); + if (NT_SUCCESS(Status)) + { + Status = RtlAddAce(Acl, + Revision, + MAXULONG, + Ace, + AceSize); + } + ExFreePoolWithTag(Ace, 'cAmK'); + return Status; +} + +VOID +CheckSid__( + _In_ PSID Sid, + _In_ ULONG SidSize, + _In_ PISID ExpectedSid, + _In_ PCSTR FileAndLine) +{ + BOOLEAN Okay; + ULONG Length; + + KmtOk(Sid != NULL, FileAndLine, "Sid is NULL\n"); + if (KmtSkip(Sid != NULL, FileAndLine, "No Sid\n")) + return; + if (KmtSkip(SidSize >= sizeof(ULONG), FileAndLine, "Sid too small: %lu\n", SidSize)) + return; + Okay = RtlValidSid(Sid); + KmtOk(Okay == TRUE, FileAndLine, "Invalid Sid\n"); + if (KmtSkip(Okay, FileAndLine, "Invalid Sid\n")) + return; + + Length = RtlLengthSid(Sid); + KmtOk(SidSize >= Length, FileAndLine, "SidSize %lu too small, need %lu\n", SidSize, Length); + if (KmtSkip(SidSize >= Length, FileAndLine, "Sid too small\n")) + return; + Okay = RtlEqualSid(Sid, ExpectedSid); + KmtOk(Okay, FileAndLine, "Sids %p and %p not equal\n", Sid, ExpectedSid); + if (!Okay) + { + WCHAR Buffer1[128]; + WCHAR Buffer2[128]; + UNICODE_STRING SidString1, SidString2; + RtlInitEmptyUnicodeString(&SidString1, Buffer1, sizeof(Buffer1)); + RtlInitEmptyUnicodeString(&SidString2, Buffer2, sizeof(Buffer2)); + (void)RtlConvertSidToUnicodeString(&SidString1, Sid, FALSE); + (void)RtlConvertSidToUnicodeString(&SidString2, ExpectedSid, FALSE); + KmtOk(0, FileAndLine, "Got %wZ, expected %wZ\n", &SidString1, &SidString2); + } +} + +VOID +VCheckAcl__( + _In_ PACL Acl, + _In_ ULONG AceCount, + _In_ PCSTR FileAndLine, + _In_ va_list Arguments) +{ + ULONG i; + ULONG Offset; + PACE_HEADER AceHeader; + INT AceType; + INT AceFlags; + ACCESS_MASK Mask; + PISID Sid; + PACCESS_ALLOWED_ACE AllowedAce; + PACCESS_DENIED_ACE DeniedAce; + PSYSTEM_AUDIT_ACE AuditAce; + + KmtOk(Acl != NULL, FileAndLine, "Acl is NULL\n"); + if (KmtSkip(Acl != NULL, FileAndLine, "No ACL\n")) + return; + KmtOk((ULONG_PTR)Acl % sizeof(ULONG) == 0, FileAndLine, "Unaligned ACL %p\n", Acl); + KmtOk(Acl->AclRevision == ACL_REVISION, FileAndLine, "AclRevision is %u\n", Acl->AclRevision); + KmtOk(Acl->Sbz1 == 0, FileAndLine, "Sbz1 is %u\n", Acl->Sbz1); + KmtOk(Acl->Sbz2 == 0, FileAndLine, "Sbz2 is %u\n", Acl->Sbz2); + KmtOk(Acl->AclSize >= sizeof(*Acl), FileAndLine, "AclSize too small: %u\n", Acl->AclSize); + KmtOk(Acl->AceCount == AceCount, FileAndLine, "AceCount is %u, expected %lu\n", Acl->AceCount, AceCount); + Offset = sizeof(*Acl); + for (i = 0; i < Acl->AceCount; i++) + { + KmtOk(Acl->AclSize >= Offset + sizeof(*AceHeader), FileAndLine, "AclSize too small (%u) at Offset %lu, ACE #%lu\n", Acl->AclSize, Offset, i); + if (Acl->AclSize < Offset + sizeof(*AceHeader)) + break; + AceHeader = (PACE_HEADER)((PUCHAR)Acl + Offset); + KmtOk((ULONG_PTR)AceHeader % sizeof(ULONG) == 0, FileAndLine, "[%lu] Unaligned ACE %p\n", i, AceHeader); + KmtOk(AceHeader->AceSize % sizeof(ULONG) == 0, FileAndLine, "[%lu] Unaligned ACE size %u\n", i, AceHeader->AceSize); + KmtOk(Acl->AclSize >= Offset + AceHeader->AceSize, FileAndLine, "[%lu] AclSize too small (%u) at Offset %lu\n", i, Acl->AclSize, Offset); + if (Acl->AclSize < Offset + AceHeader->AceSize) + break; + Offset += AceHeader->AceSize; + if (i >= AceCount) + continue; + AceType = va_arg(Arguments, INT); + AceFlags = va_arg(Arguments, INT); + KmtOk(AceHeader->AceType == AceType, FileAndLine, "[%lu] AceType is %u, expected %u\n", i, AceHeader->AceType, AceType); + KmtOk(AceHeader->AceFlags == AceFlags, FileAndLine, "[%lu] AceFlags is 0x%x, expected 0x%x\n", i, AceHeader->AceFlags, AceFlags); + if (AceType == ACCESS_ALLOWED_ACE_TYPE) + { + Sid = va_arg(Arguments, PSID); + Mask = va_arg(Arguments, INT); + KmtOk(AceHeader->AceSize >= sizeof(*AllowedAce), FileAndLine, "[%lu] AllowedAce AceSize too small: %u\n", i, AceHeader->AceSize); + if (AceHeader->AceSize < sizeof(*AllowedAce)) + continue; + AllowedAce = (PACCESS_ALLOWED_ACE)AceHeader; + KmtOk(AllowedAce->Mask == Mask, FileAndLine, "[%lu] AllowedAce Mask is 0x%lx, expected 0x%lx\n", i, AllowedAce->Mask, Mask); + CheckSid__((PSID)&AllowedAce->SidStart, + AceHeader->AceSize - FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart), + Sid, + FileAndLine); + } + else if (AceType == ACCESS_DENIED_ACE_TYPE) + { + Sid = va_arg(Arguments, PSID); + Mask = va_arg(Arguments, INT); + KmtOk(AceHeader->AceSize >= sizeof(*DeniedAce), FileAndLine, "[%lu] DeniedAce AceSize too small: %u\n", i, AceHeader->AceSize); + if (AceHeader->AceSize < sizeof(*DeniedAce)) + continue; + DeniedAce = (PACCESS_DENIED_ACE)AceHeader; + KmtOk(DeniedAce->Mask == Mask, FileAndLine, "[%lu] DeniedAce Mask is 0x%lx, expected 0x%lx\n", i, DeniedAce->Mask, Mask); + CheckSid__((PSID)&DeniedAce->SidStart, + AceHeader->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart), + Sid, + FileAndLine); + } + else if (AceType == SYSTEM_AUDIT_ACE_TYPE) + { + Sid = va_arg(Arguments, PSID); + Mask = va_arg(Arguments, INT); + KmtOk(AceHeader->AceSize >= sizeof(*AuditAce), FileAndLine, "[%lu] AuditAce AceSize too small: %u\n", i, AceHeader->AceSize); + if (AceHeader->AceSize < sizeof(*AuditAce)) + continue; + AuditAce = (PSYSTEM_AUDIT_ACE)AceHeader; + KmtOk(AuditAce->Mask == Mask, FileAndLine, "[%lu] AuditAce Mask is 0x%lx, expected 0x%lx\n", i, AuditAce->Mask, Mask); + CheckSid__((PSID)&AuditAce->SidStart, + AceHeader->AceSize - FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart), + Sid, + FileAndLine); + } + } +} + +VOID +CheckAcl__( + _In_ PACL Acl, + _In_ ULONG AceCount, + _In_ PCSTR FileAndLine, + ...) +{ + va_list Arguments; + + va_start(Arguments, FileAndLine); + VCheckAcl__(Acl, AceCount, FileAndLine, Arguments); + va_end(Arguments); +} Propchange: trunk/rostests/kmtests/ntos_se/SeHelpers.c ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/rostests/kmtests/ntos_se/SeInheritance.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_se/SeInherit…
============================================================================== --- trunk/rostests/kmtests/ntos_se/SeInheritance.c (added) +++ trunk/rostests/kmtests/ntos_se/SeInheritance.c [iso-8859-1] Tue Nov 4 22:42:15 2014 @@ -0,0 +1,880 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Kernel-Mode Test for object security inheritance + * PROGRAMMER: Thomas Faber <thomas.faber(a)reactos.org> + */ + +#include <kmt_test.h> +#include "se.h" + +static GENERIC_MAPPING GenericMapping = +{ + STANDARD_RIGHTS_READ | 0x1001, + STANDARD_RIGHTS_WRITE | 0x2002, + STANDARD_RIGHTS_EXECUTE | 0x4004, + STANDARD_RIGHTS_ALL | 0x800F, +}; + +static +VOID +TestSeAssignSecurity( + _In_ PSECURITY_SUBJECT_CONTEXT SubjectContext) +{ + NTSTATUS Status; + PTOKEN Token; + PSECURITY_DESCRIPTOR SecurityDescriptor; + SECURITY_DESCRIPTOR ParentDescriptor; + SECURITY_DESCRIPTOR ExplicitDescriptor; + ACL EmptyAcl; + PACL Acl; + PACL Acl2; + ULONG AclSize; + ULONG UsingDefault; + ULONG CanInherit; + ULONG AceFlags; + ULONG AceFlags2; + ULONG Access; + PSID GenericSid; + PSID GenericSid2; + ACCESS_MASK GenericMask; + ACCESS_MASK GenericMask2; + PSID SpecificSid; + ACCESS_MASK SpecificMask; + ACCESS_MASK SpecificMask2; + BOOLEAN ParentUsable; + + Token = SubjectContext->PrimaryToken; + CheckAcl(Token->DefaultDacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, GENERIC_ALL, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, GENERIC_READ | GENERIC_EXECUTE | STANDARD_RIGHTS_READ); + CheckSid(Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, NO_SIZE, SeExports->SeAliasAdminsSid); + CheckSid(Token->PrimaryGroup, NO_SIZE, SeExports->SeLocalSystemSid); +// Flags with no effect on current tests: SEF_SACL_AUTO_INHERIT, SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT +#define StartTestAssign(Parent, Explicit, IsDir, GotDacl, GotSacl) \ + SecurityDescriptor = NULL; \ + Status = SeAssignSecurity (Parent, \ + Explicit, \ + &SecurityDescriptor, \ + /*NULL,*/ \ + IsDir, \ + /*0,*/ \ + SubjectContext, \ + &GenericMapping, \ + PagedPool); \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + if (!skip(NT_SUCCESS(Status), "No security\n")) \ + { \ + PACL Dacl, Sacl; \ + PSID Owner, Group; \ + BOOLEAN Present; \ + BOOLEAN DaclDefaulted, SaclDefaulted; \ + BOOLEAN OwnerDefaulted, GroupDefaulted; \ + Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, \ + &Present, \ + &Dacl, \ + &DaclDefaulted); \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_uint(Present, GotDacl); \ + if (!NT_SUCCESS(Status) || !Present) \ + Dacl = NULL; \ + Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor, \ + &Present, \ + &Sacl, \ + &SaclDefaulted); \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + ok_eq_uint(Present, GotSacl); \ + if (!NT_SUCCESS(Status) || !Present) \ + Sacl = NULL; \ + Status = RtlGetOwnerSecurityDescriptor(SecurityDescriptor, \ + &Owner, \ + &OwnerDefaulted); \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + if (skip(NT_SUCCESS(Status), "No owner\n")) \ + Owner = NULL; \ + Status = RtlGetGroupSecurityDescriptor(SecurityDescriptor, \ + &Group, \ + &GroupDefaulted); \ + ok_eq_hex(Status, STATUS_SUCCESS); \ + if (skip(NT_SUCCESS(Status), "No group\n")) \ + Group = NULL; + +#define EndTestAssign() \ + SeDeassignSecurity(&SecurityDescriptor); \ + } +#define StartTestAssignLoop(Parent, Explicit) \ + { \ + BOOLEAN IsDir; \ + BOOLEAN UsingParent; \ + BOOLEAN UsingExplicit; \ + for (IsDir = FALSE; IsDir <= TRUE; IsDir++) \ + { \ + for (UsingParent = FALSE; UsingParent <= TRUE; UsingParent++) \ + { \ + for (UsingExplicit = FALSE; UsingExplicit <= TRUE; UsingExplicit++) \ + { \ + StartTestAssign(UsingParent ? Parent : NULL, \ + UsingExplicit ? Explicit : NULL, \ + IsDir, \ + TRUE, \ + FALSE) +#define EndTestAssignLoop() \ + EndTestAssign() \ + } \ + } \ + } \ + } +#define TestAssignExpectDefault(Parent, Explicit, IsDir) \ + StartTestAssign(Parent, Explicit, IsDir, TRUE, FALSE) \ + ok_eq_uint(DaclDefaulted, FALSE); \ + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, \ + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); \ + ok_eq_uint(OwnerDefaulted, FALSE); \ + CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); \ + ok_eq_uint(GroupDefaulted, FALSE); \ + CheckSid(Group, NO_SIZE, Token->PrimaryGroup); \ + EndTestAssign() +#define TestAssignExpectDefaultAll() \ + TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE) \ + TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE) \ + TestAssignExpectDefault(NULL, &ExplicitDescriptor, FALSE) \ + TestAssignExpectDefault(NULL, &ExplicitDescriptor, TRUE) \ + TestAssignExpectDefault(&ParentDescriptor, &ExplicitDescriptor, FALSE) \ + TestAssignExpectDefault(&ParentDescriptor, &ExplicitDescriptor, TRUE) + + TestAssignExpectDefault(NULL, NULL, FALSE) + TestAssignExpectDefault(NULL, NULL, TRUE) + + /* Empty parent/explicit descriptors */ + Status = RtlCreateSecurityDescriptor(&ParentDescriptor, + SECURITY_DESCRIPTOR_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlCreateSecurityDescriptor(&ExplicitDescriptor, + SECURITY_DESCRIPTOR_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + TestAssignExpectDefaultAll() + + /* NULL DACL in parent/explicit descriptor */ + for (UsingDefault = FALSE; UsingDefault <= TRUE; UsingDefault++) + { + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + TRUE, + NULL, + UsingDefault); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + NULL, + UsingDefault); + ok_eq_hex(Status, STATUS_SUCCESS); + StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor) + //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault); + ok_eq_uint(DaclDefaulted, FALSE); + if (UsingExplicit) + { + ok(Dacl == NULL, "Dacl = %p\n", Dacl); + } + else + { + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + } + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid); + EndTestAssignLoop() + } + + /* Empty default DACL in parent/explicit descriptor */ + for (UsingDefault = FALSE; UsingDefault <= TRUE; UsingDefault++) + { + Status = RtlCreateAcl(&EmptyAcl, sizeof(EmptyAcl), ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + TRUE, + &EmptyAcl, + UsingDefault); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + &EmptyAcl, + UsingDefault); + ok_eq_hex(Status, STATUS_SUCCESS); + StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor) + //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault); + ok_eq_uint(DaclDefaulted, FALSE); + if (UsingExplicit) + { + CheckAcl(Dacl, 0); + } + else + { + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + } + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid); + EndTestAssignLoop() + } + + + AclSize = sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid(SeExports->SeWorldSid); + Acl = ExAllocatePoolWithTag(PagedPool, AclSize, 'ASmK'); + if (skip(Acl != NULL, "Out of memory\n")) + return; + + Acl2 = ExAllocatePoolWithTag(PagedPool, AclSize, 'ASmK'); + if (skip(Acl2 != NULL, "Out of memory\n")) + { + ExFreePoolWithTag(Acl, 'ASmK'); + return; + } + + /* Simple DACL in parent/explicit descriptor */ + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, 0, READ_CONTROL, SeExports->SeWorldSid); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor) + //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault); + ok_eq_uint(DaclDefaulted, FALSE); + if (UsingExplicit) + { + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid, READ_CONTROL); + } + else + { + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + } + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid); + EndTestAssignLoop() + } + + /* Object-inheritable DACL in parent/explicit descriptor */ + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor) + //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault); + ok_eq_uint(DaclDefaulted, FALSE); + if (UsingExplicit && (!UsingParent || !FlagOn(UsingDefault, 2))) + { + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL); + } + else if (UsingParent) + { + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, IsDir ? INHERIT_ONLY_ACE | OBJECT_INHERIT_ACE : 0, SeExports->SeWorldSid, READ_CONTROL); + } + else + { + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + } + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid); + EndTestAssignLoop() + } + + /* Container-inheritable DACL in parent/explicit descriptor */ + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, CONTAINER_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor) + //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault); + ok_eq_uint(DaclDefaulted, FALSE); + if (UsingExplicit || (UsingParent && IsDir)) + { + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, CONTAINER_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL); + } + else + { + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + } + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid); + EndTestAssignLoop() + } + + /* Fully inheritable DACL in parent/explicit descriptor */ + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, READ_CONTROL, SeExports->SeWorldSid); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor) + //trace("Explicit %u, Parent %u, Dir %u, Default %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault); + ok_eq_uint(DaclDefaulted, FALSE); + if (UsingExplicit && (!UsingParent || !FlagOn(UsingDefault, 2))) + { + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE, SeExports->SeWorldSid, READ_CONTROL); + } + else if (UsingParent) + { + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, IsDir ? OBJECT_INHERIT_ACE | CONTAINER_INHERIT_ACE : 0, SeExports->SeWorldSid, READ_CONTROL); + } + else + { + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + } + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid); + EndTestAssignLoop() + } + + /* Different DACLs in parent and explicit descriptors */ + for (Access = 0; Access <= 1; Access++) + { + if (Access == 1) + { + GenericSid = SeExports->SeCreatorOwnerSid; + SpecificSid = SeExports->SeAliasAdminsSid; + GenericMask = GENERIC_READ; + SpecificMask = STANDARD_RIGHTS_READ | 0x0001; + GenericSid2 = SeExports->SeCreatorGroupSid; + GenericMask2 = GENERIC_EXECUTE; + SpecificMask2 = STANDARD_RIGHTS_EXECUTE | 0x0004; + } + else + { + GenericSid = SeExports->SeWorldSid; + SpecificSid = SeExports->SeWorldSid; + GenericMask = READ_CONTROL; + SpecificMask = READ_CONTROL; + GenericSid2 = SeExports->SeLocalSystemSid; + GenericMask2 = SYNCHRONIZE; + SpecificMask2 = SYNCHRONIZE; + } + for (CanInherit = 0; CanInherit <= 255; CanInherit++) + { + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + AceFlags = CanInherit & 0xf; + Status = RtlAddAccessAllowedAceEx(Acl, ACL_REVISION, AceFlags, GenericMask, GenericSid); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlCreateAcl(Acl2, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + AceFlags2 = CanInherit >> 4; + Status = RtlAddAccessAllowedAceEx(Acl2, ACL_REVISION, AceFlags2, GenericMask2, GenericSid2); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + Acl2, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + StartTestAssignLoop(&ParentDescriptor, &ExplicitDescriptor) + //trace("Explicit %u, Parent %u, Dir %u, Default %u, Inherit %u, Access %u\n", UsingExplicit, UsingParent, IsDir, UsingDefault, CanInherit, Access); + ok_eq_uint(DaclDefaulted, FALSE); + ParentUsable = UsingParent; + if (!IsDir && !FlagOn(AceFlags, OBJECT_INHERIT_ACE)) + ParentUsable = FALSE; + else if (IsDir && !FlagOn(AceFlags, CONTAINER_INHERIT_ACE) && + (!FlagOn(AceFlags, OBJECT_INHERIT_ACE) || FlagOn(AceFlags, NO_PROPAGATE_INHERIT_ACE))) + ParentUsable = FALSE; + + if (UsingExplicit && (!FlagOn(UsingDefault, 2) || !ParentUsable)) + { + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, AceFlags2, GenericSid2, FlagOn(AceFlags2, INHERIT_ONLY_ACE) ? GenericMask2 : SpecificMask2); + } + else if (ParentUsable) + { + if (IsDir && !FlagOn(AceFlags, NO_PROPAGATE_INHERIT_ACE)) + { + if (FlagOn(AceFlags, CONTAINER_INHERIT_ACE) && (SpecificMask != GenericMask || SpecificSid != GenericSid)) + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SpecificSid, SpecificMask, + ACCESS_ALLOWED_ACE_TYPE, INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE | (AceFlags & OBJECT_INHERIT_ACE), GenericSid, GenericMask); + else + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, (FlagOn(AceFlags, CONTAINER_INHERIT_ACE) ? 0 : INHERIT_ONLY_ACE) | + (AceFlags & (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE)), GenericSid, GenericMask); + } + else + CheckAcl(Dacl, 1, ACCESS_ALLOWED_ACE_TYPE, 0, SpecificSid, SpecificMask); + } + else + { + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + } + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, SeExports->SeAliasAdminsSid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, SeExports->SeLocalSystemSid); + EndTestAssignLoop() + } + } + } + + /* NULL parameters */ + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + KmtStartSeh() + Status = SeAssignSecurity(NULL, + NULL, + NULL, + FALSE, + SubjectContext, + &GenericMapping, + PagedPool); + KmtEndSeh(STATUS_ACCESS_VIOLATION); + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + + SecurityDescriptor = KmtInvalidPointer; + KmtStartSeh() + Status = SeAssignSecurity(NULL, + NULL, + &SecurityDescriptor, + FALSE, + NULL, + &GenericMapping, + PagedPool); + ok_eq_hex(Status, STATUS_NO_TOKEN); + KmtEndSeh(STATUS_SUCCESS); + ok_eq_pointer(SecurityDescriptor, NULL); + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + KmtStartSeh() + Status = SeAssignSecurity(NULL, + NULL, + NULL, + FALSE, + NULL, + &GenericMapping, + PagedPool); + KmtEndSeh(STATUS_ACCESS_VIOLATION); + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + + /* Test with Token == NULL */ + if (1) + { + /* Crash in SeLockSubjectContext while holding a critical region */ + SubjectContext->PrimaryToken = NULL; + KmtStartSeh() + SecurityDescriptor = KmtInvalidPointer; + Status = SeAssignSecurity(NULL, + NULL, + &SecurityDescriptor, + FALSE, + SubjectContext, + &GenericMapping, + PagedPool); + KmtEndSeh(STATUS_ACCESS_VIOLATION) + ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + KeLeaveCriticalRegion(); + ok_eq_pointer(SecurityDescriptor, KmtInvalidPointer); + SubjectContext->PrimaryToken = Token; + } + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + + /* Test with NULL owner in Token */ + if (1) + { + /* Crash after locking the subject context */ + PSID OldOwner; + OldOwner = Token->UserAndGroups[Token->DefaultOwnerIndex].Sid; + Token->UserAndGroups[Token->DefaultOwnerIndex].Sid = NULL; + KmtStartSeh() + SecurityDescriptor = KmtInvalidPointer; + Status = SeAssignSecurity(NULL, + NULL, + &SecurityDescriptor, + FALSE, + SubjectContext, + &GenericMapping, + PagedPool); + KmtEndSeh(STATUS_ACCESS_VIOLATION) + ok_bool_true(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + SeUnlockSubjectContext(SubjectContext); + ok_eq_pointer(SecurityDescriptor, KmtInvalidPointer); + Token->UserAndGroups[Token->DefaultOwnerIndex].Sid = OldOwner; + } + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + + /* Test with NULL group in Token */ + if (1) + { + PSID OldGroup; + OldGroup = Token->PrimaryGroup; + Token->PrimaryGroup = NULL; + KmtStartSeh() + SecurityDescriptor = KmtInvalidPointer; + Status = SeAssignSecurity(NULL, + NULL, + &SecurityDescriptor, + FALSE, + SubjectContext, + &GenericMapping, + PagedPool); + ok_eq_hex(Status, STATUS_INVALID_PRIMARY_GROUP); + ok_eq_pointer(SecurityDescriptor, NULL); + SeDeassignSecurity(&SecurityDescriptor); + KmtEndSeh(STATUS_SUCCESS); + Token->PrimaryGroup = OldGroup; + } + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + + /* Test with NULL DACL in Token */ + if (1) + { + PACL OldDacl; + OldDacl = Token->DefaultDacl; + Token->DefaultDacl = NULL; + KmtStartSeh() + StartTestAssign(NULL, NULL, FALSE, FALSE, FALSE) + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, Token->PrimaryGroup); + EndTestAssign() + KmtEndSeh(STATUS_SUCCESS); + Token->DefaultDacl = OldDacl; + } + ok_bool_false(KeAreApcsDisabled(), "KeAreApcsDisabled returned"); + + /* SEF_DEFAULT_OWNER_FROM_PARENT/SEF_DEFAULT_GROUP_FROM_PARENT */ + SecurityDescriptor = KmtInvalidPointer; + Status = SeAssignSecurityEx(NULL, + NULL, + &SecurityDescriptor, + NULL, + FALSE, + SEF_DEFAULT_OWNER_FROM_PARENT, + SubjectContext, + &GenericMapping, + PagedPool); + ok_eq_hex(Status, STATUS_INVALID_OWNER); + ok_eq_pointer(SecurityDescriptor, NULL); + SeDeassignSecurity(&SecurityDescriptor); + SecurityDescriptor = KmtInvalidPointer; + Status = SeAssignSecurityEx(NULL, + NULL, + &SecurityDescriptor, + NULL, + FALSE, + SEF_DEFAULT_GROUP_FROM_PARENT, + SubjectContext, + &GenericMapping, + PagedPool); + ok_eq_hex(Status, STATUS_INVALID_PRIMARY_GROUP); + ok_eq_pointer(SecurityDescriptor, NULL); + SeDeassignSecurity(&SecurityDescriptor); + SecurityDescriptor = KmtInvalidPointer; + Status = SeAssignSecurityEx(NULL, + NULL, + &SecurityDescriptor, + NULL, + FALSE, + SEF_DEFAULT_OWNER_FROM_PARENT | SEF_DEFAULT_GROUP_FROM_PARENT, + SubjectContext, + &GenericMapping, + PagedPool); + ok_eq_hex(Status, STATUS_INVALID_OWNER); + ok_eq_pointer(SecurityDescriptor, NULL); + SeDeassignSecurity(&SecurityDescriptor); + + /* Quick test whether inheritance for SACLs behaves the same as DACLs */ + Status = RtlSetDaclSecurityDescriptor(&ParentDescriptor, + FALSE, + NULL, + FALSE); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetDaclSecurityDescriptor(&ExplicitDescriptor, + FALSE, + NULL, + FALSE); + ok_eq_hex(Status, STATUS_SUCCESS); + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor, + TRUE, + NULL, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + NULL, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + + TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE) + TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE) + StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE) + ok_eq_uint(DaclDefaulted, FALSE); + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + ok_eq_uint(SaclDefaulted, FALSE); + ok_eq_pointer(Sacl, NULL); + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, Token->PrimaryGroup); + EndTestAssign() + } + + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor, + TRUE, + &EmptyAcl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + &EmptyAcl, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + + TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE) + TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE) + StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE) + ok_eq_uint(DaclDefaulted, FALSE); + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + ok_eq_uint(SaclDefaulted, FALSE); + CheckAcl(Sacl, 0); + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, Token->PrimaryGroup); + EndTestAssign() + } + + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlxAddAuditAccessAceEx(Acl, ACL_REVISION, 0, READ_CONTROL, SeExports->SeWorldSid, TRUE, TRUE); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + + TestAssignExpectDefault(&ParentDescriptor, NULL, FALSE) + TestAssignExpectDefault(&ParentDescriptor, NULL, TRUE) + StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE) + ok_eq_uint(DaclDefaulted, FALSE); + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + ok_eq_uint(SaclDefaulted, FALSE); + CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, SeExports->SeWorldSid, READ_CONTROL); + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, Token->PrimaryGroup); + EndTestAssign() + } + + for (UsingDefault = 0; UsingDefault <= 3; UsingDefault++) + { + Status = RtlCreateAcl(Acl, AclSize, ACL_REVISION); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlxAddAuditAccessAceEx(Acl, ACL_REVISION, OBJECT_INHERIT_ACE, READ_CONTROL, SeExports->SeCreatorOwnerSid, TRUE, TRUE); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetSaclSecurityDescriptor(&ParentDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 1)); + ok_eq_hex(Status, STATUS_SUCCESS); + Status = RtlSetSaclSecurityDescriptor(&ExplicitDescriptor, + TRUE, + Acl, + BooleanFlagOn(UsingDefault, 2)); + ok_eq_hex(Status, STATUS_SUCCESS); + + StartTestAssign(&ParentDescriptor, NULL, FALSE, TRUE, TRUE) + ok_eq_uint(DaclDefaulted, FALSE); + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + ok_eq_uint(SaclDefaulted, FALSE); + CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid, READ_CONTROL); + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, Token->PrimaryGroup); + EndTestAssign() + StartTestAssign(NULL, &ExplicitDescriptor, FALSE, TRUE, TRUE) + ok_eq_uint(DaclDefaulted, FALSE); + CheckAcl(Dacl, 2, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, STANDARD_RIGHTS_ALL | 0x800F, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, STANDARD_RIGHTS_READ | 0x0005); + ok_eq_uint(SaclDefaulted, FALSE); + CheckAcl(Sacl, 1, SYSTEM_AUDIT_ACE_TYPE, OBJECT_INHERIT_ACE | SUCCESSFUL_ACCESS_ACE_FLAG | FAILED_ACCESS_ACE_FLAG, SeExports->SeCreatorOwnerSid, READ_CONTROL); + ok_eq_uint(OwnerDefaulted, FALSE); + CheckSid(Owner, NO_SIZE, Token->UserAndGroups[Token->DefaultOwnerIndex].Sid); + ok_eq_uint(GroupDefaulted, FALSE); + CheckSid(Group, NO_SIZE, Token->PrimaryGroup); + EndTestAssign() + } + + /* TODO: Test duplicate ACEs */ + /* TODO: Test INHERITED_ACE flag */ + /* TODO: Test invalid ACE flags */ + /* TODO: Test more AutoInheritFlags values */ + + ExFreePoolWithTag(Acl2, 'ASmK'); + ExFreePoolWithTag(Acl, 'ASmK'); +} + +static +VOID +NTAPI +SystemThread( + _In_ PVOID Context) +{ + SECURITY_SUBJECT_CONTEXT SubjectContext; + ok_eq_pointer(Context, NULL); + + SeCaptureSubjectContext(&SubjectContext); + TestSeAssignSecurity(&SubjectContext); + /* TODO: Test SeSetSecurityDescrptorInfo[Ex] */ + SeReleaseSubjectContext(&SubjectContext); +} + +static +VOID +TestObRootSecurity(VOID) +{ + NTSTATUS Status; + UNICODE_STRING ObjectPath = RTL_CONSTANT_STRING(L"\\"); + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE Handle; + PVOID RootDirectory; + PSECURITY_DESCRIPTOR SecurityDescriptor; + BOOLEAN MemoryAllocated; + PACL Acl; + BOOLEAN Present; + BOOLEAN Defaulted; + + InitializeObjectAttributes(&ObjectAttributes, + &ObjectPath, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + Status = ZwOpenDirectoryObject(&Handle, + 0, + &ObjectAttributes); + ok_eq_hex(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "No handle\n")) + return; + Status = ObReferenceObjectByHandle(Handle, + 0, + NULL, + KernelMode, + &RootDirectory, + NULL); + ObCloseHandle(Handle, KernelMode); + ok_eq_hex(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "No object\n")) + return; + Status = ObGetObjectSecurity(RootDirectory, + &SecurityDescriptor, + &MemoryAllocated); + ObDereferenceObject(RootDirectory); + ok_eq_hex(Status, STATUS_SUCCESS); + if (skip(NT_SUCCESS(Status), "No security\n")) + return; + Status = RtlGetDaclSecurityDescriptor(SecurityDescriptor, + &Present, + &Acl, + &Defaulted); + ok_eq_hex(Status, STATUS_SUCCESS); + ok_eq_uint(Present, TRUE); + if (!skip(NT_SUCCESS(Status) && Present, "No DACL\n")) + { + ok_eq_uint(Defaulted, FALSE); + CheckAcl(Acl, 4, ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeWorldSid, STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeLocalSystemSid, DIRECTORY_ALL_ACCESS, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeAliasAdminsSid, DIRECTORY_ALL_ACCESS, + ACCESS_ALLOWED_ACE_TYPE, 0, SeExports->SeRestrictedSid, STANDARD_RIGHTS_READ | DIRECTORY_TRAVERSE | DIRECTORY_QUERY); + } + Status = RtlGetSaclSecurityDescriptor(SecurityDescriptor, + &Present, + &Acl, + &Defaulted); + ok_eq_hex(Status, STATUS_SUCCESS); + ok_eq_uint(Present, FALSE); + ObReleaseObjectSecurity(SecurityDescriptor, MemoryAllocated); +} + +START_TEST(SeInheritance) +{ + PKTHREAD Thread; + + TestObRootSecurity(); + Thread = KmtStartThread(SystemThread, NULL); + KmtFinishThread(Thread, NULL); +} Propchange: trunk/rostests/kmtests/ntos_se/SeInheritance.c ------------------------------------------------------------------------------ svn:eol-style = native Added: trunk/rostests/kmtests/ntos_se/se.h URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/ntos_se/se.h?rev=…
============================================================================== --- trunk/rostests/kmtests/ntos_se/se.h (added) +++ trunk/rostests/kmtests/ntos_se/se.h [iso-8859-1] Tue Nov 4 22:42:15 2014 @@ -0,0 +1,63 @@ +/* + * PROJECT: ReactOS kernel-mode tests + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory + * PURPOSE: Kernel-Mode Test Suite Se helper declarations + * PROGRAMMER: Thomas Faber <thomas.faber(a)reactos.org> + */ + +#ifndef _KMTEST_SE_H_ +#define _KMTEST_SE_H_ + +/* FIXME: belongs in ntifs.h or something */ +#define SEF_DACL_AUTO_INHERIT 1 +#define SEF_SACL_AUTO_INHERIT 2 +#define SEF_DEFAULT_DESCRIPTOR_FOR_OBJECT 4 +#define SEF_AVOID_PRIVILEGE_CHECK 8 +#define SEF_AVOID_OWNER_CHECK 16 +#define SEF_DEFAULT_OWNER_FROM_PARENT 32 +#define SEF_DEFAULT_GROUP_FROM_PARENT 64 +#define SEF_MACL_NO_WRITE_UP 256 +#define SEF_MACL_NO_READ_UP 512 +#define SEF_MACL_NO_EXECUTE_UP 1024 +#define SEF_AI_USE_EXTRA_PARAMS 2048 +#define SEF_AVOID_OWNER_RESTRICTION 4096 +#define SEF_MACL_VALID_FLAGS (SEF_MACL_NO_WRITE_UP | SEF_MACL_NO_READ_UP | SEF_MACL_NO_EXECUTE_UP) + +NTSTATUS +RtlxAddAuditAccessAceEx( + _Inout_ PACL Acl, + _In_ ULONG Revision, + _In_ ULONG Flags, + _In_ ACCESS_MASK AccessMask, + _In_ PSID Sid, + _In_ BOOLEAN Success, + _In_ BOOLEAN Failure); + +#define NO_SIZE ((ULONG)-1) + +#define CheckSid(Sid, SidSize, ExpectedSid) CheckSid_(Sid, SidSize, ExpectedSid, __FILE__, __LINE__) +#define CheckSid_(Sid, SidSize, ExpectedSid, file, line) CheckSid__(Sid, SidSize, ExpectedSid, file ":" KMT_STRINGIZE(line)) +VOID +CheckSid__( + _In_ PSID Sid, + _In_ ULONG SidSize, + _In_ PISID ExpectedSid, + _In_ PCSTR FileAndLine); + +VOID +VCheckAcl__( + _In_ PACL Acl, + _In_ ULONG AceCount, + _In_ PCSTR FileAndLine, + _In_ va_list Arguments); + +#define CheckAcl(Acl, AceCount, ...) CheckAcl_(Acl, AceCount, __FILE__, __LINE__, ##__VA_ARGS__) +#define CheckAcl_(Acl, AceCount, file, line, ...) CheckAcl__(Acl, AceCount, file ":" KMT_STRINGIZE(line), ##__VA_ARGS__) +VOID +CheckAcl__( + _In_ PACL Acl, + _In_ ULONG AceCount, + _In_ PCSTR FileAndLine, + ...); + +#endif /* !defined _KMTEST_SE_H_ */ Propchange: trunk/rostests/kmtests/ntos_se/se.h ------------------------------------------------------------------------------ svn:eol-style = native
10 years, 1 month
1
0
0
0
[pschweitzer] 65257: [NTFS] Actually, we know how to read non resident attributes, so read a non resident attribute list if found.
by pschweitzer@svn.reactos.org
Author: pschweitzer Date: Tue Nov 4 21:16:14 2014 New Revision: 65257 URL:
http://svn.reactos.org/svn/reactos?rev=65257&view=rev
Log: [NTFS] Actually, we know how to read non resident attributes, so read a non resident attribute list if found. Modified: trunk/reactos/drivers/filesystems/ntfs/mft.c Modified: trunk/reactos/drivers/filesystems/ntfs/mft.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/filesystems/ntfs/m…
============================================================================== --- trunk/reactos/drivers/filesystems/ntfs/mft.c [iso-8859-1] (original) +++ trunk/reactos/drivers/filesystems/ntfs/mft.c [iso-8859-1] Tue Nov 4 21:16:14 2014 @@ -105,44 +105,35 @@ PNTFS_ATTR_RECORD ListAttrRecord; PNTFS_ATTR_RECORD ListAttrRecordEnd; - // Do not handle non-resident yet - if (AttrRecord->IsNonResident) - { - UNIMPLEMENTED; + ListContext = PrepareAttributeContext(AttrRecord); + + ListSize = AttributeDataLength(&ListContext->Record); + if(ListSize <= 0xFFFFFFFF) + ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS); + else + ListBuffer = NULL; + + if(!ListBuffer) + { + DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize); continue; } - else - { - ListContext = PrepareAttributeContext(AttrRecord); - - ListSize = AttributeDataLength(&ListContext->Record); - if(ListSize <= 0xFFFFFFFF) - ListBuffer = ExAllocatePoolWithTag(NonPagedPool, (ULONG)ListSize, TAG_NTFS); - else - ListBuffer = NULL; - - if(!ListBuffer) + + ListAttrRecord = (PNTFS_ATTR_RECORD)ListBuffer; + ListAttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)ListBuffer + ListSize); + + if (ReadAttribute(Vcb, ListContext, 0, ListBuffer, (ULONG)ListSize) == ListSize) + { + Context = FindAttributeHelper(Vcb, ListAttrRecord, ListAttrRecordEnd, + Type, Name, NameLength); + + ReleaseAttributeContext(ListContext); + ExFreePoolWithTag(ListBuffer, TAG_NTFS); + + if (Context != NULL) { - DPRINT("Failed to allocate memory: %x\n", (ULONG)ListSize); - continue; - } - - ListAttrRecord = (PNTFS_ATTR_RECORD)ListBuffer; - ListAttrRecordEnd = (PNTFS_ATTR_RECORD)((PCHAR)ListBuffer + ListSize); - - if (ReadAttribute(Vcb, ListContext, 0, ListBuffer, (ULONG)ListSize) == ListSize) - { - Context = FindAttributeHelper(Vcb, ListAttrRecord, ListAttrRecordEnd, - Type, Name, NameLength); - - ReleaseAttributeContext(ListContext); - ExFreePoolWithTag(ListBuffer, TAG_NTFS); - - if (Context != NULL) - { - DPRINT("Found context = %p\n", Context); - return Context; - } + if (AttrRecord->IsNonResident) DPRINT("Found context = %p\n", Context); + return Context; } } }
10 years, 1 month
1
0
0
0
[tfaber] 65256: [KMTESTS] - Move out definitions for user/kernel test utility functions into their own header (still not pretty, but at least the one header won't get as huge - Make KmtStartThread/...
by tfaber@svn.reactos.org
Author: tfaber Date: Tue Nov 4 20:55:16 2014 New Revision: 65256 URL:
http://svn.reactos.org/svn/reactos?rev=65256&view=rev
Log: [KMTESTS] - Move out definitions for user/kernel test utility functions into their own header (still not pretty, but at least the one header won't get as huge - Make KmtStartThread/KmtFinishThread available to all tests Added: trunk/rostests/kmtests/include/kmt_test_kernel.h - copied, changed from r65197, trunk/rostests/kmtests/include/kmt_test.h trunk/rostests/kmtests/include/kmt_test_user.h - copied, changed from r65197, trunk/rostests/kmtests/include/kmt_test.h Modified: trunk/rostests/kmtests/include/kmt_test.h trunk/rostests/kmtests/npfs/NpfsHelpers.c trunk/rostests/kmtests/npfs/npfs.h Modified: trunk/rostests/kmtests/include/kmt_test.h URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/include/kmt_test.…
============================================================================== --- trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] (original) +++ trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] Tue Nov 4 20:55:16 2014 @@ -132,6 +132,8 @@ BOOLEAN KmtAreInterruptsEnabled(VOID); ULONG KmtGetPoolTag(PVOID Memory); USHORT KmtGetPoolType(PVOID Memory); +PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL); +VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL); #elif defined KMT_USER_MODE DWORD KmtRunKernelTest(IN PCSTR TestName); @@ -242,143 +244,9 @@ #if defined KMT_DEFINE_TEST_FUNCTIONS #if defined KMT_KERNEL_MODE -BOOLEAN KmtIsCheckedBuild; -BOOLEAN KmtIsMultiProcessorBuild; -PCSTR KmtMajorFunctionNames[] = -{ - "Create", - "CreateNamedPipe", - "Close", - "Read", - "Write", - "QueryInformation", - "SetInformation", - "QueryEa", - "SetEa", - "FlushBuffers", - "QueryVolumeInformation", - "SetVolumeInformation", - "DirectoryControl", - "FileSystemControl", - "DeviceControl", - "InternalDeviceControl/Scsi", - "Shutdown", - "LockControl", - "Cleanup", - "CreateMailslot", - "QuerySecurity", - "SetSecurity", - "Power", - "SystemControl", - "DeviceChange", - "QueryQuota", - "SetQuota", - "Pnp/PnpPower" -}; - -VOID KmtSetIrql(IN KIRQL NewIrql) -{ - KIRQL Irql = KeGetCurrentIrql(); - if (Irql > NewIrql) - KeLowerIrql(NewIrql); - else if (Irql < NewIrql) - KeRaiseIrql(NewIrql, &Irql); -} - -BOOLEAN KmtAreInterruptsEnabled(VOID) -{ - return (__readeflags() & (1 << 9)) != 0; -} - -typedef struct _POOL_HEADER -{ - union - { - struct - { -#ifdef _M_AMD64 - USHORT PreviousSize:8; - USHORT PoolIndex:8; - USHORT BlockSize:8; - USHORT PoolType:8; -#else - USHORT PreviousSize:9; - USHORT PoolIndex:7; - USHORT BlockSize:9; - USHORT PoolType:7; -#endif - }; - ULONG Ulong1; - }; -#ifdef _M_AMD64 - ULONG PoolTag; -#endif - union - { -#ifdef _M_AMD64 - PEPROCESS ProcessBilled; -#else - ULONG PoolTag; -#endif - struct - { - USHORT AllocatorBackTraceIndex; - USHORT PoolTagHash; - }; - }; -} POOL_HEADER, *PPOOL_HEADER; - -ULONG KmtGetPoolTag(PVOID Memory) -{ - PPOOL_HEADER Header; - - /* it's not so easy for allocations of PAGE_SIZE */ - if (((ULONG_PTR)Memory & (PAGE_SIZE - 1)) == 0) - return 'TooL'; - - Header = Memory; - Header--; - - return Header->PoolTag; -} - -USHORT KmtGetPoolType(PVOID Memory) -{ - PPOOL_HEADER Header; - - /* it's not so easy for allocations of PAGE_SIZE */ - if (((ULONG_PTR)Memory & (PAGE_SIZE - 1)) == 0) - return 0; - - Header = Memory; - Header--; - - return Header->PoolType; -} - -INT __cdecl KmtVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); +#include "kmt_test_kernel.h" #elif defined KMT_USER_MODE -static PKMT_RESULTBUFFER KmtAllocateResultBuffer(SIZE_T ResultBufferSize) -{ - PKMT_RESULTBUFFER Buffer = HeapAlloc(GetProcessHeap(), 0, ResultBufferSize); - if (!Buffer) - return NULL; - - Buffer->Successes = 0; - Buffer->Failures = 0; - Buffer->Skipped = 0; - Buffer->LogBufferLength = 0; - Buffer->LogBufferMaxLength = (ULONG)ResultBufferSize - FIELD_OFFSET(KMT_RESULTBUFFER, LogBuffer); - - return Buffer; -} - -static VOID KmtFreeResultBuffer(PKMT_RESULTBUFFER Buffer) -{ - HeapFree(GetProcessHeap(), 0, Buffer); -} - -#define KmtVSNPrintF vsnprintf +#include "kmt_test_user.h" #endif /* defined KMT_USER_MODE */ PKMT_RESULTBUFFER ResultBuffer = NULL; Copied: trunk/rostests/kmtests/include/kmt_test_kernel.h (from r65197, trunk/rostests/kmtests/include/kmt_test.h) URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/include/kmt_test_…
============================================================================== --- trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] (original) +++ trunk/rostests/kmtests/include/kmt_test_kernel.h [iso-8859-1] Tue Nov 4 20:55:16 2014 @@ -1,247 +1,17 @@ /* * PROJECT: ReactOS kernel-mode tests - * LICENSE: GPLv2+ - See COPYING in the top level directory + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory * PURPOSE: Kernel-Mode Test Suite test framework declarations * PROGRAMMER: Thomas Faber <thomas.faber(a)reactos.org> */ -/* Inspired by Wine C unit tests, Copyright (C) 2002 Alexandre Julliard - * Inspired by ReactOS kernel-mode regression tests, - * Copyright (C) Aleksey Bragin, Filip Navara - */ +#ifndef _KMTEST_TEST_KERNEL_H_ +#define _KMTEST_TEST_KERNEL_H_ -#ifndef _KMTEST_TEST_H_ -#define _KMTEST_TEST_H_ +#if !defined _KMTEST_TEST_H_ +#error include kmt_test.h instead of including kmt_test_kernel.h +#endif /* !defined _KMTEST_TEST_H_ */ -#include <kmt_platform.h> - -typedef VOID KMT_TESTFUNC(VOID); -typedef KMT_TESTFUNC *PKMT_TESTFUNC; - -typedef struct -{ - const char *TestName; - KMT_TESTFUNC *TestFunction; -} KMT_TEST, *PKMT_TEST; - -typedef const KMT_TEST CKMT_TEST, *PCKMT_TEST; - -extern const KMT_TEST TestList[]; - -typedef struct -{ - volatile LONG Successes; - volatile LONG Failures; - volatile LONG Skipped; - volatile LONG LogBufferLength; - LONG LogBufferMaxLength; - CHAR LogBuffer[ANYSIZE_ARRAY]; -} KMT_RESULTBUFFER, *PKMT_RESULTBUFFER; - -#ifndef KMT_STANDALONE_DRIVER - -/* usermode call-back mechanism */ - -/* list of supported operations */ -typedef enum _KMT_CALLBACK_INFORMATION_CLASS -{ - QueryVirtualMemory -} KMT_CALLBACK_INFORMATION_CLASS, *PKMT_CALLBACK_INFORMATION_CLASS; - -/* TODO: "response" is a little generic */ -typedef union _KMT_RESPONSE -{ - MEMORY_BASIC_INFORMATION MemInfo; -} KMT_RESPONSE, *PKMT_RESPONSE; - -/* this struct is sent from driver to usermode */ -typedef struct _KMT_CALLBACK_REQUEST_PACKET -{ - ULONG RequestId; - KMT_CALLBACK_INFORMATION_CLASS OperationClass; - PVOID Parameters; -} KMT_CALLBACK_REQUEST_PACKET, *PKMT_CALLBACK_REQUEST_PACKET; - -PKMT_RESPONSE KmtUserModeCallback(KMT_CALLBACK_INFORMATION_CLASS Operation, PVOID Parameters); -VOID KmtFreeCallbackResponse(PKMT_RESPONSE Response); - -//macro to simplify using the mechanism -#define Test_NtQueryVirtualMemory(BaseAddress, Size, AllocationType, ProtectionType) \ - do { \ - PKMT_RESPONSE NtQueryTest = KmtUserModeCallback(QueryVirtualMemory, BaseAddress); \ - if (NtQueryTest != NULL) \ - { \ - ok_eq_hex(NtQueryTest->MemInfo.Protect, ProtectionType); \ - ok_eq_hex(NtQueryTest->MemInfo.State, AllocationType); \ - ok_eq_size(NtQueryTest->MemInfo.RegionSize, Size); \ - KmtFreeCallbackResponse(NtQueryTest); \ - } \ - } while (0) \ - -#endif - -#ifdef KMT_STANDALONE_DRIVER -#define KMT_KERNEL_MODE - -typedef NTSTATUS (KMT_IRP_HANDLER)( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PIO_STACK_LOCATION IoStackLocation); -typedef KMT_IRP_HANDLER *PKMT_IRP_HANDLER; - -NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler); -NTSTATUS KmtUnregisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler); - -typedef NTSTATUS (KMT_MESSAGE_HANDLER)( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG ControlCode, - IN PVOID Buffer OPTIONAL, - IN SIZE_T InLength, - IN OUT PSIZE_T OutLength); -typedef KMT_MESSAGE_HANDLER *PKMT_MESSAGE_HANDLER; - -NTSTATUS KmtRegisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler); -NTSTATUS KmtUnregisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler); - -typedef enum -{ - TESTENTRY_NO_CREATE_DEVICE = 1, - TESTENTRY_NO_REGISTER_DISPATCH = 2, - TESTENTRY_NO_REGISTER_UNLOAD = 4, - TESTENTRY_NO_EXCLUSIVE_DEVICE = 8, -} KMT_TESTENTRY_FLAGS; - -NTSTATUS TestEntry(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryPath, OUT PCWSTR *DeviceName, IN OUT INT *Flags); -VOID TestUnload(IN PDRIVER_OBJECT DriverObject); -#endif /* defined KMT_STANDALONE_DRIVER */ - -#ifdef KMT_KERNEL_MODE -/* Device Extension layout */ -typedef struct -{ - PKMT_RESULTBUFFER ResultBuffer; - PMDL Mdl; -} KMT_DEVICE_EXTENSION, *PKMT_DEVICE_EXTENSION; - -extern BOOLEAN KmtIsCheckedBuild; -extern BOOLEAN KmtIsMultiProcessorBuild; -extern PCSTR KmtMajorFunctionNames[]; -extern PDRIVER_OBJECT KmtDriverObject; - -VOID KmtSetIrql(IN KIRQL NewIrql); -BOOLEAN KmtAreInterruptsEnabled(VOID); -ULONG KmtGetPoolTag(PVOID Memory); -USHORT KmtGetPoolType(PVOID Memory); -#elif defined KMT_USER_MODE -DWORD KmtRunKernelTest(IN PCSTR TestName); - -VOID KmtLoadDriver(IN PCWSTR ServiceName, IN BOOLEAN RestartIfRunning); -VOID KmtUnloadDriver(VOID); -VOID KmtOpenDriver(VOID); -VOID KmtCloseDriver(VOID); - -DWORD KmtSendToDriver(IN DWORD ControlCode); -DWORD KmtSendStringToDriver(IN DWORD ControlCode, IN PCSTR String); -DWORD KmtSendWStringToDriver(IN DWORD ControlCode, IN PCWSTR String); -DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer OPTIONAL, IN DWORD InLength, IN OUT PDWORD OutLength); -#else /* if !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */ -#error either KMT_KERNEL_MODE or KMT_USER_MODE must be defined -#endif /* !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */ - -extern PKMT_RESULTBUFFER ResultBuffer; - -#ifdef __GNUC__ -/* TODO: GCC doesn't understand %wZ :( */ -#define KMT_FORMAT(type, fmt, first) /*__attribute__((__format__(type, fmt, first)))*/ -#elif !defined __GNUC__ -#define KMT_FORMAT(type, fmt, first) -#endif /* !defined __GNUC__ */ - -#define START_TEST(name) VOID Test_##name(VOID) - -#ifndef KMT_STRINGIZE -#define KMT_STRINGIZE(x) #x -#endif /* !defined KMT_STRINGIZE */ -#define ok(test, ...) ok_(test, __FILE__, __LINE__, __VA_ARGS__) -#define trace(...) trace_( __FILE__, __LINE__, __VA_ARGS__) -#define skip(test, ...) skip_(test, __FILE__, __LINE__, __VA_ARGS__) - -#define ok_(test, file, line, ...) KmtOk(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__) -#define trace_(file, line, ...) KmtTrace( file ":" KMT_STRINGIZE(line), __VA_ARGS__) -#define skip_(test, file, line, ...) KmtSkip(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__) - -BOOLEAN KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); -BOOLEAN KmtOk(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 3, 4); -VOID KmtVTrace(PCSTR FileAndLine, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 2, 0); -VOID KmtTrace(PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 2, 3); -BOOLEAN KmtVSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); -BOOLEAN KmtSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 3, 4); -PVOID KmtAllocateGuarded(SIZE_T SizeRequested); -VOID KmtFreeGuarded(PVOID Pointer); - -#ifdef KMT_KERNEL_MODE -#define ok_irql(irql) ok(KeGetCurrentIrql() == irql, "IRQL is %d, expected %d\n", KeGetCurrentIrql(), irql) -#endif /* defined KMT_KERNEL_MODE */ -#define ok_eq_print(value, expected, spec) ok((value) == (expected), #value " = " spec ", expected " spec "\n", value, expected) -#define ok_eq_pointer(value, expected) ok_eq_print(value, expected, "%p") -#define ok_eq_int(value, expected) ok_eq_print(value, expected, "%d") -#define ok_eq_uint(value, expected) ok_eq_print(value, expected, "%u") -#define ok_eq_long(value, expected) ok_eq_print(value, expected, "%ld") -#define ok_eq_ulong(value, expected) ok_eq_print(value, expected, "%lu") -#define ok_eq_longlong(value, expected) ok_eq_print(value, expected, "%I64d") -#define ok_eq_ulonglong(value, expected) ok_eq_print(value, expected, "%I64u") -#define ok_eq_char(value, expected) ok_eq_print(value, expected, "%c") -#define ok_eq_wchar(value, expected) ok_eq_print(value, expected, "%C") -#ifndef _WIN64 -#define ok_eq_size(value, expected) ok_eq_print(value, (SIZE_T)(expected), "%lu") -#define ok_eq_longptr(value, expected) ok_eq_print(value, (LONG_PTR)(expected), "%ld") -#define ok_eq_ulongptr(value, expected) ok_eq_print(value, (ULONG_PTR)(expected), "%lu") -#elif defined _WIN64 -#define ok_eq_size(value, expected) ok_eq_print(value, (SIZE_T)(expected), "%I64u") -#define ok_eq_longptr(value, expected) ok_eq_print(value, (LONG_PTR)(expected), "%I64d") -#define ok_eq_ulongptr(value, expected) ok_eq_print(value, (ULONG_PTR)(expected), "%I64u") -#endif /* defined _WIN64 */ -#define ok_eq_hex(value, expected) ok_eq_print(value, expected, "0x%08lx") -#define ok_bool_true(value, desc) ok((value) == TRUE, desc " FALSE, expected TRUE\n") -#define ok_bool_false(value, desc) ok((value) == FALSE, desc " TRUE, expected FALSE\n") -#define ok_eq_bool(value, expected) ok((value) == (expected), #value " = %s, expected %s\n", \ - (value) ? "TRUE" : "FALSE", \ - (expected) ? "TRUE" : "FALSE") -#define ok_eq_str(value, expected) ok(!strcmp(value, expected), #value " = \"%s\", expected \"%s\"\n", value, expected) -#define ok_eq_wstr(value, expected) ok(!wcscmp(value, expected), #value " = \"%ls\", expected \"%ls\"\n", value, expected) -#define ok_eq_tag(value, expected) ok_eq_print(value, expected, "0x%08lx") - -#define KMT_MAKE_CODE(ControlCode) CTL_CODE(FILE_DEVICE_UNKNOWN, \ - 0xC00 + (ControlCode), \ - METHOD_BUFFERED, \ - FILE_ANY_ACCESS) - -#define MICROSECOND 10 -#define MILLISECOND (1000 * MICROSECOND) -#define SECOND (1000 * MILLISECOND) - -/* See apitests/include/apitest.h */ -#define KmtInvalidPointer ((PVOID)0x5555555555555555ULL) - -#define KmtStartSeh() \ -{ \ - NTSTATUS ExceptionStatus = STATUS_SUCCESS; \ - _SEH2_TRY \ - { - -#define KmtEndSeh(ExpectedStatus) \ - } \ - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \ - { \ - ExceptionStatus = _SEH2_GetExceptionCode(); \ - } \ - _SEH2_END; \ - ok_eq_hex(ExceptionStatus, (ExpectedStatus)); \ -} - -#if defined KMT_DEFINE_TEST_FUNCTIONS - -#if defined KMT_KERNEL_MODE BOOLEAN KmtIsCheckedBuild; BOOLEAN KmtIsMultiProcessorBuild; PCSTR KmtMajorFunctionNames[] = @@ -356,240 +126,59 @@ return Header->PoolType; } -INT __cdecl KmtVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); -#elif defined KMT_USER_MODE -static PKMT_RESULTBUFFER KmtAllocateResultBuffer(SIZE_T ResultBufferSize) +PKTHREAD KmtStartThread(IN PKSTART_ROUTINE StartRoutine, IN PVOID StartContext OPTIONAL) { - PKMT_RESULTBUFFER Buffer = HeapAlloc(GetProcessHeap(), 0, ResultBufferSize); - if (!Buffer) - return NULL; + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE ThreadHandle; + PVOID ThreadObject = NULL; - Buffer->Successes = 0; - Buffer->Failures = 0; - Buffer->Skipped = 0; - Buffer->LogBufferLength = 0; - Buffer->LogBufferMaxLength = (ULONG)ResultBufferSize - FIELD_OFFSET(KMT_RESULTBUFFER, LogBuffer); - - return Buffer; + InitializeObjectAttributes(&ObjectAttributes, + NULL, + OBJ_KERNEL_HANDLE, + NULL, + NULL); + ThreadHandle = INVALID_HANDLE_VALUE; + Status = PsCreateSystemThread(&ThreadHandle, + SYNCHRONIZE, + &ObjectAttributes, + NULL, + NULL, + StartRoutine, + StartContext); + ok_eq_hex(Status, STATUS_SUCCESS); + if (!skip(NT_SUCCESS(Status) && ThreadHandle != NULL && ThreadHandle != INVALID_HANDLE_VALUE, "No thread\n")) + { + Status = ObReferenceObjectByHandle(ThreadHandle, + SYNCHRONIZE, + *PsThreadType, + KernelMode, + &ThreadObject, + NULL); + ok_eq_hex(Status, STATUS_SUCCESS); + ObCloseHandle(ThreadHandle, KernelMode); + } + return ThreadObject; } -static VOID KmtFreeResultBuffer(PKMT_RESULTBUFFER Buffer) +VOID KmtFinishThread(IN PKTHREAD Thread OPTIONAL, IN PKEVENT Event OPTIONAL) { - HeapFree(GetProcessHeap(), 0, Buffer); + NTSTATUS Status; + + if (skip(Thread != NULL, "No thread\n")) + return; + + if (Event) + KeSetEvent(Event, IO_NO_INCREMENT, TRUE); + Status = KeWaitForSingleObject(Thread, + Executive, + KernelMode, + FALSE, + NULL); + ok_eq_hex(Status, STATUS_SUCCESS); + ObDereferenceObject(Thread); } -#define KmtVSNPrintF vsnprintf -#endif /* defined KMT_USER_MODE */ +INT __cdecl KmtVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); -PKMT_RESULTBUFFER ResultBuffer = NULL; - -static VOID KmtAddToLogBuffer(PKMT_RESULTBUFFER Buffer, PCSTR String, SIZE_T Length) -{ - LONG OldLength; - LONG NewLength; - - if (!Buffer) - return; - - do - { - OldLength = Buffer->LogBufferLength; - NewLength = OldLength + (ULONG)Length; - if (NewLength > Buffer->LogBufferMaxLength) - return; - } while (InterlockedCompareExchange(&Buffer->LogBufferLength, NewLength, OldLength) != OldLength); - - memcpy(&Buffer->LogBuffer[OldLength], String, Length); -} - -KMT_FORMAT(ms_printf, 5, 0) -static SIZE_T KmtXVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR FileAndLine, PCSTR Prepend, PCSTR Format, va_list Arguments) -{ - SIZE_T BufferLength = 0; - SIZE_T Length; - - if (FileAndLine) - { - PCSTR Slash; - Slash = strrchr(FileAndLine, '\\'); - if (Slash) - FileAndLine = Slash + 1; - Slash = strrchr(FileAndLine, '/'); - if (Slash) - FileAndLine = Slash + 1; - - Length = min(BufferMaxLength, strlen(FileAndLine)); - memcpy(Buffer, FileAndLine, Length); - Buffer += Length; - BufferLength += Length; - BufferMaxLength -= Length; - } - if (Prepend) - { - Length = min(BufferMaxLength, strlen(Prepend)); - memcpy(Buffer, Prepend, Length); - Buffer += Length; - BufferLength += Length; - BufferMaxLength -= Length; - } - if (Format) - { - Length = KmtVSNPrintF(Buffer, BufferMaxLength, Format, Arguments); - /* vsnprintf can return more than maxLength, we don't want to do that */ - BufferLength += min(Length, BufferMaxLength); - } - return BufferLength; -} - -KMT_FORMAT(ms_printf, 5, 6) -static SIZE_T KmtXSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR FileAndLine, PCSTR Prepend, PCSTR Format, ...) -{ - SIZE_T BufferLength; - va_list Arguments; - va_start(Arguments, Format); - BufferLength = KmtXVSNPrintF(Buffer, BufferMaxLength, FileAndLine, Prepend, Format, Arguments); - va_end(Arguments); - return BufferLength; -} - -VOID KmtFinishTest(PCSTR TestName) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - if (!ResultBuffer) - return; - - MessageLength = KmtXSNPrintF(MessageBuffer, sizeof MessageBuffer, NULL, NULL, - "%s: %ld tests executed (0 marked as todo, %ld failures), %ld skipped.\n", - TestName, - ResultBuffer->Successes + ResultBuffer->Failures, - ResultBuffer->Failures, - ResultBuffer->Skipped); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); -} - -BOOLEAN KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - if (!ResultBuffer) - return Condition != 0; - - if (Condition) - { - InterlockedIncrement(&ResultBuffer->Successes); - - if (0/*KmtReportSuccess*/) - { - MessageLength = KmtXSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Test succeeded\n", NULL); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); - } - } - else - { - InterlockedIncrement(&ResultBuffer->Failures); - MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Test failed: ", Format, Arguments); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); - } - - return Condition != 0; -} - -BOOLEAN KmtOk(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) -{ - BOOLEAN Ret; - va_list Arguments; - va_start(Arguments, Format); - Ret = KmtVOk(Condition, FileAndLine, Format, Arguments); - va_end(Arguments); - return Ret; -} - -VOID KmtVTrace(PCSTR FileAndLine, PCSTR Format, va_list Arguments) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": ", Format, Arguments); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); -} - -VOID KmtTrace(PCSTR FileAndLine, PCSTR Format, ...) -{ - va_list Arguments; - va_start(Arguments, Format); - KmtVTrace(FileAndLine, Format, Arguments); - va_end(Arguments); -} - -BOOLEAN KmtVSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - if (!ResultBuffer) - return !Condition; - - if (!Condition) - { - InterlockedIncrement(&ResultBuffer->Skipped); - MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Tests skipped: ", Format, Arguments); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); - } - - return !Condition; -} - -BOOLEAN KmtSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) -{ - BOOLEAN Ret; - va_list Arguments; - va_start(Arguments, Format); - Ret = KmtVSkip(Condition, FileAndLine, Format, Arguments); - va_end(Arguments); - return Ret; -} - -PVOID KmtAllocateGuarded(SIZE_T SizeRequested) -{ - NTSTATUS Status; - SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); - PVOID VirtualMemory = NULL; - PCHAR StartOfBuffer; - - Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); - - if (!NT_SUCCESS(Status)) - return NULL; - - Size -= PAGE_SIZE; - Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - Size = 0; - Status = ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); - ok_eq_hex(Status, STATUS_SUCCESS); - return NULL; - } - - StartOfBuffer = VirtualMemory; - StartOfBuffer += Size - SizeRequested; - - return StartOfBuffer; -} - -VOID KmtFreeGuarded(PVOID Pointer) -{ - NTSTATUS Status; - PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); - SIZE_T Size = 0; - - Status = ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); - ok_eq_hex(Status, STATUS_SUCCESS); -} - -#endif /* defined KMT_DEFINE_TEST_FUNCTIONS */ - -#endif /* !defined _KMTEST_TEST_H_ */ +#endif /* !defined _KMTEST_TEST_KERNEL_H_ */ Copied: trunk/rostests/kmtests/include/kmt_test_user.h (from r65197, trunk/rostests/kmtests/include/kmt_test.h) URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/include/kmt_test_…
============================================================================== --- trunk/rostests/kmtests/include/kmt_test.h [iso-8859-1] (original) +++ trunk/rostests/kmtests/include/kmt_test_user.h [iso-8859-1] Tue Nov 4 20:55:16 2014 @@ -1,363 +1,17 @@ /* * PROJECT: ReactOS kernel-mode tests - * LICENSE: GPLv2+ - See COPYING in the top level directory + * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory * PURPOSE: Kernel-Mode Test Suite test framework declarations * PROGRAMMER: Thomas Faber <thomas.faber(a)reactos.org> */ -/* Inspired by Wine C unit tests, Copyright (C) 2002 Alexandre Julliard - * Inspired by ReactOS kernel-mode regression tests, - * Copyright (C) Aleksey Bragin, Filip Navara - */ +#ifndef _KMTEST_TEST_USER_H_ +#define _KMTEST_TEST_USER_H_ -#ifndef _KMTEST_TEST_H_ -#define _KMTEST_TEST_H_ +#if !defined _KMTEST_TEST_H_ +#error include kmt_test.h instead of including kmt_test_user.h +#endif /* !defined _KMTEST_TEST_H_ */ -#include <kmt_platform.h> - -typedef VOID KMT_TESTFUNC(VOID); -typedef KMT_TESTFUNC *PKMT_TESTFUNC; - -typedef struct -{ - const char *TestName; - KMT_TESTFUNC *TestFunction; -} KMT_TEST, *PKMT_TEST; - -typedef const KMT_TEST CKMT_TEST, *PCKMT_TEST; - -extern const KMT_TEST TestList[]; - -typedef struct -{ - volatile LONG Successes; - volatile LONG Failures; - volatile LONG Skipped; - volatile LONG LogBufferLength; - LONG LogBufferMaxLength; - CHAR LogBuffer[ANYSIZE_ARRAY]; -} KMT_RESULTBUFFER, *PKMT_RESULTBUFFER; - -#ifndef KMT_STANDALONE_DRIVER - -/* usermode call-back mechanism */ - -/* list of supported operations */ -typedef enum _KMT_CALLBACK_INFORMATION_CLASS -{ - QueryVirtualMemory -} KMT_CALLBACK_INFORMATION_CLASS, *PKMT_CALLBACK_INFORMATION_CLASS; - -/* TODO: "response" is a little generic */ -typedef union _KMT_RESPONSE -{ - MEMORY_BASIC_INFORMATION MemInfo; -} KMT_RESPONSE, *PKMT_RESPONSE; - -/* this struct is sent from driver to usermode */ -typedef struct _KMT_CALLBACK_REQUEST_PACKET -{ - ULONG RequestId; - KMT_CALLBACK_INFORMATION_CLASS OperationClass; - PVOID Parameters; -} KMT_CALLBACK_REQUEST_PACKET, *PKMT_CALLBACK_REQUEST_PACKET; - -PKMT_RESPONSE KmtUserModeCallback(KMT_CALLBACK_INFORMATION_CLASS Operation, PVOID Parameters); -VOID KmtFreeCallbackResponse(PKMT_RESPONSE Response); - -//macro to simplify using the mechanism -#define Test_NtQueryVirtualMemory(BaseAddress, Size, AllocationType, ProtectionType) \ - do { \ - PKMT_RESPONSE NtQueryTest = KmtUserModeCallback(QueryVirtualMemory, BaseAddress); \ - if (NtQueryTest != NULL) \ - { \ - ok_eq_hex(NtQueryTest->MemInfo.Protect, ProtectionType); \ - ok_eq_hex(NtQueryTest->MemInfo.State, AllocationType); \ - ok_eq_size(NtQueryTest->MemInfo.RegionSize, Size); \ - KmtFreeCallbackResponse(NtQueryTest); \ - } \ - } while (0) \ - -#endif - -#ifdef KMT_STANDALONE_DRIVER -#define KMT_KERNEL_MODE - -typedef NTSTATUS (KMT_IRP_HANDLER)( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PIO_STACK_LOCATION IoStackLocation); -typedef KMT_IRP_HANDLER *PKMT_IRP_HANDLER; - -NTSTATUS KmtRegisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler); -NTSTATUS KmtUnregisterIrpHandler(IN UCHAR MajorFunction, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_IRP_HANDLER IrpHandler); - -typedef NTSTATUS (KMT_MESSAGE_HANDLER)( - IN PDEVICE_OBJECT DeviceObject, - IN ULONG ControlCode, - IN PVOID Buffer OPTIONAL, - IN SIZE_T InLength, - IN OUT PSIZE_T OutLength); -typedef KMT_MESSAGE_HANDLER *PKMT_MESSAGE_HANDLER; - -NTSTATUS KmtRegisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler); -NTSTATUS KmtUnregisterMessageHandler(IN ULONG ControlCode OPTIONAL, IN PDEVICE_OBJECT DeviceObject OPTIONAL, IN PKMT_MESSAGE_HANDLER MessageHandler); - -typedef enum -{ - TESTENTRY_NO_CREATE_DEVICE = 1, - TESTENTRY_NO_REGISTER_DISPATCH = 2, - TESTENTRY_NO_REGISTER_UNLOAD = 4, - TESTENTRY_NO_EXCLUSIVE_DEVICE = 8, -} KMT_TESTENTRY_FLAGS; - -NTSTATUS TestEntry(IN PDRIVER_OBJECT DriverObject, IN PCUNICODE_STRING RegistryPath, OUT PCWSTR *DeviceName, IN OUT INT *Flags); -VOID TestUnload(IN PDRIVER_OBJECT DriverObject); -#endif /* defined KMT_STANDALONE_DRIVER */ - -#ifdef KMT_KERNEL_MODE -/* Device Extension layout */ -typedef struct -{ - PKMT_RESULTBUFFER ResultBuffer; - PMDL Mdl; -} KMT_DEVICE_EXTENSION, *PKMT_DEVICE_EXTENSION; - -extern BOOLEAN KmtIsCheckedBuild; -extern BOOLEAN KmtIsMultiProcessorBuild; -extern PCSTR KmtMajorFunctionNames[]; -extern PDRIVER_OBJECT KmtDriverObject; - -VOID KmtSetIrql(IN KIRQL NewIrql); -BOOLEAN KmtAreInterruptsEnabled(VOID); -ULONG KmtGetPoolTag(PVOID Memory); -USHORT KmtGetPoolType(PVOID Memory); -#elif defined KMT_USER_MODE -DWORD KmtRunKernelTest(IN PCSTR TestName); - -VOID KmtLoadDriver(IN PCWSTR ServiceName, IN BOOLEAN RestartIfRunning); -VOID KmtUnloadDriver(VOID); -VOID KmtOpenDriver(VOID); -VOID KmtCloseDriver(VOID); - -DWORD KmtSendToDriver(IN DWORD ControlCode); -DWORD KmtSendStringToDriver(IN DWORD ControlCode, IN PCSTR String); -DWORD KmtSendWStringToDriver(IN DWORD ControlCode, IN PCWSTR String); -DWORD KmtSendBufferToDriver(IN DWORD ControlCode, IN OUT PVOID Buffer OPTIONAL, IN DWORD InLength, IN OUT PDWORD OutLength); -#else /* if !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */ -#error either KMT_KERNEL_MODE or KMT_USER_MODE must be defined -#endif /* !defined KMT_KERNEL_MODE && !defined KMT_USER_MODE */ - -extern PKMT_RESULTBUFFER ResultBuffer; - -#ifdef __GNUC__ -/* TODO: GCC doesn't understand %wZ :( */ -#define KMT_FORMAT(type, fmt, first) /*__attribute__((__format__(type, fmt, first)))*/ -#elif !defined __GNUC__ -#define KMT_FORMAT(type, fmt, first) -#endif /* !defined __GNUC__ */ - -#define START_TEST(name) VOID Test_##name(VOID) - -#ifndef KMT_STRINGIZE -#define KMT_STRINGIZE(x) #x -#endif /* !defined KMT_STRINGIZE */ -#define ok(test, ...) ok_(test, __FILE__, __LINE__, __VA_ARGS__) -#define trace(...) trace_( __FILE__, __LINE__, __VA_ARGS__) -#define skip(test, ...) skip_(test, __FILE__, __LINE__, __VA_ARGS__) - -#define ok_(test, file, line, ...) KmtOk(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__) -#define trace_(file, line, ...) KmtTrace( file ":" KMT_STRINGIZE(line), __VA_ARGS__) -#define skip_(test, file, line, ...) KmtSkip(test, file ":" KMT_STRINGIZE(line), __VA_ARGS__) - -BOOLEAN KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); -BOOLEAN KmtOk(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 3, 4); -VOID KmtVTrace(PCSTR FileAndLine, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 2, 0); -VOID KmtTrace(PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 2, 3); -BOOLEAN KmtVSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); -BOOLEAN KmtSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) KMT_FORMAT(ms_printf, 3, 4); -PVOID KmtAllocateGuarded(SIZE_T SizeRequested); -VOID KmtFreeGuarded(PVOID Pointer); - -#ifdef KMT_KERNEL_MODE -#define ok_irql(irql) ok(KeGetCurrentIrql() == irql, "IRQL is %d, expected %d\n", KeGetCurrentIrql(), irql) -#endif /* defined KMT_KERNEL_MODE */ -#define ok_eq_print(value, expected, spec) ok((value) == (expected), #value " = " spec ", expected " spec "\n", value, expected) -#define ok_eq_pointer(value, expected) ok_eq_print(value, expected, "%p") -#define ok_eq_int(value, expected) ok_eq_print(value, expected, "%d") -#define ok_eq_uint(value, expected) ok_eq_print(value, expected, "%u") -#define ok_eq_long(value, expected) ok_eq_print(value, expected, "%ld") -#define ok_eq_ulong(value, expected) ok_eq_print(value, expected, "%lu") -#define ok_eq_longlong(value, expected) ok_eq_print(value, expected, "%I64d") -#define ok_eq_ulonglong(value, expected) ok_eq_print(value, expected, "%I64u") -#define ok_eq_char(value, expected) ok_eq_print(value, expected, "%c") -#define ok_eq_wchar(value, expected) ok_eq_print(value, expected, "%C") -#ifndef _WIN64 -#define ok_eq_size(value, expected) ok_eq_print(value, (SIZE_T)(expected), "%lu") -#define ok_eq_longptr(value, expected) ok_eq_print(value, (LONG_PTR)(expected), "%ld") -#define ok_eq_ulongptr(value, expected) ok_eq_print(value, (ULONG_PTR)(expected), "%lu") -#elif defined _WIN64 -#define ok_eq_size(value, expected) ok_eq_print(value, (SIZE_T)(expected), "%I64u") -#define ok_eq_longptr(value, expected) ok_eq_print(value, (LONG_PTR)(expected), "%I64d") -#define ok_eq_ulongptr(value, expected) ok_eq_print(value, (ULONG_PTR)(expected), "%I64u") -#endif /* defined _WIN64 */ -#define ok_eq_hex(value, expected) ok_eq_print(value, expected, "0x%08lx") -#define ok_bool_true(value, desc) ok((value) == TRUE, desc " FALSE, expected TRUE\n") -#define ok_bool_false(value, desc) ok((value) == FALSE, desc " TRUE, expected FALSE\n") -#define ok_eq_bool(value, expected) ok((value) == (expected), #value " = %s, expected %s\n", \ - (value) ? "TRUE" : "FALSE", \ - (expected) ? "TRUE" : "FALSE") -#define ok_eq_str(value, expected) ok(!strcmp(value, expected), #value " = \"%s\", expected \"%s\"\n", value, expected) -#define ok_eq_wstr(value, expected) ok(!wcscmp(value, expected), #value " = \"%ls\", expected \"%ls\"\n", value, expected) -#define ok_eq_tag(value, expected) ok_eq_print(value, expected, "0x%08lx") - -#define KMT_MAKE_CODE(ControlCode) CTL_CODE(FILE_DEVICE_UNKNOWN, \ - 0xC00 + (ControlCode), \ - METHOD_BUFFERED, \ - FILE_ANY_ACCESS) - -#define MICROSECOND 10 -#define MILLISECOND (1000 * MICROSECOND) -#define SECOND (1000 * MILLISECOND) - -/* See apitests/include/apitest.h */ -#define KmtInvalidPointer ((PVOID)0x5555555555555555ULL) - -#define KmtStartSeh() \ -{ \ - NTSTATUS ExceptionStatus = STATUS_SUCCESS; \ - _SEH2_TRY \ - { - -#define KmtEndSeh(ExpectedStatus) \ - } \ - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) \ - { \ - ExceptionStatus = _SEH2_GetExceptionCode(); \ - } \ - _SEH2_END; \ - ok_eq_hex(ExceptionStatus, (ExpectedStatus)); \ -} - -#if defined KMT_DEFINE_TEST_FUNCTIONS - -#if defined KMT_KERNEL_MODE -BOOLEAN KmtIsCheckedBuild; -BOOLEAN KmtIsMultiProcessorBuild; -PCSTR KmtMajorFunctionNames[] = -{ - "Create", - "CreateNamedPipe", - "Close", - "Read", - "Write", - "QueryInformation", - "SetInformation", - "QueryEa", - "SetEa", - "FlushBuffers", - "QueryVolumeInformation", - "SetVolumeInformation", - "DirectoryControl", - "FileSystemControl", - "DeviceControl", - "InternalDeviceControl/Scsi", - "Shutdown", - "LockControl", - "Cleanup", - "CreateMailslot", - "QuerySecurity", - "SetSecurity", - "Power", - "SystemControl", - "DeviceChange", - "QueryQuota", - "SetQuota", - "Pnp/PnpPower" -}; - -VOID KmtSetIrql(IN KIRQL NewIrql) -{ - KIRQL Irql = KeGetCurrentIrql(); - if (Irql > NewIrql) - KeLowerIrql(NewIrql); - else if (Irql < NewIrql) - KeRaiseIrql(NewIrql, &Irql); -} - -BOOLEAN KmtAreInterruptsEnabled(VOID) -{ - return (__readeflags() & (1 << 9)) != 0; -} - -typedef struct _POOL_HEADER -{ - union - { - struct - { -#ifdef _M_AMD64 - USHORT PreviousSize:8; - USHORT PoolIndex:8; - USHORT BlockSize:8; - USHORT PoolType:8; -#else - USHORT PreviousSize:9; - USHORT PoolIndex:7; - USHORT BlockSize:9; - USHORT PoolType:7; -#endif - }; - ULONG Ulong1; - }; -#ifdef _M_AMD64 - ULONG PoolTag; -#endif - union - { -#ifdef _M_AMD64 - PEPROCESS ProcessBilled; -#else - ULONG PoolTag; -#endif - struct - { - USHORT AllocatorBackTraceIndex; - USHORT PoolTagHash; - }; - }; -} POOL_HEADER, *PPOOL_HEADER; - -ULONG KmtGetPoolTag(PVOID Memory) -{ - PPOOL_HEADER Header; - - /* it's not so easy for allocations of PAGE_SIZE */ - if (((ULONG_PTR)Memory & (PAGE_SIZE - 1)) == 0) - return 'TooL'; - - Header = Memory; - Header--; - - return Header->PoolTag; -} - -USHORT KmtGetPoolType(PVOID Memory) -{ - PPOOL_HEADER Header; - - /* it's not so easy for allocations of PAGE_SIZE */ - if (((ULONG_PTR)Memory & (PAGE_SIZE - 1)) == 0) - return 0; - - Header = Memory; - Header--; - - return Header->PoolType; -} - -INT __cdecl KmtVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR Format, va_list Arguments) KMT_FORMAT(ms_printf, 3, 0); -#elif defined KMT_USER_MODE static PKMT_RESULTBUFFER KmtAllocateResultBuffer(SIZE_T ResultBufferSize) { PKMT_RESULTBUFFER Buffer = HeapAlloc(GetProcessHeap(), 0, ResultBufferSize); @@ -379,217 +33,5 @@ } #define KmtVSNPrintF vsnprintf -#endif /* defined KMT_USER_MODE */ -PKMT_RESULTBUFFER ResultBuffer = NULL; - -static VOID KmtAddToLogBuffer(PKMT_RESULTBUFFER Buffer, PCSTR String, SIZE_T Length) -{ - LONG OldLength; - LONG NewLength; - - if (!Buffer) - return; - - do - { - OldLength = Buffer->LogBufferLength; - NewLength = OldLength + (ULONG)Length; - if (NewLength > Buffer->LogBufferMaxLength) - return; - } while (InterlockedCompareExchange(&Buffer->LogBufferLength, NewLength, OldLength) != OldLength); - - memcpy(&Buffer->LogBuffer[OldLength], String, Length); -} - -KMT_FORMAT(ms_printf, 5, 0) -static SIZE_T KmtXVSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR FileAndLine, PCSTR Prepend, PCSTR Format, va_list Arguments) -{ - SIZE_T BufferLength = 0; - SIZE_T Length; - - if (FileAndLine) - { - PCSTR Slash; - Slash = strrchr(FileAndLine, '\\'); - if (Slash) - FileAndLine = Slash + 1; - Slash = strrchr(FileAndLine, '/'); - if (Slash) - FileAndLine = Slash + 1; - - Length = min(BufferMaxLength, strlen(FileAndLine)); - memcpy(Buffer, FileAndLine, Length); - Buffer += Length; - BufferLength += Length; - BufferMaxLength -= Length; - } - if (Prepend) - { - Length = min(BufferMaxLength, strlen(Prepend)); - memcpy(Buffer, Prepend, Length); - Buffer += Length; - BufferLength += Length; - BufferMaxLength -= Length; - } - if (Format) - { - Length = KmtVSNPrintF(Buffer, BufferMaxLength, Format, Arguments); - /* vsnprintf can return more than maxLength, we don't want to do that */ - BufferLength += min(Length, BufferMaxLength); - } - return BufferLength; -} - -KMT_FORMAT(ms_printf, 5, 6) -static SIZE_T KmtXSNPrintF(PSTR Buffer, SIZE_T BufferMaxLength, PCSTR FileAndLine, PCSTR Prepend, PCSTR Format, ...) -{ - SIZE_T BufferLength; - va_list Arguments; - va_start(Arguments, Format); - BufferLength = KmtXVSNPrintF(Buffer, BufferMaxLength, FileAndLine, Prepend, Format, Arguments); - va_end(Arguments); - return BufferLength; -} - -VOID KmtFinishTest(PCSTR TestName) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - if (!ResultBuffer) - return; - - MessageLength = KmtXSNPrintF(MessageBuffer, sizeof MessageBuffer, NULL, NULL, - "%s: %ld tests executed (0 marked as todo, %ld failures), %ld skipped.\n", - TestName, - ResultBuffer->Successes + ResultBuffer->Failures, - ResultBuffer->Failures, - ResultBuffer->Skipped); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); -} - -BOOLEAN KmtVOk(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - if (!ResultBuffer) - return Condition != 0; - - if (Condition) - { - InterlockedIncrement(&ResultBuffer->Successes); - - if (0/*KmtReportSuccess*/) - { - MessageLength = KmtXSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Test succeeded\n", NULL); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); - } - } - else - { - InterlockedIncrement(&ResultBuffer->Failures); - MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Test failed: ", Format, Arguments); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); - } - - return Condition != 0; -} - -BOOLEAN KmtOk(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) -{ - BOOLEAN Ret; - va_list Arguments; - va_start(Arguments, Format); - Ret = KmtVOk(Condition, FileAndLine, Format, Arguments); - va_end(Arguments); - return Ret; -} - -VOID KmtVTrace(PCSTR FileAndLine, PCSTR Format, va_list Arguments) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": ", Format, Arguments); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); -} - -VOID KmtTrace(PCSTR FileAndLine, PCSTR Format, ...) -{ - va_list Arguments; - va_start(Arguments, Format); - KmtVTrace(FileAndLine, Format, Arguments); - va_end(Arguments); -} - -BOOLEAN KmtVSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, va_list Arguments) -{ - CHAR MessageBuffer[512]; - SIZE_T MessageLength; - - if (!ResultBuffer) - return !Condition; - - if (!Condition) - { - InterlockedIncrement(&ResultBuffer->Skipped); - MessageLength = KmtXVSNPrintF(MessageBuffer, sizeof MessageBuffer, FileAndLine, ": Tests skipped: ", Format, Arguments); - KmtAddToLogBuffer(ResultBuffer, MessageBuffer, MessageLength); - } - - return !Condition; -} - -BOOLEAN KmtSkip(INT Condition, PCSTR FileAndLine, PCSTR Format, ...) -{ - BOOLEAN Ret; - va_list Arguments; - va_start(Arguments, Format); - Ret = KmtVSkip(Condition, FileAndLine, Format, Arguments); - va_end(Arguments); - return Ret; -} - -PVOID KmtAllocateGuarded(SIZE_T SizeRequested) -{ - NTSTATUS Status; - SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); - PVOID VirtualMemory = NULL; - PCHAR StartOfBuffer; - - Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); - - if (!NT_SUCCESS(Status)) - return NULL; - - Size -= PAGE_SIZE; - Status = ZwAllocateVirtualMemory(ZwCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); - if (!NT_SUCCESS(Status)) - { - Size = 0; - Status = ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); - ok_eq_hex(Status, STATUS_SUCCESS); - return NULL; - } - - StartOfBuffer = VirtualMemory; - StartOfBuffer += Size - SizeRequested; - - return StartOfBuffer; -} - -VOID KmtFreeGuarded(PVOID Pointer) -{ - NTSTATUS Status; - PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); - SIZE_T Size = 0; - - Status = ZwFreeVirtualMemory(ZwCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); - ok_eq_hex(Status, STATUS_SUCCESS); -} - -#endif /* defined KMT_DEFINE_TEST_FUNCTIONS */ - -#endif /* !defined _KMTEST_TEST_H_ */ +#endif /* !defined _KMTEST_TEST_USER_H_ */ Modified: trunk/rostests/kmtests/npfs/NpfsHelpers.c URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/npfs/NpfsHelpers.…
============================================================================== --- trunk/rostests/kmtests/npfs/NpfsHelpers.c [iso-8859-1] (original) +++ trunk/rostests/kmtests/npfs/NpfsHelpers.c [iso-8859-1] Tue Nov 4 20:55:16 2014 @@ -713,62 +713,3 @@ KeSetEvent(&Context->StartWorkEvent, IO_NO_INCREMENT, TRUE); return WaitForWork(Context, MilliSeconds); } - -PKTHREAD -KmtStartThread( - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext OPTIONAL) -{ - NTSTATUS Status; - OBJECT_ATTRIBUTES ObjectAttributes; - HANDLE ThreadHandle; - PVOID ThreadObject = NULL; - - InitializeObjectAttributes(&ObjectAttributes, - NULL, - OBJ_KERNEL_HANDLE, - NULL, - NULL); - ThreadHandle = INVALID_HANDLE_VALUE; - Status = PsCreateSystemThread(&ThreadHandle, - SYNCHRONIZE, - &ObjectAttributes, - NULL, - NULL, - StartRoutine, - StartContext); - ok_eq_hex(Status, STATUS_SUCCESS); - if (!skip(NT_SUCCESS(Status) && ThreadHandle != NULL && ThreadHandle != INVALID_HANDLE_VALUE, "No thread\n")) - { - Status = ObReferenceObjectByHandle(ThreadHandle, - SYNCHRONIZE, - *PsThreadType, - KernelMode, - &ThreadObject, - NULL); - ok_eq_hex(Status, STATUS_SUCCESS); - ObCloseHandle(ThreadHandle, KernelMode); - } - return ThreadObject; -} - -VOID -KmtFinishThread( - IN PKTHREAD Thread OPTIONAL, - IN PKEVENT Event OPTIONAL) -{ - NTSTATUS Status; - - if (skip(Thread != NULL, "No thread\n")) - return; - - if (Event) - KeSetEvent(Event, IO_NO_INCREMENT, TRUE); - Status = KeWaitForSingleObject(Thread, - Executive, - KernelMode, - FALSE, - NULL); - ok_eq_hex(Status, STATUS_SUCCESS); - ObDereferenceObject(Thread); -} Modified: trunk/rostests/kmtests/npfs/npfs.h URL:
http://svn.reactos.org/svn/reactos/trunk/rostests/kmtests/npfs/npfs.h?rev=6…
============================================================================== --- trunk/rostests/kmtests/npfs/npfs.h [iso-8859-1] (original) +++ trunk/rostests/kmtests/npfs/npfs.h [iso-8859-1] Tue Nov 4 20:55:16 2014 @@ -211,15 +211,4 @@ IN PTHREAD_CONTEXT Context, IN ULONG MilliSeconds); - -PKTHREAD -KmtStartThread( - IN PKSTART_ROUTINE StartRoutine, - IN PVOID StartContext OPTIONAL); - -VOID -KmtFinishThread( - IN PKTHREAD Thread OPTIONAL, - IN PKEVENT Event OPTIONAL); - #endif /* !defined _KMTEST_NPFS_H_ */
10 years, 1 month
1
0
0
0
← Newer
1
...
25
26
27
28
29
30
31
...
38
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
Results per page:
10
25
50
100
200