diff --git a/reactos/apps/tests/args/makefile b/reactos/apps/tests/args/makefile index aec04882487..c39a84774b9 100644 --- a/reactos/apps/tests/args/makefile +++ b/reactos/apps/tests/args/makefile @@ -35,7 +35,7 @@ else $(CP) $* ../../$(DIST_DIR)/apps/$* endif -args.exe: $(OBJECTS) $(LIBS) +args.exe: $(OBJECTS) $(CC) $(OBJECTS) -o args.exe $(NM) --numeric-sort args.exe > args.sym diff --git a/reactos/apps/tests/hello/hello.c b/reactos/apps/tests/hello/hello.c index 294b00c86a7..e178e982e17 100644 --- a/reactos/apps/tests/hello/hello.c +++ b/reactos/apps/tests/hello/hello.c @@ -1,10 +1,8 @@ #include -#include + int main(int argc, char* argv[]) { - UNICODE_STRING UnicodeString; - RtlInitUnicodeString(&UnicodeString,L"Hello world\n"); - NtDisplayString(&UnicodeString); + printf("Hello world\n"); return(0); } diff --git a/reactos/apps/tests/hello/makefile b/reactos/apps/tests/hello/makefile index e4e6176dca1..954f6d49dd8 100644 --- a/reactos/apps/tests/hello/makefile +++ b/reactos/apps/tests/hello/makefile @@ -1,11 +1,10 @@ # # # -OBJECTS = ../common/crt0.o hello.o +OBJECTS = hello.o PROGS = hello.exe -LIBS = ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a +LIBS = CLEAN_FILES = hello.o hello.exe -BASE_CFLAGS = -I../../include all: hello.exe @@ -34,7 +33,7 @@ else $(CP) $* ../../$(DIST_DIR)/apps/$* endif -hello.exe: $(OBJECTS) $(LIBS) - $(LD) $(OBJECTS) $(LIBS) -o hello.exe +hello.exe: $(OBJECTS) + $(CC) $(OBJECTS) -o hello.exe include ../../rules.mak diff --git a/reactos/apps/tests/lpc/lpcclt.c b/reactos/apps/tests/lpc/lpcclt.c index ef8500cca58..92abb31a8a2 100644 --- a/reactos/apps/tests/lpc/lpcclt.c +++ b/reactos/apps/tests/lpc/lpcclt.c @@ -23,8 +23,7 @@ void main(int argc, char* argv[]) UNICODE_STRING PortName; NTSTATUS Status; HANDLE PortHandle; - LPC_MESSAGE Request; - char buffer[255]; + LPCMESSAGE Request; printf("(lpcclt.exe) Lpc client\n"); @@ -37,7 +36,7 @@ void main(int argc, char* argv[]) 0, 0, 0, - 0, + NULL, 0); if (!NT_SUCCESS(Status)) { @@ -45,14 +44,12 @@ void main(int argc, char* argv[]) return; } - strcpy(buffer, GetCommandLineA()); - Request.Buffer = buffer; - Request.Length = strlen(buffer); + strcpy(Request.MessageData, GetCommandLineA()); + Request.ActualMessageLength = strlen(Request.MessageData); + Request.TotalMessageLength = sizeof(LPCMESSAGE); printf("(lpcclt.exe) Sending message\n"); - Status = NtRequestWaitReplyPort(PortHandle, - NULL, - &Request); + Status = NtRequestPort(PortHandle, &Request); if (!NT_SUCCESS(Status)) { printf("(lpcclt.exe) Failed to send request\n"); diff --git a/reactos/apps/tests/lpc/lpcsrv.c b/reactos/apps/tests/lpc/lpcsrv.c index edb668a3177..a281312bc65 100644 --- a/reactos/apps/tests/lpc/lpcsrv.c +++ b/reactos/apps/tests/lpc/lpcsrv.c @@ -25,6 +25,7 @@ void main(int argc, char* argv[]) NTSTATUS Status; HANDLE NamedPortHandle; HANDLE PortHandle; + LPCMESSAGE ConnectMsg; printf("(lpcsrv.exe) Lpc test server\n"); @@ -37,9 +38,9 @@ void main(int argc, char* argv[]) printf("(lpcsrv.exe) Creating port\n"); Status = NtCreatePort(&NamedPortHandle, - 0, &ObjectAttributes, 0, + 0, 0); if (!NT_SUCCESS(Status)) { @@ -50,7 +51,7 @@ void main(int argc, char* argv[]) printf("(lpcsrv.exe) Listening for connections\n"); Status = NtListenPort(NamedPortHandle, - 0); + &ConnectMsg); if (!NT_SUCCESS(Status)) { printf("(lpcsrv.exe) Failed to listen for connections\n"); @@ -58,12 +59,12 @@ void main(int argc, char* argv[]) } printf("(lpcsrv.exe) Accepting connections\n"); - Status = NtAcceptConnectPort(NamedPortHandle, - &PortHandle, + Status = NtAcceptConnectPort(&PortHandle, + NamedPortHandle, + NULL, + 1, 0, - 0, - 0, - 0); + NULL); if (!NT_SUCCESS(Status)) { printf("(lpcsrv.exe) Failed to accept connection\n"); @@ -80,20 +81,18 @@ void main(int argc, char* argv[]) for(;;) { - LPC_MESSAGE Request; - char buffer[255]; + LPCMESSAGE Request; - Request.Buffer = buffer; - - Status = NtRequestWaitReplyPort(PortHandle, - &Request, - NULL); + Status = NtReplyWaitReceivePort(PortHandle, + 0, + NULL, + &Request); if (!NT_SUCCESS(Status)) { printf("(lpcsrv.exe) Failed to receive request\n"); return; } - printf("(lpcsrv.exe) Message contents are <%s>\n", Request.Buffer); + printf("(lpcsrv.exe) Message contents are <%s>\n", Request.MessageData); } } diff --git a/reactos/apps/utils/cat/cat.c b/reactos/apps/utils/cat/cat.c index 441b5b3d82d..305828e0f72 100644 --- a/reactos/apps/utils/cat/cat.c +++ b/reactos/apps/utils/cat/cat.c @@ -10,6 +10,12 @@ int main(int argc, char* argv[]) for (i=1; i args.sym + $(NM) --numeric-sort cat.exe > cat.sym include ../../rules.mak diff --git a/reactos/drivers/dd/blue/blue.c b/reactos/drivers/dd/blue/blue.c index d0cb02f89e7..43cf63a12d1 100644 --- a/reactos/drivers/dd/blue/blue.c +++ b/reactos/drivers/dd/blue/blue.c @@ -1,4 +1,4 @@ -/* $Id: blue.c,v 1.14 1999/12/06 06:43:45 phreak Exp $ +/* $Id: blue.c,v 1.15 1999/12/10 17:04:37 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -25,7 +25,7 @@ #define IDMAP_BASE 0xd0000000 #define VIDMEM_BASE 0xb8000 -#define NR_ROWS 25 +#define NR_ROWS 50 #define NR_COLUMNS 80 #define NR_SCANLINES 8 diff --git a/reactos/include/ddk/psfuncs.h b/reactos/include/ddk/psfuncs.h index a910eedae0a..6d962137071 100644 --- a/reactos/include/ddk/psfuncs.h +++ b/reactos/include/ddk/psfuncs.h @@ -1,6 +1,7 @@ HANDLE PsGetCurrentProcessId(VOID); +HANDLE PsGetCurrentThreadId(VOID); /* * FUNCTION: Creates a thread which executes in kernel mode diff --git a/reactos/include/ddk/pstypes.h b/reactos/include/ddk/pstypes.h index bb473407844..2c5a23f4e72 100644 --- a/reactos/include/ddk/pstypes.h +++ b/reactos/include/ddk/pstypes.h @@ -232,8 +232,6 @@ typedef struct _KTHREAD /* Provisionally added by David Welch */ hal_thread_state Context; -// LIST_ENTRY Entry; -// ULONG LastTick; } KTHREAD, *PKTHREAD; diff --git a/reactos/include/ddk/zw.h b/reactos/include/ddk/zw.h index 26aa51a9866..7146e088e96 100644 --- a/reactos/include/ddk/zw.h +++ b/reactos/include/ddk/zw.h @@ -1,4 +1,5 @@ -/* $Id: zw.h,v 1.22 1999/12/06 00:14:47 ekohl Exp $ + +/* $Id: zw.h,v 1.23 1999/12/10 17:04:33 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -5169,50 +5170,40 @@ ZwYieldExecution( * These prototypes are unknown as yet * (stack sizes by Peter-Michael Hager) */ -NTSTATUS -STDCALL -NtAcceptConnectPort ( /* @24 */ - IN HANDLE PortHandle, - OUT PHANDLE ConnectedPort, - IN DWORD Unknown2, - IN DWORD Unknown3, - IN DWORD Unknown4, - IN DWORD Unknown5 - ); -NTSTATUS -STDCALL -NtCompleteConnectPort ( /* @4 */ - IN HANDLE PortHandle - ); -NTSTATUS -STDCALL -NtConnectPort ( - OUT PHANDLE PortHandle, - IN PUNICODE_STRING PortName, - IN POBJECT_ATTRIBUTES PortAttributes, - IN DWORD Unknown3, - IN DWORD Unknown4, - IN DWORD Unknown5, - IN DWORD Unknown6, - IN ULONG Flags - ); +NTSTATUS STDCALL NtAcceptConnectPort (PHANDLE PortHandle, + HANDLE NamedPortHandle, + PLPCMESSAGE ServerReply, + ULONG AcceptIt, + ULONG Unknown3, + PLPCSECTIONMAPINFO MapInfo); + +NTSTATUS STDCALL NtCompleteConnectPort (IN HANDLE PortHandle); + +NTSTATUS STDCALL NtConnectPort(OUT PHANDLE PortHandle, + IN PUNICODE_STRING PortName, + IN PVOID Unknown1, + IN PLPCSECTIONINFO SectionInfo, + IN PLPCSECTIONMAPINFO MapInfo, + IN PVOID Unknown2, + IN PVOID ConnectInfo, + IN PULONG ConnectInfoLength); + +NTSTATUS STDCALL NtReplyWaitReplyPort(PVOID Unknown1, + PVOID Unknown2); + + NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, - ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, - DWORD a3, - DWORD a4); -NTSTATUS -STDCALL -NtImpersonateClientOfPort ( /* @8 */ - IN HANDLE PortHandle, - IN PCLIENT_ID ClientId - ); -NTSTATUS -STDCALL -NtListenPort ( /* @8 */ - IN HANDLE PortHAndle, - IN DWORD QueueSize /* guess */ - ); + ULONG MaxConnectInfoLength, + ULONG MaxDataLength, + ULONG Unknown1); + +NTSTATUS STDCALL NtImpersonateClientOfPort (IN HANDLE PortHandle, + IN PLPCMESSAGE ClientMessage); + +NTSTATUS STDCALL NtListenPort (IN HANDLE PortHAndle, + IN PLPCMESSAGE LpcMessage); + NTSTATUS STDCALL NtQueryInformationPort ( /* @20 */ @@ -5222,39 +5213,17 @@ NtQueryInformationPort ( /* @20 */ IN ULONG PortInformationLength, /* guess */ OUT PULONG ReturnLength /* guess */ ); -NTSTATUS -STDCALL -NtReplyPort ( /* @8 */ - IN HANDLE PortHandle, - IN PLPC_MESSAGE LpcReply /* guess */ - ); -NTSTATUS -STDCALL -NtReplyWaitReceivePort ( /* @16 */ - IN HANDLE PortHandle, - IN PLPC_MESSAGE LpcReply, /* guess */ - OUT PLPC_MESSAGE LpcMessage, /* guess */ - OUT PULONG MessageLength /* guess */ - ); -NTSTATUS -STDCALL -NtReplyWaitReplyPort ( /* @8 */ - IN HANDLE PortHandle, - IN OUT PLPC_MESSAGE LpcReply /* guess */ - ); -NTSTATUS -STDCALL -NtRequestPort ( /* @8 */ - IN HANDLE PortHandle, - IN PLPC_MESSAGE LpcMessage /* guess */ - ); -NTSTATUS -STDCALL -NtRequestWaitReplyPort ( /* @12 */ - IN HANDLE PortHandle, - IN OUT PLPC_MESSAGE LpcReply, /* guess */ - OUT PLPC_MESSAGE LpcRequest /* guess */ - ); +NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle, + IN PLPCMESSAGE LpcReply); +NTSTATUS STDCALL NtReplyWaitReceivePort (IN HANDLE PortHandle, + PVOID Unknown1, + PLPCMESSAGE MessageReply, + PLPCMESSAGE MessageRequest); +NTSTATUS STDCALL NtRequestPort ( IN HANDLE PortHandle, + IN PLPCMESSAGE LpcMessage); +NTSTATUS STDCALL NtRequestWaitReplyPort (IN HANDLE PortHandle, + IN OUT PLPCMESSAGE LpcReply, + OUT PLPCMESSAGE LpcRequest); NTSTATUS STDCALL NtReadRequestData ( /* @24 */ diff --git a/reactos/include/ddk/zwtypes.h b/reactos/include/ddk/zwtypes.h index 336fc0fe581..6fa911dec72 100644 --- a/reactos/include/ddk/zwtypes.h +++ b/reactos/include/ddk/zwtypes.h @@ -1,23 +1,49 @@ #ifndef __INCLUDE_DDK_ZWTYPES_H #define __INCLUDE_DDK_ZWTYPES_H -typedef -enum { - LpcMessageTypeUnknown, /* invalid */ - LpcMessageTypeBase, /* <256 bytes */ - LpcMessageTypeLarge, /* >255 bytes */ - LpcMessageTypeFast, /* 3.51 GDI */ - LpcMessageTypeMaximum +#define MAX_MESSAGE_DATA (0x130) -} LPC_MESSAGE_TYPE; +#define UNUSED_MSG_TYPE (0x0) +#define LPC_REQUEST (0x1) +#define LPC_REPLY (0x2) +#define LPC_DATAGRAM (0x3) +#define LPC_LOST_REPLY (0x4) +#define LPC_PORT_CLOSED (0x5) +#define LPC_CLIENT_DIED (0x6) +#define LPC_EXCEPTION (0x7) +#define LPC_DEBUG_EVENT (0x8) +#define LPC_ERROR_EVENT (0x9) +#define LPC_CONNECTION_REQUEST (0xa) +#define LPC_CONNECTION_REFUSED (0xb) -typedef struct _LPC_MESSAGE +typedef struct _LPCSECTIONINFO { - LPC_MESSAGE_TYPE Type; - ULONG Length; - PVOID Buffer; /* Page aligned! */ - DWORD Flags; /* To be defined */ -} LPC_MESSAGE, * PLPC_MESSAGE; + DWORD Length; + HANDLE SectionHandle; + DWORD Unknown1; + DWORD SectionSize; + DWORD ClientBaseAddress; + DWORD ServerBaseAddress; +} LPCSECTION, *PLPCSECTIONINFO; + +typedef struct _LPCSECTIONMAPINFO +{ + DWORD Length; + DWORD SectionSize; + DWORD ServerBaseAddress; +} LPCSECTIONMAPINFO, *PLPCSECTIONMAPINFO; + +typedef struct _LPCMESSAGE +{ + WORD ActualMessageLength; + WORD TotalMessageLength; + DWORD MessageType; + DWORD ClientProcessId; + DWORD ClientThreadId; + DWORD MessageId; + DWORD SharedSectionSize; + BYTE MessageData[MAX_MESSAGE_DATA]; +} LPCMESSAGE, *PLPCMESSAGE; #define NtCurrentProcess() ( (HANDLE) 0xFFFFFFFF ) diff --git a/reactos/include/internal/mm.h b/reactos/include/internal/mm.h index 2400c6b92ab..995d5a161cd 100644 --- a/reactos/include/internal/mm.h +++ b/reactos/include/internal/mm.h @@ -116,5 +116,6 @@ PVOID MiTryToSharePageInSection(PSECTION_OBJECT Section, ULONG Offset); NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); +VOID MmInitPagingFile(VOID); #endif diff --git a/reactos/ntoskrnl/hal/x86/spinlock.c b/reactos/ntoskrnl/hal/x86/spinlock.c index 21bf6e10205..72ab20671d2 100644 --- a/reactos/ntoskrnl/hal/x86/spinlock.c +++ b/reactos/ntoskrnl/hal/x86/spinlock.c @@ -67,7 +67,11 @@ VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock) * SpinLock = Spinlock to acquire */ { - while(InterlockedExchange(&SpinLock->Lock, 1) == 1) + if (SpinLock->Lock == 1) + { + DbgPrint("May be acquiring locked spinlock\n"); + } + while (InterlockedExchange(&SpinLock->Lock, 1) == 1) { DbgPrint("Spinning on spinlock\n"); KeBugCheck(0); diff --git a/reactos/ntoskrnl/ke/dpc.c b/reactos/ntoskrnl/ke/dpc.c index fcc18c7b94f..414e7a4c002 100644 --- a/reactos/ntoskrnl/ke/dpc.c +++ b/reactos/ntoskrnl/ke/dpc.c @@ -64,9 +64,10 @@ void KeDrainDpcQueue(void) } DPRINT("KeDrainDpcQueue()\n"); + KeRaiseIrql(HIGH_LEVEL, &oldlvl); KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); - KeRaiseIrql(HIGH_LEVEL,&oldlvl); current_entry = RemoveHeadList(&DpcQueueHead); + KeReleaseSpinLockFromDpcLevel(&DpcQueueLock); KeLowerIrql(oldlvl); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); while (current_entry!=(&DpcQueueHead)) @@ -80,15 +81,16 @@ void KeDrainDpcQueue(void) current->SystemArgument2); CHECKPOINT; current->Lock=FALSE; - KeRaiseIrql(HIGH_LEVEL,&oldlvl); + KeRaiseIrql(HIGH_LEVEL, &oldlvl); + KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); current_entry = RemoveHeadList(&DpcQueueHead); DPRINT("current_entry %x\n", current_entry); DpcQueueSize--; + KeReleaseSpinLockFromDpcLevel(&DpcQueueLock); KeLowerIrql(oldlvl); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); DPRINT("current %x\n", current); } - KeReleaseSpinLockFromDpcLevel(&DpcQueueLock); } BOOLEAN KeRemoveQueueDpc(PKDPC Dpc) diff --git a/reactos/ntoskrnl/makefile_rex b/reactos/ntoskrnl/makefile_rex index f5bd63cf084..64c9e9d127d 100644 --- a/reactos/ntoskrnl/makefile_rex +++ b/reactos/ntoskrnl/makefile_rex @@ -1,4 +1,4 @@ -# $Id: makefile_rex,v 1.38 1999/11/25 10:47:57 dwelch Exp $ +# $Id: makefile_rex,v 1.39 1999/12/10 17:04:35 dwelch Exp $ # # ReactOS Operating System # @@ -33,7 +33,7 @@ KE_I386_OBJECTS = ke/i386/thread.o ke/i386/usercall.o ke/i386/exp.o 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/section.o mm/marea.o mm/ppool.o mm/npool.o mm/pagefile.o MM_I386_OBJECTS = mm/i386/page.o mm/i386/memsafe.o diff --git a/reactos/ntoskrnl/mm/mm.c b/reactos/ntoskrnl/mm/mm.c index 346e9fce267..142acad4406 100644 --- a/reactos/ntoskrnl/mm/mm.c +++ b/reactos/ntoskrnl/mm/mm.c @@ -121,6 +121,7 @@ VOID MmInitVirtualMemory(boot_param* bp) // while (inb_p(0x60)!=0x1); inb_p(0x60); MmInitSectionImplementation(); + MmInitPagingFile(); } NTSTATUS MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address) diff --git a/reactos/ntoskrnl/mm/pagefile.c b/reactos/ntoskrnl/mm/pagefile.c new file mode 100644 index 00000000000..2c96adc47c2 --- /dev/null +++ b/reactos/ntoskrnl/mm/pagefile.c @@ -0,0 +1,247 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/mm/pagefile.c + * PURPOSE: Paging file functions + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#include +#include + +#include + +/* TYPES *********************************************************************/ + +typedef ULONG SWAPENTRY; + +typedef struct _PPAGINGFILE +{ + LIST_ENTRY PagingFileListEntry; + PFILE_OBJECT FileObject; + ULONG MaximumSize; + ULONG CurrentSize; + ULONG FreePages; + ULONG UsedPages; + PULONG AllocMap; + KSPIN_LOCK AllocMapLock; + ULONG AllocMapSize; +} PAGINGFILE, *PPAGINGFILE; + +/* GLOBALS *******************************************************************/ + +#define MAX_PAGING_FILES (32) + +static PPAGINGFILE PagingFileList[MAX_PAGING_FILES]; +static KSPIN_LOCK PagingFileListLock; + +static ULONG MiFreeSwapPages; +static ULONG MiUsedSwapPages; +static ULONG MiReservedSwapPages; + +/* FUNCTIONS *****************************************************************/ + +VOID MmInitPagingFile(VOID) +{ + KeInitializeSpinLock(&PagingFileListLock); + + MiFreeSwapPages = 0; + MiUsedSwapPages = 0; + MiReservedSwapPages = 0; +} + +VOID MmReserveSwapPages(ULONG Nr) +{ + KIRQL oldIrql; + + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + MiReservedSwapPages = MiReservedSwapPages + Nr; + MiFreeSwapPages = MiFreeSwapPages - Nr; + KeReleaseSpinLock(&PagingFileListLock, oldIrql); +} + +VOID MmDereserveSwapPages(ULONG Nr) +{ + KIRQL oldIrql; + + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + MiReservedSwapPages = MiReservedSwapPages - Nr; + MiFreeSwapPages = MiFreeSwapPages - Nr; + KeReleaseSpinLock(&PagingFileListLock, oldIrql); +} + +ULONG MiAllocPageFromPagingFile(PPAGINGFILE PagingFile) +{ + KIRQL oldIrql; + ULONG i; + ULONG off; + + KeAcquireSpinLock(&PagingFile->AllocMapLock, &oldIrql); + + for (i = 0; i < PagingFile->AllocMapSize; i++) + { + off = find_first_zero_bit(PagingFile->AllocMap, + PagingFile->AllocMapSize * 32); + clear_bit(off % 32, &PagingFile->AllocMap[off / 32]); + PagingFile->UsedPages--; + PagingFile->FreePages++; + KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); + return(off + 1); + } + + KeReleaseSpinLock(&PagingFile->AllocMapLock, oldIrql); + return(0); +} + +VOID MmFreeSwapPage(SWAPENTRY Entry) +{ + ULONG i; + ULONG off; + KIRQL oldIrql; + + i = (Entry >> 24) - 1; + off = Entry & 0xffffff; + + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + KeAcquireSpinLockAtDpcLevel(&PagingFileList[i]->AllocMapLock); + + set_bit(off % 32, &PagingFileList[i]->AllocMap[off / 32]); + + PagingFileList[i]->FreePages++; + PagingFileList[i]->UsedPages--; + + MiFreeSwapPages++; + MiUsedSwapPages--; + + KeReleaseSpinLockFromDpcLevel(&PagingFileList[i]->AllocMapLock); + KeReleaseSpinLock(&PagingFileListLock, oldIrql); +} + +SWAPENTRY MmAllocSwapPage(VOID) +{ + KIRQL oldIrql; + ULONG i; + ULONG off; + SWAPENTRY entry; + + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + + if (MiFreeSwapPages == 0) + { + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + return(0); + } + + for (i = 0; i < MAX_PAGING_FILES; i++) + { + if (PagingFileList[i] != NULL && + PagingFileList[i]->FreePages >= 1) + { + off = MiAllocPageFromPagingFile(PagingFileList[i]); + MiUsedSwapPages++; + MiFreeSwapPages--; + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + + entry = ((i+1) << 24) || off; + return(entry); + } + } + + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + return(0); +} + +NTSTATUS STDCALL NtCreatePagingFile(IN PUNICODE_STRING PageFileName, + IN ULONG MinimumSize, + IN ULONG MaximumSize, + OUT PULONG ActualSize) +{ + NTSTATUS Status; + OBJECT_ATTRIBUTES ObjectAttributes; + HANDLE FileHandle; + IO_STATUS_BLOCK IoStatus; + PFILE_OBJECT FileObject; + PPAGINGFILE PagingFile; + KIRQL oldIrql; + ULONG AllocMapSize; + ULONG i; + + InitializeObjectAttributes(&ObjectAttributes, + PageFileName, + 0, + NULL, + NULL); + Status = NtCreateFile(&FileHandle, + FILE_ALL_ACCESS, + &ObjectAttributes, + &IoStatus, + NULL, + 0, + 0, + FILE_OPEN, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + if (!NT_SUCCESS(Status)) + { + return(Status); + } + + Status = ObReferenceObjectByHandle(FileHandle, + FILE_ALL_ACCESS, + IoFileType, + UserMode, + (PVOID*)&FileObject, + NULL); + if (!NT_SUCCESS(Status)) + { + NtClose(FileHandle); + return(Status); + } + + NtClose(FileHandle); + + PagingFile = ExAllocatePool(NonPagedPool, sizeof(*PagingFile)); + if (PagingFile == NULL) + { + ObDereferenceObject(FileObject); + return(STATUS_NO_MEMORY); + } + + PagingFile->FileObject = FileObject; + PagingFile->MaximumSize = PagingFile->CurrentSize = MinimumSize; + PagingFile->FreePages = MinimumSize; + PagingFile->UsedPages = 0; + KeInitializeSpinLock(&PagingFile->AllocMapLock); + + AllocMapSize = (MinimumSize / 32) + 1; + PagingFile->AllocMap = ExAllocatePool(NonPagedPool, + AllocMapSize * sizeof(ULONG)); + PagingFile->AllocMapSize = AllocMapSize; + + if (PagingFile->AllocMap == NULL) + { + ExFreePool(PagingFile); + ObDereferenceObject(FileObject); + return(STATUS_NO_MEMORY); + } + + KeAcquireSpinLock(&PagingFileListLock, &oldIrql); + for (i = 0; i < MAX_PAGING_FILES; i++) + { + if (PagingFileList[i] == NULL) + { + PagingFileList[i] = PagingFile; + break; + } + } + MiFreeSwapPages = MiFreeSwapPages + ActualSize; + KeReleaseSpinLock(&PagingFileListLock, oldIrql); + + return(STATUS_SUCCESS); +} diff --git a/reactos/ntoskrnl/mm/paging.c b/reactos/ntoskrnl/mm/paging.c index 9b1c23b5655..c6ff3a37f5f 100644 --- a/reactos/ntoskrnl/mm/paging.c +++ b/reactos/ntoskrnl/mm/paging.c @@ -17,14 +17,3 @@ /* FUNCTIONS *****************************************************************/ -NTSTATUS -STDCALL -NtCreatePagingFile ( - IN PUNICODE_STRING PageFileName, - IN ULONG MiniumSize, - IN ULONG MaxiumSize, - OUT PULONG ActualSize - ) -{ - UNIMPLEMENTED; -} diff --git a/reactos/ntoskrnl/nt/port.c b/reactos/ntoskrnl/nt/port.c index 212a3b33bb6..44971b11bf0 100644 --- a/reactos/ntoskrnl/nt/port.c +++ b/reactos/ntoskrnl/nt/port.c @@ -1,4 +1,4 @@ -/* $Id: port.c,v 1.12 1999/12/02 20:53:54 dwelch Exp $ +/* $Id: port.c,v 1.13 1999/12/10 17:04:36 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -31,6 +31,8 @@ /* TYPES ********************************************************************/ +#define PORT_ALL_ACCESS (0x1) + #define EPORT_INACTIVE (0) #define EPORT_WAIT_FOR_CONNECT (1) #define EPORT_WAIT_FOR_ACCEPT (2) @@ -38,34 +40,102 @@ #define EPORT_WAIT_FOR_COMPLETE_CLT (4) #define EPORT_CONNECTED (5) -typedef struct _QUEUED_MESSAGE +struct _EPORT; + +typedef struct _QUEUEDMESSAGE { - LPC_MESSAGE_TYPE Type; - ULONG Length; - PVOID Buffer; - DWORD Flags; - PEPROCESS Sender; -} QUEUED_MESSAGE, *PQUEUED_MESSAGE; + struct _EPORT* Sender; + LIST_ENTRY QueueListEntry; + LPCMESSAGE Message; +} QUEUEDMESSAGE, *PQUEUEDMESSAGE; typedef struct _EPORT { KSPIN_LOCK Lock; - ULONG State; KEVENT Event; + struct _EPORT* OtherPort; - struct _EPORT* NamedPort; - ULONG NumberOfQueuedMessages; - QUEUED_MESSAGE Msg; - PEPROCESS ConnectingProcess; - struct _EPORT* ConnectingPort; + + ULONG QueueLength; + LIST_ENTRY QueueListHead; + + ULONG ConnectQueueLength; + LIST_ENTRY ConnectQueueListHead; + + ULONG MaxDataLength; + ULONG MaxConnectInfoLength; } EPORT, *PEPORT; /* GLOBALS *******************************************************************/ POBJECT_TYPE ExPortType = NULL; +static ULONG EiNextLpcMessageId; /* FUNCTIONS *****************************************************************/ +VOID EiEnqueueMessagePort(PEPORT Port, PQUEUEDMESSAGE Message) +{ + InsertTailList(&Port->QueueListHead, &Message->QueueListEntry); + Port->QueueLength++; +} + +PQUEUEDMESSAGE EiDequeueMessagePort(PEPORT Port) +{ + PQUEUEDMESSAGE Message; + PLIST_ENTRY entry; + + entry = RemoveHeadList(&Port->QueueListHead); + Message = CONTAINING_RECORD(entry, QUEUEDMESSAGE, QueueListEntry); + Port->QueueLength--; + + return(Message); +} + +VOID EiEnqueueConnectMessagePort(PEPORT Port, PQUEUEDMESSAGE Message) +{ + InsertTailList(&Port->ConnectQueueListHead, &Message->QueueListEntry); + Port->ConnectQueueLength++; +} + +PQUEUEDMESSAGE EiDequeueConnectMessagePort(PEPORT Port) +{ + PQUEUEDMESSAGE Message; + PLIST_ENTRY entry; + + entry = RemoveHeadList(&Port->ConnectQueueListHead); + Message = CONTAINING_RECORD(entry, QUEUEDMESSAGE, QueueListEntry); + Port->ConnectQueueLength--; + + return(Message); +} + +NTSTATUS EiReplyOrRequestPort(PEPORT Port, PLPCMESSAGE LpcReply, + ULONG MessageType) +{ + KIRQL oldIrql; + PQUEUEDMESSAGE MessageReply; + + MessageReply = ExAllocatePool(NonPagedPool, sizeof(QUEUEDMESSAGE)); + MessageReply->Sender = Port; + + if (LpcReply != NULL) + { + memcpy(&MessageReply->Message, LpcReply, sizeof(LPCMESSAGE)); + } + + MessageReply->Message.ClientProcessId = (DWORD)PsGetCurrentProcessId(); + MessageReply->Message.ClientThreadId = (DWORD)PsGetCurrentThreadId(); + MessageReply->Message.MessageType = MessageType; + MessageReply->Message.MessageId = InterlockedIncrement(&EiNextLpcMessageId); + + KeAcquireSpinLock(&Port->OtherPort->Lock, &oldIrql); + EiEnqueueMessagePort(Port->OtherPort, MessageReply); + KeReleaseSpinLock(&Port->OtherPort->Lock, oldIrql); + + return(STATUS_SUCCESS); +} + + VOID NiDeletePort(PVOID ObjectBody) { } @@ -124,6 +194,8 @@ NTSTATUS NiInitPort(VOID) ExPortType->OkayToClose = NULL; ExPortType->Create = NiCreatePort; + EiNextLpcMessageId = 0; + return(STATUS_SUCCESS); } @@ -132,26 +204,26 @@ static NTSTATUS NiInitializePort(PEPORT Port) memset(Port, 0, sizeof(EPORT)); KeInitializeSpinLock(&Port->Lock); KeInitializeEvent(&Port->Event, SynchronizationEvent, FALSE); - Port->State = EPORT_INACTIVE; Port->OtherPort = NULL; - Port->NumberOfQueuedMessages = 0; + Port->QueueLength = 0; + Port->ConnectQueueLength = 0; return(STATUS_SUCCESS); } NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, - ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, - DWORD a3, - DWORD a4) + ULONG MaxConnectInfoLength, + ULONG MaxDataLength, + ULONG Unknown1) { PEPORT Port; NTSTATUS Status; - DPRINT("NtCreaatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer); + DPRINT("NtCreatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer); Port = ObCreateObject(PortHandle, - 1, // DesiredAccess + PORT_ALL_ACCESS, ObjectAttributes, ExPortType); if (Port == NULL) @@ -160,23 +232,131 @@ NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, } Status = NiInitializePort(Port); - + Port->MaxConnectInfoLength = 260; + Port->MaxDataLength = 328; + return(Status); } -NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE PortHandle, - OUT PHANDLE OurPortHandle, - DWORD a2, - DWORD a3, - DWORD a4, - DWORD a5) +NTSTATUS STDCALL NtConnectPort (OUT PHANDLE ConnectedPort, + IN PUNICODE_STRING PortName, + IN PVOID Unknown1, + IN PLPCSECTIONINFO SectionInfo, + IN PLPCSECTIONMAPINFO MapInfo, + IN PVOID Unknown2, + IN PVOID ConnectInfo, + IN PULONG uConnectInfoLength) +/* + * FUNCTION: Connect to a named port and wait for the other side to + * accept the connection + */ { NTSTATUS Status; PEPORT NamedPort; PEPORT OurPort; + HANDLE OurPortHandle; + LPCMESSAGE Request; + PQUEUEDMESSAGE Reply; + ULONG ConnectInfoLength; + KIRQL oldIrql; - Status = ObReferenceObjectByHandle(PortHandle, - 1, /* AccessRequired */ + DPRINT("NtConnectPort(PortName %w)\n", PortName->Buffer); + + /* + * Copy in user parameters + */ + memcpy(&ConnectInfoLength, uConnectInfoLength, sizeof(*uConnectInfoLength)); + + /* + * Get access to the port + */ + Status = ObReferenceObjectByName(PortName, + 0, + NULL, + PORT_ALL_ACCESS, /* DesiredAccess */ + ExPortType, + UserMode, + NULL, + (PVOID*)&NamedPort); + if (!NT_SUCCESS(Status)) + { + DPRINT("Failed to reference named port (status %x)\n", Status); + return(Status); + } + + /* + * Create a port to represent our side of the connection + */ + OurPort = ObCreateObject(&OurPortHandle, + PORT_ALL_ACCESS, + NULL, + ExPortType); + NiInitializePort(OurPort); + + /* + * Create a request message + */ + Request.ActualMessageLength = ConnectInfoLength; + Request.TotalMessageLength = sizeof(LPCMESSAGE) + ConnectInfoLength; + Request.SharedSectionSize = 0; + memcpy(Request.MessageData, ConnectInfo, ConnectInfoLength); + + /* + * Queue the message to the named port + */ + KeAcquireSpinLock(&NamedPort->Lock, &oldIrql); + EiReplyOrRequestPort(NamedPort, &Request, LPC_CONNECTION_REQUEST); + KeReleaseSpinLock(&NamedPort->Lock, oldIrql); + + DPRINT("Waiting for connection completion\n"); + + /* + * Wait for them to accept our connection + */ + KeWaitForSingleObject(&OurPort->Event, + UserRequest, + UserMode, + FALSE, + NULL); + + KeAcquireSpinLock(&OurPort->Lock, &oldIrql); + Reply = EiDequeueMessagePort(OurPort); + KeReleaseSpinLock(&OurPort->Lock, oldIrql); + memcpy(ConnectInfo, Reply->Message.MessageData, + Reply->Message.ActualMessageLength); + *uConnectInfoLength = Reply->Message.ActualMessageLength; + + if (Reply->Message.MessageType == LPC_CONNECTION_REFUSED) + { + ZwClose(OurPortHandle); + ExFreePool(Reply); + return(STATUS_UNSUCCESSFUL); + } + + *ConnectedPort = OurPortHandle; + ExFreePool(Reply); + + DPRINT("Exited successfully\n"); + + return(STATUS_SUCCESS); +} + + +NTSTATUS STDCALL NtAcceptConnectPort (PHANDLE ServerPortHandle, + HANDLE NamedPortHandle, + PLPCMESSAGE LpcMessage, + ULONG AcceptIt, + ULONG Unknown2, + PLPCSECTIONMAPINFO MapInfo) +{ + NTSTATUS Status; + PEPORT NamedPort; + PEPORT OurPort; + PQUEUEDMESSAGE ConnectionRequest; + KIRQL oldIrql; + + Status = ObReferenceObjectByHandle(NamedPortHandle, + PORT_ALL_ACCESS, ExPortType, UserMode, (PVOID*)&NamedPort, @@ -186,33 +366,43 @@ NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE PortHandle, return(Status); } - if (NamedPort->State != EPORT_WAIT_FOR_ACCEPT) - { - ObDereferenceObject(NamedPort); - return(STATUS_INVALID_PARAMETER); - } - /* * Create a port object for our side of the connection */ - OurPort = ObCreateObject(OurPortHandle, - 1, - NULL, - ExPortType); - NiInitializePort(OurPort); + if (AcceptIt != 1) + { + OurPort = ObCreateObject(ServerPortHandle, + PORT_ALL_ACCESS, + NULL, + ExPortType); + NiInitializePort(OurPort); + } /* - * Connect the two port + * Dequeue the connection request */ - OurPort->OtherPort = NamedPort->ConnectingPort; - OurPort->OtherPort->OtherPort = OurPort; - OurPort->State = EPORT_WAIT_FOR_COMPLETE_SRV; - OurPort->OtherPort->State = EPORT_WAIT_FOR_COMPLETE_CLT; - OurPort->NamedPort = NamedPort; + KeAcquireSpinLock(&NamedPort->Lock, &oldIrql); + ConnectionRequest = EiDequeueConnectMessagePort(OurPort); + KeReleaseSpinLock(&NamedPort->Lock, oldIrql); + + if (AcceptIt != 1) + { + EiReplyOrRequestPort(ConnectionRequest->Sender, + LpcMessage, + LPC_CONNECTION_REFUSED); + KeSetEvent(&ConnectionRequest->Sender->Event, IO_NO_INCREMENT, FALSE); + ExFreePool(ConnectionRequest); + ObDereferenceObject(NamedPort); + return(STATUS_SUCCESS); + } - NamedPort->State = EPORT_INACTIVE; - NamedPort->ConnectingProcess = NULL; - NamedPort->ConnectingPort = NULL; + /* + * Connect the two ports + */ + OurPort->OtherPort = ConnectionRequest->Sender; + OurPort->OtherPort->OtherPort = OurPort; + EiReplyOrRequestPort(ConnectionRequest->Sender, LpcMessage, LPC_REPLY); + ExFreePool(ConnectionRequest); ObDereferenceObject(NamedPort); @@ -226,7 +416,7 @@ NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle) PEPORT OurPort; Status = ObReferenceObjectByHandle(PortHandle, - 1, /* AccessRequired */ + PORT_ALL_ACCESS, ExPortType, UserMode, (PVOID*)&OurPort, @@ -236,148 +426,40 @@ NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle) return(Status); } - if (OurPort->State != EPORT_WAIT_FOR_COMPLETE_SRV) - { - ObDereferenceObject(OurPort); - return(Status); - } + KeSetEvent(&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE); - OurPort->State = EPORT_CONNECTED; - OurPort->OtherPort->State = EPORT_CONNECTED; - - KeSetEvent(&OurPort->NamedPort->Event, IO_NO_INCREMENT, FALSE); + ObDereferenceObject(OurPort); return(STATUS_SUCCESS); } - -NTSTATUS STDCALL NtConnectPort (OUT PHANDLE ConnectedPort, - IN PUNICODE_STRING PortName, - IN POBJECT_ATTRIBUTES PortAttributes, - IN DWORD a3, - IN DWORD a4, - 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 NamedPort; - PEPORT OurPort; - HANDLE OurPortHandle; - - DPRINT("NtConnectPort(PortName %w)\n", PortName->Buffer); - - Status = ObReferenceObjectByName(PortName, - 0, - NULL, - 1, /* DesiredAccess */ - ExPortType, - UserMode, - NULL, - (PVOID*)&NamedPort); - if (!NT_SUCCESS(Status)) - { - DPRINT("Failed to reference named port (status %x)\n", Status); - return(Status); - } - - if (NamedPort->State != EPORT_WAIT_FOR_CONNECT) - { - DPRINT("Named port is in the wrong state\n"); - ObDereferenceObject(NamedPort); - return(STATUS_UNSUCCESSFUL); - } - - /* - * Create a port to represent our side of the connection - */ - OurPort = ObCreateObject(&OurPortHandle, - 1, - PortAttributes, - ExPortType); - NiInitializePort(OurPort); - OurPort->NamedPort = NamedPort; - - /* - * - */ - NamedPort->ConnectingProcess = PsGetCurrentProcess(); - NamedPort->State = EPORT_WAIT_FOR_ACCEPT; - NamedPort->ConnectingPort = OurPort; - - /* - * Tell the other side they have a connection - */ - KeSetEvent(&NamedPort->Event, IO_NO_INCREMENT, FALSE); - - DPRINT("Waiting for connection completion\n"); - - /* - * Wait for them to accept our connection - */ - KeWaitForSingleObject(&NamedPort->Event, - UserRequest, - UserMode, - FALSE, - NULL); - - *ConnectedPort = OurPortHandle; - - DPRINT("Exited successfully\n"); - - return(STATUS_SUCCESS); -} - - NTSTATUS STDCALL NtImpersonateClientOfPort (IN HANDLE PortHandle, - IN PCLIENT_ID ClientId) + IN PLPCMESSAGE ClientMessage) { UNIMPLEMENTED; } NTSTATUS STDCALL NtListenPort (IN HANDLE PortHandle, - IN DWORD QueueSize /* guess */) + IN PLPCMESSAGE ConnectMsg) /* * 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, - 1, /* AccessRequired */ - ExPortType, - UserMode, - (PVOID*)&Port, - NULL); - if (!NT_SUCCESS(Status)) + for(;;) { - DPRINT("Failed to reference object (status %x)\n", - Status); - return(Status); + Status = NtReplyWaitReceivePort(PortHandle, + NULL, + NULL, + ConnectMsg); + if (!NT_SUCCESS(Status) || + ConnectMsg->MessageType == LPC_CONNECTION_REQUEST) + { + break; + } } - - if (Port->State != EPORT_INACTIVE) - { - ObDereferenceObject(Port); - return(STATUS_INVALID_PARAMETER); - } - - Port->State = EPORT_WAIT_FOR_CONNECT; - Status = KeWaitForSingleObject(&Port->Event, - UserRequest, - UserMode, - FALSE, - NULL); - return(Status); } @@ -391,48 +473,153 @@ NTSTATUS STDCALL NtQueryInformationPort (IN HANDLE PortHandle, UNIMPLEMENTED; } + NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle, - IN PLPC_MESSAGE LpcReply /* guess */) + IN PLPCMESSAGE LpcReply) { - UNIMPLEMENTED; + NTSTATUS Status; + PEPORT Port + + DPRINT("NtReplyPort(PortHandle %x, LpcReply %x)\n", PortHandle, LpcReply); + + Status = ObReferenceObjectByHandle(PortHandle, + PORT_ALL_ACCESS, /* AccessRequired */ + ExPortType, + UserMode, + (PVOID*)&Port, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtReplyPort() = %x\n", Status); + return(Status); + } + + Status = EiReplyOrRequestPort(Port, LpcReply, LPC_REPLY); + KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE); + + ObDereferenceObject(Port); + + return(Status); } -NTSTATUS STDCALL NtReplyWaitReceivePort ( IN HANDLE PortHandle, - IN PLPC_MESSAGE LpcReply, /* guess */ - OUT PLPC_MESSAGE LpcMessage, /* guess */ - OUT PULONG MessageLength /* guess */) +NTSTATUS STDCALL NtReplyWaitReceivePort (IN HANDLE PortHandle, + PVOID Unknown, + IN PLPCMESSAGE LpcReply, + OUT PLPCMESSAGE LpcMessage) { - UNIMPLEMENTED; -} - - -NTSTATUS STDCALL NtReplyWaitReplyPort (IN HANDLE PortHandle, - IN OUT PLPC_MESSAGE LpcReply /* guess */) -{ - UNIMPLEMENTED; + NTSTATUS Status; + PEPORT Port; + KIRQL oldIrql; + PQUEUEDMESSAGE Request; + + DPRINT("NtReplyWaitReceivePort(PortHandle %x, LpcReply %x, " + "LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage); + + Status = ObReferenceObjectByHandle(PortHandle, + PORT_ALL_ACCESS, + ExPortType, + UserMode, + (PVOID*)&Port, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtReplyWaitReceivePort() = %x\n", Status); + return(Status); + } + + /* + * Send the reply + */ + if (LpcReply != NULL) + { + Status = EiReplyOrRequestPort(Port, LpcReply, LPC_REPLY); + KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE); + + if (!NT_SUCCESS(Status)) + { + ObDereferenceObject(Port); + return(Status); + } + } + + /* + * Want for a message to be received + */ + KeWaitForSingleObject(&Port->Event, + UserRequest, + UserMode, + FALSE, + NULL); + + /* + * Dequeue the message + */ + KeAcquireSpinLock(&Port->Lock, &oldIrql); + Request = EiDequeueMessagePort(Port); + memcpy(LpcMessage, &Request->Message, sizeof(*LpcMessage)); + if (Request->Message.MessageType == LPC_CONNECTION_REQUEST) + { + EiEnqueueConnectMessagePort(Port, Request); + KeReleaseSpinLock(&Port->Lock, oldIrql); + } + else + { + KeReleaseSpinLock(&Port->Lock, oldIrql); + ExFreePool(Request); + } + + /* + * + */ + ObDereferenceObject(Port); + return(STATUS_SUCCESS); } NTSTATUS STDCALL NtRequestPort (IN HANDLE PortHandle, - IN PLPC_MESSAGE LpcMessage /* guess */) -{ - return(NtRequestWaitReplyPort(PortHandle, NULL, LpcMessage)); -} - - -NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle, - IN OUT PLPC_MESSAGE LpcReply, /* guess */ - OUT PLPC_MESSAGE LpcMessage /* guess */) + IN PLPCMESSAGE LpcMessage /* guess */) { NTSTATUS Status; PEPORT Port; - DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcReply %x, " - "LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage); + DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle, + LpcMessage); Status = ObReferenceObjectByHandle(PortHandle, - 1, /* AccessRequired */ + PORT_ALL_ACCESS, + ExPortType, + UserMode, + (PVOID*)&Port, + NULL); + if (!NT_SUCCESS(Status)) + { + DPRINT("NtRequestPort() = %x\n", Status); + return(Status); + } + + Status = EiReplyOrRequestPort(Port, LpcMessage, LPC_DATAGRAM); + KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE); + + ObDereferenceObject(Port); + return(Status); +} + + +NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle, + PLPCMESSAGE LpcRequest, + PLPCMESSAGE LpcReply) +{ + NTSTATUS Status; + PEPORT Port; + PQUEUEDMESSAGE Message; + KIRQL oldIrql; + + DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, " + "LpcReply %x)\n", PortHandle, LpcRequest, LpcReply); + + Status = ObReferenceObjectByHandle(PortHandle, + PORT_ALL_ACCESS, ExPortType, UserMode, (PVOID*)&Port, @@ -442,50 +629,18 @@ NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle, return(Status); } - DPRINT("Port %x Port->OtherPort %x Port->OtherPort->OtherPort %x\n", - Port, Port->OtherPort, Port->OtherPort->OtherPort); - if (LpcMessage != NULL) - { - DPRINT("Copying message onto other port's queue\n"); - - DPRINT("LpcMessage->Length %d\n", LpcMessage->Length); - - /* - * Put the message on the other port's queue - */ - Port->OtherPort->Msg.Type = LpcMessage->Type; - Port->OtherPort->Msg.Length = LpcMessage->Length; - Port->OtherPort->Msg.Buffer = ExAllocatePool(NonPagedPool, - Port->OtherPort->Msg.Length); - memcpy(Port->OtherPort->Msg.Buffer, LpcMessage->Buffer, - Port->OtherPort->Msg.Length); - Port->OtherPort->Msg.Flags = LpcMessage->Flags; - Port->OtherPort->Msg.Sender = PsGetCurrentProcess(); - Port->OtherPort->NumberOfQueuedMessages++; - - DPRINT("Waking other side\n"); - - /* - * Wake up the other side (if it's waiting) - */ - KeSetEvent(&Port->OtherPort->Event, IO_NO_INCREMENT, FALSE); - - } + Status = EiReplyOrRequestPort(Port, LpcRequest, LPC_REQUEST); + KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE); - /* - * If we aren't waiting for a reply then return - */ - if (LpcReply == NULL) + if (!NT_SUCCESS(Status)) { ObDereferenceObject(Port); - return(STATUS_SUCCESS); + return(Status); } - DPRINT("Wait for other side to reply\n"); - /* - * Wait the other side to reply to you + * Wait for a reply */ KeWaitForSingleObject(&Port->Event, UserRequest, @@ -493,32 +648,23 @@ NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle, FALSE, NULL); - DPRINT("Copy reply from our port\n"); - /* - * Copy the received message into the process's address space + * Dequeue the reply */ - DPRINT("LpcReply->Length %d\n", LpcReply->Length); - - LpcReply->Length = Port->Msg.Length; - LpcReply->Type = Port->Msg.Type; - memcpy(LpcReply->Buffer, Port->Msg.Buffer, LpcReply->Length); - LpcReply->Flags = Port->Msg.Flags; - - DPRINT("Freeing message\n"); - - /* - * Deallocate the message and remove it from the other side's queue - */ - ExFreePool(Port->Msg.Buffer); - Port->NumberOfQueuedMessages--; - - DPRINT("Finished with success\n"); + KeAcquireSpinLock(&Port->Lock, &oldIrql); + Message = EiDequeueMessagePort(Port); + KeReleaseSpinLock(&Port->Lock, oldIrql); + memcpy(LpcReply, &Message->Message, sizeof(*LpcReply)); + ExFreePool(Message); return(STATUS_SUCCESS); } - +NTSTATUS STDCALL NtReplyWaitReplyPort(PVOID a, PVOID b) +{ + UNIMPLEMENTED; +} + /********************************************************************** * NAME SYSTEM * NtReadRequestData NOT EXPORTED diff --git a/reactos/ntoskrnl/ps/thread.c b/reactos/ntoskrnl/ps/thread.c index d191443a04a..ff11439043c 100644 --- a/reactos/ntoskrnl/ps/thread.c +++ b/reactos/ntoskrnl/ps/thread.c @@ -1,4 +1,4 @@ -/* $Id: thread.c,v 1.33 1999/12/05 23:23:50 phreak Exp $ +/* $Id: thread.c,v 1.34 1999/12/10 17:04:36 dwelch Exp $ * * COPYRIGHT: See COPYING in the top level directory * PROJECT: ReactOS kernel @@ -67,6 +67,11 @@ PETHREAD PsGetCurrentThread(VOID) return(CurrentThread); } +HANDLE PsGetCurrentThreadId(VOID) +{ + return(CurrentThread->Cid.UniqueThread); +} + VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus) { KIRQL oldlvl; diff --git a/reactos/ntoskrnl/rtl/interlck.c b/reactos/ntoskrnl/rtl/interlck.c index afecc4fc457..4c00d32e301 100644 --- a/reactos/ntoskrnl/rtl/interlck.c +++ b/reactos/ntoskrnl/rtl/interlck.c @@ -1,4 +1,4 @@ -/* $Id: interlck.c,v 1.4 1999/11/02 08:55:43 dwelch Exp $ +/* $Id: interlck.c,v 1.5 1999/12/10 17:04:37 dwelch Exp $ * * reactos/ntoskrnl/rtl/interlck.c * @@ -9,6 +9,7 @@ #include #include +#if 0 LONG FASTCALL InterlockedIncrement(PLONG Addend) { LONG r; @@ -24,12 +25,13 @@ LONG FASTCALL InterlockedDecrement(PLONG Addend) r = (*Addend); return(r); } +#endif /********************************************************************** * FASTCALL: @InterlockedIncrement@0 * STDCALL : _InterlockedIncrement@4 */ -#if 0 +#if 1 LONG FASTCALL InterlockedIncrement (PLONG Addend); /* * FUNCTION: Increments a caller supplied variable of type LONG as an @@ -78,7 +80,7 @@ __asm__( * FASTCALL: @InterlockedDecrement@0 * STDCALL : _InterlockedDecrement@4 */ -#if 0 +#if 1 LONG FASTCALL InterlockedDecrement(PLONG Addend); __asm__("\n\t.global _InterlockedDecrement@4\n\t" "_InterlockedDecrement@4:\n\t"