DirServicesPriv.cpp [plain text]
#include "DirServicesPriv.h"
#include "DirServicesUtils.h"
#include "DirServicesTypesPriv.h"
#include "PrivateTypes.h"
#include "CDSRefMap.h"
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include "CRCCalc.h"
extern pid_t gProcessPID;
extern CDSRefMap *gFWRefMap;
extern CDSRefTable *gFWRefTable;
static const UInt32 kFWBuffPad = 16;
tDirStatus VerifyTDataBuff ( tDataBuffer *inBuff, tDirStatus inNullErr, tDirStatus inEmptyErr )
{
if ( inBuff == nil )
{
return( inNullErr );
}
if ( inBuff->fBufferSize == 0 )
{
return( inEmptyErr );
}
return( eDSNoErr );
}
tDirStatus VerifyTNodeList ( tDataList *inDataList, tDirStatus inNullErr, tDirStatus inEmptyErr )
{
if ( inDataList == nil )
{
return( inNullErr );
}
if ( inDataList->fDataNodeCount == 0 )
{
return( inEmptyErr );
}
if ( dsGetDataLength( inDataList ) == 0 )
{
return( inEmptyErr );
}
return( eDSNoErr );
}
tDirStatus IsStdBuffer ( tDataBufferPtr inOutDataBuff )
{
tDirStatus outResult = eDSNoErr;
SInt32 siResult = eDSNoErr;
CBuff inBuff;
UInt32 bufTag = 0;
try
{
if ( inOutDataBuff == nil ) throw( (SInt32)eDSEmptyBuffer );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
siResult = inBuff.Initialize( inOutDataBuff );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inBuff.GetBuffType( &bufTag );
if ( siResult != eDSNoErr ) throw( siResult );
if ( (bufTag != 'StdA') && (bufTag != 'StdB') && (bufTag != 'DbgA') && (bufTag != 'DbgB') )
{
outResult = eDSInvalidTag;
}
}
catch( SInt32 err )
{
outResult = (tDirStatus)err;
}
return( outResult );
}
tDirStatus IsFWReference ( UInt32 inRef )
{
tDirStatus outResult = eDSInvalidReference;
if ((inRef & 0x00300000) != 0)
{
outResult = eDSNoErr;
}
return( outResult );
}
tDirStatus ExtractRecordEntry ( tDataBufferPtr inOutDataBuff,
UInt32 inRecordEntryIndex,
tAttributeListRef *outAttributeListRef,
tRecordEntryPtr *outRecEntryPtr )
{
SInt32 siResult = eDSNoErr;
UInt32 uiIndex = 0;
UInt32 uiCount = 0;
UInt32 uiOffset = 0;
UInt32 uberOffset = 0;
char *pData = nil;
tRecordEntryPtr pRecEntry = nil;
CBuff inBuff;
UInt32 offset = 0;
UInt16 usTypeLen = 0;
char *pRecType = nil;
UInt16 usNameLen = 0;
char *pRecName = nil;
UInt16 usAttrCnt = 0;
UInt32 buffLen = 0;
UInt32 bufTag = 0;
try
{
if ( inOutDataBuff == nil ) throw( (SInt32)eDSNullDataBuff );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
siResult = inBuff.Initialize( inOutDataBuff );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inBuff.GetBuffType( &bufTag );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inBuff.GetDataBlockCount( &uiCount );
if ( siResult != eDSNoErr ) throw( siResult );
uiIndex = inRecordEntryIndex;
if ( uiIndex == 0 ) throw( (SInt32)eDSInvalidIndex );
if ( uiIndex > uiCount ) throw( (SInt32)eDSIndexOutOfRange );
pData = inBuff.GetDataBlock( uiIndex, &uberOffset );
if ( pData == nil ) throw( (SInt32)eDSCorruptBuffer );
buffLen = inBuff.GetDataBlockLength( uiIndex );
pData += 4;
offset = 0;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usTypeLen, pData, 2 );
pData += 2;
offset += 2;
pRecType = pData;
pData += usTypeLen;
offset += usTypeLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usNameLen, pData, 2 );
pData += 2;
offset += 2;
pRecName = pData;
pData += usNameLen;
offset += usNameLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrCnt, pData, 2 );
pRecEntry = (tRecordEntry *)::calloc( 1, sizeof( tRecordEntry ) + usNameLen + usTypeLen + 4 + kFWBuffPad );
pRecEntry->fRecordNameAndType.fBufferSize = usNameLen + usTypeLen + 4 + kFWBuffPad;
pRecEntry->fRecordNameAndType.fBufferLength = usNameLen + usTypeLen + 4;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData, &usNameLen, 2 );
uiOffset += 2;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, pRecName, usNameLen );
uiOffset += usNameLen;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, &usTypeLen, 2 );
uiOffset += 2;
::memcpy( pRecEntry->fRecordNameAndType.fBufferData + uiOffset, pRecType, usTypeLen );
pRecEntry->fRecordAttributeCount = usAttrCnt;
siResult = gFWRefTable->NewAttrListRef( outAttributeListRef, 0, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
if ( (bufTag == 'DbgA') || (bufTag == 'DbgB') )
{
syslog(LOG_CRIT, "DS:dsGetRecordEntry:ExtractRecordEntry:gFWRefTable->NewAttrListRef ref = %d", *outAttributeListRef);
}
siResult = gFWRefTable->SetOffset( *outAttributeListRef, eAttrListRefType, uberOffset + offset + 4, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->SetBufTag( *outAttributeListRef, eAttrListRefType, bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
*outRecEntryPtr = pRecEntry;
pRecEntry = nil;
}
catch( SInt32 err )
{
siResult = err;
}
if (pRecEntry != nil)
{
dsDeallocRecordEntry(0,pRecEntry);
pRecEntry = nil;
}
return( (tDirStatus)siResult );
}
tDirStatus ExtractAttributeEntry ( tDataBufferPtr inOutDataBuff,
tAttributeListRef inAttrListRef,
UInt32 inAttrInfoIndex,
tAttributeValueListRef *outAttrValueListRef,
tAttributeEntryPtr *outAttrInfoPtr )
{
SInt32 siResult = eDSNoErr;
UInt16 usAttrTypeLen = 0;
UInt16 usAttrCnt = 0;
UInt16 usAttrLen16 = 0;
UInt32 usAttrLen = 0;
UInt16 usValueCnt = 0;
UInt16 usValueLen16 = 0;
UInt32 usValueLen = 0;
UInt32 i = 0;
UInt32 uiIndex = 0;
UInt32 uiAttrEntrySize = 0;
UInt32 uiOffset = 0;
UInt32 uiTotalValueSize = 0;
UInt32 offset = 0;
UInt32 buffSize = 0;
UInt32 buffLen = 0;
char *p = nil;
char *pAttrType = nil;
tAttributeEntryPtr pAttribInfo = nil;
UInt32 attrListOffset = 0;
UInt32 bufTag = 0;
try
{
siResult = gFWRefTable->GetOffset( inAttrListRef, eAttrListRefType, &attrListOffset, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->GetBufTag( inAttrListRef, eAttrListRefType, &bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
uiIndex = inAttrInfoIndex;
if (uiIndex == 0) throw( (SInt32)eDSInvalidIndex );
if ( inOutDataBuff == nil ) throw( (SInt32)eDSNullDataBuff );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
buffSize = inOutDataBuff->fBufferSize;
p = inOutDataBuff->fBufferData + attrListOffset;
offset = attrListOffset;
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrCnt, p, 2 );
if (uiIndex > usAttrCnt) throw( (SInt32)eDSIndexOutOfRange );
p += 2;
offset += 2;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
for ( i = 1; i < uiIndex; i++ )
{
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen16, p, 2 );
p += 2 + usAttrLen16;
offset += 2 + usAttrLen16;
}
uiOffset = offset;
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen16, p, 2 );
p += 2;
offset += 2;
usAttrLen = (UInt32)usAttrLen16;
}
else
{
for ( i = 1; i < uiIndex; i++ )
{
if (4 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4 + usAttrLen;
offset += 4 + usAttrLen;
}
uiOffset = offset;
if (4 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4;
offset += 4;
}
buffLen = offset + usAttrLen;
if ( buffLen > buffSize ) throw ( (SInt32)eDSInvalidBuffFormat );
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrTypeLen, p, 2 );
pAttrType = p + 2;
p += 2 + usAttrTypeLen;
offset += 2 + usAttrTypeLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
for ( i = 0; i < usValueCnt; i++ )
{
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen16, p, 2 );
p += 2 + usValueLen16;
offset += 2 + usValueLen16;
uiTotalValueSize += usValueLen16;
}
}
else
{
for ( i = 0; i < usValueCnt; i++ )
{
if (4 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4 + usValueLen;
offset += 4 + usValueLen;
uiTotalValueSize += usValueLen;
}
}
uiAttrEntrySize = sizeof( tAttributeEntry ) + usAttrTypeLen + kFWBuffPad;
pAttribInfo = (tAttributeEntry *)::calloc( 1, uiAttrEntrySize );
pAttribInfo->fAttributeValueCount = usValueCnt;
pAttribInfo->fAttributeDataSize = uiTotalValueSize;
pAttribInfo->fAttributeValueMaxSize = 512; pAttribInfo->fAttributeSignature.fBufferSize = usAttrTypeLen + kFWBuffPad;
pAttribInfo->fAttributeSignature.fBufferLength = usAttrTypeLen;
::memcpy( pAttribInfo->fAttributeSignature.fBufferData, pAttrType, usAttrTypeLen );
siResult = gFWRefTable->NewAttrValueRef( outAttrValueListRef, 0, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
if ( (bufTag == 'DbgA') || (bufTag == 'DbgB') )
{
syslog(LOG_CRIT, "DS:dsGetAttributeEntry:ExtractAttributeEntry:gFWRefTable->NewAttrValueRef ref = %d", *outAttrValueListRef);
}
siResult = gFWRefTable->SetOffset( *outAttrValueListRef, eAttrValueListRefType, uiOffset, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->SetBufTag( *outAttrValueListRef, eAttrValueListRefType, bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
*outAttrInfoPtr = pAttribInfo;
pAttribInfo = nil;
}
catch( SInt32 err )
{
siResult = err;
}
if (pAttribInfo != nil)
{
dsDeallocAttributeEntry(0,pAttribInfo);
pAttribInfo = nil;
}
return( (tDirStatus)siResult );
}
tDirStatus ExtractAttributeValue ( tDataBufferPtr inOutDataBuff,
tAttributeValueListRef inAttrValueListRef,
UInt32 inAttrValueIndex,
tAttributeValueEntryPtr *outAttrValue )
{
SInt32 siResult = eDSNoErr;
UInt16 usValueCnt = 0;
UInt16 usValueLen16 = 0;
UInt32 usValueLen = 0;
UInt16 usAttrNameLen = 0;
UInt32 i = 0;
UInt32 uiIndex = 0;
UInt32 offset = 0;
char *p = nil;
tAttributeValueEntry *pAttrValue = nil;
UInt32 buffSize = 0;
UInt32 buffLen = 0;
UInt16 attrLen16 = 0;
UInt32 attrLen = 0;
UInt32 attrValueOffset = 0;
UInt32 bufTag = 0;
try
{
siResult = gFWRefTable->GetOffset( inAttrValueListRef, eAttrValueListRefType, &attrValueOffset, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->GetBufTag( inAttrValueListRef, eAttrValueListRefType, &bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
uiIndex = inAttrValueIndex;
if (uiIndex == 0) throw( (SInt32)eDSInvalidIndex );
if ( inOutDataBuff == nil ) throw( (SInt32)eDSNullDataBuff );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
buffSize = inOutDataBuff->fBufferSize;
p = inOutDataBuff->fBufferData + attrValueOffset;
offset = attrValueOffset;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &attrLen16, p, 2 );
buffLen = attrLen16 + attrValueOffset + 2;
if (buffLen > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
p += 2;
offset += 2;
}
else
{
if (4 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &attrLen, p, 4 );
buffLen = attrLen + attrValueOffset + 4;
if (buffLen > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
p += 4;
offset += 4;
}
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrNameLen, p, 2 );
p += 2 + usAttrNameLen;
offset += 2 + usAttrNameLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
if (uiIndex > usValueCnt) throw( (SInt32)eDSIndexOutOfRange );
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
for ( i = 1; i < uiIndex; i++ )
{
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen16, p, 2 );
p += 2 + usValueLen16;
offset += 2 + usValueLen16;
}
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen16, p, 2 );
p += 2;
offset += 2;
usValueLen = (UInt32)usValueLen16;
}
else
{
for ( i = 1; i < uiIndex; i++ )
{
if (4 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4 + usValueLen;
offset += 4 + usValueLen;
}
if (4 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4;
offset += 4;
}
pAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + usValueLen + kFWBuffPad );
pAttrValue->fAttributeValueData.fBufferSize = usValueLen + kFWBuffPad;
pAttrValue->fAttributeValueData.fBufferLength = usValueLen;
if ( usValueLen + offset > buffLen ) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( pAttrValue->fAttributeValueData.fBufferData, p, usValueLen );
pAttrValue->fAttributeValueID = CalcCRCWithLength( pAttrValue->fAttributeValueData.fBufferData, usValueLen );
*outAttrValue = pAttrValue;
pAttrValue = nil;
}
catch( SInt32 err )
{
siResult = err;
}
if (pAttrValue != nil)
{
dsDeallocAttributeValueEntry(0,pAttrValue);
pAttrValue = nil;
}
return( (tDirStatus)siResult );
}
tDirStatus ExtractNextAttributeEntry ( tDataBufferPtr inOutDataBuff,
tAttributeListRef inAttrListRef,
UInt32 inAttrInfoIndex,
SInt32 *inOutOffset,
tAttributeValueListRef *outAttrValueListRef,
tAttributeEntryPtr *outAttrInfoPtr )
{
SInt32 siResult = eDSNoErr;
UInt16 usAttrTypeLen = 0;
UInt16 usAttrCnt = 0;
UInt16 usAttrLen16 = 0;
UInt32 usAttrLen = 0;
UInt16 usValueCnt = 0;
UInt32 uiIndex = 0;
UInt32 uiAttrEntrySize = 0;
UInt32 uiOffset = 0;
UInt32 uiTotalValueSize = 0;
UInt32 offset = 0;
UInt32 buffSize = 0;
UInt32 buffLen = 0;
char *p = nil;
char *pAttrType = nil;
tAttributeEntryPtr pAttribInfo = nil;
UInt32 attrListOffset = 0;
UInt32 bufTag = 0;
try
{
siResult = gFWRefTable->GetOffset( inAttrListRef, eAttrListRefType, &attrListOffset, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->GetBufTag( inAttrListRef, eAttrListRefType, &bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
uiIndex = inAttrInfoIndex;
if (uiIndex == 0) throw( (SInt32)eDSInvalidIndex );
if ( inOutDataBuff == nil ) throw( (SInt32)eDSNullDataBuff );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
buffSize = inOutDataBuff->fBufferSize;
p = inOutDataBuff->fBufferData + attrListOffset;
offset = attrListOffset;
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrCnt, p, 2 );
if (uiIndex > usAttrCnt) throw( (SInt32)eDSIndexOutOfRange );
p += 2;
offset += 2;
p += *inOutOffset;
offset += *inOutOffset;
uiOffset = offset;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen16, p, 2 );
p += 2;
offset += 2;
usAttrLen = (UInt32)usAttrLen16;
}
else
{
if (4 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrLen, p, 4 );
p += 4;
offset += 4;
}
buffLen = offset + usAttrLen;
uiTotalValueSize += usAttrLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrTypeLen, p, 2 );
pAttrType = p + 2;
p += 2 + usAttrTypeLen;
offset += 2 + usAttrTypeLen;
uiTotalValueSize -= 2;
uiTotalValueSize -= usAttrTypeLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
uiTotalValueSize -= 2;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
uiTotalValueSize -= (2 * usValueCnt);
}
else
{
uiTotalValueSize -= (4 * usValueCnt);
}
uiAttrEntrySize = sizeof( tAttributeEntry ) + usAttrTypeLen + kFWBuffPad;
pAttribInfo = (tAttributeEntry *)::calloc( 1, uiAttrEntrySize );
pAttribInfo->fAttributeValueCount = usValueCnt;
pAttribInfo->fAttributeDataSize = uiTotalValueSize; pAttribInfo->fAttributeValueMaxSize = 512; pAttribInfo->fAttributeSignature.fBufferSize = usAttrTypeLen + kFWBuffPad;
pAttribInfo->fAttributeSignature.fBufferLength = usAttrTypeLen;
::memcpy( pAttribInfo->fAttributeSignature.fBufferData, pAttrType, usAttrTypeLen );
siResult = gFWRefTable->NewAttrValueRef( outAttrValueListRef, 0, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
if ( (bufTag == 'DbgA') || (bufTag == 'DbgB') )
{
syslog(LOG_CRIT, "DS:dsGetAttributeEntry:ExtractNextAttributeEntry:gFWRefTable->NewAttrValueRef ref = %d", *outAttrValueListRef);
}
siResult = gFWRefTable->SetOffset( *outAttrValueListRef, eAttrValueListRefType, uiOffset, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->SetBufTag( *outAttrValueListRef, eAttrValueListRefType, bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
*outAttrInfoPtr = pAttribInfo;
pAttribInfo = nil;
if ( (uiIndex + 1) > usAttrCnt )
{
*inOutOffset = -1;
}
else
{
*inOutOffset += usAttrLen;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
*inOutOffset += 2;
}
else
{
*inOutOffset += 4;
}
}
}
catch( SInt32 err )
{
siResult = err;
}
if (pAttribInfo != nil)
{
dsDeallocAttributeEntry(0,pAttribInfo);
pAttribInfo = nil;
}
return( (tDirStatus)siResult );
}
tDirStatus ExtractNextAttributeValue ( tDataBufferPtr inOutDataBuff,
tAttributeValueListRef inAttrValueListRef,
UInt32 inAttrValueIndex,
SInt32 *inOutOffset,
tAttributeValueEntryPtr *outAttrValue )
{
SInt32 siResult = eDSNoErr;
UInt16 usValueCnt = 0;
UInt16 usValueLen16 = 0;
UInt32 usValueLen = 0;
UInt16 usAttrNameLen = 0;
UInt32 uiIndex = 0;
UInt32 offset = 0;
char *p = nil;
tAttributeValueEntry *pAttrValue = nil;
UInt32 buffSize = 0;
UInt32 buffLen = 0;
UInt16 attrLen16 = 0;
UInt32 attrLen = 0;
UInt32 attrValueOffset = 0;
UInt32 bufTag = 0;
try
{
siResult = gFWRefTable->GetOffset( inAttrValueListRef, eAttrValueListRefType, &attrValueOffset, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->GetBufTag( inAttrValueListRef, eAttrValueListRefType, &bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
uiIndex = inAttrValueIndex;
if (uiIndex == 0) throw( (SInt32)eDSInvalidIndex );
if ( inOutDataBuff == nil ) throw( (SInt32)eDSNullDataBuff );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
buffSize = inOutDataBuff->fBufferSize;
p = inOutDataBuff->fBufferData + attrValueOffset;
offset = attrValueOffset;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &attrLen16, p, 2 );
buffLen = attrLen16 + attrValueOffset + 2;
if (buffLen > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
p += 2;
offset += 2;
}
else
{
if (4 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &attrLen, p, 4 );
buffLen = attrLen + attrValueOffset + 4;
if (buffLen > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
p += 4;
offset += 4;
}
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usAttrNameLen, p, 2 );
p += 2 + usAttrNameLen;
offset += 2 + usAttrNameLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueCnt, p, 2 );
p += 2;
offset += 2;
if (uiIndex > usValueCnt) throw( (SInt32)eDSIndexOutOfRange );
offset += *inOutOffset;
p += *inOutOffset;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen16, p, 2 );
p += 2;
offset += 2;
usValueLen = (UInt32)usValueLen16;
}
else
{
if (4 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 4 );
p += 4;
offset += 4;
}
pAttrValue = (tAttributeValueEntry *)::calloc( 1, sizeof( tAttributeValueEntry ) + usValueLen + kFWBuffPad );
pAttrValue->fAttributeValueData.fBufferSize = usValueLen + kFWBuffPad;
pAttrValue->fAttributeValueData.fBufferLength = usValueLen;
if ( usValueLen + offset > buffLen ) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( pAttrValue->fAttributeValueData.fBufferData, p, usValueLen );
pAttrValue->fAttributeValueID = CalcCRC( pAttrValue->fAttributeValueData.fBufferData );
*outAttrValue = pAttrValue;
pAttrValue = nil;
if ( (uiIndex + 1) > usValueCnt )
{
*inOutOffset = -1;
}
else
{
*inOutOffset += usValueLen;
if ( (bufTag == 'StdB') || (bufTag == 'DbgB') )
{
*inOutOffset += 2;
}
else
{
*inOutOffset += 4;
}
}
}
catch( SInt32 err )
{
siResult = err;
}
if (pAttrValue != nil)
{
dsDeallocAttributeValueEntry(0,pAttrValue);
pAttrValue = nil;
}
return( (tDirStatus)siResult );
}
tDirStatus IsNodePathStrBuffer ( tDataBufferPtr inOutDataBuff )
{
tDirStatus outResult = eDSNoErr;
SInt32 siResult = eDSNoErr;
CBuff inBuff;
UInt32 bufTag = 0;
try
{
if ( inOutDataBuff == nil ) throw( (SInt32)eDSEmptyBuffer );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
siResult = inBuff.Initialize( inOutDataBuff );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inBuff.GetBuffType( &bufTag );
if ( siResult != eDSNoErr ) throw( siResult );
if (bufTag != 'npss') {
outResult = eDSInvalidTag;
}
}
catch( SInt32 err )
{
outResult = (tDirStatus)err;
}
return( outResult );
}
tDirStatus ExtractDirNodeName ( tDataBufferPtr inOutDataBuff,
UInt32 inDirNodeIndex,
tDataListPtr *outDataList )
{
SInt32 siResult = eDSNoErr;
UInt16 usValueLen = 0;
UInt32 iSegment = 0;
UInt32 uiIndex = 0;
UInt32 uiCount = 0;
UInt32 offset = 0;
char *p = nil;
UInt32 buffSize = 0;
char *outNodePathStr = nil;
UInt16 segmentCount = 0;
try
{
uiIndex = inDirNodeIndex;
if (uiIndex == 0) throw( (SInt32)eDSInvalidIndex );
if ( inOutDataBuff == nil ) throw( (SInt32)eDSNullDataBuff );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
if ( outDataList == nil ) throw( (SInt32)eDSNullDataList );
if (inOutDataBuff->fBufferSize < 8) throw( (SInt32)eDSInvalidBuffFormat );
buffSize = inOutDataBuff->fBufferSize;
p = inOutDataBuff->fBufferData + 4; offset = 4;
::memcpy( &uiCount, p, 4 );
if (uiCount == 0) throw( (SInt32)eDSEmptyBuffer );
if (uiIndex > uiCount) throw( (SInt32)eDSIndexOutOfRange );
::memcpy(&offset,inOutDataBuff->fBufferData + buffSize - (uiIndex * 4) , 4);
p = inOutDataBuff->fBufferData + offset;
if (2 + offset > buffSize) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &segmentCount, p, 2 );
p += 2;
offset += 2;
*outDataList = dsDataListAllocate(0);
for (iSegment = 1; iSegment <= segmentCount; iSegment++)
{
if ( 2 + offset > buffSize ) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usValueLen, p, 2 );
p += 2;
offset += 2;
if ( usValueLen > (SInt32)(buffSize - offset) ) throw( (SInt32)eDSInvalidBuffFormat );
outNodePathStr = (char *) calloc( 1, usValueLen + 1);
::memcpy( outNodePathStr, p, usValueLen );
dsAppendStringToListAlloc( 0, *outDataList, outNodePathStr );
free(outNodePathStr);
outNodePathStr = nil;
p += usValueLen;
offset += usValueLen;
}
}
catch( SInt32 err )
{
siResult = err;
}
return( (tDirStatus)siResult );
}
tDirStatus IsRemoteReferenceMap ( UInt32 inRef )
{
tDirStatus outResult = eDSInvalidReference;
if ((inRef & 0x00C00000) != 0)
{
outResult = eDSNoErr;
}
return( outResult );
}
tDirStatus MakeGDNIFWRef ( tDataBufferPtr inOutDataBuff,
tAttributeListRef *outAttributeListRef )
{
SInt32 siResult = eDSNoErr;
char *pData = nil;
CBuff inBuff;
UInt32 offset = 0;
UInt16 usTypeLen = 0;
UInt16 usNameLen = 0;
UInt32 buffLen = 0;
UInt32 bufTag = 0;
UInt32 uiOffset = 0;
try
{
if ( inOutDataBuff == nil ) throw( (SInt32)eDSNullDataBuff );
if (inOutDataBuff->fBufferSize == 0) throw( (SInt32)eDSEmptyBuffer );
siResult = inBuff.Initialize( inOutDataBuff );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = inBuff.GetBuffType( &bufTag );
if ( siResult != eDSNoErr ) throw( siResult );
buffLen = inBuff.GetDataBlockLength(1);
pData = inBuff.GetDataBlock( 1, &uiOffset );
pData += 4;
offset = 4;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usTypeLen, pData, 2 );
pData += 2;
offset += 2;
pData += usTypeLen;
offset += usTypeLen;
if (2 + offset > buffLen) throw( (SInt32)eDSInvalidBuffFormat );
::memcpy( &usNameLen, pData, 2 );
pData += 2;
offset += 2;
pData += usNameLen;
offset += usNameLen;
siResult = gFWRefTable->NewAttrListRef( outAttributeListRef, 0, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
if ( (bufTag == 'DbgA') || (bufTag == 'DbgB') )
{
syslog(LOG_CRIT, "DS:dsGetDirNodeInfo:MakeGDNIFWRef:gFWRefTable->NewAttrListRef ref = %d", *outAttributeListRef);
}
siResult = gFWRefTable->SetOffset( *outAttributeListRef, eAttrListRefType, offset + uiOffset, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
siResult = gFWRefTable->SetBufTag( *outAttributeListRef, eAttrListRefType, bufTag, gProcessPID );
if ( siResult != eDSNoErr ) throw( siResult );
}
catch( SInt32 err )
{
siResult = err;
}
return( (tDirStatus)siResult );
}
const char *dsGetPluginNamePriv( UInt32 inNodeRefNum, UInt32 inPID )
{
return gFWRefMap->GetPluginName( inNodeRefNum, inPID );
}