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.

563 lines
12 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
  4. //
  5. // This workspace contains two projects -
  6. // 1. ProgHelp which implements the Progress Interface
  7. // 2. The Sample application WmdmApp.
  8. //
  9. // ProgHelp.dll needs to be registered first for the SampleApp to run.
  10. //
  11. // ItemData.cpp: implementation of the CItemData class
  12. //
  13. // Includes
  14. //
  15. #include "appPCH.h"
  16. #include "SCClient.h"
  17. // Opaque Command to get extended certification information
  18. //
  19. // GUID = {C39BF696-B776-459c-A13A-4B7116AB9F09}
  20. //
  21. static const GUID guidCertInfoEx =
  22. { 0xc39bf696, 0xb776, 0x459c, { 0xa1, 0x3a, 0x4b, 0x71, 0x16, 0xab, 0x9f, 0x9 } };
  23. typedef struct
  24. {
  25. HRESULT hr;
  26. DWORD cbCert;
  27. BYTE pbCert[1];
  28. } CERTINFOEX;
  29. static const BYTE bCertInfoEx_App[] =
  30. { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 };
  31. static const BYTE bCertInfoEx_SP[] =
  32. { 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,
  33. 0x09, 0x08, 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00 };
  34. //
  35. // Construction/Destruction
  36. //
  37. CItemData::CItemData()
  38. {
  39. m_fIsDevice = TRUE;
  40. // Shared device/storage members
  41. //
  42. m_pStorageGlobals = NULL;
  43. m_pEnumStorage = NULL;
  44. m_szName[0] = 0;
  45. // Device-only members
  46. //
  47. m_pDevice = NULL;
  48. m_pRootStorage = NULL;
  49. m_dwType = 0;
  50. FillMemory( (void *)&m_SerialNumber, sizeof(m_SerialNumber), 0 );
  51. m_szMfr[0] = 0;
  52. m_dwVersion = 0;
  53. m_dwPowerSource = 0;
  54. m_dwPercentRemaining = 0;
  55. m_hIcon = NULL;
  56. m_dwMemSizeKB = 0;
  57. m_dwMemBadKB = 0;
  58. m_dwMemFreeKB = 0;
  59. m_fExtraCertified = FALSE;
  60. // Storage-only members
  61. //
  62. m_pStorage = NULL;
  63. m_dwAttributes = 0;
  64. FillMemory( (void *)&m_Format, sizeof(m_Format), 0 );
  65. FillMemory( (void *)&m_DateTime, sizeof(m_DateTime), 0 );
  66. m_dwSizeLow = 0;
  67. m_dwSizeHigh = 0;
  68. }
  69. CItemData::~CItemData()
  70. {
  71. if( m_hIcon )
  72. {
  73. DestroyIcon( m_hIcon );
  74. m_hIcon = NULL;
  75. }
  76. SafeRelease( m_pStorageGlobals );
  77. SafeRelease( m_pEnumStorage );
  78. SafeRelease( m_pRootStorage );
  79. SafeRelease( m_pStorage );
  80. SafeRelease( m_pDevice );
  81. }
  82. //////////////////////////////////////////////////////////////////////
  83. //
  84. // Class methods
  85. //
  86. //////////////////////////////////////////////////////////////////////
  87. HRESULT CItemData::Init( IWMDMDevice *pDevice )
  88. {
  89. HRESULT hr;
  90. WCHAR wsz[MAX_PATH];
  91. ULONG ulFetched;
  92. // This is a device object
  93. //
  94. m_fIsDevice = TRUE;
  95. //
  96. // Shared device/storage members
  97. //
  98. // Get the RootStorage, SotrageGlobals, and EnumStorage interfaces
  99. //
  100. m_pRootStorage = NULL;
  101. m_pEnumStorage = NULL;
  102. m_pStorageGlobals = NULL;
  103. {
  104. IWMDMEnumStorage *pEnumRootStorage;
  105. hr = pDevice->EnumStorage( &pEnumRootStorage );
  106. ExitOnFalse( SUCCEEDED( hr ) && pEnumRootStorage );
  107. hr = pEnumRootStorage->Next( 1, &m_pRootStorage, &ulFetched );
  108. ExitOnFalse( SUCCEEDED( hr ) && m_pRootStorage );
  109. hr = m_pRootStorage->GetStorageGlobals( &m_pStorageGlobals );
  110. ExitOnFalse( SUCCEEDED( hr ) && m_pStorageGlobals );
  111. hr = m_pRootStorage->EnumStorage( &m_pEnumStorage );
  112. ExitOnFalse( SUCCEEDED( hr ) && m_pEnumStorage );
  113. pEnumRootStorage->Release();
  114. }
  115. // Get device name
  116. //
  117. hr = pDevice->GetName( wsz, sizeof(wsz)/sizeof(WCHAR) - 1 );
  118. if( FAILED(hr) )
  119. {
  120. lstrcpy( m_szName, "" );
  121. }
  122. else
  123. {
  124. WideCharToMultiByte(
  125. CP_ACP, 0L,
  126. wsz, -1,
  127. m_szName, sizeof(m_szName),
  128. NULL, NULL
  129. );
  130. }
  131. //
  132. // Device-only members
  133. //
  134. // Set the device pointer and addref it
  135. //
  136. m_pDevice = pDevice;
  137. m_pDevice->AddRef();
  138. // Get device type
  139. //
  140. hr = pDevice->GetType( &m_dwType );
  141. if( FAILED(hr) )
  142. {
  143. m_dwType = 0L;
  144. }
  145. /// Get device serial number
  146. //
  147. BYTE abMAC[SAC_MAC_LEN];
  148. BYTE abMACVerify[SAC_MAC_LEN];
  149. HMAC hMACVerify;
  150. hr = pDevice->GetSerialNumber( &m_SerialNumber, (BYTE*)abMAC );
  151. if( SUCCEEDED(hr) )
  152. {
  153. g_cWmdm.m_pSAC->MACInit(&hMACVerify);
  154. g_cWmdm.m_pSAC->MACUpdate(hMACVerify, (BYTE*)(&m_SerialNumber), sizeof(m_SerialNumber));
  155. g_cWmdm.m_pSAC->MACFinal(hMACVerify, (BYTE*)abMACVerify);
  156. if( memcmp(abMACVerify, abMAC, sizeof(abMAC)) != 0 )
  157. {
  158. hr = E_FAIL;
  159. }
  160. }
  161. if( FAILED(hr) )
  162. {
  163. FillMemory( (void *)&m_SerialNumber, sizeof(m_SerialNumber), 0 );
  164. }
  165. // Get device manufacturer
  166. //
  167. hr = pDevice->GetManufacturer( wsz, sizeof(wsz)/sizeof(WCHAR) - 1 );
  168. if( FAILED(hr) )
  169. {
  170. lstrcpy( m_szMfr, "" );
  171. }
  172. else
  173. {
  174. WideCharToMultiByte(
  175. CP_ACP, 0L,
  176. wsz, -1,
  177. m_szMfr, sizeof(m_szMfr),
  178. NULL, NULL
  179. );
  180. }
  181. // Get device version
  182. //
  183. hr = pDevice->GetVersion( &m_dwVersion );
  184. if( FAILED(hr) )
  185. {
  186. m_dwVersion = (DWORD)-1;
  187. }
  188. // Get power source and power remaining
  189. //
  190. hr = pDevice->GetPowerSource( &m_dwPowerSource, &m_dwPercentRemaining );
  191. if( FAILED(hr) )
  192. {
  193. m_dwPowerSource = 0;
  194. m_dwPercentRemaining = 0;
  195. }
  196. // Get device icon
  197. //
  198. hr = pDevice->GetDeviceIcon( (ULONG *)&m_hIcon );
  199. if( FAILED(hr) )
  200. {
  201. m_hIcon = NULL;
  202. }
  203. // Get the total, free, and bad space on the storage
  204. //
  205. {
  206. DWORD dwLow;
  207. DWORD dwHigh;
  208. m_dwMemSizeKB = 0;
  209. hr = m_pStorageGlobals->GetTotalSize( &dwLow, &dwHigh );
  210. if( SUCCEEDED(hr) )
  211. {
  212. INT64 nSize = ( (INT64)dwHigh << 32 | (INT64)dwLow ) >> 10;
  213. m_dwMemSizeKB = (DWORD)nSize;
  214. }
  215. m_dwMemBadKB = 0;
  216. hr = m_pStorageGlobals->GetTotalBad( &dwLow, &dwHigh );
  217. if( SUCCEEDED(hr) )
  218. {
  219. INT64 nSize = ( (INT64)dwHigh << 32 | (INT64)dwLow ) >> 10;
  220. m_dwMemBadKB = (DWORD)nSize;
  221. }
  222. m_dwMemFreeKB = 0;
  223. hr = m_pStorageGlobals->GetTotalFree( &dwLow, &dwHigh );
  224. if( SUCCEEDED(hr) )
  225. {
  226. INT64 nSize = ( (INT64)dwHigh << 32 | (INT64)dwLow ) >> 10;
  227. m_dwMemFreeKB = (DWORD)nSize;
  228. }
  229. }
  230. // Call opaque command to exchange extended authentication info
  231. //
  232. {
  233. HMAC hMAC;
  234. OPAQUECOMMAND Command;
  235. CERTINFOEX *pCertInfoEx;
  236. DWORD cbData_App = sizeof( bCertInfoEx_App )/sizeof( bCertInfoEx_App[0] );
  237. DWORD cbData_SP = sizeof( bCertInfoEx_SP )/sizeof( bCertInfoEx_SP[0] );
  238. DWORD cbData_Send = sizeof( CERTINFOEX ) + cbData_App;
  239. // Fill out opaque command structure
  240. //
  241. memcpy( &(Command.guidCommand), &guidCertInfoEx, sizeof(GUID) );
  242. Command.pData = (BYTE *)CoTaskMemAlloc( cbData_Send );
  243. if( !Command.pData )
  244. {
  245. ExitOnFail( hr = E_OUTOFMEMORY );
  246. }
  247. Command.dwDataLen = cbData_Send;
  248. // Map the data in the opaque command to a CERTINFOEX structure, and
  249. // fill in the cert info to send
  250. //
  251. pCertInfoEx = (CERTINFOEX *)Command.pData;
  252. pCertInfoEx->hr = S_OK;
  253. pCertInfoEx->cbCert = cbData_App;
  254. memcpy( pCertInfoEx->pbCert, bCertInfoEx_App, cbData_App );
  255. // Compute MAC
  256. //
  257. g_cWmdm.m_pSAC->MACInit( &hMAC );
  258. g_cWmdm.m_pSAC->MACUpdate( hMAC, (BYTE*)(&(Command.guidCommand)), sizeof(GUID) );
  259. g_cWmdm.m_pSAC->MACUpdate( hMAC, (BYTE*)(&(Command.dwDataLen)), sizeof(Command.dwDataLen) );
  260. if( Command.pData )
  261. {
  262. g_cWmdm.m_pSAC->MACUpdate( hMAC, Command.pData, Command.dwDataLen );
  263. }
  264. g_cWmdm.m_pSAC->MACFinal( hMAC, Command.abMAC );
  265. // Send the command
  266. //
  267. hr = pDevice->SendOpaqueCommand( &Command );
  268. if( SUCCEEDED(hr) )
  269. {
  270. BYTE abMACVerify2[ WMDM_MAC_LENGTH ];
  271. // Compute MAC
  272. //
  273. g_cWmdm.m_pSAC->MACInit( &hMAC );
  274. g_cWmdm.m_pSAC->MACUpdate( hMAC, (BYTE*)(&(Command.guidCommand)), sizeof(GUID) );
  275. g_cWmdm.m_pSAC->MACUpdate( hMAC, (BYTE*)(&(Command.dwDataLen)), sizeof(Command.dwDataLen) );
  276. if( Command.pData )
  277. {
  278. g_cWmdm.m_pSAC->MACUpdate( hMAC, Command.pData, Command.dwDataLen );
  279. }
  280. g_cWmdm.m_pSAC->MACFinal( hMAC, abMACVerify2 );
  281. // Verify MAC matches
  282. //
  283. if( memcmp(abMACVerify2, Command.abMAC, WMDM_MAC_LENGTH) == 0 )
  284. {
  285. // Map the data in the opaque command to a CERTINFOEX structure
  286. //
  287. pCertInfoEx = (CERTINFOEX *)Command.pData;
  288. // In this simple extended authentication scheme, the callee must
  289. // provide the exact cert info
  290. //
  291. if( (pCertInfoEx->cbCert != cbData_SP) ||
  292. (memcmp(pCertInfoEx->pbCert, bCertInfoEx_SP, cbData_SP) == 0) )
  293. {
  294. m_fExtraCertified = TRUE;
  295. }
  296. }
  297. }
  298. if( Command.pData )
  299. {
  300. CoTaskMemFree( Command.pData );
  301. }
  302. }
  303. //
  304. // Storage-only members (pointers/handles only)
  305. //
  306. m_pStorage = NULL;
  307. //
  308. // Successful init
  309. //
  310. hr = S_OK;
  311. lExit:
  312. return hr;
  313. }
  314. HRESULT CItemData::Init( IWMDMStorage *pStorage )
  315. {
  316. HRESULT hr;
  317. WCHAR wsz[MAX_PATH];
  318. // This is a storage object
  319. //
  320. m_fIsDevice = FALSE;
  321. //
  322. // Shared device/storage members
  323. //
  324. // Get a pointer to the StorageGlobals interface
  325. //
  326. hr = pStorage->GetStorageGlobals( &m_pStorageGlobals );
  327. ExitOnFail( hr );
  328. // Get the storage attributes
  329. //
  330. hr = pStorage->GetAttributes( &m_dwAttributes, &m_Format );
  331. if( FAILED(hr) )
  332. {
  333. m_dwAttributes = 0;
  334. }
  335. // Get a pointer to the EnumStorage interface
  336. //
  337. if( m_dwAttributes & WMDM_FILE_ATTR_FOLDER )
  338. {
  339. hr = pStorage->EnumStorage( &m_pEnumStorage );
  340. ExitOnFail( hr );
  341. }
  342. else
  343. {
  344. m_pEnumStorage = NULL;
  345. }
  346. // Get the storage name
  347. //
  348. hr = pStorage->GetName( wsz, sizeof(wsz)/sizeof(WCHAR) - 1 );
  349. if( FAILED(hr) )
  350. {
  351. lstrcpy( m_szName, "" );
  352. }
  353. else
  354. {
  355. WideCharToMultiByte(
  356. CP_ACP, 0L,
  357. wsz, -1,
  358. m_szName, sizeof(m_szName),
  359. NULL, NULL
  360. );
  361. }
  362. /// Get storage serial number
  363. //
  364. BYTE abMAC[SAC_MAC_LEN];
  365. BYTE abMACVerify[SAC_MAC_LEN];
  366. HMAC hMAC;
  367. hr = m_pStorageGlobals->GetSerialNumber( &m_SerialNumber, (BYTE*)abMAC );
  368. if( SUCCEEDED(hr) )
  369. {
  370. g_cWmdm.m_pSAC->MACInit(&hMAC);
  371. g_cWmdm.m_pSAC->MACUpdate(hMAC, (BYTE*)(&m_SerialNumber), sizeof(m_SerialNumber));
  372. g_cWmdm.m_pSAC->MACFinal(hMAC, (BYTE*)abMACVerify);
  373. if( memcmp(abMACVerify, abMAC, sizeof(abMAC)) != 0 )
  374. {
  375. hr = E_FAIL;
  376. }
  377. }
  378. if( FAILED(hr) )
  379. {
  380. FillMemory( (void *)&m_SerialNumber, sizeof(m_SerialNumber), 0 );
  381. }
  382. //
  383. // Device-only members (pointers/handles only)
  384. //
  385. m_pDevice = NULL;
  386. m_pRootStorage = NULL;
  387. m_hIcon = NULL;
  388. m_fExtraCertified = FALSE;
  389. //
  390. // Storage-only members
  391. //
  392. // Save the WMDM storage pointer
  393. //
  394. m_pStorage = pStorage;
  395. m_pStorage->AddRef();
  396. // Get the storage date
  397. //
  398. hr = pStorage->GetDate( &m_DateTime );
  399. if( FAILED(hr) )
  400. {
  401. FillMemory( (void *)&m_DateTime, sizeof(m_DateTime), 0 );
  402. }
  403. // If the stoarge is a file, get its size
  404. // If the storage is a folder, set the size to zero
  405. //
  406. m_dwSizeLow = 0;
  407. m_dwSizeHigh = 0;
  408. if( !(m_dwAttributes & WMDM_FILE_ATTR_FOLDER) )
  409. {
  410. hr = pStorage->GetSize( &m_dwSizeLow, &m_dwSizeHigh );
  411. }
  412. //
  413. // Successful init
  414. //
  415. hr = S_OK;
  416. lExit:
  417. return hr;
  418. }
  419. HRESULT CItemData::Refresh( void )
  420. {
  421. HRESULT hr;
  422. // Only valid for a device
  423. //
  424. if( !m_fIsDevice )
  425. {
  426. ExitOnFail( hr = E_UNEXPECTED );
  427. }
  428. // Get power source and power remaining
  429. //
  430. hr = m_pDevice->GetPowerSource( &m_dwPowerSource, &m_dwPercentRemaining );
  431. if( FAILED(hr) )
  432. {
  433. m_dwPowerSource = 0;
  434. m_dwPercentRemaining = 0;
  435. }
  436. // Get the total, free, and bad space on the storage
  437. //
  438. {
  439. DWORD dwLow;
  440. DWORD dwHigh;
  441. m_dwMemSizeKB = 0;
  442. hr = m_pStorageGlobals->GetTotalSize( &dwLow, &dwHigh );
  443. if( SUCCEEDED(hr) )
  444. {
  445. INT64 nSize = ( (INT64)dwHigh << 32 | (INT64)dwLow ) >> 10;
  446. m_dwMemSizeKB = (DWORD)nSize;
  447. }
  448. m_dwMemBadKB = 0;
  449. hr = m_pStorageGlobals->GetTotalBad( &dwLow, &dwHigh );
  450. if( SUCCEEDED(hr) )
  451. {
  452. INT64 nSize = ( (INT64)dwHigh << 32 | (INT64)dwLow ) >> 10;
  453. m_dwMemBadKB = (DWORD)nSize;
  454. }
  455. m_dwMemFreeKB = 0;
  456. hr = m_pStorageGlobals->GetTotalFree( &dwLow, &dwHigh );
  457. if( SUCCEEDED(hr) )
  458. {
  459. INT64 nSize = ( (INT64)dwHigh << 32 | (INT64)dwLow ) >> 10;
  460. m_dwMemFreeKB = (DWORD)nSize;
  461. }
  462. }
  463. hr = S_OK;
  464. lExit:
  465. return hr;
  466. }