Leaked source code of windows server 2003
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.

465 lines
11 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dpvcpi.cpp
  6. * Content: Base class for providing compression DLL implementation
  7. *
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 10/27/99 rodtoll Created
  12. * 01/21/00 rodtoll Moved error level debug to info
  13. * 08/23/2000 rodtoll DllCanUnloadNow always returning TRUE!
  14. * 06/27/2001 rodtoll RC2: DPVOICE: DPVACM's DllMain calls into acm -- potential hang
  15. * Move global initialization to first object creation
  16. ***************************************************************************/
  17. #include <windows.h>
  18. #include <tchar.h>
  19. #include "osind.h"
  20. #include "dndbg.h"
  21. #include "dpvcp.h"
  22. #include "dpvcpi.h"
  23. LONG IncrementObjectCount();
  24. LONG DecrementObjectCount();
  25. extern "C" LONG g_lNumLocks;
  26. CDPVCPI::CompressionNode *CDPVCPI::s_pcnList = NULL;
  27. BOOL CDPVCPI::s_fIsLoaded = FALSE;
  28. DWORD CDPVCPI::s_dwNumCompressionTypes = 0;
  29. #undef DPF_MODNAME
  30. #define DPF_MODNAME "CDPVCPI::CDPVCPI"
  31. CDPVCPI::CDPVCPI(): m_lRefCount(0), m_fCritSecInited(FALSE)
  32. {
  33. }
  34. #undef DPF_MODNAME
  35. #define DPF_MODNAME "CDPVCPI::InitClass"
  36. BOOL CDPVCPI::InitClass()
  37. {
  38. if (DNInitializeCriticalSection( &m_csLock ))
  39. {
  40. m_fCritSecInited = TRUE;
  41. return TRUE;
  42. }
  43. else
  44. {
  45. return FALSE;
  46. }
  47. }
  48. #undef DPF_MODNAME
  49. #define DPF_MODNAME "CDPVCPI::I_CreateCompressor"
  50. HRESULT CDPVCPI::I_CreateCompressor( DPVCPIOBJECT *This, LPWAVEFORMATEX lpwfxSrcFormat, GUID guidTargetCT, PDPVCOMPRESSOR *ppCompressor, DWORD dwFlags )
  51. {
  52. return This->pObject->CreateCompressor( This, lpwfxSrcFormat, guidTargetCT, ppCompressor, dwFlags );
  53. }
  54. #undef DPF_MODNAME
  55. #define DPF_MODNAME "CDPVCPI::I_CreateDeCompressor"
  56. HRESULT CDPVCPI::I_CreateDeCompressor( DPVCPIOBJECT *This, GUID guidTargetCT, LPWAVEFORMATEX lpwfxSrcFormat, PDPVCOMPRESSOR *ppCompressor, DWORD dwFlags )
  57. {
  58. return This->pObject->CreateDeCompressor( This, guidTargetCT, lpwfxSrcFormat, ppCompressor, dwFlags );
  59. }
  60. #undef DPF_MODNAME
  61. #define DPF_MODNAME "CDPVCPI::~CDPVCPI"
  62. CDPVCPI::~CDPVCPI()
  63. {
  64. if (m_fCritSecInited)
  65. {
  66. DNDeleteCriticalSection( &m_csLock );
  67. }
  68. }
  69. #undef DPF_MODNAME
  70. #define DPF_MODNAME "CDPVCPI::DeInitCompressionList"
  71. HRESULT CDPVCPI::DeInitCompressionList()
  72. {
  73. return CN_FreeList();
  74. }
  75. #undef DPF_MODNAME
  76. #define DPF_MODNAME "CDPVCPI::QueryInterface"
  77. HRESULT CDPVCPI::QueryInterface( DPVCPIOBJECT *This, REFIID riid, PVOID *ppvObj )
  78. {
  79. HRESULT hr = S_OK;
  80. if( ppvObj == NULL ||
  81. !DNVALID_WRITEPTR( ppvObj, sizeof(LPVOID) ) )
  82. {
  83. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer passed for object" );
  84. return DVERR_INVALIDPOINTER;
  85. }
  86. *ppvObj=NULL;
  87. DNEnterCriticalSection( &This->pObject->m_csLock );
  88. // hmmm, switch would be cleaner...
  89. if( IsEqualIID(riid, IID_IUnknown) ||
  90. IsEqualIID(riid, IID_IDPVCompressionProvider ) )
  91. {
  92. *ppvObj = This;
  93. This->pObject->AddRef( This );
  94. }
  95. else
  96. {
  97. hr = E_NOINTERFACE;
  98. }
  99. DNLeaveCriticalSection( &This->pObject->m_csLock );
  100. return hr;
  101. }
  102. #undef DPF_MODNAME
  103. #define DPF_MODNAME "CDPVCPI::AddRef"
  104. HRESULT CDPVCPI::AddRef( DPVCPIOBJECT *This )
  105. {
  106. LONG rc;
  107. rc = InterlockedIncrement( &This->pObject->m_lRefCount );
  108. return rc;
  109. }
  110. #undef DPF_MODNAME
  111. #define DPF_MODNAME "CDPVCPI::Release"
  112. HRESULT CDPVCPI::Release( DPVCPIOBJECT *This )
  113. {
  114. LONG rc;
  115. if( ( rc = InterlockedDecrement( &This->pObject->m_lRefCount ) ) == 0 )
  116. {
  117. DPFX(DPFPREP, DVF_INFOLEVEL, "Destroying object" );
  118. delete This->pObject;
  119. delete This;
  120. DecrementObjectCount();
  121. }
  122. return rc;
  123. }
  124. #undef DPF_MODNAME
  125. #define DPF_MODNAME "CDPVCPI::EnumCompressionTypes"
  126. HRESULT CDPVCPI::EnumCompressionTypes( DPVCPIOBJECT *This, PVOID pBuffer, PDWORD pdwSize, PDWORD pdwNumElements, DWORD dwFlags )
  127. {
  128. if( pdwSize == NULL ||
  129. !DNVALID_WRITEPTR( pdwSize, sizeof( DWORD ) ) )
  130. {
  131. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for pdwSize" );
  132. return DVERR_INVALIDPOINTER;
  133. }
  134. if( *pdwSize > 0 &&
  135. !DNVALID_WRITEPTR( pBuffer, *pdwSize ) )
  136. {
  137. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for buffer" );
  138. return DVERR_INVALIDPOINTER;
  139. }
  140. CompressionNode *pcnWalker = s_pcnList;
  141. DWORD dwRequiredSize = 0,
  142. dwTmp = 0,
  143. dwNumElements = 0,
  144. dwStringSize = 0;
  145. LPBYTE pbDataPtr;
  146. DVFULLCOMPRESSIONINFO *pbStructPtr;
  147. HRESULT hr;
  148. // Walk the list and determine how much space we need
  149. while( pcnWalker != NULL )
  150. {
  151. hr = CI_GetSize( pcnWalker->pdvfci, &dwTmp );
  152. if( FAILED( hr ) )
  153. {
  154. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get size" );
  155. return hr;
  156. }
  157. dwRequiredSize += dwTmp;
  158. pcnWalker = pcnWalker->pcnNext;
  159. dwNumElements++;
  160. }
  161. if( dwRequiredSize > *pdwSize )
  162. {
  163. *pdwSize = dwRequiredSize;
  164. return DVERR_BUFFERTOOSMALL;
  165. }
  166. *pdwNumElements = dwNumElements;
  167. *pdwSize = dwRequiredSize;
  168. pbDataPtr = (LPBYTE) pBuffer;
  169. pbStructPtr = (DVFULLCOMPRESSIONINFO *) pBuffer;
  170. // Move data pointer to be right after location of
  171. pbDataPtr += (dwNumElements*sizeof(DVFULLCOMPRESSIONINFO));
  172. pcnWalker = s_pcnList;
  173. while( pcnWalker != NULL )
  174. {
  175. memcpy( pbStructPtr, pcnWalker->pdvfci, sizeof( DVFULLCOMPRESSIONINFO ) );
  176. // If there is a name, copy it at the end
  177. if( pcnWalker->pdvfci->lpszName != NULL && wcslen( pcnWalker->pdvfci->lpszName ) > 0 )
  178. {
  179. dwStringSize = (wcslen( pcnWalker->pdvfci->lpszName )+1)*2;
  180. memcpy( pbDataPtr, pcnWalker->pdvfci->lpszName, dwStringSize );
  181. pbStructPtr->lpszName = (wchar_t *) pbDataPtr;
  182. pbDataPtr += dwStringSize;
  183. }
  184. // If there's a description, copy it at the end
  185. if( pcnWalker->pdvfci->lpszDescription != NULL && wcslen( pcnWalker->pdvfci->lpszDescription ) > 0 )
  186. {
  187. dwStringSize = (wcslen( pcnWalker->pdvfci->lpszDescription)+1)*2;
  188. memcpy( pbDataPtr, pcnWalker->pdvfci->lpszDescription, dwStringSize );
  189. pbStructPtr->lpszDescription = (wchar_t *) pbDataPtr;
  190. pbDataPtr += dwStringSize;
  191. }
  192. // If there's a format, copy it at the end
  193. if( pcnWalker->pdvfci->lpwfxFormat != NULL )
  194. {
  195. dwStringSize = sizeof( WAVEFORMATEX ) + pcnWalker->pdvfci->lpwfxFormat->cbSize;
  196. memcpy( pbDataPtr, pcnWalker->pdvfci->lpwfxFormat, dwStringSize );
  197. pbStructPtr->lpwfxFormat = (LPWAVEFORMATEX) pbDataPtr;
  198. pbDataPtr += dwStringSize;
  199. }
  200. pbStructPtr ++;
  201. pcnWalker = pcnWalker->pcnNext;
  202. }
  203. return DV_OK;
  204. }
  205. #undef DPF_MODNAME
  206. #define DPF_MODNAME "CDPVCPI::IsCompressionSupported"
  207. HRESULT CDPVCPI::IsCompressionSupported( DPVCPIOBJECT *This, GUID guidCT )
  208. {
  209. DVFULLCOMPRESSIONINFO *pdvfci;
  210. if( !FAILED( CN_Get( guidCT, &pdvfci ) ) )
  211. {
  212. return DV_OK;
  213. }
  214. else
  215. {
  216. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid CT specified" );
  217. return DVERR_COMPRESSIONNOTSUPPORTED;
  218. }
  219. }
  220. #undef DPF_MODNAME
  221. #define DPF_MODNAME "CDPVCPI::GetCompressionInfo"
  222. HRESULT CDPVCPI::GetCompressionInfo( DPVCPIOBJECT *This, GUID guidCT, PVOID pBuffer, PDWORD pdwSize )
  223. {
  224. DVFULLCOMPRESSIONINFO *pdvfci;
  225. if( pdwSize == NULL ||
  226. !DNVALID_WRITEPTR( pdwSize, sizeof( DWORD ) ) )
  227. {
  228. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for pdwSize" );
  229. return DVERR_INVALIDPOINTER;
  230. }
  231. if( *pdwSize > 0 &&
  232. !DNVALID_WRITEPTR( pBuffer, *pdwSize ) )
  233. {
  234. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid pointer specified for buffer" );
  235. return DVERR_INVALIDPOINTER;
  236. }
  237. if( FAILED( CN_Get( guidCT, &pdvfci ) ) )
  238. {
  239. DPFX(DPFPREP, DVF_ERRORLEVEL, "Invalid CT specified" );
  240. return DVERR_COMPRESSIONNOTSUPPORTED;
  241. }
  242. else
  243. {
  244. DWORD dwSize;
  245. HRESULT hr;
  246. LPBYTE pbTmp;
  247. DWORD dwStringSize;
  248. DVFULLCOMPRESSIONINFO *pTmpInfo;
  249. hr = CI_GetSize( pdvfci, &dwSize );
  250. if( FAILED( hr ) )
  251. {
  252. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get size of ci" );
  253. return hr;
  254. }
  255. if( dwSize > *pdwSize )
  256. {
  257. *pdwSize = dwSize;
  258. DPFX(DPFPREP, DVF_WARNINGLEVEL, "Buffer too small" );
  259. return DVERR_BUFFERTOOSMALL;
  260. }
  261. *pdwSize = dwSize;
  262. memcpy( pBuffer, pdvfci, sizeof( DVFULLCOMPRESSIONINFO ) );
  263. pbTmp = (LPBYTE) pBuffer;
  264. pTmpInfo = (DVFULLCOMPRESSIONINFO *) pBuffer;
  265. pbTmp += sizeof( DVFULLCOMPRESSIONINFO );
  266. // If there is a name
  267. if( pdvfci->lpszName != NULL && wcslen( pdvfci->lpszName ) > 0 )
  268. {
  269. dwStringSize = (wcslen( pdvfci->lpszName )+1)*2;
  270. memcpy( pbTmp, pdvfci->lpszName, dwStringSize );
  271. pTmpInfo->lpszName = (wchar_t *) pbTmp;
  272. pbTmp += dwStringSize;
  273. }
  274. if( pdvfci->lpszDescription != NULL && wcslen( pdvfci->lpszDescription ) > 0 )
  275. {
  276. dwStringSize = (wcslen( pdvfci->lpszDescription)+1)*2;
  277. memcpy( pbTmp, pdvfci->lpszDescription, dwStringSize );
  278. pTmpInfo->lpszDescription = (wchar_t *) pbTmp;
  279. pbTmp += dwStringSize;
  280. }
  281. if( pdvfci->lpwfxFormat != NULL )
  282. {
  283. memcpy( pbTmp, pdvfci->lpwfxFormat, sizeof( WAVEFORMATEX ) + pdvfci->lpwfxFormat->cbSize );
  284. pTmpInfo->lpwfxFormat = (LPWAVEFORMATEX) pbTmp;
  285. }
  286. return DV_OK;
  287. }
  288. }
  289. #undef DPF_MODNAME
  290. #define DPF_MODNAME "CDPVCPI::CN_Add"
  291. HRESULT CDPVCPI::CN_Add( DVFULLCOMPRESSIONINFO *pdvfci )
  292. {
  293. CompressionNode *pcnNewNode = new CompressionNode;
  294. if( pcnNewNode == NULL )
  295. {
  296. DPFX(DPFPREP, DVF_ERRORLEVEL, "Memory alloc failure" );
  297. return DVERR_OUTOFMEMORY;
  298. }
  299. pcnNewNode->pcnNext = s_pcnList;
  300. pcnNewNode->pdvfci = pdvfci;
  301. s_pcnList = pcnNewNode;
  302. return DV_OK;
  303. }
  304. #undef DPF_MODNAME
  305. #define DPF_MODNAME "CDPVCPI::CN_Get"
  306. HRESULT CDPVCPI::CN_Get( GUID guidCT, DVFULLCOMPRESSIONINFO **pdvfci )
  307. {
  308. CompressionNode *pcnWalker = s_pcnList;
  309. *pdvfci = NULL;
  310. while( pcnWalker != NULL )
  311. {
  312. if( pcnWalker->pdvfci->guidType == guidCT )
  313. {
  314. *pdvfci = pcnWalker->pdvfci;
  315. return DV_OK;
  316. }
  317. pcnWalker = pcnWalker->pcnNext;
  318. }
  319. return DVERR_COMPRESSIONNOTSUPPORTED;
  320. }
  321. #undef DPF_MODNAME
  322. #define DPF_MODNAME "CDPVCPI::CN_FreeList"
  323. void CDPVCPI::CN_FreeItem( CompressionNode *pcNode )
  324. {
  325. if( pcNode->pdvfci->lpwfxFormat != NULL )
  326. {
  327. delete [] pcNode->pdvfci->lpwfxFormat;
  328. }
  329. if( pcNode->pdvfci->lpszName != NULL )
  330. {
  331. delete [] pcNode->pdvfci->lpszName;
  332. }
  333. if( pcNode->pdvfci->lpszDescription != NULL )
  334. {
  335. delete [] pcNode->pdvfci->lpszDescription;
  336. }
  337. delete pcNode->pdvfci;
  338. delete pcNode;
  339. }
  340. // Free up the list, deallocating memory.
  341. #undef DPF_MODNAME
  342. #define DPF_MODNAME "CDPVCPI::CN_FreeList"
  343. HRESULT CDPVCPI::CN_FreeList()
  344. {
  345. CompressionNode *pcnWalker = s_pcnList;
  346. CompressionNode *pcnTmp;
  347. while( pcnWalker != NULL )
  348. {
  349. pcnTmp = pcnWalker;
  350. pcnWalker = pcnWalker->pcnNext;
  351. CN_FreeItem( pcnTmp );
  352. }
  353. s_pcnList = NULL;
  354. return DV_OK;
  355. }
  356. #undef DPF_MODNAME
  357. #define DPF_MODNAME "CDPVCPI::CI_GetSize"
  358. HRESULT CDPVCPI::CI_GetSize( DVFULLCOMPRESSIONINFO *pdvfci, LPDWORD lpdwSize )
  359. {
  360. DWORD dwSize = sizeof( DVFULLCOMPRESSIONINFO );
  361. if( pdvfci->lpwfxFormat != NULL )
  362. {
  363. dwSize += sizeof( WAVEFORMATEX ) + pdvfci->lpwfxFormat->cbSize;
  364. }
  365. if( pdvfci->lpszName != NULL )
  366. {
  367. dwSize += ((wcslen( pdvfci->lpszName )+1)*2);
  368. }
  369. if( pdvfci->lpszDescription != NULL )
  370. {
  371. dwSize += ((wcslen( pdvfci->lpszDescription )+1)*2);
  372. }
  373. *lpdwSize = dwSize;
  374. return DV_OK;
  375. }