From: Aleksey Bragin Date: Wed, 24 Jan 2007 12:14:04 +0000 (+0000) Subject: - Merge 25572 (except the NTLPC related part), this fixes VMWare detection. X-Git-Tag: backups/alex-kd-branch@25995~25^2~30^2~25 X-Git-Url: https://git.reactos.org/?p=reactos.git;a=commitdiff_plain;h=a3ad85c5a5086e4b4f9eed570fe45cfacb739515 - Merge 25572 (except the NTLPC related part), this fixes VMWare detection. - Merge a small part of 25501 ("Fix the KiMask32Array"). svn path=/branches/ros-branch-0_3_1/; revision=25614 --- diff --git a/reactos/base/setup/vmwinst/vmwinst.c b/reactos/base/setup/vmwinst/vmwinst.c index 1438f3ec7ab..bf4e28e5ec5 100644 --- a/reactos/base/setup/vmwinst/vmwinst.c +++ b/reactos/base/setup/vmwinst/vmwinst.c @@ -1010,7 +1010,7 @@ WinMain(HINSTANCE hInstance, { PVOID ExceptionHandler; - //int Version; + int Version; WCHAR *lc; hAppInstance = hInstance; @@ -1024,9 +1024,9 @@ WinMain(HINSTANCE hInstance, return 1; } - //if(!DetectVMware(&Version)) + if(!DetectVMware(&Version)) { - //return 1; + return 1; } /* unregister the handler */ diff --git a/reactos/include/ndk/asm.h b/reactos/include/ndk/asm.h index 20783db79fe..2bba252a399 100644 --- a/reactos/include/ndk/asm.h +++ b/reactos/include/ndk/asm.h @@ -498,6 +498,7 @@ Author: #define STATUS_ACCESS_VIOLATION 0xC0000005 #define STATUS_IN_PAGE_ERROR 0xC0000006 #define STATUS_GUARD_PAGE_VIOLATION 0x80000001 +#define STATUS_PRIVILEGED_INSTRUCTION 0xC0000096 #define STATUS_STACK_OVERFLOW 0xC00000FD #define KI_EXCEPTION_ACCESS_VIOLATION 0x10000004 #define STATUS_INVALID_SYSTEM_SERVICE 0xC000001C diff --git a/reactos/ntoskrnl/KrnlFun.c b/reactos/ntoskrnl/KrnlFun.c index 284e6529087..e7d4a5dfb92 100644 --- a/reactos/ntoskrnl/KrnlFun.c +++ b/reactos/ntoskrnl/KrnlFun.c @@ -24,7 +24,6 @@ // // Ke1: // - Implement KiInitMachineDependent. -// - Implement Privileged Instruction Handler in Umode GPF. // // Fstub: // - Implement IoAssignDriveLetters using mount manager support. diff --git a/reactos/ntoskrnl/dbgk/dbgkutil.c b/reactos/ntoskrnl/dbgk/dbgkutil.c index 10a4a2a4201..38d38d3a9be 100644 --- a/reactos/ntoskrnl/dbgk/dbgkutil.c +++ b/reactos/ntoskrnl/dbgk/dbgkutil.c @@ -238,15 +238,13 @@ DbgkCreateThread(PVOID StartAddress) if (Teb) { /* Copy the system library name and link to it */ -#if 0 wcsncpy(Teb->StaticUnicodeBuffer, L"ntdll.dll", sizeof(Teb->StaticUnicodeBuffer) / sizeof(WCHAR)); -#endif Teb->Tib.ArbitraryUserPointer = Teb->StaticUnicodeBuffer; /* Return it in the debug event as well */ - LoadDll->NamePointer = Teb->Tib.ArbitraryUserPointer; + LoadDll->NamePointer = &Teb->Tib.ArbitraryUserPointer; } /* Get a handle */ diff --git a/reactos/ntoskrnl/dbgk/debug.c b/reactos/ntoskrnl/dbgk/debug.c index 6bdc0689db5..bf991926686 100644 --- a/reactos/ntoskrnl/dbgk/debug.c +++ b/reactos/ntoskrnl/dbgk/debug.c @@ -221,13 +221,9 @@ DbgkpSendApiMessageLpc(IN OUT PDBGKM_MSG Message, PsGetCurrentProcess()->CreateReported = TRUE; /* Send the LPC command */ -#if 0 Status = LpcRequestWaitReplyPort(Port, (PPORT_MESSAGE)Message, (PPORT_MESSAGE)&Buffer[0]); -#else - Status = STATUS_UNSUCCESSFUL; -#endif /* Flush the instruction cache */ ZwFlushInstructionCache(NtCurrentProcess(), NULL, 0); @@ -486,6 +482,15 @@ DbgkpPostFakeModuleMessages(IN PEPROCESS Process, i = 0; while ((NextEntry != ListHead) && (i < 500)) { + /* Skip the first entry */ + if (!i) + { + /* Go to the next module */ + NextEntry = NextEntry->Flink; + i++; + continue; + } + /* Get the entry */ LdrEntry = CONTAINING_RECORD(NextEntry, LDR_DATA_TABLE_ENTRY, @@ -724,7 +729,7 @@ DbgkpPostFakeThreadMessages(IN PEPROCESS Process, /* Get the next thread */ ThisThread = PsGetNextProcessThread(Process, ThisThread); OldThread = pLastThread; - } while(ThisThread); + } while (ThisThread); /* Check the API status */ if (!NT_SUCCESS(Status)) @@ -1075,7 +1080,7 @@ DbgkpCloseObject(IN PEPROCESS OwnerProcess OPTIONAL, OwnerProcess, DebugObject); /* If this isn't the last handle, do nothing */ - if (HandleCount > 1) return; + if (SystemHandleCount > 1) return; /* Otherwise, lock the debug object */ ExAcquireFastMutex(&DebugObject->Mutex); @@ -1293,8 +1298,12 @@ ThreadScan: /* Check if we couldn't acquire rundown for it */ if (DebugEvent->Flags & 0x10) { - /* Set busy flag */ - InterlockedOr((PLONG)&DebugEvent->Flags, 0x100); + /* Set the skip termination flag */ + PspSetCrossThreadFlag(EventThread, CT_SKIP_CREATION_MSG_BIT); + + /* Insert it into the temp list */ + RemoveEntryList(&DebugEvent->EventList); + InsertTailList(&TempList, &DebugEvent->EventList); } else { @@ -1312,15 +1321,15 @@ ThreadScan: /* Clear the backout thread */ DebugEvent->BackoutThread = NULL; - /* Set flag */ - InterlockedOr((PLONG)&DebugEvent->Flags, 0x80); + /* Set skip flag */ + PspSetCrossThreadFlag(EventThread, CT_SKIP_CREATION_MSG_BIT); } } else { - /* FIXME: TODO */ - DPRINT1("Unhandled dbgk path!\n"); - KEBUGCHECK(0); + /* Insert it into the temp list */ + RemoveEntryList(&DebugEvent->EventList); + InsertTailList(&TempList, &DebugEvent->EventList); } /* Check if the lock is held */ @@ -1346,11 +1355,14 @@ ThreadScan: if (LastThread) ObDereferenceObject(LastThread); /* Loop our temporary list */ - NextEntry = TempList.Flink; - while (NextEntry != &TempList) + while (!IsListEmpty(&TempList)) { - /* FIXME: TODO */ - KEBUGCHECK(0); + /* Remove the event */ + NextEntry = RemoveHeadList(&TempList); + DebugEvent = CONTAINING_RECORD (NextEntry, DEBUG_EVENT, EventList); + + /* Wake it */ + DbgkpWakeTarget(DebugEvent); } /* Check if we got here through success and mark the PEB, then return */ @@ -1520,9 +1532,8 @@ NtDebugContinue(IN HANDLE DebugHandle, /* Make sure that the status is valid */ if ((ContinueStatus != DBG_CONTINUE) && + (ContinueStatus != DBG_EXCEPTION_HANDLED) && (ContinueStatus != DBG_EXCEPTION_NOT_HANDLED) && - (ContinueStatus != DBG_REPLY_LATER) && - (ContinueStatus != DBG_UNABLE_TO_PROVIDE_HANDLE) && (ContinueStatus != DBG_TERMINATE_THREAD) && (ContinueStatus != DBG_TERMINATE_PROCESS)) { @@ -1820,41 +1831,48 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, DBGUI_WAIT_STATE_CHANGE WaitStateChange; NTSTATUS Status = STATUS_SUCCESS; PDEBUG_EVENT DebugEvent, DebugEvent2; - PLIST_ENTRY ListHead, NextEntry; + PLIST_ENTRY ListHead, NextEntry, NextEntry2; PAGED_CODE(); DBGKTRACE(DBGK_OBJECT_DEBUG, "Handle: %p\n", DebugHandle); /* Clear the initial wait state change structure */ RtlZeroMemory(&WaitStateChange, sizeof(WaitStateChange)); - /* Check if the call was from user mode */ - if (PreviousMode != KernelMode) + /* Protect probe in SEH */ + _SEH_TRY { - /* Protect probe in SEH */ - _SEH_TRY + /* Check if we came with a timeout */ + if (Timeout) { - /* Check if we came with a timeout */ - if (Timeout) + /* Check if the call was from user mode */ + if (PreviousMode != KernelMode) { - /* Make a copy on the stack */ - SafeTimeOut = ProbeForReadLargeInteger(Timeout); - Timeout = &SafeTimeOut; + /* Probe it */ + ProbeForReadLargeInteger(Timeout); } - /* Probe the state change structure */ - ProbeForWrite(StateChange, sizeof(*StateChange), sizeof(ULONG)); + /* Make a local copy */ + SafeTimeOut = *Timeout; + Timeout = &SafeTimeOut; + + /* Query the current time */ + KeQuerySystemTime(&StartTime); } - _SEH_HANDLE + + /* Check if the call was from user mode */ + if (PreviousMode != KernelMode) { - /* Get the exception code */ - Status = _SEH_GetExceptionCode(); + /* Probe the state change structure */ + ProbeForWrite(StateChange, sizeof(*StateChange), sizeof(ULONG)); } - _SEH_END; - if (!NT_SUCCESS(Status)) return Status; - - /* Query the current time */ - KeQuerySystemTime(&StartTime); } + _SEH_HANDLE + { + /* Get the exception code */ + Status = _SEH_GetExceptionCode(); + } + _SEH_END; + if (!NT_SUCCESS(Status)) return Status; /* Get the debug object */ Status = ObReferenceObjectByHandle(DebugHandle, @@ -1870,13 +1888,13 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, Thread = NULL; /* Wait on the debug object given to us */ - Status = KeWaitForSingleObject(DebugObject, - Executive, - PreviousMode, - Alertable, - Timeout); while (TRUE) { + Status = KeWaitForSingleObject(DebugObject, + Executive, + PreviousMode, + Alertable, + Timeout); if (!NT_SUCCESS(Status) || (Status == STATUS_TIMEOUT) || (Status == STATUS_ALERTED) || @@ -1917,10 +1935,11 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, GotEvent = TRUE; /* Loop the list internally */ - while (&DebugEvent->EventList != NextEntry) + NextEntry2 = DebugObject->EventList.Flink; + while (NextEntry2 != NextEntry) { /* Get the debug event */ - DebugEvent2 = CONTAINING_RECORD(NextEntry, + DebugEvent2 = CONTAINING_RECORD(NextEntry2, DEBUG_EVENT, EventList); @@ -1936,7 +1955,7 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, } /* Move to the next entry */ - NextEntry = NextEntry->Flink; + NextEntry2 = NextEntry2->Flink; } /* Check if we still have a valid event */ @@ -1962,14 +1981,15 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, /* Set flag */ DebugEvent->Flags |= 1; - Status = STATUS_SUCCESS; } else { /* Unsignal the event */ - DebugObject->EventsPresent.Header.SignalState = 0; - Status = STATUS_SUCCESS; + KeClearEvent(&DebugObject->EventsPresent); } + + /* Set success */ + Status = STATUS_SUCCESS; } /* Release the mutex */ @@ -1980,13 +2000,22 @@ NtWaitForDebugEvent(IN HANDLE DebugHandle, if (!GotEvent) { /* Check if we can wait again */ - if (!SafeTimeOut.QuadPart) + if (SafeTimeOut.QuadPart < 0) { /* Query the new time */ KeQuerySystemTime(&NewTime); /* Substract times */ - /* FIXME: TODO */ + SafeTimeOut.QuadPart += (NewTime.QuadPart - StartTime.QuadPart); + StartTime = NewTime; + + /* Check if we've timed out */ + if (SafeTimeOut.QuadPart > 0) + { + /* We have, break out of the loop */ + Status = STATUS_TIMEOUT; + break; + } } } else diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index 074919b5c67..c3457bbadf6 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -90,6 +90,33 @@ _UnexpectedMsg: _UnhandledMsg: .asciz "\n\x7\x7!!! Unhandled or Unexpected Code at line: %lx!!!\n" +_KiTrapPrefixTable: + .byte 0xF2 /* REP */ + .byte 0xF3 /* REP INS/OUTS */ + .byte 0x67 /* ADDR */ + .byte 0xF0 /* LOCK */ + .byte 0x66 /* OP */ + .byte 0x2E /* SEG */ + .byte 0x3E /* DS */ + .byte 0x26 /* ES */ + .byte 0x64 /* FS */ + .byte 0x65 /* GS */ + .byte 0x36 /* SS */ + +_KiTrapIoTable: + .byte 0xE4 /* IN */ + .byte 0xE5 /* IN */ + .byte 0xEC /* IN */ + .byte 0xED /* IN */ + .byte 0x6C /* INS */ + .byte 0x6D /* INS */ + .byte 0xE6 /* OUT */ + .byte 0xE7 /* OUT */ + .byte 0xEE /* OUT */ + .byte 0xEF /* OUT */ + .byte 0x6E /* OUTS */ + .byte 0x6F /* OUTS */ + /* SOFTWARE INTERRUPT SERVICES ***********************************************/ .text @@ -1423,6 +1450,29 @@ _KiTrap12: jmp _KiSystemFatalException .endfunc +.func KiTrapExceptHandler +_KiTrapExceptHandler: + + /* Setup SEH handler frame */ + mov esp, [esp+8] + pop fs:[KPCR_EXCEPTION_LIST] + add esp, 4 + pop ebp + + /* Check if the fault came from user mode */ + test dword ptr [ebp+KTRAP_FRAME_CS], MODE_MASK + jnz SetException + + /* Kernel fault, bugcheck */ + push ebp + push 0 + push 0 + push 0 + push 0 + push KMODE_EXCEPTION_NOT_HANDLED + call _KeBugCheckWithTf@24 +.endfunc + .func KiTrap13 Dr_kitd: DR_TRAP_FIXUP V86_kitd: V86_TRAP_FIXUP @@ -1627,6 +1677,7 @@ SegPopGpf: lea eax, [ebp+KTRAP_FRAME_ESP] cmp edx, eax jz HandleSegPop + int 3 /* Handle segment POP fault by setting it to 0 */ HandleSegPop: @@ -1665,7 +1716,7 @@ HandleSegPop2: /* Update EIP (will be updated below again) */ add dword ptr [ebp+KTRAP_FRAME_EIP], 1 -HandleBop4: +HandleEsPop: /* Clear the segment, update EIP and ESP */ mov dword ptr [edx], 0 add dword ptr [ebp+KTRAP_FRAME_EIP], 1 @@ -1677,15 +1728,23 @@ CheckVdmGpf: cmp dword ptr [ebx+EPROCESS_VDM_OBJECTS], 0 jz CheckPrivilegedInstruction + /* Bring interrupts back */ + sti + /* Check what kind of instruction this is */ mov eax, [ebp+KTRAP_FRAME_EIP] mov eax, [eax] /* FIXME: Check for BOP4 */ - /* Check if this is POP FS */ + /* Check if this is POP ES */ mov edx, ebp - add edx, KTRAP_FRAME_FS + add edx, KTRAP_FRAME_ES + cmp al, 0x07 + jz HandleEsPop + + /* Check if this is POP FS */ + add edx, KTRAP_FRAME_FS - KTRAP_FRAME_ES cmp ax, 0xA10F jz HandleSegPop2 @@ -1695,16 +1754,102 @@ CheckVdmGpf: jz HandleSegPop2 CheckPrivilegedInstruction: + /* Bring interrupts back */ + sti + + /* Setup a SEH handler */ + push ebp + push offset _KiTrapExceptHandler + push fs:[KPCR_EXCEPTION_LIST] + mov fs:[KPCR_EXCEPTION_LIST], esp + + /* Get EIP */ + mov esi, [ebp+KTRAP_FRAME_EIP] + + /* Setup loop count */ + mov ecx, 15 + +InstLoop: + /* Save loop count */ + push ecx + + /* Get the instruction */ + lods byte ptr [esi] + + /* Now lookup in the prefix table */ + mov ecx, 11 + mov edi, offset _KiTrapPrefixTable + repnz scasb + + /* Restore loop count */ + pop ecx + + /* If it's not a prefix byte, check other instructions */ + jnz NotPrefixByte + /* FIXME */ UNHANDLED_PATH -CheckPrivilegedInstruction2: +NotPrefixByte: + /* FIXME: Check if it's a HLT */ + + /* Check if the instruction has two bytes */ + cmp al, 0xF + jne CheckRing3Io + /* FIXME */ UNHANDLED_PATH +CheckRing3Io: + /* Get EFLAGS and IOPL */ + mov ebx, [ebp+KTRAP_FRAME_EFLAGS] + and ebx, 0x3000 + shr ebx, 12 + + /* Check the CS's RPL mask */ + mov ecx, [ebp+KTRAP_FRAME_CS] + and ecx, RPL_MASK + cmp ebx, ecx + jge NotIoViolation + +CheckPrivilegedInstruction2: + /* Check if this is a CLI or STI */ + cmp al, 0xFA + je IsPrivInstruction + cmp al, 0xFB + je IsPrivInstruction + + /* Setup I/O table lookup */ + mov ecx, 13 + mov edi, offset _KiTrapIoTable + + /* Loopup in the table */ + repnz scasb + jnz NotIoViolation + + /* FIXME: Check IOPM!!! */ + +IsPrivInstruction: + /* Cleanup the SEH frame */ + pop fs:[KPCR_EXCEPTION_LIST] + add esp, 8 + + /* Setup the exception */ + mov ebx, [ebp+KTRAP_FRAME_EIP] + mov eax, STATUS_PRIVILEGED_INSTRUCTION + jmp _DispatchNoParam + +NotIoViolation: + /* Cleanup the SEH frame */ + pop fs:[KPCR_EXCEPTION_LIST] + add esp, 8 + SetException: - /* FIXME */ - UNHANDLED_PATH + /* Setup the exception */ + mov ebx, [ebp+KTRAP_FRAME_EIP] + mov esi, -1 + mov eax, STATUS_ACCESS_VIOLATION + jmp _DispatchTwoParam DispatchV86Gpf: /* FIXME */ diff --git a/reactos/ntoskrnl/ke/thrdobj.c b/reactos/ntoskrnl/ke/thrdobj.c index ef60e8c6b36..dc76ea8bbce 100644 --- a/reactos/ntoskrnl/ke/thrdobj.c +++ b/reactos/ntoskrnl/ke/thrdobj.c @@ -18,7 +18,7 @@ extern LIST_ENTRY PspReaperListHead; ULONG KiMask32Array[MAXIMUM_PRIORITY] = { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, - 0x40, 0x80, 0x100, 0x200, 0x4000, 0x800, + 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000, 0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000, 0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,