Modified LPC implementation to be closer to nt.
authorDavid Welch <welch@cwcom.net>
Fri, 10 Dec 1999 17:04:37 +0000 (17:04 +0000)
committerDavid Welch <welch@cwcom.net>
Fri, 10 Dec 1999 17:04:37 +0000 (17:04 +0000)
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

22 files changed:
reactos/apps/tests/args/makefile
reactos/apps/tests/hello/hello.c
reactos/apps/tests/hello/makefile
reactos/apps/tests/lpc/lpcclt.c
reactos/apps/tests/lpc/lpcsrv.c
reactos/apps/utils/cat/cat.c
reactos/apps/utils/cat/makefile
reactos/drivers/dd/blue/blue.c
reactos/include/ddk/psfuncs.h
reactos/include/ddk/pstypes.h
reactos/include/ddk/zw.h
reactos/include/ddk/zwtypes.h
reactos/include/internal/mm.h
reactos/ntoskrnl/hal/x86/spinlock.c
reactos/ntoskrnl/ke/dpc.c
reactos/ntoskrnl/makefile_rex
reactos/ntoskrnl/mm/mm.c
reactos/ntoskrnl/mm/pagefile.c [new file with mode: 0644]
reactos/ntoskrnl/mm/paging.c
reactos/ntoskrnl/nt/port.c
reactos/ntoskrnl/ps/thread.c
reactos/ntoskrnl/rtl/interlck.c

index aec0488..c39a847 100644 (file)
@@ -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
 
index 294b00c..e178e98 100644 (file)
@@ -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);
 }
index e4e6176..954f6d4 100644 (file)
@@ -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
index ef8500c..92abb31 100644 (file)
@@ -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");
index edb668a..a281312 100644 (file)
@@ -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];
-       
-       Request.Buffer = buffer;
+       LPCMESSAGE Request;
        
-       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);
      }
 }
index 441b5b3..305828e 100644 (file)
@@ -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);
index 9447417..10b35f2 100644 (file)
@@ -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
index d0cb02f..43cf63a 100644 (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
  * 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
 
index a910eed..6d96213 100644 (file)
@@ -1,6 +1,7 @@
 
 
 HANDLE PsGetCurrentProcessId(VOID);
+HANDLE PsGetCurrentThreadId(VOID);
 
 /*
  * FUNCTION: Creates a thread which executes in kernel mode
index bb47340..2c5a23f 100644 (file)
@@ -232,8 +232,6 @@ typedef struct _KTHREAD
 
    /* Provisionally added by David Welch */
    hal_thread_state                   Context;
-//   LIST_ENTRY Entry;
-//   ULONG LastTick;
 
 } KTHREAD, *PKTHREAD;
 
index 26aa51a..7146e08 100644 (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
  * 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 */
index 336fc0f..6fa911d 100644 (file)
@@ -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
-
-} LPC_MESSAGE_TYPE;
-
-typedef struct _LPC_MESSAGE
-{
-   LPC_MESSAGE_TYPE    Type;
-   ULONG                       Length;
-   PVOID                       Buffer; /* Page aligned! */
-   DWORD                       Flags; /* To be defined */
-} LPC_MESSAGE, * PLPC_MESSAGE;
+#define MAX_MESSAGE_DATA   (0x130)
+
+#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 _LPCSECTIONINFO
+{
+   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 )
index 2400c6b..995d5a1 100644 (file)
@@ -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
index 21bf6e1..72ab206 100644 (file)
@@ -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);
index fcc18c7..414e7a4 100644 (file)
@@ -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)
index f5bd63c..64c9e9d 100644 (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
 #
@@ -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
 
index 346e9fc..142acad 100644 (file)
@@ -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 (file)
index 0000000..2c96adc
--- /dev/null
@@ -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);
+}
index 9b1c23b..c6ff3a3 100644 (file)
 
 /* FUNCTIONS *****************************************************************/
 
