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.

625 lines
16 KiB

  1. /*==========================================================================
  2. *
  3. * Copyright (C) 1999 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: dvcdb.cpp
  6. * Content:
  7. * This module contains the implementation of the compression
  8. * subsystem and the associated utility functions.
  9. *
  10. * History:
  11. * Date By Reason
  12. * ==== == ======
  13. * 08/29/99 rodtoll Created
  14. * 09/01/99 rodtoll Updated to add checks for valid read/write pointers
  15. * 09/07/99 rodtoll Removed bad assert and added dpf_modnames
  16. * Removed Create flag on registry opens
  17. * 09/10/99 rodtoll dwFlags check on call to DVCDB_CopyCompress...
  18. * 09/14/99 rodtoll Minor bugfix in compression info copy
  19. * 09/21/99 rodtoll Added OSInd and fixed memory leak
  20. * 10/07/99 rodtoll Added stubs for supporting new codecs
  21. * rodtoll Updated to use Unicode
  22. * 10/15/99 rodtoll Plugged some memory leaks
  23. * 10/28/99 rodtoll Updated to use new compression providers
  24. * 10/29/99 rodtoll Bug #113726 - Integrate Voxware Codecs, updating to use new
  25. * pluggable codec architecture.
  26. * 11/22/99 rodtoll Removed false error message when loading compression types
  27. * 12/16/99 rodtoll Removed asserts (which were not needed) exposed by compression
  28. * provider changes.
  29. * 02/10/2000 rodtoll Fixed crash if invalid registry entries are present.
  30. * 03/03/2000 rodtoll Updated to handle alternative gamevoice build.
  31. * 03/16/2000 rodtoll Updated converter create to check and return error code
  32. * 04/21/2000 rodtoll Bug #32889 - Does not run on Win2k w/o Admin
  33. * 06/09/00 rmt Updates to split CLSID and allow whistler compat and support external create funcs
  34. * 06/28/2000 rodtoll Prefix Bug #38022
  35. * 08/28/2000 masonb Voice Merge: Removed OSAL_* and dvosal.h, added STR_* and strutils.h
  36. * 08/31/2000 rodtoll Prefix Bug #171840
  37. * 10/05/2000 rodtoll Bug #46541 - DPVOICE: A/V linking to dpvoice.lib could cause application to fail init and crash
  38. *
  39. ***************************************************************************/
  40. #include "dxvutilspch.h"
  41. #undef DPF_SUBCOMP
  42. #define DPF_SUBCOMP DN_SUBCOMP_VOICE
  43. struct DVCDBProvider
  44. {
  45. GUID guidClassID;
  46. PDVFULLCOMPRESSIONINFO pInfo;
  47. DWORD dwNumElements;
  48. DVCDBProvider *pNext;
  49. };
  50. DVCDBProvider *g_dvcdbProviderList = NULL;
  51. #define REGISTRY_CDB_FORMAT L"Format"
  52. #define REGISTRY_WAVEFORMAT_RATE L"Rate"
  53. #define REGISTRY_WAVEFORMAT_BITS L"Bits"
  54. #define REGISTRY_WAVEFORMAT_CHANNELS L"Channels"
  55. #define REGISTRY_WAVEFORMAT_TAG L"Tag"
  56. #define REGISTRY_WAVEFORMAT_AVGPERSEC L"AvgPerSec"
  57. #define REGISTRY_WAVEFORMAT_BLOCKALIGN L"BlockAlign"
  58. #define REGISTRY_WAVEFORMAT_CBSIZE L"cbsize"
  59. #define REGISTRY_WAVEFORMAT_CBDATA L"cbdata"
  60. #undef DPF_MODNAME
  61. #define DPF_MODNAME "DVCDB_CalcUnCompressedFrameSize"
  62. DWORD DVCDB_CalcUnCompressedFrameSize( const DVFULLCOMPRESSIONINFO* lpdvInfo, const WAVEFORMATEX* lpwfxFormat )
  63. {
  64. DWORD frameSize;
  65. switch( lpwfxFormat->nSamplesPerSec )
  66. {
  67. case 8000: frameSize = lpdvInfo->dwFrame8Khz; break;
  68. case 11025: frameSize = lpdvInfo->dwFrame11Khz; break;
  69. case 22050: frameSize = lpdvInfo->dwFrame22Khz; break;
  70. case 44100: frameSize = lpdvInfo->dwFrame44Khz; break;
  71. default: return 0;
  72. }
  73. if( lpwfxFormat->wBitsPerSample == 16 )
  74. frameSize *= 2;
  75. frameSize *= lpwfxFormat->nChannels;
  76. return frameSize;
  77. }
  78. #undef DPF_MODNAME
  79. #define DPF_MODNAME "CREG_ReadAndAllocWaveFormatEx"
  80. HRESULT CREG_ReadAndAllocWaveFormatEx( HKEY hkeyReg, LPCWSTR path, LPWAVEFORMATEX *lpwfxFormat )
  81. {
  82. CRegistry waveKey;
  83. if( !waveKey.Open( hkeyReg, path, TRUE, FALSE ) )
  84. {
  85. return E_FAIL;
  86. }
  87. DWORD dwTmp;
  88. if( !waveKey.ReadDWORD( REGISTRY_WAVEFORMAT_CBSIZE, &dwTmp ) )
  89. {
  90. return E_FAIL;
  91. }
  92. *lpwfxFormat = (LPWAVEFORMATEX) new BYTE[dwTmp+sizeof(WAVEFORMATEX)];
  93. LPWAVEFORMATEX tmpFormat = *lpwfxFormat;
  94. if( tmpFormat == NULL )
  95. {
  96. return E_OUTOFMEMORY;
  97. }
  98. tmpFormat->cbSize = (BYTE) dwTmp;
  99. if( !waveKey.ReadDWORD( REGISTRY_WAVEFORMAT_RATE, &dwTmp ) )
  100. {
  101. goto READ_FAILURE;
  102. }
  103. tmpFormat->nSamplesPerSec = dwTmp;
  104. if( !waveKey.ReadDWORD( REGISTRY_WAVEFORMAT_BITS, &dwTmp ) )
  105. {
  106. goto READ_FAILURE;
  107. }
  108. tmpFormat->wBitsPerSample = (WORD) dwTmp;
  109. if( !waveKey.ReadDWORD( REGISTRY_WAVEFORMAT_CHANNELS, &dwTmp ) )
  110. {
  111. goto READ_FAILURE;
  112. }
  113. tmpFormat->nChannels = (INT) dwTmp;
  114. if( !waveKey.ReadDWORD( REGISTRY_WAVEFORMAT_TAG, &dwTmp ) )
  115. {
  116. goto READ_FAILURE;
  117. }
  118. tmpFormat->wFormatTag = (WORD) dwTmp;
  119. if( !waveKey.ReadDWORD( REGISTRY_WAVEFORMAT_AVGPERSEC, &dwTmp ) )
  120. {
  121. goto READ_FAILURE;
  122. }
  123. tmpFormat->nAvgBytesPerSec = (INT) dwTmp;
  124. if( !waveKey.ReadDWORD( REGISTRY_WAVEFORMAT_BLOCKALIGN, &dwTmp ) )
  125. {
  126. goto READ_FAILURE;
  127. }
  128. tmpFormat->nBlockAlign = (INT) dwTmp;
  129. dwTmp = tmpFormat->cbSize;
  130. if( !waveKey.ReadBlob( REGISTRY_WAVEFORMAT_CBDATA, (LPBYTE) &tmpFormat[1], &dwTmp ) )
  131. {
  132. DPFX(DPFPREP, 0, "Error reading waveformat blob" );
  133. goto READ_FAILURE;
  134. }
  135. return S_OK;
  136. READ_FAILURE:
  137. delete [] *lpwfxFormat;
  138. *lpwfxFormat = NULL;
  139. return E_FAIL;
  140. }
  141. #undef DPF_MODNAME
  142. #define DPF_MODNAME "DVCDB_LoadCompressionInfo"
  143. HRESULT DVCDB_LoadCompressionInfo( const WCHAR *swzBaseRegistryPath )
  144. {
  145. CRegistry mainKey, subKey;
  146. LPWSTR keyName = NULL;
  147. DWORD dwIndex = 0;
  148. DWORD dwSize = 0;
  149. HRESULT hr;
  150. PDPVCOMPRESSIONPROVIDER pCompressionProvider = NULL;
  151. DVCDBProvider *pNewProvider = NULL;
  152. WCHAR wszPath[_MAX_PATH];
  153. if( swzBaseRegistryPath == NULL )
  154. {
  155. DPFX(DPFPREP, 0, "INTERNAL ERROR!" );
  156. return E_FAIL;
  157. }
  158. wcscpy( wszPath, swzBaseRegistryPath );
  159. wcscat( wszPath, DPVOICE_REGISTRY_CP );
  160. if( !mainKey.Open( HKEY_LOCAL_MACHINE, wszPath, TRUE, FALSE ) )
  161. {
  162. DPFX(DPFPREP, 0, "Error reading compression providers from the registry. Path doesn't exist" );
  163. return E_FAIL;
  164. }
  165. dwIndex = 0;
  166. keyName = NULL;
  167. dwSize = 0;
  168. LPSTR lpstrKeyName = NULL;
  169. GUID guidCP;
  170. // Enumerate the subkeys at this point in the tree
  171. while( 1 )
  172. {
  173. dwSize = 0;
  174. if( !mainKey.EnumKeys( keyName, &dwSize, dwIndex ) )
  175. {
  176. if( dwSize == 0 )
  177. {
  178. DPFX(DPFPREP, DVF_INFOLEVEL, "End of provider list" );
  179. break;
  180. }
  181. if( keyName != NULL )
  182. {
  183. delete [] keyName;
  184. }
  185. keyName = new wchar_t[dwSize];
  186. }
  187. if( !mainKey.EnumKeys( keyName, &dwSize, dwIndex ) )
  188. {
  189. delete [] keyName;
  190. break;
  191. }
  192. if( FAILED( STR_AllocAndConvertToANSI( &lpstrKeyName, keyName ) ) )
  193. {
  194. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error allocating memory" );
  195. break;
  196. }
  197. DPFX(DPFPREP, DVF_INFOLEVEL, "Reading provider: %hs", lpstrKeyName );
  198. if( !subKey.Open( mainKey, keyName, TRUE, FALSE ) )
  199. {
  200. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error reading provider: %hs", lpstrKeyName );
  201. goto SKIP_TO_NEXT;
  202. }
  203. delete [] keyName;
  204. keyName = NULL;
  205. dwSize = 0;
  206. // Read the GUID from the default key
  207. if( !subKey.ReadGUID( L"", &guidCP ) )
  208. {
  209. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to read the provider's GUID" );
  210. goto SKIP_TO_NEXT;
  211. }
  212. // Attempt to create the provider
  213. hr = COM_CoCreateInstance( guidCP , NULL, CLSCTX_INPROC_SERVER, IID_IDPVCompressionProvider, (void **) &pCompressionProvider, FALSE );
  214. if( FAILED( hr ) )
  215. {
  216. DPFX(DPFPREP, DVF_ERRORLEVEL, "FAILED to create 0x%x\n", hr );
  217. goto SKIP_TO_NEXT;
  218. }
  219. // Build a record for the provider
  220. pNewProvider = new DVCDBProvider;
  221. if( pNewProvider == NULL )
  222. {
  223. DPFX(DPFPREP, DVF_ERRORLEVEL, "Out of memory" );
  224. goto SKIP_TO_NEXT;
  225. }
  226. pNewProvider->guidClassID = guidCP;
  227. pNewProvider->pInfo = NULL;
  228. pNewProvider->dwNumElements = 0;
  229. dwSize = 0;
  230. // GetCompression Info for the provider
  231. hr = pCompressionProvider->EnumCompressionTypes( pNewProvider->pInfo, &dwSize, &pNewProvider->dwNumElements, 0 );
  232. if( hr != DVERR_BUFFERTOOSMALL )
  233. {
  234. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get compression info for provider: %hs", lpstrKeyName );
  235. goto SKIP_TO_NEXT;
  236. }
  237. pNewProvider->pInfo = (DVFULLCOMPRESSIONINFO *) new BYTE[dwSize];
  238. if( pNewProvider->pInfo == NULL )
  239. {
  240. DPFX(DPFPREP, DVF_ERRORLEVEL, "Out of memory" );
  241. goto SKIP_TO_NEXT;
  242. }
  243. hr = pCompressionProvider->EnumCompressionTypes( pNewProvider->pInfo, &dwSize, &pNewProvider->dwNumElements, 0 );
  244. if( FAILED( hr ) )
  245. {
  246. DPFX(DPFPREP, DVF_ERRORLEVEL, "Unable to get compression info for %hs hr=0x%x", lpstrKeyName, hr );
  247. goto SKIP_TO_NEXT;
  248. }
  249. // Add it to the list
  250. pNewProvider->pNext = g_dvcdbProviderList;
  251. g_dvcdbProviderList = pNewProvider;
  252. pNewProvider = NULL;
  253. SKIP_TO_NEXT:
  254. if( pCompressionProvider != NULL )
  255. {
  256. pCompressionProvider->Release();
  257. pCompressionProvider = NULL;
  258. }
  259. if( pNewProvider != NULL )
  260. {
  261. delete pNewProvider;
  262. pNewProvider = NULL;
  263. }
  264. if( lpstrKeyName != NULL )
  265. delete [] lpstrKeyName;
  266. if( keyName != NULL )
  267. delete [] keyName;
  268. lpstrKeyName = NULL;
  269. keyName = NULL;
  270. dwSize = 0;
  271. dwIndex++;
  272. continue;
  273. }
  274. if( lpstrKeyName != NULL )
  275. delete [] lpstrKeyName;
  276. if( keyName != NULL )
  277. delete [] keyName;
  278. return DV_OK;
  279. }
  280. #undef DPF_MODNAME
  281. #define DPF_MODNAME "DVCDB_FreeCompressionInfo"
  282. HRESULT DVCDB_FreeCompressionInfo()
  283. {
  284. DVCDBProvider *pTmpProvider, *pTmpNext;
  285. if( g_dvcdbProviderList == NULL )
  286. return DV_OK;
  287. pTmpProvider = g_dvcdbProviderList;
  288. while( pTmpProvider != NULL )
  289. {
  290. pTmpNext = pTmpProvider->pNext;
  291. delete [] pTmpProvider->pInfo;
  292. delete pTmpProvider;
  293. pTmpProvider = pTmpNext;
  294. }
  295. g_dvcdbProviderList = NULL;
  296. return DV_OK;
  297. }
  298. #undef DPF_MODNAME
  299. #define DPF_MODNAME "DVCDB_GetCompressionClassID"
  300. HRESULT DVCDB_GetCompressionClassID( const GUID& guidCT, GUID* pguidClass )
  301. {
  302. DVCDBProvider *pTmpProvider;
  303. DWORD dwIndex;
  304. pTmpProvider = g_dvcdbProviderList;
  305. while( pTmpProvider != NULL )
  306. {
  307. for( dwIndex = 0; dwIndex < pTmpProvider->dwNumElements; dwIndex++ )
  308. {
  309. if( pTmpProvider->pInfo[dwIndex].guidType == guidCT )
  310. {
  311. *pguidClass = pTmpProvider->guidClassID;
  312. return DV_OK;
  313. }
  314. }
  315. pTmpProvider = pTmpProvider->pNext;
  316. }
  317. return DVERR_COMPRESSIONNOTSUPPORTED;
  318. }
  319. #undef DPF_MODNAME
  320. #define DPF_MODNAME "DVCDB_GetCompressionInfo"
  321. HRESULT DVCDB_GetCompressionInfo( const GUID &guidType, PDVFULLCOMPRESSIONINFO *lpdvfCompressionInfo )
  322. {
  323. DVCDBProvider *pTmpProvider;
  324. DWORD dwIndex;
  325. pTmpProvider = g_dvcdbProviderList;
  326. while( pTmpProvider != NULL )
  327. {
  328. for( dwIndex = 0; dwIndex < pTmpProvider->dwNumElements; dwIndex++ )
  329. {
  330. if( pTmpProvider->pInfo[dwIndex].guidType == guidType )
  331. {
  332. *lpdvfCompressionInfo = &pTmpProvider->pInfo[dwIndex];
  333. return DV_OK;
  334. }
  335. }
  336. pTmpProvider = pTmpProvider->pNext;
  337. }
  338. return DVERR_COMPRESSIONNOTSUPPORTED;
  339. }
  340. #undef DPF_MODNAME
  341. #define DPF_MODNAME "DVCDB_CreateConverter"
  342. HRESULT DVCDB_CreateConverter( WAVEFORMATEX *pwfxSrcFormat, const GUID &guidTarget, PDPVCOMPRESSOR *pConverter )
  343. {
  344. HRESULT hr;
  345. GUID guidProvider;
  346. PDPVCOMPRESSIONPROVIDER pCompressionProvider = NULL;
  347. hr = DVCDB_GetCompressionClassID( guidTarget, &guidProvider );
  348. if( FAILED( hr ) )
  349. {
  350. DPFX(DPFPREP, DVF_ERRORLEVEL, "Requested compression type is not supported, hr=0x%x", hr );
  351. return hr;
  352. }
  353. hr = COM_CoCreateInstance( guidProvider , NULL, CLSCTX_INPROC_SERVER, IID_IDPVCompressionProvider, (void **) &pCompressionProvider, FALSE );
  354. if( FAILED( hr ) )
  355. {
  356. DPFX(DPFPREP, DVF_ERRORLEVEL, "FAILED to create 0x%x\n", hr );
  357. return DVERR_COMPRESSIONNOTSUPPORTED;
  358. }
  359. hr = pCompressionProvider->CreateCompressor( pwfxSrcFormat, guidTarget, pConverter, 0 );
  360. if( FAILED( hr ) )
  361. {
  362. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error creating compressor hr=0x%x", hr );
  363. return hr;
  364. }
  365. pCompressionProvider->Release();
  366. return hr;
  367. }
  368. #undef DPF_MODNAME
  369. #define DPF_MODNAME "DVCDB_CreateConverter"
  370. HRESULT DVCDB_CreateConverter( const GUID &guidSrc, WAVEFORMATEX *pwfxTarget, PDPVCOMPRESSOR *pConverter )
  371. {
  372. HRESULT hr;
  373. GUID guidProvider;
  374. PDPVCOMPRESSIONPROVIDER pCompressionProvider = NULL;
  375. hr = DVCDB_GetCompressionClassID( guidSrc, &guidProvider );
  376. if( FAILED( hr ) )
  377. {
  378. DPFX(DPFPREP, DVF_ERRORLEVEL, "Requested compression type is not supported, hr=0x%x", hr );
  379. return hr;
  380. }
  381. hr = COM_CoCreateInstance( guidProvider , NULL, CLSCTX_INPROC_SERVER, IID_IDPVCompressionProvider, (void **) &pCompressionProvider, FALSE );
  382. if( FAILED( hr ) )
  383. {
  384. DPFX(DPFPREP, DVF_ERRORLEVEL, "FAILED to create 0x%x\n", hr );
  385. return DVERR_COMPRESSIONNOTSUPPORTED;
  386. }
  387. hr = pCompressionProvider->CreateDeCompressor( guidSrc, pwfxTarget, pConverter, 0 );
  388. if( FAILED( hr ) )
  389. {
  390. DPFX(DPFPREP, DVF_ERRORLEVEL, "Error creating compressor hr=0x%x", hr );
  391. return hr;
  392. }
  393. pCompressionProvider->Release();
  394. return DV_OK;
  395. }
  396. #undef DPF_MODNAME
  397. #define DPF_MODNAME "DVCDB_CopyCompressionArrayToBuffer"
  398. HRESULT DVCDB_CopyCompressionArrayToBuffer( LPVOID lpBuffer, LPDWORD lpdwSize, LPDWORD lpdwNumElements, DWORD dwFlags )
  399. {
  400. if( lpdwNumElements == NULL || lpdwSize == NULL ||
  401. !DNVALID_READPTR(lpdwNumElements,sizeof(DWORD)) ||
  402. !DNVALID_READPTR(lpdwSize,sizeof(DWORD)) )
  403. {
  404. return E_POINTER;
  405. }
  406. if( dwFlags != 0 )
  407. {
  408. return DVERR_INVALIDFLAGS;
  409. }
  410. DWORD dwIndex, dwReadIndex;
  411. DWORD dwRequiredSize = 0;
  412. DWORD dwTmpSize;
  413. LPDVCOMPRESSIONINFO lpdvTargetList;
  414. LPBYTE lpbExtraLoc = (LPBYTE) lpBuffer;
  415. *lpdwNumElements = 0;
  416. DVCDBProvider *pTmpProvider;
  417. pTmpProvider = g_dvcdbProviderList;
  418. while( pTmpProvider != NULL )
  419. {
  420. for( dwIndex = 0; dwIndex < pTmpProvider->dwNumElements; dwIndex++ )
  421. {
  422. dwRequiredSize += DVCDB_GetCompressionInfoSize( (LPDVCOMPRESSIONINFO) &pTmpProvider->pInfo[dwIndex] );
  423. (*lpdwNumElements)++;
  424. }
  425. pTmpProvider = pTmpProvider->pNext;
  426. }
  427. if( *lpdwSize < dwRequiredSize )
  428. {
  429. *lpdwSize = dwRequiredSize;
  430. return DVERR_BUFFERTOOSMALL;
  431. }
  432. *lpdwSize = dwRequiredSize;
  433. if( lpBuffer == NULL || !DNVALID_WRITEPTR(lpBuffer,dwRequiredSize) )
  434. {
  435. return E_POINTER;
  436. }
  437. lpbExtraLoc += (*lpdwNumElements)*sizeof(DVCOMPRESSIONINFO);
  438. lpdvTargetList = (LPDVCOMPRESSIONINFO) lpBuffer;
  439. pTmpProvider = g_dvcdbProviderList;
  440. dwIndex = 0;
  441. while( pTmpProvider != NULL )
  442. {
  443. for( dwReadIndex = 0; dwReadIndex < pTmpProvider->dwNumElements; dwReadIndex++, dwIndex++ )
  444. {
  445. memcpy( &lpdvTargetList[dwIndex], &pTmpProvider->pInfo[dwReadIndex], sizeof(DVCOMPRESSIONINFO) );
  446. if( pTmpProvider->pInfo[dwReadIndex].lpszDescription != NULL )
  447. {
  448. dwTmpSize = (wcslen( pTmpProvider->pInfo[dwReadIndex].lpszDescription )*2)+2;
  449. memcpy( lpbExtraLoc, pTmpProvider->pInfo[dwReadIndex].lpszDescription, dwTmpSize );
  450. lpdvTargetList[dwIndex].lpszDescription = (LPWSTR) lpbExtraLoc;
  451. lpbExtraLoc += dwTmpSize;
  452. }
  453. if( pTmpProvider->pInfo[dwReadIndex].lpszName != NULL )
  454. {
  455. dwTmpSize = (wcslen( pTmpProvider->pInfo[dwReadIndex].lpszName )*2)+2;
  456. memcpy( lpbExtraLoc, pTmpProvider->pInfo[dwReadIndex].lpszName, dwTmpSize );
  457. lpdvTargetList[dwIndex].lpszName = (LPWSTR) lpbExtraLoc;
  458. lpbExtraLoc += dwTmpSize;
  459. }
  460. }
  461. pTmpProvider = pTmpProvider->pNext;
  462. }
  463. return DV_OK;
  464. }
  465. #undef DPF_MODNAME
  466. #define DPF_MODNAME "DVCDB_GetCompressionInfoSize"
  467. DWORD DVCDB_GetCompressionInfoSize( LPDVCOMPRESSIONINFO lpdvCompressionInfo )
  468. {
  469. DNASSERT( lpdvCompressionInfo != NULL );
  470. DWORD dwSize;
  471. dwSize = sizeof( DVCOMPRESSIONINFO );
  472. if( lpdvCompressionInfo->lpszDescription != NULL )
  473. {
  474. dwSize += (wcslen( lpdvCompressionInfo->lpszDescription )*2)+2;
  475. }
  476. if( lpdvCompressionInfo->lpszName != NULL )
  477. {
  478. dwSize += (wcslen( lpdvCompressionInfo->lpszName)*2)+2;
  479. }
  480. return dwSize;
  481. }