mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 17:44:45 +00:00
Modified LPC implementation to be closer to nt.
Did some initial work on support for paging Switched some test application from using our special startup code Correctly bug in DPC code (possible fix for "releasing unacquired spinlock" error") svn path=/trunk/; revision=845
This commit is contained in:
parent
815a52debe
commit
c7b7c5b0b6
22 changed files with 796 additions and 406 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
#include <stdio.h>
|
||||
#include <ddk/ntddk.h>
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
UNICODE_STRING UnicodeString;
|
||||
RtlInitUnicodeString(&UnicodeString,L"Hello world\n");
|
||||
NtDisplayString(&UnicodeString);
|
||||
printf("Hello world\n");
|
||||
return(0);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,12 @@ int main(int argc, char* argv[])
|
|||
for (i=1; i<argc; i++)
|
||||
{
|
||||
in = fopen(argv[i],"r");
|
||||
if (in == NULL)
|
||||
{
|
||||
printf("Failed to open file %s\n", argv[i]);
|
||||
return(0);
|
||||
}
|
||||
|
||||
while ((ch = fgetc(in)) != EOF)
|
||||
{
|
||||
putchar(ch);
|
||||
|
|
|
@ -37,6 +37,6 @@ endif
|
|||
|
||||
cat.exe: $(OBJECTS) $(LIBS)
|
||||
$(CC) $(OBJECTS) -o cat.exe
|
||||
$(NM) --numeric-sort cat.exe > args.sym
|
||||
$(NM) --numeric-sort cat.exe > cat.sym
|
||||
|
||||
include ../../rules.mak
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
|
||||
HANDLE PsGetCurrentProcessId(VOID);
|
||||
HANDLE PsGetCurrentThreadId(VOID);
|
||||
|
||||
/*
|
||||
* FUNCTION: Creates a thread which executes in kernel mode
|
||||
|
|
|
@ -232,8 +232,6 @@ typedef struct _KTHREAD
|
|||
|
||||
/* Provisionally added by David Welch */
|
||||
hal_thread_state Context;
|
||||
// LIST_ENTRY Entry;
|
||||
// ULONG LastTick;
|
||||
|
||||
} KTHREAD, *PKTHREAD;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
247
reactos/ntoskrnl/mm/pagefile.c
Normal file
247
reactos/ntoskrnl/mm/pagefile.c
Normal file
|
@ -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 <ddk/ntddk.h>
|
||||
#include <internal/bitops.h>
|
||||
#include <internal/io.h>
|
||||
|
||||
#include <internal/debug.h>
|
||||
|
||||
/* 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);
|
||||
}
|
|
@ -17,14 +17,3 @@
|
|||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtCreatePagingFile (
|
||||
IN PUNICODE_STRING PageFileName,
|
||||
IN ULONG MiniumSize,
|
||||
IN ULONG MaxiumSize,
|
||||
OUT PULONG ActualSize
|
||||
)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 <ntos.h>
|
||||
#include <internal/debug.h>
|
||||
|
||||
#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"
|
||||
|
|
Loading…
Reference in a new issue