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:
David Welch 1999-12-10 17:04:37 +00:00
parent 815a52debe
commit c7b7c5b0b6
22 changed files with 796 additions and 406 deletions

View file

@ -35,7 +35,7 @@ else
$(CP) $* ../../$(DIST_DIR)/apps/$* $(CP) $* ../../$(DIST_DIR)/apps/$*
endif endif
args.exe: $(OBJECTS) $(LIBS) args.exe: $(OBJECTS)
$(CC) $(OBJECTS) -o args.exe $(CC) $(OBJECTS) -o args.exe
$(NM) --numeric-sort args.exe > args.sym $(NM) --numeric-sort args.exe > args.sym

View file

@ -1,10 +1,8 @@
#include <stdio.h> #include <stdio.h>
#include <ddk/ntddk.h>
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
UNICODE_STRING UnicodeString; printf("Hello world\n");
RtlInitUnicodeString(&UnicodeString,L"Hello world\n");
NtDisplayString(&UnicodeString);
return(0); return(0);
} }

View file

@ -1,11 +1,10 @@
# #
# #
# #
OBJECTS = ../common/crt0.o hello.o OBJECTS = hello.o
PROGS = hello.exe PROGS = hello.exe
LIBS = ../../lib/kernel32/kernel32.a ../../lib/ntdll/ntdll.a LIBS =
CLEAN_FILES = hello.o hello.exe CLEAN_FILES = hello.o hello.exe
BASE_CFLAGS = -I../../include
all: hello.exe all: hello.exe
@ -34,7 +33,7 @@ else
$(CP) $* ../../$(DIST_DIR)/apps/$* $(CP) $* ../../$(DIST_DIR)/apps/$*
endif endif
hello.exe: $(OBJECTS) $(LIBS) hello.exe: $(OBJECTS)
$(LD) $(OBJECTS) $(LIBS) -o hello.exe $(CC) $(OBJECTS) -o hello.exe
include ../../rules.mak include ../../rules.mak

View file

@ -23,8 +23,7 @@ void main(int argc, char* argv[])
UNICODE_STRING PortName; UNICODE_STRING PortName;
NTSTATUS Status; NTSTATUS Status;
HANDLE PortHandle; HANDLE PortHandle;
LPC_MESSAGE Request; LPCMESSAGE Request;
char buffer[255];
printf("(lpcclt.exe) Lpc client\n"); printf("(lpcclt.exe) Lpc client\n");
@ -37,7 +36,7 @@ void main(int argc, char* argv[])
0, 0,
0, 0,
0, 0,
0, NULL,
0); 0);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -45,14 +44,12 @@ void main(int argc, char* argv[])
return; return;
} }
strcpy(buffer, GetCommandLineA()); strcpy(Request.MessageData, GetCommandLineA());
Request.Buffer = buffer; Request.ActualMessageLength = strlen(Request.MessageData);
Request.Length = strlen(buffer); Request.TotalMessageLength = sizeof(LPCMESSAGE);
printf("(lpcclt.exe) Sending message\n"); printf("(lpcclt.exe) Sending message\n");
Status = NtRequestWaitReplyPort(PortHandle, Status = NtRequestPort(PortHandle, &Request);
NULL,
&Request);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
printf("(lpcclt.exe) Failed to send request\n"); printf("(lpcclt.exe) Failed to send request\n");

View file

