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.

1135 lines
28 KiB

  1. #include "stdafx.h"
  2. #include "enumStorage.h"
  3. #include "storageglobals.h"
  4. #include "command.h"
  5. //#include "findleak.h"
  6. //DECLARE_THIS_FILE;
  7. //
  8. // Construction/Destruction
  9. //
  10. CStorage::CStorage()
  11. {
  12. memset( &m_findData, 0, sizeof(m_findData) );
  13. memset( m_szStartPath, 0, sizeof(m_szStartPath) );
  14. memset( m_szCompletePath, 0, sizeof(m_szCompletePath) );
  15. m_hFile = INVALID_HANDLE_VALUE;
  16. m_fRoot = FALSE;
  17. }
  18. HRESULT CStorage::Init( CE_FIND_DATA *pData, LPCWSTR szStartPath, BOOL fIsDeviceStorage, IMDSPDevice *pDevice )
  19. {
  20. HRESULT hr = S_OK;
  21. if( NULL == pData ||
  22. NULL == pDevice ||
  23. NULL == szStartPath )
  24. {
  25. return( E_INVALIDARG );
  26. }
  27. memcpy( &m_findData, pData, sizeof(m_findData) );
  28. if( L'\\' != szStartPath[0] )
  29. {
  30. wcscpy( m_szStartPath, L"\\" );
  31. hr = StringCbCatW(m_szStartPath, sizeof(m_szStartPath), szStartPath);
  32. }
  33. else
  34. {
  35. hr = StringCbCopyW(m_szStartPath, sizeof(m_szStartPath), szStartPath);
  36. }
  37. if (SUCCEEDED (hr))
  38. {
  39. if( !fIsDeviceStorage )
  40. {
  41. if( 0 == _wcsicmp(L"\\", m_szStartPath) )
  42. {
  43. hr = StringCbPrintfW(m_szCompletePath, sizeof(m_szCompletePath), L"%s%s", m_szStartPath, m_findData.cFileName );
  44. }
  45. else
  46. {
  47. hr = StringCbPrintfW(m_szCompletePath, sizeof(m_szCompletePath), L"%s\\%s", m_szStartPath, m_findData.cFileName );
  48. }
  49. }
  50. else
  51. {
  52. hr = StringCbCopyW(m_szCompletePath, sizeof(m_szCompletePath), m_szStartPath);
  53. }
  54. }
  55. if (SUCCEEDED (hr))
  56. {
  57. m_fRoot = ( 0 == _wcsicmp(L"\\", m_szCompletePath) );
  58. m_spDevice = pDevice;
  59. }
  60. return( HRESULT_FROM_WIN32(HRESULT_CODE(hr)) );
  61. }
  62. void CStorage::FinalRelease()
  63. {
  64. if( INVALID_HANDLE_VALUE != m_hFile )
  65. {
  66. CeCloseHandle( m_hFile );
  67. m_hFile = INVALID_HANDLE_VALUE;
  68. }
  69. }
  70. //
  71. // IMDSPStorage
  72. //
  73. STDMETHODIMP CStorage::GetStorageGlobals( IMDSPStorageGlobals **ppStorageGlobals )
  74. {
  75. if( NULL == ppStorageGlobals )
  76. {
  77. return( E_POINTER );
  78. }
  79. *ppStorageGlobals = NULL;
  80. CComStorageGlobals *pStorageGlobals = NULL;
  81. HRESULT hr = CComStorageGlobals::CreateInstance( &pStorageGlobals );
  82. CComPtr<IMDSPStorageGlobals> spStorageGlobals = pStorageGlobals;
  83. if( SUCCEEDED( hr ) )
  84. {
  85. hr = pStorageGlobals->Init(m_szCompletePath, m_spDevice );
  86. }
  87. if( SUCCEEDED( hr ) )
  88. {
  89. *ppStorageGlobals = spStorageGlobals;
  90. spStorageGlobals.Detach();
  91. }
  92. return( hr );
  93. }
  94. STDMETHODIMP CStorage::SetAttributes( DWORD dwAttributes, _WAVEFORMATEX *pFormat )
  95. {
  96. HRESULT hr = S_OK;
  97. if( ( dwAttributes & WMDM_FILE_ATTR_CANRENAME ) ||
  98. ( dwAttributes & WMDM_FILE_ATTR_CANMOVE ) ||
  99. ( dwAttributes & WMDM_FILE_ATTR_CANDELETE ) )
  100. {
  101. m_findData.dwFileAttributes &= (~FILE_ATTRIBUTE_READONLY);
  102. }
  103. else
  104. {
  105. m_findData.dwFileAttributes |= (~FILE_ATTRIBUTE_READONLY);
  106. }
  107. if( ! CeSetFileAttributes( m_szCompletePath, m_findData.dwFileAttributes ) )
  108. {
  109. hr = CeGetLastError();
  110. if( SUCCEEDED( hr ) )
  111. {
  112. hr = CeRapiGetError();
  113. }
  114. }
  115. return( hr );
  116. }
  117. STDMETHODIMP CStorage::GetAttributes( DWORD *pdwAttributes, _WAVEFORMATEX *pFormat )
  118. {
  119. if( NULL != pdwAttributes )
  120. {
  121. *pdwAttributes = 0;
  122. }
  123. if( NULL != pFormat )
  124. {
  125. memset( pFormat, 0, sizeof(*pFormat) );
  126. }
  127. if( NULL == pdwAttributes )
  128. {
  129. return( E_INVALIDARG );
  130. }
  131. if( m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  132. {
  133. if( m_fRoot ) // Check for root file system on device
  134. {
  135. *pdwAttributes |= ( WMDM_STORAGE_ATTR_FILESYSTEM | WMDM_STORAGE_ATTR_NONREMOVABLE );
  136. }
  137. // Mark Storage Card as removable!
  138. if( !m_fRoot &&
  139. ( m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) &&
  140. ( m_findData.dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY ) )
  141. {
  142. *pdwAttributes |= WMDM_STORAGE_ATTR_REMOVABLE;
  143. }
  144. *pdwAttributes |= ( WMDM_FILE_ATTR_FOLDER | WMDM_STORAGE_ATTR_FOLDERS );
  145. }
  146. else
  147. {
  148. *pdwAttributes |= ( WMDM_FILE_ATTR_FILE | WMDM_FILE_ATTR_CANREAD | WMDM_FILE_ATTR_CANPLAY );
  149. }
  150. if( ! ( m_findData.dwFileAttributes & ( FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_INROM ) ) )
  151. {
  152. *pdwAttributes |= ( WMDM_FILE_ATTR_CANRENAME | WMDM_FILE_ATTR_CANDELETE | WMDM_FILE_ATTR_CANMOVE );
  153. }
  154. if( m_findData.dwFileAttributes & FILE_ATTRIBUTE_HAS_CHILDREN )
  155. {
  156. *pdwAttributes |= WMDM_STORAGE_ATTR_HAS_FOLDERS;
  157. }
  158. return( S_OK );
  159. }
  160. STDMETHODIMP CStorage::GetName( LPWSTR pwszName, UINT nMaxChars )
  161. {
  162. if( 0 == nMaxChars )
  163. {
  164. return( E_INVALIDARG );
  165. }
  166. if( NULL != pwszName )
  167. {
  168. memset( pwszName, 0, sizeof(WCHAR)*nMaxChars );
  169. }
  170. else
  171. {
  172. return( E_INVALIDARG );
  173. }
  174. wcsncpy(pwszName, m_findData.cFileName, nMaxChars - 1);
  175. return( S_OK );
  176. }
  177. STDMETHODIMP CStorage::GetDate( PWMDMDATETIME pDateTimeUTC )
  178. {
  179. SYSTEMTIME sysTime;
  180. HRESULT hr = S_OK;
  181. if( NULL != pDateTimeUTC )
  182. {
  183. memset( pDateTimeUTC, 0, sizeof(*pDateTimeUTC) );
  184. }
  185. else
  186. {
  187. return( E_INVALIDARG );
  188. }
  189. if( !FileTimeToSystemTime( &m_findData.ftLastWriteTime, &sysTime) )
  190. {
  191. hr = HRESULT_FROM_WIN32( GetLastError() );
  192. }
  193. if( SUCCEEDED( hr ) )
  194. {
  195. pDateTimeUTC->wYear = sysTime.wYear;
  196. pDateTimeUTC->wMonth = sysTime.wMonth;
  197. pDateTimeUTC->wDay = sysTime.wDay;
  198. pDateTimeUTC->wHour = sysTime.wHour;
  199. pDateTimeUTC->wMinute = sysTime.wMinute;
  200. pDateTimeUTC->wSecond = sysTime.wSecond;
  201. }
  202. return( hr );
  203. }
  204. STDMETHODIMP CStorage::GetSize( DWORD *pdwSizeLow, DWORD *pdwSizeHigh )
  205. {
  206. if( NULL != *pdwSizeLow )
  207. {
  208. *pdwSizeLow = 0;
  209. }
  210. if( NULL != *pdwSizeHigh )
  211. {
  212. *pdwSizeHigh = 0;
  213. }
  214. if( NULL == pdwSizeLow )
  215. {
  216. return( E_INVALIDARG );
  217. }
  218. else
  219. {
  220. *pdwSizeLow = m_findData.nFileSizeLow;
  221. }
  222. if( NULL != pdwSizeHigh )
  223. {
  224. *pdwSizeHigh = m_findData.nFileSizeHigh;
  225. }
  226. return( S_OK );
  227. }
  228. STDMETHODIMP CStorage::GetRights( PWMDMRIGHTS *ppRights, UINT *pnRightsCount, BYTE abMac[ 20 ] )
  229. {
  230. return( WMDM_E_NOTSUPPORTED );
  231. }
  232. STDMETHODIMP CStorage::CreateStorage( DWORD dwAttributes, _WAVEFORMATEX *pFormat, LPWSTR pwszName, IMDSPStorage **ppNewStorage )
  233. {
  234. HRESULT hr = S_OK;
  235. CComStorage *pNewStorage = NULL;
  236. CComPtr<IMDSPStorage> spStorage;
  237. CE_FIND_DATA findData;
  238. memset( &findData, 0, sizeof(findData) );
  239. if( NULL != ppNewStorage )
  240. {
  241. *ppNewStorage = NULL;
  242. }
  243. if( NULL == pwszName || NULL == ppNewStorage )
  244. {
  245. return( E_INVALIDARG );
  246. }
  247. WCHAR wszPath[2*MAX_PATH];
  248. memset( wszPath, 0, sizeof(wszPath) );
  249. if( m_fRoot )
  250. {
  251. _snwprintf( wszPath, sizeof(wszPath)/sizeof(wszPath[0]) - 1, L"%s%s", m_szCompletePath, pwszName );
  252. }
  253. else
  254. {
  255. _snwprintf( wszPath, sizeof(wszPath)/sizeof(wszPath[0]) - 1, L"%s\\%s", m_szCompletePath, pwszName );
  256. }
  257. if( dwAttributes & WMDM_FILE_ATTR_FOLDER )
  258. {
  259. if( !CeCreateDirectory( wszPath, NULL) )
  260. {
  261. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  262. if( SUCCEEDED( hr ) )
  263. {
  264. hr = CeRapiGetError();
  265. }
  266. }
  267. }
  268. else if ( dwAttributes & WMDM_FILE_ATTR_FILE )
  269. {
  270. HANDLE hFile = CeCreateFile( wszPath,
  271. GENERIC_READ | GENERIC_WRITE, 0, NULL,
  272. ( ( dwAttributes & WMDM_FILE_CREATE_OVERWRITE ) ? CREATE_ALWAYS : CREATE_NEW ),
  273. FILE_ATTRIBUTE_NORMAL, NULL );
  274. if( INVALID_HANDLE_VALUE == hFile )
  275. {
  276. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  277. if( SUCCEEDED( hr ) )
  278. {
  279. hr = CeRapiGetError();
  280. }
  281. }
  282. else
  283. {
  284. CeCloseHandle( hFile );
  285. hFile = INVALID_HANDLE_VALUE;
  286. }
  287. }
  288. else
  289. {
  290. hr = E_INVALIDARG;
  291. }
  292. if( SUCCEEDED( hr ) )
  293. {
  294. HANDLE hFind = CeFindFirstFile( wszPath, &findData );
  295. if( INVALID_HANDLE_VALUE == hFind )
  296. {
  297. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  298. if( SUCCEEDED( hr ) )
  299. {
  300. hr = CeRapiGetError();
  301. }
  302. }
  303. else
  304. {
  305. //
  306. // BUG BUG: In certain cases, I have seend the API succeed but the find data
  307. // remains unintialized!
  308. //
  309. _ASSERTE( findData.cFileName[0] != L'\0' && "CE API failed and indicated success" );
  310. CeFindClose( hFind );
  311. }
  312. }
  313. if( SUCCEEDED( hr ) )
  314. {
  315. hr = CComStorage::CreateInstance(&pNewStorage);
  316. spStorage = pNewStorage;
  317. }
  318. if( SUCCEEDED( hr ) )
  319. {
  320. hr = pNewStorage->Init( &findData, m_szCompletePath, FALSE, m_spDevice );
  321. }
  322. if( SUCCEEDED( hr ) )
  323. {
  324. *ppNewStorage = spStorage;
  325. spStorage.Detach();
  326. }
  327. return( hr );
  328. }
  329. STDMETHODIMP CStorage::EnumStorage( IMDSPEnumStorage * *ppEnumStorage )
  330. {
  331. HRESULT hr = S_OK;
  332. if( NULL == ppEnumStorage )
  333. {
  334. return( E_INVALIDARG );
  335. }
  336. *ppEnumStorage = NULL;
  337. if( ! ( m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
  338. {
  339. return( E_FAIL );
  340. }
  341. CComEnumStorage *pEnumStorage = NULL;
  342. CComPtr<IMDSPEnumStorage> spEnum;
  343. hr = CComEnumStorage::CreateInstance( &pEnumStorage );
  344. spEnum = pEnumStorage;
  345. if( SUCCEEDED( hr ) )
  346. {
  347. hr = pEnumStorage->Init( m_szCompletePath, FALSE, m_spDevice );
  348. }
  349. if( SUCCEEDED( hr ) )
  350. {
  351. *ppEnumStorage = spEnum;
  352. spEnum.Detach();
  353. }
  354. return( hr );
  355. }
  356. //Recieves a command and sends it directly into the WMDM interface on the CE Device for processing there
  357. //Right now, only RapierPlaycommand is a defined command
  358. STDMETHODIMP CStorage::SendOpaqueCommand( OPAQUECOMMAND *pCommand )
  359. {
  360. PROCESS_INFORMATION pi;
  361. HRESULT hr = S_OK;
  362. LPWSTR pszTargetjdw;
  363. WCHAR* keyname = L"Default";
  364. WCHAR* pszDirectorydjr;
  365. long lRes;
  366. HKEY hKey;
  367. const DWORD cdwGetAttribFail = 4294967295;
  368. DWORD dwValType;
  369. DWORD dwValSizeljc;
  370. bool foundpath = false;
  371. if( NULL == pCommand )
  372. {
  373. return( E_INVALIDARG );
  374. }
  375. //only play is a defined SDK command
  376. if( !IsEqualGUID( pCommand->guidCommand, __uuidof(RapierPlayCommand) ) )
  377. {
  378. return( E_NOTIMPL);
  379. }
  380. //
  381. //Now we have to attempt to find Media Player-- no easy task since various CE devices place it in different places
  382. //by default and there is no installation directory key placed into the CE registry
  383. //
  384. //
  385. //Attempt 1: Look up the exe that's registered to .wma files (via their icon)
  386. //
  387. lRes = CeRegOpenKeyEx(HKEY_CLASSES_ROOT,
  388. L"wmafile\\DefaultIcon",
  389. 0,
  390. KEY_ALL_ACCESS,
  391. & hKey);
  392. //
  393. //After each call, see if it succeeded (lRes == 0 == SUCCESS) and only then continue on with the registry searching.
  394. //
  395. if (!lRes)
  396. {
  397. //determine size of directory
  398. lRes = CeRegQueryValueEx(hKey,
  399. keyname,
  400. 0,
  401. NULL,
  402. NULL,
  403. &dwValSizeljc);
  404. if (!lRes)
  405. {
  406. //allocate enough space in our character array to hold the directory
  407. pszDirectorydjr = new WCHAR[dwValSizeljc];
  408. if (!pszDirectorydjr)
  409. return E_OUTOFMEMORY;
  410. //actually retrieve the path
  411. lRes = CeRegQueryValueEx (hKey,
  412. keyname,
  413. 0,
  414. &dwValType,
  415. ( (UCHAR *) pszDirectorydjr),
  416. &dwValSizeljc);
  417. //make sure it succeeded and that the returned key is the right type
  418. if (!lRes && dwValType == REG_SZ)
  419. {
  420. //often the reg key holds the path with a , and a number that needs to be cut off
  421. wchar_t* pos = wcschr (pszDirectorydjr,',');
  422. if (pos)
  423. *pos = L'\0';
  424. foundpath = true;
  425. }
  426. }
  427. }
  428. //
  429. //attempt 2: check out the directories most CE Devices install it to.
  430. //
  431. if (!foundpath)
  432. {
  433. lRes = CeGetFileAttributes(L"\\Windows\\Player.exe");
  434. if (lRes != cdwGetAttribFail)
  435. {
  436. foundpath = true;
  437. pszDirectorydjr = L"\\Windows\\Player.exe";
  438. }
  439. else
  440. {
  441. lRes = CeGetFileAttributes(L"\\Program Files\\Media Player\\Player.exe");
  442. if (lRes != cdwGetAttribFail)
  443. {
  444. foundpath = true;
  445. pszDirectorydjr = L"\\Program Files\\Media Player\\Player.exe";
  446. }
  447. else
  448. {
  449. lRes = CeGetFileAttributes(L"\\Program Files\\Windows Media Player\\Player.exe");
  450. if (lRes != cdwGetAttribFail)
  451. {
  452. foundpath = true;
  453. pszDirectorydjr = L"\\Program Files\\Windows Media Player\\Player.exe";
  454. }
  455. }
  456. }
  457. }
  458. //
  459. //attempt 3: look through start menu for shortcuts (this is the traditional way to implement this function)
  460. //
  461. if (!foundpath)
  462. {
  463. pszDirectorydjr = new WCHAR[MAX_PATH];
  464. if (!pszDirectorydjr)
  465. return E_OUTOFMEMORY;
  466. if( !CeSHGetShortcutTarget( L"\\Windows\\Start Menu\\Windows Media Player.lnk",
  467. pszDirectorydjr, MAX_PATH) )
  468. {
  469. if( !CeSHGetShortcutTarget( L"\\Windows\\Start Menu\\Windows Media.lnk",
  470. pszDirectorydjr, MAX_PATH ) )
  471. {
  472. return( E_FAIL );
  473. }
  474. else
  475. foundpath = true;
  476. }
  477. else
  478. foundpath = true;
  479. }
  480. //foundpath will only remain false if all of our 3 attempts completely failed
  481. if (!foundpath)
  482. return(E_FAIL);
  483. pszTargetjdw = wcsrchr( pszDirectorydjr, L'\"' );
  484. if( pszTargetjdw )
  485. {
  486. *pszTargetjdw = 0;
  487. }
  488. if( L'\"' == pszDirectorydjr[0] )
  489. {
  490. pszTargetjdw = &pszDirectorydjr[1];
  491. }
  492. else
  493. {
  494. pszTargetjdw = pszDirectorydjr;
  495. }
  496. //now that we have our final ptr, we can actually make the call to cecreateprocess and run it
  497. if( CeCreateProcess( pszTargetjdw,
  498. m_szCompletePath,
  499. NULL,
  500. NULL,
  501. FALSE,
  502. 0,
  503. NULL,
  504. NULL,
  505. NULL,
  506. &pi ) )
  507. {
  508. //close everything down
  509. CeCloseHandle( pi.hThread );
  510. CeCloseHandle( pi.hProcess );
  511. }
  512. else
  513. {
  514. hr = CeGetLastError();
  515. if( SUCCEEDED( hr ) )
  516. {
  517. hr = CeRapiGetError();
  518. }
  519. }
  520. return( hr );
  521. }
  522. //
  523. // IMDSPObject
  524. //
  525. STDMETHODIMP CStorage::Open( UINT fuMode)
  526. {
  527. HRESULT hr = S_OK;
  528. DWORD dwAccess = 0;
  529. if( fuMode & MDSP_READ )
  530. {
  531. dwAccess |= GENERIC_READ;
  532. }
  533. if( fuMode & MDSP_WRITE )
  534. {
  535. dwAccess |= GENERIC_WRITE;
  536. }
  537. if( INVALID_HANDLE_VALUE == m_hFile )
  538. {
  539. m_hFile = CeCreateFile( m_szCompletePath, dwAccess, 0, NULL, OPEN_EXISTING, NULL, NULL );
  540. if( INVALID_HANDLE_VALUE == m_hFile )
  541. {
  542. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  543. if( SUCCEEDED( hr ) )
  544. {
  545. hr = CeRapiGetError();
  546. }
  547. }
  548. }
  549. else
  550. {
  551. hr = E_FAIL; // Already open??? What do you do???
  552. }
  553. return( hr );
  554. }
  555. STDMETHODIMP CStorage::Read( BYTE *pData, DWORD *pdwSize, BYTE abMac[ 20 ] )
  556. {
  557. HRESULT hr = S_OK;
  558. DWORD dwToRead;
  559. DWORD dwRead;
  560. BYTE *pTmpData=NULL;
  561. if( NULL == pData || NULL == pdwSize )
  562. {
  563. return( E_INVALIDARG );
  564. }
  565. dwToRead=*pdwSize;
  566. *pdwSize = 0;
  567. pTmpData = new BYTE [dwToRead] ;
  568. if( NULL == pTmpData )
  569. {
  570. hr = E_OUTOFMEMORY;
  571. }
  572. if( SUCCEEDED( hr ) )
  573. {
  574. if( CeReadFile(m_hFile, pTmpData, dwToRead, &dwRead, NULL) )
  575. {
  576. *pdwSize = dwRead;
  577. // MAC the parameters
  578. HMAC hMAC;
  579. hr = g_pAppSCServer->MACInit(&hMAC);
  580. if( SUCCEEDED( hr ) )
  581. {
  582. hr = g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), dwRead);
  583. }
  584. if( SUCCEEDED( hr ) )
  585. {
  586. hr = g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(DWORD));
  587. }
  588. if( SUCCEEDED( hr ) )
  589. {
  590. hr = g_pAppSCServer->MACFinal(hMAC, abMac);
  591. }
  592. if( SUCCEEDED( hr ) )
  593. {
  594. hr = g_pAppSCServer->EncryptParam(pTmpData, dwRead);
  595. }
  596. if( SUCCEEDED( hr ) )
  597. {
  598. memcpy(pData, pTmpData, dwRead);
  599. }
  600. }
  601. else
  602. {
  603. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  604. if( SUCCEEDED( hr ) )
  605. {
  606. hr = CeRapiGetError();
  607. }
  608. }
  609. }
  610. if( FAILED( hr ) )
  611. {
  612. *pdwSize = 0;
  613. }
  614. delete [] pTmpData;
  615. return hr;
  616. }
  617. STDMETHODIMP CStorage::Write( BYTE *pData, DWORD *pdwSize, BYTE abMac[ 20 ] )
  618. {
  619. HRESULT hr = S_OK;
  620. DWORD dwWritten;
  621. BYTE *pTmpData=NULL;
  622. BYTE pSelfMac[WMDM_MAC_LENGTH];
  623. HMAC hMAC;
  624. DWORD dwSize = 0;
  625. if( NULL == pData || NULL == pdwSize )
  626. {
  627. return( E_INVALIDARG );
  628. }
  629. dwSize = *pdwSize;
  630. *pdwSize = 0;
  631. pTmpData = new BYTE [dwSize];
  632. if( NULL == pTmpData )
  633. {
  634. hr = E_OUTOFMEMORY;
  635. }
  636. if( SUCCEEDED( hr ) )
  637. {
  638. memcpy(pTmpData, pData, dwSize);
  639. }
  640. // Decrypt the pData Parameter
  641. if( SUCCEEDED( hr ) )
  642. {
  643. hr = g_pAppSCServer->DecryptParam(pTmpData, dwSize);
  644. }
  645. if( SUCCEEDED( hr ) )
  646. {
  647. hr = g_pAppSCServer->MACInit(&hMAC);
  648. }
  649. if( SUCCEEDED( hr ) )
  650. {
  651. hr = g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), dwSize);
  652. }
  653. if( SUCCEEDED( hr ) )
  654. {
  655. hr = g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(&dwSize), sizeof(dwSize));
  656. }
  657. if( SUCCEEDED( hr ) )
  658. {
  659. hr = g_pAppSCServer->MACFinal(hMAC, pSelfMac);
  660. }
  661. if( SUCCEEDED( hr ) )
  662. {
  663. if (memcmp(abMac, pSelfMac, WMDM_MAC_LENGTH) != 0)
  664. {
  665. hr = WMDM_E_MAC_CHECK_FAILED;
  666. }
  667. }
  668. if( SUCCEEDED( hr ) )
  669. {
  670. if( !CeWriteFile(m_hFile, pTmpData, dwSize, &dwWritten,NULL) )
  671. {
  672. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  673. if( SUCCEEDED( hr ) )
  674. {
  675. hr = CeRapiGetError();
  676. }
  677. }
  678. }
  679. if( SUCCEEDED( hr ) && NULL != pdwSize )
  680. {
  681. *pdwSize = dwSize;
  682. }
  683. delete [] pTmpData;
  684. return( hr );
  685. }
  686. STDMETHODIMP CStorage::Delete( UINT fuFlags, IWMDMProgress *pProgress )
  687. {
  688. HRESULT hr = S_OK;
  689. BOOL bRecursive = (fuFlags & WMDM_MODE_RECURSIVE);
  690. if( bRecursive &&
  691. !( m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
  692. {
  693. return( E_INVALIDARG );
  694. }
  695. if( m_findData.dwFileAttributes & FILE_ATTRIBUTE_INROM )
  696. {
  697. return( E_ACCESSDENIED );
  698. }
  699. if( ! ( m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
  700. {
  701. if( !CeDeleteFile(m_szCompletePath) )
  702. {
  703. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  704. if( SUCCEEDED( hr ) )
  705. {
  706. hr = CeRapiGetError();
  707. }
  708. }
  709. }
  710. else
  711. {
  712. hr = DeleteDirectory(m_szCompletePath, bRecursive);
  713. }
  714. if( pProgress )
  715. {
  716. pProgress->Progress( 100 );
  717. }
  718. return( hr );
  719. }
  720. STDMETHODIMP CStorage::Seek( UINT fuFlags, DWORD dwOffset)
  721. {
  722. HRESULT hr = S_OK;
  723. DWORD dwMoveMethod = 0;
  724. switch( fuFlags )
  725. {
  726. case MDSP_SEEK_CUR:
  727. dwMoveMethod = FILE_CURRENT;
  728. break;
  729. case MDSP_SEEK_EOF:
  730. dwMoveMethod = FILE_END;
  731. break;
  732. case MDSP_SEEK_BOF:
  733. default:
  734. dwMoveMethod = FILE_BEGIN;
  735. break;
  736. }
  737. if( !CeSetFilePointer( m_hFile, dwOffset, NULL, dwMoveMethod ) )
  738. {
  739. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  740. if( SUCCEEDED( hr ) )
  741. {
  742. hr = CeRapiGetError();
  743. }
  744. }
  745. return( hr );
  746. }
  747. STDMETHODIMP CStorage::Rename( LPWSTR pwszNewName, IWMDMProgress *pProgress )
  748. {
  749. HRESULT hr = S_OK;
  750. WCHAR wszRenamePath[2*MAX_PATH];
  751. LPWSTR pszSlash = NULL;
  752. if( NULL == pwszNewName )
  753. {
  754. return( E_INVALIDARG );
  755. }
  756. memset( wszRenamePath, 0, sizeof(wszRenamePath) );
  757. pszSlash = wcsrchr( m_szCompletePath, L'\\');
  758. if( pszSlash )
  759. {
  760. wcsncpy( wszRenamePath, m_szCompletePath, (pszSlash - m_szCompletePath) + 1 );
  761. wszRenamePath[ (pszSlash - m_szCompletePath) + 1 ] = L'\0';
  762. }
  763. wcsncat( wszRenamePath, pwszNewName, sizeof(wszRenamePath)/sizeof(wszRenamePath[0]) - ( wcslen(wszRenamePath) + 1 ) );
  764. if( !CeMoveFile( m_szCompletePath, wszRenamePath ) )
  765. {
  766. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  767. if( SUCCEEDED( hr ) )
  768. {
  769. hr = CeRapiGetError();
  770. }
  771. }
  772. else
  773. {
  774. HANDLE hFind = CeFindFirstFile( wszRenamePath, &m_findData );
  775. if( INVALID_HANDLE_VALUE == hFind )
  776. {
  777. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  778. if( SUCCEEDED( hr ) )
  779. {
  780. hr = CeRapiGetError();
  781. }
  782. }
  783. else
  784. {
  785. memset( m_szCompletePath, 0, sizeof(m_szCompletePath) );
  786. wcsncpy( m_szCompletePath, wszRenamePath, sizeof(m_szCompletePath)/sizeof(m_szCompletePath[0]) - 1 );
  787. CeFindClose( hFind );
  788. }
  789. }
  790. if( pProgress )
  791. {
  792. pProgress->Progress( 100 );
  793. }
  794. return( hr );
  795. }
  796. STDMETHODIMP CStorage::Move( UINT fuMode, IWMDMProgress *pProgress, IMDSPStorage *pTarget )
  797. {
  798. HRESULT hr = E_NOTIMPL;
  799. if( pProgress )
  800. {
  801. pProgress->Progress( 100 );
  802. }
  803. return( hr );
  804. }
  805. STDMETHODIMP CStorage::Close( void )
  806. {
  807. HRESULT hr = S_OK;
  808. if( INVALID_HANDLE_VALUE != m_hFile )
  809. {
  810. if( !CeCloseHandle( m_hFile ) )
  811. {
  812. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  813. if( SUCCEEDED( hr ) )
  814. {
  815. hr = CeRapiGetError();
  816. }
  817. }
  818. else
  819. {
  820. m_hFile = INVALID_HANDLE_VALUE;
  821. }
  822. }
  823. return( hr );
  824. }
  825. //
  826. // IMDSPObjectInfo
  827. //
  828. STDMETHODIMP CStorage::GetPlayLength( DWORD *pdwLength)
  829. {
  830. return( E_NOTIMPL );
  831. }
  832. STDMETHODIMP CStorage::SetPlayLength( DWORD dwLength)
  833. {
  834. return( E_NOTIMPL );
  835. }
  836. STDMETHODIMP CStorage::GetPlayOffset( DWORD *pdwOffset )
  837. {
  838. return( E_NOTIMPL );
  839. }
  840. STDMETHODIMP CStorage::SetPlayOffset( DWORD dwOffset )
  841. {
  842. return( E_NOTIMPL );
  843. }
  844. STDMETHODIMP CStorage::GetTotalLength( DWORD *pdwLength )
  845. {
  846. return( E_NOTIMPL );
  847. }
  848. STDMETHODIMP CStorage::GetLastPlayPosition( DWORD *pdwLastPos )
  849. {
  850. return( E_NOTIMPL );
  851. }
  852. STDMETHODIMP CStorage::GetLongestPlayPosition(DWORD *pdwLongestPos )
  853. {
  854. return( E_NOTIMPL );
  855. }
  856. //
  857. // Helper functions
  858. //
  859. HRESULT CStorage::DeleteDirectory(LPCWSTR pszPath, BOOL bRecursive)
  860. {
  861. HRESULT hr = S_OK;
  862. CE_FIND_DATA *rgFindData =NULL;
  863. DWORD dwCount;
  864. WCHAR szSearchPath[MAX_PATH];
  865. DWORD iFile;
  866. if( NULL == pszPath )
  867. {
  868. return( E_INVALIDARG );
  869. }
  870. if( !bRecursive )
  871. {
  872. if( !CeRemoveDirectory(pszPath) )
  873. {
  874. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  875. if( SUCCEEDED( hr ) )
  876. {
  877. hr = CeRapiGetError();
  878. }
  879. }
  880. }
  881. else
  882. {
  883. memset( szSearchPath, 0, sizeof(szSearchPath) );
  884. if( m_fRoot )
  885. {
  886. _snwprintf( szSearchPath, sizeof(szSearchPath)/sizeof(szSearchPath[0]) - 1, L"%s*.*", pszPath );
  887. }
  888. else
  889. {
  890. _snwprintf( szSearchPath, sizeof(szSearchPath)/sizeof(szSearchPath[0]) - 1, L"%s\\*.*", pszPath );
  891. }
  892. if( !CeFindAllFiles( szSearchPath,
  893. FAF_ATTRIBUTES |
  894. FAF_CREATION_TIME |
  895. FAF_LASTACCESS_TIME |
  896. FAF_LASTWRITE_TIME |
  897. FAF_SIZE_HIGH |
  898. FAF_SIZE_LOW |
  899. FAF_OID |
  900. FAF_NAME,
  901. &dwCount,
  902. &rgFindData ) )
  903. {
  904. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  905. if( SUCCEEDED( hr ) )
  906. {
  907. hr = CeRapiGetError();
  908. }
  909. }
  910. if( SUCCEEDED( hr ) )
  911. {
  912. for( iFile = 0; iFile < dwCount && SUCCEEDED( hr ); iFile++ )
  913. {
  914. memset( szSearchPath, 0, sizeof(szSearchPath) );
  915. if( m_fRoot )
  916. {
  917. _snwprintf( szSearchPath, sizeof(szSearchPath)/sizeof(szSearchPath[0]) - 1, L"%s*.*", rgFindData[iFile].cFileName);
  918. }
  919. else
  920. {
  921. _snwprintf( szSearchPath, sizeof(szSearchPath)/sizeof(szSearchPath[0]) - 1, L"%s\\*.*", rgFindData[iFile].cFileName);
  922. }
  923. if( rgFindData[iFile].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
  924. {
  925. hr = DeleteDirectory(szSearchPath, bRecursive );
  926. }
  927. else
  928. {
  929. if( !CeDeleteFile( szSearchPath ) )
  930. {
  931. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  932. if( SUCCEEDED( hr ) )
  933. {
  934. hr = CeRapiGetError();
  935. }
  936. }
  937. }
  938. }
  939. if( rgFindData )
  940. {
  941. CeRapiFreeBuffer( rgFindData );
  942. }
  943. }
  944. if( SUCCEEDED( hr ) )
  945. {
  946. if( !CeRemoveDirectory(pszPath) )
  947. {
  948. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  949. if( SUCCEEDED( hr ) )
  950. {
  951. hr = CeRapiGetError();
  952. }
  953. }
  954. }
  955. }
  956. return( hr );
  957. }