Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

453 lines
11 KiB

//+-------------------------------------------------------------------------
//
// Microsoft Windows
//
// Copyright (C) Microsoft Corporation, 1997 - 1999
//
// File: store.cxx
//
//--------------------------------------------------------------------------
#include "precomp.h"
#define cbSTORE_OVERHEAD ( 3*sizeof(DWORD) )
LPSTORE Store_New( DWORD dwStoreSize )
{
LPSTORE lpStore;
lpStore = (LPSTORE) MemAlloc( cbSTORE_OVERHEAD + dwStoreSize );
if( lpStore )
{
lpStore->dwSize = dwStoreSize;
Store_Empty( lpStore );
}
return lpStore;
}
BOOL Store_Empty( LPSTORE lpStore )
{
if( !lpStore )
{
return FALSE;
}
DbgLog1( SEV_FUNCTION, "Store_Empty: Remove: %ld bytes", lpStore->dwUsed );
lpStore->dwUsed = 0;
lpStore->dwOutOffset = 0;
return TRUE;
}
BOOL Store_AddData( LPSTORE lpStore, LPVOID lpvData, DWORD dwDataSize )
{
// have enough room for new data?
if( lpStore->dwUsed + dwDataSize > lpStore->dwSize )
{
DbgLog3( SEV_ERROR,
"Store_AddData: not enough room, used %d new %d size %d",
lpStore->dwUsed, dwDataSize, lpStore->dwSize );
return FALSE;
}
CopyMemory( (LPVOID)( &(lpStore->ab1Store[lpStore->dwUsed]) ),
lpvData,
dwDataSize );
lpStore->dwUsed += dwDataSize;
DbgLog1( SEV_INFO, "Store_AddData: dwUsed: %ld bytes", lpStore->dwUsed );
return TRUE;
}
DWORD Store_GetDataUsed( LPSTORE lpStore )
{
return lpStore->dwUsed;
}
DWORD
Store_GetSize(
LPSTORE lpStore
)
{
return lpStore->dwSize;
}
VOID Store_RemoveData( LPSTORE lpStore, DWORD dwLen )
{
DbgLog1( SEV_FUNCTION, "Store_RemoveData: Remove: %ld bytes", dwLen );
if( dwLen > lpStore->dwUsed )
{
Store_Empty( lpStore );
return;
}
lpStore->dwUsed -= dwLen;
lpStore->dwOutOffset = 0L;
if (lpStore->dwUsed)
{
CopyMemory( (LPVOID)( lpStore->ab1Store ),
(LPVOID)( &(lpStore->ab1Store[dwLen]) ),
lpStore->dwUsed );
}
DbgLog1( SEV_FUNCTION, "Store_RemoveData: dwUsed: %d", lpStore->dwUsed );
}
BOOL Store_GetData1Byte( LPSTORE lpStore, LPBYTE1 pb1 )
{
if( !pb1 )
return FALSE;
if( lpStore->dwOutOffset + sizeof(*pb1) > lpStore->dwUsed )
{
DbgLog2( SEV_ERROR,
"Store_GetData: get 1 failed, used %d, offset %d",
lpStore->dwUsed, lpStore->dwOutOffset );
return FALSE;
}
*pb1 = *( (LPBYTE1)(lpStore->ab1Store + lpStore->dwOutOffset) );
lpStore->dwOutOffset += sizeof( *pb1 );
return TRUE;
}
BOOL Store_GetData2Byte( LPSTORE lpStore, LPBYTE2 pb2 )
{
if( !pb2 )
return FALSE;
if( lpStore->dwOutOffset + sizeof(*pb2) > lpStore->dwUsed )
{
DbgLog2( SEV_ERROR,
"Store_GetData: get 2 failed, used %d, offset %d",
lpStore->dwUsed, lpStore->dwOutOffset );
return FALSE;
}
CopyMemory(pb2,lpStore->ab1Store + lpStore->dwOutOffset, sizeof(*pb2));
// *pb2 = *( (LPBYTE2)(lpStore->ab1Store + lpStore->dwOutOffset) );
ChangeByteOrder( (LPBYTE1)pb2, sizeof(*pb2), sizeof(*pb2) );
lpStore->dwOutOffset += sizeof( *pb2 );
return TRUE;
}
BOOL Store_GetData4Byte( LPSTORE lpStore, LPBYTE4 pb4 )
{
if( !pb4 )
return FALSE;
if( lpStore->dwOutOffset + sizeof(*pb4) > lpStore->dwUsed )
{
DbgLog2( SEV_ERROR,
"Store_GetData: get 4 failed, used %d, offset %d",
lpStore->dwUsed, lpStore->dwOutOffset );
return FALSE;
}
CopyMemory(pb4,lpStore->ab1Store + lpStore->dwOutOffset, sizeof(*pb4));
// *pb4 = *( (LPBYTE4)(lpStore->ab1Store + lpStore->dwOutOffset) );
ChangeByteOrder( (LPBYTE1)pb4, sizeof(*pb4), sizeof(*pb4) );
lpStore->dwOutOffset += sizeof( *pb4 );
return TRUE;
}
BOOL Store_GetDataUuid( LPSTORE lpStore, UUID * pb )
{
if( !pb )
return FALSE;
if( lpStore->dwOutOffset + sizeof(*pb) > lpStore->dwUsed )
{
DbgLog2( SEV_ERROR,
"Store_GetData: get UUID failed, used %d, offset %d",
lpStore->dwUsed, lpStore->dwOutOffset );
return FALSE;
}
CopyMemory(pb,lpStore->ab1Store + lpStore->dwOutOffset, sizeof(*pb));
// *pb = *( (UUID *)(lpStore->ab1Store + lpStore->dwOutOffset) );
ChangeByteOrder( &pb->Data1, sizeof(pb->Data1), sizeof(pb->Data1) );
ChangeByteOrder( &pb->Data2, sizeof(pb->Data2), sizeof(pb->Data2) );
ChangeByteOrder( &pb->Data3, sizeof(pb->Data3), sizeof(pb->Data3) );
lpStore->dwOutOffset += sizeof( UUID );
return TRUE;
}
BOOL Store_GetDataWsz( LPSTORE lpStore, LPWSTR wsz, DWORD BufferLength )
{
LPWSTR lpwsz = (LPWSTR)(lpStore->ab1Store + lpStore->dwOutOffset);
INT nLen = CbWsz(lpwsz);
if( !wsz || BufferLength < (DWORD) nLen)
return FALSE;
if( lpStore->dwOutOffset + nLen > lpStore->dwUsed )
{
DbgLog2( SEV_ERROR,
"Store_GetData: get Unicode string failed, used %d, offset %d",
lpStore->dwUsed, lpStore->dwOutOffset );
return FALSE;
}
wcsncpy( wsz, lpwsz, BufferLength / sizeof(WCHAR) );
lpStore->dwOutOffset += nLen;
ChangeByteOrder( (LPBYTE1)wsz, sizeof(WCHAR), nLen );
return TRUE;
}
LPVOID Store_GetDataPtr( LPSTORE lpStore )
{
return (lpStore->ab1Store + lpStore->dwOutOffset);
}
VOID Store_SkipData( LPSTORE lpStore, INT nSize )
{
lpStore->dwOutOffset += nSize;
}
BOOL Store_PokeData( LPSTORE lpStore, DWORD dwOffset, LPVOID lpvData, DWORD dwDataSize )
{
if( dwOffset + dwDataSize > lpStore->dwUsed )
return FALSE;
// NOTE: data must be atomic
ChangeByteOrder( (unsigned char *) lpvData, dwDataSize, dwDataSize );
CopyMemory(
lpStore->ab1Store + dwOffset,
lpvData,
dwDataSize
);
return TRUE;
}
BOOL Store_AddData1Byte( LPSTORE lpStore, BYTE1 b1 )
{
return Store_AddData( lpStore, &b1, sizeof(b1) );
}
BOOL Store_AddData2Byte( LPSTORE lpStore, BYTE2 b2 )
{
ChangeByteOrder( (LPBYTE1)&b2, sizeof(b2), sizeof(b2) );
return Store_AddData( lpStore, &b2, sizeof(b2) );
}
BOOL Store_AddData4Byte( LPSTORE lpStore, BYTE4 b4 )
{
ChangeByteOrder( (LPBYTE1)&b4, sizeof(b4), sizeof(b4) );
return Store_AddData( lpStore, (LPBYTE1)&b4, sizeof(b4) );
}
BOOL Store_AddDataUuid( LPSTORE lpStore, UUID * puuid )
{
UUID uuid = *puuid;
ChangeByteOrder( &uuid.Data1, sizeof(uuid.Data1), sizeof(uuid.Data1) );
ChangeByteOrder( &uuid.Data2, sizeof(uuid.Data2), sizeof(uuid.Data2) );
ChangeByteOrder( &uuid.Data3, sizeof(uuid.Data3), sizeof(uuid.Data3) );
return Store_AddData( lpStore, &uuid, sizeof(UUID) );
}
BOOL Store_AddDataWsz( LPSTORE lpStore, LPWSTR wsz )
{
INT nLen = CbWsz( wsz );
WCHAR wszCopy[MAX_PATH];
SzCpyW( wszCopy, wsz );
ChangeByteOrder( (LPBYTE1)wszCopy, sizeof(WCHAR), nLen );
return Store_AddData( lpStore, wszCopy, nLen );
}
VOID Store_Delete( LPSTORE *lplpStore )
{
if( lplpStore && *lplpStore )
{
MemFree( *lplpStore );
*lplpStore = 0;
}
}
VOID ChangeByteOrder( void * pb1, UINT uAtomSize, UINT uDataSize )
{
LPBYTE1 pb1Src;
LPBYTE1 pb1Dst;
BYTE1 b1Temp;
UINT uSwaps;
// 1 byte atoms don't change order
if( uAtomSize == 1 )
return;
// go atom-by-atom, reversing the order of each byte in each atom
for(
pb1Src = LPBYTE1(pb1), pb1Dst = LPBYTE1(pb1) + uAtomSize-1;
pb1Src < LPBYTE1(pb1) + uDataSize;
pb1Src += uAtomSize-uSwaps, pb1Dst += uAtomSize+uSwaps
)
{
uSwaps = 0;
while( pb1Src < pb1Dst )
{
b1Temp = *pb1Src;
*pb1Src++ = *pb1Dst;
*pb1Dst-- = b1Temp;
uSwaps++;
}
}
}
void
Store_DumpParameter(
LPSTORE lpStore,
BYTE1 parm
)
{
unsigned Length;
unsigned Offset = 0;
char * name;
switch (parm)
{
case OBEX_PARAM_COUNT: name = "OBEX_PARAM_COUNT"; break;
case OBEX_PARAM_NAME: name = "OBEX_PARAM_NAME"; break;
case OBEX_PARAM_LENGTH: name = "OBEX_PARAM_LENGTH"; break;
case OBEX_PARAM_UNIX_TIME: name = "OBEX_PARAM_UNIX_TIME"; break;
case OBEX_PARAM_ISO_TIME: name = "OBEX_PARAM_ISO_TIME"; break;
case OBEX_PARAM_BODY: name = "OBEX_PARAM_BODY"; break;
case OBEX_PARAM_BODY_END: name = "OBEX_PARAM_BODY_END"; break;
case OBEX_PARAM_WHO: name = "OBEX_PARAM_WHO"; break;
case PRIVATE_PARAM_WIN32_ERROR: name = "private WIN32_ERROR"; break;
default: name = "unknown"; break;
}
DbgLog2(SEV_INFO, "parameter 0x%x (%s):", parm, name);
switch (parm & OBEX_PARAM_TYPE_MASK)
{
case OBEX_PARAM_UNICODE:
case OBEX_PARAM_STREAM:
{
if (lpStore->dwSize - lpStore->dwOutOffset < 2)
{
Length = lpStore->dwSize - lpStore->dwOutOffset;
}
else
{
DbgLog2(SEV_INFO, "length = %x:%x", lpStore->ab1Store[lpStore->dwOutOffset], lpStore->ab1Store[lpStore->dwOutOffset+1]);
Length = (lpStore->ab1Store[lpStore->dwOutOffset] << 8) + lpStore->ab1Store[lpStore->dwOutOffset+1];
Length -= 3; // on-wire length includes opcode and length field themselves
Offset = 2;
}
break;
}
case OBEX_PARAM_1BYTE:
{
Length = 1;
break;
}
case OBEX_PARAM_4BYTE:
{
Length = 4;
break;
}
default:
{
DbgLog( SEV_ERROR, "Store_DumpParameter is broken\n");
return;
}
}
if ((Length+Offset) > lpStore->dwSize - lpStore->dwOutOffset)
{
Length = lpStore->dwSize - lpStore->dwOutOffset - Offset;
}
const BYTES_PER_LINE = 16;
unsigned char *p = (unsigned char *) lpStore->ab1Store + lpStore->dwOutOffset + Offset;
//
// 3 chars per byte for hex display, plus an extra space every 4 bytes,
// plus a byte for the printable representation, plus the \0.
//
char Outbuf[BYTES_PER_LINE*3+BYTES_PER_LINE/4+BYTES_PER_LINE+1];
Outbuf[0] = 0;
Outbuf[sizeof(Outbuf)-1] = 0;
char * HexDigits = "0123456789abcdef";
if (Length < 32) {
unsigned Index;
for (Offset=0; Offset < Length; Offset++) {
Index = Offset % BYTES_PER_LINE;
if (Index == 0) {
DbgLog1(SEV_INFO, " %s", Outbuf);
memset(Outbuf, ' ', sizeof(Outbuf)-1);
}
Outbuf[Index*3+Index/4 ] = HexDigits[p[Offset] / 16];
Outbuf[Index*3+Index/4+1] = HexDigits[p[Offset] % 16];
Outbuf[BYTES_PER_LINE*3+BYTES_PER_LINE/4+Index] = iscntrl(p[Offset]) ? '.' : p[Offset];
}
DbgLog1(SEV_INFO, " %s", Outbuf);
DbgLog(SEV_INFO, "");
}
}