-NTSTATUS
-STDCALL
-NtCreatePagingFile (
-       IN      PUNICODE_STRING PageFileName,
-       IN      ULONG           MiniumSize,
-       IN      ULONG           MaxiumSize,
-       OUT     PULONG          ActualSize
-       )
-{
-       UNIMPLEMENTED;
-}
index 212a3b3..44971b1 100644 (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
  * 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)
 #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,105 +232,20 @@ NTSTATUS STDCALL NtCreatePort(PHANDLE PortHandle,
      }
    
    Status = NiInitializePort(Port);
-     
-   return(Status);
-}
-
-NTSTATUS STDCALL NtAcceptConnectPort (IN HANDLE        PortHandle,
-                                     OUT PHANDLE OurPortHandle,
-                                     DWORD a2,
-                                     DWORD     a3,
-                                     DWORD     a4,
-                                     DWORD     a5)
-{
-   NTSTATUS Status;
-   PEPORT NamedPort;
-   PEPORT OurPort;
-   
-   Status = ObReferenceObjectByHandle(PortHandle,
-                                     1,   /* AccessRequired */
-                                     ExPortType,
-                                     UserMode,
-                                     (PVOID*)&NamedPort,
-                                     NULL);
-   if (!NT_SUCCESS(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
-    */
-   OurPort = ObCreateObject(OurPortHandle,
-                           1,
-                           NULL,
-                           ExPortType);
-   NiInitializePort(OurPort);
+   Port->MaxConnectInfoLength = 260;
+   Port->MaxDataLength = 328;
    
-   /*
-    * Connect the two port
-    */
-   OurPort->OtherPort = NamedPort->ConnectingPort;  
-   OurPort->OtherPort->OtherPort = OurPort;
-   OurPort->State = EPORT_WAIT_FOR_COMPLETE_SRV;
-   OurPort->OtherPort->State = EPORT_WAIT_FOR_COMPLETE_CLT;
-   OurPort->NamedPort = NamedPort;
-   
-   NamedPort->State = EPORT_INACTIVE;
-   NamedPort->ConnectingProcess = NULL;
-   NamedPort->ConnectingPort = NULL;
-   
-   ObDereferenceObject(NamedPort);
-    
-   return(STATUS_SUCCESS);
-}
-
-
-NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle)
-{
-   NTSTATUS Status;
-   PEPORT OurPort;
-   
-   Status = ObReferenceObjectByHandle(PortHandle,
-                                     1,   /* AccessRequired */
-                                     ExPortType,
-                                     UserMode,
-                                     (PVOID*)&OurPort,
-                                     NULL);
-   if (!NT_SUCCESS(Status))
-     {
-       return(Status);
-     }
-   
-   if (OurPort->State != EPORT_WAIT_FOR_COMPLETE_SRV)
-     {
-       ObDereferenceObject(OurPort);
-       return(Status);
-     }
-   
-   OurPort->State = EPORT_CONNECTED;
-   OurPort->OtherPort->State = EPORT_CONNECTED;
-   
-   KeSetEvent(&OurPort->NamedPort->Event, IO_NO_INCREMENT, FALSE);
-   
-   return(STATUS_SUCCESS);
+   return(Status);
 }
 
-
 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)
