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