mirror of https://github.com/tongzx/nt5src
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
643 lines
20 KiB
643 lines
20 KiB
/*++
|
|
|
|
Copyright (c) 2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
persist.c
|
|
|
|
Abstract:
|
|
|
|
General structure persistence functions.
|
|
|
|
Author:
|
|
|
|
Aghajanyan Souren 27-Mar-2001
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#include "persist.h"
|
|
|
|
BOOL MayExtraMemRequire(
|
|
IN PFIELD_DESCRIPTION FieldsDescription
|
|
)
|
|
{
|
|
FIELD_DESCRIPTION * FieldPtr;
|
|
|
|
for(FieldPtr = FieldsDescription; FieldPtr->Offset != END_OF_STRUCT; FieldPtr++){
|
|
if(!FieldPtr->FieldDescription && FieldPtr->ArraySizeFieldOffset && FieldPtr->byValue){
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
UINT
|
|
GetExtraMemRequirements(
|
|
IN BYTE * StructurePtr,
|
|
IN PFIELD_DESCRIPTION FieldsDescription
|
|
)
|
|
/*
|
|
This function provide additional memory requirements,
|
|
only in case when structure has variable size.
|
|
And have to be declared by PERSIST_FIELD_BY_VALUE_NESTED_TYPE_CYCLE
|
|
For example:
|
|
struct VariableSizeStruct{
|
|
......
|
|
UINT uiNumberOfItem;
|
|
ITEM items[1];
|
|
};
|
|
PERSIST_FIELD_BY_VALUE_NESTED_TYPE_CYCLE(VariableSizeStruct, ITEM, items, uiNumberOfItem)
|
|
*/
|
|
{
|
|
UINT Len;
|
|
FIELD_DESCRIPTION * FieldPtr;
|
|
UINT ExtraBytes = 0;
|
|
UINT uiItemCount;
|
|
|
|
MYASSERT(StructurePtr);
|
|
|
|
for(FieldPtr = FieldsDescription; FieldPtr->Offset != END_OF_STRUCT; FieldPtr++){
|
|
if(!FieldPtr->FieldDescription &&
|
|
FieldPtr->ArraySizeFieldOffset &&
|
|
FieldPtr->byValue &&
|
|
FieldPtr->Size){
|
|
uiItemCount = *(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, StructurePtr, FieldPtr->ArraySizeFieldOffset));
|
|
ExtraBytes += uiItemCount? FieldPtr->Size * (uiItemCount - FieldPtr->InitialNumberOfItem): 0;
|
|
}
|
|
}
|
|
|
|
return ExtraBytes;
|
|
}
|
|
|
|
BOOL
|
|
SerializeStore(
|
|
IN OUT BYTE * BufferMain,
|
|
IN BYTE * StructurePtr,
|
|
IN PFIELD_DESCRIPTION FieldsDescription,
|
|
IN OUT UINT * uiHowUsed
|
|
)
|
|
{
|
|
UINT i;
|
|
UINT iLen;
|
|
UINT Size = 0;
|
|
BYTE * SubStruct;
|
|
FIELD_DESCRIPTION * FieldPtr;
|
|
|
|
if(!uiHowUsed){
|
|
uiHowUsed = &Size;
|
|
}
|
|
|
|
MYASSERT(StructurePtr);
|
|
|
|
for(FieldPtr = FieldsDescription; FieldPtr->Offset != END_OF_STRUCT; FieldPtr++){
|
|
if(FieldPtr->FieldDescription)
|
|
{
|
|
iLen = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, StructurePtr, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
|
|
if(FieldPtr->byValue){
|
|
SubStruct = GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset);
|
|
MYASSERT(SubStruct);
|
|
}
|
|
else{
|
|
SubStruct = GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset);
|
|
if(BufferMain){
|
|
*(BufferMain + *uiHowUsed) = (SubStruct && iLen);
|
|
}
|
|
++*uiHowUsed;
|
|
if(!SubStruct || !iLen){
|
|
continue;
|
|
}
|
|
}
|
|
|
|
for(i = 0; i < iLen;
|
|
i++, SubStruct += FieldPtr->Size + GetExtraMemRequirements(SubStruct, FieldPtr->FieldDescription))
|
|
{
|
|
if(!SerializeStore(BufferMain,
|
|
SubStruct,
|
|
FieldPtr->FieldDescription,
|
|
uiHowUsed)){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
if(FieldPtr->IsString != NoStr)
|
|
{
|
|
SubStruct = GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset);
|
|
if(!SubStruct){
|
|
SubStruct = (BYTE*)(FieldPtr->IsString == AnsiStr? "": (char*)L"");
|
|
}
|
|
|
|
if(FieldPtr->IsString == AnsiStr){
|
|
iLen = (strlen((PCSTR)SubStruct) + 1) * sizeof(CHAR);
|
|
}
|
|
else{
|
|
iLen = (wcslen((PWSTR)SubStruct) + 1) * sizeof(WCHAR);
|
|
}
|
|
|
|
if(BufferMain){
|
|
memcpy((BYTE *)(BufferMain + *uiHowUsed), SubStruct, iLen);
|
|
}
|
|
|
|
*uiHowUsed += iLen;
|
|
}
|
|
else
|
|
{
|
|
if(FieldPtr->Size)
|
|
{
|
|
iLen = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, StructurePtr, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
if(BufferMain){
|
|
memcpy((char *)(BufferMain + *uiHowUsed),
|
|
GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset),
|
|
iLen * FieldPtr->Size);
|
|
}
|
|
*uiHowUsed += iLen * FieldPtr->Size;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD
|
|
CalcSignature(
|
|
IN BYTE * BufferPtr,
|
|
IN UINT Lenght
|
|
)
|
|
{
|
|
UINT i;
|
|
UINT iLen = Lenght >> 2;
|
|
UINT iRest = Lenght & 3;
|
|
UINT uiSignature = 0;
|
|
|
|
for(i = 0; i < iLen; i++){
|
|
uiSignature ^= ((DWORD *)BufferPtr)[i];
|
|
}
|
|
|
|
if(iRest){
|
|
uiSignature ^= (((DWORD *)BufferPtr)[iLen]) & (0xffffffff >> ((sizeof(DWORD) - iRest) << 3));
|
|
}
|
|
|
|
return uiSignature;
|
|
}
|
|
|
|
PersistResultsEnum
|
|
PersistStore(
|
|
OUT BYTE ** BufferPtr,
|
|
OUT UINT *Size,
|
|
IN BYTE * StructurePtr,
|
|
IN PSTRUCT_DEFINITION StructDefinitionPtr
|
|
)
|
|
{
|
|
BYTE * buffer = NULL;
|
|
BYTE * memBlock = NULL;
|
|
UINT uiBufferSize = 0;
|
|
PPERSIST_HEADER pPersistHeader;
|
|
PFIELD_DESCRIPTION FieldsDescription;
|
|
PersistResultsEnum result = Persist_Success;
|
|
|
|
if(!BufferPtr || !Size || !StructurePtr || !StructDefinitionPtr){
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
MYASSERT(FALSE);
|
|
return Persist_BadParameters;
|
|
}
|
|
|
|
FieldsDescription = StructDefinitionPtr->FieldDescriptions;
|
|
if(!FieldsDescription){
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
MYASSERT(FALSE);
|
|
return Persist_BadParameters;
|
|
}
|
|
|
|
__try{
|
|
uiBufferSize = sizeof(PERSIST_HEADER);
|
|
if(!SerializeStore(NULL, StructurePtr, FieldsDescription, &uiBufferSize)){
|
|
SetLastError(ERROR_ACCESS_DENIED);
|
|
return Persist_Fail;
|
|
}
|
|
|
|
memBlock = (BYTE *)MemAllocUninit(uiBufferSize);
|
|
|
|
if(!memBlock){
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
MYASSERT(FALSE);
|
|
return Persist_Fail;
|
|
}
|
|
|
|
buffer = memBlock;
|
|
*BufferPtr = memBlock;
|
|
*Size = uiBufferSize;
|
|
|
|
pPersistHeader = (PPERSIST_HEADER)memBlock;
|
|
buffer += sizeof(PERSIST_HEADER);
|
|
|
|
pPersistHeader->dwVersion = StructDefinitionPtr->dwVersion;
|
|
pPersistHeader->dwReserved = 0;
|
|
|
|
uiBufferSize = 0;
|
|
if(!SerializeStore(buffer, StructurePtr, FieldsDescription, &uiBufferSize)){
|
|
FreeMem(memBlock);
|
|
SetLastError(ERROR_ACCESS_DENIED);
|
|
return Persist_Fail;
|
|
}
|
|
|
|
pPersistHeader->dwSignature = CalcSignature(buffer, uiBufferSize);
|
|
|
|
SetLastError(ERROR_SUCCESS);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER){
|
|
if(memBlock){
|
|
FreeMem(memBlock);
|
|
}
|
|
result = Persist_Fail;
|
|
SetLastError(ERROR_ACCESS_DENIED);
|
|
}
|
|
|
|
|
|
return result;
|
|
}
|
|
|
|
BOOL
|
|
SerializeLoad(
|
|
IN BYTE * BufferMain,
|
|
IN OUT BYTE * StructurePtr,
|
|
IN PFIELD_DESCRIPTION FieldsDescription,
|
|
IN OUT UINT * uiHowUsed,
|
|
IN BOOL bRestoreOnlyByValue
|
|
)
|
|
{
|
|
FIELD_DESCRIPTION * FieldPtr;
|
|
UINT i;
|
|
UINT iLen;
|
|
UINT Size = 0;
|
|
BYTE * SubStruct;
|
|
BYTE * OriginalBuffer;
|
|
UINT sizeValue;
|
|
UINT uiPrevValue;
|
|
|
|
if(!uiHowUsed){
|
|
uiHowUsed = &Size;
|
|
}
|
|
|
|
MYASSERT(StructurePtr);
|
|
|
|
for(FieldPtr = FieldsDescription; FieldPtr->Offset != END_OF_STRUCT; FieldPtr++){
|
|
if(FieldPtr->FieldDescription)
|
|
{
|
|
iLen = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, StructurePtr, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
|
|
if(FieldPtr->byValue){
|
|
SubStruct = GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset);
|
|
}
|
|
else{
|
|
if(bRestoreOnlyByValue){
|
|
continue;
|
|
}
|
|
|
|
if(!*(BufferMain + (*uiHowUsed)++)){
|
|
*GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(DWORD*, StructurePtr, FieldPtr->Offset) =
|
|
(DWORD)NULL;
|
|
continue;
|
|
}
|
|
|
|
MYASSERT(FieldPtr->Size && iLen);
|
|
|
|
sizeValue = FieldPtr->Size * iLen;
|
|
|
|
SubStruct = (BYTE *)MemAllocUninit(sizeValue);
|
|
if(!SubStruct){
|
|
return FALSE;
|
|
}
|
|
|
|
if(MayExtraMemRequire(FieldPtr->FieldDescription)){
|
|
OriginalBuffer = SubStruct;
|
|
uiPrevValue = *uiHowUsed;
|
|
for(i = 0; i < iLen; i++, SubStruct += FieldPtr->Size)
|
|
{
|
|
if(!SerializeLoad(BufferMain,
|
|
SubStruct,
|
|
FieldPtr->FieldDescription,
|
|
&uiPrevValue,
|
|
TRUE)){
|
|
return FALSE;
|
|
}
|
|
sizeValue += GetExtraMemRequirements(SubStruct, FieldPtr->FieldDescription);
|
|
}
|
|
FreeMem(OriginalBuffer);
|
|
|
|
SubStruct = (BYTE *)MemAllocZeroed(sizeValue);
|
|
if(!SubStruct){
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
*GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(DWORD*, StructurePtr, FieldPtr->Offset) =
|
|
(DWORD)SubStruct;
|
|
}
|
|
|
|
for(i = 0; i < iLen;
|
|
i++, SubStruct += FieldPtr->Size + GetExtraMemRequirements(SubStruct, FieldPtr->FieldDescription))
|
|
{
|
|
if(!SerializeLoad(BufferMain,
|
|
SubStruct,
|
|
FieldPtr->FieldDescription,
|
|
uiHowUsed,
|
|
FALSE)){
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
if(FieldPtr->IsString != NoStr){
|
|
if(bRestoreOnlyByValue){
|
|
continue;
|
|
}
|
|
|
|
if(FieldPtr->IsString == AnsiStr){
|
|
iLen = strlen((char *)(BufferMain + *uiHowUsed)) + sizeof(CHAR);
|
|
}
|
|
else{
|
|
iLen = (wcslen((WCHAR *)(BufferMain + *uiHowUsed)) + 1) * sizeof(WCHAR);
|
|
}
|
|
MYASSERT(iLen);
|
|
|
|
if(iLen != (FieldPtr->IsString == AnsiStr? sizeof(CHAR): sizeof(WCHAR)))
|
|
{
|
|
SubStruct = (BYTE *)MemAllocUninit(iLen);
|
|
if(!SubStruct){
|
|
return FALSE;
|
|
}
|
|
memcpy((BYTE *)SubStruct, (BYTE *)(BufferMain + *uiHowUsed), iLen);
|
|
}
|
|
else{
|
|
SubStruct = NULL;
|
|
}
|
|
|
|
*GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(DWORD *, StructurePtr, FieldPtr->Offset) = (DWORD)SubStruct;
|
|
|
|
*uiHowUsed += iLen;
|
|
}
|
|
else
|
|
{
|
|
if(FieldPtr->Size)
|
|
{
|
|
iLen = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, StructurePtr, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
sizeValue = iLen * FieldPtr->Size;
|
|
if(iLen > 1 && bRestoreOnlyByValue){
|
|
continue;
|
|
}
|
|
|
|
memcpy(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset),
|
|
(char *)(BufferMain + *uiHowUsed),
|
|
sizeValue);
|
|
*uiHowUsed += sizeValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
PersistResultsEnum
|
|
PersistLoad(
|
|
IN BYTE * BufferPtr,
|
|
IN UINT Size,
|
|
OUT BYTE * StructurePtr,
|
|
IN PSTRUCT_DEFINITION StructDefinitionPtr
|
|
)
|
|
{
|
|
UINT uiBufferSize = 0;
|
|
PPERSIST_HEADER pPersistHeader;
|
|
PFIELD_DESCRIPTION FieldsDescription;
|
|
PersistResultsEnum result = Persist_Success;
|
|
|
|
if(!BufferPtr || !Size || !StructurePtr || !StructDefinitionPtr){
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
MYASSERT(FALSE);
|
|
return Persist_BadParameters;
|
|
}
|
|
|
|
FieldsDescription = StructDefinitionPtr->FieldDescriptions;
|
|
if(!FieldsDescription){
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
MYASSERT(FALSE);
|
|
return Persist_BadParameters;
|
|
}
|
|
|
|
__try{
|
|
pPersistHeader = (PPERSIST_HEADER)BufferPtr;
|
|
|
|
if(pPersistHeader->dwVersion != StructDefinitionPtr->dwVersion){
|
|
SetLastError(ERROR_ACCESS_DENIED);
|
|
MYASSERT(FALSE);
|
|
return Persist_WrongVersion;
|
|
}
|
|
|
|
BufferPtr += sizeof(PERSIST_HEADER);
|
|
Size -= sizeof(PERSIST_HEADER);
|
|
if(pPersistHeader->dwSignature != CalcSignature(BufferPtr, Size)){
|
|
SetLastError(ERROR_CRC);
|
|
return Persist_WrongSignature;
|
|
}
|
|
|
|
uiBufferSize = 0;
|
|
//Top structure cannot be variable size
|
|
if(!SerializeLoad(BufferPtr, StructurePtr, FieldsDescription, &uiBufferSize, FALSE)){
|
|
SetLastError(ERROR_ACCESS_DENIED);
|
|
return Persist_Fail;
|
|
}
|
|
|
|
SetLastError(ERROR_SUCCESS);
|
|
}
|
|
__except(EXCEPTION_EXECUTE_HANDLER){
|
|
result = Persist_Fail;
|
|
SetLastError(ERROR_ACCESS_DENIED);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
VOID
|
|
PersistReleaseMemory(
|
|
IN BYTE * StructurePtr,
|
|
IN PFIELD_DESCRIPTION FieldsDescription
|
|
)
|
|
{
|
|
UINT i;
|
|
UINT iLen;
|
|
FIELD_DESCRIPTION * FieldPtr;
|
|
BYTE * SubStruct;
|
|
|
|
if(!StructurePtr || !FieldsDescription){
|
|
return;
|
|
}
|
|
|
|
for(FieldPtr = FieldsDescription; FieldPtr->Offset != END_OF_STRUCT; FieldPtr++){
|
|
if(FieldPtr->FieldDescription){
|
|
iLen = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, StructurePtr, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
|
|
if(!iLen){
|
|
continue;
|
|
}
|
|
|
|
if(FieldPtr->byValue){
|
|
SubStruct = GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset);
|
|
}
|
|
else{
|
|
SubStruct = GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset);
|
|
}
|
|
|
|
if(!SubStruct){
|
|
continue;
|
|
}
|
|
|
|
for(i = 0; i < iLen; i++, SubStruct += FieldPtr->Size){
|
|
PersistReleaseMemory(SubStruct, FieldPtr->FieldDescription);
|
|
}
|
|
|
|
if(!FieldPtr->byValue){
|
|
FreeMem(GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, StructurePtr, FieldPtr->Offset));
|
|
}
|
|
}
|
|
else{
|
|
if(FieldPtr->IsString != NoStr){
|
|
SubStruct = (BYTE *)GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(PCSTR, StructurePtr, FieldPtr->Offset);
|
|
if(SubStruct){
|
|
FreeMem(SubStruct);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL
|
|
CompareStructures(
|
|
IN BYTE * pStructure1,
|
|
IN BYTE * pStructure2,
|
|
IN PFIELD_DESCRIPTION FieldsDescription
|
|
)
|
|
{
|
|
UINT i;
|
|
UINT iLen1;
|
|
UINT iLen2;
|
|
FIELD_DESCRIPTION * FieldPtr;
|
|
BYTE * pSubStruct1;
|
|
BYTE * pSubStruct2;
|
|
|
|
if(!pStructure1 || !pStructure2 || !FieldsDescription){
|
|
return FALSE;
|
|
}
|
|
|
|
for(FieldPtr = FieldsDescription; FieldPtr->Offset != END_OF_STRUCT; FieldPtr++){
|
|
if(FieldPtr->FieldDescription){
|
|
iLen1 = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, pStructure1, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
|
|
iLen2 = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, pStructure2, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
|
|
if(iLen1 != iLen2){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
if(!iLen1){
|
|
continue;
|
|
}
|
|
|
|
if(FieldPtr->byValue){
|
|
pSubStruct1 = GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, pStructure1, FieldPtr->Offset);
|
|
pSubStruct2 = GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, pStructure2, FieldPtr->Offset);
|
|
}
|
|
else{
|
|
pSubStruct1 = GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, pStructure1, FieldPtr->Offset);
|
|
pSubStruct2 = GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, pStructure2, FieldPtr->Offset);
|
|
}
|
|
|
|
if(!pSubStruct1 || !pSubStruct2){
|
|
if(pSubStruct1 != pSubStruct2){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
for(i = 0; i < iLen1;
|
|
i++,
|
|
pSubStruct1 += FieldPtr->Size + GetExtraMemRequirements(pSubStruct1, FieldPtr->FieldDescription),
|
|
pSubStruct2 += FieldPtr->Size + GetExtraMemRequirements(pSubStruct2, FieldPtr->FieldDescription)){
|
|
if(!CompareStructures(pSubStruct1, pSubStruct2, FieldPtr->FieldDescription)){
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
if(FieldPtr->IsString != NoStr)
|
|
{
|
|
pSubStruct1 = GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, pStructure1, FieldPtr->Offset);
|
|
pSubStruct2 = GET_STRUCT_MEMBER_BYREF_FROM_OFFSET(BYTE*, pStructure2, FieldPtr->Offset);
|
|
if(!pSubStruct1 || !pSubStruct2){
|
|
if(pSubStruct1 != pSubStruct2){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if(FieldPtr->IsString == AnsiStr){
|
|
if(strcmp((LPCSTR)pSubStruct1, (LPCSTR)pSubStruct1)){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else{
|
|
if(wcscmp((LPCWSTR)pSubStruct1, (LPCWSTR)pSubStruct1)){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
else{
|
|
iLen1 = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, pStructure1, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
iLen2 = FieldPtr->ArraySizeFieldOffset?
|
|
*(GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(UINT*, pStructure2, FieldPtr->ArraySizeFieldOffset)):
|
|
1;
|
|
|
|
if(iLen1 != iLen2){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
pSubStruct1 = GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, pStructure1, FieldPtr->Offset);
|
|
pSubStruct2 = GET_STRUCT_MEMBER_BYVALUE_FROM_OFFSET(BYTE*, pStructure2, FieldPtr->Offset);
|
|
if(memcmp(pSubStruct1, pSubStruct2, iLen1 * FieldPtr->Size)){
|
|
MYASSERT(FALSE);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|