+                               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
@@ -268,13 +255,25 @@ NTSTATUS STDCALL NtConnectPort (OUT       PHANDLE                 ConnectedPort,
    PEPORT NamedPort;
    PEPORT OurPort;
    HANDLE OurPortHandle;
+   LPCMESSAGE Request;
+   PQUEUEDMESSAGE Reply;
+   ULONG ConnectInfoLength;
+   KIRQL oldIrql;
    
    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,
-                                   1,  /* DesiredAccess */
+                                   PORT_ALL_ACCESS,  /* DesiredAccess */
                                    ExPortType,
                                    UserMode,
                                    NULL,
@@ -285,47 +284,57 @@ NTSTATUS STDCALL NtConnectPort (OUT       PHANDLE                 ConnectedPort,
        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,
+                           PORT_ALL_ACCESS,
+                           NULL,
                            ExPortType);
    NiInitializePort(OurPort);
-   OurPort->NamedPort = NamedPort;
    
    /*
-    * 
+    * Create a request message
     */
-   NamedPort->ConnectingProcess = PsGetCurrentProcess();
-   NamedPort->State = EPORT_WAIT_FOR_ACCEPT;
-   NamedPort->ConnectingPort = OurPort;
+   Request.ActualMessageLength = ConnectInfoLength;
+   Request.TotalMessageLength = sizeof(LPCMESSAGE) + ConnectInfoLength;
+   Request.SharedSectionSize = 0;
+   memcpy(Request.MessageData, ConnectInfo, ConnectInfoLength);
    
    /*
-    * Tell the other side they have a connection
+    * Queue the message to the named port
     */
-   KeSetEvent(&NamedPort->Event, IO_NO_INCREMENT, FALSE);
+   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(&NamedPort->Event,
+   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");
    
@@ -333,51 +342,124 @@ NTSTATUS STDCALL NtConnectPort (OUT      PHANDLE                 ConnectedPort,
 }
 
 
-NTSTATUS STDCALL NtImpersonateClientOfPort (IN HANDLE          PortHandle,
-                                           IN  PCLIENT_ID      ClientId)
+NTSTATUS STDCALL NtAcceptConnectPort (PHANDLE ServerPortHandle,
+                                     HANDLE NamedPortHandle,
+                                     PLPCMESSAGE LpcMessage,
+                                     ULONG AcceptIt,
+                                     ULONG Unknown2,
+                                     PLPCSECTIONMAPINFO MapInfo)
 {
-   UNIMPLEMENTED;
+   NTSTATUS Status;
+   PEPORT NamedPort;
+   PEPORT OurPort;
+   PQUEUEDMESSAGE ConnectionRequest;
+   KIRQL oldIrql;
+   
+   Status = ObReferenceObjectByHandle(NamedPortHandle,
+                                     PORT_ALL_ACCESS,
+                                     ExPortType,
+                                     UserMode,
+                                     (PVOID*)&NamedPort,
+                                     NULL);
+   if (!NT_SUCCESS(Status))
+     {
+       return(Status);
+     }
+   
+   /*
+    * Create a port object for our side of the connection
+    */
+   if (AcceptIt != 1)
+     {
+       OurPort = ObCreateObject(ServerPortHandle,
+                                PORT_ALL_ACCESS,
+                                NULL,
+                                ExPortType);
+       NiInitializePort(OurPort);
+     }
+   
+   /*
+    * Dequeue the connection request
+    */
+   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);
+     }
+   
+   /*
+    * Connect the two ports
+    */
+   OurPort->OtherPort = ConnectionRequest->Sender;
+   OurPort->OtherPort->OtherPort = OurPort;
+   EiReplyOrRequestPort(ConnectionRequest->Sender, LpcMessage, LPC_REPLY);
+   ExFreePool(ConnectionRequest);
+   
+   ObDereferenceObject(NamedPort);
+    
+   return(STATUS_SUCCESS);
 }
 
 
