mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 01:24:38 +00:00
__PdxSerializeProcessData and __PdxUnserializeProcessData calls
svn path=/trunk/; revision=2692
This commit is contained in:
parent
e2f5d4b2f6
commit
cabe571090
1 changed files with 419 additions and 0 deletions
419
posix/lib/psxdll/misc/pdata.c
Normal file
419
posix/lib/psxdll/misc/pdata.c
Normal file
|
@ -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 */
|
||||
|
Loading…
Reference in a new issue