From 9b614b887dc094ca5519281931a5f6bdde738502 Mon Sep 17 00:00:00 2001 From: David Welch Date: Thu, 25 Nov 1999 10:47:58 +0000 Subject: [PATCH] Corrected ntdll mapping bug Implemented prototype lpc mechanism svn path=/trunk/; revision=795 --- reactos/Makefile | 2 +- reactos/apps/tests/lpc/lpcclt.c | 61 ++++ reactos/apps/tests/lpc/lpcsrv.c | 99 +++++++ reactos/apps/tests/lpc/makefile | 71 +++-- reactos/include/ddk/zw.h | 21 +- reactos/include/ddk/zwtypes.h | 19 +- reactos/include/internal/mm.h | 3 + reactos/install.sh | 2 + reactos/lib/ntdll/def/ntdll.edf | 5 +- reactos/lib/ntdll/ldr/startup.c | 9 +- reactos/lib/ntdll/ldr/utils.c | 439 ++++++++++++++--------------- reactos/ntoskrnl/ke/i386/exp.c | 12 +- reactos/ntoskrnl/makefile_rex | 4 +- reactos/ntoskrnl/mm/i386/memsafe.s | 74 +++++ reactos/ntoskrnl/mm/marea.c | 6 +- reactos/ntoskrnl/mm/section.c | 4 +- reactos/ntoskrnl/mm/virtual.c | 7 + reactos/ntoskrnl/nt/port.c | 268 ++++++++++++------ reactos/subsys/smss/init.c | 3 +- 19 files changed, 723 insertions(+), 386 deletions(-) create mode 100644 reactos/apps/tests/lpc/lpcclt.c create mode 100644 reactos/apps/tests/lpc/lpcsrv.c create mode 100644 reactos/ntoskrnl/mm/i386/memsafe.s diff --git a/reactos/Makefile b/reactos/Makefile index 676badd69ec..398e18c024d 100644 --- a/reactos/Makefile +++ b/reactos/Makefile @@ -41,7 +41,7 @@ FS_DRIVERS = vfat # FS_DRIVERS = minix ext2 template KERNEL_SERVICES = $(DEVICE_DRIVERS) $(FS_DRIVERS) -APPS = args hello shell test cat bench apc shm +APPS = args hello shell test cat bench apc shm lpc # APPS = cmd all: buildno $(COMPONENTS) $(DLLS) $(SUBSYS) $(LOADERS) $(KERNEL_SERVICES) $(APPS) diff --git a/reactos/apps/tests/lpc/lpcclt.c b/reactos/apps/tests/lpc/lpcclt.c new file mode 100644 index 00000000000..e135a54af3c --- /dev/null +++ b/reactos/apps/tests/lpc/lpcclt.c @@ -0,0 +1,61 @@ +#include +#include +#include +#include + +HANDLE OutputHandle; +HANDLE InputHandle; + +void debug_printf(char* fmt, ...) +{ + va_list args; + char buffer[255]; + + va_start(args,fmt); + vsprintf(buffer,fmt,args); + WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL); + va_end(args); +} + + +void main(int argc, char* argv[]) +{ + UNICODE_STRING PortName; + NTSTATUS Status; + HANDLE PortHandle; + LPC_MESSAGE Request; + char buffer[255]; + + printf("Lpc client\n"); + + RtlInitUnicodeString(&PortName, L"\\TestPort"); + + printf("Connecting to port\n"); + Status = NtConnectPort(&PortHandle, + &PortName, + NULL, + 0, + 0, + 0, + 0, + 0); + if (!NT_SUCCESS(Status)) + { + printf("Failed to connect\n"); + return; + } + + strcpy(buffer, GetCommandLineA()); + Request.Buffer = buffer; + + Status = NtRequestWaitReplyPort(PortHandle, + NULL, + &Request); + if (!NT_SUCCESS(Status)) + { + printf("Failed to send request\n"); + return; + } + + printf("Succeeded\n"); +} diff --git a/reactos/apps/tests/lpc/lpcsrv.c b/reactos/apps/tests/lpc/lpcsrv.c new file mode 100644 index 00000000000..d9b2bc6ddf5 --- /dev/null +++ b/reactos/apps/tests/lpc/lpcsrv.c @@ -0,0 +1,99 @@ +#include +#include +#include +#include + +HANDLE OutputHandle; +HANDLE InputHandle; + +void debug_printf(char* fmt, ...) +{ + va_list args; + char buffer[255]; + + va_start(args,fmt); + vsprintf(buffer,fmt,args); + WriteConsoleA(OutputHandle, buffer, strlen(buffer), NULL, NULL); + va_end(args); +} + + +void main(int argc, char* argv[]) +{ + UNICODE_STRING PortName; + OBJECT_ATTRIBUTES ObjectAttributes; + NTSTATUS Status; + HANDLE NamedPortHandle; + HANDLE PortHandle; + + printf("Lpc test server\n"); + + RtlInitUnicodeString(&PortName, L"\\TestPort"); + InitializeObjectAttributes(&ObjectAttributes, + &PortName, + 0, + NULL, + NULL); + + printf("Creating port\n"); + Status = NtCreatePort(&NamedPortHandle, + 0, + &ObjectAttributes, + 0, + 0); + if (!NT_SUCCESS(Status)) + { + printf("Failed to create port\n"); + return; + } + + + printf("Listening for connections\n"); + Status = NtListenPort(NamedPortHandle, + 0); + if (!NT_SUCCESS(Status)) + { + printf("Failed to listen for connections\n"); + return; + } + + printf("Accepting connections\n"); + Status = NtAcceptConnectPort(NamedPortHandle, + &PortHandle, + 0, + 0, + 0, + 0); + if (!NT_SUCCESS(Status)) + { + printf("Failed to accept connection\n"); + return; + } + + printf("Completing connection\n"); + Status = NtCompleteConnectPort(PortHandle); + if (!NT_SUCCESS(Status)) + { + printf("Failed to complete connection\n"); + return; + } + + for(;;) + { + LPC_MESSAGE Request; + char buffer[255]; + + Request.Buffer = buffer; + + Status = NtRequestWaitReplyPort(PortHandle, + &Request, + NULL); + if (!NT_SUCCESS(Status)) + { + printf("Failed to receive request\n"); + return; + } + + printf("Message contents are <%s>\n", Request.Buffer); + } +} diff --git a/reactos/apps/tests/lpc/makefile b/reactos/apps/tests/lpc/makefile index f840e6b347d..e13fe8223ca 100644 --- a/reactos/apps/tests/lpc/makefile +++ b/reactos/apps/tests/lpc/makefile @@ -1,24 +1,51 @@ -# $Id: makefile,v 1.3 1999/07/17 23:10:12 ea Exp $ -# ReactOS Operating System -# LPC test -CC=gcc -LD=ld -CFLAGS=-I../../include +# +# +# +SRV_OBJECTS= ../common/crt0.o lpcsrv.o +CLT_OBJECTS= ../common/crt0.o lpcclt.o + +PROGS= lpcsrv.exe lpcclt.exe + +BASE_CFLAGS = -I../../include +LIBS = ../../lib/crtdll/crtdll.a ../../lib/kernel32/kernel32.a \ + ../../lib/ntdll/ntdll.a + +all: $(PROGS) + +.phony: all + +clean: + - $(RM) lpcsrv.o + - $(RM) lpcsrv.exe + - $(RM) lpcsrv.sym + +.phony: clean + +floppy: $(PROGS:%=$(FLOPPY_DIR)/apps/%) + +$(PROGS:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* $(FLOPPY_DIR)\apps\$* +else + $(CP) $* $(FLOPPY_DIR)/apps/$* +endif + +dist: $(PROGS:%=../../$(DIST_DIR)/apps/%) + +$(PROGS:%=../../$(DIST_DIR)/apps/%): ../../$(DIST_DIR)/apps/%: % +ifeq ($(DOSCLI),yes) + $(CP) $* ..\..\$(DIST_DIR)\apps\$* +else + $(CP) $* ../../$(DIST_DIR)/apps/$* +endif + +lpcsrv.exe: $(SRV_OBJECTS) $(LIBS) + $(LD) $(SRV_OBJECTS) $(LIBS) -o lpcsrv.exe + $(NM) --numeric-sort lpcsrv.exe > lpcsrv.sym + +lpcclt.exe: $(CLT_OBJECTS) $(LIBS) + $(LD) $(CLT_OBJECTS) $(LIBS) -o lpcclt.exe + $(NM) --numeric-sort lpcclt.exe > lpcclt.sym -all: conport.exe creport.exe simpless.exe - -conport.exe: conport.o dumpinfo.o - $(CC) -o conport conport.o dumpinfo.o - -creport.exe: creport.o dumpinfo.o. - $(CC) -o creport creport.o dumpinfo.o - -simpless.exe: simpless.o dumpinfo.o. - $(CC) -o simpless simpless.o dumpinfo.o - -%.o: %.c - $(CC) $(CFLAGS) -c $< -o $@ - - -#EOF +include ../../rules.mak diff --git a/reactos/include/ddk/zw.h b/reactos/include/ddk/zw.h index 626ed8a913a..df16d662da3 100644 --- a/reactos/include/ddk/zw.h +++ b/reactos/include/ddk/zw.h @@ -1,4 +1,4 @@ -/* $Id: zw.h,v 1.20 1999/11/24 11:51:42 dwelch Exp $ +/* $Id: zw.h,v 1.21 1999/11/25 10:47:53 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -5177,15 +5177,6 @@ NtConnectPort ( IN DWORD Unknown6, IN ULONG Flags ); -/*NTSTATUS -STDCALL -NtCreatePort ( - IN POBJECT_ATTRIBUTES PortAttributes OPTIONAL, - OUT PHANDLE PortHandle, - IN ACCESS_MASK GrantedAccess, - IN DWORD Unknown3, - IN ULONG Flags - );*/ NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, @@ -5216,13 +5207,13 @@ NTSTATUS STDCALL NtReplyPort ( /* @8 */ IN HANDLE PortHandle, - IN PLPC_REPLY LpcReply /* guess */ + IN PLPC_MESSAGE LpcReply /* guess */ ); NTSTATUS STDCALL NtReplyWaitReceivePort ( /* @16 */ IN HANDLE PortHandle, - IN PLPC_REPLY LpcReply, /* guess */ + IN PLPC_MESSAGE LpcReply, /* guess */ OUT PLPC_MESSAGE LpcMessage, /* guess */ OUT PULONG MessageLength /* guess */ ); @@ -5230,7 +5221,7 @@ NTSTATUS STDCALL NtReplyWaitReplyPort ( /* @8 */ IN HANDLE PortHandle, - IN OUT PLPC_REPLY LpcReply /* guess */ + IN OUT PLPC_MESSAGE LpcReply /* guess */ ); NTSTATUS STDCALL @@ -5242,8 +5233,8 @@ NTSTATUS STDCALL NtRequestWaitReplyPort ( /* @12 */ IN HANDLE PortHandle, - IN OUT PLPC_REPLY LpcReply, /* guess */ - IN TIME * TimeToWait /* guess */ + IN OUT PLPC_MESSAGE LpcReply, /* guess */ + OUT PLPC_MESSAGE LpcRequest /* guess */ ); NTSTATUS STDCALL diff --git a/reactos/include/ddk/zwtypes.h b/reactos/include/ddk/zwtypes.h index 5dcbae63628..24f3e7aa6eb 100644 --- a/reactos/include/ddk/zwtypes.h +++ b/reactos/include/ddk/zwtypes.h @@ -11,21 +11,12 @@ enum { } LPC_MESSAGE_TYPE; -typedef -struct _LPC_REPLY +typedef struct _LPC_MESSAGE { - DWORD ReplyValue; - -} LPC_REPLY, * PLPC_REPLY; - -typedef -struct _LPC_MESSAGE -{ - LPC_MESSAGE_TYPE Type; - ULONG Length; - PVOID Buffer; /* Page aligned! */ - DWORD Flags; /* To be defined */ - + LPC_MESSAGE_TYPE Type; + ULONG Length; + PVOID Buffer; /* Page aligned! */ + DWORD Flags; /* To be defined */ } LPC_MESSAGE, * PLPC_MESSAGE; diff --git a/reactos/include/internal/mm.h b/reactos/include/internal/mm.h index 84affd7bf58..40dc76184f5 100644 --- a/reactos/include/internal/mm.h +++ b/reactos/include/internal/mm.h @@ -113,4 +113,7 @@ NTSTATUS MmUnmapViewOfSection(PEPROCESS Process, PMEMORY_AREA MemoryArea); PVOID MiTryToSharePageInSection(PSECTION_OBJECT Section, ULONG Offset); +NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); +NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); + #endif diff --git a/reactos/install.sh b/reactos/install.sh index 3529a45b753..1cbb81e98c3 100644 --- a/reactos/install.sh +++ b/reactos/install.sh @@ -22,3 +22,5 @@ cp subsys/win32k/win32k.sys $1/reactos/system32/drivers cp apps/apc/apc.exe $1/reactos/bin cp apps/shm/shmsrv.exe $1/reactos/bin cp apps/shm/shmclt.exe $1/reactos/bin +cp apps/lpc/lpcsrv.exe $1/reactos/bin +cp apps/lpc/lpcclt.exe $1/reactos/bin diff --git a/reactos/lib/ntdll/def/ntdll.edf b/reactos/lib/ntdll/def/ntdll.edf index d3ec2b002b3..b5479035ecf 100644 --- a/reactos/lib/ntdll/def/ntdll.edf +++ b/reactos/lib/ntdll/def/ntdll.edf @@ -1,4 +1,4 @@ -; $Id: ntdll.edf,v 1.12 1999/11/20 21:46:16 ekohl Exp $ +; $Id: ntdll.edf,v 1.13 1999/11/25 10:47:55 dwelch Exp $ ; ; ReactOS Operating System ; @@ -572,4 +572,5 @@ LdrGetExportByOrdinal LdrLoadDll LdrMapNTDllForProcess LdrUnloadDll - +LdrAccessResource +LdrFindResource_U diff --git a/reactos/lib/ntdll/ldr/startup.c b/reactos/lib/ntdll/ldr/startup.c index 5fe060bb73e..62c2f5842f3 100644 --- a/reactos/lib/ntdll/ldr/startup.c +++ b/reactos/lib/ntdll/ldr/startup.c @@ -1,4 +1,4 @@ -/* $Id: startup.c,v 1.11 1999/11/24 11:51:45 dwelch Exp $ +/* $Id: startup.c,v 1.12 1999/11/25 10:47:55 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -36,11 +36,8 @@ extern HANDLE __ProcessHeap; /* FUNCTIONS *****************************************************************/ -NTSTATUS -LdrMapNTDllForProcess ( - HANDLE ProcessHandle, - PHANDLE PtrNTDllSectionHandle - ) +NTSTATUS LdrMapNTDllForProcess (HANDLE ProcessHandle, + PHANDLE PtrNTDllSectionHandle) { ULONG InitialViewSize; NTSTATUS Status; diff --git a/reactos/lib/ntdll/ldr/utils.c b/reactos/lib/ntdll/ldr/utils.c index 974a1a24185..aaba18f8c15 100644 --- a/reactos/lib/ntdll/ldr/utils.c +++ b/reactos/lib/ntdll/ldr/utils.c @@ -1,4 +1,4 @@ -/* $Id: utils.c,v 1.16 1999/11/24 11:51:45 dwelch Exp $ +/* $Id: utils.c,v 1.17 1999/11/25 10:47:56 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -59,11 +59,8 @@ LdrFindDll (PDLL* Dll,PCHAR Name); * */ -NTSTATUS -LdrLoadDll ( - PDLL * Dll, - PCHAR Name - ) +NTSTATUS LdrLoadDll (PDLL* Dll, + PCHAR Name) { char fqname [255] = "\\??\\C:\\reactos\\system32\\"; ANSI_STRING AnsiString; @@ -111,8 +108,8 @@ LdrLoadDll ( * Open the DLL's image file. */ - if ( LdrFindDll(Dll,fqname) == STATUS_SUCCESS ) - return STATUS_SUCCESS; + if (LdrFindDll(Dll, Name) == STATUS_SUCCESS) + return STATUS_SUCCESS; RtlInitAnsiString( @@ -226,21 +223,21 @@ LdrLoadDll ( Status = ZwMapViewOfSection( SectionHandle, NtCurrentProcess(), - (PVOID *) & ImageBase, + (PVOID*)&ImageBase, 0, InitialViewSize, NULL, - & InitialViewSize, + &InitialViewSize, 0, MEM_COMMIT, PAGE_READWRITE ); if (!NT_SUCCESS(Status)) { - DPRINT("NTDLL.LDR: map view of section failed "); - ZwClose(FileHandle); - - return Status; + dprintf("NTDLL.LDR: map view of section failed (Status %x)", + Status); + ZwClose(FileHandle); + return(Status); } ZwClose(FileHandle); @@ -258,7 +255,9 @@ LdrLoadDll ( LdrDllListHead.Next = (*Dll); - if ( (*Dll)->Headers->FileHeader.Characteristics & IMAGE_FILE_DLL == IMAGE_FILE_DLL ) { + if (((*Dll)->Headers->FileHeader.Characteristics & IMAGE_FILE_DLL) == + IMAGE_FILE_DLL) + { Entrypoint = (PDLLMAIN_FUNC) LdrPEStartup( @@ -306,60 +305,54 @@ LdrLoadDll ( * NOTE * */ -static -NTSTATUS -LdrFindDll ( - PDLL * Dll, - PCHAR Name - ) +static NTSTATUS LdrFindDll(PDLL* Dll, PCHAR Name) { - PIMAGE_EXPORT_DIRECTORY ExportDir; - DLL * current; - PIMAGE_OPTIONAL_HEADER OptionalHeader; - - -// DPRINT("NTDLL.LdrFindDll(Name %s)\n", Name); + PIMAGE_EXPORT_DIRECTORY ExportDir; + DLL * current; + PIMAGE_OPTIONAL_HEADER OptionalHeader; - current = & LdrDllListHead; - -// NULL is the current process - - if ( Name == NULL ) { - *Dll = current; - return STATUS_SUCCESS; - } - - do - { - OptionalHeader = & current->Headers->OptionalHeader; - ExportDir = (PIMAGE_EXPORT_DIRECTORY) - OptionalHeader->DataDirectory[ - IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - ExportDir = (PIMAGE_EXPORT_DIRECTORY) - ((ULONG)ExportDir + (ULONG)current->BaseAddress); + + DPRINT("NTDLL.LdrFindDll(Name %s)\n", Name); + + current = & LdrDllListHead; + + // NULL is the current process + + if ( Name == NULL ) + { + *Dll = current; + return STATUS_SUCCESS; + } + + do + { + OptionalHeader = & current->Headers->OptionalHeader; + ExportDir = (PIMAGE_EXPORT_DIRECTORY) + OptionalHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT] + .VirtualAddress; + ExportDir = (PIMAGE_EXPORT_DIRECTORY) + ((ULONG)ExportDir + (ULONG)current->BaseAddress); -// DPRINT("Scanning %x %x %x\n", -// ExportDir->Name, -// current->BaseAddress, -// (ExportDir->Name + current->BaseAddress) -// ); -// DPRINT("Scanning %s\n", -// ExportDir->Name + current->BaseAddress -// ); - if (strcmp(ExportDir->Name + current->BaseAddress, Name) == 0) - { - *Dll = current; - current->ReferenceCount++; - return STATUS_SUCCESS; - } + DPRINT("Scanning %x %x %x\n",ExportDir->Name, + current->BaseAddress, + (ExportDir->Name + current->BaseAddress)); + DPRINT("Scanning %s %s\n", + ExportDir->Name + current->BaseAddress, Name); - current = current->Next; - - } while (current != & LdrDllListHead); + if (strcmp(ExportDir->Name + current->BaseAddress, Name) == 0) + { + *Dll = current; + current->ReferenceCount++; + return STATUS_SUCCESS; + } + + current = current->Next; + + } while (current != & LdrDllListHead); - DPRINT("Failed to find dll %s\n",Name); + DPRINT("Failed to find dll %s\n",Name); - return -1; + return -1; } @@ -700,61 +693,54 @@ LdrPerformRelocations ( * NOTE * */ -static -NTSTATUS -LdrFixupImports ( - PIMAGE_NT_HEADERS NTHeaders, - PVOID ImageBase - ) +static NTSTATUS LdrFixupImports(PIMAGE_NT_HEADERS NTHeaders, + PVOID ImageBase) { - PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory; - ULONG Ordinal; - PDLL Module; - NTSTATUS Status; - - - /* - * Process each import module. - */ - ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY) ( - ImageBase - + NTHeaders->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] - .VirtualAddress - ); - while (ImportModuleDirectory->dwRVAModuleName) - { - PVOID * ImportAddressList; - PULONG FunctionNameList; - DWORD pName; - PWORD pHint; + PIMAGE_IMPORT_MODULE_DIRECTORY ImportModuleDirectory; + ULONG Ordinal; + PDLL Module; + NTSTATUS Status; + + + /* + * Process each import module. + */ + ImportModuleDirectory = (PIMAGE_IMPORT_MODULE_DIRECTORY)( + ImageBase + NTHeaders->OptionalHeader + .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] + .VirtualAddress); + + while (ImportModuleDirectory->dwRVAModuleName) + { + PVOID * ImportAddressList; + PULONG FunctionNameList; + DWORD pName; + PWORD pHint; - Status = LdrLoadDll( - & Module, - (PCHAR) ( - ImageBase - + ImportModuleDirectory->dwRVAModuleName - ) - ); - if (!NT_SUCCESS(Status)) - { - return Status; - } - /* - * Get the import address list. - */ - ImportAddressList = (PVOID *) ( - NTHeaders->OptionalHeader.ImageBase - + ImportModuleDirectory->dwRVAFunctionAddressList - ); - /* - * Get the list of functions to import. - */ - if (ImportModuleDirectory->dwRVAFunctionNameList != 0) - { + DPRINT("ImportModule->Directory->dwRVAModuleName %s\n", + (PCHAR)(ImageBase + ImportModuleDirectory->dwRVAModuleName)); + + Status = LdrLoadDll(&Module, + (PCHAR)(ImageBase + +ImportModuleDirectory->dwRVAModuleName)); + if (!NT_SUCCESS(Status)) + { + return Status; + } + /* + * Get the import address list. + */ + ImportAddressList = (PVOID *)(NTHeaders->OptionalHeader.ImageBase + + ImportModuleDirectory->dwRVAFunctionAddressList); + + /* + * Get the list of functions to import. + */ + if (ImportModuleDirectory->dwRVAFunctionNameList != 0) + { FunctionNameList = (PULONG) ( - ImageBase - + ImportModuleDirectory->dwRVAFunctionNameList + ImageBase + + ImportModuleDirectory->dwRVAFunctionNameList ); } else @@ -797,6 +783,7 @@ LdrFixupImports ( ); if ((*ImportAddressList) == NULL) { + dprintf("Failed to import %s\n", pName); return STATUS_UNSUCCESSFUL; } } @@ -837,132 +824,116 @@ LdrFixupImports ( * NOTE * */ -PEPFUNC -LdrPEStartup ( - PVOID ImageBase, - HANDLE SectionHandle - ) +PEPFUNC LdrPEStartup (PVOID ImageBase, + HANDLE SectionHandle) { - NTSTATUS Status; - PEPFUNC EntryPoint; - PIMAGE_DOS_HEADER DosHeader; - PIMAGE_NT_HEADERS NTHeaders; + NTSTATUS Status; + PEPFUNC EntryPoint; + PIMAGE_DOS_HEADER DosHeader; + PIMAGE_NT_HEADERS NTHeaders; + - - /* - * Overlay DOS and WNT headers structures - * to the DLL's image. - */ - DosHeader = (PIMAGE_DOS_HEADER) ImageBase; - NTHeaders = (PIMAGE_NT_HEADERS) (ImageBase + DosHeader->e_lfanew); - /* - * Initialize image sections. - */ - LdrMapSections( - NtCurrentProcess(), - ImageBase, - SectionHandle, - NTHeaders - ); - /* - * If the base address is different from the - * one the DLL is actually loaded, perform any - * relocation. - */ - if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase) - { - Status = LdrPerformRelocations( - NTHeaders, - ImageBase - ); - if (!NT_SUCCESS(Status)) - { - dprintf("LdrPerformRelocations() failed\n"); - return NULL; - } - } - /* - * If the DLL's imports symbols from other - * modules, fixup the imported calls entry points. - */ - if (NTHeaders->OptionalHeader - .DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] - .VirtualAddress != 0) - { - Status = LdrFixupImports( - NTHeaders, - ImageBase - ); - if (!NT_SUCCESS(Status)) - { - dprintf("LdrFixupImports() failed\n"); - return NULL; - } - } - /* - * Compute the DLL's entry point's address. - */ - EntryPoint = (PEPFUNC) ( - ImageBase - + NTHeaders->OptionalHeader.AddressOfEntryPoint - ); - DPRINT("LdrPEStartup() = %x\n",EntryPoint); - return EntryPoint; + /* + * Overlay DOS and WNT headers structures + * to the DLL's image. + */ + DosHeader = (PIMAGE_DOS_HEADER) ImageBase; + NTHeaders = (PIMAGE_NT_HEADERS) (ImageBase + DosHeader->e_lfanew); + + /* + * Initialize image sections. + */ + LdrMapSections(NtCurrentProcess(), + ImageBase, + SectionHandle, + NTHeaders); + + /* + * If the base address is different from the + * one the DLL is actually loaded, perform any + * relocation. + */ + if (ImageBase != (PVOID) NTHeaders->OptionalHeader.ImageBase) + { + Status = LdrPerformRelocations(NTHeaders, ImageBase); + if (!NT_SUCCESS(Status)) + { + dprintf("LdrPerformRelocations() failed\n"); + return NULL; + } + } + + /* + * If the DLL's imports symbols from other + * modules, fixup the imported calls entry points. + */ + if (NTHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] + .VirtualAddress != 0) + { + DPRINT("About to fixup imports\n"); + Status = LdrFixupImports(NTHeaders, ImageBase); + if (!NT_SUCCESS(Status)) + { + dprintf("LdrFixupImports() failed\n"); + return NULL; + } + } + + /* + * Compute the DLL's entry point's address. + */ + EntryPoint = (PEPFUNC) (ImageBase + + NTHeaders->OptionalHeader.AddressOfEntryPoint); + DPRINT("LdrPEStartup() = %x\n",EntryPoint); + return EntryPoint; } NTSTATUS LdrUnloadDll(PDLL Dll) { - - PDLLMAIN_FUNC Entrypoint; - NTSTATUS Status; - - if ( Dll == NULL || Dll == &LdrDllListHead ) - return -1; - - - if ( Dll->ReferenceCount > 1 ) { - Dll->ReferenceCount--; - return STATUS_SUCCESS; - } - - if ( Dll->Headers->FileHeader.Characteristics & IMAGE_FILE_DLL == IMAGE_FILE_DLL ) { - - Entrypoint = - (PDLLMAIN_FUNC) LdrPEStartup( - Dll->BaseAddress, - Dll->SectionHandle - ); - if (Entrypoint != NULL) - { - DPRINT("Calling entry point at 0x%08x\n", Entrypoint); - if (FALSE == Entrypoint( - Dll, - DLL_PROCESS_DETACH, - NULL - )) - { - DPRINT("NTDLL.LDR: DLL failed to detach\n"); - return -1; - } - else - { - DPRINT("NTDLL.LDR: DLL detached successfully\n"); - } - } - else - { - DPRINT("NTDLL.LDR: Entrypoint is NULL for \n"); - } - - } - Status = ZwUnmapViewOfSection( - NtCurrentProcess(), - Dll->BaseAddress - ); - - ZwClose(Dll->SectionHandle); + PDLLMAIN_FUNC Entrypoint; + NTSTATUS Status; - return Status; + if ( Dll == NULL || Dll == &LdrDllListHead ) + return -1; + + + if ( Dll->ReferenceCount > 1 ) + { + Dll->ReferenceCount--; + return STATUS_SUCCESS; + } + + if ( Dll->Headers->FileHeader.Characteristics & IMAGE_FILE_DLL == IMAGE_FILE_DLL ) { + + Entrypoint = (PDLLMAIN_FUNC) LdrPEStartup(Dll->BaseAddress, + Dll->SectionHandle); + if (Entrypoint != NULL) + { + DPRINT("Calling entry point at 0x%08x\n", Entrypoint); + if (FALSE == Entrypoint(Dll, + DLL_PROCESS_DETACH, + NULL)) + { + DPRINT("NTDLL.LDR: DLL failed to detach\n"); + return -1; + } + else + { + DPRINT("NTDLL.LDR: DLL detached successfully\n"); + } + } + else + { + DPRINT("NTDLL.LDR: Entrypoint is NULL for \n"); + } + + } + Status = ZwUnmapViewOfSection(NtCurrentProcess(), + Dll->BaseAddress); + + ZwClose(Dll->SectionHandle); + + return Status; } static IMAGE_RESOURCE_DIRECTORY_ENTRY * LdrGetNextEntry(IMAGE_RESOURCE_DIRECTORY *ResourceDir, LPCWSTR ResourceName, ULONG Offset) diff --git a/reactos/ntoskrnl/ke/i386/exp.c b/reactos/ntoskrnl/ke/i386/exp.c index 707f280e7da..bd6f7763746 100644 --- a/reactos/ntoskrnl/ke/i386/exp.c +++ b/reactos/ntoskrnl/ke/i386/exp.c @@ -147,14 +147,14 @@ static void print_address(PVOID address) if (address >= current->Base && address < (current->Base + current->Length)) { - DbgPrint("<%w: %x>\n", current->Name, + DbgPrint("<%w: %x>", current->Name, address - current->Base); return; } current_entry = current_entry->Flink; } - DbgPrint("<%x>\n", address); + DbgPrint("<%x>", address); } asmlinkage void exception_handler(unsigned int edi, @@ -240,8 +240,9 @@ asmlinkage void exception_handler(unsigned int edi, DbgPrint("Exception: %d(%x)\n",type,error_code&0xffff); } DbgPrint("CS:EIP %x:%x\n",cs&0xffff,eip); - DbgPrint("CS:EIP %x"); + DbgPrint("CS:EIP %x:", cs&0xffff); print_address(eip); + DbgPrint("\n"); __asm__("movl %%cr2,%0\n\t" : "=d" (cr2)); __asm__("movl %%cr3,%0\n\t" @@ -301,6 +302,7 @@ asmlinkage void exception_handler(unsigned int edi, { // DbgPrint(" %.8x", stack[i]); print_address(stack[i]); + DbgPrint(" "); } } } @@ -323,8 +325,8 @@ asmlinkage void exception_handler(unsigned int edi, } } - DPRINT1("Killing current task\n"); - for(;;); + DbgPrint("\n"); + DbgPrint("Killing current task\n"); KeLowerIrql(PASSIVE_LEVEL); if ((cs&0xffff) == USER_CS) { diff --git a/reactos/ntoskrnl/makefile_rex b/reactos/ntoskrnl/makefile_rex index 4ace4a581d6..f5bd63cf084 100644 --- a/reactos/ntoskrnl/makefile_rex +++ b/reactos/ntoskrnl/makefile_rex @@ -1,4 +1,4 @@ -# $Id: makefile_rex,v 1.37 1999/11/15 15:56:16 ekohl Exp $ +# $Id: makefile_rex,v 1.38 1999/11/25 10:47:57 dwelch Exp $ # # ReactOS Operating System # @@ -35,7 +35,7 @@ MM_OBJECTS = mm/mm.o mm/freelist.o mm/pool.o mm/virtual.o \ mm/mdl.o mm/zone.o mm/special.o mm/paging.o \ mm/section.o mm/marea.o mm/ppool.o mm/npool.o -MM_I386_OBJECTS = mm/i386/page.o +MM_I386_OBJECTS = mm/i386/page.o mm/i386/memsafe.o IO_OBJECTS = io/iomgr.o io/create.o io/irp.o io/device.o io/rw.o \ io/queue.o io/drvlck.o io/timer.o io/share.o io/errlog.o \ diff --git a/reactos/ntoskrnl/mm/i386/memsafe.s b/reactos/ntoskrnl/mm/i386/memsafe.s new file mode 100644 index 00000000000..92887528652 --- /dev/null +++ b/reactos/ntoskrnl/mm/i386/memsafe.s @@ -0,0 +1,74 @@ +.globl _MmSafeCopyFromUser +.globl _MmSafeCopyFromUserEnd +.globl _MmSafeCopyToUser +.globl _MmSafeCopyToUserEnd + + /* + * NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, + * ULONG NumberOfBytes) + */ +_MmSafeCopyFromUser: + pushl %ebp + movl %esp,%ebp + + pushl %esi + pushl %edi + pushl %ecx + + movl 8(%ebp),%edi + movl 12(%ebp),%esi + movl 16(%ebp),%ecx + + /* + * Default return code + */ + movl $0,%eax + + /* + * This is really a synthetic instruction since if we incur a + * pagefault then eax will be set to an appropiate STATUS code + */ + rep movsb + + popl %ecx + popl %edi + popl %esi + + ret + +_MmSafeCopyFromUserEnd: + + /* + * NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, + * ULONG NumberOfBytes) + */ +_MmSafeCopyToUser: + pushl %ebp + movl %esp,%ebp + + pushl %esi + pushl %edi + pushl %ecx + + movl 8(%ebp),%edi + movl 12(%ebp),%esi + movl 16(%ebp),%ecx + + /* + * Default return code + */ + movl $0,%eax + + /* + * This is really a synthetic instruction since if we incur a + * pagefault then eax will be set to an appropiate STATUS code + */ + rep movsb + + popl %ecx + popl %edi + popl %esi + + ret + +_MemSafeCopyToUser: diff --git a/reactos/ntoskrnl/mm/marea.c b/reactos/ntoskrnl/mm/marea.c index 2d4a40d79d2..fd77ab36610 100644 --- a/reactos/ntoskrnl/mm/marea.c +++ b/reactos/ntoskrnl/mm/marea.c @@ -19,8 +19,8 @@ /* GLOBALS *******************************************************************/ -static LIST_ENTRY SystemAreaList = {NULL,NULL}; -static KSPIN_LOCK SystemAreaListLock = {0,}; +static LIST_ENTRY SystemAreaList; +static KSPIN_LOCK SystemAreaListLock; /* FUNCTIONS *****************************************************************/ @@ -573,6 +573,7 @@ NTSTATUS MmCreateMemoryArea(KPROCESSOR_MODE Mode, +(PAGESIZE*2)); if ((*BaseAddress)==0) { + DPRINT("No suitable gap\n"); MmUnlockMemoryAreaListByMode(Mode,&oldlvl); return(STATUS_UNSUCCESSFUL); } @@ -585,6 +586,7 @@ NTSTATUS MmCreateMemoryArea(KPROCESSOR_MODE Mode, *BaseAddress, Length)!=NULL) { + DPRINT("Memory area already occupied\n"); MmUnlockMemoryAreaList(*BaseAddress,&oldlvl); return(STATUS_UNSUCCESSFUL); } diff --git a/reactos/ntoskrnl/mm/section.c b/reactos/ntoskrnl/mm/section.c index 5e65c9e0d93..6ef667cc800 100644 --- a/reactos/ntoskrnl/mm/section.c +++ b/reactos/ntoskrnl/mm/section.c @@ -1,4 +1,4 @@ -/* $Id: section.c,v 1.16 1999/11/24 11:51:52 dwelch Exp $ +/* $Id: section.c,v 1.17 1999/11/25 10:47:57 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -366,6 +366,8 @@ NTSTATUS STDCALL NtMapViewOfSection(HANDLE SectionHandle, NULL); if (!NT_SUCCESS(Status)) { + DPRINT("ObReferenceObjectByHandle(ProcessHandle, ...) failed (%x)\n", + Status); ObDereferenceObject(Section); return Status; } diff --git a/reactos/ntoskrnl/mm/virtual.c b/reactos/ntoskrnl/mm/virtual.c index e672c4f67f7..219d9594bd9 100644 --- a/reactos/ntoskrnl/mm/virtual.c +++ b/reactos/ntoskrnl/mm/virtual.c @@ -568,14 +568,21 @@ NTSTATUS STDCALL NtWriteVirtualMemory(IN HANDLE ProcessHandle, KeAttachProcess(Process); + DPRINT("Attached to process copying memory\n"); + SystemAddress = MmGetSystemAddressForMdl(Mdl); memcpy(BaseAddress, SystemAddress, NumberOfBytesToWrite); + DPRINT("Done copy\n"); + KeDetachProcess(); ObDereferenceObject(Process); *NumberOfBytesWritten = NumberOfBytesToWrite; + + DPRINT("Finished NtWriteVirtualMemory()\n"); + return(STATUS_SUCCESS); } diff --git a/reactos/ntoskrnl/nt/port.c b/reactos/ntoskrnl/nt/port.c index 0b329bc52cf..0428eea94a6 100644 --- a/reactos/ntoskrnl/nt/port.c +++ b/reactos/ntoskrnl/nt/port.c @@ -1,4 +1,4 @@ -/* $Id: port.c,v 1.9 1999/11/24 11:51:53 dwelch Exp $ +/* $Id: port.c,v 1.10 1999/11/25 10:47:58 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -25,14 +25,17 @@ #include #include +//#define NDEBUG #include /* TYPES ********************************************************************/ -#define EPORT_WAIT_FOR_CONNECT (1) -#define EPORT_WAIT_FOR_ACCEPT (2) -#define EPORT_WAIT_FOR_COMPLETE (3) -#define EPORT_CONNECTED (4) +#define EPORT_INACTIVE (0) +#define EPORT_WAIT_FOR_CONNECT (1) +#define EPORT_WAIT_FOR_ACCEPT (2) +#define EPORT_WAIT_FOR_COMPLETE_SRV (3) +#define EPORT_WAIT_FOR_COMPLETE_CLT (4) +#define EPORT_CONNECTED (5) typedef struct _QUEUED_MESSAGE { @@ -41,7 +44,6 @@ typedef struct _QUEUED_MESSAGE PVOID Buffer; DWORD Flags; PEPROCESS Sender; - PMDL BufferMdl; } QUEUED_MESSAGE, *PQUEUED_MESSAGE; typedef struct _EPORT @@ -49,8 +51,11 @@ typedef struct _EPORT KSPIN_LOCK Lock; ULONG State; KEVENT Event; - struct _EPORT* ForeignPort; + struct _EPORT* OtherPort; + ULONG NumberOfQueuedMessages; QUEUED_MESSAGE Msg; + PEPROCESS ConnectingProcess; + struct _EPORT* ConnectingPort; } EPORT, *PEPORT; /* GLOBALS *******************************************************************/ @@ -84,6 +89,18 @@ NTSTATUS NiInitPort(VOID) return(STATUS_SUCCESS); } +static NTSTATUS NiInitializePort(PEPORT Port) +{ + memset(Port, 0, sizeof(EPORT)); + KeInitializeSpinLock(&Port->Lock); + KeInitializeEvent(&Port->Event, NotificationEvent, FALSE); + Port->State = EPORT_INACTIVE; + Port->OtherPort = NULL; + Port->NumberOfQueuedMessages = 0; + + return(STATUS_SUCCESS); +} + NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, @@ -91,9 +108,10 @@ NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, DWORD a4) { PEPORT Port; + NTSTATUS Status; Port = ObCreateObject(PortHandle, - DesiredAccess, + 1, // DesiredAccess ObjectAttributes, ExPortType); if (Port == NULL) @@ -101,53 +119,60 @@ NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, return(STATUS_UNSUCCESSFUL); } - KeInitializeSpinLock(&Port->Lock); - KeInitializeEvent(&Port->Event, NotificationEvent, FALSE); - Port->State = EPORT_WAIT_FOR_CONNECT; - Port->ForeignPort = NULL; + Status = NiInitializePort(Port); - return(STATUS_SUCCESS); + return(Status); } -NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE PortHandle, - OUT PHANDLE ConnectedPort, - DWORD a2, +NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE PortHandle, + OUT PHANDLE OurPortHandle, + DWORD a2, DWORD a3, DWORD a4, DWORD a5) { NTSTATUS Status; - PEPORT Port; + PEPORT NamedPort; + PEPORT OurPort; Status = ObReferenceObjectByHandle(PortHandle, - 0, /* AccessRequired */ + 1, /* AccessRequired */ ExPortType, UserMode, - (PVOID*)&Port, + (PVOID*)&NamedPort, NULL); if (!NT_SUCCESS(Status)) { return(Status); } - if (Port->State != EPORT_WAIT_FOR_ACCEPT) + if (NamedPort->State != EPORT_WAIT_FOR_ACCEPT) { + ObDereferenceObject(NamedPort); return(STATUS_INVALID_PARAMETER); } - Status = ObCreateHandle(PsGetCurrentProcess(), - Port->ForeignPort, - 0, /* DesiredAccess */ - FALSE, - ConnectedPort); - if (!NT_SUCCESS(Status)) - { - return(Status); - } + /* + * Create a port object for our side of the connection + */ + OurPort = ObCreateObject(OurPortHandle, + 1, + NULL, + ExPortType); - KeSetEvent(&Port->ForeignPort->Event, IO_NO_INCREMENT, FALSE); + /* + * Connect the two port + */ + OurPort->OtherPort = NamedPort->ConnectingPort; + OurPort->OtherPort->OtherPort = OurPort; + OurPort->State = EPORT_WAIT_FOR_COMPLETE_SRV; + OurPort->OtherPort->State = EPORT_WAIT_FOR_COMPLETE_CLT; - Port->ForeignPort->State = EPORT_WAIT_FOR_COMPLETE; + NamedPort->State = EPORT_INACTIVE; + NamedPort->ConnectingProcess = NULL; + NamedPort->ConnectingPort = NULL; + + ObDereferenceObject(NamedPort); return(STATUS_SUCCESS); } @@ -156,23 +181,29 @@ NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE PortHandle, NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle) { NTSTATUS Status; - PEPORT Port; + PEPORT OurPort; Status = ObReferenceObjectByHandle(PortHandle, - 0, /* AccessRequired */ + 1, /* AccessRequired */ ExPortType, UserMode, - (PVOID*)&Port, + (PVOID*)&OurPort, NULL); if (!NT_SUCCESS(Status)) { return(Status); } - Port->ForeignPort->State = EPORT_CONNECTED; - Port->State = EPORT_CONNECTED; + if (OurPort->State != EPORT_WAIT_FOR_COMPLETE_SRV) + { + ObDereferenceObject(OurPort); + return(Status); + } - KeSetEvent(&Port->ForeignPort->Event, IO_NO_INCREMENT, FALSE); + OurPort->State = EPORT_CONNECTED; + OurPort->OtherPort->State = EPORT_CONNECTED; + + KeSetEvent(&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE); return(STATUS_SUCCESS); } @@ -186,46 +217,66 @@ NTSTATUS STDCALL NtConnectPort (OUT PHANDLE ConnectedPort, IN DWORD a5, IN DWORD a6, IN ULONG Flags) +/* + * FUNCTION: Connect to a named port and wait for the other side to + * accept the connection + */ { NTSTATUS Status; - PEPORT ForeignPort; - PEPORT Port; + PEPORT NamedPort; + PEPORT OurPort; + HANDLE OurPortHandle; Status = ObReferenceObjectByName(PortName, 0, NULL, - 0, /* DesiredAccess */ + 1, /* DesiredAccess */ ExPortType, UserMode, NULL, - (PVOID*)&ForeignPort); + (PVOID*)&NamedPort); if (!NT_SUCCESS(Status)) { return(Status); } - if (ForeignPort->State != EPORT_WAIT_FOR_CONNECT) + if (NamedPort->State != EPORT_WAIT_FOR_CONNECT) { + ObDereferenceObject(NamedPort); return(STATUS_UNSUCCESSFUL); } - Port = ObCreateObject(ConnectedPort, - 0, /* DesiredAccess */ - PortAttributes, - ExPortType); - if (Port == NULL) - { - return(STATUS_UNSUCCESSFUL); - } + /* + * Create a port to represent our side of the connection + */ + OurPort = ObCreateObject(&OurPortHandle, + 1, + PortAttributes, + ExPortType); + NiInitializePort(OurPort); - KeInitializeSpinLock(&Port->Lock); - KeInitializeEvent(&Port->Event, NotificationEvent, FALSE); - Port->State = EPORT_WAIT_FOR_ACCEPT; - Port->ForeignPort = ForeignPort; + /* + * + */ + NamedPort->ConnectingProcess = PsGetCurrentProcess(); + NamedPort->State = EPORT_WAIT_FOR_ACCEPT; + NamedPort->ConnectingPort = OurPort; - ForeignPort->State = EPORT_WAIT_FOR_ACCEPT; + /* + * Tell the other side they have a connection + */ + KeSetEvent(&NamedPort->Event, IO_NO_INCREMENT, FALSE); - KeSetEvent(&ForeignPort->Event, IO_NO_INCREMENT, FALSE); + /* + * Wait for them to accept our connection + */ + KeWaitForSingleObject(&NamedPort->Event, + UserRequest, + UserMode, + FALSE, + NULL); + + *ConnectedPort = OurPortHandle; return(STATUS_SUCCESS); } @@ -240,21 +291,36 @@ NTSTATUS STDCALL NtImpersonateClientOfPort (IN HANDLE PortHandle, NTSTATUS STDCALL NtListenPort (IN HANDLE PortHandle, IN DWORD QueueSize /* guess */) +/* + * FUNCTION: Listen on a named port and wait for a connection attempt + */ { NTSTATUS Status; PEPORT Port; + DPRINT("NtListenPort(PortHandle %x, QueueSize %d)\n", + PortHandle, QueueSize); + Status = ObReferenceObjectByHandle(PortHandle, - 0, /* AccessRequired */ + 1, /* AccessRequired */ ExPortType, UserMode, (PVOID*)&Port, NULL); if (!NT_SUCCESS(Status)) { + DPRINT("Failed to reference object (status %x)\n", + Status); return(Status); } + if (Port->State != EPORT_INACTIVE) + { + ObDereferenceObject(Port); + return(STATUS_INVALID_PARAMETER); + } + + Port->State = EPORT_WAIT_FOR_CONNECT; Status = KeWaitForSingleObject(&Port->Event, UserRequest, UserMode, @@ -276,14 +342,14 @@ NTSTATUS STDCALL NtQueryInformationPort (IN HANDLE PortHandle, NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle, - IN PLPC_REPLY LpcReply /* guess */) + IN PLPC_MESSAGE LpcReply /* guess */) { UNIMPLEMENTED; } NTSTATUS STDCALL NtReplyWaitReceivePort ( IN HANDLE PortHandle, - IN PLPC_REPLY LpcReply, /* guess */ + IN PLPC_MESSAGE LpcReply, /* guess */ OUT PLPC_MESSAGE LpcMessage, /* guess */ OUT PULONG MessageLength /* guess */) { @@ -292,7 +358,7 @@ NTSTATUS STDCALL NtReplyWaitReceivePort ( IN HANDLE PortHandle, NTSTATUS STDCALL NtReplyWaitReplyPort (IN HANDLE PortHandle, - IN OUT PLPC_REPLY LpcReply /* guess */) + IN OUT PLPC_MESSAGE LpcReply /* guess */) { UNIMPLEMENTED; } @@ -301,11 +367,19 @@ NTSTATUS STDCALL NtReplyWaitReplyPort (IN HANDLE PortHandle, NTSTATUS STDCALL NtRequestPort (IN HANDLE PortHandle, IN PLPC_MESSAGE LpcMessage /* guess */) { - NTSTATUS Status; + return(NtRequestWaitReplyPort(PortHandle, NULL, LpcMessage)); +} + + +NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle, + IN OUT PLPC_MESSAGE LpcReply, /* guess */ + OUT PLPC_MESSAGE LpcMessage /* guess */) +{ + NTSTATUS Status; PEPORT Port; Status = ObReferenceObjectByHandle(PortHandle, - 0, /* AccessRequired */ + 1, /* AccessRequired */ ExPortType, UserMode, (PVOID*)&Port, @@ -315,29 +389,61 @@ NTSTATUS STDCALL NtRequestPort (IN HANDLE PortHandle, return(Status); } - Port->Msg.Type = LpcMessage->Type; - Port->Msg.Length = LpcMessage->Length; - Port->Msg.Buffer = LpcMessage->Buffer; - Port->Msg.Flags = LpcMessage->Flags; - Port->Msg.Sender = PsGetCurrentProcess(); - Port->Msg.BufferMdl = MmCreateMdl(NULL, - LpcMessage->Buffer, - LpcMessage->Length); - MmProbeAndLockPages(Port->Msg.BufferMdl, - UserMode, - IoReadAccess); + if (LpcMessage != NULL) + { + /* + * Put the message on the other port's queue + */ + Port->Msg.Type = LpcMessage->Type; + Port->Msg.Length = LpcMessage->Length; + Port->Msg.Buffer = ExAllocatePool(NonPagedPool, Port->Msg.Length); + memcpy(Port->Msg.Buffer, LpcMessage->Buffer, Port->Msg.Length); + Port->Msg.Flags = LpcMessage->Flags; + Port->Msg.Sender = PsGetCurrentProcess(); + Port->NumberOfQueuedMessages++; + + /* + * Wake up the other side (if it's waiting) + */ + KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE); + + } + + /* + * If we aren't waiting for a reply then return + */ + if (LpcReply == NULL) + { + ObDereferenceObject(Port); + return(STATUS_SUCCESS); + } + + /* + * Wait the other side to reply to you + */ + KeWaitForSingleObject(&Port->Event, + UserRequest, + UserMode, + FALSE, + NULL); + + /* + * Copy the received message into the process's address space + */ + LpcReply->Length = Port->OtherPort->Msg.Length; + LpcReply->Type = Port->OtherPort->Msg.Type; + memcpy(LpcReply->Buffer, Port->OtherPort->Msg.Buffer, LpcReply->Length); + LpcReply->Flags = Port->OtherPort->Msg.Flags; + + /* + * Deallocate the message and remove it from the other side's queue + */ + ExFreePool(Port->OtherPort->Msg.Buffer); + Port->OtherPort->NumberOfQueuedMessages--; return(STATUS_SUCCESS); } - -NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle, - IN OUT PLPC_REPLY LpcReply, /* guess */ - IN TIME* TimeToWait /* guess */) -{ - UNIMPLEMENTED; -} - /********************************************************************** * NAME SYSTEM diff --git a/reactos/subsys/smss/init.c b/reactos/subsys/smss/init.c index cc862b831fb..df68fd4480d 100644 --- a/reactos/subsys/smss/init.c +++ b/reactos/subsys/smss/init.c @@ -1,4 +1,4 @@ -/* $Id: init.c,v 1.2 1999/10/24 17:07:57 rex Exp $ +/* $Id: init.c,v 1.3 1999/11/25 10:47:58 dwelch Exp $ * * init.c - Session Manager initialization * @@ -63,6 +63,7 @@ InitSessionManager( #endif /* Start the simple shell (shell.exe) */ + DisplayString(L"Executing shell\n"); RtlInitUnicodeString(&CmdLineW, L"\\??\\C:\\reactos\\system32\\shell.exe"); Status = RtlCreateUserProcess(&CmdLineW,