summaryrefslogtreecommitdiffstats
path: root/private/ntos/dll/dlluistb.c
blob: dcc86921dfffae9c01fea92c4f55bafc82bb7c15 (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
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    dlluistb.c

Abstract:

    Debug Subsystem DbgUi API Stubs

Author:

    Mark Lucovsky (markl) 23-Jan-1990

Revision History:

--*/

#include "dbgdllp.h"

#define DbgStateChangeSemaphore (NtCurrentTeb()->DbgSsReserved[0])
#define DbgUiApiPort (NtCurrentTeb()->DbgSsReserved[1])

NTSTATUS
DbgUiConnectToDbg( VOID )

/*++

Routine Description:

    This routine makes a connection between the caller and the DbgUi
    port in the Dbg subsystem.  In addition to returning a handle to a
    port object, a handle to a state change semaphore is returned.  This
    semaphore is used in DbgUiWaitStateChange APIs.

Arguments:

    None.

Return Value:

    TBD.

--*/

{
    NTSTATUS st;
    UNICODE_STRING PortName;
    ULONG ConnectionInformationLength;
    SECURITY_QUALITY_OF_SERVICE DynamicQos;

    //
    // if app is already connected, don't reconnect
    //
    st = STATUS_SUCCESS;
    if ( !DbgUiApiPort ) {
        //
        // Set up the security quality of service parameters to use over the
        // port.  Use the most efficient (least overhead) - which is dynamic
        // rather than static tracking.
        //

        DynamicQos.ImpersonationLevel = SecurityImpersonation;
        DynamicQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
        DynamicQos.EffectiveOnly = TRUE;


        RtlInitUnicodeString(&PortName,L"\\DbgUiApiPort");
        ConnectionInformationLength = sizeof(DbgStateChangeSemaphore);
        st = NtConnectPort(
                &DbgUiApiPort,
                &PortName,
                &DynamicQos,
                NULL,
                NULL,
                NULL,
                (PVOID)&DbgStateChangeSemaphore,
                &ConnectionInformationLength
                );
        if ( NT_SUCCESS(st) ) {
            NtRegisterThreadTerminatePort(DbgUiApiPort);
        } else {
            DbgUiApiPort = NULL;
        }
    }
    return st;

}

NTSTATUS
DbgUiWaitStateChange (
    OUT PDBGUI_WAIT_STATE_CHANGE StateChange,
    IN PLARGE_INTEGER Timeout OPTIONAL
    )

/*++

Routine Description:

    This function causes the calling user interface to wait for a
    state change to occur in one of it's application threads. The
    wait is ALERTABLE.

Arguments:

    StateChange - Supplies the address of state change record that
        will contain the state change information.

Return Value:

    TBD

--*/

{
    NTSTATUS st;
    DBGUI_APIMSG ApiMsg;
    PDBGUI_WAIT_STATE_CHANGE args;


    //
    // Wait for a StateChange to occur
    //

top:
    st = NtWaitForSingleObject(DbgStateChangeSemaphore,TRUE,Timeout);
    if ( st != STATUS_SUCCESS ) {
        return st;
    }

    //
    // Pick up the state change
    //

    args = &ApiMsg.u.WaitStateChange;

    DBGUI_FORMAT_API_MSG(ApiMsg,DbgUiWaitStateChangeApi,sizeof(*args));
    st = NtRequestWaitReplyPort(
            DbgUiApiPort,
            (PPORT_MESSAGE) &ApiMsg,
            (PPORT_MESSAGE) &ApiMsg
            );

    if ( NT_SUCCESS(st) ) {
        if ( ApiMsg.ReturnedStatus == DBG_NO_STATE_CHANGE ) {
            DbgPrint("DBGUISTB: Waring No State Change\n");
            goto top;
        }
        *StateChange = *args;
        return ApiMsg.ReturnedStatus;
    } else {
        return st;
    }
}

NTSTATUS
DbgUiContinue (
    IN PCLIENT_ID AppClientId,
    IN NTSTATUS ContinueStatus
    )

/*++

Routine Description:

    This function continues an application thread whose state change was
    previously reported through DbgUiWaitStateChange.

Arguments:

    AppClientId - Supplies the address of the ClientId of the
        application thread being continued.  This must be an application
        thread that previously notified the caller through
        DbgUiWaitStateChange but has not yet been continued.

    ContinueStatus - Supplies the continuation status to the thread
        being continued.  valid values for this are:

        DBG_EXCEPTION_HANDLED
        DBG_EXCEPTION_NOT_HANDLED
        DBG_TERMINATE_THREAD
        DBG_TERMINATE_PROCESS
        DBG_CONTINUE

Return Value:

    STATUS_SUCCESS - Successful call to DbgUiContinue

    STATUS_INVALID_CID - An invalid ClientId was specified for the
        AppClientId, or the specified Application was not waiting
        for a continue.

    STATUS_INVALID_PARAMETER - An invalid continue status was specified.

--*/

{
    NTSTATUS st;
    DBGUI_APIMSG ApiMsg;
    PDBGUI_CONTINUE args;


    args = &ApiMsg.u.Continue;
    args->AppClientId = *AppClientId;
    args->ContinueStatus = ContinueStatus;

    DBGUI_FORMAT_API_MSG(ApiMsg,DbgUiContinueApi,sizeof(*args));

    st = NtRequestWaitReplyPort(
            DbgUiApiPort,
            (PPORT_MESSAGE) &ApiMsg,
            (PPORT_MESSAGE) &ApiMsg
            );

    if ( NT_SUCCESS(st) ) {
        return ApiMsg.ReturnedStatus;
    } else {
        return st;
    }
}