@ -25,6 +25,7 @@ void main(int argc, char* argv[])
NTSTATUS Status; NTSTATUS Status;
HANDLE NamedPortHandle; HANDLE NamedPortHandle;
HANDLE PortHandle; HANDLE PortHandle;
LPCMESSAGE ConnectMsg;
printf("(lpcsrv.exe) Lpc test server\n"); printf("(lpcsrv.exe) Lpc test server\n");
@ -37,9 +38,9 @@ void main(int argc, char* argv[])
printf("(lpcsrv.exe) Creating port\n"); printf("(lpcsrv.exe) Creating port\n");
Status = NtCreatePort(&NamedPortHandle, Status = NtCreatePort(&NamedPortHandle,
0,
&ObjectAttributes, &ObjectAttributes,
0, 0,
0,
0); 0);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
@ -50,7 +51,7 @@ void main(int argc, char* argv[])
printf("(lpcsrv.exe) Listening for connections\n"); printf("(lpcsrv.exe) Listening for connections\n");
Status = NtListenPort(NamedPortHandle, Status = NtListenPort(NamedPortHandle,
0); &ConnectMsg);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
printf("(lpcsrv.exe) Failed to listen for connections\n"); 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"); printf("(lpcsrv.exe) Accepting connections\n");
Status = NtAcceptConnectPort(NamedPortHandle, Status = NtAcceptConnectPort(&PortHandle,
&PortHandle, NamedPortHandle,
NULL,
1,
0, 0,
0, NULL);
0,
0);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
printf("(lpcsrv.exe) Failed to accept connection\n"); printf("(lpcsrv.exe) Failed to accept connection\n");
@ -80,20 +81,18 @@ void main(int argc, char* argv[])
for(;;) for(;;)
{ {
LPC_MESSAGE Request; LPCMESSAGE Request;
char buffer[255];
Request.Buffer = buffer; Status = NtReplyWaitReceivePort(PortHandle,
0,
Status = NtRequestWaitReplyPort(PortHandle, NULL,
&Request, &Request);
NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
printf("(lpcsrv.exe) Failed to receive request\n"); printf("(lpcsrv.exe) Failed to receive request\n");
return; return;
} }
printf("(lpcsrv.exe) Message contents are <%s>\n", Request.Buffer); printf("(lpcsrv.exe) Message contents are <%s>\n", Request.MessageData);
} }
} }

View file

