Partially implemented PEB

Some bug fixes
Hacked crtdll to compile with a minimal set of functions

svn path=/trunk/; revision=371
This commit is contained in:
David Welch 1999-04-10 12:08:24 +00:00
parent 9221d5c854
commit fd78805ffc
34 changed files with 1512 additions and 1106 deletions

View file

@ -26,10 +26,13 @@ void main(int argc, char* argv[])
AllocConsole();
InputHandle = GetStdHandle(STD_INPUT_HANDLE);
OutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
debug_printf("GetCommandLineA() %s\n",GetCommandLineA());
#if 0
for (i=0; i<argc; i++)
{
debug_printf("Args: '%s'\n",argv[i]);
}
#endif
}

View file

@ -1,8 +1,7 @@
#
#
#
OBJECTS= ../common/crt0.o args.o
LIBS= ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a
OBJECTS= args.o
all: args.exe
@ -16,7 +15,7 @@ clean:
.phony: clean
args.exe: $(OBJECTS) $(LIBS)
$(CC) -specs=../../specs $(OBJECTS) $(LIBS) -lgcc -o args.exe
$(CC) $(OBJECTS) -o args.exe
$(NM) --numeric-sort args.exe > args.sym
include ../../rules.mak

View file

@ -14,6 +14,20 @@
#define IDMAP_BASE (0xd0000000)
#define VIDMEM_BASE 0xb8000
/*
* 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 NR_ROWS 50
#define NR_COLUMNS 80

View file

@ -22,9 +22,9 @@
* DISCLAMED. This includes but is not limited to warranties of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Revision: 1.4 $
* $Author: ariadne $
* $Date: 1999/04/03 10:41:29 $
* $Revision: 1.5 $
* $Author: dwelch $
* $Date: 1999/04/10 12:08:06 $
*
*/
/* Appropriated for Reactos Crtdll by Ariadne */
@ -94,8 +94,8 @@ typedef struct {
* The three standard file pointers provided by the run time library.
* NOTE: These will go to the bit-bucket silently in GUI applications!
*/
extern FILE (*__imp__iob)[]; /* A pointer to an array of FILE */
#define _iob (*__imp__iob) /* An array of FILE */
extern FILE (*_iob)[]; /* A pointer to an array of FILE */
//#define _iob (*__imp__iob) /* An array of FILE */
#define stdin (&_iob[0])
#define stdout (&_iob[1])
#define stderr (&_iob[2])

View file

@ -16,7 +16,6 @@
#define __DDK_ZW_H
#include <windows.h>
//#ifndef WIN32_LEAN_AND_MEAN
#define PTOKEN_GROUPS PVOID
#define PTOKEN_PRIVILEGES PVOID
@ -29,14 +28,14 @@
/*
* FUNCTION: Checks a clients access rights to a object
* ARGUMENTS:
SecurityDescriptor = Security information against which the access is checked
* SecurityDescriptor = Security information against which the access is checked
* ClientToken = Represents a client
DesiredAcces =
GenericMapping =
PrivilegeSet =
ReturnLength = Bytes written
GrantedAccess =
AccessStatus = Indicates if the ClientToken allows the requested access
* DesiredAcces =
* GenericMapping =
* PrivilegeSet =
* ReturnLength = Bytes written
* GrantedAccess =
* AccessStatus = Indicates if the ClientToken allows the requested access
* REMARKS: The arguments map to the win32 AccessCheck
* RETURNS: Status
*/
@ -5070,15 +5069,25 @@ NTSTATUS STDCALL NtAcceptConnectPort(VOID);
NTSTATUS STDCALL NtCompleteConnectPort(VOID);
NTSTATUS STDCALL NtConnectPort(VOID);
//NTSTATUS STDCALL NtConnectPort(VOID);
NTSTATUS STDCALL NtConnectPort(PHANDLE Handle,
POBJECT_ATTRIBUTES ObjectAttributes);
//NTSTATUS STDCALL NtCreatePort(VOID);
NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS STDCALL NtCreatePort(VOID);
NTSTATUS STDCALL NtCreateToken(VOID);
NTSTATUS STDCALL NtGetPlugPlayEvent(VOID);
NTSTATUS STDCALL NtImpersonateClientOfPort(VOID);
NTSTATUS STDCALL NtListenPort(VOID);
//NTSTATUS STDCALL NtListenPort(VOID);
NTSTATUS STDCALL NtListenPort(HANDLE PortHandle,
PLARGE_INTEGER Timeout,
PPORT_MSG_DATA Msg);
NTSTATUS STDCALL NtLoadKey2(VOID);
@ -5095,12 +5104,17 @@ NTSTATUS STDCALL NtReadRequestData(VOID);
NTSTATUS STDCALL NtReplyPort(VOID);
NTSTATUS STDCALL NtReplyWaitReceivePort(VOID);
NTSTATUS STDCALL NtReplyWaitReplyPort(VOID);
NTSTATUS STDCALL NtRequestPort(VOID);
//NTSTATUS STDCALL NtRequestPort(VOID);
NTSTATUS STDCALL NtRequestPort(HANDLE PortHandle,
ULONG DataLength,
PVOID Data,
ULONG Options,
PHANDLE ReplyPortHandle);
NTSTATUS STDCALL NtSetDefaultLocale(VOID);
//NTSTATUS STDCALL NtSetLdtEntries(VOID);
NTSTATUS STDCALL NtSetLdtEntries(PEPROCESS Process,
NTSTATUS STDCALL NtSetLdtEntries(PETHREAD Thread,
ULONG FirstEntry,
PULONG Entries);

View file

@ -1,6 +1,13 @@
#ifndef __INCLUDE_DDK_ZWTYPES_H
#define __INCLUDE_DDK_ZWTYPES_H
/* Added by David Welch at 09/04/99 */
typedef struct _PORT_MSG_DATA
{
ULONG DataLength;
PVOID Data;
HANDLE ReplyPort;
} PORT_MSG_DATA, *PPORT_MSG_DATA;
#define NtCurrentProcess() ( (HANDLE) 0xFFFFFFFF )

View file

@ -1 +1,2 @@
VOID NtInitializeEventImplementation(VOID);
NTSTATUS NiInitPort(VOID);

View file

@ -0,0 +1,12 @@
/* TEB/PEB parameters */
#ifndef __INCLUDE_INTERNAL_TEB
#define __INCLUDE_INTERNAL_TEB
#include <internal/ps.h>
#define PEB_BASE (0xb0001000)
#define PEB_STARTUPINFO (0xb0003000)
#define NtCurrentPeb() ((PNT_PEB)PEB_BASE)
#endif /* __INCLUDE_INTERNAL_TEB */

View file

@ -13,8 +13,6 @@
#include <ddk/ntddk.h>
NT_PEB *GetCurrentPeb(VOID);
typedef
DWORD
(*WaitForInputIdleType)(

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,3 @@
HOST=mingw32-windows
ifneq ($(HOST),mingw32-windows)
ifneq ($(HOST),mingw32-linux)
DLLTARGET=crtdll.a
@ -27,7 +26,8 @@ DIRECT_OBJECTS = direct/chdir.o direct/chdrive.o direct/getcwd.o direct/getdrive
MALLOC_OBJECTS = malloc/expand.o malloc/heap.o
MISC_OBJECTS = misc/GetArgs.o misc/setnew.o misc/purecall.o
#MISC_OBJECTS = misc/GetArgs.o misc/setnew.o misc/purecall.o
MISC_OBJECTS = misc/GetArgs.o
STRING_OBJECTS = string/memchr.o string/memcmp.o string/strcat.o \
string/strchr.o string/strcmp.o string/strcoll.o \
@ -100,14 +100,20 @@ MATH_OBJECTS = math/acos.o math/acosh.o math/asin.o math/asinh.o math/atan.o mat
math/tanh.o math/stubs.o math/j0_y0.o math/j1_y1.o math/jn_yn.o
OBJECTS = $(ASSERT_OBJECTS) $(CTYPE_OBJECTS) $(CONIO_OBJECTS) $(DIRECT_OBJECTS)\
$(MISC_OBJECTS) $(STRING_OBJECTS) $(STDIO_OBJECTS) $(STDLIB_OBJECTS) \
$(IO_OBJECTS) $(PROCESS_OBJECTS) $(TIME_OBJECTS) $(MALLOC_OBJECTS)\
$(SYS_STAT_OBJECTS) $(SIGNAL_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS)\
$(SEARCH_OBJECTS)
#OBJECTS = $(ASSERT_OBJECTS) $(CTYPE_OBJECTS) $(CONIO_OBJECTS) $(DIRECT_OBJECTS)\
# $(MISC_OBJECTS) $(STRING_OBJECTS) $(STDIO_OBJECTS) $(STDLIB_OBJECTS) \
# $(IO_OBJECTS) $(PROCESS_OBJECTS) $(TIME_OBJECTS) $(MALLOC_OBJECTS)\
# $(SYS_STAT_OBJECTS) $(SIGNAL_OBJECTS) $(MATH_OBJECTS) $(FLOAT_OBJECTS)\
# $(SEARCH_OBJECTS)
crtdll.a: $(OBJECTS)
OBJECTS = $(MISC_OBJECTS) string/strdup.o stdlib/malloc.o stdlib/abort.o \
stdlib/_exit.o stdlib/atexit.o stdio/fileno.o io/fmode.o \
float/fpreset.o stdio/stdhnd.o io/setmode.o io/open.o \
stdio/vsprintf.o
crtdll.a: $(OBJECTS)
$(LD) -r $(OBJECTS) -o crtdll.a
crtdll.dll: $(DLLMAIN) $(OBJECTS) crtdll.def
@ -115,12 +121,14 @@ crtdll.dll: $(DLLMAIN) $(OBJECTS) crtdll.def
$(DLLTOOL) --dllname crtdll.dll --def crtdll.def \
--output-lib crtdll.a
$(CC) -specs=crt_specs -mdll -o junk.tmp \
-Wl,--base-file,base.tmp crtdll.o ../ntdll/ntdll.a
-Wl,--base-file,base.tmp crtdll.o ../kernel32/kernel32.a \
../ntdll/ntdll.a
- $(RM) junk.tmp
$(DLLTOOL) --dllname crtdll.dll --base-file base.tmp \
--output-exp temp.exp --def crtdll.def
- $(RM) base.tmp
$(CC) -specs=crt_specs -mdll -o crtdll.dll crtdll.o ../ntdll/ntdll.a\
$(CC) -specs=crt_specs -mdll -o crtdll.dll crtdll.o \
../kernel32/kernel32.a ../ntdll/ntdll.a\
-Wl,--image-base,0x20000000 \
-Wl,--file-alignment,0x1000 \
-Wl,--section-alignment,0x1000 \
@ -128,5 +136,7 @@ crtdll.dll: $(DLLMAIN) $(OBJECTS) crtdll.def
- $(RM) temp.exp
$(NM) --numeric-sort crtdll.dll > crtdll.sym
include ../../Rules.mak
clean:
include ../../rules.mak

View file

@ -39,4 +39,4 @@ FILE _crtdll_iob[] =
}
};
FILE (*__imp__iob)[] = &_crtdll_iob;
FILE (*_iob)[] = &_crtdll_iob;

View file

@ -4,6 +4,13 @@
#include <limits.h>
#include <crtdll/internal/file.h>
#if 1
int
vsprintf(char *str, const char *fmt, va_list ap)
{
abort();
}
#else
int
vsprintf(char *str, const char *fmt, va_list ap)
{
@ -17,3 +24,4 @@ vsprintf(char *str, const char *fmt, va_list ap)
*f._ptr = 0;
return len;
}
#endif

View file

@ -6,6 +6,7 @@
struct __atexit *__atexit_ptr = 0;
#if 0
void exit(int status)
{
//int i;
@ -27,7 +28,7 @@ void exit(int status)
_exit(status);
for(;;);
}
#endif
void _exit(int _status)

View file

@ -4,9 +4,8 @@
static char msg[] = "Abort!\r\n";
void
abort()
void abort()
{
_write(stderr->_file, msg, sizeof(msg)-1);
_exit(1);
// _write(stderr->_file, msg, sizeof(msg)-1);
// _exit(1);
}

View file

@ -17,7 +17,7 @@
#include <wchar.h>
#include <string.h>
//#define NDEBUG
#define NDEBUG
#include <kernel32/kernel32.h>
/* EXTERNS ******************************************************************/

View file

@ -12,7 +12,7 @@
#include <windows.h>
//#define NDEBUG
#define NDEBUG
#include <kernel32/kernel32.h>
/* GLOBALS *******************************************************************/

View file

@ -4,7 +4,6 @@
#include <kernel32/kernel32.h>
VOID WINAPI __HeapInit(LPVOID base, ULONG minsize, ULONG maxsize);
VOID KERNEL32_Init()
{

View file

@ -17,7 +17,7 @@
//#include <stdlib.h>
#if 0
@ -526,4 +526,4 @@ int unicode2ansi( char *ansi,const WCHAR *uni, int s)
#endif

View file

@ -12,6 +12,9 @@
#include <ddk/ntddk.h>
#include <wchar.h>
#include <kernel32/proc.h>
#include <internal/teb.h>
#include <kernel32/kernel32.h>
WINBOOL STDCALL DllMain (HANDLE hInst,
ULONG ul_reason_for_call,
@ -19,57 +22,48 @@ WINBOOL STDCALL DllMain (HANDLE hInst,
NT_TEB *Teb;
BOOL WINAPI DllMainCRTStartup(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
return(TRUE);
return(DllMain(hDll,dwReason,lpReserved));
}
WINBOOL STDCALL DllMain (HANDLE hInst,
ULONG ul_reason_for_call,
LPVOID lpReserved)
VOID WINAPI __HeapInit(LPVOID base, ULONG minsize, ULONG maxsize);
WINBOOL STDCALL DllMain(HANDLE hInst,
ULONG ul_reason_for_call,
LPVOID lpReserved)
{
switch( ul_reason_for_call ) {
case DLL_PROCESS_ATTACH:
{
GetCurrentPeb()->ProcessHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS,
8192,
0);
InitAtomTable(13);
SetCurrentDirectoryW(L"C:");
// SetSystemDirectoryW(L"C:\\Reactos\\System");
// SetWindowsDirectoryW(L"C:\\Reactos");
}
DPRINT("DllMain");
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
DPRINT("DLL_PROCESS_ATTACH\n");
}
case DLL_THREAD_ATTACH:
{
Teb = HeapAlloc(GetProcessHeap(),0,sizeof(NT_TEB));
Teb->Peb = GetCurrentPeb();
Teb->HardErrorMode = SEM_NOGPFAULTERRORBOX;
Teb->dwTlsIndex=0;
break;
}
case DLL_PROCESS_DETACH:
{
HeapFree(GetProcessHeap(),0,Teb);
HeapDestroy(GetCurrentPeb()->ProcessHeap);
break;
}
case DLL_THREAD_DETACH:
{
HeapFree(GetProcessHeap(),0,Teb);
break;
}
default:
{
// Teb = HeapAlloc(GetProcessHeap(),0,sizeof(NT_TEB));
// Teb->Peb = GetCurrentPeb();
// Teb->HardErrorMode = SEM_NOGPFAULTERRORBOX;
// Teb->dwTlsIndex=0;
break;
}
case DLL_PROCESS_DETACH:
{
// HeapFree(GetProcessHeap(),0,Teb);
HeapDestroy(NtCurrentPeb()->ProcessHeap);
break;
}
case DLL_THREAD_DETACH:
{
// HeapFree(GetProcessHeap(),0,Teb);
break;
}
default:
break;
}
return TRUE;
return TRUE;
}

View file

@ -16,30 +16,30 @@
#include <kernel32/thread.h>
#include <wchar.h>
#include <string.h>
#include <internal/teb.h>
/* GLOBALS ******************************************************************/
static unsigned char CommandLineA[MAX_PATH];
static CHAR CommandLineA[MAX_PATH];
/* FUNCTIONS ****************************************************************/
LPSTR STDCALL GetCommandLineA(VOID)
{
WCHAR *CommandLineW;
ULONG i = 0;
CommandLineW = GetCommandLineW();
while ((CommandLineW[i])!=0 && i < MAX_PATH)
{
CommandLineA[i] = (unsigned char)CommandLineW[i];
i++;
}
CommandLineA[i] = 0;
return CommandLineA;
ULONG i;
PWSTR CommandLineW;
CommandLineW = GetCommandLineW();
for (i=0; i<MAX_PATH && CommandLineW[i]!=0; i++)
{
CommandLineA[i] = (CHAR)CommandLineW[i];
}
CommandLineW[i] = 0;
return(CommandLineA);
}
LPWSTR STDCALL GetCommandLineW(VOID)
{
return GetCurrentPeb()->StartupInfo->CommandLine;
return(NtCurrentPeb()->StartupInfo->CommandLine);
}

View file

@ -19,8 +19,9 @@
#include <pe.h>
#include <internal/i386/segment.h>
#include <ntdll/ldr.h>
#include <internal/teb.h>
//#define NDEBUG
#define NDEBUG
#include <kernel32/kernel32.h>
/* FUNCTIONS ****************************************************************/
@ -349,6 +350,68 @@ HANDLE KERNEL32_MapFile(LPCWSTR lpApplicationName,
#define NTDLL_BASE (0x80000000)
static NTSTATUS CreatePeb(HANDLE ProcessHandle, PWSTR CommandLine)
{
NTSTATUS Status;
PVOID PebBase;
ULONG PebSize;
NT_PEB Peb;
ULONG BytesWritten;
PVOID StartupInfoBase;
ULONG StartupInfoSize;
PROCESSINFOW StartupInfo;
PebBase = PEB_BASE;
PebSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&PebBase,
0,
&PebSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
return(Status);
}
memset(&Peb, 0, sizeof(Peb));
Peb.StartupInfo = PEB_STARTUPINFO;
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)PEB_BASE,
&Peb,
sizeof(Peb),
&BytesWritten);
StartupInfoBase = PEB_STARTUPINFO;
StartupInfoSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&StartupInfoBase,
0,
&StartupInfoSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
return(Status);
}
memset(&StartupInfo, 0, sizeof(StartupInfo));
wcscpy(StartupInfo.CommandLine, CommandLine);
DPRINT("StartupInfoSize %x\n",StartupInfoSize);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)PEB_STARTUPINFO,
&StartupInfo,
StartupInfoSize,
&BytesWritten);
return(STATUS_SUCCESS);
}
WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
@ -417,7 +480,13 @@ WINBOOL STDCALL CreateProcessW(LPCWSTR lpApplicationName,
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
/*
*
*/
DPRINT("Creating peb\n");
CreatePeb(hProcess, TempCommandLine);
DPRINT("Creating thread for process\n");
lpStartAddress = (LPTHREAD_START_ROUTINE)
((PIMAGE_OPTIONAL_HEADER)OPTHDROFFSET(NTDLL_BASE))->

View file

@ -17,15 +17,13 @@
#include <wchar.h>
#include <string.h>
#include <internal/i386/segment.h>
#include <internal/teb.h>
#define NDEBUG
#include <kernel32/kernel32.h>
/* GLOBALS *****************************************************************/
static NT_PEB CurrentPeb;
static PROCESSINFOW ProcessInfo;
WaitForInputIdleType lpfnGlobalRegisterWaitForInputIdle;
VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
@ -34,19 +32,6 @@ VOID RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle
WINBOOL STDCALL GetProcessId(HANDLE hProcess, LPDWORD lpProcessId);
VOID InitializePeb(PWSTR CommandLine)
{
DPRINT("InitializePeb(CommandLine %x)\n",CommandLine);
// DPRINT("ProcessInfo.CommandLine %x\n",ProcessInfo.CommandLine);
// wcscpy(ProcessInfo.CommandLine, CommandLine);
CurrentPeb.StartupInfo = &ProcessInfo;
}
NT_PEB *GetCurrentPeb(VOID)
{
return(&CurrentPeb);
}
HANDLE STDCALL GetCurrentProcess(VOID)
{
return (HANDLE)NtCurrentProcess();
@ -249,19 +234,16 @@ SleepEx(
VOID
STDCALL
GetStartupInfoW(
LPSTARTUPINFO lpStartupInfo
)
VOID STDCALL GetStartupInfoW(LPSTARTUPINFO lpStartupInfo)
{
NT_PEB *pPeb = GetCurrentPeb();
if (lpStartupInfo == NULL ) {
SetLastError(ERROR_INVALID_PARAMETER);
return;
}
NT_PEB *pPeb = NtCurrentPeb();
if (lpStartupInfo == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return;
}
lpStartupInfo->cb = sizeof(STARTUPINFO);
lstrcpyW(lpStartupInfo->lpDesktop, pPeb->StartupInfo->Desktop);
lstrcpyW(lpStartupInfo->lpTitle, pPeb->StartupInfo->Title);
@ -291,75 +273,67 @@ GetStartupInfoW(
}
VOID
STDCALL
GetStartupInfoA(
LPSTARTUPINFO lpStartupInfo
)
VOID STDCALL GetStartupInfoA(LPSTARTUPINFO lpStartupInfo)
{
NT_PEB *pPeb = GetCurrentPeb();
ULONG i = 0;
if (lpStartupInfo == NULL ) {
SetLastError(ERROR_INVALID_PARAMETER);
return;
}
lpStartupInfo->cb = sizeof(STARTUPINFO);
i = 0;
while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
{
lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
i++;
}
lpStartupInfo->lpDesktop[i] = 0;
i = 0;
while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
{
lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
i++;
}
lpStartupInfo->lpTitle[i] = 0;
lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize;
lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars;
lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars;
lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute;
lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags;
lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow;
//lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved;
//lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1;
//lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2;
lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput;
lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput;
lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError;
NT_PEB *pPeb = NtCurrentPeb();
ULONG i = 0;
if (lpStartupInfo == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return;
}
lpStartupInfo->cb = sizeof(STARTUPINFO);
i = 0;
while ((pPeb->StartupInfo->Desktop[i])!=0 && i < MAX_PATH)
{
lpStartupInfo->lpDesktop[i] = (unsigned char)pPeb->StartupInfo->Desktop[i];
i++;
}
lpStartupInfo->lpDesktop[i] = 0;
i = 0;
while ((pPeb->StartupInfo->Title[i])!=0 && i < MAX_PATH)
{
lpStartupInfo->lpTitle[i] = (unsigned char)pPeb->StartupInfo->Title[i];
i++;
}
lpStartupInfo->lpTitle[i] = 0;
lpStartupInfo->dwX = pPeb->StartupInfo->dwX;
lpStartupInfo->dwY = pPeb->StartupInfo->dwY;
lpStartupInfo->dwXSize = pPeb->StartupInfo->dwXSize;
lpStartupInfo->dwYSize = pPeb->StartupInfo->dwYSize;
lpStartupInfo->dwXCountChars = pPeb->StartupInfo->dwXCountChars;
lpStartupInfo->dwYCountChars = pPeb->StartupInfo->dwYCountChars;
lpStartupInfo->dwFillAttribute = pPeb->StartupInfo->dwFillAttribute;
lpStartupInfo->dwFlags = pPeb->StartupInfo->dwFlags;
lpStartupInfo->wShowWindow = pPeb->StartupInfo->wShowWindow;
//lpStartupInfo->cbReserved2 = pPeb->StartupInfo->cbReserved;
//lpStartupInfo->lpReserved = pPeb->StartupInfo->lpReserved1;
//lpStartupInfo->lpReserved2 = pPeb->StartupInfo->lpReserved2;
lpStartupInfo->hStdInput = pPeb->StartupInfo->hStdInput;
lpStartupInfo->hStdOutput = pPeb->StartupInfo->hStdOutput;
lpStartupInfo->hStdError = pPeb->StartupInfo->hStdError;
return;
}
BOOL
STDCALL
FlushInstructionCache(
HANDLE hProcess,
LPCVOID lpBaseAddress,
DWORD dwSize
)
BOOL STDCALL FlushInstructionCache(HANDLE hProcess,
LPCVOID lpBaseAddress,
DWORD dwSize)
{
NTSTATUS errCode;
errCode = NtFlushInstructionCache(hProcess,(PVOID)lpBaseAddress,dwSize);
if ( !NT_SUCCESS(errCode) ) {
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
return TRUE;
NTSTATUS errCode;
errCode = NtFlushInstructionCache(hProcess,(PVOID)lpBaseAddress,dwSize);
if (!NT_SUCCESS(errCode))
{
SetLastError(RtlNtStatusToDosError(errCode));
return FALSE;
}
return TRUE;
}
VOID STDCALL ExitProcess(UINT uExitCode)
@ -367,25 +341,20 @@ VOID STDCALL ExitProcess(UINT uExitCode)
NtTerminateProcess(NtCurrentProcess() ,uExitCode);
}
VOID
STDCALL
FatalAppExitA(
UINT uAction,
LPCSTR lpMessageText
)
VOID STDCALL FatalAppExitA(UINT uAction, LPCSTR lpMessageText)
{
WCHAR MessageTextW[MAX_PATH];
UINT i;
i = 0;
while ((*lpMessageText)!=0 && i < 35)
{
MessageTextW[i] = *lpMessageText;
lpMessageText++;
i++;
}
MessageTextW[i] = 0;
return FatalAppExitW(uAction,MessageTextW);
WCHAR MessageTextW[MAX_PATH];
UINT i;
i = 0;
while ((*lpMessageText)!=0 && i < 35)
{
MessageTextW[i] = *lpMessageText;
lpMessageText++;
i++;
}
MessageTextW[i] = 0;
return FatalAppExitW(uAction,MessageTextW);
}

View file

@ -23,6 +23,11 @@
/* FUNCTIONS *****************************************************************/
typedef WINBOOL STDCALL (*PDLLMAIN_FUNC)(HANDLE hInst,
ULONG ul_reason_for_call,
LPVOID lpReserved);
static NTSTATUS LdrLoadDll(PDLL* Dll, PCHAR Name)
{
char fqname[255] = "\\??\\C:\\reactos\\system\\";
@ -37,6 +42,7 @@ static NTSTATUS LdrLoadDll(PDLL* Dll, PCHAR Name)
ULONG ImageSize, InitialViewSize;
PVOID ImageBase;
HANDLE FileHandle, SectionHandle;
PDLLMAIN_FUNC Entrypoint;
DPRINT("LdrLoadDll(Base %x, Name %s)\n",Dll,Name);
@ -131,7 +137,12 @@ static NTSTATUS LdrLoadDll(PDLL* Dll, PCHAR Name)
LdrDllListHead.Next->Prev = (*Dll);
LdrDllListHead.Next = (*Dll);
LdrPEStartup(ImageBase, SectionHandle);
Entrypoint = (PDLLMAIN_FUNC)LdrPEStartup(ImageBase, SectionHandle);
if (Entrypoint != NULL)
{
DPRINT("Calling entry point at %x\n",Entrypoint);
Entrypoint(ImageBase, DLL_PROCESS_ATTACH, NULL);
}
return(STATUS_SUCCESS);
}

View file

@ -15,7 +15,7 @@ include rules.mak
# Required to run the system
#
COMPONENTS = iface_native ntoskrnl
DLLS = ntdll kernel32
DLLS = ntdll kernel32 crtdll
#DLLS = crtdll mingw32
#
@ -32,7 +32,7 @@ LOADERS = dos
#
# Select the device drivers and filesystems you want
#
DEVICE_DRIVERS = blue ide keyboard mouse null parallal serial
DEVICE_DRIVERS = blue ide keyboard mouse null parallel serial
# DEVICE_DRIVERS = beep event floppy ide_test sound test test1
FS_DRIVERS = minix vfat ext2
# FS_DRIVERS = template

View file

@ -18,7 +18,7 @@
NTSTATUS STDCALL NtSetLdtEntries(PEPROCESS Process,
NTSTATUS STDCALL NtSetLdtEntries(PETHREAD Thread,
ULONG FirstEntry,
PULONG Entries)
{

View file

@ -14,7 +14,7 @@
#include <internal/ke.h>
#include <internal/mm.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS *****************************************************************/

439
reactos/ntoskrnl/ldr/init.c Normal file
View file

@ -0,0 +1,439 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ldr/loader.c
* PURPOSE: Loaders for PE executables
* PROGRAMMERS: Jean Michault
* Rex Jolliff (rex@lvcablemodem.com)
* UPDATE HISTORY:
* DW 22/05/98 Created
* RJJ 10/12/98 Completed image loader function and added hooks for MZ/PE
* RJJ 10/12/98 Built driver loader function and added hooks for PE/COFF
* RJJ 10/12/98 Rolled in David's code to load COFF drivers
* JM 14/12/98 Built initial PE user module loader
* RJJ 06/03/99 Moved user PE loader into NTDLL
*/
/* INCLUDES *****************************************************************/
#include <windows.h>
#include <internal/i386/segment.h>
#include <internal/linkage.h>
#include <internal/module.h>
#include <internal/ntoskrnl.h>
#include <internal/ob.h>
#include <internal/ps.h>
#include <string.h>
#include <internal/string.h>
#include <internal/symbol.h>
#include <internal/teb.h>
#include <ddk/ntddk.h>
//#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ****************************************************************/
/* LdrLoadImage
* FUNCTION:
* Builds the initial environment for a process. Should be used
* to load the initial user process.
* ARGUMENTS:
* HANDLE ProcessHandle handle of the process to load the module into
* PUNICODE_STRING Filename name of the module to load
* RETURNS:
* NTSTATUS
*/
#define STACK_TOP (0xb0000000)
static NTSTATUS LdrCreatePeb(HANDLE ProcessHandle)
{
NTSTATUS Status;
PVOID PebBase;
ULONG PebSize;
NT_PEB Peb;
ULONG BytesWritten;
PebBase = PEB_BASE;
PebSize = 0x1000;
Status = ZwAllocateVirtualMemory(ProcessHandle,
&PebBase,
0,
&PebSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
return(Status);
}
memset(&Peb, 0, sizeof(Peb));
Peb.StartupInfo = PEB_STARTUPINFO;
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)PEB_BASE,
&Peb,
sizeof(Peb),
&BytesWritten);
return(STATUS_SUCCESS);
}
NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
{
char BlockBuffer[1024];
DWORD ImageBase, LdrStartupAddr, StackBase;
ULONG ImageSize, StackSize;
NTSTATUS Status;
OBJECT_ATTRIBUTES FileObjectAttributes;
HANDLE FileHandle, SectionHandle, NTDllSectionHandle, ThreadHandle;
HANDLE DupNTDllSectionHandle;
CONTEXT Context;
UNICODE_STRING DllPathname;
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
ULONG BytesWritten;
ULONG InitialViewSize;
ULONG i;
HANDLE DupSectionHandle;
/* Locate and open NTDLL to determine ImageBase and LdrStartup */
RtlInitUnicodeString(&DllPathname,L"\\??\\C:\\reactos\\system\\ntdll.dll");
InitializeObjectAttributes(&FileObjectAttributes,
&DllPathname,
0,
NULL,
NULL);
DPRINT("Opening NTDLL\n");
Status = ZwOpenFile(&FileHandle,
FILE_ALL_ACCESS,
&FileObjectAttributes,
NULL,
0,
0);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL open failed ");
DbgPrintErrorMessage(Status);
return Status;
}
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 1024, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL header read failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* FIXME: this will fail if the NT headers are more than 1024 bytes from start */
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
if (DosHeader->e_magic != IMAGE_DOS_MAGIC ||
DosHeader->e_lfanew == 0L ||
*(PULONG)((PUCHAR)BlockBuffer + DosHeader->e_lfanew) != IMAGE_PE_MAGIC)
{
DPRINT("NTDLL format invalid\n");
ZwClose(FileHandle);
return STATUS_UNSUCCESSFUL;
}
NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
ImageBase = NTHeaders->OptionalHeader.ImageBase;
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
/* FIXME: retrieve the offset of LdrStartup from NTDLL */
DPRINT("ImageBase %x\n",ImageBase);
LdrStartupAddr = ImageBase + NTHeaders->OptionalHeader.AddressOfEntryPoint;
/* Create a section for NTDLL */
Status = ZwCreateSection(&NTDllSectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READWRITE,
MEM_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL create section failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* Map the NTDLL into the process */
InitialViewSize = DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
Status = ZwMapViewOfSection(NTDllSectionHandle,
ProcessHandle,
(PVOID *)&ImageBase,
0,
InitialViewSize,
NULL,
&InitialViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL map view of secion failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the section here */
ZwClose(FileHandle);
return Status;
}
for (i=0; i<NTHeaders->FileHeader.NumberOfSections; i++)
{
PIMAGE_SECTION_HEADER Sections;
LARGE_INTEGER Offset;
ULONG Base;
Sections = (PIMAGE_SECTION_HEADER)SECHDROFFSET(BlockBuffer);
Base = Sections[i].VirtualAddress + ImageBase;
SET_LARGE_INTEGER_HIGH_PART(Offset,0);
SET_LARGE_INTEGER_LOW_PART(Offset,Sections[i].PointerToRawData);
Status = ZwMapViewOfSection(NTDllSectionHandle,
ProcessHandle,
(PVOID *)&Base,
0,
Sections[i].Misc.VirtualSize,
&Offset,
(PULONG)&Sections[i].Misc.VirtualSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL map view of secion failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the section here */
ZwClose(FileHandle);
return Status;
}
}
ZwClose(FileHandle);
/* Open process image to determine ImageBase and StackBase/Size */
InitializeObjectAttributes(&FileObjectAttributes,
Filename,
0,
NULL,
NULL);
DPRINT("Opening image file %w\n",FileObjectAttributes.ObjectName->Buffer);
Status = ZwOpenFile(&FileHandle, FILE_ALL_ACCESS, &FileObjectAttributes,
NULL, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("Image open failed ");
DbgPrintErrorMessage(Status);
return Status;
}
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 1024, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("Image header read failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* FIXME: this will fail if the NT headers are more than 1024 bytes from start */
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
if (DosHeader->e_magic != IMAGE_DOS_MAGIC ||
DosHeader->e_lfanew == 0L ||
*(PULONG)((PUCHAR)BlockBuffer + DosHeader->e_lfanew) != IMAGE_PE_MAGIC)
{
DPRINT("Image invalid format rc=%08lx\n", Status);
ZwClose(FileHandle);
return STATUS_UNSUCCESSFUL;
}
NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
ImageBase = NTHeaders->OptionalHeader.ImageBase;
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
/* Create a section for the image */
Status = ZwCreateSection(&SectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READWRITE,
MEM_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("Image create section failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* Map the image into the process */
InitialViewSize = DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
DPRINT("InitialViewSize %x\n",InitialViewSize);
Status = ZwMapViewOfSection(SectionHandle,
ProcessHandle,
(PVOID *)&ImageBase,
0,
InitialViewSize,
NULL,
&InitialViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("Image map view of section failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the section here */
ZwClose(FileHandle);
return Status;
}
ZwClose(FileHandle);
/* Create page backed section for stack */
StackBase = (STACK_TOP - NTHeaders->OptionalHeader.SizeOfStackReserve);
StackSize = NTHeaders->OptionalHeader.SizeOfStackReserve;
Status = ZwAllocateVirtualMemory(ProcessHandle,
(PVOID *)&StackBase,
0,
&StackSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("Stack allocation failed ");
DbgPrintErrorMessage(Status);
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
ZwDuplicateObject(NtCurrentProcess(),
&SectionHandle,
ProcessHandle,
&DupSectionHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
ZwDuplicateObject(NtCurrentProcess(),
&NTDllSectionHandle,
ProcessHandle,
&DupNTDllSectionHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 4),
&DupNTDllSectionHandle,
sizeof(DupNTDllSectionHandle),
&BytesWritten);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 8),
&ImageBase,
sizeof(ImageBase),
&BytesWritten);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 12),
&DupSectionHandle,
sizeof(DupSectionHandle),
&BytesWritten);
/*
* Create a peb (grungy)
*/
Status = LdrCreatePeb(ProcessHandle);
if (!NT_SUCCESS(Status))
{
DbgPrint("LDR: Failed to create initial peb\n");
return(Status);
}
/* Initialize context to point to LdrStartup */
memset(&Context,0,sizeof(CONTEXT));
Context.SegSs = USER_DS;
Context.Esp = STACK_TOP - 16;
Context.EFlags = 0x202;
Context.SegCs = USER_CS;
Context.Eip = LdrStartupAddr;
Context.SegDs = USER_DS;
Context.SegEs = USER_DS;
Context.SegFs = USER_DS;
Context.SegGs = USER_DS;
DPRINT("LdrStartupAddr %x\n",LdrStartupAddr);
/* FIXME: Create process and let 'er rip */
Status = ZwCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
ProcessHandle,
NULL,
&Context,
NULL,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("Thread creation failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the stack memory block here */
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
return STATUS_SUCCESS;
}
NTSTATUS LdrLoadInitialProcess(VOID)
/*
* FIXME: The location of the initial process should be configurable,
* from command line or registry
*/
{
NTSTATUS Status;
HANDLE ProcessHandle;
UNICODE_STRING ProcessName;
Status = ZwCreateProcess(&ProcessHandle,
PROCESS_ALL_ACCESS,
NULL,
SystemProcessHandle,
FALSE,
NULL,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
DbgPrint("Could not create process\n");
return Status;
}
RtlInitUnicodeString(&ProcessName, L"\\??\\C:\\reactos\\system\\shell.exe");
Status = LdrLoadImage(ProcessHandle, &ProcessName);
return Status;
}

View file

@ -892,354 +892,3 @@ LdrCOFFGetSymbolValueByName(module *Module,
return 0L;
}
/* LdrLoadImage
* FUNCTION:
* Builds the initial environment for a process. Should be used
* to load the initial user process.
* ARGUMENTS:
* HANDLE ProcessHandle handle of the process to load the module into
* PUNICODE_STRING Filename name of the module to load
* RETURNS:
* NTSTATUS
*/
#define STACK_TOP (0xb0000000)
NTSTATUS LdrLoadImage(HANDLE ProcessHandle, PUNICODE_STRING Filename)
{
char BlockBuffer[1024];
DWORD ImageBase, LdrStartupAddr, StackBase;
ULONG ImageSize, StackSize;
NTSTATUS Status;
OBJECT_ATTRIBUTES FileObjectAttributes;
HANDLE FileHandle, SectionHandle, NTDllSectionHandle, ThreadHandle;
HANDLE DupNTDllSectionHandle;
CONTEXT Context;
UNICODE_STRING DllPathname;
PIMAGE_DOS_HEADER DosHeader;
PIMAGE_NT_HEADERS NTHeaders;
ULONG BytesWritten;
ULONG InitialViewSize;
ULONG i;
HANDLE DupSectionHandle;
/* Locate and open NTDLL to determine ImageBase and LdrStartup */
RtlInitUnicodeString(&DllPathname,L"\\??\\C:\\reactos\\system\\ntdll.dll");
InitializeObjectAttributes(&FileObjectAttributes,
&DllPathname,
0,
NULL,
NULL);
DPRINT("Opening NTDLL\n");
Status = ZwOpenFile(&FileHandle, FILE_ALL_ACCESS, &FileObjectAttributes, NULL, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL open failed ");
DbgPrintErrorMessage(Status);
return Status;
}
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 1024, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL header read failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* FIXME: this will fail if the NT headers are more than 1024 bytes from start */
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
if (DosHeader->e_magic != IMAGE_DOS_MAGIC ||
DosHeader->e_lfanew == 0L ||
*(PULONG)((PUCHAR)BlockBuffer + DosHeader->e_lfanew) != IMAGE_PE_MAGIC)
{
DPRINT("NTDLL format invalid\n");
ZwClose(FileHandle);
return STATUS_UNSUCCESSFUL;
}
NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
ImageBase = NTHeaders->OptionalHeader.ImageBase;
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
/* FIXME: retrieve the offset of LdrStartup from NTDLL */
DPRINT("ImageBase %x\n",ImageBase);
LdrStartupAddr = ImageBase + NTHeaders->OptionalHeader.AddressOfEntryPoint;
/* Create a section for NTDLL */
Status = ZwCreateSection(&NTDllSectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READWRITE,
MEM_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL create section failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* Map the NTDLL into the process */
InitialViewSize = DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
Status = ZwMapViewOfSection(NTDllSectionHandle,
ProcessHandle,
(PVOID *)&ImageBase,
0,
InitialViewSize,
NULL,
&InitialViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL map view of secion failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the section here */
ZwClose(FileHandle);
return Status;
}
for (i=0; i<NTHeaders->FileHeader.NumberOfSections; i++)
{
PIMAGE_SECTION_HEADER Sections;
LARGE_INTEGER Offset;
ULONG Base;
Sections = (PIMAGE_SECTION_HEADER)SECHDROFFSET(BlockBuffer);
Base = Sections[i].VirtualAddress + ImageBase;
SET_LARGE_INTEGER_HIGH_PART(Offset,0);
SET_LARGE_INTEGER_LOW_PART(Offset,Sections[i].PointerToRawData);
Status = ZwMapViewOfSection(NTDllSectionHandle,
ProcessHandle,
(PVOID *)&Base,
0,
Sections[i].Misc.VirtualSize,
&Offset,
(PULONG)&Sections[i].Misc.VirtualSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("NTDLL map view of secion failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the section here */
ZwClose(FileHandle);
return Status;
}
}
ZwClose(FileHandle);
/* Open process image to determine ImageBase and StackBase/Size */
InitializeObjectAttributes(&FileObjectAttributes,
Filename,
0,
NULL,
NULL);
DPRINT("Opening image file %w\n",FileObjectAttributes.ObjectName->Buffer);
Status = ZwOpenFile(&FileHandle, FILE_ALL_ACCESS, &FileObjectAttributes,
NULL, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("Image open failed ");
DbgPrintErrorMessage(Status);
return Status;
}
Status = ZwReadFile(FileHandle, 0, 0, 0, 0, BlockBuffer, 1024, 0, 0);
if (!NT_SUCCESS(Status))
{
DPRINT("Image header read failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* FIXME: this will fail if the NT headers are more than 1024 bytes from start */
DosHeader = (PIMAGE_DOS_HEADER) BlockBuffer;
if (DosHeader->e_magic != IMAGE_DOS_MAGIC ||
DosHeader->e_lfanew == 0L ||
*(PULONG)((PUCHAR)BlockBuffer + DosHeader->e_lfanew) != IMAGE_PE_MAGIC)
{
DPRINT("Image invalid format rc=%08lx\n", Status);
ZwClose(FileHandle);
return STATUS_UNSUCCESSFUL;
}
NTHeaders = (PIMAGE_NT_HEADERS)(BlockBuffer + DosHeader->e_lfanew);
ImageBase = NTHeaders->OptionalHeader.ImageBase;
ImageSize = NTHeaders->OptionalHeader.SizeOfImage;
/* Create a section for the image */
Status = ZwCreateSection(&SectionHandle,
SECTION_ALL_ACCESS,
NULL,
NULL,
PAGE_READWRITE,
MEM_COMMIT,
FileHandle);
if (!NT_SUCCESS(Status))
{
DPRINT("Image create section failed ");
DbgPrintErrorMessage(Status);
ZwClose(FileHandle);
return Status;
}
/* Map the image into the process */
InitialViewSize = DosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS)
+ sizeof(IMAGE_SECTION_HEADER) * NTHeaders->FileHeader.NumberOfSections;
DPRINT("InitialViewSize %x\n",InitialViewSize);
Status = ZwMapViewOfSection(SectionHandle,
ProcessHandle,
(PVOID *)&ImageBase,
0,
InitialViewSize,
NULL,
&InitialViewSize,
0,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("Image map view of section failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the section here */
ZwClose(FileHandle);
return Status;
}
ZwClose(FileHandle);
/* Create page backed section for stack */
StackBase = (STACK_TOP - NTHeaders->OptionalHeader.SizeOfStackReserve);
StackSize = NTHeaders->OptionalHeader.SizeOfStackReserve;
Status = ZwAllocateVirtualMemory(ProcessHandle,
(PVOID *)&StackBase,
0,
&StackSize,
MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(Status))
{
DPRINT("Stack allocation failed ");
DbgPrintErrorMessage(Status);
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
ZwDuplicateObject(NtCurrentProcess(),
&SectionHandle,
ProcessHandle,
&DupSectionHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
ZwDuplicateObject(NtCurrentProcess(),
&NTDllSectionHandle,
ProcessHandle,
&DupNTDllSectionHandle,
0,
FALSE,
DUPLICATE_SAME_ACCESS);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 4),
&DupNTDllSectionHandle,
sizeof(DupNTDllSectionHandle),
&BytesWritten);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 8),
&ImageBase,
sizeof(ImageBase),
&BytesWritten);
ZwWriteVirtualMemory(ProcessHandle,
(PVOID)(STACK_TOP - 12),
&DupSectionHandle,
sizeof(DupSectionHandle),
&BytesWritten);
/* Initialize context to point to LdrStartup */
memset(&Context,0,sizeof(CONTEXT));
Context.SegSs = USER_DS;
Context.Esp = STACK_TOP - 16;
Context.EFlags = 0x202;
Context.SegCs = USER_CS;
Context.Eip = LdrStartupAddr;
Context.SegDs = USER_DS;
Context.SegEs = USER_DS;
Context.SegFs = USER_DS;
Context.SegGs = USER_DS;
DPRINT("LdrStartupAddr %x\n",LdrStartupAddr);
/* FIXME: Create process and let 'er rip */
Status = ZwCreateThread(&ThreadHandle,
THREAD_ALL_ACCESS,
NULL,
ProcessHandle,
NULL,
&Context,
NULL,
FALSE);
if (!NT_SUCCESS(Status))
{
DPRINT("Thread creation failed ");
DbgPrintErrorMessage(Status);
/* FIXME: destroy the stack memory block here */
/* FIXME: unmap the section here */
/* FIXME: destroy the section here */
return Status;
}
return STATUS_SUCCESS;
}
NTSTATUS LdrLoadInitialProcess(VOID)
/*
* FIXME: The location of the initial process should be configurable,
* from command line or registry
*/
{
NTSTATUS Status;
HANDLE ProcessHandle;
UNICODE_STRING ProcessName;
Status = ZwCreateProcess(&ProcessHandle,
PROCESS_ALL_ACCESS,
NULL,
SystemProcessHandle,
FALSE,
NULL,
NULL,
NULL);
if (!NT_SUCCESS(Status))
{
DbgPrint("Could not create process\n");
return Status;
}
RtlInitUnicodeString(&ProcessName, L"\\??\\C:\\reactos\\system\\shell.exe");
Status = LdrLoadImage(ProcessHandle, &ProcessName);
return Status;
}

View file

@ -48,11 +48,11 @@ CM_OBJECTS = cm/registry.o
DBG_OBJECTS = dbg/brkpoint.o dbg/errinfo.o
LDR_OBJECTS = ldr/loader.o
LDR_OBJECTS = ldr/loader.o ldr/init.o
CC_OBJECTS = cc/cacheman.o cc/block.o cc/view.o
objects: ../ntoskrnl/objects
objects:
mkdir objects
objects/hal.o: $(HAL_OBJECTS)

View file

@ -91,8 +91,8 @@ 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);
DPRINT("ExUnmapPage(Addr %x)\n",Addr);
DPRINT("i %x\n",i);
KeAcquireSpinLock(&AllocMapLock, &oldIrql);
MmSetPage(NULL, (PVOID)Addr, 0, 0);
@ -108,7 +108,7 @@ PVOID ExAllocatePage(VOID)
ULONG PhysPage;
PhysPage = (ULONG)MmAllocPage();
DbgPrint("Allocated page %x\n",PhysPage);
DPRINT("Allocated page %x\n",PhysPage);
if (PhysPage == 0)
{
return(NULL);
@ -119,7 +119,7 @@ PVOID ExAllocatePage(VOID)
{
if (!test_bit(i%32,&alloc_map[i/32]))
{
DbgPrint("i %x\n",i);
DPRINT("i %x\n",i);
set_bit(i%32,&alloc_map[i/32]);
addr = kernel_pool_base + (i*PAGESIZE);
MmSetPage(NULL, (PVOID)addr, PAGE_READWRITE, PhysPage);

View file

@ -20,4 +20,5 @@
VOID NtInit(VOID)
{
NtInitializeEventImplementation();
NiInitPort();
}

View file

@ -8,14 +8,96 @@
* Created 22/05/98
*/
/* NOTES ********************************************************************
*
* This is a very rough implementation, not compatible with mach or nt
*
*
*
*
*/
/* INCLUDES *****************************************************************/
#include <ddk/ntddk.h>
#include <internal/ob.h>
#include <string.h>
#include <internal/string.h>
#include <internal/debug.h>
/* TYPES ********************************************************************/
struct _EPORT;
typedef struct _PORT_MSG
{
ULONG DataLength;
PVOID Data;
LIST_ENTRY ListEntry;
struct _EPORT* ReplyPort;
PMDL Mdl;
} EPORT_MSG, *PEPORT_MSG;
typedef struct _EPORT
{
PEPROCESS Owner;
LIST_ENTRY MsgQueueHead;
KEVENT MsgNotify;
KSPIN_LOCK PortLock;
} EPORT, *PEPORT;
/* GLOBALS *******************************************************************/
POBJECT_TYPE ExPortType = NULL;
/* FUNCTIONS *****************************************************************/
NTSTATUS NiInitPort(VOID)
{
ExPortType = ExAllocatePool(NonPagedPool,sizeof(OBJECT_TYPE));
RtlInitUnicodeString(&ExPortType->TypeName,L"Event");
ExPortType->MaxObjects = ULONG_MAX;
ExPortType->MaxHandles = ULONG_MAX;
ExPortType->TotalObjects = 0;
ExPortType->TotalHandles = 0;
ExPortType->PagedPoolCharge = 0;
ExPortType->NonpagedPoolCharge = sizeof(EPORT);
ExPortType->Dump = NULL;
ExPortType->Open = NULL;
ExPortType->Close = NULL;
ExPortType->Delete = NULL;
ExPortType->Parse = NULL;
ExPortType->Security = NULL;
ExPortType->QueryName = NULL;
ExPortType->OkayToClose = NULL;
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes)
{
PEPORT Port;
Port = ObCreateObject(PortHandle,
DesiredAccess,
ObjectAttributes,
ExPortType);
if (Port == NULL)
{
return(STATUS_UNSUCCESSFUL);
}
InitializeListHead(&Port->MsgQueueHead);
KeInitializeEvent(&Port->MsgNotify, NotificationEvent, FALSE);
KeInitializeSpinLock(&Port->PortLock);
Port->Owner = PsGetCurrentProcess();
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NtAcceptConnectPort(VOID)
{
UNIMPLEMENTED;
@ -26,19 +108,85 @@ NTSTATUS STDCALL NtCompleteConnectPort(VOID)
UNIMPLEMENTED;
}
NTSTATUS STDCALL NtConnectPort(VOID)
NTSTATUS STDCALL NtConnectPort(PHANDLE PortHandle,
POBJECT_ATTRIBUTES ObjectAttributes)
{
UNIMPLEMENTED;
NTSTATUS Status;
PEPORT Port;
Status = ObReferenceObjectByName(ObjectAttributes->ObjectName,
ObjectAttributes->Attributes,
NULL,
STANDARD_RIGHTS_REQUIRED,
ExPortType,
UserMode,
NULL,
(PVOID*)&Port);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
Status = ObCreateHandle(PsGetCurrentProcess(),
Port,
STANDARD_RIGHTS_REQUIRED,
FALSE,
PortHandle);
ObDereferenceObject(Port);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NtCreatePort(VOID)
NTSTATUS STDCALL NtListenPort(HANDLE PortHandle,
PLARGE_INTEGER Timeout,
PPORT_MSG_DATA Msg)
{
UNIMPLEMENTED;
}
NTSTATUS STDCALL NtListenPort(VOID)
{
UNIMPLEMENTED;
NTSTATUS Status;
PEPORT Port;
KIRQL oldIrql;
PEPORT_MSG KMsg;
PVOID Data;
Status = ObReferenceObjectByHandle(PortHandle,
STANDARD_RIGHTS_REQUIRED,
ExPortType,
UserMode,
(PVOID*)&Port,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Status = KeWaitForSingleObject(&Port->MsgNotify, 0,
KernelMode, FALSE, Timeout);
if (!NT_SUCCESS(Status))
{
return(Status);
}
KeAcquireSpinLock(&Port->PortLock, &oldIrql);
KMsg = CONTAINING_RECORD(RemoveHeadList(&Port->MsgQueueHead),
EPORT_MSG,
ListEntry);
KeReleaseSpinLock(&Port->PortLock, oldIrql);
if (KMsg->DataLength > Msg->DataLength)
{
return(STATUS_UNSUCCESSFUL);
}
Msg->DataLength = KMsg->DataLength;
Data = MmGetSystemAddressForMdl(KMsg->Mdl);
memcpy(Msg->Data, Data, KMsg->DataLength);
MmUnmapLockedPages(Data, KMsg->Mdl);
Status = ObCreateHandle(PsGetCurrentProcess(),
KMsg->ReplyPort,
FALSE,
STANDARD_RIGHTS_REQUIRED,
&Msg->ReplyPort);
ObDereferenceObject(PortHandle);
return(Status);
}
NTSTATUS STDCALL NtReplyPort(VOID)
@ -56,9 +204,70 @@ NTSTATUS STDCALL NtReplyWaitReplyPort(VOID)
UNIMPLEMENTED;
}
NTSTATUS STDCALL NtRequestPort(VOID)
NTSTATUS STDCALL NtRequestPort(HANDLE PortHandle,
ULONG DataLength,
PVOID Data,
ULONG Options,
PHANDLE ReplyPortHandle)
/*
* FUNCTION: Send a request to a port
* ARGUMENTS:
* PortHandle = Handle to the destination port
* DataLength = Length of the data to send
* Data = Data to send
* Option = Send options
* ReplyPortHandle = Optional port for reply
*/
{
UNIMPLEMENTED;
PEPORT Port;
NTSTATUS Status;
KIRQL oldIrql;
PEPORT_MSG Msg;
Status = ObReferenceObjectByHandle(PortHandle,
STANDARD_RIGHTS_REQUIRED,
ExPortType,
UserMode,
(PVOID*)&Port,
NULL);
if (!NT_SUCCESS(Status))
{
return(Status);
}
Msg = ExAllocatePool(NonPagedPool, sizeof(EPORT_MSG));
Msg->DataLength = DataLength;
Msg->Mdl = MmCreateMdl(NULL,
Data,
Msg->DataLength);
MmProbeAndLockPages(Msg->Mdl,
UserMode,
IoReadAccess);
if (ReplyPortHandle != NULL)
{
NtCreatePort(ReplyPortHandle,
STANDARD_RIGHTS_REQUIRED,
NULL);
Status = ObReferenceObjectByHandle(*ReplyPortHandle,
STANDARD_RIGHTS_REQUIRED,
ExPortType,
UserMode,
(PVOID*)&Msg->ReplyPort,
NULL);
if (!NT_SUCCESS(Status))
{
ExFreePool(Msg);
return(Status);
}
}
KeAcquireSpinLock(&Port->PortLock, &oldIrql);
InsertHeadList(&Port->MsgQueueHead, &Msg->ListEntry);
KeReleaseSpinLock(&Port->PortLock, oldIrql);
KeSetEvent(&Port->MsgNotify, 0, FALSE);
return(STATUS_SUCCESS);
}
NTSTATUS STDCALL NtRequestWaitReplyPort(VOID)

View file

@ -16,10 +16,10 @@
#include <internal/mm.h>
#include <internal/ob.h>
//#define NDEBUG
#define NDEBUG
#include <internal/debug.h>
/* GLBOALS *******************************************************************/
/* GLOBALS *******************************************************************/
extern ULONG PiNrThreads;
@ -28,7 +28,8 @@ extern ULONG PiNrThreads;
VOID PiDeleteProcess(PVOID ObjectBody)
{
DPRINT("PiDeleteProcess(ObjectBody %x)\n",ObjectBody);
(VOID)MmReleaseMmInfo((PEPROCESS)ObjectBody);
/* FIXME: This doesn't work, why? */
// (VOID)MmReleaseMmInfo((PEPROCESS)ObjectBody);
}
VOID PsTerminateCurrentThread(NTSTATUS ExitStatus)