| 1429 | } |
| 1430 | |
| 1431 | NTSTATUS NtDebugContinue( |
| 1432 | _In_ HANDLE DebugObjectHandle, |
| 1433 | _In_ PCLIENT_ID AppClientId, |
| 1434 | _In_ NTSTATUS ContinueStatus |
| 1435 | ) { |
| 1436 | NTSTATUS status; |
| 1437 | PDEBUG_OBJECT DebugObject; |
| 1438 | PDEBUG_EVENT DebugEvent, FoundDebugEvent; |
| 1439 | KPROCESSOR_MODE PreviousMode; |
| 1440 | PLIST_ENTRY Entry; |
| 1441 | CLIENT_ID ClientId; |
| 1442 | BOOLEAN GetEvent; |
| 1443 | |
| 1444 | PreviousMode = ExGetPreviousMode(); |
| 1445 | |
| 1446 | __try { |
| 1447 | if (PreviousMode != KernelMode) { |
| 1448 | ClientId = *AppClientId; |
| 1449 | } |
| 1450 | } |
| 1451 | __except (EXCEPTION_EXECUTE_HANDLER) { |
| 1452 | return GetExceptionCode(); |
| 1453 | } |
| 1454 | |
| 1455 | switch (ContinueStatus) |
| 1456 | { |
| 1457 | case DBG_EXCEPTION_HANDLED: |
| 1458 | case DBG_CONTINUE: |
| 1459 | case DBG_TERMINATE_PROCESS: |
| 1460 | case DBG_TERMINATE_THREAD: |
| 1461 | case DBG_EXCEPTION_NOT_HANDLED: |
| 1462 | break; |
| 1463 | default: |
| 1464 | return STATUS_INVALID_PARAMETER; |
| 1465 | } |
| 1466 | |
| 1467 | status = ObReferenceObjectByHandle(DebugObjectHandle, |
| 1468 | DEBUG_OBJECT_WAIT_STATE_CHANGE, |
| 1469 | *DbgkDebugObjectType, |
| 1470 | PreviousMode, |
| 1471 | (PVOID*)&DebugObject, |
| 1472 | nullptr); |
| 1473 | |
| 1474 | if (!NT_SUCCESS(status)) { |
| 1475 | return status; |
| 1476 | } |
| 1477 | |
| 1478 | GetEvent = FALSE; |
| 1479 | FoundDebugEvent = nullptr; |
| 1480 | |
| 1481 | ExAcquireFastMutex(&DebugObject->Mutex); |
| 1482 | for (Entry = DebugObject->EventList.Flink; |
| 1483 | Entry != &DebugObject->EventList; |
| 1484 | Entry = Entry->Flink) { |
| 1485 | DebugEvent = CONTAINING_RECORD(Entry, DEBUG_EVENT, EventList); |
| 1486 | |
| 1487 | if (DebugEvent->ClientId.UniqueProcess == AppClientId->UniqueProcess) { |
| 1488 | if (!GetEvent) { |
nothing calls this directly
no test coverage detected