summaryrefslogtreecommitdiffstats
path: root/private/sm/server/dbgapsup.c
blob: 6233b8a9b2b6a28f120c256ad6b35ab76aac94ba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    dbgapsup.c

Abstract:

    This module implements support routines for application threads

Author:

    Mark Lucovsky (markl) 23-Jan-1990

Revision History:

--*/

#include "smsrvp.h"

PDBGP_APP_THREAD
DbgpIsAppInHashTable(
    IN PCLIENT_ID AppClientId
    )

/*++

Routine Description:

    This routine scans the application thread hash table looking
    for an application thread that matches the specified client id.

    If a matching application thread is found, then its address is
    returned.

Arguments:

    AppClientId - Supplies the address of ClientId of the application
        thread to locate.

Return Value:

    NULL - No application thread with a matching ClientId could be located.

    NON-NULL - Returns the address of the application thread that
        matches the specified ClientId.

--*/

{
    ULONG Index;
    PLIST_ENTRY Head, Next;
    PDBGP_APP_THREAD AppThread;

    RtlEnterCriticalSection(&DbgpHashTableLock);

    Index = DBGP_THREAD_CLIENT_ID_TO_INDEX(AppClientId);

    Head = &DbgpAppThreadHashTable[Index];
    Next = Head->Flink;

    while ( Next != Head ) {
        AppThread = CONTAINING_RECORD(Next,DBGP_APP_THREAD,HashTableLinks);
        if ( DBGP_CLIENT_IDS_EQUAL(
                &AppThread->AppClientId,
                AppClientId
                )) {
            RtlLeaveCriticalSection(&DbgpHashTableLock);
//DbgpDumpAppThread(AppThread);
            return AppThread;
        }
        Next = Next->Flink;
    }

    RtlLeaveCriticalSection(&DbgpHashTableLock);
#if DBG
//    DbgPrint("DBGSS: AppThread for %lx.%lx Not Found\n",AppClientId->UniqueProcess,AppClientId->UniqueThread);
#endif // DBG
    return NULL;
}

PDBGP_APP_PROCESS
DbgpIsAppProcessInHashTable(
    IN PCLIENT_ID AppClientId
    )

/*++

Routine Description:

    This routine scans the application process hash table looking for an
    application process whose ClientId.UniqueOrocess field matches the
    specified client id's.

    If a matching application process is found, then its address is
    returned.

Arguments:

    AppClientId - Supplies the address of ClientId of the application
        process to locate.

Return Value:

    NULL - No application process with a matching ClientId could be located.

    NON-NULL - Returns the address of the application process that
        matches the specified ClientId.

--*/

{
    ULONG Index;
    PLIST_ENTRY Head, Next;
    PDBGP_APP_PROCESS AppProcess;

    RtlEnterCriticalSection(&DbgpHashTableLock);

    Index = DBGP_PROCESS_CLIENT_ID_TO_INDEX(AppClientId);

    Head = &DbgpAppProcessHashTable[Index];
    Next = Head->Flink;

    while ( Next != Head ) {
        AppProcess = CONTAINING_RECORD(Next,DBGP_APP_PROCESS,HashTableLinks);
        if ( AppProcess->AppClientId.UniqueProcess == AppClientId->UniqueProcess) {
            RtlLeaveCriticalSection(&DbgpHashTableLock);
            return AppProcess;
        }
        Next = Next->Flink;
    }

    RtlLeaveCriticalSection(&DbgpHashTableLock);
#if DBG
//    DbgPrint("DBGSS: AppProcess for %lx.%lx Not Found\n",AppClientId->UniqueProcess,AppClientId->UniqueThread);
#endif // DBG
    return NULL;
}

PDBGP_APP_THREAD
DbgpLocateStateChangeApp(
    IN PDBGP_USER_INTERFACE UserInterface,
    OUT PDBG_STATE PreviousState
    )

/*++

Routine Description:

    This routine scans the specified user interface's application list
    looking for an application whose state has changed.  If an
    application whose State is not DbgIdle or DbgReplyPending is found,
    its address is returned.

Arguments:

    UserInterface - Supplies the address of UserInterface whose
        application list is to be scanned.

    PreviousState - Supplies the address of a variable that returns
        the previous debug state of an application thread reporting
        a state change.

Return Value:

    NULL - No application thread reporting a state change could be located.

    NON-NULL - Returns the address of the application thread reporting a state
        change.

--*/

{
    PLIST_ENTRY HeadProcess, NextProcess;
    PLIST_ENTRY HeadThread, NextThread;
    PDBGP_APP_THREAD AppThread;
    PDBGP_APP_PROCESS AppProcess;

    RtlEnterCriticalSection(&UserInterface->UserInterfaceLock);

    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);

        HeadThread = &AppProcess->AppThreadListHead;
        NextThread = HeadThread->Flink;

        while ( NextThread != HeadThread ) {
            AppThread = CONTAINING_RECORD(NextThread,DBGP_APP_THREAD,AppLinks);
            if ( DBGP_REPORTING_STATE_CHANGE(AppThread) ) {
                *PreviousState = AppThread->CurrentState;
                AppThread->ContinueState = AppThread->CurrentState;
                AppThread->CurrentState = DbgReplyPending;

                //
                // Reshuffle so that this thread is placed
                // at front of list for process, and so that
                // process is placed at front of list for
                // user interface
                //

                RemoveEntryList(&AppThread->AppLinks);
                InsertHeadList(
                    &AppProcess->AppThreadListHead,
                    &AppThread->AppLinks
                    );

                RemoveEntryList(&AppProcess->AppLinks);
                InsertHeadList(
                    &UserInterface->AppProcessListHead,
                    &AppProcess->AppLinks
                    );

                RtlLeaveCriticalSection(&UserInterface->UserInterfaceLock);
//DbgpDumpAppThread(AppThread);
                return AppThread;
            }
            NextThread = NextThread->Flink;
        }

        NextProcess = NextProcess->Flink;
    }

    RtlLeaveCriticalSection(&UserInterface->UserInterfaceLock);
    return NULL;
}