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
January 2007
----- 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
21 participants
401 discussions
Start a n
N
ew thread
[ion] 25586: - Implement new ExHandle* implementation using pushlocks and the Windows 2003 HANDLE_TABLE structure and semantics. Only the currently used base APIs were implemented; support for audit masks still disabled, debug/tracing calls disabled. - Remove manual overrides of NTDDI_VERSION all over the thread and set it once globally, since ExHandle* was the only non-updated package. The entire kernel now builds with Windows 2003 SP1 as a target. - Remove this entry from kernel fun.
by ion@svn.reactos.org
Author: ion Date: Mon Jan 22 11:15:17 2007 New Revision: 25586 URL:
http://svn.reactos.org/svn/reactos?rev=25586&view=rev
Log: - Implement new ExHandle* implementation using pushlocks and the Windows 2003 HANDLE_TABLE structure and semantics. Only the currently used base APIs were implemented; support for audit masks still disabled, debug/tracing calls disabled. - Remove manual overrides of NTDDI_VERSION all over the thread and set it once globally, since ExHandle* was the only non-updated package. The entire kernel now builds with Windows 2003 SP1 as a target. - Remove this entry from kernel fun. Modified: trunk/reactos/ntoskrnl/KrnlFun.c trunk/reactos/ntoskrnl/cm/ntfunc.c trunk/reactos/ntoskrnl/ex/handle.c trunk/reactos/ntoskrnl/include/internal/ex.h trunk/reactos/ntoskrnl/include/internal/ob.h trunk/reactos/ntoskrnl/include/ntoskrnl.h trunk/reactos/ntoskrnl/ke/apc.c trunk/reactos/ntoskrnl/ke/dpc.c trunk/reactos/ntoskrnl/ke/gate.c trunk/reactos/ntoskrnl/ke/gmutex.c trunk/reactos/ntoskrnl/ke/i386/kiinit.c trunk/reactos/ntoskrnl/ob/obhandle.c trunk/reactos/ntoskrnl/ob/oblife.c trunk/reactos/ntoskrnl/ob/obname.c trunk/reactos/ntoskrnl/ob/obref.c trunk/reactos/ntoskrnl/ob/obsecure.c trunk/reactos/ntoskrnl/ob/obwait.c trunk/reactos/ntoskrnl/ps/kill.c trunk/reactos/ntoskrnl/rtl/libsupp.c Modified: trunk/reactos/ntoskrnl/KrnlFun.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=255…
============================================================================== --- trunk/reactos/ntoskrnl/KrnlFun.c (original) +++ trunk/reactos/ntoskrnl/KrnlFun.c Mon Jan 22 11:15:17 2007 @@ -7,9 +7,6 @@ // Do NOT complain about it. // Do NOT ask when it will be fixed. // Failure to respect this will *ACHIEVE NOTHING*. -// -// Ex: -// - Use pushlocks for handle implementation. // // Ke2: // - Dispatcher Rewrite (DPCs-Timers-Waits). Modified: trunk/reactos/ntoskrnl/cm/ntfunc.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/cm/ntfunc.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/cm/ntfunc.c (original) +++ trunk/reactos/ntoskrnl/cm/ntfunc.c Mon Jan 22 11:15:17 2007 @@ -66,7 +66,7 @@ ObjectHeader = OBJECT_TO_OBJECT_HEADER(ObjectBody); /* check that this is a valid kernel pointer */ - ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED); + //ASSERT((ULONG_PTR)ObjectHeader & EX_HANDLE_ENTRY_LOCKED); if (GrantedAccess & MAXIMUM_ALLOWED) { @@ -82,9 +82,9 @@ NewEntry.Object = ObjectHeader; if(HandleAttributes & OBJ_INHERIT) - NewEntry.ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE; + NewEntry.ObAttributes |= OBJ_INHERIT; else - NewEntry.ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE; + NewEntry.ObAttributes &= ~OBJ_INHERIT; NewEntry.GrantedAccess = GrantedAccess; if ((HandleAttributes & OBJ_KERNEL_HANDLE) && Modified: trunk/reactos/ntoskrnl/ex/handle.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/handle.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/ex/handle.c (original) +++ trunk/reactos/ntoskrnl/ex/handle.c Mon Jan 22 11:15:17 2007 @@ -1,937 +1,1241 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ex/handle.c +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ex/init.c * PURPOSE: Generic Executive Handle Tables - * - * PROGRAMMERS: Thomas Weidenmueller <w3seek(a)reactos.com> - * - * TODO: - * - * - the last entry of a subhandle list should be reserved for auditing - * - * ExReferenceHandleDebugInfo - * ExSnapShotHandleTables - * ExpMoveFreeHandles (???) + * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org) + * Thomas Weidenmueller <w3seek(a)reactos.com> */ -/* INCLUDES *****************************************************************/ +/* INCLUDES ******************************************************************/ #include <ntoskrnl.h> - #define NDEBUG -#include <internal/debug.h> - -static LIST_ENTRY ExpHandleTableHead; -static FAST_MUTEX ExpHandleTableListLock; -static LARGE_INTEGER ExpHandleShortWait; - -#define ExAcquireHandleTableListLock() \ - ExAcquireFastMutexUnsafe(&ExpHandleTableListLock) - -#define ExReleaseHandleTableListLock() \ - ExReleaseFastMutexUnsafe(&ExpHandleTableListLock) - -#define ExAcquireHandleLockExclusive(HandleTable) \ - ExAcquireResourceExclusiveLite(&(HandleTable)->HandleLock, TRUE) - -#define ExAcquireHandleLockShared(HandleTable) \ - ExAcquireResourceSharedLite(&(HandleTable)->HandleLock, TRUE) - -#define ExReleaseHandleLock(HandleTable) \ - ExReleaseResourceLite(&(HandleTable)->HandleLock) - -/* - 5 bits: reserved - 8 bits: top level index - 10 bits: middle level index - 9 bits: sub handle index -*/ -#define N_TLI_BITS 8 /* top level index */ -#define N_MLI_BITS 10 /* middle level index */ -#define N_EI_BITS 9 /* sub handle index */ -#define TLI_OFFSET (N_MLI_BITS + N_EI_BITS) -#define MLI_OFFSET N_EI_BITS -#define EI_OFFSET 0 - -#define N_TOPLEVEL_POINTERS (1 << N_TLI_BITS) -#define N_MIDDLELEVEL_POINTERS (1 << N_MLI_BITS) -#define N_SUBHANDLE_ENTRIES (1 << N_EI_BITS) -#define EX_MAX_HANDLES (N_TOPLEVEL_POINTERS * N_MIDDLELEVEL_POINTERS * N_SUBHANDLE_ENTRIES) - -#define VALID_HANDLE_MASK (((N_TOPLEVEL_POINTERS - 1) << TLI_OFFSET) | \ - ((N_MIDDLELEVEL_POINTERS - 1) << MLI_OFFSET) | ((N_SUBHANDLE_ENTRIES - 1) << EI_OFFSET)) -#define TLI_FROM_HANDLE(index) (ULONG)(((index) >> TLI_OFFSET) & (N_TOPLEVEL_POINTERS - 1)) -#define MLI_FROM_HANDLE(index) (ULONG)(((index) >> MLI_OFFSET) & (N_MIDDLELEVEL_POINTERS - 1)) -#define ELI_FROM_HANDLE(index) (ULONG)(((index) >> EI_OFFSET) & (N_SUBHANDLE_ENTRIES - 1)) - -#define N_MAX_HANDLE (N_TOPLEVEL_POINTERS * N_MIDDLELEVEL_POINTERS * N_SUBHANDLE_ENTRIES) - -#define BUILD_HANDLE(tli, mli, eli) ((((tli) & (N_TOPLEVEL_POINTERS - 1)) << TLI_OFFSET) | \ - (((mli) & (N_MIDDLELEVEL_POINTERS - 1)) << MLI_OFFSET) | (((eli) & (N_SUBHANDLE_ENTRIES - 1)) << EI_OFFSET)) - -#define IS_INVALID_EX_HANDLE(index) \ - (((index) & ~VALID_HANDLE_MASK) != 0) -#define IS_VALID_EX_HANDLE(index) \ - (((index) & ~VALID_HANDLE_MASK) == 0) - -#define HANDLE_TO_EX_HANDLE(handle) \ - (LONG)(((LONG)(handle) >> 2) - 1) -#define EX_HANDLE_TO_HANDLE(exhandle) \ - (HANDLE)(((exhandle) + 1) << 2) - -static BOOLEAN ExpInitialized = FALSE; - -/******************************************************************************/ +#include <debug.h> + +/* GLOBALS *******************************************************************/ + +LIST_ENTRY HandleTableListHead; +EX_PUSH_LOCK HandleTableListLock; +#define SizeOfHandle(x) sizeof(HANDLE) * x + +/* PRIVATE FUNCTIONS *********************************************************/ VOID +NTAPI ExpInitializeHandleTables(VOID) { - ExpHandleShortWait.QuadPart = -50000; - InitializeListHead(&ExpHandleTableHead); - ExInitializeFastMutex(&ExpHandleTableListLock); - - ExpInitialized = TRUE; + /* Initialize the list of handle tables and the lock */ + InitializeListHead(&HandleTableListHead); + ExInitializePushLock((PULONG_PTR)&HandleTableListLock); +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN EXHANDLE LookupHandle) +{ + ULONG i, j, k, TableLevel, NextHandle; + ULONG_PTR TableBase; + PHANDLE_TABLE_ENTRY Entry = NULL; + EXHANDLE Handle = LookupHandle; + PCHAR Level1, Level2, Level3; + + /* Clear the tag bits and check what the next handle is */ + Handle.TagBits = 0; + NextHandle = HandleTable->NextHandleNeedingPool; + if (Handle.Value >= NextHandle) return NULL; + + /* Get the table code */ + TableBase = (ULONG_PTR)HandleTable->TableCode; + + /* Extract the table level and actual table base */ + TableLevel = (ULONG)(TableBase & 3); + TableBase = TableBase - TableLevel; + + /* Check what level we're running at */ + switch (TableLevel) + { + /* Direct index */ + case 0: + + /* Use level 1 and just get the entry directlry */ + Level1 = (PUCHAR)TableBase; + Entry = (PVOID)&Level1[Handle.Value * + (sizeof(HANDLE_TABLE_ENTRY) / + SizeOfHandle(1))]; + break; + + /* Nested index into mid level */ + case 1: + + /* Get the second table and index into it */ + Level2 = (PUCHAR)TableBase; + i = Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES); + + /* Substract this index, and get the next one */ + Handle.Value -= i; + j = Handle.Value / + (SizeOfHandle(LOW_LEVEL_ENTRIES) / sizeof(PHANDLE_TABLE_ENTRY)); + + /* Now get the next table and get the entry from it */ + Level1 = (PUCHAR)*(PHANDLE_TABLE_ENTRY*)&Level2[j]; + Entry = (PVOID)&Level1[i * + (sizeof(HANDLE_TABLE_ENTRY) / + SizeOfHandle(1))]; + break; + + /* Nested index into high level */ + case 2: + + /* Start with the 3rd level table */ + Level3 = (PUCHAR)TableBase; + i = Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES); + + /* Subtract this index and get the index for the next lower table */ + Handle.Value -= i; + k = Handle.Value / + (SizeOfHandle(LOW_LEVEL_ENTRIES) / sizeof(PHANDLE_TABLE_ENTRY)); + + /* Get the remaining index in the 2nd level table */ + j = k % (MID_LEVEL_ENTRIES * sizeof(PHANDLE_TABLE_ENTRY)); + + /* Get the remaining index, which is in the third table */ + k -= j; + k /= MID_LEVEL_ENTRIES; + + /* Extract the table level for the handle in each table */ + Level2 = (PUCHAR)*(PHANDLE_TABLE_ENTRY*)&Level3[k]; + Level1 = (PUCHAR)*(PHANDLE_TABLE_ENTRY*)&Level2[j]; + + /* Get the handle table entry */ + Entry = (PVOID)&Level1[i * + (sizeof(HANDLE_TABLE_ENTRY) / + SizeOfHandle(1))]; + + default: + + /* All done */ + break; + } + + /* Return the handle entry */ + return Entry; +} + +PVOID +NTAPI +ExpAllocateTablePagedPool(IN PEPROCESS Process OPTIONAL, + IN SIZE_T Size) +{ + PVOID Buffer; + + /* Do the allocation */ + Buffer = ExAllocatePoolWithTag(PagedPool, Size, TAG('O', 'b', 't', 'b')); + if (Buffer) + { + /* Clear the memory */ + RtlZeroMemory(Buffer, Size); + + /* Check if we have a process to charge quota */ + if (Process) + { + /* FIXME: Charge quota */ + } + } + + /* Return the allocated memory */ + return Buffer; +} + +PVOID +NTAPI +ExpAllocateTablePagedPoolNoZero(IN PEPROCESS Process OPTIONAL, + IN SIZE_T Size) +{ + PVOID Buffer; + + /* Do the allocation */ + Buffer = ExAllocatePoolWithTag(PagedPool, Size, TAG('O', 'b', 't', 'b')); + if (Buffer) + { + /* Check if we have a process to charge quota */ + if (Process) + { + /* FIXME: Charge quota */ + } + } + + /* Return the allocated memory */ + return Buffer; +} + +VOID +NTAPI +ExpFreeTablePagedPool(IN PEPROCESS Process OPTIONAL, + IN PVOID Buffer, + IN SIZE_T Size) +{ + /* Free the buffer */ + ExFreePool(Buffer); + if (Process) + { + /* FIXME: Release quota */ + } +} + +VOID +NTAPI +ExpFreeLowLevelTable(IN PEPROCESS Process, + IN PHANDLE_TABLE_ENTRY TableEntry) +{ + /* Check if we have an entry */ + if (TableEntry[0].Object) + { + /* Free the entry */ + ExpFreeTablePagedPool(Process, + TableEntry[0].Object, + LOW_LEVEL_ENTRIES * + sizeof(HANDLE_TABLE_ENTRY_INFO)); + } + + /* Free the table */ + ExpFreeTablePagedPool(Process, TableEntry, PAGE_SIZE); +} + +VOID +NTAPI +ExpFreeHandleTable(IN PHANDLE_TABLE HandleTable) +{ + PEPROCESS Process = HandleTable->QuotaProcess; + ULONG i, j; + ULONG TableLevel = (ULONG)(HandleTable->TableCode & 3); + ULONG_PTR TableBase = HandleTable->TableCode & ~3; + PHANDLE_TABLE_ENTRY Level1, *Level2, **Level3; + PAGED_CODE(); + + /* Check which level we're at */ + if (!TableLevel) + { + /* Select the first level table base and just free it */ + Level1 = (PVOID)TableBase; + ExpFreeLowLevelTable(Process, Level1); + } + else if (TableLevel == 1) + { + /* Select the second level table base */ + Level2 = (PVOID)TableBase; + + /* Loop each mid level entry */ + for (i = 0; i < MID_LEVEL_ENTRIES; i++) + { + /* Leave if we've reached the last entry */ + if (!Level2[i]) break; + + /* Free the second level table */ + ExpFreeLowLevelTable(Process, Level2[i]); + } + + /* Free the second level table */ + ExpFreeTablePagedPool(Process, Level2, PAGE_SIZE); + } + else + { + /* Select the third level table base */ + Level3 = (PVOID)TableBase; + + /* Loop each high level entry */ + for (i = 0; i < HIGH_LEVEL_ENTRIES; i++) + { + /* Leave if we've reached the last entry */ + if (!Level3[i]) break; + + /* Loop each mid level entry */ + for (j = 0; j < MID_LEVEL_ENTRIES; j++) + { + /* Leave if we've reached the last entry */ + if (!Level3[i][j]) break; + + /* Free the second level table */ + ExpFreeLowLevelTable(Process, Level3[i][j]); + } + + /* Free the third level table entry */ + ExpFreeTablePagedPool(Process, Level3[i], PAGE_SIZE); + } + + /* Free the third level table */ + ExpFreeTablePagedPool(Process, + Level3, + HIGH_LEVEL_ENTRIES * + sizeof(PHANDLE_TABLE_ENTRY)); + } + + /* Free the actual table and check if we need to release quota */ + ExFreePool(HandleTable); + if (Process) + { + /* FIXME: TODO */ + } +} + +VOID +NTAPI +ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN EXHANDLE Handle, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + ULONG OldValue, NewValue, *Free; + ULONG i; + PAGED_CODE(); + + /* Sanity checks */ + ASSERT(HandleTableEntry->Object == NULL); + ASSERT(HandleTableEntry == ExpLookupHandleTableEntry(HandleTable, Handle)); + + /* Decrement the handle count */ + InterlockedDecrement(&HandleTable->HandleCount); + + /* Mark the handle as free */ + NewValue = (ULONG)Handle.Value & ~(SizeOfHandle(1) - 1); + + /* Check if we're FIFO */ + if (!HandleTable->StrictFIFO) + { + /* Select a lock index */ + i = (NewValue >> 2) % 4; + + /* Select which entry to use */ + Free = (HandleTable->HandleTableLock[i].Locked) ? + &HandleTable->FirstFree : &HandleTable->LastFree; + } + else + { + /* No need to worry about locking, take the last entry */ + Free = &HandleTable->LastFree; + } + + /* Start value change loop */ + for (;;) + { + /* Get the current value and write */ + OldValue = *Free; + HandleTableEntry->NextFreeTableEntry = (ULONG)OldValue; + if (InterlockedCompareExchange(Free, NewValue, OldValue) == OldValue) + { + /* Break out, we're done. Make sure the handle value makes sense */ + ASSERT((OldValue & FREE_HANDLE_MASK) < + HandleTable->NextHandleNeedingPool); + break; + } + } } PHANDLE_TABLE -ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL) -{ - PHANDLE_TABLE HandleTable; - - PAGED_CODE(); - - if(!ExpInitialized) - { +NTAPI +ExpAllocateHandleTable(IN PEPROCESS Process OPTIONAL, + IN BOOLEAN NewTable) +{ + PHANDLE_TABLE HandleTable; + PHANDLE_TABLE_ENTRY HandleTableTable, HandleEntry; + ULONG i; + PAGED_CODE(); + + /* Allocate the table */ + HandleTable = ExAllocatePoolWithTag(PagedPool, + sizeof(HANDLE_TABLE), + TAG('O', 'b', 't', 'b')); + if (!HandleTable) return NULL; + + /* Check if we have a process */ + if (Process) + { + /* FIXME: Charge quota */ + } + + /* Clear the table */ + RtlZeroMemory(HandleTable, sizeof(HANDLE_TABLE)); + + /* Now allocate the first level structures */ + HandleTableTable = ExpAllocateTablePagedPoolNoZero(Process, PAGE_SIZE); + if (!HandleTableTable) + { + /* Failed, free the table */ + ExFreePool(HandleTable); + return NULL; + } + + /* Write the pointer to our first level structures */ + HandleTable->TableCode = (ULONG_PTR)HandleTableTable; + + /* Initialize the first entry */ + HandleEntry = &HandleTableTable[0]; + HandleEntry->NextFreeTableEntry = -2; + HandleEntry->Value = 0; + + /* Check if this is a new table */ + if (NewTable) + { + /* Go past the root entry */ + HandleEntry++; + + /* Loop every low level entry */ + for (i = 1; i < (LOW_LEVEL_ENTRIES - 1); i++) + { + /* Set up the free data */ + HandleEntry->Value = 0; + HandleEntry->NextFreeTableEntry = (i + 1) * SizeOfHandle(1); + + /* Move to the next entry */ + HandleEntry++; + } + + /* Terminate the last entry */ + HandleEntry->Value = 0; + HandleEntry->NextFreeTableEntry = 0; + HandleTable->FirstFree = SizeOfHandle(1); + } + + /* Set the next handle needing pool after our allocated page from above */ + HandleTable->NextHandleNeedingPool = LOW_LEVEL_ENTRIES * SizeOfHandle(1); + + /* Setup the rest of the handle table data */ + HandleTable->QuotaProcess = Process; + HandleTable->UniqueProcessId = PsGetCurrentProcess()->UniqueProcessId; + HandleTable->Flags = 0; + + /* Loop all the handle table locks */ + for (i = 0; i < 4; i++) HandleTable->HandleTableLock[i].Value = 0; + + /* Initialize the contention event lock and return the lock */ + HandleTable->HandleContentionEvent.Value = 0; + return HandleTable; +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExpAllocateLowLevelTable(IN PHANDLE_TABLE HandleTable, + IN BOOLEAN DoInit) +{ + ULONG i, Base; + PHANDLE_TABLE_ENTRY Low, HandleEntry; + + /* Allocate the low level table */ + Low = ExpAllocateTablePagedPoolNoZero(HandleTable->QuotaProcess, + PAGE_SIZE); + if (!Low) return NULL; + + /* Setup the initial entry */ + HandleEntry = &Low[0]; + HandleEntry->NextFreeTableEntry = -2; + HandleEntry->Value = 0; + + /* Check if we're initializing */ + if (DoInit) + { + /* Go to the next entry and the base entry */ + HandleEntry++; + Base = HandleTable->NextHandleNeedingPool + SizeOfHandle(2); + + /* Loop each entry */ + for (i = Base; + i < Base + SizeOfHandle(LOW_LEVEL_ENTRIES - 2); + i += SizeOfHandle(1)) + { + /* Free this entry and move on to the next one */ + HandleEntry->NextFreeTableEntry = i; + HandleEntry->Value = 0; + HandleEntry++; + } + + /* Terminate the last entry */ + HandleEntry->NextFreeTableEntry = 0; + HandleEntry->Value = 0; + } + + /* Return the low level table */ + return Low; +} + +PHANDLE_TABLE_ENTRY* +NTAPI +ExpAllocateMidLevelTable(IN PHANDLE_TABLE HandleTable, + IN BOOLEAN DoInit, + OUT PHANDLE_TABLE_ENTRY *LowTableEntry) +{ + PHANDLE_TABLE_ENTRY *Mid, Low; + + /* Allocate the mid level table */ + Mid = ExpAllocateTablePagedPool(HandleTable->QuotaProcess, PAGE_SIZE); + if (!Mid) return NULL; + + /* Allocate a new low level for it */ + Low = ExpAllocateLowLevelTable(HandleTable, DoInit); + if (!Low) + { + /* We failed, free the mid table */ + ExpFreeTablePagedPool(HandleTable->QuotaProcess, Mid, PAGE_SIZE); + return NULL; + } + + /* Link the tables and return the pointer */ + Mid[0] = Low; + *LowTableEntry = Low; + return Mid; +} + +BOOLEAN +NTAPI +ExpAllocateHandleTableEntrySlow(IN PHANDLE_TABLE HandleTable, + IN BOOLEAN DoInit) +{ + ULONG i, j, Index; + PHANDLE_TABLE_ENTRY Low, *Mid, **High, *SecondLevel, **ThirdLevel; + ULONG NewFree, FirstFree; + PVOID Value; + ULONG_PTR TableBase = HandleTable->TableCode & ~3; + ULONG TableLevel = (ULONG)(TableBase & 3); + PAGED_CODE(); + + /* Check how many levels we already have */ + if (!TableLevel) + { + /* Allocate a mid level, since we only have a low level */ + Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low); + if (!Mid) return FALSE; + + /* Link up the tables */ + Mid[1] = Mid[0]; + Mid[0] = (PVOID)TableBase; + + /* Write the new level and attempt to change the table code */ + TableBase = ((ULONG_PTR)Mid) | 1; + Value = InterlockedExchangePointer(&HandleTable->TableCode, TableBase); + } + else if (TableLevel == 1) + { + /* Setup the 2nd level table */ + SecondLevel = (PVOID)TableBase; + + /* Get if the next index can fit in the table */ + i = HandleTable->NextHandleNeedingPool / + SizeOfHandle(LOW_LEVEL_ENTRIES); + if (i < MID_LEVEL_ENTRIES) + { + /* We need to allocate a new table */ + Low = ExpAllocateLowLevelTable(HandleTable, DoInit); + if (!Low) return FALSE; + + /* Update the table */ + Value = InterlockedExchangePointer(&SecondLevel[i], Low); + ASSERT(Value == NULL); + } + else + { + /* We need a new high level table */ + High = ExpAllocateTablePagedPool(HandleTable->QuotaProcess, + HIGH_LEVEL_ENTRIES); + if (!High) return FALSE; + + /* Allocate a new mid level table as well */ + Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low); + if (!Mid) + { + /* We failed, free the high level table as welll */ + ExpFreeTablePagedPool(HandleTable->QuotaProcess, + High, + HIGH_LEVEL_ENTRIES); + return FALSE; + } + + /* Link up the tables */ + High[0] = (PVOID)TableBase; + High[1] = Mid; + + /* Write the new table and change the table code */ + TableBase = ((ULONG_PTR)High) | 2; + Value = InterlockedExchangePointer(&HandleTable->TableCode, + (PVOID)TableBase); + } + } + else if (TableLevel == 2) + { + /* Setup the 3rd level table */ + ThirdLevel = (PVOID)TableBase; + + /* Get the index and check if it can fit */ + i = HandleTable->NextHandleNeedingPool / SizeOfHandle(MAX_MID_INDEX); + if (i >= HIGH_LEVEL_ENTRIES) return FALSE; + + /* Check if there's no mid-level table */ + if (!ThirdLevel[i]) + { + /* Allocate a new mid level table */ + Mid = ExpAllocateMidLevelTable(HandleTable, DoInit, &Low); + if (!Mid) return FALSE; + + /* Update the table pointer */ + Value = InterlockedExchangePointer(&ThirdLevel[i], Mid); + ASSERT(Value == NULL); + } + else + { + /* We have one, check at which index we should insert our entry */ + Index = (HandleTable->NextHandleNeedingPool / SizeOfHandle(1)) - + i * MAX_MID_INDEX; + j = Index / LOW_LEVEL_ENTRIES; + + /* Allocate a new low level */ + Low = ExpAllocateLowLevelTable(HandleTable, DoInit); + if (!Low) return FALSE; + + /* Update the table pointer */ + Value = InterlockedExchangePointer(&ThirdLevel[i][j], Low); + ASSERT(Value == NULL); + } + } + + /* Update the index of the next handle */ + Index = InterlockedExchangeAdd(&HandleTable->NextHandleNeedingPool, + SizeOfHandle(LOW_LEVEL_ENTRIES)); + + /* Check if need to initialize the table */ + if (DoInit) + { + /* Create a new index number */ + Index += SizeOfHandle(1); + + /* Start free index change loop */ + for (;;) + { + /* Setup the first free index */ + FirstFree = HandleTable->FirstFree; + Low[LOW_LEVEL_ENTRIES - 1].NextFreeTableEntry = FirstFree; + + /* Change the index */ + NewFree = InterlockedCompareExchange(&HandleTable->FirstFree, + Index, + FirstFree); + if (NewFree == FirstFree) break; + } + } + + /* All done */ + return TRUE; +} + +ULONG +NTAPI +ExpMoveFreeHandles(IN PHANDLE_TABLE HandleTable) +{ + ULONG LastFree, i; + + /* Clear the last free index */ + LastFree = InterlockedExchange(&HandleTable->LastFree, 0); + + /* Check if we had no index */ + if (!LastFree) return LastFree; + + /* Acquire the locks we need */ + for (i = 1; i < 4; i++) + { + /* Acquire this lock exclusively */ + ExWaitOnPushLock(&HandleTable->HandleTableLock[i]); + } + + /* Check if we're not strict FIFO */ + if (!HandleTable->StrictFIFO) + { + /* Update the first free index */ + if (!InterlockedCompareExchange(&HandleTable->FirstFree, LastFree, 0)) + { + /* We're done, exit */ + return LastFree; + } + } + + /* We are strict FIFO, we need to reverse the entries */ KEBUGCHECK(0); - } - - if(QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - /* allocate enough memory for the handle table and the lowest level */ - HandleTable = ExAllocatePoolWithTag(NonPagedPool, - sizeof(HANDLE_TABLE) + (N_TOPLEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY*)), - TAG('E', 'x', 'H', 't')); - if(HandleTable != NULL) - { - /* initialize the handle table */ - HandleTable->Flags = 0; - HandleTable->HandleCount = 0; - HandleTable->Table = (PHANDLE_TABLE_ENTRY**)(HandleTable + 1); - HandleTable->QuotaProcess = QuotaProcess; - HandleTable->FirstFree = -1; /* no entries freed so far */ - HandleTable->NextHandleNeedingPool = 0; /* no entries freed so far, so we have to allocate already for the first handle */ - HandleTable->UniqueProcessId = (QuotaProcess ? QuotaProcess->UniqueProcessId : NULL); - - ExInitializeResource(&HandleTable->HandleLock); - - KeInitializeEvent(&HandleTable->HandleContentionEvent, - NotificationEvent, - FALSE); - - RtlZeroMemory(HandleTable->Table, N_TOPLEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY*)); - - /* during bootup KeGetCurrentThread() might be NULL, needs to be fixed... */ - if(KeGetCurrentThread() != NULL) - { - /* insert it into the global handle table list */ - KeEnterCriticalRegion(); - - ExAcquireHandleTableListLock(); - InsertTailList(&ExpHandleTableHead, - &HandleTable->HandleTableList); - ExReleaseHandleTableListLock(); - - KeLeaveCriticalRegion(); + return LastFree; +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable, + OUT PEXHANDLE NewHandle) +{ + ULONG OldValue, NewValue, NewValue1; + PHANDLE_TABLE_ENTRY Entry; + EXHANDLE Handle; + BOOLEAN Result; + ULONG i; + + /* Start allocation loop */ + for (;;) + { + /* Get the current link */ + OldValue = HandleTable->FirstFree; + while (!OldValue) + { + /* No free entries remain, lock the handle table */ + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&HandleTable->HandleTableLock[0]); + + /* Check the value again */ + OldValue = HandleTable->FirstFree; + if (OldValue) + { + /* Another thread has already created a new level, bail out */ + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + break; + } + + /* Now move any free handles */ + OldValue = ExpMoveFreeHandles(HandleTable); + if (OldValue) + { + /* Another thread has already moved them, bail out */ + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + break; + } + + /* We're the first one through, so do the actual allocation */ + Result = ExpAllocateHandleTableEntrySlow(HandleTable, TRUE); + + /* Unlock the table and get the value now */ + ExReleasePushLockExclusive(&HandleTable->HandleTableLock[0]); + KeLeaveCriticalRegion(); + OldValue = HandleTable->FirstFree; + + /* Check if allocation failed */ + if (!Result) + { + /* Check if nobody else went through here */ + if (!OldValue) + { + /* We're still the only thread around, so fail */ + NewHandle->GenericHandleOverlay = NULL; + return NULL; + } + } + } + + /* We made it, write the current value */ + Handle.Value = (OldValue & FREE_HANDLE_MASK); + + /* Lookup the entry for this handle */ + Entry = ExpLookupHandleTableEntry(HandleTable, Handle); + + /* Get an available lock and acquire it */ + i = ((OldValue & FREE_HANDLE_MASK) >> 2) % 4; + KeEnterCriticalRegion(); + ExAcquirePushLockShared(&HandleTable->HandleTableLock[i]); + + /* Check if the value changed after acquiring the lock */ + if (OldValue != HandleTable->FirstFree) + { + /* It did, so try again */ + ExReleasePushLockShared(&HandleTable->HandleTableLock[i]); + KeLeaveCriticalRegion(); + continue; + } + + /* Now get the next value and do the compare */ + NewValue = Entry->NextFreeTableEntry; + NewValue1 = InterlockedCompareExchange(&HandleTable->FirstFree, + NewValue, + OldValue); + + /* The change was done, so release the lock */ + ExReleasePushLockShared(&HandleTable->HandleTableLock[i]); + KeLeaveCriticalRegion(); + + /* Check if the compare was successful */ + if (NewValue1 == OldValue) + { + /* Make sure that the new handle is in range, and break out */ + ASSERT((NewValue & FREE_HANDLE_MASK) < + HandleTable->NextHandleNeedingPool); + break; + } + else + { + /* The compare failed, make sure we expected it */ + ASSERT((NewValue1 & FREE_HANDLE_MASK) != + (OldValue & FREE_HANDLE_MASK)); + } + } + + /* Increase the number of handles */ + InterlockedIncrement(&HandleTable->HandleCount); + + /* Return the handle and the entry */ + *NewHandle = Handle; + return Entry; +} + +PHANDLE_TABLE +NTAPI +ExCreateHandleTable(IN PEPROCESS Process OPTIONAL) +{ + PHANDLE_TABLE HandleTable; + PAGED_CODE(); + + /* Allocate the handle table */ + HandleTable = ExpAllocateHandleTable(Process, TRUE); + if (!HandleTable) return NULL; + + /* Acquire the handle table lock */ + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&HandleTableListLock); + + /* Insert it into the list */ + InsertTailList(&HandleTableListHead, &HandleTable->HandleTableList); + + /* Release the lock */ + ExReleasePushLockExclusive(&HandleTableListLock); + KeLeaveCriticalRegion(); + + /* Return the handle table */ + return HandleTable; +} + +HANDLE +NTAPI +ExCreateHandle(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + EXHANDLE Handle; + PHANDLE_TABLE_ENTRY NewEntry; + PAGED_CODE(); + + /* Start with a clean handle */ + Handle.GenericHandleOverlay = NULL; + + /* Allocate a new entry */ + NewEntry = ExpAllocateHandleTableEntry(HandleTable, &Handle); + if (NewEntry) + { + /* Enter a critical region */ + KeEnterCriticalRegion(); + + /* Write the entry */ + *NewEntry = *HandleTableEntry; + + /* Unlock it and leave the critical region */ + ExUnlockHandleTableEntry(HandleTable, NewEntry); + KeLeaveCriticalRegion(); + } + + /* Return the handle value */ + return Handle.GenericHandleOverlay; +} + +VOID +NTAPI +ExpBlockOnLockedHandleEntry(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + LONG_PTR OldValue; + DEFINE_WAIT_BLOCK(WaitBlock); + + /* Block on the pushlock */ + ExBlockPushLock(&HandleTable->HandleContentionEvent, WaitBlock); + + /* Get the current value and check if it's been unlocked */ + OldValue = HandleTableEntry->Value; + if (!(OldValue) || (OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT)) + { + /* Unblock the pushlock and return */ + ExfUnblockPushLock(&HandleTable->HandleContentionEvent, WaitBlock); } else { - InsertTailList(&ExpHandleTableHead, - &HandleTable->HandleTableList); - } - } - else - { - /* FIXME - return the quota to the process */ - } - - return HandleTable; + /* Wait for it to be unblocked */ + ExWaitForUnblockPushLock(&HandleTable->HandleContentionEvent, + WaitBlock); + } +} + +BOOLEAN +NTAPI +ExpLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + LONG_PTR NewValue, OldValue; + + /* Sanity check */ + ASSERT((KeGetCurrentThread()->CombinedApcDisable != 0) || + (KeGetCurrentIrql() == APC_LEVEL)); + + /* Start lock loop */ + for (;;) + { + /* Get the current value and check if it's locked */ + OldValue = (LONG_PTR)HandleTableEntry->Object; + if (OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT) + { + /* It's not locked, remove the lock bit to lock it */ + NewValue = OldValue & ~EXHANDLE_TABLE_ENTRY_LOCK_BIT; + if (InterlockedCompareExchangePointer(&HandleTableEntry->Object, + NewValue, + OldValue) == (PVOID)OldValue) + { + /* We locked it, get out */ + return TRUE; + } + } + else + { + /* We couldn't lock it, bail out if it's been freed */ + if (!OldValue) return FALSE; + } + + /* It's locked, wait for it to be unlocked */ + ExpBlockOnLockedHandleEntry(HandleTable, HandleTableEntry); + } } VOID -ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, - IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL) -{ - PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp; - LONG ExHandle = 0; - - PAGED_CODE(); - - ASSERT(HandleTable); - - KeEnterCriticalRegion(); - - /* ensure there's no other operations going by acquiring an exclusive lock */ - ExAcquireHandleLockExclusive(HandleTable); - - ASSERT(!(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING)); - - HandleTable->Flags |= EX_HANDLE_TABLE_CLOSING; - - KePulseEvent(&HandleTable->HandleContentionEvent, - EVENT_INCREMENT, - FALSE); - - /* call the callback function to cleanup the objects associated with the - handle table */ - for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS; - tlp != lasttlp; - tlp++) - { - if((*tlp) != NULL) - { - for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS; - mlp != lastmlp; - mlp++) - { - if((*mlp) != NULL) - { - PHANDLE_TABLE_ENTRY curee, laste; - - for(curee = *mlp, laste = *mlp + N_SUBHANDLE_ENTRIES; - curee != laste; - curee++) - { - if(curee->Object != NULL && SweepHandleCallback != NULL) +NTAPI +ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) +{ + LONG_PTR OldValue; + PAGED_CODE(); + + /* Sanity check */ + ASSERT((KeGetCurrentThread()->CombinedApcDisable != 0) || + (KeGetCurrentIrql() == APC_LEVEL)); + + /* Set the lock bit and make sure it wasn't earlier */ + OldValue = InterlockedOr(&HandleTableEntry->Value, + EXHANDLE_TABLE_ENTRY_LOCK_BIT); + ASSERT((OldValue & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0); + + /* Unblock any waiters */ + ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL); +} + +VOID +NTAPI +ExRemoveHandleTable(IN PHANDLE_TABLE HandleTable) +{ + PAGED_CODE(); + + /* Acquire the table lock */ + KeEnterCriticalRegion(); + ExAcquirePushLockExclusive(&HandleTableListLock); + + /* Remove the table and reset the list */ + RemoveEntryList(&HandleTable->HandleTableList); + InitializeListHead(&HandleTable->HandleTableList); + + /* Release the lock */ + ExReleasePushLockExclusive(&HandleTableListLock); + KeLeaveCriticalRegion(); +} + +VOID +NTAPI +ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable, + IN PVOID DestroyHandleProcedure OPTIONAL) +{ + PAGED_CODE(); + + /* Remove the handle from the list */ + ExRemoveHandleTable(HandleTable); + + /* Check if we have a desotry callback */ + if (DestroyHandleProcedure) + { + /* FIXME: */ + KEBUGCHECK(0); + } + + /* Free the handle table */ + ExpFreeHandleTable(HandleTable); +} + +BOOLEAN +NTAPI +ExDestroyHandle(IN PHANDLE_TABLE HandleTable, + IN HANDLE Handle, + IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL) +{ + EXHANDLE ExHandle; + PVOID Object; + PAGED_CODE(); + + /* Setup the actual handle value */ + ExHandle.GenericHandleOverlay = Handle; + + /* Enter a critical region and check if we have to lookup the handle */ + KeEnterCriticalRegion(); + if (!HandleTableEntry) + { + /* Lookup the entry */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle); + + /* Make sure that we found an entry, and that it's valid */ + if (!(HandleTableEntry) || + !(HandleTableEntry->Object) || + (HandleTableEntry->NextFreeTableEntry == -2)) + { + /* Invalid handle, fail */ + KeLeaveCriticalRegion(); + return FALSE; + } + + /* Lock the entry */ + if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) + { + /* Couldn't lock, fail */ + KeLeaveCriticalRegion(); + return FALSE; + } + } + else + { + /* Make sure the handle is locked */ + ASSERT((HandleTableEntry->Value & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0); + } + + /* Clear the handle */ + Object = InterlockedExchangePointer(&HandleTableEntry->Object, NULL); + + /* Sanity checks */ + ASSERT(Object != NULL); + ASSERT((((ULONG_PTR)Object) & EXHANDLE_TABLE_ENTRY_LOCK_BIT) == 0); + + /* Unblock the pushlock */ + ExfUnblockPushLock(&HandleTable->HandleContentionEvent, NULL); + + /* Free the actual entry */ + ExpFreeHandleTableEntry(HandleTable, ExHandle, HandleTableEntry); + + /* If we got here, return success */ + KeLeaveCriticalRegion(); + return TRUE; +} + +PHANDLE_TABLE_ENTRY +NTAPI +ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, + IN HANDLE Handle) +{ + EXHANDLE ExHandle; + PHANDLE_TABLE_ENTRY HandleTableEntry; + PAGED_CODE(); + + /* Set the handle value */ + ExHandle.GenericHandleOverlay = Handle; + + /* Fail if we got an invalid index */ + if (!(ExHandle.Index & (LOW_LEVEL_ENTRIES - 1))) return NULL; + + /* Do the lookup */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle); + if (!HandleTableEntry) return NULL; + + /* Lock it */ + if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) return NULL; + + /* Return the entry */ + return HandleTableEntry; +} + +PHANDLE_TABLE +NTAPI +ExDupHandleTable(IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, + IN ULONG_PTR Mask) +{ + PHANDLE_TABLE NewTable; + EXHANDLE Handle; + PHANDLE_TABLE_ENTRY HandleTableEntry, NewEntry; + BOOLEAN Failed = FALSE; + PAGED_CODE(); + + /* Allocate the duplicated copy */ + NewTable = ExpAllocateHandleTable(Process, FALSE); + if (!NewTable) return NULL; + + /* Loop each entry */ + while (NewTable->NextHandleNeedingPool < + HandleTable->NextHandleNeedingPool) + { + /* Insert it into the duplicated copy */ + if (!ExpAllocateHandleTableEntrySlow(NewTable, FALSE)) + { + /* Insert failed, free the new copy and return */ + ExpFreeHandleTable(NewTable); + return NULL; + } + } + + /* Setup the initial handle table data */ + NewTable->HandleCount = 0; + NewTable->ExtraInfoPages = 0; + NewTable->FirstFree = 0; + + /* Setup the first handle value */ + Handle.Value = SizeOfHandle(1); + + /* Enter a critical region and lookup the new entry */ + KeEnterCriticalRegion(); + while ((NewEntry = ExpLookupHandleTableEntry(NewTable, Handle))) + { + /* Lookup the old entry */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle); + + /* Loop each entry */ + do + { + /* Check if it doesn't match the audit mask */ + if (!(HandleTableEntry->Value & Mask)) { - curee->ObAttributes |= EX_HANDLE_ENTRY_LOCKED; - SweepHandleCallback(curee, EX_HANDLE_TO_HANDLE(ExHandle), Context); - } - - ExHandle++; - } - } - else - break; - } - } - else - break; - } - - ExReleaseHandleLock(HandleTable); - - KeLeaveCriticalRegion(); -} - -VOID -ExDestroyHandleTable(IN PHANDLE_TABLE HandleTable) -{ - PHANDLE_TABLE_ENTRY **tlp, **lasttlp, *mlp, *lastmlp; - PEPROCESS QuotaProcess; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING); - - KeEnterCriticalRegion(); - - /* at this point the table should not be queried or altered anymore, - no locks should be necessary */ - - ASSERT(HandleTable->Flags & EX_HANDLE_TABLE_CLOSING); - - /* remove the handle table from the global handle table list */ - ExAcquireHandleTableListLock(); - RemoveEntryList(&HandleTable->HandleTableList); - ExReleaseHandleTableListLock(); - - QuotaProcess = HandleTable->QuotaProcess; - - /* free the tables */ - for(tlp = HandleTable->Table, lasttlp = HandleTable->Table + N_TOPLEVEL_POINTERS; - tlp != lasttlp; - tlp++) - { - if((*tlp) != NULL) - { - for(mlp = *tlp, lastmlp = (*tlp) + N_MIDDLELEVEL_POINTERS; - mlp != lastmlp; - mlp++) - { - if((*mlp) != NULL) - { - ExFreePool(*mlp); - - if(QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } - } - } - - ExFreePool(*tlp); - - if(QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } - } - } - - KeLeaveCriticalRegion(); - - /* free the handle table */ - ExDeleteResource(&HandleTable->HandleLock); - ExFreePool(HandleTable); - - if(QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } -} - -PHANDLE_TABLE -ExDupHandleTable(IN PEPROCESS QuotaProcess OPTIONAL, - IN PEX_DUPLICATE_HANDLE_CALLBACK DuplicateHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL, - IN PHANDLE_TABLE SourceHandleTable) -{ - PHANDLE_TABLE HandleTable; - - PAGED_CODE(); - - ASSERT(SourceHandleTable); - - HandleTable = ExCreateHandleTable(QuotaProcess); - if(HandleTable != NULL) - { - PHANDLE_TABLE_ENTRY **tlp, **srctlp, **etlp, *mlp, *srcmlp, *emlp, stbl, srcstbl, estbl; - LONG tli, mli, eli; - - tli = mli = eli = 0; - - /* make sure the other handle table isn't being changed during the duplication */ - ExAcquireHandleLockShared(SourceHandleTable); - - /* allocate enough tables */ - etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS; - for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table; - srctlp != etlp; - srctlp++, tlp++) - { - if(*srctlp != NULL) - { - /* allocate middle level entry tables */ - if(QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - *tlp = ExAllocatePoolWithTag(PagedPool, - N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(*tlp != NULL) - { - RtlZeroMemory(*tlp, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY)); - - KeMemoryBarrier(); - - emlp = *srctlp + N_MIDDLELEVEL_POINTERS; - for(srcmlp = *srctlp, mlp = *tlp; - srcmlp != emlp; - srcmlp++, mlp++) - { - if(*srcmlp != NULL) - { - /* allocate subhandle tables */ - if(QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - *mlp = ExAllocatePoolWithTag(PagedPool, - N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(*mlp != NULL) - { - RtlZeroMemory(*mlp, N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY)); - } - else - { - goto freehandletable; - } + /* Free it since we won't use it */ + Failed = TRUE; } else { - *mlp = NULL; - } - } - } - else - { -freehandletable: - DPRINT1("Failed to duplicate handle table 0x%p\n", SourceHandleTable); - - ExReleaseHandleLock(SourceHandleTable); - - ExDestroyHandleTable(HandleTable); - /* allocate an empty handle table */ - return ExCreateHandleTable(QuotaProcess); - } - } - } - - /* duplicate the handles */ - HandleTable->HandleCount = SourceHandleTable->HandleCount; - HandleTable->FirstFree = SourceHandleTable->FirstFree; - HandleTable->NextHandleNeedingPool = SourceHandleTable->NextHandleNeedingPool; - - /* make sure all tables are zeroed */ - KeMemoryBarrier(); - - etlp = SourceHandleTable->Table + N_TOPLEVEL_POINTERS; - for(srctlp = SourceHandleTable->Table, tlp = HandleTable->Table; - srctlp != etlp; - srctlp++, tlp++, tli++) - { - if(*srctlp != NULL) - { - ASSERT(*tlp != NULL); - - emlp = *srctlp + N_MIDDLELEVEL_POINTERS; - for(srcmlp = *srctlp, mlp = *tlp; - srcmlp != emlp; - srcmlp++, mlp++, mli++) - { - if(*srcmlp != NULL) - { - ASSERT(*mlp != NULL); - - /* walk all handle entries and duplicate them if wanted */ - estbl = *srcmlp + N_SUBHANDLE_ENTRIES; - for(srcstbl = *srcmlp, stbl = *mlp; - srcstbl != estbl; - srcstbl++, stbl++, eli++) - { - /* try to duplicate the source handle */ - if(srcstbl->Object != NULL && - ExLockHandleTableEntry(SourceHandleTable, - srcstbl)) - { - /* ask the caller if this handle should be duplicated */ - if(DuplicateHandleCallback != NULL && - !DuplicateHandleCallback(HandleTable, - srcstbl, - Context)) + /* Lock the entry */ + if (!ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) { - /* free the entry and chain it into the free list */ - HandleTable->HandleCount--; - stbl->Object = NULL; - stbl->NextFreeTableEntry = HandleTable->FirstFree; - HandleTable->FirstFree = BUILD_HANDLE(tli, mli, eli); + /* Free it since we can't lock it, so we won't use it */ + Failed = TRUE; } else { - /* duplicate the handle and unlock it */ - stbl->GrantedAccess = srcstbl->GrantedAccess; - stbl->ObAttributes = srcstbl->ObAttributes & ~EX_HANDLE_ENTRY_LOCKED; + /* Copy the handle value */ + *NewEntry = *HandleTableEntry; + + /* Call the duplicate callback */ + if (DupHandleProcedure(Process, + HandleTable, + HandleTableEntry, + NewEntry)) + { + /* Lock the entry, increase the handle count */ + NewEntry->Value |= EXHANDLE_TABLE_ENTRY_LOCK_BIT; + NewTable->HandleCount++; + } + else + { + /* Duplication callback refused, fail */ + Failed = TRUE; + } } - ExUnlockHandleTableEntry(SourceHandleTable, - srcstbl); - } - else - { - /* this is a free handle table entry, copy over the entire - structure as-is */ - *stbl = *srcstbl; - } } - } - } - } - } - - /* release the source handle table */ - ExReleaseHandleLock(SourceHandleTable); - } - - return HandleTable; -} - -static PHANDLE_TABLE_ENTRY -ExpAllocateHandleTableEntry(IN PHANDLE_TABLE HandleTable, - OUT PHANDLE Handle) -{ - PHANDLE_TABLE_ENTRY Entry = NULL; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Handle); - ASSERT(KeGetCurrentThread() != NULL); - - DPRINT("HT[0x%p]: HandleCount: %d\n", HandleTable, HandleTable->HandleCount); - - if(HandleTable->HandleCount < EX_MAX_HANDLES) - { - ULONG tli, mli, eli; - - if(HandleTable->FirstFree != -1) - { - /* there's a free handle entry we can just grab and use */ - tli = TLI_FROM_HANDLE(HandleTable->FirstFree); - mli = MLI_FROM_HANDLE(HandleTable->FirstFree); - eli = ELI_FROM_HANDLE(HandleTable->FirstFree); - - /* the pointer should be valid in any way!!! */ - ASSERT(HandleTable->Table[tli]); - ASSERT(HandleTable->Table[tli][mli]); - - Entry = &HandleTable->Table[tli][mli][eli]; - - *Handle = EX_HANDLE_TO_HANDLE(HandleTable->FirstFree); - - /* save the index to the next free handle (if available) */ - HandleTable->FirstFree = Entry->NextFreeTableEntry; - Entry->NextFreeTableEntry = 0; - Entry->Object = NULL; - - HandleTable->HandleCount++; - } - else - { - /* we need to allocate a new subhandle table first */ - PHANDLE_TABLE_ENTRY cure, laste, ntbl, *nmtbl; - ULONG i; - BOOLEAN AllocatedMtbl; - - ASSERT(HandleTable->NextHandleNeedingPool <= N_MAX_HANDLE); - - /* the index of the next table to be allocated was saved in - NextHandleNeedingPool the last time a handle entry was allocated and - the subhandle entry list was full. the subhandle entry index of - NextHandleNeedingPool should be 0 here! */ - tli = TLI_FROM_HANDLE(HandleTable->NextHandleNeedingPool); - mli = MLI_FROM_HANDLE(HandleTable->NextHandleNeedingPool); - DPRINT("HandleTable->NextHandleNeedingPool: 0x%x\n", HandleTable->NextHandleNeedingPool); - DPRINT("tli: 0x%x mli: 0x%x eli: 0x%x\n", tli, mli, ELI_FROM_HANDLE(HandleTable->NextHandleNeedingPool)); - - ASSERT(ELI_FROM_HANDLE(HandleTable->NextHandleNeedingPool) == 0); - - DPRINT("HandleTable->Table[%d] == 0x%p\n", tli, HandleTable->Table[tli]); - - /* allocate a middle level entry list if required */ - nmtbl = HandleTable->Table[tli]; - if(nmtbl == NULL) - { - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - nmtbl = ExAllocatePoolWithTag(PagedPool, - N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(nmtbl == NULL) - { - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - return the quota to the process */ - } - - return NULL; - } - - /* clear the middle level entry list */ - RtlZeroMemory(nmtbl, N_MIDDLELEVEL_POINTERS * sizeof(PHANDLE_TABLE_ENTRY)); - - /* make sure the table was zeroed before we set one item */ - KeMemoryBarrier(); - - /* note, don't set the the pointer in the top level list yet because we - might screw up lookups if allocating a subhandle entry table failed - and this newly allocated table might get freed again */ - AllocatedMtbl = TRUE; - } - else - { - AllocatedMtbl = FALSE; - - /* allocate a subhandle entry table in any case! */ - ASSERT(nmtbl[mli] == NULL); - } - - DPRINT("HandleTable->Table[%d][%d] == 0x%p\n", tli, mli, nmtbl[mli]); - - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Charge process quota before allocating the handle table! */ - } - - ntbl = ExAllocatePoolWithTag(PagedPool, - N_SUBHANDLE_ENTRIES * sizeof(HANDLE_TABLE_ENTRY), - TAG('E', 'x', 'H', 't')); - if(ntbl == NULL) - { - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Return process quota charged */ - } - - /* free the middle level entry list, if allocated, because it's empty and - unused */ - if(AllocatedMtbl) - { - ExFreePool(nmtbl); - - if(HandleTable->QuotaProcess != NULL) - { - /* FIXME - Return process quota charged */ - } - } - - return NULL; - } - - /* let's just use the very first entry */ - Entry = ntbl; - Entry->ObAttributes = EX_HANDLE_ENTRY_LOCKED; - Entry->NextFreeTableEntry = 0; - - *Handle = EX_HANDLE_TO_HANDLE(HandleTable->NextHandleNeedingPool); - - HandleTable->HandleCount++; - - /* set the FirstFree member to the second entry and chain the - free entries */ - HandleTable->FirstFree = HandleTable->NextHandleNeedingPool + 1; - for(cure = Entry + 1, laste = Entry + N_SUBHANDLE_ENTRIES, i = HandleTable->FirstFree + 1; - cure != laste; - cure++, i++) - { - cure->Object = NULL; - cure->NextFreeTableEntry = i; - } - /* truncate the free entry list */ - (cure - 1)->NextFreeTableEntry = -1; - - /* save the pointers to the allocated list(s) */ - (void)InterlockedExchangePointer(&nmtbl[mli], ntbl); - if(AllocatedMtbl) - { - (void)InterlockedExchangePointer(&HandleTable->Table[tli], nmtbl); - } - - /* increment the NextHandleNeedingPool to the next index where we need to - allocate new memory */ - HandleTable->NextHandleNeedingPool += N_SUBHANDLE_ENTRIES; - } - } - else - { - DPRINT1("Can't allocate any more handles in handle table 0x%p!\n", HandleTable); - } - - return Entry; -} - -static VOID -ExpFreeHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry, - IN LONG Handle) -{ - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - ASSERT(IS_VALID_EX_HANDLE(Handle)); - - DPRINT("ExpFreeHandleTableEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry); - - /* automatically unlock the entry if currently locked. We however don't notify - anyone who waited on the handle because we're holding an exclusive lock after - all and these locks will fail then */ - (void)InterlockedExchangePointer(&Entry->Object, NULL); - Entry->NextFreeTableEntry = HandleTable->FirstFree; - HandleTable->FirstFree = Handle; - - HandleTable->HandleCount--; -} - -static PHANDLE_TABLE_ENTRY -ExpLookupHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN LONG Handle) -{ - PHANDLE_TABLE_ENTRY Entry = NULL; - - PAGED_CODE(); - - ASSERT(HandleTable); - - if(IS_VALID_EX_HANDLE(Handle)) - { - ULONG tli, mli, eli; - PHANDLE_TABLE_ENTRY *mlp; - - tli = TLI_FROM_HANDLE(Handle); - mli = MLI_FROM_HANDLE(Handle); - eli = ELI_FROM_HANDLE(Handle); - - mlp = HandleTable->Table[tli]; - if(Handle < HandleTable->NextHandleNeedingPool && - mlp != NULL && mlp[mli] != NULL && mlp[mli][eli].Object != NULL) - { - Entry = &mlp[mli][eli]; - DPRINT("handle lookup 0x%x -> entry 0x%p [HT:0x%p] ptr: 0x%p\n", Handle, Entry, HandleTable, mlp[mli][eli].Object); - } - } - else - { - DPRINT("Looking up invalid handle 0x%x\n", Handle); - } - - return Entry; + + /* Check if we failed earlier and need to free */ + if (Failed) + { + /* Free this entry */ + NewEntry->Object = NULL; + NewEntry->NextFreeTableEntry = NewTable->FirstFree; + NewTable->FirstFree = Handle.Value; + } + + /* Increase the handle value and move to the next entry */ + Handle.Value += SizeOfHandle(1); + NewEntry++; + HandleTableEntry++; + } while (Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES)); + + /* We're done, skip the last entry */ + Handle.Value += SizeOfHandle(1); + } + + /* Acquire the table lock and insert this new table into the list */ + ExAcquirePushLockExclusive(&HandleTableListLock); + InsertTailList(&HandleTableListHead, &NewTable->HandleTableList); + ExReleasePushLockExclusive(&HandleTableListLock); + + /* Leave the critical region we entered previously and return the table */ + KeLeaveCriticalRegion(); + return NewTable; } BOOLEAN -ExLockHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry) -{ - ULONG_PTR Current, New; - - PAGED_CODE(); - - DPRINT("Entering handle table entry 0x%p lock...\n", Entry); - - ASSERT(HandleTable); - ASSERT(Entry); - - for(;;) - { - Current = (volatile ULONG_PTR)Entry->Object; - - if(!Current || (HandleTable->Flags & EX_HANDLE_TABLE_CLOSING)) - { - DPRINT("Attempted to lock empty handle table entry 0x%p or handle table shut down\n", Entry); - break; - } - - if(!(Current & EX_HANDLE_ENTRY_LOCKED)) - { - New = Current | EX_HANDLE_ENTRY_LOCKED; - if(InterlockedCompareExchangePointer(&Entry->Object, - (PVOID)New, - (PVOID)Current) == (PVOID)Current) - { - DPRINT("SUCCESS handle table 0x%p entry 0x%p lock\n", HandleTable, Entry); - /* we acquired the lock */ - return TRUE; - } - } - - /* wait about 5ms at maximum so we don't wait forever in unfortunate - co-incidences where releasing the lock in another thread happens right - before we're waiting on the contention event to get pulsed, which might - never happen again... */ - KeWaitForSingleObject(&HandleTable->HandleContentionEvent, - Executive, - KernelMode, - FALSE, - &ExpHandleShortWait); - } - - return FALSE; -} - -VOID -ExUnlockHandleTableEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry) -{ - ULONG_PTR Current, New; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - - DPRINT("ExUnlockHandleTableEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry); - - Current = (volatile ULONG_PTR)Entry->Object; - - ASSERT(Current & EX_HANDLE_ENTRY_LOCKED); - - New = Current & ~EX_HANDLE_ENTRY_LOCKED; - - (void)InterlockedExchangePointer(&Entry->Object, - (PVOID)New); - - /* we unlocked the entry, pulse the contention event so threads who're waiting - on the release can continue */ - KePulseEvent(&HandleTable->HandleContentionEvent, - EVENT_INCREMENT, - FALSE); -} - -HANDLE -ExCreateHandle(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry) -{ - PHANDLE_TABLE_ENTRY NewHandleTableEntry; - HANDLE Handle = NULL; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - - /* The highest bit in Entry->Object has to be 1 so we make sure it's a - pointer to kmode memory. It will cleared though because it also indicates - the lock */ - ASSERT((ULONG_PTR)Entry->Object & EX_HANDLE_ENTRY_LOCKED); - - KeEnterCriticalRegion(); - ExAcquireHandleLockExclusive(HandleTable); - - NewHandleTableEntry = ExpAllocateHandleTableEntry(HandleTable, - &Handle); - if(NewHandleTableEntry != NULL) - { - *NewHandleTableEntry = *Entry; - - ExUnlockHandleTableEntry(HandleTable, - NewHandleTableEntry); - } - - ExReleaseHandleLock(HandleTable); - KeLeaveCriticalRegion(); - - return Handle; -} - -BOOLEAN -ExDestroyHandle(IN PHANDLE_TABLE HandleTable, - IN HANDLE Handle) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - LONG ExHandle; - BOOLEAN Ret = FALSE; - - PAGED_CODE(); - - ASSERT(HandleTable); - - ExHandle = HANDLE_TO_EX_HANDLE(Handle); - - KeEnterCriticalRegion(); - ExAcquireHandleLockExclusive(HandleTable); - - HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, - ExHandle); - - if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry)) - { - /* free and automatically unlock the handle. However we don't need to pulse - the contention event since other locks on this entry will fail */ - ExpFreeHandleTableEntry(HandleTable, - HandleTableEntry, - ExHandle); - Ret = TRUE; - } - - ExReleaseHandleLock(HandleTable); - KeLeaveCriticalRegion(); - - return Ret; -} - -VOID -ExDestroyHandleByEntry(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry, - IN HANDLE Handle) -{ - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(Entry); - - /* This routine requires the entry to be locked */ - ASSERT((ULONG_PTR)Entry->Object & EX_HANDLE_ENTRY_LOCKED); - - DPRINT("DestroyHandleByEntry HT:0x%p Entry:0x%p\n", HandleTable, Entry); - - KeEnterCriticalRegion(); - ExAcquireHandleLockExclusive(HandleTable); - - /* free and automatically unlock the handle. However we don't need to pulse - the contention event since other locks on this entry will fail */ - ExpFreeHandleTableEntry(HandleTable, - Entry, - HANDLE_TO_EX_HANDLE(Handle)); - - ExReleaseHandleLock(HandleTable); - KeLeaveCriticalRegion(); -} - -PHANDLE_TABLE_ENTRY -ExMapHandleToPointer(IN PHANDLE_TABLE HandleTable, - IN HANDLE Handle) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - - PAGED_CODE(); - - ASSERT(HandleTable); - - HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, - HANDLE_TO_EX_HANDLE(Handle)); - if (HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry)) - { - DPRINT("ExMapHandleToPointer HT:0x%p Entry:0x%p locked\n", HandleTable, HandleTableEntry); - return HandleTableEntry; - } - - return NULL; -} - -BOOLEAN +NTAPI ExChangeHandle(IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, - IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback, - IN PVOID Context) -{ - PHANDLE_TABLE_ENTRY HandleTableEntry; - BOOLEAN Ret = FALSE; - - PAGED_CODE(); - - ASSERT(HandleTable); - ASSERT(ChangeHandleCallback); - - KeEnterCriticalRegion(); - - HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, - HANDLE_TO_EX_HANDLE(Handle)); - - if(HandleTableEntry != NULL && ExLockHandleTableEntry(HandleTable, HandleTableEntry)) - { - Ret = ChangeHandleCallback(HandleTable, - HandleTableEntry, - Context); - - ExUnlockHandleTableEntry(HandleTable, - HandleTableEntry); - } - - KeLeaveCriticalRegion(); - - return Ret; -} - -/* EOF */ + IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, + IN ULONG_PTR Context) +{ + EXHANDLE ExHandle; + PHANDLE_TABLE_ENTRY HandleTableEntry; + BOOLEAN Result = FALSE; + PAGED_CODE(); + + /* Set the handle value */ + ExHandle.GenericHandleOverlay = Handle; + + /* Find the entry for this handle */ + HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, ExHandle); + + /* Make sure that we found an entry, and that it's valid */ + if (!(HandleTableEntry) || + !(HandleTableEntry->Object) || + (HandleTableEntry->NextFreeTableEntry == -2)) + { + /* It isn't, fail */ + return FALSE; + } + + /* Enter a critical region */ + KeEnterCriticalRegion(); + + /* Try locking the handle entry */ + if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) + { + /* Call the change routine and unlock the entry */ + Result = ChangeRoutine(HandleTableEntry, Context); + ExUnlockHandleTableEntry(HandleTable, HandleTableEntry); + } + + /* Leave the critical region and return the callback result */ + KeLeaveCriticalRegion(); + return Result; +} + +VOID +NTAPI +ExSweepHandleTable(IN PHANDLE_TABLE HandleTable, + IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, + IN PVOID Context) +{ + EXHANDLE Handle; + PHANDLE_TABLE_ENTRY HandleTableEntry; + PAGED_CODE(); + + /* Set the initial value and loop the entries */ + Handle.Value = SizeOfHandle(1); + while ((HandleTableEntry = ExpLookupHandleTableEntry(HandleTable, Handle))) + { + /* Loop each handle */ + do + { + /* Lock the entry */ + if (ExpLockHandleTableEntry(HandleTable, HandleTableEntry)) + { + /* Notify the callback routine */ + EnumHandleProcedure(HandleTableEntry, + Handle.GenericHandleOverlay, + Context); + } + + /* Go to the next handle and entry */ + Handle.Value += SizeOfHandle(1); + HandleTableEntry++; + } while (Handle.Value % SizeOfHandle(LOW_LEVEL_ENTRIES)); + + /* Skip past the last entry */ + Handle.Value += SizeOfHandle(1); + } +} Modified: trunk/reactos/ntoskrnl/include/internal/ex.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ex.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ex.h Mon Jan 22 11:15:17 2007 @@ -21,6 +21,20 @@ ULONG ExpUnicodeCaseTableDataOffset; PVOID ExpNlsSectionPointer; +typedef struct _EXHANDLE +{ + union + { + struct + { + ULONG TagBits:2; + ULONG Index:30; + }; + HANDLE GenericHandleOverlay; + ULONG_PTR Value; + }; +} EXHANDLE, *PEXHANDLE; + typedef struct _ETIMER { KTIMER KeTimer; @@ -42,13 +56,6 @@ #define MAX_FAST_REFS 7 -#define EX_OBJ_TO_HDR(eob) ((POBJECT_HEADER)((ULONG_PTR)(eob) & \ - ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \ - EX_HANDLE_ENTRY_AUDITONCLOSE))) -#define EX_HTE_TO_HDR(hte) ((POBJECT_HEADER)((ULONG_PTR)((hte)->Object) & \ - ~(EX_HANDLE_ENTRY_PROTECTFROMCLOSE | EX_HANDLE_ENTRY_INHERITABLE | \ - EX_HANDLE_ENTRY_AUDITONCLOSE))) - /* Note: we only use a spinlock on SMP. On UP, we cli/sti intead */ #ifndef CONFIG_SMP #define ExAcquireResourceLock(l, i) { \ @@ -67,6 +74,27 @@ #define ExWaitForRundownProtectionRelease _ExWaitForRundownProtectionRelease #define ExRundownCompleted _ExRundownCompleted #define ExGetPreviousMode KeGetPreviousMode + + +// +// Various bits tagged on the handle or handle table +// +#define EXHANDLE_TABLE_ENTRY_LOCK_BIT 1 +#define FREE_HANDLE_MASK -1 + +// +// Number of entries in each table level +// +#define LOW_LEVEL_ENTRIES (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)) +#define MID_LEVEL_ENTRIES (PAGE_SIZE / sizeof(PHANDLE_TABLE_ENTRY)) +#define HIGH_LEVEL_ENTRIES (65535 / (LOW_LEVEL_ENTRIES * MID_LEVEL_ENTRIES)) + +// +// Maximum index in each table level before we need another table +// +#define MAX_LOW_INDEX LOW_LEVEL_ENTRIES +#define MAX_MID_INDEX (MID_LEVEL_ENTRIES * LOW_LEVEL_ENTRIES) +#define MAX_HIGH_INDEX (MID_LEVEL_ENTRIES * MID_LEVEL_ENTRIES * LOW_LEVEL_ENTRIES) // // Detect GCC 4.1.2+ @@ -308,104 +336,98 @@ /* HANDLE TABLE FUNCTIONS ***************************************************/ -#define EX_HANDLE_ENTRY_LOCKED (1 << ((sizeof(PVOID) * 8) - 1)) -#define EX_HANDLE_ENTRY_PROTECTFROMCLOSE (1 << 0) -#define EX_HANDLE_ENTRY_INHERITABLE (1 << 1) -#define EX_HANDLE_ENTRY_AUDITONCLOSE (1 << 2) - -#define EX_HANDLE_TABLE_CLOSING 0x1 - -#define EX_HANDLE_ENTRY_FLAGSMASK (EX_HANDLE_ENTRY_LOCKED | \ - EX_HANDLE_ENTRY_PROTECTFROMCLOSE | \ - EX_HANDLE_ENTRY_INHERITABLE | \ - EX_HANDLE_ENTRY_AUDITONCLOSE) - -typedef VOID (NTAPI PEX_SWEEP_HANDLE_CALLBACK)( +typedef VOID +(NTAPI *PEX_SWEEP_HANDLE_CALLBACK)( PHANDLE_TABLE_ENTRY HandleTableEntry, - HANDLE Handle, + HANDLE Handle, PVOID Context ); -typedef BOOLEAN (NTAPI PEX_DUPLICATE_HANDLE_CALLBACK)( - PHANDLE_TABLE HandleTable, - PHANDLE_TABLE_ENTRY HandleTableEntry, - PVOID Context -); - -typedef BOOLEAN (NTAPI PEX_CHANGE_HANDLE_CALLBACK)( - PHANDLE_TABLE HandleTable, - PHANDLE_TABLE_ENTRY HandleTableEntry, - PVOID Context -); - -VOID -ExpInitializeHandleTables(VOID); +typedef BOOLEAN +(NTAPI *PEX_DUPLICATE_HANDLE_CALLBACK)( + IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY HandleTableEntry, + IN PHANDLE_TABLE_ENTRY NewEntry +); + +typedef BOOLEAN +(NTAPI *PEX_CHANGE_HANDLE_CALLBACK)( + PHANDLE_TABLE_ENTRY HandleTableEntry, + ULONG_PTR Context +); + +VOID +NTAPI +ExpInitializeHandleTables( + VOID +); PHANDLE_TABLE -ExCreateHandleTable(IN PEPROCESS QuotaProcess OPTIONAL); - -VOID -ExDestroyHandleTable( - IN PHANDLE_TABLE HandleTable -); - -VOID -ExSweepHandleTable( - IN PHANDLE_TABLE HandleTable, - IN PEX_SWEEP_HANDLE_CALLBACK SweepHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL -); - -PHANDLE_TABLE -ExDupHandleTable( - IN PEPROCESS QuotaProcess OPTIONAL, - IN PEX_DUPLICATE_HANDLE_CALLBACK DuplicateHandleCallback OPTIONAL, - IN PVOID Context OPTIONAL, - IN PHANDLE_TABLE SourceHandleTable -); - -BOOLEAN -ExLockHandleTableEntry( - IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry -); - -VOID +NTAPI +ExCreateHandleTable( + IN PEPROCESS Process OPTIONAL +); + +VOID +NTAPI ExUnlockHandleTableEntry( IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry + IN PHANDLE_TABLE_ENTRY HandleTableEntry ); HANDLE +NTAPI ExCreateHandle( IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry + IN PHANDLE_TABLE_ENTRY HandleTableEntry +); + +VOID +NTAPI +ExDestroyHandleTable( + IN PHANDLE_TABLE HandleTable, + IN PVOID DestroyHandleProcedure OPTIONAL ); BOOLEAN +NTAPI ExDestroyHandle( IN PHANDLE_TABLE HandleTable, - IN HANDLE Handle -); - -VOID -ExDestroyHandleByEntry( - IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY Entry, - IN HANDLE Handle + IN HANDLE Handle, + IN PHANDLE_TABLE_ENTRY HandleTableEntry OPTIONAL ); PHANDLE_TABLE_ENTRY +NTAPI ExMapHandleToPointer( IN PHANDLE_TABLE HandleTable, IN HANDLE Handle ); +PHANDLE_TABLE +NTAPI +ExDupHandleTable( + IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PEX_DUPLICATE_HANDLE_CALLBACK DupHandleProcedure, + IN ULONG_PTR Mask +); + BOOLEAN +NTAPI ExChangeHandle( IN PHANDLE_TABLE HandleTable, IN HANDLE Handle, - IN PEX_CHANGE_HANDLE_CALLBACK ChangeHandleCallback, + IN PEX_CHANGE_HANDLE_CALLBACK ChangeRoutine, + IN ULONG_PTR Context +); + +VOID +NTAPI +ExSweepHandleTable( + IN PHANDLE_TABLE HandleTable, + IN PEX_SWEEP_HANDLE_CALLBACK EnumHandleProcedure, IN PVOID Context ); @@ -797,7 +819,7 @@ VOID FORCEINLINE ExWaitOnPushLock(PEX_PUSH_LOCK PushLock) -{ +{ /* Check if we're locked */ if (PushLock->Locked) { Modified: trunk/reactos/ntoskrnl/include/internal/ob.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ob.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ob.h Mon Jan 22 11:15:17 2007 @@ -44,6 +44,16 @@ GENERIC_ALL) // +// Handle Bit Flags +// +#define OBJ_PROTECT_CLOSE 0x01 +//#define OBJ_INHERIT 0x02 +#define OBJ_AUDIT_OBJECT_CLOSE 0x04 +#define OBJ_HANDLE_ATTRIBUTES (OBJ_PROTECT_CLOSE |\ + OBJ_INHERIT | \ + OBJ_AUDIT_OBJECT_CLOSE) + +// // Identifies a Kernel Handle // #define KERNEL_HANDLE_FLAG \ @@ -65,6 +75,12 @@ // #define ObpGetHandleCountByHandleTable(HandleTable) \ ((PHANDLE_TABLE)HandleTable)->HandleCount + +// +// Converts from an EXHANDLE object to a POBJECT_HEADER +// +#define ObpGetHandleObject(x) \ + ((POBJECT_HEADER)((ULONG_PTR)x->Object & ~OBJ_HANDLE_ATTRIBUTES)) // // Context Structures for Ex*Handle Callbacks @@ -214,9 +230,8 @@ BOOLEAN NTAPI ObpSetHandleAttributes( - IN PHANDLE_TABLE HandleTable, IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, - IN PVOID Context + IN ULONG_PTR Context ); VOID Modified: trunk/reactos/ntoskrnl/include/ntoskrnl.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/ntoskrnl.…
============================================================================== --- trunk/reactos/ntoskrnl/include/ntoskrnl.h (original) +++ trunk/reactos/ntoskrnl/include/ntoskrnl.h Mon Jan 22 11:15:17 2007 @@ -8,7 +8,9 @@ /* INCLUDES ******************************************************************/ -/* Tells the WDK that we don't want to import */ +/* Always target Windows 2003 Service Pack 1 */ +#undef NTDDI_VERSION +#define NTDDI_VERSION NTDDI_WS03SP1 #define NTKERNELAPI /* DDK/IFS/NDK Headers */ Modified: trunk/reactos/ntoskrnl/ke/apc.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/apc.c?rev=2558…
============================================================================== --- trunk/reactos/ntoskrnl/ke/apc.c (original) +++ trunk/reactos/ntoskrnl/ke/apc.c Mon Jan 22 11:15:17 2007 @@ -8,7 +8,6 @@ /* INCLUDES *****************************************************************/ -#define NTDDI_VERSION NTDDI_WS03 #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h> @@ -952,3 +951,4 @@ + Modified: trunk/reactos/ntoskrnl/ke/dpc.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/dpc.c?rev=2558…
============================================================================== --- trunk/reactos/ntoskrnl/ke/dpc.c (original) +++ trunk/reactos/ntoskrnl/ke/dpc.c Mon Jan 22 11:15:17 2007 @@ -9,8 +9,6 @@ */ /* INCLUDES ******************************************************************/ - -#define NTDDI_VERSION NTDDI_WS03 #include <ntoskrnl.h> #define NDEBUG Modified: trunk/reactos/ntoskrnl/ke/gate.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/gate.c?rev=255…
============================================================================== --- trunk/reactos/ntoskrnl/ke/gate.c (original) +++ trunk/reactos/ntoskrnl/ke/gate.c Mon Jan 22 11:15:17 2007 @@ -8,7 +8,6 @@ /* INCLUDES *****************************************************************/ -#define NTDDI_VERSION NTDDI_WS03 #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h> Modified: trunk/reactos/ntoskrnl/ke/gmutex.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/gmutex.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/ke/gmutex.c (original) +++ trunk/reactos/ntoskrnl/ke/gmutex.c Mon Jan 22 11:15:17 2007 @@ -9,7 +9,6 @@ /* INCLUDES ******************************************************************/ -#define NTDDI_VERSION NTDDI_WS03SP1 #include <ntoskrnl.h> #define NDEBUG #include <internal/debug.h> Modified: trunk/reactos/ntoskrnl/ke/i386/kiinit.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kiinit.c?…
============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/kiinit.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/kiinit.c Mon Jan 22 11:15:17 2007 @@ -8,7 +8,6 @@ /* INCLUDES *****************************************************************/ -#define NTDDI_VERSION NTDDI_WS03SP1 #include <ntoskrnl.h> #define NDEBUG #include <debug.h> @@ -788,3 +787,4 @@ KiIdleLoop(); } + Modified: trunk/reactos/ntoskrnl/ob/obhandle.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obhandle.c?rev…
============================================================================== --- trunk/reactos/ntoskrnl/ob/obhandle.c (original) +++ trunk/reactos/ntoskrnl/ob/obhandle.c Mon Jan 22 11:15:17 2007 @@ -131,16 +131,13 @@ if (HandleEntry) { /* Get the object header and validate the type*/ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry); /* Get the granted access and validate it */ GrantedAccess = HandleEntry->GrantedAccess; /* Mask out the internal attributes */ - Attributes = HandleEntry->ObAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + Attributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES; /* Fill out the information */ HandleInformation->HandleAttributes = Attributes; @@ -588,7 +585,7 @@ PAGED_CODE(); /* Get the object data */ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry); ObjectType = ObjectHeader->Type; Body = &ObjectHeader->Body; GrantedAccess = HandleEntry->GrantedAccess; @@ -621,7 +618,7 @@ } /* The callback allowed us to close it, but does the handle itself? */ - if ((HandleEntry->ObAttributes & EX_HANDLE_ENTRY_PROTECTFROMCLOSE) && + if ((HandleEntry->ObAttributes & OBJ_PROTECT_CLOSE) && !(IgnoreHandleProtection)) { /* It doesn't, are we from user mode? */ @@ -650,7 +647,7 @@ } /* Destroy and unlock the handle entry */ - ExDestroyHandleByEntry(HandleTable, HandleEntry, Handle); + ExDestroyHandle(HandleTable, Handle, HandleEntry); /* Now decrement the handle count */ ObpDecrementHandleCount(Body, PsGetCurrentProcess(), GrantedAccess); @@ -1258,10 +1255,7 @@ NewEntry.Object = ObjectHeader; /* Mask out the internal attributes */ - NewEntry.ObAttributes |= HandleAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + NewEntry.ObAttributes |= HandleAttributes & OBJ_HANDLE_ATTRIBUTES; /* Remove what's not in the valid access mask */ GrantedAccess = DesiredAccess & (ObjectType->TypeInfo.ValidAccessMask | @@ -1460,14 +1454,11 @@ if (AccessState->GenerateOnClose) { /* Force the attribute on */ - HandleAttributes|= EX_HANDLE_ENTRY_AUDITONCLOSE; + HandleAttributes|= OBJ_AUDIT_OBJECT_CLOSE; } /* Mask out the internal attributes */ - NewEntry.ObAttributes |= HandleAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + NewEntry.ObAttributes |= HandleAttributes & OBJ_HANDLE_ATTRIBUTES; /* Get the original desired access */ DesiredAccess = AccessState->RemainingDesiredAccess | @@ -1697,9 +1688,6 @@ * * The ObpSetHandleAttributes routine <FILLMEIN> * -* @param HandleTable -* <FILLMEIN>. -* * @param HandleTableEntry * <FILLMEIN>. * @@ -1713,12 +1701,11 @@ *--*/ BOOLEAN NTAPI -ObpSetHandleAttributes(IN PHANDLE_TABLE HandleTable, - IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, - IN PVOID Context) +ObpSetHandleAttributes(IN OUT PHANDLE_TABLE_ENTRY HandleTableEntry, + IN ULONG_PTR Context) { - POBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleInfo = Context; - POBJECT_HEADER ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry); + POBP_SET_HANDLE_ATTRIBUTES_CONTEXT SetHandleInfo = (PVOID)Context; + POBJECT_HEADER ObjectHeader = ObpGetHandleObject(HandleTableEntry); PAGED_CODE(); /* Don't allow operations on kernel objects */ @@ -1740,24 +1727,24 @@ } /* Set the flag */ - HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_INHERITABLE; + HandleTableEntry->ObAttributes |= OBJ_INHERIT; } else { /* Otherwise this implies we're removing the flag */ - HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_INHERITABLE; + HandleTableEntry->ObAttributes &= ~OBJ_INHERIT; } /* Check if making the handle protected */ if (SetHandleInfo->Information.ProtectFromClose) { /* Set the flag */ - HandleTableEntry->ObAttributes |= EX_HANDLE_ENTRY_PROTECTFROMCLOSE; + HandleTableEntry->ObAttributes |= OBJ_PROTECT_CLOSE; } else { /* Otherwise, remove it */ - HandleTableEntry->ObAttributes &= ~EX_HANDLE_ENTRY_PROTECTFROMCLOSE; + HandleTableEntry->ObAttributes &= ~OBJ_PROTECT_CLOSE; } /* Return success */ @@ -1823,9 +1810,10 @@ *--*/ BOOLEAN NTAPI -ObpDuplicateHandleCallback(IN PHANDLE_TABLE HandleTable, - IN PHANDLE_TABLE_ENTRY HandleTableEntry, - IN PVOID Context) +ObpDuplicateHandleCallback(IN PEPROCESS Process, + IN PHANDLE_TABLE HandleTable, + IN PHANDLE_TABLE_ENTRY OldEntry, + IN PHANDLE_TABLE_ENTRY HandleTableEntry) { POBJECT_HEADER ObjectHeader; BOOLEAN Ret = FALSE; @@ -1834,11 +1822,17 @@ PAGED_CODE(); /* Make sure that the handle is inheritable */ - Ret = (HandleTableEntry->ObAttributes & EX_HANDLE_ENTRY_INHERITABLE) != 0; + Ret = (HandleTableEntry->ObAttributes & OBJ_INHERIT) != 0; if (Ret) { /* Get the object header */ - ObjectHeader = EX_HTE_TO_HDR(HandleTableEntry); + ObjectHeader = ObpGetHandleObject(HandleTableEntry); + + /* Increment the pointer count */ + InterlockedIncrement(&ObjectHeader->PointerCount); + + /* Release the handle lock */ + ExUnlockHandleTableEntry(HandleTable, OldEntry); /* Setup the access state */ AccessState.PreviouslyGrantedAccess = HandleTableEntry->GrantedAccess; @@ -1848,18 +1842,19 @@ &AccessState, KernelMode, HandleTableEntry->ObAttributes, - PsGetCurrentProcess(), + Process, ObInheritHandle); if (!NT_SUCCESS(Status)) { /* Return failure */ + ObDereferenceObject(&ObjectHeader->Body); Ret = FALSE; } - else - { - /* Otherwise increment the pointer count */ - InterlockedIncrement(&ObjectHeader->PointerCount); - } + } + else + { + /* Release the handle lock */ + ExUnlockHandleTableEntry(HandleTable, OldEntry); } /* Return duplication result */ @@ -1906,9 +1901,9 @@ /* Duplicate the parent's */ HandleTable = ExDupHandleTable(Process, + HandleTable, ObpDuplicateHandleCallback, - NULL, - HandleTable); + OBJ_INHERIT); } else { @@ -1981,7 +1976,7 @@ /* Destroy the object table */ Process->ObjectTable = NULL; - ExDestroyHandleTable(HandleTable); + ExDestroyHandleTable(HandleTable, NULL); } NTSTATUS @@ -2121,10 +2116,7 @@ /* Fill out the entry */ NewHandleEntry.Object = ObjectHeader; - NewHandleEntry.ObAttributes |= HandleAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + NewHandleEntry.ObAttributes |= HandleAttributes & OBJ_HANDLE_ATTRIBUTES; /* Check if we're using a generic mask */ if (DesiredAccess & GENERIC_ACCESS) Modified: trunk/reactos/ntoskrnl/ob/oblife.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/oblife.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/ob/oblife.c (original) +++ trunk/reactos/ntoskrnl/ob/oblife.c Mon Jan 22 11:15:17 2007 @@ -1442,10 +1442,9 @@ ObjectInformation; /* Set the flags */ - HandleFlags->Inherit = (HandleInfo.HandleAttributes & - EX_HANDLE_ENTRY_INHERITABLE) != 0; + HandleFlags->Inherit = HandleInfo.HandleAttributes & OBJ_INHERIT; HandleFlags->ProtectFromClose = (HandleInfo.HandleAttributes & - EX_HANDLE_ENTRY_PROTECTFROMCLOSE) != 0; + OBJ_PROTECT_CLOSE) != 0; /* Break out with success */ Status = STATUS_SUCCESS; @@ -1581,7 +1580,7 @@ if (!ExChangeHandle(ObjectTable, ObjectHandle, ObpSetHandleAttributes, - &Context)) + (ULONG_PTR)&Context)) { /* Some failure */ Status = STATUS_ACCESS_DENIED; Modified: trunk/reactos/ntoskrnl/ob/obname.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obname.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/ob/obname.c (original) +++ trunk/reactos/ntoskrnl/ob/obname.c Mon Jan 22 11:15:17 2007 @@ -11,7 +11,6 @@ /* INCLUDES ******************************************************************/ -#define NTDDI_VERSION NTDDI_WINXP #include <ntoskrnl.h> #define NDEBUG #include <debug.h> Modified: trunk/reactos/ntoskrnl/ob/obref.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obref.c?rev=25…
============================================================================== --- trunk/reactos/ntoskrnl/ob/obref.c (original) +++ trunk/reactos/ntoskrnl/ob/obref.c Mon Jan 22 11:15:17 2007 @@ -560,7 +560,7 @@ if (HandleEntry) { /* Get the object header and validate the type*/ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry); if (!(ObjectType) || (ObjectType == ObjectHeader->Type)) { /* Get the granted access and validate it */ @@ -572,10 +572,7 @@ InterlockedIncrement(&ObjectHeader->PointerCount); /* Mask out the internal attributes */ - Attributes = HandleEntry->ObAttributes & - (EX_HANDLE_ENTRY_PROTECTFROMCLOSE | - EX_HANDLE_ENTRY_INHERITABLE | - EX_HANDLE_ENTRY_AUDITONCLOSE); + Attributes = HandleEntry->ObAttributes & OBJ_HANDLE_ATTRIBUTES; /* Check if the caller wants handle information */ if (HandleInformation) Modified: trunk/reactos/ntoskrnl/ob/obsecure.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obsecure.c?rev…
============================================================================== --- trunk/reactos/ntoskrnl/ob/obsecure.c (original) +++ trunk/reactos/ntoskrnl/ob/obsecure.c Mon Jan 22 11:15:17 2007 @@ -829,8 +829,7 @@ if(HandleEntry) { /* Check if the flag is set */ - *GenerateOnClose = (HandleEntry->ObAttributes & - EX_HANDLE_ENTRY_AUDITONCLOSE) != 0; + *GenerateOnClose = HandleEntry->ObAttributes & OBJ_AUDIT_OBJECT_CLOSE; /* Unlock the entry */ ExUnlockHandleTableEntry(HandleTable, HandleEntry); Modified: trunk/reactos/ntoskrnl/ob/obwait.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ob/obwait.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/ob/obwait.c (original) +++ trunk/reactos/ntoskrnl/ob/obwait.c Mon Jan 22 11:15:17 2007 @@ -181,7 +181,7 @@ } /* Get the Object Header */ - ObjectHeader = EX_HTE_TO_HDR(HandleEntry); + ObjectHeader = ObpGetHandleObject(HandleEntry); /* Get default Object */ DefaultObject = ObjectHeader->Type->DefaultObject; Modified: trunk/reactos/ntoskrnl/ps/kill.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ps/kill.c?rev=255…
============================================================================== --- trunk/reactos/ntoskrnl/ps/kill.c (original) +++ trunk/reactos/ntoskrnl/ps/kill.c Mon Jan 22 11:15:17 2007 @@ -310,7 +310,7 @@ if (Process->UniqueProcessId) { /* Delete the PID */ - if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId))) + if (!(ExDestroyHandle(PspCidTable, Process->UniqueProcessId, NULL))) { /* Something wrong happened, bugcheck */ KEBUGCHECK(CID_HANDLE_DELETION); @@ -360,7 +360,7 @@ if (Thread->Cid.UniqueThread) { /* Delete the CID Handle */ - if (!(ExDestroyHandle(PspCidTable, Thread->Cid.UniqueThread))) + if (!(ExDestroyHandle(PspCidTable, Thread->Cid.UniqueThread, NULL))) { /* Something wrong happened, bugcheck */ KEBUGCHECK(CID_HANDLE_DELETION); Modified: trunk/reactos/ntoskrnl/rtl/libsupp.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/rtl/libsupp.c?rev…
============================================================================== --- trunk/reactos/ntoskrnl/rtl/libsupp.c (original) +++ trunk/reactos/ntoskrnl/rtl/libsupp.c Mon Jan 22 11:15:17 2007 @@ -259,7 +259,7 @@ ExSweepHandleTable(AtomTable->ExHandleTable, NULL, NULL); - ExDestroyHandleTable(AtomTable->ExHandleTable); + ExDestroyHandleTable(AtomTable->ExHandleTable, NULL); AtomTable->ExHandleTable = NULL; } } @@ -308,7 +308,8 @@ RtlpFreeAtomHandle(PRTL_ATOM_TABLE AtomTable, PRTL_ATOM_TABLE_ENTRY Entry) { ExDestroyHandle(AtomTable->ExHandleTable, - (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2)); + (HANDLE)((ULONG_PTR)Entry->HandleIndex << 2), + NULL); } BOOLEAN @@ -336,7 +337,8 @@ } else ExDestroyHandle(AtomTable->ExHandleTable, - Handle); + Handle, + NULL); } return FALSE;
17 years, 11 months
1
0
0
0
[ion] 25585: - Fix HANDLE_TABLE definition. - Fix LPC bugcheck during 2nd stage setup and/or bootup (double-free): - LpcReplyMessage and LpcWaitingOnPort are a union inside ETHREAD, and they can actually be both accessed in the same time! (Unlike other unions which are self-exclusive). Therefore, we need a way to: 1) Mark a message vs a port. 2) Retrieve the correct object. This has now been implemented with some helper inline functions.
by ion@svn.reactos.org
Author: ion Date: Mon Jan 22 11:07:24 2007 New Revision: 25585 URL:
http://svn.reactos.org/svn/reactos?rev=25585&view=rev
Log: - Fix HANDLE_TABLE definition. - Fix LPC bugcheck during 2nd stage setup and/or bootup (double-free): - LpcReplyMessage and LpcWaitingOnPort are a union inside ETHREAD, and they can actually be both accessed in the same time! (Unlike other unions which are self-exclusive). Therefore, we need a way to: 1) Mark a message vs a port. 2) Retrieve the correct object. This has now been implemented with some helper inline functions. Modified: trunk/reactos/include/ndk/extypes.h trunk/reactos/ntoskrnl/include/internal/lpc.h trunk/reactos/ntoskrnl/include/internal/lpc_x.h trunk/reactos/ntoskrnl/lpc/close.c trunk/reactos/ntoskrnl/lpc/complete.c trunk/reactos/ntoskrnl/lpc/connect.c trunk/reactos/ntoskrnl/lpc/reply.c trunk/reactos/ntoskrnl/lpc/send.c Modified: trunk/reactos/include/ndk/extypes.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/extypes.h?rev=…
============================================================================== --- trunk/reactos/include/ndk/extypes.h (original) +++ trunk/reactos/include/ndk/extypes.h Mon Jan 22 11:07:24 2007 @@ -592,14 +592,6 @@ }; } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; -// -// FIXME -// -#ifdef _REACTOS_ -#undef NTDDI_VERSION -#define NTDDI_VERSION NTDDI_WIN2K -#endif - typedef struct _HANDLE_TABLE { #if (NTDDI_VERSION >= NTDDI_WINXP) @@ -610,7 +602,7 @@ PEPROCESS QuotaProcess; PVOID UniqueProcessId; #if (NTDDI_VERSION >= NTDDI_WINXP) - EX_PUSH_LOCK HandleLock; + EX_PUSH_LOCK HandleTableLock[4]; LIST_ENTRY HandleTableList; EX_PUSH_LOCK HandleContentionEvent; #else Modified: trunk/reactos/ntoskrnl/include/internal/lpc.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/lpc.h (original) +++ trunk/reactos/ntoskrnl/include/internal/lpc.h Mon Jan 22 11:07:24 2007 @@ -46,6 +46,14 @@ } #endif #endif + +// +// LPC Port/Message Flags +// +#define LPCP_THREAD_FLAG_IS_PORT 1 +#define LPCP_THREAD_FLAG_NO_IMPERSONATION 2 +#define LPCP_THREAD_FLAGS (LPCP_THREAD_FLAG_IS_PORT | \ + LPCP_THREAD_FLAG_NO_IMPERSONATION) // // Internal Port Management Modified: trunk/reactos/ntoskrnl/include/internal/lpc_x.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/lpc_x.h (original) +++ trunk/reactos/ntoskrnl/include/internal/lpc_x.h Mon Jan 22 11:07:24 2007 @@ -120,3 +120,47 @@ KeReleaseGuardedMutex(&LpcpLock); return Message; } + +// +// Get the LPC Message associated to the Thread +// +PLPCP_MESSAGE +FORCEINLINE +LpcpGetMessageFromThread(IN PETHREAD Thread) +{ + /* Check if the port flag is set */ + if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT) + { + /* The pointer is actually a port, not a message, so return NULL */ + return NULL; + } + + /* Otherwise, this is a message. Return the pointer */ + return (PVOID)((ULONG_PTR)Thread->LpcReplyMessage & ~LPCP_THREAD_FLAGS); +} + +PLPCP_PORT_OBJECT +FORCEINLINE +LpcpGetPortFromThread(IN PETHREAD Thread) +{ + /* Check if the port flag is set */ + if (((ULONG_PTR)Thread->LpcReplyMessage) & LPCP_THREAD_FLAG_IS_PORT) + { + /* The pointer is actually a port, return it */ + return (PVOID)((ULONG_PTR)Thread->LpcWaitingOnPort & + ~LPCP_THREAD_FLAGS); + } + + /* Otherwise, this is a message. There is nothing to return */ + return NULL; +} + +VOID +FORCEINLINE +LpcpSetPortToThread(IN PETHREAD Thread, + IN PLPCP_PORT_OBJECT Port) +{ + /* Set the port object */ + Thread->LpcWaitingOnPort = (PVOID)(((ULONG_PTR)Port) | + LPCP_THREAD_FLAG_IS_PORT); +} Modified: trunk/reactos/ntoskrnl/lpc/close.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/close.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/lpc/close.c (original) +++ trunk/reactos/ntoskrnl/lpc/close.c Mon Jan 22 11:07:24 2007 @@ -36,7 +36,7 @@ Thread->LpcReplyMessageId = 0; /* Check if there's a reply message */ - Message = Thread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(Thread); if (Message) { /* FIXME: TODO */ @@ -57,7 +57,7 @@ PETHREAD Thread = NULL; BOOLEAN LockHeld = Flags & 1, ReleaseLock = Flags & 2; PAGED_CODE(); - DPRINT1("Message: %p. Flags: %lx\n", Message, Flags); + LPCTRACE(LPC_CLOSE_DEBUG, "Message: %p. Flags: %lx\n", Message, Flags); /* Acquire the lock if not already */ if (!LockHeld) KeAcquireGuardedMutex(&LpcpLock); @@ -125,10 +125,10 @@ { /* Disconnect it */ Port->ConnectedPort->ConnectedPort = NULL; - if (Port->ConnectedPort->ConnectionPort) - { - /* Save and clear connection port */ - ConnectionPort = Port->ConnectedPort->ConnectionPort; + ConnectionPort = Port->ConnectedPort->ConnectionPort; + if (ConnectionPort) + { + /* Clear connection port */ Port->ConnectedPort->ConnectionPort = NULL; } } @@ -162,7 +162,7 @@ if (!KeReadStateSemaphore(&Thread->LpcReplySemaphore)) { /* Get the message */ - Message = Thread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(Thread); if (Message) { /* Check if it's a connection request */ @@ -198,7 +198,7 @@ /* Loop queued messages */ while ((Port->MsgQueue.ReceiveHead.Flink) && - !(IsListEmpty (&Port->MsgQueue.ReceiveHead))) + !(IsListEmpty(&Port->MsgQueue.ReceiveHead))) { /* Get the message */ Message = CONTAINING_RECORD(Port->MsgQueue.ReceiveHead.Flink, @@ -342,9 +342,6 @@ /* Send it */ for (;;) { - /* FIXME: HACK OF D00m */ - break; - /* Send the message */ if (LpcRequestPort(Port, &ClientDiedMsg.h) != STATUS_NO_MEMORY) break; Modified: trunk/reactos/ntoskrnl/lpc/complete.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/complete.c?re…
============================================================================== --- trunk/reactos/ntoskrnl/lpc/complete.c (original) +++ trunk/reactos/ntoskrnl/lpc/complete.c Mon Jan 22 11:07:24 2007 @@ -88,7 +88,7 @@ KeAcquireGuardedMutex(&LpcpLock); /* Make sure that the client wants a reply, and this is the right one */ - if (!(ClientThread->LpcReplyMessage) || + if (!(LpcpGetMessageFromThread(ClientThread)) || !(ReplyMessage->MessageId) || (ClientThread->LpcReplyMessageId != ReplyMessage->MessageId)) { @@ -100,7 +100,7 @@ } /* Now get the message and connection message */ - Message = ClientThread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(ClientThread); ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1); /* Get the client and connection port as well */ @@ -353,7 +353,7 @@ Thread = Port->ClientThread; /* Make sure it has a reply message */ - if (!Thread->LpcReplyMessage) + if (!LpcpGetMessageFromThread(Thread)) { /* It doesn't, quit */ KeReleaseGuardedMutex(&LpcpLock); Modified: trunk/reactos/ntoskrnl/lpc/connect.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/connect.c?rev…
============================================================================== --- trunk/reactos/ntoskrnl/lpc/connect.c (original) +++ trunk/reactos/ntoskrnl/lpc/connect.c Mon Jan 22 11:07:24 2007 @@ -35,7 +35,7 @@ } /* Check if there's a reply message */ - ReplyMessage = CurrentThread->LpcReplyMessage; + ReplyMessage = LpcpGetMessageFromThread(CurrentThread); if (ReplyMessage) { /* Get the message */ @@ -54,7 +54,7 @@ CurrentThread->LpcReplyMessage = NULL; /* Get the connection message and clear the section */ - *ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(*Message + 1); + *ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(ReplyMessage + 1); SectionToMap = (*ConnectMessage)->SectionToMap; (*ConnectMessage)->SectionToMap = NULL; } Modified: trunk/reactos/ntoskrnl/lpc/reply.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/reply.c?rev=2…
============================================================================== --- trunk/reactos/ntoskrnl/lpc/reply.c (original) +++ trunk/reactos/ntoskrnl/lpc/reply.c Mon Jan 22 11:07:24 2007 @@ -279,12 +279,10 @@ KeAcquireGuardedMutex(&LpcpLock); /* Make sure this is the reply the thread is waiting for */ - if ((WakeupThread->LpcReplyMessageId != ReplyMessage->MessageId))// || -#if 0 - ((WakeupThread->LpcReplyMessage) && - (LpcpGetMessageType(&((PLPCP_MESSAGE)WakeupThread-> - LpcReplyMessage)->Request) != LPC_REQUEST))) -#endif + if ((WakeupThread->LpcReplyMessageId != ReplyMessage->MessageId) || + ((LpcpGetMessageFromThread(WakeupThread)) && + (LpcpGetMessageType(&LpcpGetMessageFromThread(WakeupThread)-> + Request) != LPC_REQUEST))) { /* It isn't, fail */ LpcpFreeToPortZone(Message, 3); Modified: trunk/reactos/ntoskrnl/lpc/send.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/send.c?rev=25…
============================================================================== --- trunk/reactos/ntoskrnl/lpc/send.c (original) +++ trunk/reactos/ntoskrnl/lpc/send.c Mon Jan 22 11:07:24 2007 @@ -155,8 +155,8 @@ /* We're done */ KeLeaveCriticalRegion(); + if (ConnectionPort) ObDereferenceObject(ConnectionPort); LPCTRACE(LPC_SEND_DEBUG, "Port: %p. Message: %p\n", QueuePort, Message); - if (ConnectionPort) ObDereferenceObject(ConnectionPort); return STATUS_SUCCESS; } @@ -366,7 +366,7 @@ /* Insert the message in our chain */ InsertTailList(&QueuePort->MsgQueue.ReceiveHead, &Message->Entry); InsertTailList(&ReplyPort->LpcReplyChainHead, &Thread->LpcReplyChain); - Thread->LpcWaitingOnPort = Port; + LpcpSetPortToThread(Thread, Port); /* Release the lock and get the semaphore we'll use later */ KeEnterCriticalRegion(); @@ -392,7 +392,7 @@ KeAcquireGuardedMutex(&LpcpLock); /* Get the LPC Message and clear our thread's reply data */ - Message = Thread->LpcReplyMessage; + Message = LpcpGetMessageFromThread(Thread); Thread->LpcReplyMessage = NULL; Thread->LpcReplyMessageId = 0;
17 years, 11 months
1
0
0
0
[ion] 25584: - Implement a cute little hack called DEFINE_WAIT_BLOCK which makes pushlocks work on GCC 3.4.5 as well as 4.1.2+ (with no perf-hit on the latter). - Implement ExWaitForUnblockPushLock (just a wrapper around ExTimedWaitForUnblockPushLock). - Simplfy ExBlockPushLock and fix some bugs. - Fix a bug in ExfReleasePushLockExclusive when we have to wake the lock. - Fix a bug in ExfUnblockPushLock which was touching the wrong pointer. - Fix ExWaitOnPushLock to verify that the pushlock is ac
by ion@svn.reactos.org
Author: ion Date: Mon Jan 22 09:47:44 2007 New Revision: 25584 URL:
http://svn.reactos.org/svn/reactos?rev=25584&view=rev
Log: - Implement a cute little hack called DEFINE_WAIT_BLOCK which makes pushlocks work on GCC 3.4.5 as well as 4.1.2+ (with no perf-hit on the latter). - Implement ExWaitForUnblockPushLock (just a wrapper around ExTimedWaitForUnblockPushLock). - Simplfy ExBlockPushLock and fix some bugs. - Fix a bug in ExfReleasePushLockExclusive when we have to wake the lock. - Fix a bug in ExfUnblockPushLock which was touching the wrong pointer. - Fix ExWaitOnPushLock to verify that the pushlock is actually locked. Modified: trunk/reactos/ntoskrnl/ex/init.c trunk/reactos/ntoskrnl/ex/pushlock.c trunk/reactos/ntoskrnl/include/internal/ex.h Modified: trunk/reactos/ntoskrnl/ex/init.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/init.c?rev=255…
============================================================================== --- trunk/reactos/ntoskrnl/ex/init.c (original) +++ trunk/reactos/ntoskrnl/ex/init.c Mon Jan 22 09:47:44 2007 @@ -1,11 +1,11 @@ /* -* PROJECT: ReactOS Kernel -* LICENSE: GPL - See COPYING in the top level directory -* FILE: ntoskrnl/ex/init.c -* PURPOSE: Executive Initialization Code -* PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org) -* Eric Kohl (ekohl(a)rz-online.de) -*/ + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ex/init.c + * PURPOSE: Executive Initialization Code + * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org) + * Eric Kohl (ekohl(a)rz-online.de) + */ /* INCLUDES ******************************************************************/ Modified: trunk/reactos/ntoskrnl/ex/pushlock.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ex/pushlock.c?rev…
============================================================================== --- trunk/reactos/ntoskrnl/ex/pushlock.c (original) +++ trunk/reactos/ntoskrnl/ex/pushlock.c Mon Jan 22 09:47:44 2007 @@ -342,6 +342,33 @@ } /*++ + * @name ExWaitForUnblockPushLock + * + * The ExWaitForUnblockPushLock routine waits for a pushlock + * to be unblocked, for a specified internal. + * + * @param PushLock + * Pointer to a pushlock whose waiter list needs to be optimized. + * + * @param WaitBlock + * Pointer to the pushlock's wait block. + * + * @return STATUS_SUCCESS is the pushlock is now unblocked, otherwise the error + * code returned by KeWaitForSingleObject. + * + * @remarks If the wait fails, then a manual unblock is attempted. + * + *--*/ +VOID +FASTCALL +ExWaitForUnblockPushLock(IN PEX_PUSH_LOCK PushLock, + IN PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock) +{ + /* Call the timed function with no timeout */ + ExTimedWaitForUnblockPushLock(PushLock, WaitBlock, NULL); +} + +/*++ * @name ExBlockPushLock * * The ExBlockPushLock routine blocks a pushlock. @@ -360,25 +387,33 @@ VOID FASTCALL ExBlockPushLock(PEX_PUSH_LOCK PushLock, - PVOID WaitBlock) -{ - PVOID NewValue, OldValue; + PVOID pWaitBlock) +{ + PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock = pWaitBlock; + EX_PUSH_LOCK NewValue, OldValue; + + /* Detect invalid wait block alignment */ + ASSERT((ULONG_PTR)pWaitBlock & 0x10); /* Set the waiting bit */ - ((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Flags |= EX_PUSH_LOCK_FLAGS_WAIT; - - /* Link the wait blocks */ - ((PEX_PUSH_LOCK_WAIT_BLOCK)WaitBlock)->Next = PushLock->Ptr; - - /* Try to set this one as the wait block now */ - NewValue = PushLock->Ptr; + WaitBlock->Flags = EX_PUSH_LOCK_FLAGS_WAIT; + + /* Get the old value */ + OldValue = *PushLock; + + /* Start block loop */ for (;;) { + /* Link the wait blocks */ + WaitBlock->Next = OldValue.Ptr; + /* Set the new wait block value */ - OldValue = InterlockedCompareExchangePointer(&PushLock->Ptr, - WaitBlock, - NewValue); - if (OldValue == NewValue) break; + NewValue.Ptr = InterlockedCompareExchangePointer(&PushLock->Ptr, + WaitBlock, + OldValue.Ptr); + if (OldValue.Ptr == NewValue.Ptr) break; + + /* Try again with the new value */ NewValue = OldValue; } } @@ -404,7 +439,7 @@ FASTCALL ExfAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock) { - EX_PUSH_LOCK_WAIT_BLOCK WaitBlock; + DEFINE_WAIT_BLOCK(WaitBlock); EX_PUSH_LOCK OldValue = *PushLock, NewValue, TempValue; BOOLEAN NeedWake; ULONG i; @@ -435,23 +470,23 @@ else { /* We'll have to create a Waitblock */ - WaitBlock.Flags = EX_PUSH_LOCK_FLAGS_EXCLUSIVE | - EX_PUSH_LOCK_FLAGS_WAIT; - WaitBlock.Previous = NULL; + WaitBlock->Flags = EX_PUSH_LOCK_FLAGS_EXCLUSIVE | + EX_PUSH_LOCK_FLAGS_WAIT; + WaitBlock->Previous = NULL; NeedWake = FALSE; /* Check if there is already a waiter */ if (OldValue.Waiting) { /* Nobody is the last waiter yet */ - WaitBlock.Last = NULL; + WaitBlock->Last = NULL; /* We are an exclusive waiter */ - WaitBlock.ShareCount = 0; + WaitBlock->ShareCount = 0; /* Set the current Wait Block pointer */ - WaitBlock.Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) - OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS); + WaitBlock->Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) + OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS); /* Point to ours */ NewValue.Value = (OldValue.Value & EX_PUSH_LOCK_MULTIPLE_SHARED) | @@ -466,10 +501,10 @@ else { /* We are the first waiter, so loop the wait block */ - WaitBlock.Last = &WaitBlock; + WaitBlock->Last = WaitBlock; /* Set the share count */ - WaitBlock.ShareCount = OldValue.Shared; + WaitBlock->ShareCount = OldValue.Shared; /* Check if someone is sharing this pushlock */ if (OldValue.Shared > 1) @@ -483,7 +518,7 @@ else { /* No shared count */ - WaitBlock.ShareCount = 0; + WaitBlock->ShareCount = 0; /* Point to our wait block */ NewValue.Value = EX_PUSH_LOCK_LOCK | @@ -494,10 +529,10 @@ #if DBG /* Setup the Debug Wait Block */ - WaitBlock.Signaled = 0; - WaitBlock.OldValue = OldValue; - WaitBlock.NewValue = NewValue; - WaitBlock.PushLock = PushLock; + WaitBlock->Signaled = 0; + WaitBlock->OldValue = OldValue; + WaitBlock->NewValue = NewValue; + WaitBlock->PushLock = PushLock; #endif /* Sanity check */ @@ -524,26 +559,26 @@ } /* Set up the Wait Gate */ - KeInitializeGate(&WaitBlock.WakeGate); + KeInitializeGate(&WaitBlock->WakeGate); /* Now spin on the push lock if necessary */ i = ExPushLockSpinCount; - if ((i) && (WaitBlock.Flags & EX_PUSH_LOCK_WAITING)) + if ((i) && (WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) { /* Spin */ while (--i) YieldProcessor(); } /* Now try to remove the wait bit */ - if (InterlockedBitTestAndReset(&WaitBlock.Flags, 1)) + if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1)) { /* Nobody removed it already, let's do a full wait */ - KeWaitForGate(&WaitBlock.WakeGate, WrPushLock, KernelMode); - ASSERT(WaitBlock.Signaled); + KeWaitForGate(&WaitBlock->WakeGate, WrPushLock, KernelMode); + ASSERT(WaitBlock->Signaled); } /* We shouldn't be shared anymore */ - ASSERT((WaitBlock.ShareCount == 0)); + ASSERT((WaitBlock->ShareCount == 0)); /* Loop again */ OldValue = NewValue; @@ -570,7 +605,7 @@ FASTCALL ExfAcquirePushLockShared(PEX_PUSH_LOCK PushLock) { - EX_PUSH_LOCK_WAIT_BLOCK WaitBlock; + DEFINE_WAIT_BLOCK(WaitBlock); EX_PUSH_LOCK OldValue = *PushLock, NewValue; BOOLEAN NeedWake; ULONG i; @@ -614,20 +649,20 @@ else { /* We'll have to create a Waitblock */ - WaitBlock.Flags = EX_PUSH_LOCK_FLAGS_WAIT; - WaitBlock.ShareCount = 0; + WaitBlock->Flags = EX_PUSH_LOCK_FLAGS_WAIT; + WaitBlock->ShareCount = 0; NeedWake = FALSE; - WaitBlock.Previous = NULL; + WaitBlock->Previous = NULL; /* Check if there is already a waiter */ if (OldValue.Waiting) { /* Set the current Wait Block pointer */ - WaitBlock.Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) - OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS); + WaitBlock->Next = (PEX_PUSH_LOCK_WAIT_BLOCK)((ULONG_PTR) + OldValue.Ptr &~ EX_PUSH_LOCK_PTR_BITS); /* Nobody is the last waiter yet */ - WaitBlock.Last = NULL; + WaitBlock->Last = NULL; /* Point to ours */ NewValue.Value = (OldValue.Value & (EX_PUSH_LOCK_MULTIPLE_SHARED | @@ -642,7 +677,7 @@ else { /* We are the first waiter, so loop the wait block */ - WaitBlock.Last = &WaitBlock; + WaitBlock->Last = WaitBlock; /* Point to our wait block */ NewValue.Value = (OldValue.Value & (EX_PUSH_LOCK_MULTIPLE_SHARED | @@ -656,10 +691,10 @@ #if DBG /* Setup the Debug Wait Block */ - WaitBlock.Signaled = 0; - WaitBlock.OldValue = OldValue; - WaitBlock.NewValue = NewValue; - WaitBlock.PushLock = PushLock; + WaitBlock->Signaled = 0; + WaitBlock->OldValue = OldValue; + WaitBlock->NewValue = NewValue; + WaitBlock->PushLock = PushLock; #endif /* Write the new value */ @@ -683,26 +718,26 @@ } /* Set up the Wait Gate */ - KeInitializeGate(&WaitBlock.WakeGate); + KeInitializeGate(&WaitBlock->WakeGate); /* Now spin on the push lock if necessary */ i = ExPushLockSpinCount; - if ((i) && (WaitBlock.Flags & EX_PUSH_LOCK_WAITING)) + if ((i) && (WaitBlock->Flags & EX_PUSH_LOCK_WAITING)) { /* Spin */ while (--i) YieldProcessor(); } /* Now try to remove the wait bit */ - if (InterlockedBitTestAndReset(&WaitBlock.Flags, 1)) + if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1)) { /* Fast-path did not work, we need to do a full wait */ - KeWaitForGate(&WaitBlock.WakeGate, WrPushLock, KernelMode); - ASSERT(WaitBlock.Signaled); + KeWaitForGate(&WaitBlock->WakeGate, WrPushLock, KernelMode); + ASSERT(WaitBlock->Signaled); } /* We shouldn't be shared anymore */ - ASSERT((WaitBlock.ShareCount == 0)); + ASSERT((WaitBlock->ShareCount == 0)); } } } @@ -1004,7 +1039,7 @@ FASTCALL ExfReleasePushLockExclusive(PEX_PUSH_LOCK PushLock) { - EX_PUSH_LOCK NewValue; + EX_PUSH_LOCK NewValue, WakeValue; EX_PUSH_LOCK OldValue = *PushLock; /* Loop until we can change */ @@ -1023,6 +1058,28 @@ /* Sanity check */ ASSERT(NewValue.Waking && !NewValue.Locked); + + /* Write the New Value. Save our original value for waking */ + WakeValue = NewValue; + NewValue.Ptr = InterlockedCompareExchangePointer(PushLock, + NewValue.Ptr, + OldValue.Ptr); + + /* Check if the value changed behind our back */ + if (NewValue.Value != OldValue.Value) + { + /* Wake the Pushlock */ + ExfWakePushLock(PushLock, WakeValue); + break; + } + } + else + { + /* A simple unlock */ + NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_LOCK; + + /* Sanity check */ + ASSERT(NewValue.Waking && !NewValue.Waiting); /* Write the New Value */ NewValue.Ptr = InterlockedCompareExchangePointer(PushLock, @@ -1030,36 +1087,11 @@ OldValue.Ptr); /* Check if the value changed behind our back */ - if (NewValue.Value != OldValue.Value) - { - /* Loop again */ - OldValue = NewValue; - continue; - } - - /* Wake the Pushlock */ - ExfWakePushLock(PushLock, NewValue); - break; - } - else - { - /* A simple unlock */ - NewValue.Value = OldValue.Value &~ EX_PUSH_LOCK_LOCK; - - /* Sanity check */ - ASSERT(NewValue.Waking && !NewValue.Waiting); - - /* Write the New Value */ - NewValue.Ptr = InterlockedCompareExchangePointer(PushLock, - NewValue.Ptr, - OldValue.Ptr); - - /* Check if the value changed behind our back */ if (NewValue.Value == OldValue.Value) break; - - /* Loop again */ - OldValue = NewValue; - } + } + + /* Loop again */ + OldValue = NewValue; } } @@ -1128,7 +1160,7 @@ KIRQL OldIrql = DISPATCH_LEVEL; /* Get the wait block and erase the previous one */ - WaitBlock = InterlockedExchangePointer(PushLock->Ptr, 0); + WaitBlock = InterlockedExchangePointer(&PushLock->Ptr, NULL); if (WaitBlock) { /* Check if there is a linked pushlock and raise IRQL appropriately */ @@ -1144,7 +1176,7 @@ if (InterlockedBitTestAndReset(&WaitBlock->Flags, 1)) { /* Nobody removed the flag before us, so signal the event */ - KeSetEventBoostPriority(&WaitBlock->WakeEvent, IO_NO_INCREMENT); + KeSetEventBoostPriority(&WaitBlock->WakeEvent, NULL); } /* Check if there was a next block */ @@ -1161,6 +1193,6 @@ EX_PUSH_LOCK_FLAGS_WAIT)) { /* Wait for the pushlock to be unblocked */ - ExTimedWaitForUnblockPushLock(PushLock, CurrentWaitBlock, NULL); - } -} + ExWaitForUnblockPushLock(PushLock, CurrentWaitBlock); + } +} Modified: trunk/reactos/ntoskrnl/include/internal/ex.h URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ex.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ex.h Mon Jan 22 09:47:44 2007 @@ -68,6 +68,36 @@ #define ExRundownCompleted _ExRundownCompleted #define ExGetPreviousMode KeGetPreviousMode +// +// Detect GCC 4.1.2+ +// +#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40102 + +// +// Broken GCC with Alignment Bug. We'll do alignment ourselves at higher cost. +// +#define DEFINE_WAIT_BLOCK(x) \ + struct _AlignHack \ + { \ + UCHAR Hack[15]; \ + EX_PUSH_LOCK_WAIT_BLOCK UnalignedBlock; \ + } WaitBlockBuffer; \ + PEX_PUSH_LOCK_WAIT_BLOCK x = (PEX_PUSH_LOCK_WAIT_BLOCK) \ + ((ULONG_PTR)&WaitBlockBuffer.UnalignedBlock &~ 0xF); + +#else + +// +// This is only for compatibility; the compiler will optimize the extra +// local variable (the actual pointer) away, so we don't take any perf hit +// by doing this. +// +#define DEFINE_WAIT_BLOCK(x) \ + EX_PUSH_LOCK_WAIT_BLOCK WaitBlockBuffer; \ + PEX_PUSH_LOCK_WAIT_BLOCK x = &WaitBlockBuffer; + +#endif + /* INITIALIZATION FUNCTIONS *************************************************/ VOID @@ -596,6 +626,23 @@ /* PUSHLOCKS *****************************************************************/ +/* FIXME: VERIFY THESE! */ + +VOID +FASTCALL +ExBlockPushLock(PEX_PUSH_LOCK PushLock, + PVOID WaitBlock); + +VOID +FASTCALL +ExfUnblockPushLock(PEX_PUSH_LOCK PushLock, + PVOID CurrentWaitBlock); + +VOID +FASTCALL +ExWaitForUnblockPushLock(IN PEX_PUSH_LOCK PushLock, + IN PEX_PUSH_LOCK_WAIT_BLOCK WaitBlock); + /*++ * @name ExInitializePushLock * INTERNAL MACRO @@ -751,12 +798,16 @@ FORCEINLINE ExWaitOnPushLock(PEX_PUSH_LOCK PushLock) { - /* Acquire the lock */ - ExfAcquirePushLockExclusive(PushLock); - ASSERT(PushLock->Locked); - - /* Release it */ - ExfReleasePushLockExclusive(PushLock); + /* Check if we're locked */ + if (PushLock->Locked) + { + /* Acquire the lock */ + ExfAcquirePushLockExclusive(PushLock); + ASSERT(PushLock->Locked); + + /* Release it */ + ExfReleasePushLockExclusive(PushLock); + } } /*++
17 years, 11 months
1
0
0
0
[cwittich] 25583: some more warnings fixes (gcc 4.2)
by cwittich@svn.reactos.org
Author: cwittich Date: Mon Jan 22 06:00:02 2007 New Revision: 25583 URL:
http://svn.reactos.org/svn/reactos?rev=25583&view=rev
Log: some more warnings fixes (gcc 4.2) Modified: trunk/reactos/dll/win32/riched20/editor.c trunk/reactos/regtests/winetests/user32/edit.c Modified: trunk/reactos/dll/win32/riched20/editor.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/riched20/editor.…
============================================================================== --- trunk/reactos/dll/win32/riched20/editor.c (original) +++ trunk/reactos/dll/win32/riched20/editor.c Mon Jan 22 06:00:02 2007 @@ -2137,7 +2137,7 @@ wcW.cbWndExtra = 4; wcW.hInstance = NULL; /* hInstance would register DLL-local class */ wcW.hIcon = NULL; - wcW.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM)); + wcW.hCursor = LoadCursorW(NULL, (LPCWSTR) IDC_IBEAM); wcW.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); wcW.lpszMenuName = NULL; wcW.lpszClassName = wszClassName; @@ -2153,7 +2153,7 @@ wcA.cbWndExtra = 4; wcA.hInstance = NULL; /* hInstance would register DLL-local class */ wcA.hIcon = NULL; - wcA.hCursor = LoadCursorW(NULL, MAKEINTRESOURCEW(IDC_IBEAM)); + wcA.hCursor = LoadCursorA(NULL, (LPCSTR) IDC_IBEAM); wcA.hbrBackground = (HBRUSH)GetStockObject(NULL_BRUSH); wcA.lpszMenuName = NULL; wcA.lpszClassName = "RichEdit20A"; Modified: trunk/reactos/regtests/winetests/user32/edit.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/regtests/winetests/user32/…
============================================================================== --- trunk/reactos/regtests/winetests/user32/edit.c (original) +++ trunk/reactos/regtests/winetests/user32/edit.c Mon Jan 22 06:00:02 2007 @@ -939,7 +939,7 @@ text_position.cbWndExtra = 0; text_position.hInstance = hinst; text_position.hIcon = NULL; - text_position.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW)); + text_position.hCursor = LoadCursorA(NULL, (LPCSTR) IDC_ARROW); text_position.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); text_position.lpszMenuName = NULL; text_position.lpszClassName = szEditTextPositionClass;
17 years, 11 months
1
0
0
0
[weiden] 25582: This is the last fix for GCC4.2. Now everything can be built with -O3
by weiden@svn.reactos.org
Author: weiden Date: Mon Jan 22 02:54:59 2007 New Revision: 25582 URL:
http://svn.reactos.org/svn/reactos?rev=25582&view=rev
Log: This is the last fix for GCC4.2. Now everything can be built with -O3 Modified: trunk/reactos/dll/win32/setupapi/parser.c trunk/reactos/subsystems/win32/win32k/objects/print.c Modified: trunk/reactos/dll/win32/setupapi/parser.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/setupapi/parser.…
============================================================================== --- trunk/reactos/dll/win32/setupapi/parser.c (original) +++ trunk/reactos/dll/win32/setupapi/parser.c Mon Jan 22 02:54:59 2007 @@ -1033,7 +1033,7 @@ const WCHAR *dir; WCHAR *ptr, *ret; INT dirid; - unsigned int len1; + unsigned int len1 = 0; DWORD len2; if (!SetupGetIntField( context, 1, &dirid )) return NULL; Modified: trunk/reactos/subsystems/win32/win32k/objects/print.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ob…
============================================================================== --- trunk/reactos/subsystems/win32/win32k/objects/print.c (original) +++ trunk/reactos/subsystems/win32/win32k/objects/print.c Mon Jan 22 02:54:59 2007 @@ -125,7 +125,7 @@ &BitmapObj->SurfObj, Escape, InSize, - (PVOID)InData, + (PVOID)((ULONG_PTR)InData), OutSize, (PVOID)OutData); }
17 years, 11 months
1
0
0
0
[janderwald] 25581: - define msvc compabitble debug macro - fix error in debug print
by janderwald@svn.reactos.org
Author: janderwald Date: Mon Jan 22 02:29:12 2007 New Revision: 25581 URL:
http://svn.reactos.org/svn/reactos?rev=25581&view=rev
Log: - define msvc compabitble debug macro - fix error in debug print Modified: trunk/reactos/dll/ntdll/ldr/utils.c Modified: trunk/reactos/dll/ntdll/ldr/utils.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/ntdll/ldr/utils.c?rev=…
============================================================================== --- trunk/reactos/dll/ntdll/ldr/utils.c (original) +++ trunk/reactos/dll/ntdll/ldr/utils.c Mon Jan 22 02:29:12 2007 @@ -29,7 +29,8 @@ #ifdef NDEBUG #if defined(__GNUC__) #define TRACE_LDR(args...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } -#else +#elif defined(_MSC_VER) +#define TRACE_LDR(args, ...) if (RtlGetNtGlobalFlags() & FLG_SHOW_LDR_SNAPS) { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(__VA_ARGS__); } #endif /* __GNUC__ */ #else #define TRACE_LDR(args...) do { DbgPrint("(LDR:%s:%d) ",__FILE__,__LINE__); DbgPrint(args); } while(0) @@ -736,7 +737,7 @@ TRACE_LDR("LdrLoadDll, loading %wZ%s%S\n", Name, - SearchPath ? " from " : "", + SearchPath ? L" from " : L"", SearchPath ? SearchPath : L""); if (Name == NULL)
17 years, 11 months
1
0
0
0
[weiden] 25580: Fix compilation with GCC4.2. Please check changes in CreateProcessInternalW for correctness!
by weiden@svn.reactos.org
Author: weiden Date: Mon Jan 22 02:29:10 2007 New Revision: 25580 URL:
http://svn.reactos.org/svn/reactos?rev=25580&view=rev
Log: Fix compilation with GCC4.2. Please check changes in CreateProcessInternalW for correctness! Modified: trunk/reactos/dll/win32/kernel32/misc/console.c trunk/reactos/dll/win32/kernel32/process/create.c Modified: trunk/reactos/dll/win32/kernel32/misc/console.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/co…
============================================================================== --- trunk/reactos/dll/win32/kernel32/misc/console.c (original) +++ trunk/reactos/dll/win32/kernel32/misc/console.c Mon Jan 22 02:29:10 2007 @@ -2765,10 +2765,10 @@ static BOOL IntScrollConsoleScreenBuffer(HANDLE hConsoleOutput, - PSMALL_RECT lpScrollRectangle, - PSMALL_RECT lpClipRectangle, + const SMALL_RECT *lpScrollRectangle, + const SMALL_RECT *lpClipRectangle, COORD dwDestinationOrigin, - PCHAR_INFO lpFill, + const CHAR_INFO *lpFill, BOOL bUnicode) { CSR_API_MESSAGE Request; ULONG CsrRequest; @@ -2846,10 +2846,10 @@ ) { return IntScrollConsoleScreenBuffer(hConsoleOutput, - (PSMALL_RECT)lpScrollRectangle, - (PSMALL_RECT)lpClipRectangle, + lpScrollRectangle, + lpClipRectangle, dwDestinationOrigin, - (PCHAR_INFO)lpFill, + lpFill, TRUE); } Modified: trunk/reactos/dll/win32/kernel32/process/create.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/process…
============================================================================== --- trunk/reactos/dll/win32/kernel32/process/create.c (original) +++ trunk/reactos/dll/win32/kernel32/process/create.c Mon Jan 22 02:29:10 2007 @@ -981,7 +981,7 @@ RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); return CreateProcessW(L"ntvdm.exe", - (LPWSTR)lpApplicationName, + (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */ lpProcessAttributes, lpThreadAttributes, bInheritHandles, @@ -1052,7 +1052,7 @@ RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer); RtlFreeHeap(RtlGetProcessHeap(), 0, ApplicationName.Buffer); return CreateProcessW(L"ntvdm.exe", - (LPWSTR)lpApplicationName, + (LPWSTR)((ULONG_PTR)lpApplicationName), /* FIXME: Buffer must be writable!!! */ lpProcessAttributes, lpThreadAttributes, bInheritHandles,
17 years, 11 months
1
0
0
0
[janderwald] 25579: msvc only knows _snprintf ...
by janderwald@svn.reactos.org
Author: janderwald Date: Mon Jan 22 02:23:24 2007 New Revision: 25579 URL:
http://svn.reactos.org/svn/reactos?rev=25579&view=rev
Log: msvc only knows _snprintf ... Modified: trunk/reactos/base/applications/utils/binpatch/patch.c Modified: trunk/reactos/base/applications/utils/binpatch/patch.c URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/utils/bi…
============================================================================== --- trunk/reactos/base/applications/utils/binpatch/patch.c (original) +++ trunk/reactos/base/applications/utils/binpatch/patch.c Mon Jan 22 02:23:24 2007 @@ -1,3 +1,4 @@ +#include <windows.h> #include <conio.h> #include <io.h> #include <stdio.h> @@ -502,7 +503,7 @@ if (c == 'y') { char buffer[MAX_PATH]; - snprintf(buffer, MAX_PATH, "%s.bak", fileName); + _snprintf(buffer, MAX_PATH, "%s.bak", fileName); buffer[MAX_PATH-1] = '\0'; makeBackup = 1; if (access(buffer, 0) >= 0) /* file exists */
17 years, 11 months
1
0
0
0
[janderwald] 25578: required cast because unsigned value ranges are always >= 0
by janderwald@svn.reactos.org
Author: janderwald Date: Mon Jan 22 02:21:55 2007 New Revision: 25578 URL:
http://svn.reactos.org/svn/reactos?rev=25578&view=rev
Log: required cast because unsigned value ranges are always >= 0 Modified: trunk/reactos/base/applications/network/telnet/src/tconsole.cpp Modified: trunk/reactos/base/applications/network/telnet/src/tconsole.cpp URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/network/…
============================================================================== --- trunk/reactos/base/applications/network/telnet/src/tconsole.cpp (original) +++ trunk/reactos/base/applications/network/telnet/src/tconsole.cpp Mon Jan 22 02:21:55 2007 @@ -417,7 +417,7 @@ if(ini.get_vt100_mode() && cbString + (unsigned)CON_CUR_X == (unsigned)CON_COLS) { cbString--; - if(cbString >= 0) WriteConsole(hConsole, pszString, cbString, &Result, 0); + if((long)cbString >= 0) WriteConsole(hConsole, pszString, cbString, &Result, 0); COORD dwBufferCoord; dwBufferCoord.X = 0;
17 years, 11 months
1
0
0
0
[janderwald] 25577: remove stdcall declaration
by janderwald@svn.reactos.org
Author: janderwald Date: Mon Jan 22 02:19:35 2007 New Revision: 25577 URL:
http://svn.reactos.org/svn/reactos?rev=25577&view=rev
Log: remove stdcall declaration Modified: trunk/reactos/base/applications/regedit/clb/clb.def Modified: trunk/reactos/base/applications/regedit/clb/clb.def URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/applications/regedit/…
============================================================================== --- trunk/reactos/base/applications/regedit/clb/clb.def (original) +++ trunk/reactos/base/applications/regedit/clb/clb.def Mon Jan 22 02:19:35 2007 @@ -1,10 +1,10 @@ LIBRARY clb.dll EXPORTS -ClbAddData@12 @1 -ClbSetColumnWidths@12 @2 -ClbStyleW@8 @3 -ClbWndProc@16 @4 -CustomControlInfoW@4 @5 +ClbAddData @1 +ClbSetColumnWidths @2 +ClbStyleW @3 +ClbWndProc @4 +CustomControlInfoW @5 ; EOF
17 years, 11 months
1
0
0
0
← Newer
1
...
6
7
8
9
10
11
12
...
41
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Results per page:
10
25
50
100
200