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.

695 lines
15 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // � 1999 Microsoft Corporation. All rights reserved.
  4. //
  5. // Refer to your End User License Agreement for details on your rights/restrictions to use these sample files.
  6. //
  7. // MSHDSP.DLL is a sample WMDM Service Provider(SP) that enumerates fixed drives.
  8. // This sample shows you how to implement an SP according to the WMDM documentation.
  9. // This sample uses fixed drives on your PC to emulate portable media, and
  10. // shows the relationship between different interfaces and objects. Each hard disk
  11. // volume is enumerated as a device and directories and files are enumerated as
  12. // Storage objects under respective devices. You can copy non-SDMI compliant content
  13. // to any device that this SP enumerates. To copy an SDMI compliant content to a
  14. // device, the device must be able to report a hardware embedded serial number.
  15. // Hard disks do not have such serial numbers.
  16. //
  17. // To build this SP, you are recommended to use the MSHDSP.DSP file under Microsoft
  18. // Visual C++ 6.0 and run REGSVR32.EXE to register the resulting MSHDSP.DLL. You can
  19. // then build the sample application from the WMDMAPP directory to see how it gets
  20. // loaded by the application. However, you need to obtain a certificate from
  21. // Microsoft to actually run this SP. This certificate would be in the KEY.C file
  22. // under the INCLUDE directory for one level up.
  23. // MDSPDevice.cpp : Implementation of CMDSPDevice
  24. #include "hdspPCH.h"
  25. #include "rescopy.h"
  26. #include <SerialNumber.h>
  27. #include <mmreg.h>
  28. //
  29. // Define some tables and constants we will need below
  30. //
  31. #define WAVE_FORMAT_MSAUDIO 0x161
  32. static const _WAVEFORMATEX g_krgWaveFormats[] =
  33. {
  34. // wFormatTag, nChanneels, nSamplesPerSec, nAvgBytesPerSec, nBlockAlign, wBitsPerSample, cbSize
  35. { WAVE_FORMAT_MPEGLAYER3, 0, 0, 0, 0, 0, 0 },
  36. { WAVE_FORMAT_MSAUDIO, 2, 32000, 8000, 0, 0, 0 },
  37. { WAVE_FORMAT_MSAUDIO, 2, 44000, 20000, 0, 0, 0 }
  38. };
  39. static const LPCWSTR g_kszMimeTypes[] =
  40. {
  41. L"audio/mpeg",
  42. L"audio/x-ms-wma"
  43. };
  44. /////////////////////////////////////////////////////////////////////////////
  45. // CMDSPDevice
  46. HRESULT CMDSPDevice::InitGlobalDeviceInfo()
  47. {
  48. return SetGlobalDeviceStatus(m_wcsName, 0, FALSE);
  49. }
  50. CMDSPDevice::CMDSPDevice() :
  51. m_fAlreadyCopiedResFiles( FALSE )
  52. {
  53. }
  54. CMDSPDevice::~CMDSPDevice()
  55. {
  56. }
  57. STDMETHODIMP CMDSPDevice::GetName(LPWSTR pwszName, UINT nMaxChars)
  58. {
  59. HRESULT hr = E_FAIL;
  60. CFRg(g_pAppSCServer);
  61. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  62. {
  63. CORg(WMDM_E_NOTCERTIFIED);
  64. }
  65. CARg(pwszName);
  66. CPRg(nMaxChars>wcslen(m_wcsName));
  67. if( m_wcsName[0] )
  68. {
  69. wcscpy(pwszName, L"Lyra ");
  70. wcscat(pwszName, m_wcsName);
  71. hr = S_OK;
  72. }
  73. else
  74. {
  75. hr = WMDM_E_NOTSUPPORTED;
  76. }
  77. Error:
  78. hrLogDWORD("IMDSPDevice::GetName returned 0x%08lx", hr, hr);
  79. return hr;
  80. }
  81. STDMETHODIMP CMDSPDevice::GetManufacturer(LPWSTR pwszName, UINT nMaxChars)
  82. {
  83. HRESULT hr = S_OK;
  84. CFRg(g_pAppSCServer);
  85. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  86. {
  87. CORg(WMDM_E_NOTCERTIFIED);
  88. }
  89. CARg(pwszName);
  90. if(FAILED(UtilGetManufacturer(m_wcsName, &pwszName, nMaxChars)))
  91. {
  92. hr = E_NOTIMPL;
  93. }
  94. Error:
  95. hrLogDWORD("IMDSPDevice::GetManufacturer returned 0x%08lx", hr, hr);
  96. return hr;
  97. }
  98. STDMETHODIMP CMDSPDevice::GetVersion(DWORD * pdwVersion)
  99. {
  100. HRESULT hr;
  101. CFRg(g_pAppSCServer);
  102. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  103. {
  104. CORg(WMDM_E_NOTCERTIFIED);
  105. }
  106. hr = WMDM_E_NOTSUPPORTED;
  107. Error:
  108. hrLogDWORD("IMDSPDevice::GetVersion returned 0x%08lx", hr, hr);
  109. return hr;
  110. }
  111. STDMETHODIMP CMDSPDevice::GetType(DWORD * pdwType)
  112. {
  113. HRESULT hr = S_OK;
  114. WMDMID snTmp;
  115. CFRg(g_pAppSCServer);
  116. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  117. {
  118. CORg(WMDM_E_NOTCERTIFIED);
  119. }
  120. CARg(pdwType);
  121. *pdwType = WMDM_DEVICE_TYPE_STORAGE | WMDM_DEVICE_TYPE_NONSDMI;
  122. snTmp.cbSize = sizeof(WMDMID);
  123. hr = UtilGetSerialNumber(m_wcsName, &snTmp, FALSE);
  124. if( hr == S_OK )
  125. {
  126. *pdwType |= WMDM_DEVICE_TYPE_SDMI;
  127. }
  128. hr=S_OK;
  129. Error:
  130. hrLogDWORD("IMDSPDevice::GetType returned 0x%08lx", hr, hr);
  131. return hr;
  132. }
  133. STDMETHODIMP CMDSPDevice::GetSerialNumber(
  134. PWMDMID pSerialNumber,
  135. BYTE abMac[WMDM_MAC_LENGTH])
  136. {
  137. HRESULT hr;
  138. CFRg(g_pAppSCServer);
  139. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  140. {
  141. CORg(WMDM_E_NOTCERTIFIED);
  142. }
  143. CARg(pSerialNumber);
  144. hr = UtilGetSerialNumber(m_wcsName, pSerialNumber, TRUE);
  145. if( hr == HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED) )
  146. {
  147. hr = WMDM_E_NOTSUPPORTED;
  148. }
  149. if( hr == S_OK )
  150. {
  151. // MAC the parameters
  152. HMAC hMAC;
  153. CORg(g_pAppSCServer->MACInit(&hMAC));
  154. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pSerialNumber), sizeof(WMDMID)));
  155. CORg(g_pAppSCServer->MACFinal(hMAC, abMac));
  156. }
  157. Error:
  158. hrLogDWORD("IMDSPDevice::GetSerialNumber returned 0x%08lx", hr, hr);
  159. return hr;
  160. }
  161. STDMETHODIMP CMDSPDevice::GetPowerSource(DWORD * pdwPowerSource, DWORD * pdwPercentRemaining)
  162. {
  163. HRESULT hr=S_OK;
  164. CFRg(g_pAppSCServer);
  165. if( !(g_pAppSCServer->fIsAuthenticated()) )
  166. {
  167. CORg(WMDM_E_NOTCERTIFIED);
  168. }
  169. CARg(pdwPowerSource);
  170. CARg(pdwPercentRemaining);
  171. *pdwPowerSource = WMDM_POWER_CAP_EXTERNAL |
  172. WMDM_POWER_IS_EXTERNAL |
  173. WMDM_POWER_PERCENT_AVAILABLE;
  174. *pdwPercentRemaining = 100;
  175. Error:
  176. hrLogDWORD("IMDSPDevice::GetPowerSource returned 0x%08lx", hr, hr);
  177. return hr;
  178. }
  179. BOOL IsDriveReady(int nDriveNum)
  180. {
  181. DWORD dwRet=ERROR_SUCCESS;
  182. // Disable drive error popup
  183. UINT uPrevErrMode=SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
  184. char szDL[32]="A:\\D569CFEE41e6A522E8F5.jnk";
  185. szDL[0] += (char)nDriveNum;
  186. HANDLE hFile=CreateFile(
  187. szDL, // file name
  188. 0, // access mode
  189. 0, // share mode
  190. NULL, // SD
  191. OPEN_EXISTING, // how to create
  192. 0, // file attributes
  193. NULL // handle to template file
  194. );
  195. if( hFile == INVALID_HANDLE_VALUE )
  196. {
  197. dwRet=GetLastError();
  198. }
  199. else
  200. {
  201. CloseHandle(hFile); // rare situation when such a file exists.
  202. }
  203. // Restore default system error handling
  204. SetErrorMode(uPrevErrMode);
  205. return (ERROR_FILE_NOT_FOUND==dwRet || ERROR_SUCCESS==dwRet);
  206. }
  207. STDMETHODIMP CMDSPDevice::GetStatus(DWORD * pdwStatus)
  208. {
  209. HRESULT hr = S_OK;
  210. CFRg(g_pAppSCServer);
  211. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  212. {
  213. CORg(WMDM_E_NOTCERTIFIED);
  214. }
  215. CARg(pdwStatus);
  216. CHRg(GetGlobalDeviceStatus(m_wcsName, pdwStatus));
  217. if( !( *pdwStatus & WMDM_STATUS_BUSY) )
  218. {
  219. if( IsDriveReady((m_wcsName[0]>96)?(m_wcsName[0]-L'a'):(m_wcsName[0]-L'A')))
  220. {
  221. *pdwStatus = WMDM_STATUS_READY;
  222. }
  223. else
  224. {
  225. *pdwStatus = WMDM_STATUS_STORAGE_NOTPRESENT;
  226. }
  227. }
  228. hr = S_OK;
  229. Error:
  230. hrLogDWORD("IMDSPDevice::GetStatus returned 0x%08lx", hr, hr);
  231. return hr;
  232. }
  233. STDMETHODIMP CMDSPDevice::GetDeviceIcon(ULONG *hIcon)
  234. {
  235. HRESULT hr = S_OK;
  236. CFRg(g_pAppSCServer);
  237. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  238. {
  239. CORg(WMDM_E_NOTCERTIFIED);
  240. }
  241. CFRg(g_hinstance);
  242. CARg(hIcon);
  243. CWRg( (*hIcon)=HandleToULong(LoadIconA(g_hinstance, MAKEINTRESOURCEA(IDI_ICON_PM)) ));
  244. Error:
  245. hrLogDWORD("IMDSPDevice::GetDeviceIcon returned 0x%08lx", hr, hr);
  246. return hr;
  247. }
  248. STDMETHODIMP CMDSPDevice::SendOpaqueCommand(OPAQUECOMMAND *pCommand)
  249. {
  250. HRESULT hr;
  251. CFRg(g_pAppSCServer);
  252. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  253. {
  254. CORg(WMDM_E_NOTCERTIFIED);
  255. }
  256. hr = WMDM_E_NOTSUPPORTED;
  257. Error:
  258. hrLogDWORD("IMDSPDevice::SendOpaqueCommand returned 0x%08lx", hr, hr);
  259. return hr;
  260. }
  261. // IMDSPDeviceControl
  262. STDMETHODIMP CMDSPDevice::GetDCStatus(/*[out]*/ DWORD *pdwStatus)
  263. {
  264. HRESULT hr = E_FAIL;
  265. CFRg(g_pAppSCServer);
  266. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  267. {
  268. CORg(WMDM_E_NOTCERTIFIED);
  269. }
  270. hr = GetStatus(pdwStatus);
  271. Error:
  272. hrLogDWORD("IMDSPDeviceControl::GetDCStatus returned 0x%08lx", hr, hr);
  273. return hr;
  274. }
  275. STDMETHODIMP CMDSPDevice::GetCapabilities(/*[out]*/ DWORD *pdwCapabilitiesMask)
  276. {
  277. HRESULT hr;
  278. CFRg(g_pAppSCServer);
  279. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  280. {
  281. CORg(WMDM_E_NOTCERTIFIED);
  282. }
  283. if( !pdwCapabilitiesMask )
  284. {
  285. return E_INVALIDARG;
  286. }
  287. *pdwCapabilitiesMask = WMDM_DEVICECAP_CANSTREAMPLAY;
  288. hr = S_OK;
  289. Error:
  290. hrLogDWORD("IMDSPDeviceControl::GetCapabilities returned 0x%08lx", hr, hr);
  291. return S_OK;
  292. }
  293. STDMETHODIMP CMDSPDevice::Play()
  294. {
  295. HRESULT hr;
  296. CFRg(g_pAppSCServer);
  297. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  298. {
  299. CORg(WMDM_E_NOTCERTIFIED);
  300. }
  301. hr = WMDM_E_NOTSUPPORTED;
  302. Error:
  303. hrLogDWORD("IMDSPDeviceControl::Play returned 0x%08lx", hr, hr);
  304. return hr;
  305. }
  306. STDMETHODIMP CMDSPDevice::Record(/*[in]*/ _WAVEFORMATEX *pFormat)
  307. {
  308. HRESULT hr;
  309. CFRg(g_pAppSCServer);
  310. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  311. {
  312. CORg(WMDM_E_NOTCERTIFIED);
  313. }
  314. hr = WMDM_E_NOTSUPPORTED;
  315. Error:
  316. hrLogDWORD("IMDSPDeviceControl::Record returned 0x%08lx", hr, hr);
  317. return hr;
  318. }
  319. STDMETHODIMP CMDSPDevice::Pause()
  320. {
  321. HRESULT hr;
  322. CFRg(g_pAppSCServer);
  323. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  324. {
  325. CORg(WMDM_E_NOTCERTIFIED);
  326. }
  327. hr = WMDM_E_NOTSUPPORTED;
  328. Error:
  329. hrLogDWORD("IMDSPDeviceControl::Pause returned 0x%08lx", hr, hr);
  330. return hr;
  331. }
  332. STDMETHODIMP CMDSPDevice::Resume()
  333. {
  334. HRESULT hr;
  335. CFRg(g_pAppSCServer);
  336. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  337. {
  338. CORg(WMDM_E_NOTCERTIFIED);
  339. }
  340. hr = WMDM_E_NOTSUPPORTED;
  341. Error:
  342. hrLogDWORD("IMDSPDeviceControl::Resume returned 0x%08lx", hr, hr);
  343. return hr;
  344. }
  345. STDMETHODIMP CMDSPDevice::Stop()
  346. {
  347. HRESULT hr;
  348. CFRg(g_pAppSCServer);
  349. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  350. {
  351. CORg(WMDM_E_NOTCERTIFIED);
  352. }
  353. hr = WMDM_E_NOTSUPPORTED;
  354. Error:
  355. hrLogDWORD("IMDSPDeviceControl::Stop returned 0x%08lx", hr, hr);
  356. return hr;
  357. }
  358. STDMETHODIMP CMDSPDevice::Seek(/*[in]*/ UINT fuMode, /*[in]*/ int nOffset)
  359. {
  360. HRESULT hr;
  361. CFRg(g_pAppSCServer);
  362. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  363. {
  364. CORg(WMDM_E_NOTCERTIFIED);
  365. }
  366. hr = WMDM_E_NOTSUPPORTED;
  367. Error:
  368. hrLogDWORD("IMDSPDeviceControl::Seek returned 0x%08lx", hr, hr);
  369. return hr;
  370. }
  371. STDMETHODIMP CMDSPDevice::GetFormatSupport(
  372. _WAVEFORMATEX **pFormatEx,
  373. UINT *pnFormatCount,
  374. LPWSTR **pppwszMimeType,
  375. UINT *pnMimeTypeCount)
  376. {
  377. HRESULT hr = S_OK;
  378. UINT idxMimes = 0;
  379. UINT cMimes = 0;
  380. if( NULL != pnFormatCount )
  381. {
  382. *pnFormatCount = 0;
  383. }
  384. if( NULL != pFormatEx )
  385. {
  386. memset( pFormatEx, 0, sizeof(*pFormatEx) );
  387. }
  388. if( NULL != pppwszMimeType )
  389. {
  390. *pppwszMimeType = NULL;
  391. }
  392. if( NULL != pnMimeTypeCount )
  393. {
  394. *pnMimeTypeCount = 0;
  395. }
  396. if( NULL == pnFormatCount )
  397. {
  398. return( E_INVALIDARG );
  399. }
  400. if( NULL == pFormatEx )
  401. {
  402. return( E_INVALIDARG );
  403. }
  404. if( NULL == pppwszMimeType )
  405. {
  406. return( E_INVALIDARG );
  407. }
  408. if( NULL == pnMimeTypeCount )
  409. {
  410. return( E_INVALIDARG );
  411. }
  412. CFRg(g_pAppSCServer);
  413. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  414. {
  415. CORg(WMDM_E_NOTCERTIFIED);
  416. }
  417. // Prefast flags this as a potential problem, but this is ok. To
  418. // silence Prefast, we've changed it to an equivalent, using the
  419. // fact that g_krgWaveFormats is an aaray of _WAVEFORMATEX.
  420. // *pFormatEx = (_WAVEFORMATEX *)CoTaskMemAlloc(sizeof(_WAVEFORMATEX) * sizeof(g_krgWaveFormats)/sizeof(g_krgWaveFormats[0]));
  421. *pFormatEx = (_WAVEFORMATEX *)CoTaskMemAlloc(sizeof(g_krgWaveFormats));
  422. if( NULL == *pFormatEx )
  423. {
  424. hr = E_OUTOFMEMORY;
  425. }
  426. if( SUCCEEDED( hr ) )
  427. {
  428. *pnFormatCount = sizeof(g_krgWaveFormats)/sizeof(g_krgWaveFormats[0]);
  429. memcpy( *pFormatEx, g_krgWaveFormats, sizeof(g_krgWaveFormats));
  430. }
  431. if( SUCCEEDED( hr ) )
  432. {
  433. cMimes = sizeof(g_kszMimeTypes) /sizeof(g_kszMimeTypes[0]);
  434. *pppwszMimeType = (LPWSTR *)CoTaskMemAlloc( sizeof(LPWSTR) * cMimes );
  435. if( NULL == pppwszMimeType )
  436. {
  437. hr = E_OUTOFMEMORY;
  438. }
  439. else
  440. {
  441. for( idxMimes = 0; idxMimes < cMimes; idxMimes++ )
  442. {
  443. (*pppwszMimeType)[idxMimes] = NULL;
  444. }
  445. }
  446. }
  447. if( SUCCEEDED( hr ) )
  448. {
  449. for( idxMimes = 0; SUCCEEDED( hr ) && idxMimes < cMimes; idxMimes++ )
  450. {
  451. (*pppwszMimeType)[idxMimes] = (LPWSTR)CoTaskMemAlloc(sizeof(WCHAR)*(wcslen(g_kszMimeTypes[idxMimes])+1));
  452. if( NULL == (*pppwszMimeType)[idxMimes] )
  453. {
  454. hr = E_OUTOFMEMORY;
  455. }
  456. else
  457. {
  458. wcscpy( (*pppwszMimeType)[idxMimes], g_kszMimeTypes[idxMimes]);
  459. }
  460. }
  461. }
  462. if( SUCCEEDED( hr ) )
  463. {
  464. *pnMimeTypeCount = cMimes;
  465. }
  466. else
  467. {
  468. if( *pppwszMimeType )
  469. {
  470. for( idxMimes = 0; SUCCEEDED( hr ) && idxMimes < cMimes; idxMimes++ )
  471. {
  472. if( NULL != (*pppwszMimeType)[idxMimes] )
  473. {
  474. CoTaskMemFree( (*pppwszMimeType)[idxMimes] );
  475. }
  476. }
  477. CoTaskMemFree( *pppwszMimeType );
  478. *pppwszMimeType = NULL;
  479. }
  480. if( *pFormatEx )
  481. {
  482. CoTaskMemFree( *pFormatEx );
  483. *pFormatEx = NULL;
  484. }
  485. *pnMimeTypeCount = 0;
  486. *pnFormatCount = 0;
  487. }
  488. Error:
  489. return( hr );
  490. }
  491. STDMETHODIMP CMDSPDevice::EnumStorage(IMDSPEnumStorage * * ppEnumStorage)
  492. {
  493. HRESULT hr;
  494. USES_CONVERSION;
  495. CFRg(g_pAppSCServer);
  496. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  497. {
  498. CORg(WMDM_E_NOTCERTIFIED);
  499. }
  500. CARg(ppEnumStorage);
  501. CComObject<CMDSPEnumStorage> *pEnumObj;
  502. CORg(CComObject<CMDSPEnumStorage>::CreateInstance(&pEnumObj));
  503. hr = pEnumObj->QueryInterface(
  504. IID_IMDSPEnumStorage,
  505. reinterpret_cast<void**>(ppEnumStorage)
  506. );
  507. if( SUCCEEDED( hr ) &&
  508. !m_fAlreadyCopiedResFiles )
  509. {
  510. CHAR szDestPath[MAX_PATH];
  511. _snprintf( szDestPath, sizeof(szDestPath)/sizeof(szDestPath[0]), "%S%s", m_wcsName, "PMP" );
  512. hr = CopyFileResToDirectory( _Module.GetResourceInstance(), szDestPath );
  513. m_fAlreadyCopiedResFiles = SUCCEEDED(hr);
  514. }
  515. if( SUCCEEDED( hr ) )
  516. {
  517. wcscpy(pEnumObj->m_wcsPath, m_wcsName);
  518. }
  519. else
  520. {
  521. delete pEnumObj;
  522. *ppEnumStorage = NULL;
  523. }
  524. Error:
  525. hrLogDWORD("IMDSPDevice::EnumStorage returned 0x%08lx", hr, hr);
  526. return hr;
  527. }