00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
#include "precomp.h"
00019
#pragma hdrstop
00020
00021
#include "dbt.h"
00022
#include "ntdddisk.h"
00023
#include "ntuser.h"
00024
00025
#include <winsta.h>
00026
#include <wstmsg.h>
00027
00028
00029
00030
00031
00032
VOID HardErrorRemove(
PCTXHARDERRORINFO);
00033
VOID RemoteMessageThread(PVOID);
00034
00035
00036
00037
00038
00039
VOID HardErrorInsert(PCSR_THREAD, PHARDERROR_MSG,
PCTXHARDERRORINFO);
00040
NTSTATUS ReplyMessageToTerminalServer(
PCTXHARDERRORINFO);
00041
00042 extern BOOLEAN
gbExitInProgress;
00043
00044
00045
00046
00047
00048 CONST
int aidReturn[] = { 0, 0, IDABORT, IDCANCEL, IDIGNORE, IDNO, IDOK, IDRETRY, IDYES };
00049 PCTXHARDERRORINFO gpchiList =
NULL;
00050 HANDLE
ghMessageThread =
NULL;
00051 DWORD gidMessageThread;
00052 OBJECT_ATTRIBUTES
g_ObjA;
00053 HANDLE
g_hDoMessageEvent =
NULL;
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
NTSTATUS
00068 RemoteDoMessage(
00069 PWINSTATION_APIMSG pMsg)
00070 {
00071 WINSTATIONSENDMESSAGEMSG * pSMsg = &pMsg->u.SendMessage;
00072
PCTXHARDERRORINFO pchi;
00073
NTSTATUS Status;
00074
00075
EnterCrit();
00076
00077
00078
00079
00080
if ((pchi = (
PCTXHARDERRORINFO)LocalAlloc(LPTR,
sizeof(
CTXHARDERRORINFO))) ==
NULL) {
00081
LeaveCrit();
00082
return (STATUS_NO_MEMORY);
00083 }
00084
else if ((pchi->
pTitle = LocalAlloc(LPTR, pSMsg->TitleLength +
sizeof(TCHAR))) ==
NULL) {
00085 LocalFree(pchi);
00086
LeaveCrit();
00087
return (STATUS_NO_MEMORY);
00088 }
00089
else if ((pchi->
pMessage = LocalAlloc(LPTR, pSMsg->MessageLength +
sizeof(TCHAR))) ==
NULL) {
00090 LocalFree(pchi->
pTitle);
00091 LocalFree(pchi);
00092
LeaveCrit();
00093
return (STATUS_NO_MEMORY);
00094 }
00095
00096
00097
00098
00099 pchi->
ClientId = pMsg->h.ClientId;
00100 pchi->
MessageId = pMsg->MessageId;
00101 pchi->
Timeout = pSMsg->Timeout;
00102 pchi->
pResponse = pSMsg->pResponse;
00103 pchi->
hEvent = pSMsg->hEvent;
00104 pchi->
DoNotWait = pSMsg->DoNotWait;
00105 pchi->
Style = pSMsg->Style;
00106
00107 pchi->
pTitle[pSMsg->TitleLength/
sizeof(TCHAR)] =
L'\0';
00108 RtlMoveMemory(pchi->
pTitle, pSMsg->pTitle, pSMsg->TitleLength);
00109
00110 pchi->
pMessage[pSMsg->MessageLength/
sizeof(TCHAR)] =
L'\0';
00111 RtlMoveMemory(pchi->
pMessage, pSMsg->pMessage, pSMsg->MessageLength);
00112
00113
DBGHYD((
"RemoteDoMessage: pchi->pTitle - %S\n", pchi->
pTitle));
00114
DBGHYD((
"RemoteDoMessage: pchi->pMessage - %S\n", pchi->
pMessage));
00115
00116
00117
00118
00119 pchi->
pchiNext =
gpchiList;
00120
gpchiList = pchi;
00121
00122
LeaveCrit();
00123
00124
00125
00126
00127
if (
ghMessageThread ==
NULL) {
00128
DBGHYD((
"RemoteDoMessage: starting RemoteMessageThread ...\n"));
00129
00130
if ((
ghMessageThread = CreateThread(
NULL, 4096,
00131 (LPTHREAD_START_ROUTINE)
RemoteMessageThread,
00132 (
LPVOID)
NULL,
00133 0, &
gidMessageThread)) ==
NULL) {
00134
00135
DBGHYD((
"RemoteDoMessage: cannot start RemoteMessageThread, error %u\n",
00136 GetLastError()));
00137 }
00138 }
else {
00139
if (
g_hDoMessageEvent ==
NULL) {
00140
return STATUS_UNSUCCESSFUL;
00141 }
00142
Status =
NtSetEvent(
g_hDoMessageEvent,
NULL);
00143
00144
if (!
NT_SUCCESS(
Status)) {
00145
DBGHYD((
"RemoteDoMessage: Error NtSetEvent failed, Status=%x, rc=%u\n",
00146
Status, GetLastError()));
00147
return Status;
00148 }
00149 }
00150
00151
return STATUS_SUCCESS;
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
VOID
00167 RemoteMessageThread(
00168 PVOID pVoid)
00169 {
00170 HARDERROR_MSG hemsg;
00171
PCTXHARDERRORINFO pchi, *ppchi;
00172 UNICODE_STRING Message, Title;
00173
NTSTATUS Status;
00174
00175
00176
00177
00178 InitializeObjectAttributes(&
g_ObjA,
NULL, 0,
NULL,
NULL);
00179
Status =
NtCreateEvent(&
g_hDoMessageEvent, EVENT_ALL_ACCESS, &
g_ObjA,
00180 NotificationEvent,
FALSE);
00181
00182
if (!
NT_SUCCESS(
Status)) {
00183
DBGHYD((
"RemoteMessageThread: Error NtCreateEvent failed, rc=%u\n",
00184 GetLastError()));
00185
return;
00186 }
00187
00188
while (!
gbExitInProgress) {
00189
00190
EnterCrit();
00191
00192
00193
00194
00195
if (
gpchiList !=
NULL) {
00196
00197
00198
00199
00200
for (ppchi = &
gpchiList;
00201 (*ppchi !=
NULL) && ((*ppchi)->pchiNext !=
NULL);
00202 ppchi = &(*ppchi)->
pchiNext) ;
00203
00204
00205
00206
00207
if ((pchi = *ppchi) !=
NULL) {
00208
00209
00210
00211
00212
for (ppchi = &
gpchiList; *ppchi !=
NULL && *ppchi != pchi;
00213 ppchi = &(*ppchi)->
pchiNext)
00214 ;
00215
00216
if (*ppchi !=
NULL) {
00217 *ppchi = pchi->
pchiNext;
00218 }
00219
00220
LeaveCrit();
00221
00222
00223
00224
00225
RtlInitUnicodeString(&Title, pchi->
pTitle);
00226
RtlInitUnicodeString(&Message, pchi->
pMessage);
00227
00228
00229
00230
00231 hemsg.h.ClientId = pchi->
ClientId;
00232 hemsg.Status = STATUS_SERVICE_NOTIFICATION;
00233 hemsg.NumberOfParameters = 3;
00234 hemsg.UnicodeStringParameterMask = 3;
00235 hemsg.ValidResponseOptions = OptionOk;
00236 hemsg.Parameters[0] = (ULONG_PTR)&Message;
00237 hemsg.Parameters[1] = (ULONG_PTR)&Title;
00238 hemsg.Parameters[2] = (ULONG_PTR)pchi->
Style;
00239
00240
00241
00242
00243
HardErrorInsert(
NULL, &hemsg, pchi);
00244 }
else {
00245
LeaveCrit();
00246 }
00247 }
else {
00248
LeaveCrit();
00249 }
00250
00251
if (
gpchiList ==
NULL) {
00252
00253 UserAssert(
g_hDoMessageEvent !=
NULL);
00254
00255
Status =
NtWaitForSingleObject(
g_hDoMessageEvent,
FALSE,
NULL);
00256
00257 UserAssert(
NT_SUCCESS(
Status));
00258
00259
NtResetEvent(
g_hDoMessageEvent,
NULL);
00260 }
00261 }
00262
00263
NtClose(
g_hDoMessageEvent);
00264
g_hDoMessageEvent =
NULL;
00265
00266
return;
00267
00268 UNREFERENCED_PARAMETER(pVoid);
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 VOID HardErrorRemove(
00283
PCTXHARDERRORINFO pchi)
00284 {
00285
00286
00287
00288
00289
if (!pchi->
DoNotWait) {
00290
ReplyMessageToTerminalServer(pchi);
00291 }
00292
00293
00294
00295
00296 LocalFree(pchi->
pMessage);
00297 LocalFree(pchi->
pTitle);
00298 LocalFree(pchi);
00299 }