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

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997 - 1999
  6. //
  7. // File: store.cxx
  8. //
  9. //--------------------------------------------------------------------------
  10. #include "precomp.h"
  11. #define cbSTORE_OVERHEAD ( 3*sizeof(DWORD) )
  12. LPSTORE Store_New( DWORD dwStoreSize )
  13. {
  14. LPSTORE lpStore;
  15. lpStore = (LPSTORE) MemAlloc( cbSTORE_OVERHEAD + dwStoreSize );
  16. if( lpStore )
  17. {
  18. lpStore->dwSize = dwStoreSize;
  19. Store_Empty( lpStore );
  20. }
  21. return lpStore;
  22. }
  23. BOOL Store_Empty( LPSTORE lpStore )
  24. {
  25. if( !lpStore )
  26. {
  27. return FALSE;
  28. }
  29. DbgLog1( SEV_FUNCTION, "Store_Empty: Remove: %ld bytes", lpStore->dwUsed );
  30. lpStore->dwUsed = 0;
  31. lpStore->dwOutOffset = 0;
  32. return TRUE;
  33. }
  34. BOOL Store_AddData( LPSTORE lpStore, LPVOID lpvData, DWORD dwDataSize )
  35. {
  36. // have enough room for new data?
  37. if( lpStore->dwUsed + dwDataSize > lpStore->dwSize )
  38. {
  39. DbgLog3( SEV_ERROR,
  40. "Store_AddData: not enough room, used %d new %d size %d",
  41. lpStore->dwUsed, dwDataSize, lpStore->dwSize );
  42. return FALSE;
  43. }
  44. CopyMemory( (LPVOID)( &(lpStore->ab1Store[lpStore->dwUsed]) ),
  45. lpvData,
  46. dwDataSize );
  47. lpStore->dwUsed += dwDataSize;
  48. DbgLog1( SEV_INFO, "Store_AddData: dwUsed: %ld bytes", lpStore->dwUsed );
  49. return TRUE;
  50. }
  51. DWORD Store_GetDataUsed( LPSTORE lpStore )
  52. {
  53. return lpStore->dwUsed;
  54. }
  55. DWORD
  56. Store_GetSize(
  57. LPSTORE lpStore
  58. )
  59. {
  60. return lpStore->dwSize;
  61. }
  62. VOID Store_RemoveData( LPSTORE lpStore, DWORD dwLen )
  63. {
  64. DbgLog1( SEV_FUNCTION, "Store_RemoveData: Remove: %ld bytes", dwLen );
  65. if( dwLen > lpStore->dwUsed )
  66. {
  67. Store_Empty( lpStore );
  68. return;
  69. }
  70. lpStore->dwUsed -= dwLen;
  71. lpStore->dwOutOffset = 0L;
  72. if (lpStore->dwUsed)
  73. {
  74. CopyMemory( (LPVOID)( lpStore->ab1Store ),
  75. (LPVOID)( &(lpStore->ab1Store[dwLen]) ),
  76. lpStore->dwUsed );
  77. }
  78. DbgLog1( SEV_FUNCTION, "Store_RemoveData: dwUsed: %d", lpStore->dwUsed );
  79. }
  80. BOOL Store_GetData1Byte( LPSTORE lpStore, LPBYTE1 pb1 )
  81. {
  82. if( !pb1 )
  83. return FALSE;
  84. if( lpStore->dwOutOffset + sizeof(*pb1) > lpStore->dwUsed )
  85. {
  86. DbgLog2( SEV_ERROR,
  87. "Store_GetData: get 1 failed, used %d, offset %d",
  88. lpStore->dwUsed, lpStore->dwOutOffset );
  89. return FALSE;
  90. }
  91. *pb1 = *( (LPBYTE1)(lpStore->ab1Store + lpStore->dwOutOffset) );
  92. lpStore->dwOutOffset += sizeof( *pb1 );
  93. return TRUE;
  94. }
  95. BOOL Store_GetData2Byte( LPSTORE lpStore, LPBYTE2 pb2 )
  96. {
  97. if( !pb2 )
  98. return FALSE;
  99. if( lpStore->dwOutOffset + sizeof(*pb2) > lpStore->dwUsed )
  100. {
  101. DbgLog2( SEV_ERROR,
  102. "Store_GetData: get 2 failed, used %d, offset %d",
  103. lpStore->dwUsed, lpStore->dwOutOffset );
  104. return FALSE;
  105. }
  106. CopyMemory(pb2,lpStore->ab1Store + lpStore->dwOutOffset, sizeof(*pb2));
  107. // *pb2 = *( (LPBYTE2)(lpStore->ab1Store + lpStore->dwOutOffset) );
  108. ChangeByteOrder( (LPBYTE1)pb2, sizeof(*pb2), sizeof(*pb2) );
  109. lpStore->dwOutOffset += sizeof( *pb2 );
  110. return TRUE;
  111. }
  112. BOOL Store_GetData4Byte( LPSTORE lpStore, LPBYTE4 pb4 )
  113. {
  114. if( !pb4 )
  115. return FALSE;
  116. if( lpStore->dwOutOffset + sizeof(*pb4) > lpStore->dwUsed )
  117. {
  118. DbgLog2( SEV_ERROR,
  119. "Store_GetData: get 4 failed, used %d, offset %d",
  120. lpStore->dwUsed, lpStore->dwOutOffset );
  121. return FALSE;
  122. }
  123. CopyMemory(pb4,lpStore->ab1Store + lpStore->dwOutOffset, sizeof(*pb4));
  124. // *pb4 = *( (LPBYTE4)(lpStore->ab1Store + lpStore->dwOutOffset) );
  125. ChangeByteOrder( (LPBYTE1)pb4, sizeof(*pb4), sizeof(*pb4) );
  126. lpStore->dwOutOffset += sizeof( *pb4 );
  127. return TRUE;
  128. }
  129. BOOL Store_GetDataUuid( LPSTORE lpStore, UUID * pb )
  130. {
  131. if( !pb )
  132. return FALSE;
  133. if( lpStore->dwOutOffset + sizeof(*pb) > lpStore->dwUsed )
  134. {
  135. DbgLog2( SEV_ERROR,
  136. "Store_GetData: get UUID failed, used %d, offset %d",
  137. lpStore->dwUsed, lpStore->dwOutOffset );
  138. return FALSE;
  139. }
  140. CopyMemory(pb,lpStore->ab1Store + lpStore->dwOutOffset, sizeof(*pb));
  141. // *pb = *( (UUID *)(lpStore->ab1Store + lpStore->dwOutOffset) );
  142. ChangeByteOrder( &pb->Data1, sizeof(pb->Data1), sizeof(pb->Data1) );
  143. ChangeByteOrder( &pb->Data2, sizeof(pb->Data2), sizeof(pb->Data2) );
  144. ChangeByteOrder( &pb->Data3, sizeof(pb->Data3), sizeof(pb->Data3) );
  145. lpStore->dwOutOffset += sizeof( UUID );
  146. return TRUE;
  147. }
  148. BOOL Store_GetDataWsz( LPSTORE lpStore, LPWSTR wsz, DWORD BufferLength )
  149. {
  150. LPWSTR lpwsz = (LPWSTR)(lpStore->ab1Store + lpStore->dwOutOffset);
  151. INT nLen = CbWsz(lpwsz);
  152. if( !wsz || BufferLength < (DWORD) nLen)
  153. return FALSE;
  154. if( lpStore->dwOutOffset + nLen > lpStore->dwUsed )
  155. {
  156. DbgLog2( SEV_ERROR,
  157. "Store_GetData: get Unicode string failed, used %d, offset %d",
  158. lpStore->dwUsed, lpStore->dwOutOffset );
  159. return FALSE;
  160. }
  161. wcsncpy( wsz, lpwsz, BufferLength / sizeof(WCHAR) );
  162. lpStore->dwOutOffset += nLen;
  163. ChangeByteOrder( (LPBYTE1)wsz, sizeof(WCHAR), nLen );
  164. return TRUE;
  165. }
  166. LPVOID Store_GetDataPtr( LPSTORE lpStore )
  167. {
  168. return (lpStore->ab1Store + lpStore->dwOutOffset);
  169. }
  170. VOID Store_SkipData( LPSTORE lpStore, INT nSize )
  171. {
  172. lpStore->dwOutOffset += nSize;
  173. }
  174. BOOL Store_PokeData( LPSTORE lpStore, DWORD dwOffset, LPVOID lpvData, DWORD dwDataSize )
  175. {
  176. if( dwOffset + dwDataSize > lpStore->dwUsed )
  177. return FALSE;
  178. // NOTE: data must be atomic
  179. ChangeByteOrder( (unsigned char *) lpvData, dwDataSize, dwDataSize );
  180. CopyMemory(
  181. lpStore->ab1Store + dwOffset,
  182. lpvData,
  183. dwDataSize
  184. );
  185. return TRUE;
  186. }
  187. BOOL Store_AddData1Byte( LPSTORE lpStore, BYTE1 b1 )
  188. {
  189. return Store_AddData( lpStore, &b1, sizeof(b1) );
  190. }
  191. BOOL Store_AddData2Byte( LPSTORE lpStore, BYTE2 b2 )
  192. {
  193. ChangeByteOrder( (LPBYTE1)&b2, sizeof(b2), sizeof(b2) );
  194. return Store_AddData( lpStore, &b2, sizeof(b2) );
  195. }
  196. BOOL Store_AddData4Byte( LPSTORE lpStore, BYTE4 b4 )
  197. {
  198. ChangeByteOrder( (LPBYTE1)&b4, sizeof(b4), sizeof(b4) );
  199. return Store_AddData( lpStore, (LPBYTE1)&b4, sizeof(b4) );
  200. }
  201. BOOL Store_AddDataUuid( LPSTORE lpStore, UUID * puuid )
  202. {
  203. UUID uuid = *puuid;
  204. ChangeByteOrder( &uuid.Data1, sizeof(uuid.Data1), sizeof(uuid.Data1) );
  205. ChangeByteOrder( &uuid.Data2, sizeof(uuid.Data2), sizeof(uuid.Data2) );
  206. ChangeByteOrder( &uuid.Data3, sizeof(uuid.Data3), sizeof(uuid.Data3) );
  207. return Store_AddData( lpStore, &uuid, sizeof(UUID) );
  208. }
  209. BOOL Store_AddDataWsz( LPSTORE lpStore, LPWSTR wsz )
  210. {
  211. INT nLen = CbWsz( wsz );
  212. WCHAR wszCopy[MAX_PATH];
  213. SzCpyW( wszCopy, wsz );
  214. ChangeByteOrder( (LPBYTE1)wszCopy, sizeof(WCHAR), nLen );
  215. return Store_AddData( lpStore, wszCopy, nLen );
  216. }
  217. VOID Store_Delete( LPSTORE *lplpStore )
  218. {
  219. if( lplpStore && *lplpStore )
  220. {
  221. MemFree( *lplpStore );
  222. *lplpStore = 0;
  223. }
  224. }
  225. VOID ChangeByteOrder( void * pb1, UINT uAtomSize, UINT uDataSize )
  226. {
  227. LPBYTE1 pb1Src;
  228. LPBYTE1 pb1Dst;
  229. BYTE1 b1Temp;
  230. UINT uSwaps;
  231. // 1 byte atoms don't change order
  232. if( uAtomSize == 1 )
  233. return;
  234. // go atom-by-atom, reversing the order of each byte in each atom
  235. for(
  236. pb1Src = LPBYTE1(pb1), pb1Dst = LPBYTE1(pb1) + uAtomSize-1;
  237. pb1Src < LPBYTE1(pb1) + uDataSize;
  238. pb1Src += uAtomSize-uSwaps, pb1Dst += uAtomSize+uSwaps
  239. )
  240. {
  241. uSwaps = 0;
  242. while( pb1Src < pb1Dst )
  243. {
  244. b1Temp = *pb1Src;
  245. *pb1Src++ = *pb1Dst;
  246. *pb1Dst-- = b1Temp;
  247. uSwaps++;
  248. }
  249. }
  250. }
  251. void
  252. Store_DumpParameter(
  253. LPSTORE lpStore,
  254. BYTE1 parm
  255. )
  256. {
  257. unsigned Length;
  258. unsigned Offset = 0;
  259. char * name;
  260. switch (parm)
  261. {
  262. case OBEX_PARAM_COUNT: name = "OBEX_PARAM_COUNT"; break;
  263. case OBEX_PARAM_NAME: name = "OBEX_PARAM_NAME"; break;
  264. case OBEX_PARAM_LENGTH: name = "OBEX_PARAM_LENGTH"; break;
  265. case OBEX_PARAM_UNIX_TIME: name = "OBEX_PARAM_UNIX_TIME"; break;
  266. case OBEX_PARAM_ISO_TIME: name = "OBEX_PARAM_ISO_TIME"; break;
  267. case OBEX_PARAM_BODY: name = "OBEX_PARAM_BODY"; break;
  268. case OBEX_PARAM_BODY_END: name = "OBEX_PARAM_BODY_END"; break;
  269. case OBEX_PARAM_WHO: name = "OBEX_PARAM_WHO"; break;
  270. case PRIVATE_PARAM_WIN32_ERROR: name = "private WIN32_ERROR"; break;
  271. default: name = "unknown"; break;
  272. }
  273. DbgLog2(SEV_INFO, "parameter 0x%x (%s):", parm, name);
  274. switch (parm & OBEX_PARAM_TYPE_MASK)
  275. {
  276. case OBEX_PARAM_UNICODE:
  277. case OBEX_PARAM_STREAM:
  278. {
  279. if (lpStore->dwSize - lpStore->dwOutOffset < 2)
  280. {
  281. Length = lpStore->dwSize - lpStore->dwOutOffset;
  282. }
  283. else
  284. {
  285. DbgLog2(SEV_INFO, "length = %x:%x", lpStore->ab1Store[lpStore->dwOutOffset], lpStore->ab1Store[lpStore->dwOutOffset+1]);
  286. Length = (lpStore->ab1Store[lpStore->dwOutOffset] << 8) + lpStore->ab1Store[lpStore->dwOutOffset+1];
  287. Length -= 3; // on-wire length includes opcode and length field themselves
  288. Offset = 2;
  289. }
  290. break;
  291. }
  292. case OBEX_PARAM_1BYTE:
  293. {
  294. Length = 1;
  295. break;
  296. }
  297. case OBEX_PARAM_4BYTE:
  298. {
  299. Length = 4;
  300. break;
  301. }
  302. default:
  303. {
  304. DbgLog( SEV_ERROR, "Store_DumpParameter is broken\n");
  305. return;
  306. }
  307. }
  308. if ((Length+Offset) > lpStore->dwSize - lpStore->dwOutOffset)
  309. {
  310. Length = lpStore->dwSize - lpStore->dwOutOffset - Offset;
  311. }
  312. const BYTES_PER_LINE = 16;
  313. unsigned char *p = (unsigned char *) lpStore->ab1Store + lpStore->dwOutOffset + Offset;
  314. //
  315. // 3 chars per byte for hex display, plus an extra space every 4 bytes,
  316. // plus a byte for the printable representation, plus the \0.
  317. //
  318. char Outbuf[BYTES_PER_LINE*3+BYTES_PER_LINE/4+BYTES_PER_LINE+1];
  319. Outbuf[0] = 0;
  320. Outbuf[sizeof(Outbuf)-1] = 0;
  321. char * HexDigits = "0123456789abcdef";
  322. if (Length < 32) {
  323. unsigned Index;
  324. for (Offset=0; Offset < Length; Offset++) {
  325. Index = Offset % BYTES_PER_LINE;
  326. if (Index == 0) {
  327. DbgLog1(SEV_INFO, " %s", Outbuf);
  328. memset(Outbuf, ' ', sizeof(Outbuf)-1);
  329. }
  330. Outbuf[Index*3+Index/4 ] = HexDigits[p[Offset] / 16];
  331. Outbuf[Index*3+Index/4+1] = HexDigits[p[Offset] % 16];
  332. Outbuf[BYTES_PER_LINE*3+BYTES_PER_LINE/4+Index] = iscntrl(p[Offset]) ? '.' : p[Offset];
  333. }
  334. DbgLog1(SEV_INFO, " %s", Outbuf);
  335. DbgLog(SEV_INFO, "");
  336. }
  337. }