Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenserver.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS CSR Sub System 00004 * FILE: subsys/csr/csrsrv/server.c 00005 * PURPOSE: CSR Server DLL Server Functions 00006 * PROGRAMMERS: Alex Ionescu (alex@relsoft.net) 00007 */ 00008 00009 /* INCLUDES ******************************************************************/ 00010 #include "srv.h" 00011 00012 #define NDEBUG 00013 #include <debug.h> 00014 00015 /* DATA **********************************************************************/ 00016 00017 PCSR_API_ROUTINE CsrServerApiDispatchTable[5] = 00018 { 00019 CsrSrvClientConnect, 00020 CsrSrvUnusedFunction, 00021 CsrSrvUnusedFunction, 00022 CsrSrvIdentifyAlertableThread, 00023 CsrSrvSetPriorityClass 00024 }; 00025 00026 BOOLEAN CsrServerApiServerValidTable[5] = 00027 { 00028 TRUE, 00029 FALSE, 00030 TRUE, 00031 TRUE, 00032 TRUE 00033 }; 00034 00035 PCHAR CsrServerApiNameTable[5] = 00036 { 00037 "ClientConnect", 00038 "ThreadConnect", 00039 "ProfileControl", 00040 "IdentifyAlertableThread", 00041 "SetPriorityClass" 00042 }; 00043 00044 PCSR_SERVER_DLL CsrLoadedServerDll[CSR_SERVER_DLL_MAX]; 00045 PVOID CsrSrvSharedSectionHeap; 00046 PVOID CsrSrvSharedSectionBase; 00047 PVOID *CsrSrvSharedStaticServerData; 00048 ULONG CsrSrvSharedSectionSize; 00049 HANDLE CsrSrvSharedSection; 00050 00051 /* PRIVATE FUNCTIONS**********************************************************/ 00052 00053 /*++ 00054 * @name CsrLoadServerDll 00055 * @implemented NT4 00056 * 00057 * The CsrLoadServerDll routine loads a CSR Server DLL and calls its entrypoint 00058 * 00059 * @param DllString 00060 * Pointer to the CSR Server DLL to load and call. 00061 * 00062 * @param EntryPoint 00063 * Pointer to the name of the server's initialization function. If 00064 * this parameter is NULL, the default ServerDllInitialize will be 00065 * assumed. 00066 * 00067 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00068 * othwerwise. 00069 * 00070 * @remarks None. 00071 * 00072 *--*/ 00073 NTSTATUS 00074 NTAPI 00075 CsrLoadServerDll(IN PCHAR DllString, 00076 IN PCHAR EntryPoint OPTIONAL, 00077 IN ULONG ServerId) 00078 { 00079 NTSTATUS Status; 00080 ANSI_STRING DllName; 00081 UNICODE_STRING TempString, ErrorString; 00082 ULONG_PTR Parameters[2]; 00083 HANDLE hServerDll = NULL; 00084 ULONG Size; 00085 PCSR_SERVER_DLL ServerDll; 00086 STRING EntryPointString; 00087 PCSR_SERVER_DLL_INIT_CALLBACK ServerDllInitProcedure; 00088 ULONG Response; 00089 00090 /* Check if it's beyond the maximum we support */ 00091 if (ServerId >= CSR_SERVER_DLL_MAX) return STATUS_TOO_MANY_NAMES; 00092 00093 /* Check if it's already been loaded */ 00094 if (CsrLoadedServerDll[ServerId]) return STATUS_INVALID_PARAMETER; 00095 00096 /* Convert the name to Unicode */ 00097 ASSERT(DllString != NULL); 00098 RtlInitAnsiString(&DllName, DllString); 00099 Status = RtlAnsiStringToUnicodeString(&TempString, &DllName, TRUE); 00100 if (!NT_SUCCESS(Status)) return Status; 00101 00102 /* If we are loading ourselves, don't actually load us */ 00103 if (ServerId != CSR_SRV_SERVER) 00104 { 00105 /* Load the DLL */ 00106 Status = LdrLoadDll(NULL, 0, &TempString, &hServerDll); 00107 if (!NT_SUCCESS(Status)) 00108 { 00109 /* Setup error parameters */ 00110 Parameters[0] = (ULONG_PTR)&TempString; 00111 Parameters[1] = (ULONG_PTR)&ErrorString; 00112 RtlInitUnicodeString(&ErrorString, L"Default Load Path"); 00113 00114 /* Send a hard error */ 00115 NtRaiseHardError(Status, 00116 2, 00117 3, 00118 Parameters, 00119 OptionOk, 00120 &Response); 00121 } 00122 00123 /* Get rid of the string */ 00124 RtlFreeUnicodeString(&TempString); 00125 if (!NT_SUCCESS(Status)) return Status; 00126 } 00127 00128 /* Allocate a CSR DLL Object */ 00129 Size = sizeof(CSR_SERVER_DLL) + DllName.MaximumLength; 00130 ServerDll = RtlAllocateHeap(CsrHeap, HEAP_ZERO_MEMORY, Size); 00131 if (!ServerDll) 00132 { 00133 if (hServerDll) LdrUnloadDll(hServerDll); 00134 return STATUS_NO_MEMORY; 00135 } 00136 00137 /* Set up the Object */ 00138 ServerDll->Length = Size; 00139 ServerDll->SharedSection = CsrSrvSharedSectionHeap; 00140 ServerDll->Event = CsrInitializationEvent; 00141 ServerDll->Name.Length = DllName.Length; 00142 ServerDll->Name.MaximumLength = DllName.MaximumLength; 00143 ServerDll->Name.Buffer = (PCHAR)(ServerDll + 1); 00144 if (DllName.Length) 00145 { 00146 strncpy(ServerDll->Name.Buffer, DllName.Buffer, DllName.Length); 00147 } 00148 ServerDll->ServerId = ServerId; 00149 ServerDll->ServerHandle = hServerDll; 00150 00151 /* Now get the entrypoint */ 00152 if (hServerDll) 00153 { 00154 /* Initialize a string for the entrypoint, or use the default */ 00155 RtlInitAnsiString(&EntryPointString, 00156 !(EntryPoint) ? "ServerDllInitialization" : 00157 EntryPoint); 00158 00159 /* Get a pointer to it */ 00160 Status = LdrGetProcedureAddress(hServerDll, 00161 &EntryPointString, 00162 0, 00163 (PVOID)&ServerDllInitProcedure); 00164 } 00165 else 00166 { 00167 /* No handle, so we are loading ourselves */ 00168 ServerDllInitProcedure = CsrServerDllInitialization; 00169 Status = STATUS_SUCCESS; 00170 } 00171 00172 /* Check if we got the pointer, and call it */ 00173 if (NT_SUCCESS(Status)) 00174 { 00175 /* Get the result from the Server DLL */ 00176 Status = ServerDllInitProcedure(ServerDll); 00177 00178 /* Check for Success */ 00179 if (NT_SUCCESS(Status)) 00180 { 00181 /* 00182 * Add this Server's Per-Process Data Size to the total that each 00183 * process will need. 00184 */ 00185 CsrTotalPerProcessDataLength += ServerDll->SizeOfProcessData; 00186 00187 /* Save the pointer in our list */ 00188 CsrLoadedServerDll[ServerDll->ServerId] = ServerDll; 00189 00190 /* Does it use our generic heap? */ 00191 if (ServerDll->SharedSection != CsrSrvSharedSectionHeap) 00192 { 00193 /* No, save the pointer to its shared section in our list */ 00194 CsrSrvSharedStaticServerData[ServerDll->ServerId] = ServerDll->SharedSection; 00195 } 00196 } 00197 else 00198 { 00199 /* Use shared failure code */ 00200 goto LoadFailed; 00201 } 00202 } 00203 else 00204 { 00205 LoadFailed: 00206 /* Server Init failed, unload it */ 00207 if (hServerDll) LdrUnloadDll(hServerDll); 00208 00209 /* Delete the Object */ 00210 RtlFreeHeap(CsrHeap, 0, ServerDll); 00211 } 00212 00213 /* Return to caller */ 00214 return Status; 00215 } 00216 00217 /*++ 00218 * @name CsrServerDllInitialization 00219 * @implemented NT4 00220 * 00221 * The CsrServerDllInitialization is the initialization routine for 00222 * the this Server DLL. 00223 * 00224 * @param LoadedServerDll 00225 * Pointer to the CSR Server DLL structure representing this Server DLL. 00226 * 00227 * @return STATUS_SUCCESS. 00228 * 00229 * @remarks None. 00230 * 00231 *--*/ 00232 NTSTATUS 00233 NTAPI 00234 CsrServerDllInitialization(IN PCSR_SERVER_DLL LoadedServerDll) 00235 { 00236 /* Setup the DLL Object */ 00237 LoadedServerDll->ApiBase = 0; 00238 LoadedServerDll->HighestApiSupported = 5; 00239 LoadedServerDll->DispatchTable = CsrServerApiDispatchTable; 00240 LoadedServerDll->ValidTable = CsrServerApiServerValidTable; 00241 LoadedServerDll->NameTable = CsrServerApiNameTable; 00242 LoadedServerDll->SizeOfProcessData = 0; 00243 LoadedServerDll->ConnectCallback = NULL; 00244 LoadedServerDll->DisconnectCallback = NULL; 00245 00246 /* All done */ 00247 return STATUS_SUCCESS; 00248 } 00249 00250 /*++ 00251 * @name CsrSrvClientConnect 00252 * 00253 * The CsrSrvClientConnect CSR API handles a new connection to a server DLL. 00254 * 00255 * @param ApiMessage 00256 * Pointer to the CSR API Message for this request. 00257 * 00258 * @param Reply 00259 * Optional reply to this request. 00260 * 00261 * @return STATUS_SUCCESS in case of success, STATUS_INVALID_PARAMETER 00262 * or STATUS_TOO_MANY_NAMES in case of failure. 00263 * 00264 * @remarks None. 00265 * 00266 *--*/ 00267 NTSTATUS 00268 NTAPI 00269 CsrSrvClientConnect(IN OUT PCSR_API_MESSAGE ApiMessage, 00270 IN OUT PULONG Reply OPTIONAL) 00271 { 00272 NTSTATUS Status; 00273 PCSR_CLIENT_CONNECT ClientConnect; 00274 PCSR_SERVER_DLL ServerDll; 00275 PCSR_PROCESS CurrentProcess = ((PCSR_THREAD)NtCurrentTeb()->CsrClientThread)->Process; 00276 00277 /* Load the Message, set default reply */ 00278 ClientConnect = (PCSR_CLIENT_CONNECT)&ApiMessage->CsrClientConnect; 00279 *Reply = 0; 00280 00281 /* Validate the ServerID */ 00282 if (ClientConnect->ServerId >= CSR_SERVER_DLL_MAX) 00283 { 00284 return STATUS_TOO_MANY_NAMES; 00285 } 00286 else if (!CsrLoadedServerDll[ClientConnect->ServerId]) 00287 { 00288 return STATUS_INVALID_PARAMETER; 00289 } 00290 00291 /* Validate the Message Buffer */ 00292 if (!(CsrValidateMessageBuffer(ApiMessage, 00293 ClientConnect->ConnectionInfo, 00294 ClientConnect->ConnectionInfoSize, 00295 1))) 00296 { 00297 /* Fail due to buffer overflow or other invalid buffer */ 00298 return STATUS_INVALID_PARAMETER; 00299 } 00300 00301 /* Load the Server DLL */ 00302 ServerDll = CsrLoadedServerDll[ClientConnect->ServerId]; 00303 00304 /* Check if it has a Connect Callback */ 00305 if (ServerDll->ConnectCallback) 00306 { 00307 /* Call the callback */ 00308 Status = ServerDll->ConnectCallback(CurrentProcess, 00309 ClientConnect->ConnectionInfo, 00310 &ClientConnect->ConnectionInfoSize); 00311 } 00312 else 00313 { 00314 /* Assume success */ 00315 Status = STATUS_SUCCESS; 00316 } 00317 00318 /* Return status */ 00319 return Status; 00320 } 00321 00322 /*++ 00323 * @name CsrSrvCreateSharedSection 00324 * 00325 * The CsrSrvCreateSharedSection creates the Shared Section that all CSR Server 00326 * DLLs and Clients can use to share data. 00327 * 00328 * @param ParameterValue 00329 * Specially formatted string from our registry command-line which 00330 * specifies various arguments for the shared section. 00331 * 00332 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00333 * othwerwise. 00334 * 00335 * @remarks None. 00336 * 00337 *--*/ 00338 NTSTATUS 00339 NTAPI 00340 CsrSrvCreateSharedSection(IN PCHAR ParameterValue) 00341 { 00342 PCHAR SizeValue = ParameterValue; 00343 ULONG Size; 00344 NTSTATUS Status; 00345 LARGE_INTEGER SectionSize; 00346 ULONG ViewSize = 0; 00347 PPEB Peb = NtCurrentPeb(); 00348 00349 /* If there's no parameter, fail */ 00350 if (!ParameterValue) return STATUS_INVALID_PARAMETER; 00351 00352 /* Find the first comma, and null terminate */ 00353 while (*SizeValue) 00354 { 00355 if (*SizeValue == ',') 00356 { 00357 *SizeValue++ = ANSI_NULL; 00358 break; 00359 } 00360 else 00361 { 00362 SizeValue++; 00363 } 00364 } 00365 00366 /* Make sure it's valid */ 00367 if (!*SizeValue) return STATUS_INVALID_PARAMETER; 00368 00369 /* Convert it to an integer */ 00370 Status = RtlCharToInteger(SizeValue, 0, &Size); 00371 if (!NT_SUCCESS(Status)) return Status; 00372 00373 /* Multiply by 1024 entries and round to page size */ 00374 CsrSrvSharedSectionSize = ROUND_UP(Size * 1024, CsrNtSysInfo.PageSize); 00375 00376 /* Create the Secion */ 00377 SectionSize.LowPart = CsrSrvSharedSectionSize; 00378 SectionSize.HighPart = 0; 00379 Status = NtCreateSection(&CsrSrvSharedSection, 00380 SECTION_ALL_ACCESS, 00381 NULL, 00382 &SectionSize, 00383 PAGE_EXECUTE_READWRITE, 00384 SEC_BASED | SEC_RESERVE, 00385 NULL); 00386 if (!NT_SUCCESS(Status)) return Status; 00387 00388 /* Map the section */ 00389 Status = NtMapViewOfSection(CsrSrvSharedSection, 00390 NtCurrentProcess(), 00391 &CsrSrvSharedSectionBase, 00392 0, 00393 0, 00394 NULL, 00395 &ViewSize, 00396 ViewUnmap, 00397 MEM_TOP_DOWN, 00398 PAGE_EXECUTE_READWRITE); 00399 if (!NT_SUCCESS(Status)) 00400 { 00401 /* Fail */ 00402 NtClose(CsrSrvSharedSection); 00403 return Status; 00404 } 00405 00406 /* FIXME: Write the value to registry */ 00407 00408 /* The Heap is the same place as the Base */ 00409 CsrSrvSharedSectionHeap = CsrSrvSharedSectionBase; 00410 00411 /* Create the heap */ 00412 if (!(RtlCreateHeap(HEAP_ZERO_MEMORY | HEAP_CLASS_7, 00413 CsrSrvSharedSectionHeap, 00414 CsrSrvSharedSectionSize, 00415 PAGE_SIZE, 00416 0, 00417 0))) 00418 { 00419 /* Failure, unmap section and return */ 00420 NtUnmapViewOfSection(NtCurrentProcess(), CsrSrvSharedSectionBase); 00421 NtClose(CsrSrvSharedSection); 00422 return STATUS_NO_MEMORY; 00423 } 00424 00425 /* Now allocate space from the heap for the Shared Data */ 00426 CsrSrvSharedStaticServerData = RtlAllocateHeap(CsrSrvSharedSectionHeap, 00427 0, 00428 CSR_SERVER_DLL_MAX * 00429 sizeof(PVOID)); 00430 if (!CsrSrvSharedStaticServerData) return STATUS_NO_MEMORY; 00431 00432 /* Write the values to the PEB */ 00433 Peb->ReadOnlySharedMemoryBase = CsrSrvSharedSectionBase; 00434 Peb->ReadOnlySharedMemoryHeap = CsrSrvSharedSectionHeap; 00435 Peb->ReadOnlyStaticServerData = CsrSrvSharedStaticServerData; 00436 00437 /* Return */ 00438 return STATUS_SUCCESS; 00439 } 00440 00441 /*++ 00442 * @name CsrSrvAttachSharedSection 00443 * 00444 * The CsrSrvAttachSharedSection maps the CSR Shared Section into a new 00445 * CSR Process' address space, and returns the pointers to the section 00446 * through the Connection Info structure. 00447 * 00448 * @param CsrProcess 00449 * Pointer to the CSR Process that is attempting a connection. 00450 * 00451 * @param ConnectInfo 00452 * Pointer to the CSR Connection Info structure for the incoming 00453 * connection. 00454 * 00455 * @return STATUS_SUCCESS in case of success, STATUS_UNSUCCESSFUL 00456 * othwerwise. 00457 * 00458 * @remarks None. 00459 * 00460 *--*/ 00461 NTSTATUS 00462 NTAPI 00463 CsrSrvAttachSharedSection(IN PCSR_PROCESS CsrProcess OPTIONAL, 00464 OUT PCSR_CONNECTION_INFO ConnectInfo) 00465 { 00466 NTSTATUS Status; 00467 ULONG ViewSize = 0; 00468 00469 /* Check if we have a process */ 00470 if (CsrProcess) 00471 { 00472 /* Map the sectio into this process */ 00473 Status = NtMapViewOfSection(CsrSrvSharedSection, 00474 CsrProcess->ProcessHandle, 00475 &CsrSrvSharedSectionBase, 00476 0, 00477 0, 00478 NULL, 00479 &ViewSize, 00480 ViewUnmap, 00481 SEC_NO_CHANGE, 00482 PAGE_EXECUTE_READ); 00483 if (!NT_SUCCESS(Status)) return Status; 00484 } 00485 00486 /* Write the values in the Connection Info structure */ 00487 ConnectInfo->SharedSectionBase = CsrSrvSharedSectionBase; 00488 ConnectInfo->SharedSectionHeap = CsrSrvSharedSectionHeap; 00489 ConnectInfo->SharedSectionData = CsrSrvSharedStaticServerData; 00490 00491 /* Return success */ 00492 return STATUS_SUCCESS; 00493 } 00494 00495 /*++ 00496 * @name CsrSrvIdentifyAlertableThread 00497 * @implemented NT4 00498 * 00499 * The CsrSrvIdentifyAlertableThread CSR API marks a CSR Thread as alertable. 00500 * 00501 * @param ApiMessage 00502 * Pointer to the CSR API Message for this request. 00503 * 00504 * @param Reply 00505 * Pointer to an optional reply to this request. 00506 * 00507 * @return STATUS_SUCCESS. 00508 * 00509 * @remarks None. 00510 * 00511 *--*/ 00512 NTSTATUS 00513 NTAPI 00514 CsrSrvIdentifyAlertableThread(IN OUT PCSR_API_MESSAGE ApiMessage, 00515 IN OUT PULONG Reply) 00516 { 00517 PCSR_THREAD CsrThread = NtCurrentTeb()->CsrClientThread; 00518 00519 /* Set the alertable flag */ 00520 CsrThread->Flags |= CsrThreadAltertable; 00521 00522 /* Return success */ 00523 return STATUS_SUCCESS; 00524 } 00525 00526 /*++ 00527 * @name CsrSrvSetPriorityClass 00528 * @implemented NT4 00529 * 00530 * The CsrSrvSetPriorityClass CSR API is deprecated. 00531 * 00532 * @param ApiMessage 00533 * Pointer to the CSR API Message for this request. 00534 * 00535 * @param Reply 00536 * Pointer to an optional reply to this request. 00537 * 00538 * @return STATUS_SUCCESS. 00539 * 00540 * @remarks None. 00541 * 00542 *--*/ 00543 NTSTATUS 00544 NTAPI 00545 CsrSrvSetPriorityClass(IN OUT PCSR_API_MESSAGE ApiMessage, 00546 IN OUT PULONG Reply) 00547 { 00548 /* Deprecated */ 00549 return STATUS_SUCCESS; 00550 } 00551 00552 /*++ 00553 * @name CsrSrvUnusedFunction 00554 * @implemented NT4 00555 * 00556 * The CsrSrvUnusedFunction CSR API is a stub for deprecated APIs. 00557 * 00558 * The CsrSrvSetPriorityClass CSR API is deprecated. 00559 * 00560 * @param ApiMessage 00561 * Pointer to the CSR API Message for this request. 00562 * 00563 * @param Reply 00564 * Pointer to an optional reply to this request. 00565 * 00566 * @return STATUS_INVALID_PARAMETER. 00567 * 00568 * @remarks CsrSrvSetPriorityClass does not use this stub because it must 00569 * return success. 00570 * 00571 *--*/ 00572 NTSTATUS 00573 NTAPI 00574 CsrSrvUnusedFunction(IN OUT PCSR_API_MESSAGE ApiMessage, 00575 IN OUT PULONG Reply) 00576 { 00577 /* Deprecated */ 00578 return STATUS_INVALID_PARAMETER; 00579 } 00580 00581 /* PUBLIC FUNCTIONS***********************************************************/ 00582 00583 /*++ 00584 * @name CsrSetCallingSpooler 00585 * @implemented NT4 00586 * 00587 * the CsrSetCallingSpooler routine is deprecated. 00588 * 00589 * @param Reserved 00590 * Deprecated 00591 * 00592 * @return None. 00593 * 00594 * @remarks This routine was used in archaic versions of NT for Printer Drivers. 00595 * 00596 *--*/ 00597 VOID 00598 NTAPI 00599 CsrSetCallingSpooler(ULONG Reserved) 00600 { 00601 /* Deprecated */ 00602 return; 00603 } 00604 00605 /*++ 00606 * @name CsrUnhandledExceptionFilter 00607 * @implemented NT5 00608 * 00609 * The CsrUnhandledExceptionFilter routine handles all exceptions 00610 * within SEH-protected blocks. 00611 * 00612 * @param ExceptionPointers 00613 * System-defined Argument. 00614 * 00615 * @return EXCEPTION_EXECUTE_HANDLER. 00616 * 00617 * @remarks None. 00618 * 00619 *--*/ 00620 LONG 00621 NTAPI 00622 CsrUnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo) 00623 { 00624 SYSTEM_KERNEL_DEBUGGER_INFORMATION DebuggerInfo; 00625 EXCEPTION_DISPOSITION Result = EXCEPTION_EXECUTE_HANDLER; 00626 BOOLEAN OldValue; 00627 NTSTATUS Status; 00628 UNICODE_STRING ErrorSource; 00629 ULONG_PTR ErrorParameters[4]; 00630 ULONG Response; 00631 00632 /* Check if a debugger is installed */ 00633 Status = NtQuerySystemInformation(SystemKernelDebuggerInformation, 00634 &DebuggerInfo, 00635 sizeof(DebuggerInfo), 00636 NULL); 00637 00638 /* Check if this is Session 0, and the Debugger is Enabled */ 00639 if ((NtCurrentPeb()->SessionId) && (NT_SUCCESS(Status)) && 00640 (DebuggerInfo.KernelDebuggerEnabled)) 00641 { 00642 /* Call the Unhandled Exception Filter */ 00643 if ((Result = RtlUnhandledExceptionFilter(ExceptionInfo)) != 00644 EXCEPTION_CONTINUE_EXECUTION) 00645 { 00646 /* We're going to raise an error. Get Shutdown Privilege first */ 00647 Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, 00648 TRUE, 00649 TRUE, 00650 &OldValue); 00651 00652 /* Use the Process token if that failed */ 00653 if (Status == STATUS_NO_TOKEN) 00654 { 00655 Status = RtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, 00656 TRUE, 00657 FALSE, 00658 &OldValue); 00659 } 00660 00661 /* Initialize our Name String */ 00662 RtlInitUnicodeString(&ErrorSource, L"Windows SubSystem"); 00663 00664 /* Set the parameters */ 00665 ErrorParameters[0] = (ULONG_PTR)&ErrorSource; 00666 ErrorParameters[1] = ExceptionInfo->ExceptionRecord->ExceptionCode; 00667 ErrorParameters[2] = (ULONG_PTR)ExceptionInfo->ExceptionRecord->ExceptionAddress; 00668 ErrorParameters[3] = (ULONG_PTR)ExceptionInfo->ContextRecord; 00669 00670 /* Bugcheck */ 00671 Status = NtRaiseHardError(STATUS_SYSTEM_PROCESS_TERMINATED, 00672 4, 00673 1, 00674 ErrorParameters, 00675 OptionShutdownSystem, 00676 &Response); 00677 } 00678 00679 /* Just terminate us */ 00680 NtTerminateProcess(NtCurrentProcess(), 00681 ExceptionInfo->ExceptionRecord->ExceptionCode); 00682 } 00683 00684 return Result; 00685 } 00686 00687 /* EOF */ Generated on Sat May 26 2012 04:25:30 for ReactOS by
1.7.6.1
|