__PdxSerializeProcessData and __PdxUnserializeProcessData calls
authorKJK::Hyperion <hackbunny@reactos.org>
Sun, 10 Mar 2002 17:04:07 +0000 (17:04 +0000)
committerKJK::Hyperion <hackbunny@reactos.org>
Sun, 10 Mar 2002 17:04:07 +0000 (17:04 +0000)
svn path=/trunk/; revision=2692

posix/lib/psxdll/misc/pdata.c [new file with mode: 0644]

diff --git a/posix/lib/psxdll/misc/pdata.c b/posix/lib/psxdll/misc/pdata.c
new file mode 100644 (file)
index 0000000..143972e
--- /dev/null
@@ -0,0 +1,419 @@
+/* $Id: pdata.c,v 1.1 2002/03/10 17:04:07 hyperion Exp $
+ */
+/*
+ * COPYRIGHT:   See COPYING in the top level directory
+ * PROJECT:     ReactOS POSIX+ Subsystem
+ * FILE:        subsys/psx/lib/psxdll/misc/pdata.c
+ * PURPOSE:     Process data management
+ * PROGRAMMER:  KJK::Hyperion <noog@libero.it>
+ * UPDATE HISTORY:
+ *              06/03/2002: Created
+ *              07/03/2002: Added __PdxUnserializeProcessData() (KJK::Hyperion
+ *                          <noog@libero.it>)
+ */
+
+#include <ddk/ntddk.h>
+#include <string.h>
+#include <psx/fdtable.h>
+#include <psx/pdata.h>
+#include <psx/stdlib.h>
+#include <psx/debug.h>
+
+/* serialize a process data block in a contiguous, page-aligned block, suitable
+   for transfer across processes */
+NTSTATUS
+STDCALL
+__PdxSerializeProcessData
+(
+ IN __PPDX_PDATA ProcessData,
+ OUT __PPDX_SERIALIZED_PDATA *SerializedProcessData
+)
+{
+ __PPDX_SERIALIZED_PDATA pspdProcessData = 0;
+ NTSTATUS  nErrCode;
+ PBYTE     pBufferTail;
+ ULONG     ulAllocSize = sizeof(__PDX_SERIALIZED_PDATA) - 1;
+ size_t   *pnArgLengths;
+ size_t   *pnEnvVarsLengths;
+ int      nEnvVarsCount;
+ int      i;
+
+ /* calculate buffer length */
+ /* FIXME please! this is the most inefficient way to do it */
+
+ /* argv */
+ pnArgLengths = __malloc(ProcessData->ArgCount * sizeof(size_t));
+
+ for(i = 0; i < ProcessData->ArgCount; i ++)
+ {
+  int nStrLen = strlen(ProcessData->ArgVect[i]) + 1;
+  ulAllocSize += nStrLen;
+  pnArgLengths[i] = nStrLen;
+
+  INFO
+  (
+   "argument %d: \"%s\", length %d\n",
+   i,
+   ProcessData->ArgVect[i],
+   nStrLen
+  );
+ }
+
+ /* environ */
+ pnEnvVarsLengths = 0;
+ nEnvVarsCount = 0;
+
+ for(i = 0; *(ProcessData->Environment)[i] != 0; i++)
+ {
+  int nStrLen = strlen(*(ProcessData->Environment)[i]) + 1;
+  ulAllocSize += nStrLen;
+
+  nEnvVarsCount ++;
+  __realloc(pnEnvVarsLengths, nEnvVarsCount * sizeof(size_t));
+  pnEnvVarsLengths[i] = nStrLen;
+
+  INFO
+  (
+   "environment variable %d: \"%s\", length %d\n",
+   i,
+   *(ProcessData->Environment)[i],
+   nStrLen
+  );
+ }
+
+ INFO("(%d environment variables were found)\n", nEnvVarsCount);
+
+ /* current directory */
+ ulAllocSize += ProcessData->CurDir.Length;
+ INFO
+ (
+  "current directory: \"%Z\", length %d\n",
+  &ProcessData->CurDir,
+  ProcessData->CurDir.Length
+ );
+
+ /* root directory */
+ ulAllocSize += ProcessData->RootPath.Length;
+ INFO
+ (
+  "root directory: \"%Z\", length %d\n",
+  &ProcessData->RootPath,
+  ProcessData->RootPath.Length
+ );
+
+ /* file descriptors table */
+ ulAllocSize += sizeof(__fildes_t) * ProcessData->FdTable.AllocatedDescriptors;
+ INFO
+ (
+  "descriptors table contains %d allocated descriptors, combined length %d\n",
+  ProcessData->FdTable.AllocatedDescriptors,
+  sizeof(__fildes_t) * ProcessData->FdTable.AllocatedDescriptors
+ );
+
+ /* extra descriptors data */
+ for(i = 0; ProcessData->FdTable.AllocatedDescriptors; i ++)
+  if(ProcessData->FdTable.Descriptors[i].ExtraData != NULL)
+  {
+   ulAllocSize += ProcessData->FdTable.Descriptors[i].ExtraDataSize;
+
+   INFO
+   (
+    "descriptor %d has %d bytes of associated data\n",
+    i,
+    ProcessData->FdTable.Descriptors[i].ExtraDataSize
+   );
+
+  }
+
+ /* allocate return block */
+ INFO("about to allocate %d bytes\n", ulAllocSize);
+
+ nErrCode = NtAllocateVirtualMemory
+ (
+  NtCurrentProcess(),
+  (PVOID *)&pspdProcessData,
+  0,
+  &ulAllocSize,
+  MEM_COMMIT,
+  PAGE_READWRITE
+ );
+
+ /* failure */
+ if(!NT_SUCCESS(nErrCode))
+ {
+  ERR("NtAllocateVirtualMemory() failed with status 0x%08X\n", nErrCode);
+  __free(pnArgLengths);
+  __free(pnEnvVarsLengths);
+  *SerializedProcessData = 0;
+  return;
+ }
+
+ INFO("%d bytes actually allocated\n", ulAllocSize);
+ pspdProcessData->AllocSize = ulAllocSize;
+
+ /* copy data */
+ /* static data */
+ memcpy(&pspdProcessData->ProcessData, ProcessData, sizeof(__PDX_PDATA));
+
+ /* buffers */
+ pBufferTail = &pspdProcessData->Buffer[0];
+ INFO("buffer tail begins at 0x%08X\n", pBufferTail);
+
+ /* argv */
+ pspdProcessData->ProcessData.ArgVect = 0;
+
+ for(i = 0; i < ProcessData->ArgCount; i ++)
+ {
+  INFO
+  (
+   "copying %d bytes of argument %d (\"%s\") to 0x%08X\n",
+   pnArgLengths[i], 
+   i,
+   ProcessData->ArgVect[i],
+   pBufferTail
+  );
+
+  strncpy(pBufferTail, ProcessData->ArgVect[i], pnArgLengths[i]);
+  pBufferTail += pnArgLengths[i];
+
+  INFO
+  (
+   "buffer tail increased by %d bytes, new tail at 0x%08X\n",
+   pnArgLengths[i],
+   pBufferTail
+  );
+
+ }
+
+ __free(pnArgLengths);
+
+ /* environ */
+ pspdProcessData->ProcessData.Environment = (char ***)nEnvVarsCount;
+
+ for(i = 0; i < nEnvVarsCount; i ++)
+ {
+  INFO
+  (
+   "copying %d bytes of environment variable %d (\"%s\") to 0x%08X\n",
+   pnEnvVarsLengths[i], 
+   i,
+   ProcessData->Environment[i],
+   pBufferTail
+  );
+
+  strncpy(pBufferTail, *ProcessData->Environment[i], pnEnvVarsLengths[i]);
+  pBufferTail += pnEnvVarsLengths[i];
+
+  INFO
+  (
+   "buffer tail increased by %d bytes, new tail at 0x%08X\n",
+   pnEnvVarsLengths[i],
+   pBufferTail
+  );
+ }
+
+ __free(pnEnvVarsLengths);
+
+ /* current directory */
+ INFO
+ (
+  "copying %d bytes of current directory (\"%Z\") to 0x%08X\n",
+  ProcessData->CurDir.Length,
+  &ProcessData->CurDir,
+  pBufferTail
+ );
+
+ memcpy(pBufferTail, ProcessData->CurDir.Buffer, ProcessData->CurDir.Length);
+ pBufferTail += ProcessData->CurDir.Length;
+
+ INFO
+ (
+  "buffer tail increased by %d bytes, new tail at 0x%08X\n",
+  ProcessData->CurDir.Length,
+  pBufferTail
+ );
+
+ /* root directory */
+ INFO
+ (
+  "copying %d bytes of root directory (\"%Z\") to 0x%08X\n",
+  ProcessData->RootPath.Length,
+  &ProcessData->RootPath,
+  pBufferTail
+ );
+
+ memcpy
+ (
+  pBufferTail,
+  ProcessData->RootPath.Buffer,
+  ProcessData->RootPath.Length
+ );
+
+ pBufferTail += ProcessData->RootPath.Length;
+
+ INFO
+ (
+  "buffer tail increased by %d bytes, new tail at 0x%08X\n",
+  ProcessData->RootPath.Length,
+  pBufferTail
+ );
+
+ /* file descriptors table */
+ /* save the offset to the descriptors array */
+ pspdProcessData->ProcessData.FdTable.Descriptors =
+  (PVOID)((ULONG)pBufferTail - (ULONG)pspdProcessData);
+
+ INFO
+ (
+  "descriptors table contains %d allocated descriptors, combined length %d\n",
+  ProcessData->FdTable.AllocatedDescriptors,
+  sizeof(__fildes_t) * ProcessData->FdTable.AllocatedDescriptors
+ );
+
+ memcpy
+ (
+  pBufferTail,
+  ProcessData->FdTable.Descriptors,
+  sizeof(__fildes_t) * ProcessData->FdTable.AllocatedDescriptors
+ );
+
+ pBufferTail +=
+  sizeof(__fildes_t) * ProcessData->FdTable.AllocatedDescriptors;
+
+ INFO
+ (
+  "buffer tail increased by %d bytes, new tail at 0x%08X\n",
+  sizeof(__fildes_t) * ProcessData->FdTable.AllocatedDescriptors,
+  pBufferTail
+ );
+
+ /* extra descriptors data */
+ for(i = 0; ProcessData->FdTable.AllocatedDescriptors; i ++)
+  if(ProcessData->FdTable.Descriptors[i].ExtraData != 0)
+  {
+   INFO
+   (
+    "descriptor %d has %d bytes of associated data\n",
+    i,
+    ProcessData->FdTable.Descriptors[i].ExtraDataSize
+   );
+
+   memcpy
+   (
+    pBufferTail,
+    ProcessData->FdTable.Descriptors[i].ExtraData,
+    ProcessData->FdTable.Descriptors[i].ExtraDataSize
+   );
+
+   pBufferTail += ProcessData->FdTable.Descriptors[i].ExtraDataSize;
+
+   INFO
+   (
+    "buffer tail increased by %d bytes, new tail at 0x%08X\n",
+    ProcessData->FdTable.Descriptors[i].ExtraDataSize,
+    pBufferTail
+   );
+  }
+
+ /* success */
+ *SerializedProcessData = pspdProcessData;
+}
+
+/* unserialize a process data block. Dynamic data will be moved into the default
+   heap */
+NTSTATUS
+STDCALL
+__PdxUnserializeProcessData
+(
+ IN OUT __PPDX_SERIALIZED_PDATA *SerializedProcessData,
+ OUT __PPDX_PDATA *ProcessData OPTIONAL
+)
+{
+ int i;
+ int nEnvVarsCount;
+ __PPDX_PDATA ppdReturnBlock;
+ BOOLEAN      bInPlace;
+ PBYTE        pBufferTail;
+
+ /* no return buffer */
+ if(NULL == ProcessData)
+ {
+  /* perform an in-place conversion */
+  ppdReturnBlock = &((*SerializedProcessData)->ProcessData);
+  bInPlace = TRUE;
+ }
+ else
+ {
+  /* use the provided return buffer */
+  ppdReturnBlock = *ProcessData;
+  bInPlace = FALSE;
+ }
+
+ /* non in-place conversion: copy static data */
+ if(!bInPlace)
+ {
+  memcpy(ppdReturnBlock, *SerializedProcessData, sizeof(*ppdReturnBlock));
+ }
+
+ pBufferTail = &((*SerializedProcessData)->Buffer[0]);
+
+ /* allocate arguments array */
+ ppdReturnBlock->ArgVect = __malloc(ppdReturnBlock->ArgCount * sizeof(char *));
+
+ /* duplicate arguments */
+ for(i = 0; i < ppdReturnBlock->ArgCount; i ++)
+ {
+  int nStrLen = strlen(pBufferTail) + 1;
+  ppdReturnBlock->ArgVect[i] = __malloc(nStrLen);
+  strncpy(ppdReturnBlock->ArgVect[i], pBufferTail, nStrLen);
+  pBufferTail += nStrLen;
+ }
+
+ /* allocate environment array */
+ nEnvVarsCount = ppdReturnBlock->Environment;
+ ppdReturnBlock->Environment = __malloc(nEnvVarsCount * sizeof(char *));
+
+ /* duplicate environment */
+ for(i = 0; i < nEnvVarsCount; i ++)
+ {
+  int nStrLen = strlen(pBufferTail) + 1;
+  ppdReturnBlock->Environment[i] = __malloc(nStrLen);
+  strncpy(ppdReturnBlock->Environment[i], pBufferTail, nStrLen);
+  pBufferTail += nStrLen;
+ }
+
+ /* static buffer for path conversions */
+ ppdReturnBlock->NativePathBuffer.Buffer = __malloc(0xFFFF);
+ ppdReturnBlock->NativePathBuffer.Length = 0;
+ ppdReturnBlock->NativePathBuffer.MaximumLength = 0xFFFF;
+
+ /* current directory */
+ ppdReturnBlock->CurDir.Buffer = __malloc(ppdReturnBlock->CurDir.Length);
+ ppdReturnBlock->CurDir.MaximumLength = ppdReturnBlock->CurDir.Length;
+ memcpy(ppdReturnBlock->CurDir.Buffer, pBufferTail, ppdReturnBlock->CurDir.Length);
+ pBufferTail += ppdReturnBlock->CurDir.Length;
+
+ /* root directory */
+ ppdReturnBlock->RootPath.Buffer = __malloc(ppdReturnBlock->RootPath.Length);
+ ppdReturnBlock->RootPath.MaximumLength = ppdReturnBlock->RootPath.Length;
+ memcpy(ppdReturnBlock->RootPath.Buffer, pBufferTail, ppdReturnBlock->RootPath.Length);
+ pBufferTail += ppdReturnBlock->RootPath.Length;
+
+ /* file descriptors table */
+ ppdReturnBlock->FdTable.Descriptors = __malloc(ppdReturnBlock->FdTable.AllocatedDescriptors * sizeof(__fildes_t));
+ memcpy(ppdReturnBlock->FdTable.Descriptors, pBufferTail, ppdReturnBlock->FdTable.AllocatedDescriptors * sizeof(__fildes_t));
+ pBufferTail += ppdReturnBlock->FdTable.AllocatedDescriptors * sizeof(__fildes_t);
+
+ for(i = 0; i < ppdReturnBlock->FdTable.AllocatedDescriptors; i ++)
+ {
+  if(ppdReturnBlock->FdTable.Descriptors[i].ExtraData != 0)
+  {
+   ppdReturnBlock->FdTable.Descriptors[i].ExtraData = __malloc(ppdReturnBlock->FdTable.Descriptors[i].ExtraDataSize);
+   memcpy(ppdReturnBlock->FdTable.Descriptors[i].ExtraData, pBufferTail, ppdReturnBlock->FdTable.Descriptors[i].ExtraDataSize);
+   pBufferTail += ppdReturnBlock->FdTable.Descriptors[i].ExtraDataSize;
+  }
+ }
+}
+
+/* EOF */
+