summaryrefslogtreecommitdiffstats
path: root/private/sm/server/dbguisup.c
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/sm/server/dbguisup.c
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/sm/server/dbguisup.c')
-rw-r--r--private/sm/server/dbguisup.c242
1 files changed, 242 insertions, 0 deletions
diff --git a/private/sm/server/dbguisup.c b/private/sm/server/dbguisup.c
new file mode 100644
index 000000000..2fbcfb0e1
--- /dev/null
+++ b/private/sm/server/dbguisup.c
@@ -0,0 +1,242 @@
+/*++
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ dbguisup.c
+
+Abstract:
+
+ This module implements support routines for User Interfaces
+
+Author:
+
+ Mark Lucovsky (markl) 23-Jan-1990
+
+Revision History:
+
+--*/
+
+#include "smsrvp.h"
+
+PDBGP_USER_INTERFACE
+DbgpIsUiInHashTable(
+ IN PCLIENT_ID DebugUiClientId
+ )
+
+/*++
+
+Routine Description:
+
+ This routine scans the user interface hash table looking
+ for a user interface that matches the specified client id.
+
+ If a matching user interface is found, then its address is
+ returned.
+
+Arguments:
+
+ DebugUiClientId - Supplies the address of ClientId of the user
+ interface to locate.
+
+Return Value:
+
+ NULL - No user interface with a matching ClientId could be located.
+
+ NON-NULL - Returns the address of the user interface that matches
+ the specified ClientId.
+
+--*/
+
+{
+ ULONG Index;
+ PLIST_ENTRY Head, Next;
+ PDBGP_USER_INTERFACE UserInterface;
+
+ RtlEnterCriticalSection(&DbgpHashTableLock);
+
+ Index = DBGP_PROCESS_CLIENT_ID_TO_INDEX(DebugUiClientId);
+
+ Head = &DbgpUiHashTable[Index];
+ Next = Head->Flink;
+
+ while ( Next != Head ) {
+ UserInterface = CONTAINING_RECORD(Next,DBGP_USER_INTERFACE,HashTableLinks);
+ if ( DBGP_CLIENT_IDS_EQUAL(
+ &UserInterface->DebugUiClientId,
+ DebugUiClientId
+ )) {
+ RtlLeaveCriticalSection(&DbgpHashTableLock);
+ return UserInterface;
+ }
+ Next = Next->Flink;
+ }
+
+ RtlLeaveCriticalSection(&DbgpHashTableLock);
+ return NULL;
+}
+
+VOID
+DbgpUiHasTerminated(
+ IN PCLIENT_ID DebugUiClientId
+ )
+
+/*++
+
+Routine Description:
+
+ This routine processes client died messages from a user interface.
+ Its purpose is to cleanup all control blocks/data structures associated
+ with a user-interface.
+
+Arguments:
+
+ DebugUiClientId - Supplies the client id of the terminated Ui.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ PLIST_ENTRY HeadProcess, NextProcess;
+ PLIST_ENTRY HeadThread, NextThread;
+ PDBGP_APP_THREAD AppThread;
+ PDBGP_APP_PROCESS AppProcess;
+ NTSTATUS st;
+ PDBGP_USER_INTERFACE UserInterface;
+ DBGSRV_APIMSG ContinueMsg;
+ HANDLE NullPort;
+ HANDLE Thread;
+ OBJECT_ATTRIBUTES ThreadObja;
+ KERNEL_USER_TIMES Times;
+
+ InitializeObjectAttributes(&ThreadObja, NULL, 0, NULL, NULL);
+ NullPort = NULL;
+ RtlEnterCriticalSection(&DbgpHashTableLock);
+ UserInterface = DbgpIsUiInHashTable(DebugUiClientId);
+ if ( !UserInterface ) {
+ RtlLeaveCriticalSection(&DbgpHashTableLock);
+ return;
+ }
+
+ //
+ // User interface was located, so take it out of the list.
+ //
+
+ RemoveEntryList(&UserInterface->HashTableLinks);
+ RtlLeaveCriticalSection(&DbgpHashTableLock);
+
+ //
+ // Now process each thread and process owned by the user-interface
+ //
+
+ HeadProcess = &UserInterface->AppProcessListHead;
+ NextProcess = HeadProcess->Flink;
+
+ while ( NextProcess != HeadProcess ) {
+
+ //
+ // For each process managed by the user interface,
+ // scan its thread list
+ //
+
+ AppProcess = CONTAINING_RECORD(NextProcess,DBGP_APP_PROCESS,AppLinks);
+ NtSetInformationProcess(
+ AppProcess->DbgSrvHandleToProcess,
+ ProcessDebugPort,
+ &NullPort,
+ sizeof(HANDLE)
+ );
+
+ HeadThread = &AppProcess->AppThreadListHead;
+ NextThread = HeadThread->Flink;
+
+ while ( NextThread != HeadThread ) {
+ AppThread = CONTAINING_RECORD(NextThread,DBGP_APP_THREAD,AppLinks);
+
+ //
+ // Terminate the thread if not already dead
+ //
+
+ st = NtOpenThread(
+ &Thread,
+ THREAD_TERMINATE | THREAD_QUERY_INFORMATION,
+ &ThreadObja,
+ &AppThread->AppClientId
+ );
+
+ if ( NT_SUCCESS(st) ) {
+
+ //
+ // check exit time
+ //
+
+ st = NtQueryInformationThread(
+ Thread,
+ ThreadTimes,
+ (PVOID) &Times,
+ sizeof(Times),
+ NULL
+ );
+ if ( NT_SUCCESS(st) ) {
+ if ( Times.ExitTime.LowPart == 0 &&
+ Times.ExitTime.HighPart == 0 ) {
+ NtTerminateThread(Thread,DBG_TERMINATE_PROCESS);
+ }
+ }
+
+ NtClose(Thread);
+ }
+
+ if ( AppThread->CurrentState == DbgReplyPending ) {
+
+ AppThread->CurrentState = DbgIdle;
+ DBGSRV_FORMAT_API_MSG(ContinueMsg,DbgSrvContinueApi,0L,AppThread->LastSsApiMsg.ContinueKey);
+ ContinueMsg.ReturnedStatus = DBG_CONTINUE;
+ st = NtRequestPort(
+ AppThread->Subsystem->CommunicationPort,
+ (PPORT_MESSAGE)&ContinueMsg
+ );
+ ASSERT(NT_SUCCESS(st));
+
+ }
+ else {
+ if ( DBGP_REPORTING_STATE_CHANGE(AppThread) ) {
+ AppThread->ContinueState = AppThread->CurrentState;
+ AppThread->CurrentState = DbgIdle;
+ DBGSRV_FORMAT_API_MSG(ContinueMsg,DbgSrvContinueApi,0L,AppThread->LastSsApiMsg.ContinueKey);
+ ContinueMsg.ReturnedStatus = DBG_CONTINUE;
+ st = NtRequestPort(
+ AppThread->Subsystem->CommunicationPort,
+ (PPORT_MESSAGE)&ContinueMsg
+ );
+ }
+ }
+
+ if ( AppThread->HandleToThread &&
+ !AppThread->HandleToThread & 1 ) {
+ NtClose(AppThread->HandleToThread);
+ }
+
+ NextThread = NextThread->Flink;
+ RemoveEntryList(&AppThread->AppLinks);
+ RemoveEntryList(&AppThread->HashTableLinks);
+ RtlFreeHeap(RtlProcessHeap(), 0,AppThread);
+ }
+ NtClose(AppProcess->DbgSrvHandleToProcess);
+
+ NextProcess = NextProcess->Flink;
+ RemoveEntryList(&AppProcess->HashTableLinks);
+ RemoveEntryList(&AppProcess->AppLinks);
+ RtlFreeHeap(RtlProcessHeap(), 0,AppProcess);
+ }
+ NtClose(UserInterface->CommunicationPort);
+ NtClose(UserInterface->DebugUiProcess);
+ NtClose(UserInterface->StateChangeSemaphore);
+ RtlDeleteCriticalSection(&UserInterface->UserInterfaceLock);
+ RtlFreeHeap(RtlProcessHeap(), 0,UserInterface);
+}