Author: ion
Date: Mon Jan 22 01:43:32 2007
New Revision: 25572
URL:
http://svn.reactos.org/svn/reactos?rev=25572&view=rev
Log:
- Fix IN/OUT privileged instruction fault (we don't yet handle HLT/CLI/STI other
prefixes but the framework is there).
- Enable back proper VMWARE detection.
- Fix namepointer setup in DbgkCreateThread.
- Skip the first entry when doing fake module load messages.
- Fix which handle count is read in DbgkCloseObject.
- Set the right flags for the debug event thread instead of random flags inside the debug
event itself when parsing in DbgkpSetProcessDebugPort.
- Add debug event in the temporary list to be woken, if rundown couldn't be acquired.
- Properly validate continue statues allowed in NtDebugContinue.
- Properly support timeout in NtWaitForDebugEvent.
- Properly do backout in NtWaitForDebugEvent.
- Disable LPC debug messages accidentally enabled, and add a small hack to better find the
cause of the LPC shutdown bug.
Modified:
trunk/reactos/base/setup/vmwinst/vmwinst.c
trunk/reactos/include/ndk/asm.h
trunk/reactos/ntoskrnl/KrnlFun.c
trunk/reactos/ntoskrnl/dbgk/dbgkutil.c
trunk/reactos/ntoskrnl/dbgk/debug.c
trunk/reactos/ntoskrnl/ke/i386/trap.s
trunk/reactos/ntoskrnl/lpc/close.c
trunk/reactos/ntoskrnl/lpc/port.c
Modified: trunk/reactos/base/setup/vmwinst/vmwinst.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/base/setup/vmwinst/vmwinst…
==============================================================================
--- trunk/reactos/base/setup/vmwinst/vmwinst.c (original)
+++ trunk/reactos/base/setup/vmwinst/vmwinst.c Mon Jan 22 01:43:32 2007
@@ -1010,7 +1010,7 @@
{
PVOID ExceptionHandler;
- //int Version;
+ int Version;
WCHAR *lc;
hAppInstance = hInstance;
@@ -1024,9 +1024,9 @@
return 1;
}
- //if(!DetectVMware(&Version))
- {
- //return 1;
+ if(!DetectVMware(&Version))
+ {
+ return 1;
}
/* unregister the handler */
Modified: trunk/reactos/include/ndk/asm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/asm.h?rev=2557…
==============================================================================
--- trunk/reactos/include/ndk/asm.h (original)
+++ trunk/reactos/include/ndk/asm.h Mon Jan 22 01:43:32 2007
@@ -499,6 +499,7 @@
#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
Modified: trunk/reactos/ntoskrnl/KrnlFun.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/KrnlFun.c?rev=255…
==============================================================================
--- trunk/reactos/ntoskrnl/KrnlFun.c (original)
+++ trunk/reactos/ntoskrnl/KrnlFun.c Mon Jan 22 01:43:32 2007
@@ -7,9 +7,6 @@
// Do NOT complain about it.
// Do NOT ask when it will be fixed.
// Failure to respect this will *ACHIEVE NOTHING*.
-//
-// Ke1:
-// - Implement Privileged Instruction Handler in Umode GPF.
//
// Ex:
// - Use pushlocks for handle implementation.
Modified: trunk/reactos/ntoskrnl/dbgk/dbgkutil.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/dbgkutil.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/dbgk/dbgkutil.c (original)
+++ trunk/reactos/ntoskrnl/dbgk/dbgkutil.c Mon Jan 22 01:43:32 2007
@@ -238,15 +238,13 @@
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 */
Modified: trunk/reactos/ntoskrnl/dbgk/debug.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/dbgk/debug.c?rev=…
==============================================================================
--- trunk/reactos/ntoskrnl/dbgk/debug.c (original)
+++ trunk/reactos/ntoskrnl/dbgk/debug.c Mon Jan 22 01:43:32 2007
@@ -221,13 +221,9 @@
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 @@
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 @@
/* 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 @@
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 @@
/* 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 @@
/* 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 @@
if (LastThread) ObDereferenceObject(LastThread);
/* Loop our temporary list */
- NextEntry = TempList.Flink;
- while (NextEntry != &TempList)
- {
- /* FIXME: TODO */
- KEBUGCHECK(0);
+ while (!IsListEmpty(&TempList))
+ {
+ /* 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 @@
/* 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 @@
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
- {
- /* Check if we came with a timeout */
- if (Timeout)
- {
- /* Make a copy on the stack */
- SafeTimeOut = ProbeForReadLargeInteger(Timeout);
- Timeout = &SafeTimeOut;
- }
-
+ /* Protect probe in SEH */
+ _SEH_TRY
+ {
+ /* Check if we came with a timeout */
+ if (Timeout)
+ {
+ /* Check if the call was from user mode */
+ if (PreviousMode != KernelMode)
+ {
+ /* Probe it */
+ ProbeForReadLargeInteger(Timeout);
+ }
+
+ /* Make a local copy */
+ SafeTimeOut = *Timeout;
+ Timeout = &SafeTimeOut;
+
+ /* Query the current time */
+ KeQuerySystemTime(&StartTime);
+ }
+
+ /* Check if the call was from user mode */
+ if (PreviousMode != KernelMode)
+ {
/* Probe the state change structure */
ProbeForWrite(StateChange, sizeof(*StateChange), sizeof(ULONG));
}
- _SEH_HANDLE
- {
- /* Get the exception code */
- Status = _SEH_GetExceptionCode();
- }
- _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 @@
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 @@
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 @@
}
/* Move to the next entry */
- NextEntry = NextEntry->Flink;
+ NextEntry2 = NextEntry2->Flink;
}
/* Check if we still have a valid event */
@@ -1962,14 +1981,15 @@
/* 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 @@
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
Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/trap.s?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/trap.s (original)
+++ trunk/reactos/ntoskrnl/ke/i386/trap.s Mon Jan 22 01:43:32 2007
@@ -93,6 +93,33 @@
_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
@@ -1426,6 +1453,29 @@
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
@@ -1630,6 +1680,7 @@
lea eax, [ebp+KTRAP_FRAME_ESP]
cmp edx, eax
jz HandleSegPop
+ int 3
/* Handle segment POP fault by setting it to 0 */
HandleSegPop:
@@ -1668,7 +1719,7 @@
/* 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
@@ -1680,15 +1731,23 @@
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 ES */
+ mov edx, ebp
+ add edx, KTRAP_FRAME_ES
+ cmp al, 0x07
+ jz HandleEsPop
+
/* Check if this is POP FS */
- mov edx, ebp
- add edx, KTRAP_FRAME_FS
+ add edx, KTRAP_FRAME_FS - KTRAP_FRAME_ES
cmp ax, 0xA10F
jz HandleSegPop2
@@ -1698,16 +1757,102 @@
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 */
Modified: trunk/reactos/ntoskrnl/lpc/close.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/close.c?rev=2…
==============================================================================
--- trunk/reactos/ntoskrnl/lpc/close.c (original)
+++ trunk/reactos/ntoskrnl/lpc/close.c Mon Jan 22 01:43:32 2007
@@ -57,7 +57,7 @@
PETHREAD Thread = NULL;
BOOLEAN LockHeld = Flags & 1, ReleaseLock = Flags & 2;
PAGED_CODE();
- LPCTRACE(LPC_CLOSE_DEBUG, "Message: %p. Flags: %lx\n", Message, Flags);
+ DPRINT1("Message: %p. Flags: %lx\n", Message, Flags);
/* Acquire the lock if not already */
if (!LockHeld) KeAcquireGuardedMutex(&LpcpLock);
@@ -342,6 +342,9 @@
/* Send it */
for (;;)
{
+ /* FIXME: HACK OF D00m */
+ break;
+
/* Send the message */
if (LpcRequestPort(Port,
&ClientDiedMsg.h) != STATUS_NO_MEMORY) break;
Modified: trunk/reactos/ntoskrnl/lpc/port.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/lpc/port.c?rev=25…
==============================================================================
--- trunk/reactos/ntoskrnl/lpc/port.c (original)
+++ trunk/reactos/ntoskrnl/lpc/port.c Mon Jan 22 01:43:32 2007
@@ -18,7 +18,7 @@
ULONG LpcpMaxMessageSize;
PAGED_LOOKASIDE_LIST LpcpMessagesLookaside;
KGUARDED_MUTEX LpcpLock;
-ULONG LpcpTraceLevel = LPC_CLOSE_DEBUG;
+ULONG LpcpTraceLevel = 0;
ULONG LpcpNextMessageId = 1, LpcpNextCallbackId = 1;
static GENERIC_MAPPING LpcpPortMapping =