From e856535365d4e5f357aa88329dabd22383a44008 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Wed, 8 Feb 2012 22:05:53 +0000 Subject: [PATCH] [SMSS2]: Implement (not yet used) Session Management APIs. svn path=/trunk/; revision=55501 --- reactos/base/system/smss2/smsessn.c | 141 +++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 1 deletion(-) diff --git a/reactos/base/system/smss2/smsessn.c b/reactos/base/system/smss2/smsessn.c index c8d44558013..6cee473dc79 100644 --- a/reactos/base/system/smss2/smsessn.c +++ b/reactos/base/system/smss2/smsessn.c @@ -14,6 +14,14 @@ /* GLOBALS ********************************************************************/ +typedef struct _SMP_SESSION +{ + LIST_ENTRY Entry; + ULONG SessionId; + PSMP_SUBSYSTEM Subsystem; + PSMP_SUBSYSTEM OtherSubsystem; +} SMP_SESSION, *PSMP_SESSION; + RTL_CRITICAL_SECTION SmpSessionListLock; LIST_ENTRY SmpSessionListHead; ULONG SmpNextSessionId; @@ -23,6 +31,137 @@ HANDLE SmpSessionsObjectDirectory; /* FUNCTIONS ******************************************************************/ +BOOLEAN +NTAPI +SmpCheckDuplicateMuSessionId(IN ULONG MuSessionId) +{ + PSMP_SUBSYSTEM Subsystem; + BOOLEAN FoundDuplicate = FALSE; + PLIST_ENTRY NextEntry; + + /* Lock the subsystem database */ + RtlEnterCriticalSection(&SmpKnownSubSysLock); + + /* Scan each entry */ + NextEntry = SmpKnownSubSysHead.Flink; + while (NextEntry != &SmpKnownSubSysHead) + { + /* Check if this entry has the same session ID */ + Subsystem = CONTAINING_RECORD(NextEntry, SMP_SUBSYSTEM, Entry); + if (Subsystem->MuSessionId == MuSessionId) + { + /* Break out of here! */ + FoundDuplicate = TRUE; + break; + } + + /* Keep going */ + NextEntry = NextEntry->Flink; + } + + /* Release the database and return the result */ + RtlLeaveCriticalSection(&SmpKnownSubSysLock); + return FoundDuplicate; +} + +PSMP_SESSION +NTAPI +SmpSessionIdToSession(IN ULONG SessionId) +{ + PSMP_SESSION Session, FoundSession = NULL; + PLIST_ENTRY NextEntry; + + /* Loop the session list -- lock must already be held! */ + NextEntry = SmpSessionListHead.Flink; + while (NextEntry != &SmpSessionListHead) + { + /* Check if this session's ID matches */ + Session = CONTAINING_RECORD(NextEntry, SMP_SESSION, Entry); + if (Session->SessionId == SessionId) + { + /* Set this as the found session and break out */ + FoundSession = Session; + break; + } + + /* Keep going */ + NextEntry = NextEntry->Flink; + } + + /* Return the session that was found and exit */ + return FoundSession; +} + +VOID +NTAPI +SmpDeleteSession(IN ULONG SessionId) +{ + PSMP_SESSION Session; + + /* Enter the lock and get the session structure */ + RtlEnterCriticalSection(&SmpSessionListLock); + Session = SmpSessionIdToSession(SessionId); + if (Session) + { + /* Remove it from the list */ + RemoveEntryList(&Session->Entry); + RtlLeaveCriticalSection(&SmpSessionListLock); + + /* Now free the structure outside of the lock */ + RtlFreeHeap(SmpHeap, 0, Session); + } + else + { + /* ID doesn't map to one of our structures, nothing to do... */ + RtlLeaveCriticalSection(&SmpSessionListLock); + } +} + +ULONG +NTAPI +SmpAllocateSessionId(IN PSMP_SUBSYSTEM Subsystem, + IN PSMP_SUBSYSTEM OtherSubsystem) +{ + ULONG SessionId; + PSMP_SESSION Session; + + /* Allocate a new ID while under the lock */ + RtlEnterCriticalSection(&SmpSessionListLock); + SessionId = SmpNextSessionId++; + + /* Check for overflow */ + if (SmpNextSessionIdScanMode) + { + /* Break if it happened */ + DbgPrint("SMSS: SessionId's Wrapped\n"); + DbgBreakPoint(); + } + else + { + /* Detect it for next time */ + if (!SmpNextSessionId) SmpNextSessionIdScanMode = 1; + } + + /* Allocate a session structure */ + Session = RtlAllocateHeap(SmpHeap, 0, sizeof(SMP_SESSION)); + if (Session) + { + /* Write the session data and insert it into the session list */ + Session->Subsystem = Subsystem; + Session->SessionId = SessionId; + Session->OtherSubsystem = OtherSubsystem; + InsertTailList(&SmpSessionListHead, &Session->Entry); + } + else + { + DPRINT1("SMSS: Unable to keep track of session ID -- no memory available\n"); + } + + /* Release the session lock */ + RtlLeaveCriticalSection(&SmpSessionListLock); + return SessionId; +} + NTSTATUS NTAPI SmpGetProcessMuSessionId(IN HANDLE ProcessHandle, @@ -49,7 +188,7 @@ SmpGetProcessMuSessionId(IN HANDLE ProcessHandle, ProcessHandle, Status); *SessionId = 0; } - + /* Return result */ return Status; }