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.

778 lines
18 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
  4. //
  5. // MSHDSP.DLL is a sample WMDM Service Provider(SP) that enumerates fixed drives.
  6. // This sample shows you how to implement an SP according to the WMDM documentation.
  7. // This sample uses fixed drives on your PC to emulate portable media, and
  8. // shows the relationship between different interfaces and objects. Each hard disk
  9. // volume is enumerated as a device and directories and files are enumerated as
  10. // Storage objects under respective devices. You can copy non-SDMI compliant content
  11. // to any device that this SP enumerates. To copy an SDMI compliant content to a
  12. // device, the device must be able to report a hardware embedded serial number.
  13. // Hard disks do not have such serial numbers.
  14. //
  15. // To build this SP, you are recommended to use the MSHDSP.DSP file under Microsoft
  16. // Visual C++ 6.0 and run REGSVR32.EXE to register the resulting MSHDSP.DLL. You can
  17. // then build the sample application from the WMDMAPP directory to see how it gets
  18. // loaded by the application. However, you need to obtain a certificate from
  19. // Microsoft to actually run this SP. This certificate would be in the KEY.C file
  20. // under the INCLUDE directory for one level up.
  21. // MDSPDevice.cpp : Implementation of CMDSPDevice
  22. #include "hdspPCH.h"
  23. #include "mshdsp.h"
  24. #include "wmsstd.h"
  25. #define STRSAFE_NO_DEPRECATE
  26. #include "strsafe.h"
  27. /////////////////////////////////////////////////////////////////////////////
  28. // CMDSPDevice
  29. HRESULT CMDSPDevice::InitGlobalDeviceInfo()
  30. {
  31. return SetGlobalDeviceStatus(m_wcsName, 0, FALSE);
  32. }
  33. CMDSPDevice::CMDSPDevice()
  34. {
  35. m_wcsName[0] = 0;
  36. }
  37. CMDSPDevice::~CMDSPDevice()
  38. {
  39. }
  40. STDMETHODIMP CMDSPDevice::GetName(LPWSTR pwszName, UINT nMaxChars)
  41. {
  42. HRESULT hr = E_FAIL;
  43. CFRg(g_pAppSCServer);
  44. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  45. {
  46. CORg(WMDM_E_NOTCERTIFIED);
  47. }
  48. CARg(pwszName);
  49. CPRg(nMaxChars>wcslen(m_wcsName));
  50. if( m_wcsName[0] )
  51. {
  52. wcscpy(pwszName, m_wcsName);
  53. hr = S_OK;
  54. }
  55. else
  56. {
  57. hr = WMDM_E_NOTSUPPORTED;
  58. }
  59. Error:
  60. hrLogDWORD("IMDSPDevice::GetName returned 0x%08lx", hr, hr);
  61. return hr;
  62. }
  63. STDMETHODIMP CMDSPDevice::GetManufacturer(LPWSTR pwszName, UINT nMaxChars)
  64. {
  65. HRESULT hr = S_OK;
  66. CFRg(g_pAppSCServer);
  67. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  68. {
  69. CORg(WMDM_E_NOTCERTIFIED);
  70. }
  71. CARg(pwszName);
  72. if(FAILED(UtilGetManufacturer(m_wcsName, &pwszName, nMaxChars)))
  73. {
  74. if (hr != STRSAFE_E_INSUFFICIENT_BUFFER)
  75. {
  76. hr = E_NOTIMPL;
  77. }
  78. }
  79. Error:
  80. hrLogDWORD("IMDSPDevice::GetManufacturer returned 0x%08lx", hr, hr);
  81. return hr;
  82. }
  83. STDMETHODIMP CMDSPDevice::GetVersion(DWORD * pdwVersion)
  84. {
  85. HRESULT hr;
  86. CFRg(g_pAppSCServer);
  87. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  88. {
  89. CORg(WMDM_E_NOTCERTIFIED);
  90. }
  91. hr = WMDM_E_NOTSUPPORTED;
  92. Error:
  93. hrLogDWORD("IMDSPDevice::GetVersion returned 0x%08lx", hr, hr);
  94. return hr;
  95. }
  96. STDMETHODIMP CMDSPDevice::GetType(DWORD * pdwType)
  97. {
  98. HRESULT hr = S_OK;
  99. WMDMID snTmp;
  100. CFRg(g_pAppSCServer);
  101. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  102. {
  103. CORg(WMDM_E_NOTCERTIFIED);
  104. }
  105. CARg(pdwType);
  106. *pdwType = WMDM_DEVICE_TYPE_STORAGE | WMDM_DEVICE_TYPE_NONSDMI;
  107. snTmp.cbSize = sizeof(WMDMID);
  108. hr = UtilGetSerialNumber(m_wcsName, &snTmp, FALSE);
  109. if( hr == S_OK )
  110. {
  111. *pdwType |= WMDM_DEVICE_TYPE_SDMI;
  112. }
  113. hr=S_OK;
  114. Error:
  115. hrLogDWORD("IMDSPDevice::GetType returned 0x%08lx", hr, hr);
  116. return hr;
  117. }
  118. STDMETHODIMP CMDSPDevice::GetSerialNumber(
  119. PWMDMID pSerialNumber,
  120. BYTE abMac[WMDM_MAC_LENGTH])
  121. {
  122. HRESULT hr;
  123. CFRg(g_pAppSCServer);
  124. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  125. {
  126. CORg(WMDM_E_NOTCERTIFIED);
  127. }
  128. CARg(pSerialNumber);
  129. hr = UtilGetSerialNumber(m_wcsName, pSerialNumber, TRUE);
  130. if( hr == HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) )
  131. {
  132. hr = WMDM_E_NOTSUPPORTED;
  133. }
  134. if( hr == S_OK )
  135. {
  136. // MAC the parameters
  137. HMAC hMAC;
  138. CORg(g_pAppSCServer->MACInit(&hMAC));
  139. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pSerialNumber), sizeof(WMDMID)));
  140. CORg(g_pAppSCServer->MACFinal(hMAC, abMac));
  141. }
  142. Error:
  143. hrLogDWORD("IMDSPDevice::GetSerialNumber returned 0x%08lx", hr, hr);
  144. return hr;
  145. }
  146. STDMETHODIMP CMDSPDevice::GetPowerSource(DWORD * pdwPowerSource, DWORD * pdwPercentRemaining)
  147. {
  148. HRESULT hr=S_OK;
  149. CFRg(g_pAppSCServer);
  150. if( !(g_pAppSCServer->fIsAuthenticated()) )
  151. {
  152. CORg(WMDM_E_NOTCERTIFIED);
  153. }
  154. CARg(pdwPowerSource);
  155. CARg(pdwPercentRemaining);
  156. *pdwPowerSource = WMDM_POWER_CAP_EXTERNAL |
  157. WMDM_POWER_IS_EXTERNAL |
  158. WMDM_POWER_PERCENT_AVAILABLE;
  159. *pdwPercentRemaining = 100;
  160. Error:
  161. hrLogDWORD("IMDSPDevice::GetPowerSource returned 0x%08lx", hr, hr);
  162. return hr;
  163. }
  164. STDMETHODIMP CMDSPDevice::GetStatus(DWORD * pdwStatus)
  165. {
  166. HRESULT hr = S_OK;
  167. CFRg(g_pAppSCServer);
  168. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  169. {
  170. CORg(WMDM_E_NOTCERTIFIED);
  171. }
  172. CARg(pdwStatus);
  173. CHRg(GetGlobalDeviceStatus(m_wcsName, pdwStatus));
  174. if( !( *pdwStatus & WMDM_STATUS_BUSY) )
  175. {
  176. *pdwStatus = WMDM_STATUS_READY;
  177. }
  178. hr = S_OK;
  179. Error:
  180. hrLogDWORD("IMDSPDevice::GetStatus returned 0x%08lx", hr, hr);
  181. return hr;
  182. }
  183. STDMETHODIMP CMDSPDevice::GetDeviceIcon(ULONG *hIcon)
  184. {
  185. HRESULT hr = S_OK;
  186. CFRg(g_pAppSCServer);
  187. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  188. {
  189. CORg(WMDM_E_NOTCERTIFIED);
  190. }
  191. CFRg(g_hinstance);
  192. CARg(hIcon);
  193. CWRg( (*hIcon)=HandleToULong(LoadIconA(g_hinstance, MAKEINTRESOURCEA(IDI_ICON_PM)) ));
  194. Error:
  195. hrLogDWORD("IMDSPDevice::GetDeviceIcon returned 0x%08lx", hr, hr);
  196. return hr;
  197. }
  198. // Opaque Command to get extended certification information
  199. //
  200. // GUID = {C39BF696-B776-459c-A13A-4B7116AB9F09}
  201. //
  202. static const GUID guidCertInfoEx =
  203. { 0xc39bf696, 0xb776, 0x459c, { 0xa1, 0x3a, 0x4b, 0x71, 0x16, 0xab, 0x9f, 0x9 } };
  204. typedef struct
  205. {
  206. HRESULT hr;
  207. DWORD cbCert;
  208. BYTE pbCert[1];
  209. } CERTINFOEX;
  210. static const BYTE bCertInfoEx_App[] =
  211. { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
  212. static const BYTE bCertInfoEx_SP[] =
  213. { 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
  214. 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
  215. STDMETHODIMP CMDSPDevice::SendOpaqueCommand(OPAQUECOMMAND *pCommand)
  216. {
  217. HRESULT hr;
  218. HMAC hMAC;
  219. BYTE abMACVerify[WMDM_MAC_LENGTH];
  220. CFRg(g_pAppSCServer);
  221. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  222. {
  223. CORg(WMDM_E_NOTCERTIFIED);
  224. }
  225. // Compute and verify MAC
  226. //
  227. CORg( g_pAppSCServer->MACInit(&hMAC) );
  228. CORg( g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(&(pCommand->guidCommand)), sizeof(GUID)) );
  229. CORg( g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(&(pCommand->dwDataLen)), sizeof(pCommand->dwDataLen)) );
  230. if( pCommand->pData )
  231. {
  232. CORg( g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pCommand->pData), pCommand->dwDataLen) );
  233. }
  234. CORg( g_pAppSCServer->MACFinal(hMAC, abMACVerify) );
  235. if (memcmp(abMACVerify, pCommand->abMAC, WMDM_MAC_LENGTH) != 0)
  236. {
  237. CORg(WMDM_E_MAC_CHECK_FAILED);
  238. }
  239. // Take action based on the command GUID
  240. //
  241. if( memcmp(&(pCommand->guidCommand), &guidCertInfoEx, sizeof(GUID)) == 0 )
  242. {
  243. //
  244. // Command to exchange extended authentication information
  245. //
  246. CERTINFOEX *pCertInfoEx;
  247. DWORD cbData_App = sizeof( bCertInfoEx_App )/sizeof( BYTE );
  248. DWORD cbData_SP = sizeof( bCertInfoEx_SP )/sizeof( BYTE );
  249. DWORD cbData_Return = sizeof(CERTINFOEX) + cbData_SP;
  250. // The caller must include their extended cert info
  251. //
  252. if( !pCommand->pData )
  253. {
  254. CORg( E_INVALIDARG );
  255. }
  256. // Map the data in the opaque command to a CERTINFOEX structure
  257. //
  258. pCertInfoEx = (CERTINFOEX *)pCommand->pData;
  259. // In this simple extended authentication scheme, the caller must
  260. // provide the exact cert info
  261. //
  262. if( (pCertInfoEx->cbCert != cbData_App) ||
  263. (memcmp(pCertInfoEx->pbCert, bCertInfoEx_App, cbData_App) != 0) )
  264. {
  265. CORg( WMDM_E_NOTCERTIFIED );
  266. }
  267. // Free the caller data and allocate enough data for our return data
  268. //
  269. CoTaskMemFree( pCommand->pData );
  270. CFRg( (pCommand->pData = (BYTE *)CoTaskMemAlloc(cbData_Return)) );
  271. pCommand->dwDataLen = cbData_Return;
  272. // Copy the extended cert info into return data structure
  273. //
  274. pCertInfoEx = (CERTINFOEX *)pCommand->pData;
  275. pCertInfoEx->hr = S_OK;
  276. pCertInfoEx->cbCert = cbData_SP;
  277. memcpy( pCertInfoEx->pbCert, bCertInfoEx_SP, cbData_SP );
  278. // Compute MAC on return data
  279. //
  280. CORg( g_pAppSCServer->MACInit( &hMAC ) );
  281. CORg( g_pAppSCServer->MACUpdate( hMAC, (BYTE*)(&(pCommand->guidCommand)), sizeof(GUID) ) );
  282. CORg( g_pAppSCServer->MACUpdate( hMAC, (BYTE*)(&(pCommand->dwDataLen)), sizeof(pCommand->dwDataLen) ) );
  283. if( pCommand->pData )
  284. {
  285. CORg( g_pAppSCServer->MACUpdate( hMAC, (BYTE*)(pCommand->pData), pCommand->dwDataLen ) );
  286. }
  287. CORg( g_pAppSCServer->MACFinal( hMAC, pCommand->abMAC ) );
  288. hr = S_OK;
  289. }
  290. else
  291. {
  292. CORg(WMDM_E_NOTSUPPORTED);
  293. }
  294. Error:
  295. hrLogDWORD("IMDSPDevice::SendOpaqueCommand returned 0x%08lx", hr, hr);
  296. return hr;
  297. }
  298. // IMDSPDevice2
  299. STDMETHODIMP CMDSPDevice::GetStorage( LPCWSTR pszStorageName, IMDSPStorage** ppStorage )
  300. {
  301. HRESULT hr;
  302. HRESULT hrTemp;
  303. WCHAR pwszFileName[MAX_PATH+1];
  304. char pszTemp[MAX_PATH];
  305. CComObject<CMDSPStorage> *pStg = NULL;
  306. // Get name of new file
  307. DWORD dwLen = wcslen(m_wcsName);
  308. // We reserve one char for the \ that might be added below
  309. if (dwLen >= ARRAYSIZE(pwszFileName)-1)
  310. {
  311. hr = STRSAFE_E_INSUFFICIENT_BUFFER; //defined in strsafe.h
  312. goto Error;
  313. }
  314. wcscpy( pwszFileName, m_wcsName );
  315. if( pwszFileName[dwLen-1] != '\\' )
  316. wcscat( pwszFileName, L"\\" );
  317. hrTemp = StringCchCatW( pwszFileName,
  318. ARRAYSIZE(pwszFileName) - 1,
  319. // - 1 ensures the result fits into a MAX_PATH buffer.
  320. // This makes the wcscpy into pStg->m_wcsName (below) safe.
  321. pszStorageName );
  322. if (FAILED(hrTemp))
  323. {
  324. // The file does not exist
  325. hr = E_FAIL; // @@@@ Something else? S_FALSE?
  326. goto Error;
  327. }
  328. WideCharToMultiByte(CP_ACP, NULL, pwszFileName, -1, pszTemp, MAX_PATH, NULL, NULL);
  329. if( GetFileAttributesA( pszTemp ) == -1 )
  330. {
  331. // The file does not exist
  332. hr = S_FALSE;
  333. goto Error;
  334. }
  335. // Create new storage object
  336. hr = CComObject<CMDSPStorage>::CreateInstance(&pStg);
  337. hr = pStg->QueryInterface( IID_IMDSPStorage, reinterpret_cast<void**>(ppStorage));
  338. wcscpy(pStg->m_wcsName, pwszFileName);
  339. Error:
  340. if( hr != S_OK )
  341. {
  342. *ppStorage = NULL;
  343. }
  344. hrLogDWORD("IMDSPDevice::GetStorage returned 0x%08lx", hr, hr);
  345. return hr;
  346. }
  347. STDMETHODIMP CMDSPDevice::GetFormatSupport2(
  348. DWORD dwFlags,
  349. _WAVEFORMATEX** ppAudioFormatEx,
  350. UINT* pnAudioFormatCount,
  351. _VIDEOINFOHEADER** ppVideoFormatEx,
  352. UINT* pnVideoFormatCount,
  353. WMFILECAPABILITIES** ppFileType,
  354. UINT* pnFileTypeCount )
  355. {
  356. return E_NOTIMPL;
  357. }
  358. STDMETHODIMP CMDSPDevice::GetSpecifyPropertyPages(
  359. ISpecifyPropertyPages** ppSpecifyPropPages,
  360. IUnknown*** pppUnknowns,
  361. ULONG *pcUnks )
  362. {
  363. HRESULT hr;
  364. IUnknown** ppUnknownArray = NULL;
  365. CFRg(g_pAppSCServer);
  366. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  367. {
  368. CORg(WMDM_E_NOTCERTIFIED);
  369. }
  370. CARg(ppSpecifyPropPages);
  371. CARg(pppUnknowns);
  372. CARg(pcUnks);
  373. // This object also supports the ISpecifyPropertyPages interface
  374. CORg( QueryInterface( __uuidof(ISpecifyPropertyPages),
  375. reinterpret_cast<void**>(ppSpecifyPropPages) ) );
  376. // Return one IUnknown interface, property page will QI for IDevice
  377. ppUnknownArray = (IUnknown**)CoTaskMemAlloc( sizeof(IUnknown*[1]) );
  378. CORg( QueryInterface( __uuidof(IUnknown),
  379. reinterpret_cast<void**>(&ppUnknownArray[0]) ) );
  380. *pppUnknowns = ppUnknownArray;
  381. *pcUnks = 1;
  382. Error:
  383. hrLogDWORD("IMDSPDevice::GetSpecifyPropertyPages returned 0x%08lx", hr, hr);
  384. return hr;
  385. }
  386. STDMETHODIMP CMDSPDevice::GetPnPName( LPWSTR pwszPnPName, UINT nMaxChars )
  387. {
  388. return E_NOTIMPL;
  389. }
  390. // ISpecifyPropertyPages
  391. STDMETHODIMP CMDSPDevice::GetPages(CAUUID *pPages)
  392. {
  393. HRESULT hr = S_OK;
  394. if( pPages == NULL )
  395. {
  396. return E_POINTER;
  397. }
  398. // Return the GUID for our property page
  399. pPages->cElems = 1;
  400. pPages->pElems = (GUID *)CoTaskMemAlloc( sizeof(GUID) * pPages->cElems );
  401. if( pPages->pElems == NULL )
  402. {
  403. hr = E_OUTOFMEMORY;
  404. }
  405. else
  406. {
  407. memcpy( &pPages->pElems[0], &__uuidof(HDSPPropPage), sizeof(GUID) );
  408. }
  409. return( hr );
  410. }
  411. // IMDSPDeviceControl
  412. STDMETHODIMP CMDSPDevice::GetDCStatus(/*[out]*/ DWORD *pdwStatus)
  413. {
  414. HRESULT hr = E_FAIL;
  415. CFRg(g_pAppSCServer);
  416. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  417. {
  418. CORg(WMDM_E_NOTCERTIFIED);
  419. }
  420. hr = GetStatus(pdwStatus);
  421. Error:
  422. hrLogDWORD("IMDSPDeviceControl::GetDCStatus returned 0x%08lx", hr, hr);
  423. return hr;
  424. }
  425. STDMETHODIMP CMDSPDevice::GetCapabilities(/*[out]*/ DWORD *pdwCapabilitiesMask)
  426. {
  427. HRESULT hr;
  428. CFRg(g_pAppSCServer);
  429. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  430. {
  431. CORg(WMDM_E_NOTCERTIFIED);
  432. }
  433. if( !pdwCapabilitiesMask )
  434. {
  435. return E_INVALIDARG;
  436. }
  437. *pdwCapabilitiesMask = WMDM_DEVICECAP_CANSTREAMPLAY;
  438. hr = S_OK;
  439. Error:
  440. hrLogDWORD("IMDSPDeviceControl::GetCapabilities returned 0x%08lx", hr, hr);
  441. return S_OK;
  442. }
  443. STDMETHODIMP CMDSPDevice::Play()
  444. {
  445. HRESULT hr;
  446. CFRg(g_pAppSCServer);
  447. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  448. {
  449. CORg(WMDM_E_NOTCERTIFIED);
  450. }
  451. hr = WMDM_E_NOTSUPPORTED;
  452. Error:
  453. hrLogDWORD("IMDSPDeviceControl::Play returned 0x%08lx", hr, hr);
  454. return hr;
  455. }
  456. STDMETHODIMP CMDSPDevice::Record(/*[in]*/ _WAVEFORMATEX *pFormat)
  457. {
  458. HRESULT hr;
  459. CFRg(g_pAppSCServer);
  460. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  461. {
  462. CORg(WMDM_E_NOTCERTIFIED);
  463. }
  464. hr = WMDM_E_NOTSUPPORTED;
  465. Error:
  466. hrLogDWORD("IMDSPDeviceControl::Record returned 0x%08lx", hr, hr);
  467. return hr;
  468. }
  469. STDMETHODIMP CMDSPDevice::Pause()
  470. {
  471. HRESULT hr;
  472. CFRg(g_pAppSCServer);
  473. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  474. {
  475. CORg(WMDM_E_NOTCERTIFIED);
  476. }
  477. hr = WMDM_E_NOTSUPPORTED;
  478. Error:
  479. hrLogDWORD("IMDSPDeviceControl::Pause returned 0x%08lx", hr, hr);
  480. return hr;
  481. }
  482. STDMETHODIMP CMDSPDevice::Resume()
  483. {
  484. HRESULT hr;
  485. CFRg(g_pAppSCServer);
  486. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  487. {
  488. CORg(WMDM_E_NOTCERTIFIED);
  489. }
  490. hr = WMDM_E_NOTSUPPORTED;
  491. Error:
  492. hrLogDWORD("IMDSPDeviceControl::Resume returned 0x%08lx", hr, hr);
  493. return hr;
  494. }
  495. STDMETHODIMP CMDSPDevice::Stop()
  496. {
  497. HRESULT hr;
  498. CFRg(g_pAppSCServer);
  499. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  500. {
  501. CORg(WMDM_E_NOTCERTIFIED);
  502. }
  503. hr = WMDM_E_NOTSUPPORTED;
  504. Error:
  505. hrLogDWORD("IMDSPDeviceControl::Stop returned 0x%08lx", hr, hr);
  506. return hr;
  507. }
  508. STDMETHODIMP CMDSPDevice::Seek(/*[in]*/ UINT fuMode, /*[in]*/ int nOffset)
  509. {
  510. HRESULT hr;
  511. CFRg(g_pAppSCServer);
  512. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  513. {
  514. CORg(WMDM_E_NOTCERTIFIED);
  515. }
  516. hr = WMDM_E_NOTSUPPORTED;
  517. Error:
  518. hrLogDWORD("IMDSPDeviceControl::Seek returned 0x%08lx", hr, hr);
  519. return hr;
  520. }
  521. STDMETHODIMP CMDSPDevice::GetFormatSupport(
  522. _WAVEFORMATEX **pFormatEx,
  523. UINT *pnFormatCount,
  524. LPWSTR **pppwszMimeType,
  525. UINT *pnMimeTypeCount)
  526. {
  527. HRESULT hr = S_OK;
  528. CFRg(g_pAppSCServer);
  529. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  530. {
  531. CORg(WMDM_E_NOTCERTIFIED);
  532. }
  533. CARg(pFormatEx);
  534. CARg(pppwszMimeType);
  535. CARg(pnFormatCount);
  536. CARg(pnMimeTypeCount);
  537. *pnFormatCount = 1;
  538. *pFormatEx = (_WAVEFORMATEX *)CoTaskMemAlloc(sizeof(_WAVEFORMATEX));
  539. CPRg( *pFormatEx );
  540. (*pFormatEx)->wFormatTag = WMDM_WAVE_FORMAT_ALL;
  541. (*pFormatEx)->nChannels = 2;
  542. (*pFormatEx)->cbSize = 0;
  543. (*pFormatEx)->nSamplesPerSec = 0;
  544. (*pFormatEx)->nAvgBytesPerSec = 0;
  545. (*pFormatEx)->nBlockAlign = 0;
  546. (*pFormatEx)->wBitsPerSample = 0;
  547. *pnMimeTypeCount= 1;
  548. *pppwszMimeType = (LPWSTR *)CoTaskMemAlloc(sizeof(LPWSTR)*1);
  549. CPRg(*pppwszMimeType);
  550. **pppwszMimeType = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR)*(wcslen(WCS_MIME_TYPE_ALL)+1));
  551. CPRg(**pppwszMimeType);
  552. wcscpy(**pppwszMimeType, WCS_MIME_TYPE_ALL);
  553. Error:
  554. hrLogDWORD("IMDSPDevice::GetFormatSupport returned 0x%08lx", hr, hr);
  555. return hr;
  556. }
  557. STDMETHODIMP CMDSPDevice::EnumStorage(IMDSPEnumStorage** ppEnumStorage)
  558. {
  559. HRESULT hr;
  560. CFRg(g_pAppSCServer);
  561. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  562. {
  563. CORg(WMDM_E_NOTCERTIFIED);
  564. }
  565. CARg(ppEnumStorage);
  566. CComObject<CMDSPEnumStorage> *pEnumObj;
  567. CORg(CComObject<CMDSPEnumStorage>::CreateInstance(&pEnumObj));
  568. hr = pEnumObj->QueryInterface(
  569. IID_IMDSPEnumStorage,
  570. reinterpret_cast<void**>(ppEnumStorage)
  571. );
  572. if( FAILED(hr) )
  573. {
  574. delete pEnumObj;
  575. }
  576. else
  577. {
  578. // wcscpy(pEnumObj->m_wcsPath, m_wcsName);
  579. hr = StringCbCopyW(pEnumObj->m_wcsPath,
  580. ARRAYSIZE(pEnumObj->m_wcsPath),
  581. m_wcsName);
  582. if (FAILED(hr))
  583. {
  584. (*ppEnumStorage)->Release();
  585. *ppEnumStorage = NULL;
  586. goto Error;
  587. }
  588. }
  589. Error:
  590. hrLogDWORD("IMDSPDevice::EnumStorage returned 0x%08lx", hr, hr);
  591. return hr;
  592. }