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.

268 lines
6.6 KiB

  1. //////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 2000 Microsoft Corporation. All Rights Reserved.
  4. //
  5. // File: DplayBufHelp.cpp
  6. // Content: Helper functions for DPlay Buffers (Byte arrays)
  7. //
  8. //////////////////////////////////////////////////////////////////////////////
  9. #include "stdafx.h"
  10. #include "Direct.h"
  11. #define SAFE_FREE(p) { if(p) { free (p); p=NULL; } }
  12. #define SAFE_DELETE(p) { if(p) { delete (p); p=NULL; } }
  13. #define INITIAL_BUFFER_SIZE 20
  14. HRESULT WINAPI VB_GrowBuffer(SAFEARRAY **Buffer, DWORD dwGrowSize);
  15. HRESULT WINAPI VB_NewBuffer(SAFEARRAY **Buffer, long *lOffSet);
  16. HRESULT WINAPI VB_AddDataToBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet);
  17. HRESULT WINAPI VB_AddStringToBuffer(SAFEARRAY **Buffer, BSTR StringData, long *lOffSet);
  18. HRESULT WINAPI VB_GetDataFromBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet);
  19. HRESULT WINAPI VB_GetStringFromBuffer(SAFEARRAY **Buffer, long *lOffSet, BSTR *sData);
  20. // Functions for writing a buffer
  21. HRESULT WINAPI VB_AddStringToBuffer(SAFEARRAY **Buffer, BSTR StringData, long *lOffSet)
  22. {
  23. HRESULT hr;
  24. // For strings we will first write out a DWORD
  25. // containging the length of the string. Then we
  26. // will write the actual data to the string.
  27. DWORD dwStrLen= (((DWORD*)StringData)[-1]);
  28. DWORD dwDataSize = sizeof(DWORD) + dwStrLen;
  29. if (!StringData)
  30. return E_INVALIDARG;
  31. if (!((SAFEARRAY*)*Buffer))
  32. {
  33. // We need to create this buffer, it doesn't exist
  34. SAFEARRAY *lpData = NULL;
  35. SAFEARRAYBOUND rgsabound[1];
  36. // Let's create our SafeArray
  37. rgsabound[0].lLbound = 0; // A single dimension array that is zero based
  38. rgsabound[0].cElements = dwDataSize; //Set the initial size
  39. // Create this data
  40. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  41. if (!lpData)
  42. return E_OUTOFMEMORY;
  43. (SAFEARRAY*)*Buffer = lpData;
  44. }
  45. if (!((SAFEARRAY*)*Buffer)->pvData)
  46. return E_INVALIDARG;
  47. // Do we have enough memory for this string right now?
  48. if (*lOffSet + dwDataSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
  49. if (FAILED( hr = VB_GrowBuffer(Buffer, dwDataSize) ) )
  50. return hr;
  51. // Ok, now we' ve got our memory, copy it over
  52. // First the length
  53. BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
  54. __try {
  55. memcpy(lPtr + *lOffSet, &dwStrLen, sizeof(DWORD));
  56. *lOffSet += sizeof(DWORD);
  57. // Now the actual string
  58. memcpy(lPtr + *lOffSet, StringData, dwStrLen);
  59. *lOffSet += dwStrLen;
  60. }
  61. __except(EXCEPTION_EXECUTE_HANDLER)
  62. {
  63. return E_INVALIDARG;
  64. }
  65. return S_OK;
  66. }
  67. HRESULT WINAPI VB_AddDataToBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet)
  68. {
  69. HRESULT hr;
  70. if (!lData)
  71. return E_INVALIDARG;
  72. if (!lSize)
  73. return E_INVALIDARG;
  74. if (!((SAFEARRAY*)*Buffer))
  75. {
  76. // We need to create this buffer, it doesn't exist
  77. SAFEARRAY *lpData = NULL;
  78. SAFEARRAYBOUND rgsabound[1];
  79. // Let's create our SafeArray
  80. rgsabound[0].lLbound = 0; // A single dimension array that is zero based
  81. rgsabound[0].cElements = lSize; //Set the initial size
  82. // Create this data
  83. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  84. if (!lpData)
  85. return E_OUTOFMEMORY;
  86. (SAFEARRAY*)*Buffer = lpData;
  87. }
  88. if (!((SAFEARRAY*)*Buffer)->pvData)
  89. return E_INVALIDARG;
  90. // Do we have enough memory for this string right now?
  91. if (*lOffSet + lSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
  92. if (FAILED( hr = VB_GrowBuffer(Buffer, lSize) ) )
  93. return hr;
  94. BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
  95. __try {
  96. memcpy(lPtr + *lOffSet, lData, lSize);
  97. *lOffSet += lSize;
  98. }
  99. __except(EXCEPTION_EXECUTE_HANDLER)
  100. {
  101. return E_INVALIDARG;
  102. }
  103. return S_OK;
  104. }
  105. HRESULT WINAPI VB_NewBuffer(SAFEARRAY **Buffer, long *lOffSet)
  106. {
  107. // Set up with a 20 byte msg at first
  108. SAFEARRAY *lpData = NULL;
  109. SAFEARRAYBOUND rgsabound[1];
  110. // Let's create our SafeArray
  111. rgsabound[0].lLbound = 0; // A single dimension array that is zero based
  112. rgsabound[0].cElements = INITIAL_BUFFER_SIZE; //Set the initial size
  113. // Create this data
  114. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  115. if (!lpData)
  116. return E_OUTOFMEMORY;
  117. (SAFEARRAY*)*Buffer = lpData;
  118. *lOffSet = 0;
  119. return S_OK;
  120. }
  121. HRESULT WINAPI VB_GrowBuffer(SAFEARRAY **Buffer, DWORD dwGrowSize)
  122. {
  123. SAFEARRAY *lpData = NULL;
  124. SAFEARRAYBOUND rgsabound[1];
  125. DWORD dwCurSize = 0;
  126. if (!dwGrowSize)
  127. return E_INVALIDARG;
  128. if (!((SAFEARRAY*)*Buffer))
  129. return E_INVALIDARG;
  130. if (!((SAFEARRAY*)*Buffer)->pvData)
  131. return E_INVALIDARG;
  132. dwCurSize = ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements;
  133. // Let's create a new SafeArray
  134. rgsabound[0].lLbound = 0; // A single dimension array that is zero based
  135. rgsabound[0].cElements = dwCurSize + dwGrowSize; //Set the size
  136. // Create this data
  137. lpData = SafeArrayCreate(VT_UI1, 1, rgsabound);
  138. if (!lpData)
  139. return E_OUTOFMEMORY;
  140. __try {
  141. memcpy(lpData->pvData, ((SAFEARRAY*)*Buffer)->pvData, dwCurSize);
  142. SafeArrayDestroy((SAFEARRAY*)*Buffer);
  143. (SAFEARRAY*)*Buffer = lpData;
  144. }
  145. __except(EXCEPTION_EXECUTE_HANDLER)
  146. {
  147. return E_FAIL;
  148. }
  149. return S_OK;
  150. }
  151. HRESULT WINAPI VB_GetDataFromBuffer(SAFEARRAY **Buffer, void *lData, DWORD lSize, long *lOffSet)
  152. {
  153. // Simply copy the memory from the offset to the new data
  154. if (!lData)
  155. return E_INVALIDARG;
  156. if (!lSize)
  157. return E_INVALIDARG;
  158. if (!(SAFEARRAY*)*Buffer)
  159. return E_INVALIDARG;
  160. if (!((SAFEARRAY*)*Buffer)->pvData)
  161. return E_INVALIDARG;
  162. if (*lOffSet + lSize > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
  163. return E_INVALIDARG;
  164. BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
  165. __try {
  166. memcpy(lData, lPtr + *lOffSet, lSize);
  167. *lOffSet += lSize;
  168. }
  169. __except(EXCEPTION_EXECUTE_HANDLER)
  170. {
  171. return E_INVALIDARG;
  172. }
  173. return S_OK;
  174. }
  175. HRESULT WINAPI VB_GetStringFromBuffer(SAFEARRAY **Buffer, long *lOffSet, BSTR *sData)
  176. {
  177. DWORD dwStrLen = 0;
  178. WCHAR *sNewString = NULL;
  179. // Simply copy the memory from the offset to the new data
  180. if (!(SAFEARRAY*)*Buffer)
  181. return E_INVALIDARG;
  182. if (!((SAFEARRAY*)*Buffer)->pvData)
  183. return E_INVALIDARG;
  184. if (*lOffSet + sizeof(DWORD) > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
  185. return E_INVALIDARG;
  186. BYTE *lPtr = (BYTE*)((SAFEARRAY*)*Buffer)->pvData;
  187. __try {
  188. // First read the size of the string
  189. dwStrLen = *(DWORD*)(lPtr + *lOffSet);
  190. *lOffSet += sizeof(DWORD);
  191. if (*lOffSet + dwStrLen > ((SAFEARRAY*)*Buffer)->rgsabound[0].cElements)
  192. return E_INVALIDARG;
  193. sNewString = (WCHAR*)new BYTE[dwStrLen+2];
  194. if (!sNewString)
  195. return E_OUTOFMEMORY;
  196. ZeroMemory(sNewString, dwStrLen+2);
  197. memcpy(sNewString, lPtr + *lOffSet, dwStrLen);
  198. *sData = SysAllocString(sNewString);
  199. *lOffSet += (dwStrLen);
  200. }
  201. __except(EXCEPTION_EXECUTE_HANDLER)
  202. {
  203. return E_INVALIDARG;
  204. }
  205. return S_OK;
  206. }