|
|
//+-------------------------------------------------------------------------
//
// 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, "");
}
}
|