@ -10,6 +10,12 @@ int main(int argc, char* argv[])
for (i=1; i<argc; i++) for (i=1; i<argc; i++)
{ {
in = fopen(argv[i],"r"); in = fopen(argv[i],"r");
if (in == NULL)
{
printf("Failed to open file %s\n", argv[i]);
return(0);
}
while ((ch = fgetc(in)) != EOF) while ((ch = fgetc(in)) != EOF)
{ {
putchar(ch); putchar(ch);

View file

@ -37,6 +37,6 @@ endif
cat.exe: $(OBJECTS) $(LIBS) cat.exe: $(OBJECTS) $(LIBS)
$(CC) $(OBJECTS) -o cat.exe $(CC) $(OBJECTS) -o cat.exe
$(NM) --numeric-sort cat.exe > args.sym $(NM) --numeric-sort cat.exe > cat.sym
include ../../rules.mak include ../../rules.mak

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -25,7 +25,7 @@
#define IDMAP_BASE 0xd0000000 #define IDMAP_BASE 0xd0000000
#define VIDMEM_BASE 0xb8000 #define VIDMEM_BASE 0xb8000
#define NR_ROWS 25 #define NR_ROWS 50
#define NR_COLUMNS 80 #define NR_COLUMNS 80
#define NR_SCANLINES 8 #define NR_SCANLINES 8

View file

@ -1,6 +1,7 @@
HANDLE PsGetCurrentProcessId(VOID); HANDLE PsGetCurrentProcessId(VOID);
HANDLE PsGetCurrentThreadId(VOID);
/* /*
* FUNCTION: Creates a thread which executes in kernel mode * FUNCTION: Creates a thread which executes in kernel mode

View file

@ -232,8 +232,6 @@ typedef struct _KTHREAD
/* Provisionally added by David Welch */ /* Provisionally added by David Welch */
hal_thread_state Context; hal_thread_state Context;
// LIST_ENTRY Entry;
// ULONG LastTick;
} KTHREAD, *PKTHREAD; } KTHREAD, *PKTHREAD;

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -5169,50 +5170,40 @@ ZwYieldExecution(
* These prototypes are unknown as yet * These prototypes are unknown as yet
* (stack sizes by Peter-Michael Hager) * (stack sizes by Peter-Michael Hager)
*/ */
NTSTATUS NTSTATUS STDCALL NtAcceptConnectPort (PHANDLE PortHandle,
STDCALL HANDLE NamedPortHandle,
NtAcceptConnectPort ( /* @24 */ PLPCMESSAGE ServerReply,
IN HANDLE PortHandle, ULONG AcceptIt,
OUT PHANDLE ConnectedPort, ULONG Unknown3,
IN DWORD Unknown2, PLPCSECTIONMAPINFO MapInfo);
IN DWORD Unknown3,
IN DWORD Unknown4, NTSTATUS STDCALL NtCompleteConnectPort (IN HANDLE PortHandle);
IN DWORD Unknown5
); NTSTATUS STDCALL NtConnectPort(OUT PHANDLE PortHandle,
NTSTATUS IN PUNICODE_STRING PortName,
STDCALL IN PVOID Unknown1,
NtCompleteConnectPort ( /* @4 */ IN PLPCSECTIONINFO SectionInfo,
IN HANDLE PortHandle IN PLPCSECTIONMAPINFO MapInfo,
); IN PVOID Unknown2,
NTSTATUS IN PVOID ConnectInfo,
STDCALL IN PULONG ConnectInfoLength);
NtConnectPort (
OUT PHANDLE PortHandle, NTSTATUS STDCALL NtReplyWaitReplyPort(PVOID Unknown1,
IN PUNICODE_STRING PortName, PVOID Unknown2);
IN POBJECT_ATTRIBUTES PortAttributes,
IN DWORD Unknown3,
IN DWORD Unknown4,
IN DWORD Unknown5,
IN DWORD Unknown6,
IN ULONG Flags
);
NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes, POBJECT_ATTRIBUTES ObjectAttributes,
DWORD a3, ULONG MaxConnectInfoLength,
DWORD a4); ULONG MaxDataLength,
NTSTATUS ULONG Unknown1);
STDCALL
NtImpersonateClientOfPort ( /* @8 */ NTSTATUS STDCALL NtImpersonateClientOfPort (IN HANDLE PortHandle,
IN HANDLE PortHandle, IN PLPCMESSAGE ClientMessage);
IN PCLIENT_ID ClientId
); NTSTATUS STDCALL NtListenPort (IN HANDLE PortHAndle,
NTSTATUS IN PLPCMESSAGE LpcMessage);
STDCALL
NtListenPort ( /* @8 */
IN HANDLE PortHAndle,
IN DWORD QueueSize /* guess */
);
NTSTATUS NTSTATUS
STDCALL STDCALL
NtQueryInformationPort ( /* @20 */ NtQueryInformationPort ( /* @20 */
@ -5222,39 +5213,17 @@ NtQueryInformationPort ( /* @20 */
IN ULONG PortInformationLength, /* guess */ IN ULONG PortInformationLength, /* guess */
OUT PULONG ReturnLength /* guess */ OUT PULONG ReturnLength /* guess */
); );
NTSTATUS NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle,
STDCALL IN PLPCMESSAGE LpcReply);
NtReplyPort ( /* @8 */ NTSTATUS STDCALL NtReplyWaitReceivePort (IN HANDLE PortHandle,
IN HANDLE PortHandle, PVOID Unknown1,
IN PLPC_MESSAGE LpcReply /* guess */ PLPCMESSAGE MessageReply,
); PLPCMESSAGE MessageRequest);
NTSTATUS NTSTATUS STDCALL NtRequestPort ( IN HANDLE PortHandle,
STDCALL IN PLPCMESSAGE LpcMessage);
NtReplyWaitReceivePort ( /* @16 */ NTSTATUS STDCALL NtRequestWaitReplyPort (IN HANDLE PortHandle,
IN HANDLE PortHandle, IN OUT PLPCMESSAGE LpcReply,
IN PLPC_MESSAGE LpcReply, /* guess */ OUT PLPCMESSAGE LpcRequest);
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 NTSTATUS
STDCALL STDCALL
NtReadRequestData ( /* @24 */ NtReadRequestData ( /* @24 */

View file

@ -1,23 +1,49 @@
#ifndef __INCLUDE_DDK_ZWTYPES_H #ifndef __INCLUDE_DDK_ZWTYPES_H
#define __INCLUDE_DDK_ZWTYPES_H #define __INCLUDE_DDK_ZWTYPES_H
typedef #define MAX_MESSAGE_DATA (0x130)
enum {
LpcMessageTypeUnknown, /* invalid */
LpcMessageTypeBase, /* <256 bytes */
LpcMessageTypeLarge, /* >255 bytes */
LpcMessageTypeFast, /* 3.51 GDI */
LpcMessageTypeMaximum
} 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; DWORD Length;
ULONG Length; HANDLE SectionHandle;
PVOID Buffer; /* Page aligned! */ DWORD Unknown1;
DWORD Flags; /* To be defined */ DWORD SectionSize;
} LPC_MESSAGE, * PLPC_MESSAGE; 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 ) #define NtCurrentProcess() ( (HANDLE) 0xFFFFFFFF )

View file

@ -116,5 +116,6 @@ PVOID MiTryToSharePageInSection(PSECTION_OBJECT Section, ULONG Offset);
NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); NTSTATUS MmSafeCopyFromUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes);
NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes); NTSTATUS MmSafeCopyToUser(PVOID Dest, PVOID Src, ULONG NumberOfBytes);
VOID MmInitPagingFile(VOID);
#endif #endif

