+/* $Id: $\r
+ *\r
+ * init.c - VMS Enviroment Subsystem Server - Initialization\r
+ * \r
+ * ReactOS Operating System\r
+ * \r
+ * --------------------------------------------------------------------\r
+ *\r
+ * This software is free software; you can redistribute it and/or\r
+ * modify it under the terms of the GNU General Public License as\r
+ * published by the Free Software Foundation; either version 2 of the\r
+ * License, or (at your option) any later version.\r
+ *\r
+ * This software is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\r
+ * General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with this software; see the file COPYING.LIB. If not, write\r
+ * to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge,\r
+ * MA 02139, USA. \r
+ *\r
+ * --------------------------------------------------------------------\r
+ */\r
+#include "vmsss.h"\r
+\r
+//#define NDEBUG\r
+#include <debug.h>\r
+\r
+\r
+HANDLE VmsSbApiPort = (HANDLE) 0; // \VMS\SbApiPort\r
+HANDLE SmCalledBack = (HANDLE) 0; // signalled when SM connects to \VMS\SbApiPort\r
+HANDLE SmVmsSbApiPort = (HANDLE) 0; // server side (our one) port for SM conn request\r
+HANDLE SmApiPort = (HANDLE) 0; // client side of \SmApiPort\r
+\r
+HANDLE VmsSessionPort = (HANDLE) 0; // pseudo terminals call here for a new session\r
+HANDLE VmsApiPort = (HANDLE) 0; // VMS processes call here for system calls\r
+\r
+/**********************************************************************\r
+ * SB API Port Thread\r
+ *********************************************************************/\r
+static VOID STDCALL\r
+VmsSbApiPortThread (PVOID x)\r
+{\r
+ HANDLE Port = (HANDLE) x;\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+ LPC_MAX_MESSAGE ConnectionRequest = {{0}};\r
+\r
+ DPRINT("VMS: %s: called\n", __FUNCTION__);\r
+ \r
+ Status = NtListenPort (Port, & ConnectionRequest.Header);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: NtListenPort failed (Status=0x%08lx)\n",\r
+ __FUNCTION__, Status);\r
+ }else{\r
+ DPRINT("VMS: %s received a connection request\n", __FUNCTION__);\r
+ Status = NtAcceptConnectPort (& SmVmsSbApiPort,\r
+ 0,\r
+ & ConnectionRequest.Header,\r
+ TRUE, /* accept it */\r
+ NULL,\r
+ NULL);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: NtAcceptConnectPort failed (Status=0x%08lx)\n",\r
+ __FUNCTION__, Status);\r
+ }else{\r
+ DPRINT("VMS: %s accepted the connection request\n", __FUNCTION__);\r
+ Status = NtCompleteConnectPort (SmVmsSbApiPort);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: NtCompleteConnectPort failed (Status=0x%08lx)\n",\r
+ __FUNCTION__, Status);\r
+ }else{\r
+ DPRINT("VMS: %s completed the connection request\n", __FUNCTION__);\r
+ Status = NtSetEvent (SmCalledBack, NULL);\r
+ DPRINT("VMS: %s signalled the main thread to initialize the subsystem\n", __FUNCTION__);\r
+ DPRINT("VMS: %s enters main loop\n", __FUNCTION__);\r
+ while (TRUE)\r
+ {\r
+ }\r
+ }\r
+ }\r
+ }\r
+ NtClose (Port);\r
+ NtTerminateThread (NtCurrentThread(), Status);\r
+}\r
+/**********************************************************************\r
+ * API Port Thread\r
+ *********************************************************************/\r
+static VOID STDCALL\r
+VmsApiPortThread (PVOID x)\r
+{\r
+ HANDLE Port = (HANDLE) x;\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+ \r
+ DPRINT("VMS: %s: called\n", __FUNCTION__);\r
+ while (TRUE)\r
+ {\r
+ }\r
+ NtClose (Port);\r
+ NtTerminateThread (NtCurrentThread(), Status);\r
+}\r
+\r
+/**********************************************************************\r
+ * NAME PRIVATE\r
+ * VmspCreateObDirectory/1\r
+ */\r
+static NTSTATUS FASTCALL\r
+VmspCreateObDirectory (PWSTR DirectoryName)\r
+{\r
+ UNICODE_STRING usDirectoryName = {0};\r
+ OBJECT_ATTRIBUTES DirectoryAttributes = {0};\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+ HANDLE hDirectory = (HANDLE) 0;\r
+\r
+ DPRINT("VMS: %s called\n", __FUNCTION__);\r
+\r
+ RtlInitUnicodeString (& usDirectoryName,\r
+ DirectoryName);\r
+ InitializeObjectAttributes (& DirectoryAttributes,\r
+ & usDirectoryName,\r
+ 0, NULL, NULL);\r
+ Status = NtCreateDirectoryObject (& hDirectory,\r
+ DIRECTORY_CREATE_SUBDIRECTORY,\r
+ & DirectoryAttributes);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: NtCreateDirectoryObject failed (Status=0x%08lx)\n",\r
+ __FUNCTION__, Status);\r
+ return Status;\r
+ }\r
+ NtClose (hDirectory);\r
+ return STATUS_SUCCESS;\r
+}\r
+\r
+/**********************************************************************\r
+ * NAME PRIVATE\r
+ * VmspCreatePort/1\r
+ */\r
+static NTSTATUS STDCALL\r
+VmspCreatePort (IN OUT PHANDLE pPortHandle,\r
+ IN PWSTR PortName,\r
+ IN ULONG MaxDataSize,\r
+ IN ULONG MaxMessageSize,\r
+ IN PTHREAD_START_ROUTINE ListeningThread)\r
+{\r
+ UNICODE_STRING usPortName = {0};\r
+ OBJECT_ATTRIBUTES PortAttributes = {0};\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+\r
+ DPRINT("VMS: %s called\n", __FUNCTION__);\r
+\r
+ if(NULL == ListeningThread)\r
+ {\r
+ return STATUS_INVALID_PARAMETER;\r
+ }\r
+ \r
+ RtlInitUnicodeString (& usPortName, PortName);\r
+ Status = NtCreatePort (pPortHandle,\r
+ & PortAttributes,\r
+ MaxDataSize,\r
+ MaxMessageSize,\r
+ 0);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: NtCreatePort failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
+ return Status;\r
+ }\r
+ Status = RtlCreateUserThread (NtCurrentProcess(),\r
+ NULL,\r
+ FALSE,\r
+ 0, 0, 0,\r
+ ListeningThread,\r
+ pPortHandle,\r
+ NULL, NULL);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: RtlCreateUserThread failed (Status=0x%08lx)\n", __FUNCTION__, Status);\r
+ return Status;\r
+ }\r
+ return Status;\r
+}\r
+\r
+/**********************************************************************\r
+ * VmsInitializeServer/0\r
+ */\r
+NTSTATUS\r
+VmsInitializeServer(VOID)\r
+{\r
+ NTSTATUS Status = STATUS_SUCCESS;\r
+ WCHAR NameBuffer [32];\r
+\r
+ DPRINT("VMS: %s called\n", __FUNCTION__);\r
+\r
+ /* Create the \VMS directory */\r
+ wcscpy (NameBuffer, L"\\VMS");\r
+ Status = VmspCreateObDirectory (NameBuffer);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: VmspCreateObDirectory failed!\n", __FUNCTION__);\r
+ }else{\r
+ /* Create the \VMS\SbApiPort port */\r
+ wcscat (NameBuffer, L"\\SbApiPort");\r
+ Status = VmspCreatePort (& VmsSbApiPort,\r
+ NameBuffer,\r
+ 0x104,\r
+ 0x148,\r
+ VmsSbApiPortThread);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS %s: VmspCreatePort failed (Status=%08lx)\n",\r
+ __FUNCTION__, Status);\r
+ return Status;\r
+ }else{\r
+ OBJECT_ATTRIBUTES EventAttributes;\r
+ \r
+ InitializeObjectAttributes (& EventAttributes,\r
+ NULL,\r
+ 0,\r
+ NULL,\r
+ NULL);\r
+ Status = NtCreateEvent (& SmCalledBack,\r
+ EVENT_ALL_ACCESS,\r
+ & EventAttributes,\r
+ SynchronizationEvent,\r
+ FALSE);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: NtCreateEvent failed (Status=0x%08lx)\n",\r
+ __FUNCTION__, Status);\r
+ return Status;\r
+ }else{\r
+ UNICODE_STRING VmsSbApiPortName;\r
+\r
+ RtlInitUnicodeString (& VmsSbApiPortName, NameBuffer);\r
+ Status = SmConnectApiPort (& VmsSbApiPortName,\r
+ VmsSbApiPort,\r
+ 77, /* VMS CUI */\r
+ & SmApiPort);\r
+ if(!NT_SUCCESS(Status))\r
+ {\r
+ DPRINT("VMS: %s: SmConnectApiPort failed (Status=0x%08lx)\n",\r
+ __FUNCTION__, Status);\r
+ return Status;\r
+ }else{\r
+ Status = NtWaitForSingleObject (SmCalledBack,\r
+ FALSE,\r
+ INFINITE);\r
+ /* OK initialize the VMS subsystem */\r
+ wcscpy (& NameBuffer[4], L"\\ApiPort");\r
+ Status = VmspCreatePort (& VmsApiPort,\r
+ NameBuffer,\r
+ 0x104,\r
+ 0x148,\r
+ VmsApiPortThread);\r
+ /* TODO */\r
+ \r
+ wcscpy (& NameBuffer[4], L"\\Session");\r
+ Status = VmspCreateObDirectory (NameBuffer);\r
+ /* TODO */\r
+\r
+ Status = SmCompleteSession (SmApiPort,\r
+ VmsSbApiPort,\r
+ VmsApiPort);\r
+ }\r
+ }\r
+ }\r
+ }\r
+ return STATUS_SUCCESS; \r
+}\r
+\r
+/* EOF */\r