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.

1698 lines
38 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. // MDSPStorage.cpp : Implementation of CMDSPStorage
  24. #include "hdspPCH.h"
  25. #include "inc\wmplenc.h"
  26. #define CONEg(p)\
  27. do\
  28. {\
  29. if (!(p))\
  30. {\
  31. hr = WMDM_E_INTERFACEDEAD;\
  32. goto Error;\
  33. }\
  34. }\
  35. while (fFalse)
  36. typedef struct __MOVETHREADARGS
  37. {
  38. WCHAR wcsSrc[MAX_PATH];
  39. WCHAR wcsDst[MAX_PATH];
  40. BOOL bNewThread;
  41. IWMDMProgress *pProgress;
  42. LPSTREAM pStream;
  43. CMDSPStorage *pThis;
  44. DWORD dwStatus;
  45. } MOVETHREADARGS;
  46. /////////////////////////////////////////////////////////////////////////////
  47. // CMDSPStorage
  48. CMDSPStorage::CMDSPStorage()
  49. {
  50. m_hFile = INVALID_HANDLE_VALUE;
  51. m_fEncryptToMPX = FALSE;
  52. m_fCreatedHeader = FALSE;
  53. m_cUsedData = 0;
  54. }
  55. CMDSPStorage::~CMDSPStorage()
  56. {
  57. if( m_hFile != INVALID_HANDLE_VALUE )
  58. {
  59. CloseHandle(m_hFile);
  60. }
  61. }
  62. STDMETHODIMP CMDSPStorage::GetStorageGlobals(IMDSPStorageGlobals **ppStorageGlobals)
  63. {
  64. HRESULT hr;
  65. int i;
  66. CFRg(g_pAppSCServer);
  67. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  68. {
  69. CORg(WMDM_E_NOTCERTIFIED);
  70. }
  71. g_CriticalSection.Lock();
  72. CARg(ppStorageGlobals);
  73. CONEg(m_wcsName[0]);
  74. WCHAR devName[MAX_PATH], *pW;
  75. pW=&devName[0];
  76. wcsParseDeviceName(m_wcsName, &(pW));
  77. for(i=0; i<MDSP_MAX_DEVICE_OBJ;i++)
  78. {
  79. if( !wcscmp(g_GlobalDeviceInfo[i].wcsDevName, devName) )
  80. {
  81. break;
  82. }
  83. }
  84. if( i<MDSP_MAX_DEVICE_OBJ && g_GlobalDeviceInfo[i].pIMDSPStorageGlobals ) // found match
  85. {
  86. *ppStorageGlobals = (IMDSPStorageGlobals *)g_GlobalDeviceInfo[i].pIMDSPStorageGlobals;
  87. ((IMDSPStorageGlobals *)g_GlobalDeviceInfo[i].pIMDSPStorageGlobals)->AddRef();
  88. hr = S_OK;
  89. } else { // new entry in the global array
  90. if(!(i<MDSP_MAX_DEVICE_OBJ) ) // no match found
  91. {
  92. for(i=0; i<MDSP_MAX_DEVICE_OBJ;i++)
  93. {
  94. if( !g_GlobalDeviceInfo[i].bValid )
  95. {
  96. break;
  97. }
  98. }
  99. }
  100. CPRg(i<MDSP_MAX_DEVICE_OBJ);
  101. CComObject<CMDSPStorageGlobals> *pObj;
  102. CORg(CComObject<CMDSPStorageGlobals>::CreateInstance(&pObj));
  103. hr=pObj->QueryInterface(
  104. IID_IMDSPStorageGlobals,
  105. reinterpret_cast<void**>(&g_GlobalDeviceInfo[i].pIMDSPStorageGlobals)
  106. );
  107. if( FAILED(hr) )
  108. {
  109. delete pObj;
  110. }
  111. else
  112. {
  113. wcscpy(pObj->m_wcsName, devName);
  114. *ppStorageGlobals = (IMDSPStorageGlobals *)g_GlobalDeviceInfo[i].pIMDSPStorageGlobals;
  115. g_GlobalDeviceInfo[i].bValid=TRUE;
  116. wcscpy(g_GlobalDeviceInfo[i].wcsDevName, devName);
  117. g_GlobalDeviceInfo[i].dwStatus = 0;
  118. } // end of else
  119. } // end of else
  120. Error:
  121. g_CriticalSection.Unlock();
  122. hrLogDWORD("IMDSPStorage::GetStorageGlobals returned 0x%08lx", hr, hr);
  123. return hr;
  124. }
  125. STDMETHODIMP CMDSPStorage::SetAttributes(
  126. DWORD dwAttributes,
  127. _WAVEFORMATEX *pFormat
  128. )
  129. {
  130. HRESULT hr=E_FAIL;
  131. DWORD dwAttrib;
  132. CFRg(g_pAppSCServer);
  133. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  134. {
  135. CORg(WMDM_E_NOTCERTIFIED);
  136. }
  137. CONEg(m_wcsName[0]);
  138. dwAttrib = UtilGetFileAttributesW(m_wcsName);
  139. if( dwAttrib == (DWORD)0xFFFFFFFF )
  140. {
  141. return E_FAIL;
  142. }
  143. if( (dwAttributes & WMDM_FILE_ATTR_READONLY) )
  144. {
  145. dwAttrib |= FILE_ATTRIBUTE_READONLY;
  146. }
  147. else
  148. {
  149. dwAttrib &= (~FILE_ATTRIBUTE_READONLY);
  150. }
  151. if( (dwAttributes & WMDM_FILE_ATTR_HIDDEN) )
  152. {
  153. dwAttrib |= FILE_ATTRIBUTE_HIDDEN;
  154. }
  155. else
  156. {
  157. dwAttrib &= (~FILE_ATTRIBUTE_HIDDEN);
  158. }
  159. if( (dwAttributes & WMDM_FILE_ATTR_SYSTEM) )
  160. {
  161. dwAttrib |= FILE_ATTRIBUTE_SYSTEM;
  162. }
  163. else
  164. {
  165. dwAttrib &= (~FILE_ATTRIBUTE_SYSTEM);
  166. }
  167. CWRg(UtilSetFileAttributesW(m_wcsName, dwAttrib));
  168. hr=S_OK;
  169. Error:
  170. hrLogDWORD("IMDSPStorage::SetAttributes returned 0x%08lx", hr, hr);
  171. return hr;
  172. }
  173. STDMETHODIMP CMDSPStorage::GetAttributes(
  174. DWORD * pdwAttributes,
  175. _WAVEFORMATEX * pFormat
  176. )
  177. {
  178. HRESULT hr=S_OK;
  179. DWORD dwAttrib;
  180. CFRg(g_pAppSCServer);
  181. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  182. {
  183. CORg(WMDM_E_NOTCERTIFIED);
  184. }
  185. CARg(pdwAttributes);
  186. CONEg(m_wcsName[0]);
  187. dwAttrib = UtilGetFileAttributesW(m_wcsName);
  188. if( dwAttrib == (DWORD)0xFFFFFFFF )
  189. {
  190. return HRESULT_FROM_WIN32(GetLastError());
  191. }
  192. *pdwAttributes = ( WMDM_STORAGE_ATTR_REMOVABLE |
  193. WMDM_STORAGE_ATTR_FOLDERS | WMDM_FILE_ATTR_CANREAD );
  194. if( !(dwAttrib & FILE_ATTRIBUTE_READONLY) )
  195. {
  196. *pdwAttributes |= (WMDM_FILE_ATTR_CANDELETE |
  197. WMDM_FILE_ATTR_CANMOVE | WMDM_FILE_ATTR_CANRENAME);
  198. }
  199. if( dwAttrib & FILE_ATTRIBUTE_DIRECTORY )
  200. {
  201. *pdwAttributes |= WMDM_FILE_ATTR_FOLDER;
  202. QuerySubFoldersAndFiles(m_wcsName, pdwAttributes); // No failure check, if failed, just keep current attributes
  203. }
  204. else
  205. {
  206. *pdwAttributes |= WMDM_FILE_ATTR_FILE;
  207. }
  208. // Now handle Hidden, ReadOnly, and System attributes
  209. if( (dwAttrib & FILE_ATTRIBUTE_READONLY) )
  210. {
  211. *pdwAttributes |= WMDM_FILE_ATTR_READONLY;
  212. }
  213. if( (dwAttrib & FILE_ATTRIBUTE_HIDDEN) )
  214. {
  215. *pdwAttributes |= WMDM_FILE_ATTR_HIDDEN;
  216. }
  217. if( (dwAttrib & FILE_ATTRIBUTE_SYSTEM) )
  218. {
  219. *pdwAttributes |= WMDM_FILE_ATTR_SYSTEM;
  220. }
  221. hr=S_OK;
  222. Error:
  223. hrLogDWORD("IMDSPStorage::GetAttributes returned 0x%08lx", hr, hr);
  224. return hr;
  225. }
  226. STDMETHODIMP CMDSPStorage::GetName(LPWSTR pwszName, UINT nMaxChars)
  227. {
  228. HRESULT hr=S_OK;
  229. CFRg(g_pAppSCServer);
  230. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  231. {
  232. CORg(WMDM_E_NOTCERTIFIED);
  233. }
  234. CONEg(m_wcsName[0]);
  235. CARg(pwszName);
  236. CPRg(wcslen(m_wcsName)<nMaxChars);
  237. if( m_wcsName[wcslen(m_wcsName)-1] == 0x5c ) // this is root storage
  238. {
  239. wcscpy(pwszName, wcsrchr(m_wcsName, 0x5c));
  240. }
  241. else
  242. {
  243. wcscpy(pwszName, wcsrchr(m_wcsName, 0x5c)+1);
  244. }
  245. Error:
  246. hrLogDWORD("IMDSPStorage::GetName returned 0x%08lx", hr, hr);
  247. return hr;
  248. }
  249. STDMETHODIMP CMDSPStorage::GetDate(PWMDMDATETIME pDateTimeUTC)
  250. {
  251. HRESULT hr=E_FAIL;
  252. HANDLE hFFile = INVALID_HANDLE_VALUE;
  253. SYSTEMTIME sysTime;
  254. CFRg(g_pAppSCServer);
  255. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  256. {
  257. CORg(WMDM_E_NOTCERTIFIED);
  258. }
  259. CARg(pDateTimeUTC);
  260. CONEg(m_wcsName[0]);
  261. if( g_bIsWinNT )
  262. {
  263. WIN32_FIND_DATAW wfd;
  264. if( FILE_ATTRIBUTE_DIRECTORY & GetFileAttributesW(m_wcsName) )
  265. {
  266. // Get name and date of current directory
  267. WCHAR pwszTmpFile[MAX_PATH];
  268. wcscpy( pwszTmpFile, m_wcsName );
  269. if( pwszTmpFile[wcslen(pwszTmpFile)-1] != 0x5c ) wcscat(pwszTmpFile, g_wcsBackslash);
  270. wcscat(pwszTmpFile, L".");
  271. hFFile=FindFirstFileW(pwszTmpFile, &wfd);
  272. }
  273. else
  274. hFFile=FindFirstFileW(m_wcsName, &wfd);
  275. CWRg(hFFile != INVALID_HANDLE_VALUE);
  276. CFRg(FileTimeToSystemTime((CONST FILETIME *)&(wfd.ftLastWriteTime), &sysTime));
  277. }
  278. else
  279. {
  280. WIN32_FIND_DATAA fd;
  281. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  282. if( FILE_ATTRIBUTE_DIRECTORY & GetFileAttributesA(m_szTmp) )
  283. {
  284. if( m_szTmp[strlen(m_szTmp)-1] != 0x5c ) strcat(m_szTmp, g_szBackslash);
  285. strcat(m_szTmp, ".");
  286. }
  287. hFFile=FindFirstFileA(m_szTmp, &fd);
  288. CWRg(hFFile != INVALID_HANDLE_VALUE);
  289. CFRg(FileTimeToSystemTime((CONST FILETIME *)&(fd.ftLastWriteTime), &sysTime));
  290. }
  291. pDateTimeUTC->wYear = sysTime.wYear;
  292. pDateTimeUTC->wMonth = sysTime.wMonth;
  293. pDateTimeUTC->wDay = sysTime.wDay;
  294. pDateTimeUTC->wHour = sysTime.wHour;
  295. pDateTimeUTC->wMinute = sysTime.wMinute;
  296. pDateTimeUTC->wSecond = sysTime.wSecond;
  297. hr=S_OK;
  298. Error:
  299. if(hFFile != INVALID_HANDLE_VALUE)
  300. {
  301. FindClose(hFFile);
  302. }
  303. hrLogDWORD("IMDSPStorage::GetDate returned 0x%08lx", hr, hr);
  304. return hr;
  305. }
  306. STDMETHODIMP CMDSPStorage::GetSize(DWORD * pdwSizeLow, DWORD * pdwSizeHigh)
  307. {
  308. HRESULT hr = S_OK;
  309. HANDLE hFile = INVALID_HANDLE_VALUE;
  310. DWORD dwLS;
  311. DWORD dwHS;
  312. CFRg(g_pAppSCServer);
  313. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  314. {
  315. CORg(WMDM_E_NOTCERTIFIED);
  316. }
  317. CARg(pdwSizeLow);
  318. CONEg(m_wcsName[0]);
  319. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  320. dwLS = 0;
  321. dwHS = 0;
  322. if( FILE_ATTRIBUTE_DIRECTORY & GetFileAttributesA(m_szTmp) )
  323. {
  324. *pdwSizeLow = 0;
  325. *pdwSizeHigh = 0;
  326. }
  327. else
  328. {
  329. CORg(GetFileSizeRecursive(m_szTmp, &dwLS, &dwHS));
  330. *pdwSizeLow = dwLS;
  331. if(pdwSizeHigh)
  332. {
  333. *pdwSizeHigh = dwHS;
  334. }
  335. }
  336. hr = S_OK;
  337. Error:
  338. hrLogDWORD("IMDSPStorage::GetSize returned 0x%08lx", hr, hr);
  339. return hr;
  340. }
  341. STDMETHODIMP CMDSPStorage::GetRights(PWMDMRIGHTS *ppRights,UINT *pnRightsCount,
  342. BYTE abMac[WMDM_MAC_LENGTH])
  343. {
  344. HRESULT hr=WMDM_E_NOTSUPPORTED;
  345. CFRg(g_pAppSCServer);
  346. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  347. {
  348. CORg(WMDM_E_NOTCERTIFIED);
  349. }
  350. Error:
  351. hrLogDWORD("IMDSPStorage::GetRights returned 0x%08lx", hr, hr);
  352. return hr;
  353. }
  354. STDMETHODIMP CMDSPStorage::CreateStorage(DWORD dwAttributes, _WAVEFORMATEX * pFormat, LPWSTR pwszName, IMDSPStorage * * ppNewStorage)
  355. {
  356. HRESULT hr=E_FAIL;
  357. HANDLE hFile;
  358. WCHAR *pwcs, wcsCopy[MAX_PATH];
  359. DWORD curAttr=0, fsAttrib=FILE_ATTRIBUTE_NORMAL;
  360. LPWSTR pszExt = NULL;
  361. BOOL fEncryptToMPX = FALSE;
  362. CFRg(g_pAppSCServer);
  363. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  364. {
  365. CORg(WMDM_E_NOTCERTIFIED);
  366. }
  367. CONEg(m_wcsName[0]);
  368. CARg(pwszName);
  369. CARg(ppNewStorage);
  370. wcscpy(wcsCopy, m_wcsName);
  371. if( wcsCopy[wcslen(wcsCopy)-1] == 0x5c )
  372. {
  373. wcsCopy[wcslen(wcsCopy)-1] = NULL; // trim the last backslash;
  374. }
  375. curAttr = UtilGetFileAttributesW(wcsCopy);
  376. if( !(curAttr & FILE_ATTRIBUTE_DIRECTORY ) ) // if current storage is a file
  377. {
  378. if( dwAttributes & WMDM_STORAGECONTROL_INSERTINTO )
  379. {
  380. CORg(WMDM_E_NOTSUPPORTED); // can't do InsertInto
  381. }
  382. else
  383. { // for file, the default is Before&After
  384. pwcs=wcsrchr(wcsCopy, g_wcsBackslash[0]);
  385. CFRg(pwcs);
  386. }
  387. }
  388. else
  389. { // current storage is a dir
  390. if( (dwAttributes & WMDM_STORAGECONTROL_INSERTBEFORE) ||
  391. (dwAttributes & WMDM_STORAGECONTROL_INSERTAFTER) ) // before or after
  392. {
  393. pwcs=wcsrchr(wcsCopy, g_wcsBackslash[0]);
  394. CFRg(pwcs);
  395. }
  396. else
  397. { // for dir, the default is InsertInto
  398. pwcs=wcsCopy+wcslen(wcsCopy);
  399. }
  400. }
  401. wcscpy(pwcs, g_wcsBackslash);
  402. wcscat(pwcs, pwszName);
  403. pszExt = wcsrchr( wcsCopy, L'.' );
  404. if( NULL != pszExt )
  405. {
  406. fEncryptToMPX = !wcsicmp( pszExt, L".mp3" );
  407. if( fEncryptToMPX )
  408. {
  409. wcsncpy( pszExt, L".mpx", 4 );
  410. }
  411. }
  412. // Find what file system attribute the intend storage should be
  413. if( dwAttributes & WMDM_FILE_ATTR_HIDDEN )
  414. {
  415. fsAttrib |= FILE_ATTRIBUTE_HIDDEN;
  416. }
  417. if( dwAttributes & WMDM_FILE_ATTR_SYSTEM )
  418. {
  419. fsAttrib |= FILE_ATTRIBUTE_SYSTEM;
  420. }
  421. if( dwAttributes & WMDM_FILE_ATTR_READONLY )
  422. {
  423. fsAttrib |= FILE_ATTRIBUTE_READONLY;
  424. }
  425. if( dwAttributes & WMDM_FILE_ATTR_FOLDER )
  426. {
  427. if(UtilCreateDirectoryW(wcsCopy, NULL))
  428. {
  429. hr=S_OK;
  430. }
  431. else
  432. {
  433. hr=GetLastError();
  434. if( hr == ERROR_ALREADY_EXISTS )
  435. {
  436. if( dwAttributes & WMDM_FILE_CREATE_OVERWRITE )
  437. {
  438. hr=S_OK;
  439. }
  440. else
  441. {
  442. hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
  443. }
  444. }
  445. else
  446. {
  447. hr = HRESULT_FROM_WIN32(hr);
  448. goto Error;
  449. }
  450. }
  451. if( S_OK == hr )
  452. {
  453. CWRg(UtilSetFileAttributesW(wcsCopy, fsAttrib));
  454. }
  455. }
  456. else if ( dwAttributes & WMDM_FILE_ATTR_FILE )
  457. {
  458. // If Overwrite is specified, use CREATE_ALWAYS
  459. if( dwAttributes & WMDM_FILE_CREATE_OVERWRITE )
  460. {
  461. hFile=UtilCreateFileW(wcsCopy, GENERIC_WRITE | GENERIC_READ,
  462. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  463. CREATE_ALWAYS, fsAttrib, NULL);
  464. }
  465. else
  466. {
  467. hFile=UtilCreateFileW(wcsCopy, GENERIC_WRITE | GENERIC_READ,
  468. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
  469. CREATE_NEW, fsAttrib, NULL);
  470. }
  471. CWRg(hFile != INVALID_HANDLE_VALUE);
  472. CloseHandle(hFile);
  473. hr=S_OK;
  474. }
  475. else
  476. {
  477. hr=E_INVALIDARG;
  478. goto Error;
  479. }
  480. if( hr==S_OK )
  481. {
  482. CComObject<CMDSPStorage> *pObj;
  483. CORg(CComObject<CMDSPStorage>::CreateInstance(&pObj));
  484. hr=pObj->QueryInterface(IID_IMDSPStorage, reinterpret_cast<void**>(ppNewStorage));
  485. if( FAILED(hr) )
  486. {
  487. delete pObj;
  488. }
  489. else
  490. {
  491. pObj->m_fEncryptToMPX = fEncryptToMPX;
  492. wcscpy(pObj->m_wcsName, wcsCopy);
  493. }
  494. }
  495. Error:
  496. hrLogDWORD("IMDSPStorage::CreateStorage returned 0x%08lx", hr, hr);
  497. return hr;
  498. }
  499. STDMETHODIMP CMDSPStorage::SendOpaqueCommand(OPAQUECOMMAND *pCommand)
  500. {
  501. HRESULT hr = WMDM_E_NOTSUPPORTED;
  502. CFRg(g_pAppSCServer);
  503. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  504. {
  505. CORg(WMDM_E_NOTCERTIFIED);
  506. }
  507. Error:
  508. hrLogDWORD("IMDSPStorage::SendOpaqueCommand returned 0x%08lx", hr, hr);
  509. return hr;
  510. }
  511. // IMDSPObjectInfo
  512. STDMETHODIMP CMDSPStorage::GetPlayLength(/*[out]*/ DWORD *pdwLength)
  513. {
  514. HRESULT hr;
  515. CFRg(g_pAppSCServer);
  516. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  517. {
  518. CORg(WMDM_E_NOTCERTIFIED);
  519. }
  520. if ( !pdwLength )
  521. {
  522. hr = E_INVALIDARG;
  523. }
  524. else
  525. {
  526. hr = WMDM_E_NOTSUPPORTED; // For PMSP
  527. }
  528. Error:
  529. hrLogDWORD("IMDSPObjectInfo::GetPlayLength returned 0x%08lx", hr, hr);
  530. return hr;
  531. }
  532. STDMETHODIMP CMDSPStorage::SetPlayLength(/*[in]*/ DWORD dwLength)
  533. {
  534. HRESULT hr = WMDM_E_NOTSUPPORTED; // For PMSP
  535. CFRg(g_pAppSCServer);
  536. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  537. {
  538. CORg(WMDM_E_NOTCERTIFIED);
  539. }
  540. Error:
  541. hrLogDWORD("IMDSPObjectInfo::SetPlayLength returned 0x%08lx", hr, hr);
  542. return hr;
  543. }
  544. STDMETHODIMP CMDSPStorage::GetPlayOffset(/*[out]*/ DWORD *pdwOffset)
  545. {
  546. HRESULT hr;
  547. CFRg(g_pAppSCServer);
  548. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  549. {
  550. CORg(WMDM_E_NOTCERTIFIED);
  551. }
  552. if ( !pdwOffset )
  553. {
  554. hr = E_INVALIDARG;
  555. }
  556. else
  557. {
  558. hr = WMDM_E_NOTSUPPORTED; // For PMSP
  559. }
  560. Error:
  561. hrLogDWORD("IMDSPObjectInfo::GetPlayOffset returned 0x%08lx", hr, hr);
  562. return hr;
  563. }
  564. STDMETHODIMP CMDSPStorage::SetPlayOffset(/*[in]*/ DWORD dwOffset)
  565. {
  566. HRESULT hr = WMDM_E_NOTSUPPORTED; // For PMSP
  567. CFRg(g_pAppSCServer);
  568. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  569. {
  570. CORg(WMDM_E_NOTCERTIFIED);
  571. }
  572. Error:
  573. hrLogDWORD("IMDSPObjectInfo::SetPlayOffset returned 0x%08lx", hr, hr);
  574. return hr;
  575. }
  576. STDMETHODIMP CMDSPStorage::GetTotalLength(/*[out]*/ DWORD *pdwLength)
  577. {
  578. HRESULT hr;
  579. CFRg(g_pAppSCServer);
  580. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  581. {
  582. CORg(WMDM_E_NOTCERTIFIED);
  583. }
  584. if ( !pdwLength )
  585. {
  586. hr = E_INVALIDARG;
  587. }
  588. else
  589. {
  590. hr = WMDM_E_NOTSUPPORTED; // For PMSP
  591. }
  592. Error:
  593. hrLogDWORD("IMDSPObjectInfo::GetTotalLength returned 0x%08lx", hr, hr);
  594. return hr;
  595. }
  596. STDMETHODIMP CMDSPStorage::GetLastPlayPosition(/*[out]*/ DWORD *pdwLastPos)
  597. {
  598. HRESULT hr;
  599. CFRg(g_pAppSCServer);
  600. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  601. {
  602. CORg(WMDM_E_NOTCERTIFIED);
  603. }
  604. if ( !pdwLastPos )
  605. {
  606. hr = E_INVALIDARG;
  607. }
  608. else
  609. {
  610. hr = WMDM_E_NOTSUPPORTED; // For PMSP
  611. }
  612. Error:
  613. hrLogDWORD("IMDSPObjectInfo::GetLastPlayPosition returned 0x%08lx", hr, hr);
  614. return hr;
  615. }
  616. STDMETHODIMP CMDSPStorage::GetLongestPlayPosition(/*[out]*/ DWORD *pdwLongestPos)
  617. {
  618. HRESULT hr;
  619. CFRg(g_pAppSCServer);
  620. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  621. {
  622. CORg(WMDM_E_NOTCERTIFIED);
  623. }
  624. if ( !pdwLongestPos )
  625. {
  626. hr = E_INVALIDARG;
  627. }
  628. else
  629. {
  630. hr = WMDM_E_NOTSUPPORTED; // For PMSP
  631. }
  632. Error:
  633. hrLogDWORD("IMDSPObjectInfo::GetLongestPlayPosition returned 0x%08lx", hr, hr);
  634. return hr;
  635. }
  636. // IMDSPObject
  637. STDMETHODIMP CMDSPStorage::Open(UINT fuMode)
  638. {
  639. HRESULT hr;
  640. DWORD dwMode;
  641. CFRg(g_pAppSCServer);
  642. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  643. {
  644. CORg(WMDM_E_NOTCERTIFIED);
  645. }
  646. CONEg(m_wcsName[0]);
  647. if( m_hFile != INVALID_HANDLE_VALUE )
  648. {
  649. hr = WMDM_E_BUSY;
  650. goto Error;
  651. }
  652. dwMode = UtilGetFileAttributesW(m_wcsName);
  653. if( (dwMode & FILE_ATTRIBUTE_DIRECTORY) )
  654. {
  655. hr=WMDM_E_NOTSUPPORTED;
  656. }
  657. else
  658. {
  659. dwMode = 0;
  660. if(fuMode & MDSP_WRITE )
  661. {
  662. dwMode |= GENERIC_WRITE;
  663. }
  664. if(fuMode & MDSP_READ )
  665. {
  666. dwMode |= GENERIC_READ;
  667. }
  668. m_hFile=UtilCreateFileW(
  669. m_wcsName, dwMode,
  670. FILE_SHARE_READ | FILE_SHARE_WRITE,
  671. NULL,
  672. OPEN_EXISTING,
  673. FILE_ATTRIBUTE_NORMAL,
  674. NULL
  675. );
  676. if( m_hFile == INVALID_HANDLE_VALUE )
  677. {
  678. hr = E_FAIL;
  679. }
  680. else
  681. {
  682. hr = S_OK;
  683. }
  684. }
  685. Error:
  686. hrLogDWORD("IMDSPObject::Open returned 0x%08lx", hr, hr);
  687. return hr;
  688. }
  689. STDMETHODIMP CMDSPStorage::Read(
  690. BYTE *pData,
  691. DWORD *pdwSize,
  692. BYTE abMac[WMDM_MAC_LENGTH]
  693. )
  694. {
  695. HRESULT hr;
  696. DWORD dwToRead, dwRead=NULL;
  697. BYTE *pTmpData=NULL;
  698. CFRg(g_pAppSCServer);
  699. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  700. {
  701. CORg(WMDM_E_NOTCERTIFIED);
  702. }
  703. CARg(pData);
  704. CARg(pdwSize);
  705. dwToRead=*pdwSize;
  706. if ( m_hFile == INVALID_HANDLE_VALUE )
  707. {
  708. return E_FAIL;
  709. }
  710. pTmpData = new BYTE [dwToRead] ;
  711. CPRg(pTmpData);
  712. if( ReadFile(m_hFile,(LPVOID)pTmpData,dwToRead,&dwRead,NULL) )
  713. {
  714. *pdwSize = dwRead;
  715. if( dwRead )
  716. {
  717. // MAC the parameters
  718. HMAC hMAC;
  719. CORg(g_pAppSCServer->MACInit(&hMAC));
  720. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), dwRead));
  721. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(DWORD)));
  722. CORg(g_pAppSCServer->MACFinal(hMAC, abMac));
  723. CORg(g_pAppSCServer->EncryptParam(pTmpData, dwRead));
  724. memcpy(pData, pTmpData, dwRead);
  725. }
  726. hr = S_OK;
  727. }
  728. else
  729. {
  730. *pdwSize = 0;
  731. hr = E_FAIL;
  732. }
  733. Error:
  734. hrLogDWORD("IMDSPObject::Read returned 0x%08lx", hr, hr);
  735. if(pTmpData)
  736. {
  737. delete [] pTmpData;
  738. }
  739. return hr;
  740. }
  741. STDMETHODIMP CMDSPStorage::Write(
  742. BYTE *pData,
  743. DWORD *pdwSize,
  744. BYTE abMac[WMDM_MAC_LENGTH]
  745. )
  746. {
  747. HRESULT hr;
  748. DWORD dwWritten=0;
  749. DWORD dwEncryptionWritten = 0;
  750. BYTE *pTmpData=NULL;
  751. BYTE *pDataWalk = NULL;
  752. int cbSkipID3V2 = 0;
  753. BYTE pSelfMac[WMDM_MAC_LENGTH];
  754. USES_CONVERSION;
  755. char CFDriveLetter[1];
  756. DWORD idxWalk = 0;
  757. CARg(pData);
  758. CARg(pdwSize);
  759. if ( m_hFile == INVALID_HANDLE_VALUE )
  760. {
  761. return E_FAIL;
  762. }
  763. if( *pdwSize == 0 )
  764. {
  765. return S_OK;
  766. }
  767. pTmpData = new BYTE [*pdwSize];
  768. CPRg(pTmpData);
  769. memcpy(pTmpData, pData, *pdwSize);
  770. // Decrypt the pData Parameter
  771. CHRg(g_pAppSCServer->DecryptParam(pTmpData, *pdwSize));
  772. HMAC hMAC;
  773. CORg(g_pAppSCServer->MACInit(&hMAC));
  774. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), *pdwSize));
  775. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(*pdwSize)));
  776. CORg(g_pAppSCServer->MACFinal(hMAC, pSelfMac));
  777. if (memcmp(abMac, pSelfMac, WMDM_MAC_LENGTH) != 0)
  778. {
  779. hr = WMDM_E_MAC_CHECK_FAILED;
  780. goto Error;
  781. }
  782. if( m_fEncryptToMPX && !m_fCreatedHeader )
  783. {
  784. //
  785. // Used to get serial number
  786. //
  787. CComPtr<IMDSPStorageGlobals> spStorageGlobals;
  788. BYTE abMacTemp[WMDM_MAC_LENGTH];
  789. WMDMID serialNum;
  790. DWORD dwSerialNumSize = sizeof(serialNum);
  791. BOOL fGotSerialNumber = FALSE;
  792. //
  793. // Grab the serial number of the CF if we can
  794. //
  795. hr = GetStorageGlobals( &spStorageGlobals );
  796. if( SUCCEEDED( hr ) )
  797. {
  798. hr = spStorageGlobals->GetSerialNumber( &serialNum, abMacTemp );
  799. if( SUCCEEDED( hr ) )
  800. {
  801. fGotSerialNumber = TRUE;
  802. }
  803. hr = S_OK;
  804. }
  805. if( SUCCEEDED( hr ) )
  806. {
  807. memset( m_LyraKeystore, 0, sizeof(m_LyraKeystore) );
  808. if( fGotSerialNumber )
  809. {
  810. memcpy( m_LyraKeystore, serialNum.pID, min( sizeof(m_LyraKeystore), serialNum.SerialNumberLength ) );
  811. }
  812. else
  813. {
  814. memset( m_LyraKeystore, 32, 20 );
  815. }
  816. }
  817. if( SUCCEEDED( hr ) )
  818. {
  819. if( -1 == EncodeToLyra(8, m_LyraHeader, m_cUsedData, m_rgEncryptionData, m_LyraKeystore, CFDriveLetter ) )
  820. {
  821. hr = E_FAIL; // What to do here!!!
  822. }
  823. }
  824. if( SUCCEEDED( hr ) )
  825. {
  826. unsigned char headerWrite[26];
  827. for( int idxHeader = 0; idxHeader < sizeof(headerWrite); idxHeader++ )
  828. {
  829. headerWrite[idxHeader] = (unsigned char)((int)(m_LyraHeader[idxHeader]));
  830. }
  831. if( WriteFile( m_hFile, headerWrite, sizeof(headerWrite), &dwEncryptionWritten, NULL ) )
  832. {
  833. dwWritten += dwEncryptionWritten;
  834. FlushFileBuffers( m_hFile );
  835. }
  836. else
  837. {
  838. hr = HRESULT_FROM_WIN32( GetLastError() );
  839. }
  840. }
  841. if( SUCCEEDED( hr ) )
  842. {
  843. m_fCreatedHeader = TRUE;
  844. }
  845. }
  846. if( SUCCEEDED( hr ) )
  847. {
  848. if( m_fEncryptToMPX )
  849. {
  850. pDataWalk = pTmpData;
  851. while( SUCCEEDED( hr ) &&
  852. 0 != *pdwSize )
  853. {
  854. for( idxWalk = 0;
  855. m_cUsedData < sizeof(m_rgEncryptionData)/sizeof(m_rgEncryptionData[0])
  856. && idxWalk < *pdwSize; idxWalk++ )
  857. {
  858. m_rgEncryptionData[ m_cUsedData ] = *pDataWalk;
  859. m_cUsedData++;
  860. pDataWalk++;
  861. }
  862. *pdwSize -= idxWalk;
  863. if( 0 == *pdwSize )
  864. {
  865. break;
  866. }
  867. _ASSERTE( m_cUsedData == sizeof(m_rgEncryptionData)/sizeof(m_rgEncryptionData[0]) );
  868. cbSkipID3V2 = EncodeToLyra(98, m_LyraHeader, m_cUsedData, m_rgEncryptionData, m_LyraKeystore, CFDriveLetter );
  869. _ASSERTE( 0 != cbSkipID3V2 );
  870. if( -1 == cbSkipID3V2 )
  871. {
  872. hr = E_UNEXPECTED; // What to do here!!!
  873. }
  874. else
  875. {
  876. if( cbSkipID3V2 > 0 )
  877. {
  878. if( cbSkipID3V2 > LYRA_BUFFER_BLOCK_SIZE )
  879. {
  880. hr = E_INVALIDARG;
  881. }
  882. else
  883. {
  884. unsigned char blockWrite[LYRA_BUFFER_BLOCK_SIZE];
  885. for( idxWalk = 0; idxWalk < (DWORD)cbSkipID3V2; idxWalk++ )
  886. {
  887. blockWrite[idxWalk] = (unsigned char)((int)(m_rgEncryptionData[idxWalk]));
  888. }
  889. if( WriteFile( m_hFile, blockWrite, cbSkipID3V2, &dwEncryptionWritten, NULL ) )
  890. {
  891. _ASSERTE( (DWORD)cbSkipID3V2 == dwEncryptionWritten );
  892. memmove( m_rgEncryptionData,
  893. &m_rgEncryptionData[ cbSkipID3V2 ],
  894. sizeof(m_rgEncryptionData[0]) * (m_cUsedData - cbSkipID3V2 ) );
  895. m_cUsedData -= cbSkipID3V2;
  896. FlushFileBuffers( m_hFile );
  897. }
  898. else
  899. {
  900. hr = HRESULT_FROM_WIN32( GetLastError() );
  901. }
  902. }
  903. }
  904. else
  905. {
  906. cbSkipID3V2 = -1 * cbSkipID3V2;
  907. if( cbSkipID3V2 > LYRA_BUFFER_BLOCK_SIZE )
  908. {
  909. hr = E_INVALIDARG;
  910. }
  911. else
  912. {
  913. memmove( m_rgEncryptionData,
  914. &m_rgEncryptionData[ cbSkipID3V2 ],
  915. sizeof(m_rgEncryptionData[0]) * (m_cUsedData - cbSkipID3V2 ) );
  916. }
  917. }
  918. if( SUCCEEDED( hr ) )
  919. {
  920. dwWritten += cbSkipID3V2;
  921. }
  922. }
  923. }
  924. }
  925. else
  926. {
  927. if( WriteFile(m_hFile,pTmpData,*pdwSize,&dwWritten,NULL) )
  928. {
  929. FlushFileBuffers(m_hFile); // Flush data and wait until it is actually written
  930. hr = S_OK;
  931. }
  932. else
  933. {
  934. hr = HRESULT_FROM_WIN32(GetLastError());
  935. }
  936. }
  937. }
  938. *pdwSize = dwWritten;
  939. Error:
  940. hrLogDWORD("IMDSPObject::Write returned 0x%08lx", hr, hr);
  941. if( pTmpData )
  942. {
  943. delete [] pTmpData;
  944. }
  945. return hr;
  946. }
  947. STDMETHODIMP CMDSPStorage::Delete(UINT fuMode, IWMDMProgress *pProgress)
  948. {
  949. HRESULT hr=E_FAIL;
  950. BOOL bProgressStarted=FALSE;
  951. BOOL bBusyStatusSet=FALSE;
  952. DWORD dwStatus=NULL;
  953. if( pProgress )
  954. {
  955. CORg(pProgress->Begin(100));
  956. bProgressStarted=TRUE;
  957. }
  958. CFRg(g_pAppSCServer);
  959. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  960. {
  961. CORg(WMDM_E_NOTCERTIFIED);
  962. }
  963. CONEg(m_wcsName[0]);
  964. if ( m_hFile != INVALID_HANDLE_VALUE )
  965. {
  966. CloseHandle(m_hFile);
  967. m_hFile = INVALID_HANDLE_VALUE;
  968. }
  969. CHRg(GetGlobalDeviceStatus(m_wcsName, &dwStatus));
  970. if( dwStatus & WMDM_STATUS_BUSY )
  971. {
  972. hr=WMDM_E_BUSY;
  973. goto Error;
  974. }
  975. dwStatus |= (WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_DELETING );
  976. CHRg(SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE));
  977. bBusyStatusSet=TRUE;
  978. if( g_bIsWinNT )
  979. {
  980. if( fuMode & WMDM_MODE_RECURSIVE )
  981. {
  982. CORg(DeleteFileRecursiveW(m_wcsName));
  983. }
  984. else
  985. {
  986. if( FILE_ATTRIBUTE_DIRECTORY & GetFileAttributesW(m_wcsName) )
  987. {
  988. CWRg(RemoveDirectoryW(m_wcsName));
  989. }
  990. else
  991. {
  992. CWRg(DeleteFileW(m_wcsName));
  993. }
  994. }
  995. }
  996. else
  997. {
  998. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  999. if( fuMode & WMDM_MODE_RECURSIVE )
  1000. {
  1001. CORg(DeleteFileRecursiveA(m_szTmp));
  1002. }
  1003. else
  1004. {
  1005. if( FILE_ATTRIBUTE_DIRECTORY & GetFileAttributesA(m_szTmp) )
  1006. {
  1007. CWRg(RemoveDirectoryA(m_szTmp));
  1008. }
  1009. else
  1010. {
  1011. CWRg(DeleteFileA(m_szTmp));
  1012. }
  1013. }
  1014. }
  1015. hr=S_OK;
  1016. Error:
  1017. if( bBusyStatusSet )
  1018. {
  1019. dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_DELETING ));
  1020. SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE);
  1021. }
  1022. if( hr == S_OK )
  1023. {
  1024. m_wcsName[0]=NULL; // Nullify the storage name
  1025. }
  1026. if( bProgressStarted )
  1027. {
  1028. pProgress->Progress( 100 );
  1029. pProgress->End();
  1030. }
  1031. hrLogDWORD("IMDSPObject::Delete returned 0x%08lx", hr, hr);
  1032. return hr;
  1033. }
  1034. STDMETHODIMP CMDSPStorage::Seek(/*[in]*/ UINT fuFlags, /*[in]*/ DWORD dwOffset)
  1035. {
  1036. HRESULT hr=S_OK;
  1037. CFRg(g_pAppSCServer);
  1038. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1039. {
  1040. CORg(WMDM_E_NOTCERTIFIED);
  1041. }
  1042. CONEg(m_wcsName[0]);
  1043. CFRg( m_hFile != INVALID_HANDLE_VALUE );
  1044. DWORD dwMoveMethod;
  1045. switch (fuFlags)
  1046. {
  1047. case MDSP_SEEK_BOF:
  1048. dwMoveMethod = FILE_BEGIN;
  1049. break;
  1050. case MDSP_SEEK_CUR:
  1051. dwMoveMethod = FILE_CURRENT;
  1052. break;
  1053. case MDSP_SEEK_EOF:
  1054. dwMoveMethod = FILE_END;
  1055. break;
  1056. default:
  1057. return E_INVALIDARG;
  1058. }
  1059. CWRg( (DWORD)0xFFFFFFFF != SetFilePointer(m_hFile, dwOffset, NULL, dwMoveMethod ) );
  1060. Error:
  1061. hrLogDWORD("IMDSPObject::Seek returned 0x%08lx", hr, hr);
  1062. return hr;
  1063. }
  1064. STDMETHODIMP CMDSPStorage::Rename(/*[in]*/ LPWSTR pwszNewName, IWMDMProgress *pProgress)
  1065. {
  1066. HRESULT hr;
  1067. BOOL bProgressStarted=FALSE;
  1068. BOOL bBusyStatusSet=FALSE;
  1069. DWORD dwStatus;
  1070. WCHAR *pSlash;
  1071. WCHAR *wcsNewFullPath=NULL;
  1072. LPWSTR pszMP3 = NULL;
  1073. if( pProgress )
  1074. {
  1075. CORg(pProgress->Begin(100));
  1076. bProgressStarted=TRUE;
  1077. }
  1078. CFRg(g_pAppSCServer);
  1079. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1080. {
  1081. CORg(WMDM_E_NOTCERTIFIED);
  1082. }
  1083. CARg(pwszNewName);
  1084. CONEg(m_wcsName[0]);
  1085. CFRg(wcslen(m_wcsName)>3); // cannot rename a root storage
  1086. if ( m_hFile != INVALID_HANDLE_VALUE )
  1087. {
  1088. CloseHandle(m_hFile);
  1089. m_hFile = INVALID_HANDLE_VALUE;
  1090. }
  1091. CHRg(GetGlobalDeviceStatus(m_wcsName, &dwStatus));
  1092. if( dwStatus & WMDM_STATUS_BUSY )
  1093. {
  1094. hr=WMDM_E_BUSY;
  1095. goto Error;
  1096. }
  1097. dwStatus |= (WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING );
  1098. CHRg(SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE));
  1099. bBusyStatusSet = TRUE;
  1100. //
  1101. // Because WMP7.0 will rename file names to track titles, we have to change .mp3 to .mpx here as well
  1102. //
  1103. pszMP3 = wcsrchr( pwszNewName, L'.');
  1104. if( NULL != pszMP3 && 0 == wcsicmp( pszMP3, L".mp3" ) )
  1105. {
  1106. *(pszMP3 + 3) = L'x';
  1107. }
  1108. wcsNewFullPath = new WCHAR [wcslen(m_wcsName)+wcslen(pwszNewName)+2];
  1109. CPRg(wcsNewFullPath);
  1110. wcscpy(wcsNewFullPath, m_wcsName);
  1111. if( wcsNewFullPath[wcslen(wcsNewFullPath)-1] == 0x5c )
  1112. {
  1113. wcsNewFullPath[wcslen(wcsNewFullPath)-1] = 0; // trim last slash
  1114. }
  1115. pSlash=wcsrchr(wcsNewFullPath, 0x5c);
  1116. CFRg(pSlash);
  1117. *(pSlash+1)=0;
  1118. pSlash=wcsrchr(pwszNewName, 0x5c);
  1119. if( pSlash )
  1120. {
  1121. wcscat(wcsNewFullPath, pSlash+1);
  1122. }
  1123. else
  1124. {
  1125. wcscat(wcsNewFullPath, pwszNewName);
  1126. }
  1127. // Now move
  1128. CWRg( UtilMoveFileW(m_wcsName, wcsNewFullPath));
  1129. wcscpy(m_wcsName, wcsNewFullPath);
  1130. hr=S_OK;
  1131. Error:
  1132. if( bBusyStatusSet )
  1133. {
  1134. dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING ));
  1135. SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE);
  1136. }
  1137. if( bProgressStarted )
  1138. {
  1139. pProgress->Progress( 100 );
  1140. pProgress->End();
  1141. }
  1142. if(wcsNewFullPath)
  1143. {
  1144. delete [] wcsNewFullPath;
  1145. }
  1146. hrLogDWORD("IMDSPObject::Rename returned 0x%08lx", hr, hr);
  1147. return hr;
  1148. }
  1149. STDMETHODIMP CMDSPStorage::EnumStorage(IMDSPEnumStorage * * ppEnumStorage)
  1150. {
  1151. HRESULT hr;
  1152. CFRg(g_pAppSCServer);
  1153. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1154. {
  1155. CORg(WMDM_E_NOTCERTIFIED);
  1156. }
  1157. CARg(ppEnumStorage);
  1158. CONEg(m_wcsName[0]);
  1159. DWORD dwAttrib;
  1160. CORg(GetAttributes(&dwAttrib, NULL));
  1161. if( dwAttrib & WMDM_FILE_ATTR_FILE )
  1162. {
  1163. return WMDM_E_NOTSUPPORTED;
  1164. }
  1165. CComObject<CMDSPEnumStorage> *pEnumObj;
  1166. CORg(CComObject<CMDSPEnumStorage>::CreateInstance(&pEnumObj));
  1167. hr=pEnumObj->QueryInterface(IID_IMDSPEnumStorage, reinterpret_cast<void**>(ppEnumStorage));
  1168. if( FAILED(hr) )
  1169. {
  1170. delete pEnumObj;
  1171. }
  1172. else
  1173. {
  1174. wcscpy(pEnumObj->m_wcsPath, m_wcsName);
  1175. }
  1176. Error:
  1177. hrLogDWORD("IMDSPStorage::EnumStorage returned 0x%08lx", hr, hr);
  1178. return hr;
  1179. }
  1180. STDMETHODIMP CMDSPStorage::Close()
  1181. {
  1182. HRESULT hr=S_OK;
  1183. CFRg(g_pAppSCServer);
  1184. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1185. {
  1186. CORg(WMDM_E_NOTCERTIFIED);
  1187. }
  1188. CONEg(m_wcsName[0]);
  1189. if( m_hFile != INVALID_HANDLE_VALUE )
  1190. {
  1191. if( 0 != m_cUsedData && m_fEncryptToMPX )
  1192. {
  1193. char CFDriveLetter[1];
  1194. unsigned char blockWrite[LYRA_BUFFER_BLOCK_SIZE];
  1195. DWORD cbSkipID3V2 = EncodeToLyra(98, m_LyraHeader, m_cUsedData, m_rgEncryptionData, m_LyraKeystore, CFDriveLetter );
  1196. DWORD dwWritten;
  1197. if( cbSkipID3V2 > 0 )
  1198. {
  1199. if( cbSkipID3V2 > LYRA_BUFFER_BLOCK_SIZE )
  1200. {
  1201. hr = E_INVALIDARG;
  1202. }
  1203. else
  1204. {
  1205. for( DWORD idxWalk = 0; idxWalk < (DWORD)cbSkipID3V2; idxWalk++ )
  1206. {
  1207. blockWrite[idxWalk] = (unsigned char)((int)(m_rgEncryptionData[idxWalk]));
  1208. }
  1209. WriteFile( m_hFile, blockWrite, cbSkipID3V2, &dwWritten, NULL );
  1210. }
  1211. }
  1212. }
  1213. CloseHandle(m_hFile);
  1214. m_hFile=INVALID_HANDLE_VALUE;
  1215. }
  1216. Error:
  1217. hrLogDWORD("IMDSPObject::Close returned 0x%08lx", hr, hr);
  1218. return hr;
  1219. }
  1220. DWORD MoveFunc( void *args )
  1221. {
  1222. HRESULT hr=S_OK;
  1223. MOVETHREADARGS *pCMArgs;
  1224. WCHAR *pWcs;
  1225. pCMArgs = (MOVETHREADARGS *)args;
  1226. if( pCMArgs->bNewThread )
  1227. {
  1228. CORg(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
  1229. if( pCMArgs->pProgress )
  1230. {
  1231. CORg(CoGetInterfaceAndReleaseStream(pCMArgs->pStream,
  1232. IID_IWMDMProgress, (LPVOID *)&(pCMArgs->pProgress)));
  1233. }
  1234. }
  1235. pWcs = wcsrchr(pCMArgs->wcsSrc, 0x5c);
  1236. if(!pWcs)
  1237. {
  1238. hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  1239. goto Error;
  1240. }
  1241. if( pCMArgs->wcsDst[wcslen(pCMArgs->wcsDst)-1] != 0x5c )
  1242. {
  1243. wcscat(pCMArgs->wcsDst,g_wcsBackslash);
  1244. }
  1245. wcscat(pCMArgs->wcsDst, pWcs+1);
  1246. CWRg( UtilMoveFileW(pCMArgs->wcsSrc,pCMArgs->wcsDst) );
  1247. // Substitute current object name with the moved one
  1248. wcscpy(pCMArgs->pThis->m_wcsName, pCMArgs->wcsDst);
  1249. hr=S_OK;
  1250. Error:
  1251. if( pCMArgs->bNewThread )
  1252. {
  1253. // Reset status, we've got here we must have set the status busy before
  1254. pCMArgs->dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING));
  1255. SetGlobalDeviceStatus(pCMArgs->wcsSrc, pCMArgs->dwStatus, TRUE);
  1256. // Reset progress, we've got here we must have set the progress before
  1257. if( pCMArgs->pProgress )
  1258. {
  1259. pCMArgs->pProgress->Progress(100);
  1260. pCMArgs->pProgress->End();
  1261. pCMArgs->pProgress->Release(); // since we did AddRef to get here
  1262. }
  1263. if( pCMArgs )
  1264. {
  1265. delete pCMArgs;
  1266. }
  1267. CoUninitialize();
  1268. }
  1269. return hr;
  1270. }
  1271. STDMETHODIMP CMDSPStorage::Move(UINT fuMode, IWMDMProgress *pProgress,
  1272. IMDSPStorage *pTarget)
  1273. {
  1274. HRESULT hr=E_FAIL;
  1275. WCHAR *wcsSrc=NULL;
  1276. WCHAR *wcsDst=NULL;
  1277. WCHAR *pWcs=NULL;
  1278. CMDSPStorage *pStg =NULL;
  1279. MOVETHREADARGS *pMoveArgs=NULL;
  1280. DWORD dwThreadID;
  1281. DWORD dwStatus=NULL;
  1282. BOOL bProgStarted=FALSE;
  1283. BOOL bBusyStatusSet=FALSE;
  1284. BOOL bThreadFailed=TRUE;
  1285. BOOL bAddRefed=FALSE;
  1286. // Start the progress
  1287. if( pProgress )
  1288. {
  1289. CORg(pProgress->Begin(100));
  1290. bProgStarted=TRUE;
  1291. }
  1292. CFRg(g_pAppSCServer);
  1293. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1294. {
  1295. CORg(WMDM_E_NOTCERTIFIED);
  1296. }
  1297. CONEg(m_wcsName[0]);
  1298. CHRg(GetGlobalDeviceStatus(m_wcsName, &dwStatus));
  1299. if( dwStatus & WMDM_STATUS_BUSY )
  1300. {
  1301. hr=WMDM_E_BUSY;
  1302. goto Error;
  1303. }
  1304. pMoveArgs = new MOVETHREADARGS;
  1305. CPRg(pMoveArgs);
  1306. ZeroMemory(pMoveArgs, sizeof(MOVETHREADARGS));
  1307. dwStatus |= (WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING );
  1308. CHRg(SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE));
  1309. bBusyStatusSet=TRUE;
  1310. // setup MoveArgs for MoveFunc
  1311. pMoveArgs->dwStatus = dwStatus;
  1312. CARg(pTarget);
  1313. pStg = (CMDSPStorage *)pTarget;
  1314. wcsSrc = (WCHAR *)&(pMoveArgs->wcsSrc[0]);
  1315. CPRg(wcsSrc);
  1316. wcsDst = (WCHAR *)&(pMoveArgs->wcsDst[0]);
  1317. CPRg(wcsDst);
  1318. // Make sure the source and destination are on the same device
  1319. wcsParseDeviceName(m_wcsName, &wcsSrc);
  1320. wcsParseDeviceName(pStg->m_wcsName, &wcsDst);
  1321. if( wcscmp(wcsSrc, wcsDst) )
  1322. {
  1323. hr = WMDM_E_NOTSUPPORTED; // do not support move out of the same device
  1324. goto Error;
  1325. }
  1326. // Now check for target's attributes
  1327. DWORD dwDstAttrib;
  1328. wcscpy(wcsSrc, m_wcsName);
  1329. wcscpy(wcsDst, pStg->m_wcsName);
  1330. if ( fuMode & WMDM_STORAGECONTROL_INSERTINTO )
  1331. {
  1332. CHRg(pTarget->GetAttributes(&dwDstAttrib, NULL));
  1333. CARg( dwDstAttrib & WMDM_FILE_ATTR_FOLDER ); // INSERTINFO must be to a folder
  1334. }
  1335. else
  1336. {
  1337. // Get the folder one level up
  1338. pWcs = wcsrchr(wcsDst, 0x5c);
  1339. CFRg(pWcs);
  1340. *pWcs=NULL;
  1341. CFRg( FILE_ATTRIBUTE_DIRECTORY & UtilGetFileAttributesW(wcsDst) ); // Normally shouldn't fail here
  1342. }
  1343. pMoveArgs->pThis = this;
  1344. pMoveArgs->bNewThread =(fuMode & WMDM_MODE_THREAD)?TRUE:FALSE;
  1345. // Now handle Progress marshaling
  1346. if( pProgress )
  1347. {
  1348. pMoveArgs->pProgress = pProgress;
  1349. pProgress->AddRef(); // since we are going to use it in MoveFunc()
  1350. bAddRefed=TRUE;
  1351. if( pMoveArgs->bNewThread )
  1352. {
  1353. CORg(CoMarshalInterThreadInterfaceInStream(
  1354. IID_IWMDMProgress, (LPUNKNOWN)pProgress,
  1355. (LPSTREAM *)&(pMoveArgs->pStream)));
  1356. }
  1357. }
  1358. if ( m_hFile != INVALID_HANDLE_VALUE )
  1359. {
  1360. CloseHandle(m_hFile);
  1361. m_hFile = INVALID_HANDLE_VALUE;
  1362. }
  1363. if( fuMode & WMDM_MODE_BLOCK )
  1364. {
  1365. hr = MoveFunc((void *)pMoveArgs);
  1366. }
  1367. else if ( fuMode & WMDM_MODE_THREAD )
  1368. {
  1369. if( CreateThread(
  1370. NULL,
  1371. 0,
  1372. (LPTHREAD_START_ROUTINE)MoveFunc,
  1373. (void *)pMoveArgs,
  1374. 0,
  1375. &dwThreadID
  1376. )
  1377. )
  1378. {
  1379. bThreadFailed=FALSE;
  1380. hr=S_OK;
  1381. }
  1382. else
  1383. {
  1384. hr=HRESULT_FROM_WIN32(GetLastError());
  1385. }
  1386. } else
  1387. hr = E_INVALIDARG;
  1388. Error:
  1389. if( (fuMode&WMDM_MODE_BLOCK) || bThreadFailed ) // otherwise these will be in MoveFunc()
  1390. {
  1391. if( bBusyStatusSet )
  1392. {
  1393. dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING));
  1394. SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE);
  1395. }
  1396. if( bProgStarted )
  1397. {
  1398. pProgress->Progress(100);
  1399. pProgress->End();
  1400. }
  1401. if( bAddRefed )
  1402. {
  1403. pProgress->Release(); // since we called AddRef before calling MoveFunc()
  1404. }
  1405. if( pMoveArgs )
  1406. {
  1407. delete pMoveArgs;
  1408. }
  1409. }
  1410. return hr /*WMDM_E_NOTSUPPORTED*/;
  1411. }