View file

@ -67,7 +67,11 @@ VOID KeAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock)
* SpinLock = Spinlock to acquire * 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"); DbgPrint("Spinning on spinlock\n");
KeBugCheck(0); KeBugCheck(0);

View file

@ -64,9 +64,10 @@ void KeDrainDpcQueue(void)
} }
DPRINT("KeDrainDpcQueue()\n"); DPRINT("KeDrainDpcQueue()\n");
KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock); KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
KeRaiseIrql(HIGH_LEVEL,&oldlvl);
current_entry = RemoveHeadList(&DpcQueueHead); current_entry = RemoveHeadList(&DpcQueueHead);
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
KeLowerIrql(oldlvl); KeLowerIrql(oldlvl);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
while (current_entry!=(&DpcQueueHead)) while (current_entry!=(&DpcQueueHead))
@ -80,15 +81,16 @@ void KeDrainDpcQueue(void)
current->SystemArgument2); current->SystemArgument2);
CHECKPOINT; CHECKPOINT;
current->Lock=FALSE; current->Lock=FALSE;
KeRaiseIrql(HIGH_LEVEL,&oldlvl); KeRaiseIrql(HIGH_LEVEL, &oldlvl);
KeAcquireSpinLockAtDpcLevel(&DpcQueueLock);
current_entry = RemoveHeadList(&DpcQueueHead); current_entry = RemoveHeadList(&DpcQueueHead);
DPRINT("current_entry %x\n", current_entry); DPRINT("current_entry %x\n", current_entry);
DpcQueueSize--; DpcQueueSize--;
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
KeLowerIrql(oldlvl); KeLowerIrql(oldlvl);
current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry); current = CONTAINING_RECORD(current_entry,KDPC,DpcListEntry);
DPRINT("current %x\n", current); DPRINT("current %x\n", current);
} }
KeReleaseSpinLockFromDpcLevel(&DpcQueueLock);
} }
BOOLEAN KeRemoveQueueDpc(PKDPC Dpc) BOOLEAN KeRemoveQueueDpc(PKDPC Dpc)

View file

@ -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 # 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_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/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 MM_I386_OBJECTS = mm/i386/page.o mm/i386/memsafe.o

View file

