{
WaitForSingleObject(ProcessInformation.hProcess,INFINITE);
}
+ CloseHandle(ProcessInformation.hProcess);
return(ret);
}
//#define NDEBUG
#include <internal/debug.h>
+#define IDMAP_BASE (0xd0000000)
+
+/*
+ * Return a linear address which can be used to access the physical memory
+ * starting at x
+ */
+extern inline unsigned int physical_to_linear(unsigned int x)
+{
+ return(x+IDMAP_BASE);
+}
+
+extern inline unsigned int linear_to_physical(unsigned int x)
+{
+ return(x-IDMAP_BASE);
+}
#define VIDMEM_BASE 0xb8000
#ifdef COMPILER_LARGE_INTEGERS
#define GET_LARGE_INTEGER_HIGH_PART(LI) ( ( (LI) >> 32) )
-#define GET_LARGE_INTEGER_LOW_PART(LI) ( ((LI) & 0xFFFFFFFF) )
+#define GET_LARGE_INTEGER_LOW_PART(LI) (ULONG)( ((LI) & 0xFFFFFFFF) )
#define SET_LARGE_INTEGER_HIGH_PART(LI, HP) \
( (LI) = ((LI) & 0xFFFFFFFFL) | ( ((LARGE_INTEGER)(HP)) << 32 ) )
#define SET_LARGE_INTEGER_LOW_PART(LI, LP) \
#include <internal/hal.h>
#ifndef TLS_MINIMUM_AVAILABLE
- #define TLS_MINIMUM_AVAILABLE (64)
+#define TLS_MINIMUM_AVAILABLE (64)
#endif
#ifndef MAX_PATH
- #define MAX_PATH (260)
+#define MAX_PATH (260)
#endif
typedef NTSTATUS (*PKSTART_ROUTINE)(PVOID StartContext);
HANDLE UniqueProcess;
HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;
-
+
typedef struct _NT_TIB {
struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
PVOID StackBase;
typedef struct _NT_TEB
{
-
NT_TIB Tib;
CLIENT_ID Cid;
HANDLE RPCHandle;
NTSTATUS LastStatusValue;
DWORD LockCount;
UCHAR HardErrorMode;
-
} NT_TEB;
typedef struct _KTHREAD
--- /dev/null
+VOID ExUnmapPage(PVOID Addr);
+PVOID ExAllocatePage(VOID);
PVOID MmAllocPage(VOID);
VOID MmFreePage(PVOID PhysicalAddress, ULONG Nr);
VOID MmDeletePageTable(PEPROCESS Process, PVOID Address);
+NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest);
+NTSTATUS MmReleaseMmInfo(PEPROCESS Process);
#endif
PVOID* ReturnedObject,
PWSTR* RemainingPath);
+ULONG ObGetReferenceCount(PVOID Object);
#endif /* __INCLUDE_INTERNAL_OBJMGR_H */
void HalTaskSwitch(PKTHREAD thread);
NTSTATUS HalInitTaskWithContext(PETHREAD Thread, PCONTEXT Context);
NTSTATUS HalReleaseTask(PETHREAD Thread);
+VOID PiDeleteProcess(PVOID ObjectBody);
#endif
bFsIoControlCode = TRUE;
else
bFsIoControlCode = FALSE;
-// CHECKPOINT
- if(lpOverlapped != NULL) {
+ if(lpOverlapped != NULL) {
hEvent = lpOverlapped->hEvent;
lpOverlapped->Internal = STATUS_PENDING;
IoStatusBlock = (PIO_STATUS_BLOCK)lpOverlapped;
IoStatusBlock = &IIosb;
}
-// CHECKPOINT
if(bFsIoControlCode == TRUE) {
errCode = NtFsControlFile(hDevice,hEvent,NULL,NULL,IoStatusBlock,dwIoControlCode,lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize );
} else {
errCode = NtDeviceIoControlFile(hDevice,hEvent,NULL,NULL,IoStatusBlock,dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize);
}
-// CHECKPOINT
- if(errCode == STATUS_PENDING ) {
+
+ if(errCode == STATUS_PENDING ) {
if(NtWaitForSingleObject(hDevice,FALSE,NULL) < 0) {
*lpBytesReturned = IoStatusBlock->Information;
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
-// CHECKPOINT
- if (lpOverlapped)
+ if (lpOverlapped)
*lpBytesReturned = lpOverlapped->InternalHigh;
else
*lpBytesReturned = IoStatusBlock->Information;
-// CHECKPOINT
return TRUE;
}
;GetCommProperties@8
;GetCommState@8
;GetCommTimeouts@8
-;GetCommandLineA@0
-;GetCommandLineW@0
+GetCommandLineA@0
+GetCommandLineW@0
;GetCompressedFileSizeA@8
;GetCompressedFileSizeW@8
;GetComputerNameA@8
;GetDriveTypeA@4
;GetDriveTypeW@4
;GetEnvironmentStrings@0
-;GetEnvironmentStringsA@0
-;GetEnvironmentStringsW@0
+GetEnvironmentStringsA@0
+GetEnvironmentStringsW@0
;GetEnvironmentVariableA@12
;GetEnvironmentVariableW@12
;GetExitCodeProcess@8
;GetPrivateProfileStructW@20
;GetProcAddress@8
;GetProcessAffinityMask@12
-;GetProcessHeap@0
+GetProcessHeap@0
;GetProcessHeaps@8
;GetProcessShutdownParameters@8
;GetProcessTimes@20
;GetUserDefaultLCID@0
;GetUserDefaultLangID@0
;GetVDMCurrentDirectories@8
-;GetVersion@0
+GetVersion@0
;GetVersionExA@4
;GetVersionExW@4
;GetVolumeInformationA@32
;GlobalUnfix@4
;GlobalUnlock@4
;GlobalWire@4
-;HeapAlloc@12
-;HeapCompact@8
-;HeapCreate@12
+HeapAlloc@12
+HeapCompact@8
+HeapCreate@12
;HeapCreateTagsW@16
-;HeapDestroy@4
+HeapDestroy@4
;HeapExtend@16
-;HeapFree@12
+HeapFree@12
;HeapLock@4
;HeapQueryTagW@20
-;HeapReAlloc@16
-;HeapSize@12
+HeapReAlloc@16
+HeapSize@12
;HeapSummary@12
-;HeapUnlock@4
+HeapUnlock@4
;HeapUsage@20
-;HeapValidate@12
+HeapValidate@12
;HeapWalk@8
;InitAtomTable@4
;InitializeCriticalSection@4
__asm__("movl %%cr2,%0\n\t"
: "=d" (cr2));
DbgPrint("cr2 %x\n",cr2);
- for(;;);
DbgPrint("Process: %x\n",PsGetCurrentProcess());
- DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread);
+ if (PsGetCurrentThread() != NULL)
+ {
+ DbgPrint("Thread: %x\n",PsGetCurrentThread()->Cid.UniqueThread);
+ }
DbgPrint("DS %x ES %x FS %x GS %x\n",ds&0xffff,es&0xffff,fs&0xffff,
gs&0xfff);
DbgPrint("EAX: %.8x EBX: %.8x ECX: %.8x\n",eax,ebx,ecx);
#include <string.h>
#include <internal/string.h>
#include <internal/bitops.h>
+#include <internal/ex.h>
#include <ddk/ntddk.h>
#define NDEBUG
(((ULONG)v / (1024 * 1024))&(~0x3)))
#define ADDR_TO_PTE(v) (PULONG)(PAGETABLE_MAP + ((ULONG)v / 1024))
+NTSTATUS MmReleaseMmInfo(PEPROCESS Process)
+{
+ ULONG i,j,addr;
+
+ DbgPrint("MmReleaseMmInfo(Process %x)\n",Process);
+
+ KeAttachProcess(Process);
+ for (i=0; i<1024; i++)
+ {
+ if (ADDR_TO_PDE(i*4*1024*1024) != 0)
+ {
+ for (j=0; j<1024; j++)
+ {
+ addr = i*4*1024*1024 + j*4*1024;
+ if (ADDR_TO_PTE(addr) != 0)
+ {
+ MmFreePage((PVOID)PAGE_MASK(*ADDR_TO_PTE(addr)), 1);
+ }
+ }
+ }
+ }
+ KeDetachProcess();
+ MmFreePage(Process->Pcb.PageTableDirectory, 1);
+ Process->Pcb.PageTableDirectory = NULL;
+
+ DbgPrint("Finished MmReleaseMmInfo()\n");
+ return(STATUS_SUCCESS);
+}
+
+NTSTATUS MmCopyMmInfo(PEPROCESS Src, PEPROCESS Dest)
+{
+ PULONG PhysPageDirectory;
+ PULONG PageDirectory;
+ PULONG CurrentPageDirectory;
+ PKPROCESS KProcess = &Dest->Pcb;
+ ULONG i;
+
+ DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
+
+ PageDirectory = ExAllocatePage();
+ if (PageDirectory == NULL)
+ {
+ return(STATUS_UNSUCCESSFUL);
+ }
+ PhysPageDirectory = (PULONG)
+ GET_LARGE_INTEGER_LOW_PART(MmGetPhysicalAddress(PageDirectory));
+ KProcess->PageTableDirectory = PhysPageDirectory;
+ CurrentPageDirectory = (PULONG)PAGEDIRECTORY_MAP;
+
+ memset(PageDirectory,0,PAGESIZE);
+ for (i=768; i<896; i++)
+ {
+ PageDirectory[i] = CurrentPageDirectory[i];
+ }
+ DPRINT("Addr %x\n",0xf0000000 / (4*1024*1024));
+ PageDirectory[0xf0000000 / (4*1024*1024)] = (ULONG)PhysPageDirectory | 0x7;
+
+ ExUnmapPage(PageDirectory);
+
+ DPRINT("Finished MmCopyMmInfo()\n");
+ return(STATUS_SUCCESS);
+}
+
VOID MmDeletePageTable(PEPROCESS Process, PVOID Address)
{
if (Process != NULL && Process != PsGetCurrentProcess())
return(Entry);
}
+VOID MmDeletePageEntry(PEPROCESS Process, PVOID Address)
+{
+ PULONG page_tlb;
+ PULONG page_dir;
+
+ if (Process != NULL && Process != PsGetCurrentProcess())
+ {
+ KeAttachProcess(Process);
+ }
+ page_dir = ADDR_TO_PDE(Address);
+ if ((*page_dir) == 0)
+ {
+ if (Process != NULL && Process != PsGetCurrentProcess())
+ {
+ KeDetachProcess();
+ }
+ return;
+ }
+ page_tlb = ADDR_TO_PTE(Address);
+ *page_tlb = 0;
+ if (Process != NULL && Process != PsGetCurrentProcess())
+ {
+ KeDetachProcess();
+ }
+}
+
+
PULONG MmGetPageEntry(PVOID PAddress)
/*
* FUNCTION: Get a pointer to the page table entry for a virtual address
return((MmGetPageEntryForProcess(Process, Address)) & PA_PRESENT);
}
+
VOID MmSetPage(PEPROCESS Process,
PVOID Address,
ULONG flProtect,
&(gdt[thread->Context.nr/8].a),
gdt[thread->Context.nr/8].a,
gdt[thread->Context.nr/8].b);
+ DPRINT("thread->Context.cr3 %x\n",thread->Context.cr3);
__asm__("pushfl\n\t"
"cli\n\t"
"ljmp %0\n\t"
#include <internal/ke.h>
#include <internal/mm.h>
+//#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/
CurrentThread->ThreadsProcess = Process;
PageDir = (ULONG)CurrentThread->ThreadsProcess->Pcb.PageTableDirectory;
CurrentThread->Tcb.Context.cr3 = PageDir;
+ DPRINT("Switching process context to %x\n",PageDir)
__asm__("movl %0,%%cr3\n\t"
: /* no inputs */
: "r" (PageDir));
/* FUNCTIONS ***************************************************************/
+VOID ExUnmapPage(PVOID Addr)
+{
+ KIRQL oldIrql;
+ ULONG i = ((ULONG)Addr - kernel_pool_base) / PAGESIZE;
+
+ DbgPrint("ExUnmapPage(Addr %x)\n",Addr);
+ DbgPrint("i %x\n",i);
+
+ KeAcquireSpinLock(&AllocMapLock, &oldIrql);
+ MmSetPage(NULL, (PVOID)Addr, 0, 0);
+ clear_bit(i%32, &alloc_map[i/32]);
+ KeReleaseSpinLock(&AllocMapLock, oldIrql);
+}
+
PVOID ExAllocatePage(VOID)
{
KIRQL oldlvl;
ULONG addr;
ULONG i;
-
+ ULONG PhysPage;
+
+ PhysPage = (ULONG)MmAllocPage();
+ DbgPrint("Allocated page %x\n",PhysPage);
+ if (PhysPage == 0)
+ {
+ return(NULL);
+ }
+
KeAcquireSpinLock(&AllocMapLock, &oldlvl);
for (i=1; i<ALLOC_MAP_SIZE;i++)
{
if (!test_bit(i%32,&alloc_map[i/32]))
{
+ DbgPrint("i %x\n",i);
+ set_bit(i%32,&alloc_map[i/32]);
addr = kernel_pool_base + (i*PAGESIZE);
- MmSetPage(NULL,
- (PVOID)addr,
- PAGE_READWRITE,
- (ULONG)MmAllocPage());
+ MmSetPage(NULL, (PVOID)addr, PAGE_READWRITE, PhysPage);
KeReleaseSpinLock(&AllocMapLock, oldlvl);
return((PVOID)addr);
}
if (!NT_SUCCESS(Status))
{
DPRINT("ZwMapViewOfSection() = %x\n",Status);
+ ObDereferenceObject(Process);
return(Status);
}
Result->Data.SectionData.Section = Section;
}
DPRINT("*BaseAddress %x\n",*BaseAddress);
-
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
stat = 0;
break;
}
+ DPRINT("Completed page fault handling\n");
if (stat)
{
KeLowerIrql(oldlvl);
MemoryArea->Type = Type;
MemoryArea->Attributes =Protect;
DPRINT("*BaseAddress %x\n",*BaseAddress);
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
Type,
Protect);
DPRINT("*BaseAddress %x\n",*BaseAddress);
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
}
if (Status != STATUS_SUCCESS)
{
DPRINT("ZwAllocateVirtualMemory() = %x\n",Status);
+ ObDereferenceObject(Process);
return(Status);
}
DPRINT("*BaseAddress %x\n",*BaseAddress);
-
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
case MEM_RELEASE:
if (MemoryArea->BaseAddress != (*BaseAddress))
{
+ ObDereferenceObject(Process);
return(STATUS_UNSUCCESSFUL);
}
MmFreeMemoryArea(PsGetCurrentProcess(),
BaseAddress,
0,
TRUE);
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
case MEM_DECOMMIT:
*RegionSize,
MEMORY_AREA_RESERVE,
MemoryArea->Attributes);
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
-
+ ObDereferenceObject(Process);
return(STATUS_NOT_IMPLEMENTED);
}
}
MmChangeAreaProtection(Process,BaseAddress,NumberOfBytesToProtect,
NewAccessProtection);
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
KeDetachProcess();
+ ObDereferenceObject(Process);
+
*NumberOfBytesWritten = NumberOfBytesToWrite;
return(STATUS_SUCCESS);
}
if (Handle == NtCurrentProcess())
{
+ BODY_TO_HEADER(PsGetCurrentProcess())->RefCount++;
*Object = PsGetCurrentProcess();
return(STATUS_SUCCESS);
}
if (Handle == NtCurrentThread())
{
+ BODY_TO_HEADER(PsGetCurrentThread())->RefCount++;
*Object = PsGetCurrentThread();
return(STATUS_SUCCESS);
}
if (Header->RefCount < 0 || Header->HandleCount < 0)
{
+ DbgPrint("Object %x/%x has invalid reference or handle count\n",
+ Header,HEADER_TO_BODY(Header));
KeBugCheck(0);
}
return(STATUS_SUCCESS);
}
+ULONG ObGetReferenceCount(PVOID ObjectBody)
+{
+ POBJECT_HEADER Header = BODY_TO_HEADER(ObjectBody);
+
+ return(Header->RefCount);
+}
+
VOID ObDereferenceObject(PVOID ObjectBody)
/*
* FUNCTION: Decrements a given object's reference count and performs
#include <ddk/ntddk.h>
#include <internal/ps.h>
#include <internal/ke.h>
+#include <internal/mm.h>
+#include <internal/ob.h>
-#define NDEBUG
+//#define NDEBUG
#include <internal/debug.h>
/* GLBOALS *******************************************************************/
/* FUNCTIONS *****************************************************************/
+VOID PiDeleteProcess(PVOID ObjectBody)
+{
+ DPRINT("PiDeleteProcess(ObjectBody %x)\n",ObjectBody);
+ (VOID)MmReleaseMmInfo((PEPROCESS)ObjectBody);
+}
+
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)
/*
* FUNCTION: Terminates the current thread
DPRINT("terminating %x\n",CurrentThread);
ObDereferenceObject(CurrentThread->ThreadsProcess);
+ CurrentThread->ThreadsProcess = NULL;
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
CurrentThread->Tcb.ThreadState = THREAD_STATE_TERMINATED;
ZwYieldExecution();
NTSTATUS Status;
PEPROCESS Process;
KIRQL oldlvl;
-
+
+ DPRINT("ZwTerminateProcess(ProcessHandle %x, ExitStatus %x)\n",
+ ProcessHandle, ExitStatus);
+
Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_TERMINATE,
PsProcessType,
{
return(Status);
}
-
+
+ DPRINT("Process %x ReferenceCount %d\n",Process,
+ ObGetReferenceCount(Process));
+
PiTerminateProcessThreads(Process, ExitStatus);
KeRaiseIrql(DISPATCH_LEVEL, &oldlvl);
- KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
Process->Pcb.ProcessState = PROCESS_STATE_TERMINATED;
+ KeDispatcherObjectWake(&Process->Pcb.DispatcherHeader);
if (PsGetCurrentThread()->ThreadsProcess == Process)
{
KeLowerIrql(oldlvl);
+ ObDereferenceObject(Process);
PsTerminateCurrentThread(ExitStatus);
}
KeLowerIrql(oldlvl);
+ ObDereferenceObject(Process);
return(STATUS_SUCCESS);
}
#include <internal/ob.h>
#include <internal/mm.h>
#include <internal/ke.h>
+#include <internal/ps.h>
#include <string.h>
#include <internal/string.h>
/* FUNCTIONS *****************************************************************/
-#define IDMAP_BASE (0xd0000000)
-
-/*
- * Return a linear address which can be used to access the physical memory
- * starting at x
- */
-extern inline unsigned int physical_to_linear(unsigned int x)
-{
- return(x+IDMAP_BASE);
-}
-
-extern inline unsigned int linear_to_physical(unsigned int x)
-{
- return(x-IDMAP_BASE);
-}
-
-PEPROCESS PsGetSystemProcess(VOID)
-{
- return(SystemProcess);
-}
-
VOID PsInitProcessManagment(VOID)
{
ANSI_STRING AnsiString;
PsProcessType->Dump = NULL;
PsProcessType->Open = NULL;
PsProcessType->Close = NULL;
- PsProcessType->Delete = NULL;
+ PsProcessType->Delete = PiDeleteProcess;
PsProcessType->Parse = NULL;
PsProcessType->Security = NULL;
PsProcessType->QueryName = NULL;
/*
* Initialize the system process
*/
- SystemProcess = ObCreateObject(NULL,PROCESS_ALL_ACCESS,NULL,
- PsProcessType);
+ SystemProcess = ObCreateObject(NULL,
+ PROCESS_ALL_ACCESS,
+ NULL,
+ PsProcessType);
KProcess = &SystemProcess->Pcb;
InitializeListHead(&(KProcess->MemoryAreaList));
{
PEPROCESS Process;
PEPROCESS ParentProcess;
- PULONG PageDirectory;
- PULONG CurrentPageDirectory;
- ULONG i;
PKPROCESS KProcess;
NTSTATUS Status;
- PULONG PhysicalPageDirectory;
DPRINT("ZwCreateProcess(ObjectAttributes %x)\n",ObjectAttributes);
ObCreateHandleTable(ParentProcess,
InheritObjectTable,
Process);
-
- PhysicalPageDirectory = (PULONG)MmAllocPage();
- PageDirectory = (PULONG)physical_to_linear((ULONG)PhysicalPageDirectory);
- KProcess->PageTableDirectory = PhysicalPageDirectory;
-
- CurrentPageDirectory = (PULONG)physical_to_linear(
- (ULONG)get_page_directory());
-
- memset(PageDirectory,0,PAGESIZE);
- for (i=768; i<896; i++)
- {
- PageDirectory[i] = CurrentPageDirectory[i];
- }
- PageDirectory[0xf0000000 / (4*1024*1024)]
- = (ULONG)PhysicalPageDirectory | 0x7;
-
+ MmCopyMmInfo(ParentProcess, Process);
+
/*
* FIXME: I don't what I'm supposed to know with a section handle
*/
}
Process->Pcb.ProcessState = PROCESS_STATE_ACTIVE;
-
+ ObDereferenceObject(Process);
+ ObDereferenceObject(ParentProcess);
return(STATUS_SUCCESS);
}
}
else
{
- Thread->ThreadsProcess=SystemProcess;
+ Thread->ThreadsProcess = SystemProcess;
ObReferenceObjectByPointer(Thread->ThreadsProcess,
PROCESS_CREATE_THREAD,
PsProcessType,
}
}
-void PsInitThreadManagment(void)
+VOID PiDeleteThread(PVOID ObjectBody)
+{
+ DbgPrint("PiDeleteThread(ObjectBody %x)\n",ObjectBody);
+}
+
+VOID PsInitThreadManagment(VOID)
/*
* FUNCTION: Initialize thread managment
*/
PsThreadType->Dump = NULL;
PsThreadType->Open = NULL;
PsThreadType->Close = NULL;
- PsThreadType->Delete = NULL;
+ PsThreadType->Delete = PiDeleteThread;
PsThreadType->Parse = NULL;
PsThreadType->Security = NULL;
PsThreadType->QueryName = NULL;
default:
Status = STATUS_UNSUCCESSFUL;
}
+ ObDereferenceObject(Thread);
return(Status);
}