Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

icamsg.c

Go to the documentation of this file.
00001 00002 /************************************************************************* 00003 * 00004 * icamsg.c 00005 * 00006 * Process ICA send message requests 00007 * 00008 * Copyright (c) 1985 - 1999, Microsoft Corporation 00009 * 00010 * $Author: 00011 * 00012 *************************************************************************/ 00013 00014 /* 00015 * Includes 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 * Local functions 00031 */ 00032 VOID HardErrorRemove(PCTXHARDERRORINFO); 00033 VOID RemoteMessageThread(PVOID); 00034 00035 00036 /* 00037 * External functions 00038 */ 00039 VOID HardErrorInsert(PCSR_THREAD, PHARDERROR_MSG, PCTXHARDERRORINFO); 00040 NTSTATUS ReplyMessageToTerminalServer(PCTXHARDERRORINFO); 00041 00042 extern BOOLEAN gbExitInProgress; 00043 00044 /* 00045 * Local data 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 * RemoteDoMessage 00059 * 00060 * ENTRY: 00061 * 00062 * EXIT: 00063 * STATUS_SUCCESS - successful 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(); // to synchronize heap calls 00076 00077 /* 00078 * Create list entry 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 * Initialize 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 * Link in at head 00118 */ 00119 pchi->pchiNext = gpchiList; 00120 gpchiList = pchi; 00121 00122 LeaveCrit(); 00123 00124 /* 00125 * Start message thread if not running, otherwise signal thread 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 * RemoteMessageThread 00158 * 00159 * ENTRY: 00160 * 00161 * EXIT: 00162 * STATUS_SUCCESS - successful 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 * Create sync event 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(); // to synchronize heap calls 00191 00192 /* 00193 * Valid list 00194 */ 00195 if (gpchiList != NULL) { 00196 00197 /* 00198 * Find last entry 00199 */ 00200 for (ppchi = &gpchiList; 00201 (*ppchi != NULL) && ((*ppchi)->pchiNext != NULL); 00202 ppchi = &(*ppchi)->pchiNext) ; 00203 00204 /* 00205 * Found it 00206 */ 00207 if ((pchi = *ppchi) != NULL) { 00208 00209 /* 00210 * Unlink from the list. 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 * Make strings unicode 00224 */ 00225 RtlInitUnicodeString(&Title, pchi->pTitle); 00226 RtlInitUnicodeString(&Message, pchi->pMessage); 00227 00228 /* 00229 * Initialize harderror message struct 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 * Place message in harderror queue 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 * HardErrorRemove 00274 * 00275 * ENTRY: 00276 * 00277 * EXIT: 00278 * STATUS_SUCCESS - successful 00279 * 00280 ******************************************************************************/ 00281 00282 VOID HardErrorRemove( 00283 PCTXHARDERRORINFO pchi) 00284 { 00285 00286 /* 00287 * Notify ICASRV's RPC thread if waiting 00288 */ 00289 if (!pchi->DoNotWait) { 00290 ReplyMessageToTerminalServer(pchi); 00291 } 00292 00293 /* 00294 * Free memory 00295 */ 00296 LocalFree(pchi->pMessage); 00297 LocalFree(pchi->pTitle); 00298 LocalFree(pchi); 00299 }

Generated on Sat May 15 19:40:19 2004 for test by doxygen 1.3.7