@ -121,6 +121,7 @@ VOID MmInitVirtualMemory(boot_param* bp)
// while (inb_p(0x60)!=0x1); inb_p(0x60); // while (inb_p(0x60)!=0x1); inb_p(0x60);
MmInitSectionImplementation(); MmInitSectionImplementation();
MmInitPagingFile();
} }
NTSTATUS MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address) NTSTATUS MmCommitedSectionHandleFault(MEMORY_AREA* MemoryArea, PVOID Address)

View 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);
}

View file

@ -17,14 +17,3 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
NTSTATUS
STDCALL
NtCreatePagingFile (
IN PUNICODE_STRING PageFileName,
IN ULONG MiniumSize,
IN ULONG MaxiumSize,
OUT PULONG ActualSize
)
{
UNIMPLEMENTED;
}

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -31,6 +31,8 @@
/* TYPES ********************************************************************/ /* TYPES ********************************************************************/
#define PORT_ALL_ACCESS (0x1)
#define EPORT_INACTIVE (0) #define EPORT_INACTIVE (0)
#define EPORT_WAIT_FOR_CONNECT (1) #define EPORT_WAIT_FOR_CONNECT (1)
#define EPORT_WAIT_FOR_ACCEPT (2) #define EPORT_WAIT_FOR_ACCEPT (2)
@ -38,34 +40,102 @@
#define EPORT_WAIT_FOR_COMPLETE_CLT (4) #define EPORT_WAIT_FOR_COMPLETE_CLT (4)
#define EPORT_CONNECTED (5) #define EPORT_CONNECTED (5)
typedef struct _QUEUED_MESSAGE struct _EPORT;
typedef struct _QUEUEDMESSAGE
{ {
LPC_MESSAGE_TYPE Type; struct _EPORT* Sender;
ULONG Length; LIST_ENTRY QueueListEntry;
PVOID Buffer; LPCMESSAGE Message;
DWORD Flags; } QUEUEDMESSAGE, *PQUEUEDMESSAGE;
PEPROCESS Sender;
} QUEUED_MESSAGE, *PQUEUED_MESSAGE;
typedef struct _EPORT typedef struct _EPORT
{ {
KSPIN_LOCK Lock; KSPIN_LOCK Lock;
ULONG State;
KEVENT Event; KEVENT Event;
struct _EPORT* OtherPort; struct _EPORT* OtherPort;
struct _EPORT* NamedPort;
ULONG NumberOfQueuedMessages; ULONG QueueLength;
QUEUED_MESSAGE Msg; LIST_ENTRY QueueListHead;
PEPROCESS ConnectingProcess;
struct _EPORT* ConnectingPort; ULONG ConnectQueueLength;
LIST_ENTRY ConnectQueueListHead;
ULONG MaxDataLength;
ULONG MaxConnectInfoLength;
} EPORT, *PEPORT; } EPORT, *PEPORT;
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
POBJECT_TYPE ExPortType = NULL; POBJECT_TYPE ExPortType = NULL;
static ULONG EiNextLpcMessageId;
/* FUNCTIONS *****************************************************************/ /* 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) VOID NiDeletePort(PVOID ObjectBody)
{ {
} }
@ -124,6 +194,8 @@ NTSTATUS NiInitPort(VOID)
ExPortType->OkayToClose = NULL; ExPortType->OkayToClose = NULL;
ExPortType->Create = NiCreatePort; ExPortType->Create = NiCreatePort;
EiNextLpcMessageId = 0;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
@ -132,26 +204,26 @@ static NTSTATUS NiInitializePort(PEPORT Port)
memset(Port, 0, sizeof(EPORT)); memset(Port, 0, sizeof(EPORT));
KeInitializeSpinLock(&Port->Lock); KeInitializeSpinLock(&Port->Lock);
KeInitializeEvent(&Port->Event, SynchronizationEvent, FALSE); KeInitializeEvent(&Port->Event, SynchronizationEvent, FALSE);
Port->State = EPORT_INACTIVE;
Port->OtherPort = NULL; Port->OtherPort = NULL;
Port->NumberOfQueuedMessages = 0; Port->QueueLength = 0;
Port->ConnectQueueLength = 0;
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle, NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes, POBJECT_ATTRIBUTES ObjectAttributes,
DWORD a3, ULONG MaxConnectInfoLength,
DWORD a4) ULONG MaxDataLength,
ULONG Unknown1)
{ {
PEPORT Port; PEPORT Port;
NTSTATUS Status; NTSTATUS Status;
DPRINT("NtCreaatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer); DPRINT("NtCreatePort() Name %x\n", ObjectAttributes->ObjectName->Buffer);
Port = ObCreateObject(PortHandle, Port = ObCreateObject(PortHandle,
1, // DesiredAccess PORT_ALL_ACCESS,
ObjectAttributes, ObjectAttributes,
ExPortType); ExPortType);
if (Port == NULL) if (Port == NULL)
@ -160,23 +232,131 @@ NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle,
} }
Status = NiInitializePort(Port); Status = NiInitializePort(Port);
Port->MaxConnectInfoLength = 260;
Port->MaxDataLength = 328;
return(Status); return(Status);
} }
NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE PortHandle, NTSTATUS STDCALL NtConnectPort (OUT PHANDLE ConnectedPort,
OUT PHANDLE OurPortHandle, IN PUNICODE_STRING PortName,
DWORD a2, IN PVOID Unknown1,
DWORD a3, IN PLPCSECTIONINFO SectionInfo,
DWORD a4, IN PLPCSECTIONMAPINFO MapInfo,
DWORD a5) 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; NTSTATUS Status;
PEPORT NamedPort; PEPORT NamedPort;
PEPORT OurPort; PEPORT OurPort;
HANDLE OurPortHandle;
LPCMESSAGE Request;
PQUEUEDMESSAGE Reply;
ULONG ConnectInfoLength;
KIRQL oldIrql;
Status = ObReferenceObjectByHandle(PortHandle, DPRINT("NtConnectPort(PortName %w)\n", PortName->Buffer);
1, /* AccessRequired */
/*
* 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, ExPortType,
UserMode, UserMode,
(PVOID*)&NamedPort, (PVOID*)&NamedPort,
@ -186,33 +366,43 @@ NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE PortHandle,
return(Status); 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 * Create a port object for our side of the connection
*/ */
OurPort = ObCreateObject(OurPortHandle, if (AcceptIt != 1)
1, {
NULL, OurPort = ObCreateObject(ServerPortHandle,
ExPortType); PORT_ALL_ACCESS,
NiInitializePort(OurPort); NULL,
ExPortType);
NiInitializePort(OurPort);
}
/* /*
* Connect the two port * Dequeue the connection request
*/ */
OurPort->OtherPort = NamedPort->ConnectingPort; KeAcquireSpinLock(&NamedPort->Lock, &oldIrql);
OurPort->OtherPort->OtherPort = OurPort; ConnectionRequest = EiDequeueConnectMessagePort(OurPort);
OurPort->State = EPORT_WAIT_FOR_COMPLETE_SRV; KeReleaseSpinLock(&NamedPort->Lock, oldIrql);
OurPort->OtherPort->State = EPORT_WAIT_FOR_COMPLETE_CLT;
OurPort->NamedPort = NamedPort; 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; * Connect the two ports
NamedPort->ConnectingPort = NULL; */
OurPort->OtherPort = ConnectionRequest->Sender;
OurPort->OtherPort->OtherPort = OurPort;
EiReplyOrRequestPort(ConnectionRequest->Sender, LpcMessage, LPC_REPLY);
ExFreePool(ConnectionRequest);
ObDereferenceObject(NamedPort); ObDereferenceObject(NamedPort);
@ -226,7 +416,7 @@ NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle)
PEPORT OurPort; PEPORT OurPort;
Status = ObReferenceObjectByHandle(PortHandle, Status = ObReferenceObjectByHandle(PortHandle,
1, /* AccessRequired */ PORT_ALL_ACCESS,
ExPortType, ExPortType,
UserMode, UserMode,
(PVOID*)&OurPort, (PVOID*)&OurPort,
@ -236,148 +426,40 @@ NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle)
return(Status); return(Status);
} }
if (OurPort->State != EPORT_WAIT_FOR_COMPLETE_SRV) KeSetEvent(&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE);
{
ObDereferenceObject(OurPort);
return(Status);
}
OurPort->State = EPORT_CONNECTED; ObDereferenceObject(OurPort);
OurPort->OtherPort->State = EPORT_CONNECTED;
KeSetEvent(&OurPort->NamedPort->Event, IO_NO_INCREMENT, FALSE);
return(STATUS_SUCCESS); 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, NTSTATUS STDCALL NtImpersonateClientOfPort (IN HANDLE PortHandle,
IN PCLIENT_ID ClientId) IN PLPCMESSAGE ClientMessage)
{ {
UNIMPLEMENTED; UNIMPLEMENTED;
} }
NTSTATUS STDCALL NtListenPort (IN HANDLE PortHandle, 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 * FUNCTION: Listen on a named port and wait for a connection attempt
*/ */
{ {
NTSTATUS Status; NTSTATUS Status;
PEPORT Port;
DPRINT("NtListenPort(PortHandle %x, QueueSize %d)\n", for(;;)
PortHandle, QueueSize);
Status = ObReferenceObjectByHandle(PortHandle,
1, /* AccessRequired */
ExPortType,
UserMode,
(PVOID*)&Port,
NULL);
if (!NT_SUCCESS(Status))
{ {
DPRINT("Failed to reference object (status %x)\n", Status = NtReplyWaitReceivePort(PortHandle,
Status); NULL,
return(Status); 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); return(Status);
} }
@ -391,48 +473,153 @@ NTSTATUS STDCALL NtQueryInformationPort (IN HANDLE PortHandle,
UNIMPLEMENTED; UNIMPLEMENTED;
} }
NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle, 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, NTSTATUS STDCALL NtReplyWaitReceivePort (IN HANDLE PortHandle,
IN PLPC_MESSAGE LpcReply, /* guess */ PVOID Unknown,
OUT PLPC_MESSAGE LpcMessage, /* guess */ IN PLPCMESSAGE LpcReply,
OUT PULONG MessageLength /* guess */) OUT PLPCMESSAGE LpcMessage)
{ {
UNIMPLEMENTED; NTSTATUS Status;
} PEPORT Port;
KIRQL oldIrql;
PQUEUEDMESSAGE Request;
NTSTATUS STDCALL NtReplyWaitReplyPort (IN HANDLE PortHandle,
IN OUT PLPC_MESSAGE LpcReply /* guess */) DPRINT("NtReplyWaitReceivePort(PortHandle %x, LpcReply %x, "
{ "LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
UNIMPLEMENTED;
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, NTSTATUS STDCALL NtRequestPort (IN HANDLE PortHandle,
IN PLPC_MESSAGE LpcMessage /* guess */) IN PLPCMESSAGE LpcMessage /* guess */)
{
return(NtRequestWaitReplyPort(PortHandle, NULL, LpcMessage));
}
NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle,
IN OUT PLPC_MESSAGE LpcReply, /* guess */
OUT PLPC_MESSAGE LpcMessage /* guess */)
{ {
NTSTATUS Status; NTSTATUS Status;
PEPORT Port; PEPORT Port;
DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcReply %x, " DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle,
"LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage); LpcMessage);
Status = ObReferenceObjectByHandle(PortHandle, 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, ExPortType,
UserMode, UserMode,
(PVOID*)&Port, (PVOID*)&Port,
@ -442,50 +629,18 @@ NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle,
return(Status); return(Status);
} }
DPRINT("Port %x Port->OtherPort %x Port->OtherPort->OtherPort %x\n",
Port, Port->OtherPort, Port->OtherPort->OtherPort);
if (LpcMessage != NULL) Status = EiReplyOrRequestPort(Port, LpcRequest, LPC_REQUEST);
{ KeSetEvent(&Port->Event, IO_NO_INCREMENT, FALSE);
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);
}
/* if (!NT_SUCCESS(Status))
* If we aren't waiting for a reply then return
*/
if (LpcReply == NULL)
{ {
ObDereferenceObject(Port); 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, KeWaitForSingleObject(&Port->Event,
UserRequest, UserRequest,
@ -493,32 +648,23 @@ NTSTATUS STDCALL NtRequestWaitReplyPort(IN HANDLE PortHandle,
FALSE, FALSE,
NULL); 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); KeAcquireSpinLock(&Port->Lock, &oldIrql);
Message = EiDequeueMessagePort(Port);
LpcReply->Length = Port->Msg.Length; KeReleaseSpinLock(&Port->Lock, oldIrql);
LpcReply->Type = Port->Msg.Type; memcpy(LpcReply, &Message->Message, sizeof(*LpcReply));
memcpy(LpcReply->Buffer, Port->Msg.Buffer, LpcReply->Length); ExFreePool(Message);
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");
return(STATUS_SUCCESS); return(STATUS_SUCCESS);
} }
NTSTATUS STDCALL NtReplyWaitReplyPort(PVOID a, PVOID b)
{
UNIMPLEMENTED;
}
/********************************************************************** /**********************************************************************
* NAME SYSTEM * NAME SYSTEM
* NtReadRequestData NOT EXPORTED * NtReadRequestData NOT EXPORTED

View file

@ -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 * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -67,6 +67,11 @@ PETHREAD PsGetCurrentThread(VOID)
return(CurrentThread); return(CurrentThread);
} }
HANDLE PsGetCurrentThreadId(VOID)
{
return(CurrentThread->Cid.UniqueThread);
}
VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus) VOID PiTerminateProcessThreads(PEPROCESS Process, NTSTATUS ExitStatus)
{ {
KIRQL oldlvl; KIRQL oldlvl;

View file

@ -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 * reactos/ntoskrnl/rtl/interlck.c
* *
@ -9,6 +9,7 @@
#include <ntos.h> #include <ntos.h>
#include <internal/debug.h> #include <internal/debug.h>
#if 0
LONG FASTCALL InterlockedIncrement(PLONG Addend) LONG FASTCALL InterlockedIncrement(PLONG Addend)
{ {
LONG r; LONG r;
@ -24,12 +25,13 @@ LONG FASTCALL InterlockedDecrement(PLONG Addend)
r = (*Addend); r = (*Addend);
return(r); return(r);
} }
#endif
/********************************************************************** /**********************************************************************
* FASTCALL: @InterlockedIncrement@0 * FASTCALL: @InterlockedIncrement@0
* STDCALL : _InterlockedIncrement@4 * STDCALL : _InterlockedIncrement@4
*/ */
#if 0 #if 1
LONG FASTCALL InterlockedIncrement (PLONG Addend); LONG FASTCALL InterlockedIncrement (PLONG Addend);
/* /*
* FUNCTION: Increments a caller supplied variable of type LONG as an * FUNCTION: Increments a caller supplied variable of type LONG as an
@ -78,7 +80,7 @@ __asm__(
* FASTCALL: @InterlockedDecrement@0 * FASTCALL: @InterlockedDecrement@0
* STDCALL : _InterlockedDecrement@4 * STDCALL : _InterlockedDecrement@4
*/ */
#if 0 #if 1
LONG FASTCALL InterlockedDecrement(PLONG Addend); LONG FASTCALL InterlockedDecrement(PLONG Addend);
__asm__("\n\t.global _InterlockedDecrement@4\n\t" __asm__("\n\t.global _InterlockedDecrement@4\n\t"
"_InterlockedDecrement@4:\n\t" "_InterlockedDecrement@4:\n\t"