-NTSTATUS STDCALL NtListenPort (IN HANDLE PortHandle,
-                              IN DWORD QueueSize       /* guess */)
-/*
- * FUNCTION: Listen on a named port and wait for a connection attempt
- */
+NTSTATUS STDCALL NtCompleteConnectPort (HANDLE PortHandle)
 {
    NTSTATUS Status;
-   PEPORT Port;
-   
-   DPRINT("NtListenPort(PortHandle %x, QueueSize %d)\n",
-         PortHandle, QueueSize);
+   PEPORT OurPort;
    
    Status = ObReferenceObjectByHandle(PortHandle,
-                                     1,   /* AccessRequired */
+                                     PORT_ALL_ACCESS,
                                      ExPortType,
                                      UserMode,
-                                     (PVOID*)&Port,
+                                     (PVOID*)&OurPort,
                                      NULL);
    if (!NT_SUCCESS(Status))
      {
-       DPRINT("Failed to reference object (status %x)\n",
-              Status);
        return(Status);
      }
    
-   if (Port->State != EPORT_INACTIVE)
-     {
-       ObDereferenceObject(Port);
-       return(STATUS_INVALID_PARAMETER);
-     }
+   KeSetEvent(&OurPort->OtherPort->Event, IO_NO_INCREMENT, FALSE);
+   
+   ObDereferenceObject(OurPort);
    
-   Port->State = EPORT_WAIT_FOR_CONNECT;
-   Status = KeWaitForSingleObject(&Port->Event,
-                                 UserRequest,
-                                 UserMode,
-                                 FALSE,
-                                 NULL);
+   return(STATUS_SUCCESS);
+}
+
+NTSTATUS STDCALL NtImpersonateClientOfPort (IN HANDLE          PortHandle,
+                                           IN  PLPCMESSAGE ClientMessage)
+{
+   UNIMPLEMENTED;
+}
+
+
+NTSTATUS STDCALL NtListenPort (IN HANDLE PortHandle,
+                              IN PLPCMESSAGE ConnectMsg)
+/*
+ * FUNCTION: Listen on a named port and wait for a connection attempt
+ */
+{
+   NTSTATUS Status;
    
+   for(;;)
+     {
+       Status = NtReplyWaitReceivePort(PortHandle,
+                                       NULL,
+                                       NULL,
+                                       ConnectMsg);
+       if (!NT_SUCCESS(Status) || 
+           ConnectMsg->MessageType == LPC_CONNECTION_REQUEST)
+         {
+            break;
+         }
+     }
    return(Status);
 }
 
@@ -391,48 +473,153 @@ NTSTATUS STDCALL NtQueryInformationPort (IN HANDLE PortHandle,
    UNIMPLEMENTED;
 }
 
-NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle,
-                             IN PLPC_MESSAGE LpcReply  /* guess */)
-{
-       UNIMPLEMENTED;
-}
 
-
-NTSTATUS STDCALL NtReplyWaitReceivePort ( IN   HANDLE          PortHandle,
-                                        IN     PLPC_MESSAGE    LpcReply,       /* guess */
-                                        OUT    PLPC_MESSAGE    LpcMessage,     /* guess */
-                                        OUT    PULONG          MessageLength   /* guess */)
+NTSTATUS STDCALL NtReplyPort (IN HANDLE PortHandle,
+                             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 NtReplyWaitReplyPort (IN      HANDLE          PortHandle,
-                                      IN OUT   PLPC_MESSAGE    LpcReply        /* guess */)
+NTSTATUS STDCALL NtReplyWaitReceivePort (IN    HANDLE          PortHandle,
+                                        PVOID Unknown,
+                                        IN     PLPCMESSAGE     LpcReply,     
+                                        OUT    PLPCMESSAGE     LpcMessage)
 {
-   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 */)
+                               IN PLPCMESSAGE  LpcMessage      /* guess */)
 {
-   return(NtRequestWaitReplyPort(PortHandle, NULL, LpcMessage));
+   NTSTATUS Status;
+   PEPORT Port;
+   
+   DPRINT("NtRequestPort(PortHandle %x LpcMessage %x)\n", PortHandle, 
+         LpcMessage);
+   
+   Status = ObReferenceObjectByHandle(PortHandle,
+                                     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,
-                                       IN OUT PLPC_MESSAGE LpcReply,   /* guess */
-                                       OUT PLPC_MESSAGE LpcMessage     /* guess */)
+                                       PLPCMESSAGE LpcRequest,    
+                                       PLPCMESSAGE LpcReply)
 {
    NTSTATUS Status;
    PEPORT Port;
+   PQUEUEDMESSAGE Message;
+   KIRQL oldIrql;
    
-   DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcReply %x, "
-         "LpcMessage %x)\n", PortHandle, LpcReply, LpcMessage);
+   DPRINT("NtRequestWaitReplyPort(PortHandle %x, LpcRequest %x, "
+         "LpcReply %x)\n", PortHandle, LpcRequest, LpcReply);
    
    Status = ObReferenceObjectByHandle(PortHandle,
-                                     1,   /* AccessRequired */
+                                     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
index d191443..ff11439 100644 (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
  * 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;
index afecc4f..4c00d32 100644 (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
  *
@@ -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"