From cabe5710906fefa6ab4e726bdbdcaab95a21fd5b Mon Sep 17 00:00:00 2001 From: "KJK::Hyperion" Date: Sun, 10 Mar 2002 17:04:07 +0000 Subject: [PATCH] __PdxSerializeProcessData and __PdxUnserializeProcessData calls svn path=/trunk/; revision=2692 --- posix/lib/psxdll/misc/pdata.c | 419 ++++++++++++++++++++++++++++++++++ 1 file changed, 419 insertions(+) create mode 100644 posix/lib/psxdll/misc/pdata.c diff --git a/posix/lib/psxdll/misc/pdata.c b/posix/lib/psxdll/misc/pdata.c new file mode 100644 index 00000000000..143972e1d8e --- /dev/null +++ b/posix/lib/psxdll/misc/pdata.c @@ -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 + * UPDATE HISTORY: + * 06/03/2002: Created + * 07/03/2002: Added __PdxUnserializeProcessData() (KJK::Hyperion + * ) + */ + +#include +#include +#include +#include +#include +#include + +/* 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 */ +