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.

1857 lines
41 KiB

  1. //
  2. // Microsoft Windows Media Technologies
  3. // Copyright (C) Microsoft Corporation, 1999 - 2001. All rights reserved.
  4. //
  5. // MSHDSP.DLL is a sample WMDM Service Provider(SP) that enumerates fixed drives.
  6. // This sample shows you how to implement an SP according to the WMDM documentation.
  7. // This sample uses fixed drives on your PC to emulate portable media, and
  8. // shows the relationship between different interfaces and objects. Each hard disk
  9. // volume is enumerated as a device and directories and files are enumerated as
  10. // Storage objects under respective devices. You can copy non-SDMI compliant content
  11. // to any device that this SP enumerates. To copy an SDMI compliant content to a
  12. // device, the device must be able to report a hardware embedded serial number.
  13. // Hard disks do not have such serial numbers.
  14. //
  15. // To build this SP, you are recommended to use the MSHDSP.DSP file under Microsoft
  16. // Visual C++ 6.0 and run REGSVR32.EXE to register the resulting MSHDSP.DLL. You can
  17. // then build the sample application from the WMDMAPP directory to see how it gets
  18. // loaded by the application. However, you need to obtain a certificate from
  19. // Microsoft to actually run this SP. This certificate would be in the KEY.C file
  20. // under the INCLUDE directory for one level up.
  21. // MDSPStorage.cpp : Implementation of CMDSPStorage
  22. #include "hdspPCH.h"
  23. #include "wmsstd.h"
  24. #define STRSAFE_NO_DEPRECATE
  25. #include "strsafe.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. }
  52. CMDSPStorage::~CMDSPStorage()
  53. {
  54. if( m_hFile != INVALID_HANDLE_VALUE )
  55. {
  56. CloseHandle(m_hFile);
  57. }
  58. }
  59. STDMETHODIMP CMDSPStorage::GetStorageGlobals(IMDSPStorageGlobals **ppStorageGlobals)
  60. {
  61. HRESULT hr;
  62. int i;
  63. BOOL bLocked = 0;
  64. CFRg(g_pAppSCServer);
  65. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  66. {
  67. CORg(WMDM_E_NOTCERTIFIED);
  68. }
  69. g_CriticalSection.Lock();
  70. bLocked = 1;
  71. CARg(ppStorageGlobals);
  72. CONEg(m_wcsName[0]);
  73. WCHAR devName[MAX_PATH], *pW;
  74. pW = &devName[0];
  75. hr = wcsParseDeviceName(m_wcsName, pW, ARRAYSIZE(devName));
  76. if (FAILED(hr))
  77. {
  78. goto Error;
  79. }
  80. for(i=0; i<MDSP_MAX_DEVICE_OBJ;i++)
  81. {
  82. if( !wcscmp(g_GlobalDeviceInfo[i].wcsDevName, devName) )
  83. {
  84. break;
  85. }
  86. }
  87. if( i<MDSP_MAX_DEVICE_OBJ && g_GlobalDeviceInfo[i].pIMDSPStorageGlobals ) // found match
  88. {
  89. *ppStorageGlobals = (IMDSPStorageGlobals *)g_GlobalDeviceInfo[i].pIMDSPStorageGlobals;
  90. ((IMDSPStorageGlobals *)g_GlobalDeviceInfo[i].pIMDSPStorageGlobals)->AddRef();
  91. hr = S_OK;
  92. }
  93. else
  94. { // new entry in the global array
  95. if(!(i<MDSP_MAX_DEVICE_OBJ) ) // no match found
  96. {
  97. for(i=0; i<MDSP_MAX_DEVICE_OBJ;i++)
  98. {
  99. if( !g_GlobalDeviceInfo[i].bValid )
  100. {
  101. break;
  102. }
  103. }
  104. }
  105. CPRg(i<MDSP_MAX_DEVICE_OBJ);
  106. CComObject<CMDSPStorageGlobals> *pObj;
  107. CORg(CComObject<CMDSPStorageGlobals>::CreateInstance(&pObj));
  108. hr = pObj->QueryInterface(
  109. IID_IMDSPStorageGlobals,
  110. reinterpret_cast<void**>(&g_GlobalDeviceInfo[i].pIMDSPStorageGlobals)
  111. );
  112. if( FAILED(hr) )
  113. {
  114. delete pObj;
  115. }
  116. else
  117. {
  118. HRESULT hrTemp;
  119. // wcscpy(pObj->m_wcsName, devName);
  120. hrTemp = StringCchCopyW(pObj->m_wcsName, ARRAYSIZE(pObj->m_wcsName), devName);
  121. if (FAILED(hrTemp))
  122. {
  123. ((IUnknown*) (g_GlobalDeviceInfo[i].pIMDSPStorageGlobals))->Release();
  124. g_GlobalDeviceInfo[i].pIMDSPStorageGlobals = NULL;
  125. hr = hrTemp;
  126. goto Error;
  127. }
  128. // wcscpy(g_GlobalDeviceInfo[i].wcsDevName, devName);
  129. hrTemp = StringCchCopyW(g_GlobalDeviceInfo[i].wcsDevName,
  130. ARRAYSIZE(g_GlobalDeviceInfo[i].wcsDevName), devName);
  131. if (FAILED(hrTemp))
  132. {
  133. ((IUnknown*) (g_GlobalDeviceInfo[i].pIMDSPStorageGlobals))->Release();
  134. g_GlobalDeviceInfo[i].pIMDSPStorageGlobals = NULL;
  135. g_GlobalDeviceInfo[i].wcsDevName[0] = 0;
  136. hr = hrTemp;
  137. goto Error;
  138. }
  139. *ppStorageGlobals = (IMDSPStorageGlobals *)g_GlobalDeviceInfo[i].pIMDSPStorageGlobals;
  140. g_GlobalDeviceInfo[i].bValid=TRUE;
  141. g_GlobalDeviceInfo[i].dwStatus = 0;
  142. } // end of else
  143. } // end of else
  144. Error:
  145. if (bLocked)
  146. {
  147. g_CriticalSection.Unlock();
  148. }
  149. hrLogDWORD("IMSDPStorage::GetStorageGlobals returned 0x%08lx", hr, hr);
  150. return hr;
  151. }
  152. STDMETHODIMP CMDSPStorage::SetAttributes(DWORD dwAttributes, _WAVEFORMATEX *pFormat)
  153. {
  154. HRESULT hr = E_FAIL;
  155. DWORD dwAttrib;
  156. CFRg(g_pAppSCServer);
  157. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  158. {
  159. CORg(WMDM_E_NOTCERTIFIED);
  160. }
  161. CONEg(m_wcsName[0]);
  162. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  163. dwAttrib = GetFileAttributesA(m_szTmp);
  164. if( dwAttrib == (DWORD)0xFFFFFFFF )
  165. {
  166. return E_FAIL;
  167. }
  168. if( (dwAttributes & WMDM_FILE_ATTR_READONLY) )
  169. {
  170. dwAttrib |= FILE_ATTRIBUTE_READONLY;
  171. }
  172. if( (dwAttributes & WMDM_FILE_ATTR_HIDDEN) )
  173. {
  174. dwAttrib |= FILE_ATTRIBUTE_HIDDEN;
  175. }
  176. if( (dwAttributes & WMDM_FILE_ATTR_SYSTEM) )
  177. {
  178. dwAttrib |= FILE_ATTRIBUTE_SYSTEM;
  179. }
  180. CWRg(SetFileAttributesA(m_szTmp, dwAttrib));
  181. hr = S_OK;
  182. Error:
  183. hrLogDWORD("IMSDPStorage::SetAttributes returned 0x%08lx", hr, hr);
  184. return hr;
  185. }
  186. HRESULT QuerySubFoldersAndFiles(LPCSTR szCurrentFolder, DWORD *pdwAttr)
  187. {
  188. HRESULT hr = E_FAIL;
  189. LPSTR szName = NULL;
  190. int len;
  191. WIN32_FIND_DATAA fd;
  192. int nErrorEnd=0;
  193. HANDLE hFFile = INVALID_HANDLE_VALUE;
  194. DWORD dwAttrib;
  195. CARg(szCurrentFolder);
  196. CARg(pdwAttr);
  197. len = strlen(szCurrentFolder);
  198. CARg(len>2);
  199. szName = new char [len+BACKSLASH_SZ_STRING_LENGTH+MAX_PATH];
  200. CPRg(szName);
  201. strcpy(szName, szCurrentFolder);
  202. if( szName[strlen(szName)-1] != 0x5c )
  203. {
  204. strcat(szName, g_szBackslash);
  205. }
  206. strcat(szName, "*");
  207. while( !nErrorEnd )
  208. {
  209. if( hFFile == INVALID_HANDLE_VALUE )
  210. {
  211. hFFile = FindFirstFileA(szName, &fd);
  212. if( hFFile == INVALID_HANDLE_VALUE )
  213. {
  214. nErrorEnd = 1;
  215. }
  216. }
  217. else
  218. {
  219. if( !FindNextFileA(hFFile, &fd) )
  220. {
  221. nErrorEnd = 1;
  222. }
  223. }
  224. if ( !nErrorEnd && hFFile != INVALID_HANDLE_VALUE )
  225. {
  226. if( !strcmp(fd.cFileName, ".") || !strcmp(fd.cFileName, "..") )
  227. {
  228. continue;
  229. }
  230. else
  231. {
  232. strcpy(szName, szCurrentFolder);
  233. if( szName[strlen(szName)-1] != 0x5c ) strcat(szName, g_szBackslash);
  234. strcat(szName, fd.cFileName);
  235. dwAttrib = GetFileAttributesA(szName);
  236. if( dwAttrib & FILE_ATTRIBUTE_DIRECTORY )
  237. {
  238. *pdwAttr |= WMDM_STORAGE_ATTR_HAS_FOLDERS;
  239. }
  240. else
  241. {
  242. *pdwAttr |= WMDM_STORAGE_ATTR_HAS_FILES;
  243. }
  244. if( (*pdwAttr & WMDM_STORAGE_ATTR_HAS_FOLDERS) &&
  245. (*pdwAttr & WMDM_STORAGE_ATTR_HAS_FILES ) )
  246. {
  247. break; // No need to continue since we found both
  248. }
  249. }
  250. } // End of If
  251. } // End of while
  252. hr = S_OK;
  253. Error:
  254. if( hFFile != INVALID_HANDLE_VALUE )
  255. {
  256. FindClose(hFFile);
  257. }
  258. if( szName )
  259. {
  260. delete [] szName;
  261. }
  262. return hr; // If FAILED(hr), sorry, can't do it.
  263. }
  264. STDMETHODIMP CMDSPStorage::GetAttributes(DWORD * pdwAttributes, _WAVEFORMATEX * pFormat)
  265. {
  266. HRESULT hr = S_OK;
  267. DWORD dwAttrib;
  268. CFRg(g_pAppSCServer);
  269. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  270. {
  271. CORg(WMDM_E_NOTCERTIFIED);
  272. }
  273. CARg(pdwAttributes);
  274. CONEg(m_wcsName[0]);
  275. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  276. dwAttrib = GetFileAttributesA(m_szTmp);
  277. if( dwAttrib == (DWORD)0xFFFFFFFF )
  278. {
  279. return E_FAIL;
  280. }
  281. *pdwAttributes = WMDM_STORAGE_ATTR_REMOVABLE |
  282. WMDM_STORAGE_ATTR_FOLDERS |
  283. WMDM_FILE_ATTR_CANREAD;
  284. if( !(dwAttrib & FILE_ATTRIBUTE_READONLY) )
  285. {
  286. *pdwAttributes |= WMDM_FILE_ATTR_CANDELETE |
  287. WMDM_FILE_ATTR_CANMOVE |
  288. WMDM_FILE_ATTR_CANRENAME;
  289. }
  290. if( dwAttrib & FILE_ATTRIBUTE_DIRECTORY )
  291. {
  292. *pdwAttributes |= WMDM_FILE_ATTR_FOLDER;
  293. QuerySubFoldersAndFiles(m_szTmp, pdwAttributes); // No failure check, if failed, just keep current attributes
  294. }
  295. else
  296. {
  297. *pdwAttributes |= WMDM_FILE_ATTR_FILE;
  298. }
  299. // Now handle Hidden, ReadOnly, and System attributes
  300. if( (dwAttrib & FILE_ATTRIBUTE_READONLY) )
  301. {
  302. *pdwAttributes |= WMDM_FILE_ATTR_READONLY;
  303. }
  304. if( (dwAttrib & FILE_ATTRIBUTE_HIDDEN) )
  305. {
  306. *pdwAttributes |= WMDM_FILE_ATTR_HIDDEN;
  307. }
  308. if( (dwAttrib & FILE_ATTRIBUTE_SYSTEM) )
  309. {
  310. *pdwAttributes |= WMDM_FILE_ATTR_SYSTEM;
  311. }
  312. Error:
  313. hrLogDWORD("IMSDPStorage::GetAttributes returned 0x%08lx", hr, hr);
  314. return hr;
  315. }
  316. STDMETHODIMP CMDSPStorage::GetName(LPWSTR pwszName, UINT nMaxChars)
  317. {
  318. HRESULT hr = S_OK;
  319. CFRg(g_pAppSCServer);
  320. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  321. {
  322. CORg(WMDM_E_NOTCERTIFIED);
  323. }
  324. CONEg(m_wcsName[0]);
  325. CARg(pwszName);
  326. CPRg(wcslen(m_wcsName)<nMaxChars);
  327. if( m_wcsName[wcslen(m_wcsName)-1] == 0x5c ) // this is root storage
  328. {
  329. wcscpy(pwszName, wcsrchr(m_wcsName, 0x5c));
  330. }
  331. else
  332. {
  333. wcscpy(pwszName, wcsrchr(m_wcsName, 0x5c)+1);
  334. }
  335. Error:
  336. hrLogDWORD("IMSDPStorage::GetName returned 0x%08lx", hr, hr);
  337. return hr;
  338. }
  339. STDMETHODIMP CMDSPStorage::GetDate(PWMDMDATETIME pDateTimeUTC)
  340. {
  341. HRESULT hr = E_FAIL;
  342. HANDLE hFFile = INVALID_HANDLE_VALUE;
  343. WIN32_FIND_DATA wfd;
  344. SYSTEMTIME sysTime;
  345. CFRg(g_pAppSCServer);
  346. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  347. {
  348. CORg(WMDM_E_NOTCERTIFIED);
  349. }
  350. CARg(pDateTimeUTC);
  351. CONEg(m_wcsName[0]);
  352. CWRg(WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL));
  353. DWORD curAttr = GetFileAttributesA(m_szTmp);
  354. if (curAttr == INVALID_FILE_ATTRIBUTES)
  355. {
  356. hr = HRESULT_FROM_WIN32(GetLastError());
  357. goto Error;
  358. }
  359. if( FILE_ATTRIBUTE_DIRECTORY & curAttr )
  360. {
  361. DWORD dwLen = strlen(m_szTmp)-1;
  362. if( m_szTmp[dwLen-1] != 0x5c )
  363. {
  364. if (dwLen > ARRAYSIZE(m_szTmp) - 3)
  365. {
  366. hr = STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  367. goto Error;
  368. }
  369. else
  370. {
  371. strcat(m_szTmp, g_szBackslash);
  372. }
  373. }
  374. else
  375. {
  376. if (dwLen > ARRAYSIZE(m_szTmp) - 2)
  377. {
  378. hr = STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  379. goto Error;
  380. }
  381. }
  382. strcat(m_szTmp, ".");
  383. }
  384. hFFile = FindFirstFile(m_szTmp, &wfd);
  385. CWRg(hFFile != INVALID_HANDLE_VALUE);
  386. CFRg(FileTimeToSystemTime((CONST FILETIME *)&wfd.ftLastWriteTime, &sysTime));
  387. pDateTimeUTC->wYear = sysTime.wYear;
  388. pDateTimeUTC->wMonth = sysTime.wMonth;
  389. pDateTimeUTC->wDay = sysTime.wDay;
  390. pDateTimeUTC->wHour = sysTime.wHour;
  391. pDateTimeUTC->wMinute = sysTime.wMinute;
  392. pDateTimeUTC->wSecond = sysTime.wSecond;
  393. hr = S_OK;
  394. Error:
  395. if(hFFile != INVALID_HANDLE_VALUE)
  396. {
  397. FindClose(hFFile);
  398. }
  399. hrLogDWORD("IMSDPStorage::GetDate returned 0x%08lx", hr, hr);
  400. return hr;
  401. }
  402. STDMETHODIMP CMDSPStorage::GetSize(DWORD * pdwSizeLow, DWORD * pdwSizeHigh)
  403. {
  404. HRESULT hr = S_OK;
  405. HANDLE hFile = INVALID_HANDLE_VALUE;
  406. DWORD dwLS;
  407. DWORD dwHS;
  408. CFRg(g_pAppSCServer);
  409. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  410. {
  411. CORg(WMDM_E_NOTCERTIFIED);
  412. }
  413. CARg(pdwSizeLow);
  414. CONEg(m_wcsName[0]);
  415. CWRg(WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL));
  416. dwLS = 0;
  417. dwHS = 0;
  418. DWORD curAttr = GetFileAttributesA(m_szTmp);
  419. if (curAttr == INVALID_FILE_ATTRIBUTES)
  420. {
  421. hr = HRESULT_FROM_WIN32(GetLastError());
  422. goto Error;
  423. }
  424. if( FILE_ATTRIBUTE_DIRECTORY & curAttr )
  425. {
  426. *pdwSizeLow = 0;
  427. *pdwSizeHigh = 0;
  428. }
  429. else
  430. {
  431. CORg(GetFileSizeRecursive(m_szTmp, &dwLS, &dwHS));
  432. *pdwSizeLow = dwLS;
  433. if(pdwSizeHigh)
  434. {
  435. *pdwSizeHigh = dwHS;
  436. }
  437. }
  438. hr = S_OK;
  439. Error:
  440. hrLogDWORD("IMSDPStorage::GetSize returned 0x%08lx", hr, hr);
  441. return hr;
  442. }
  443. STDMETHODIMP CMDSPStorage::GetRights(PWMDMRIGHTS *ppRights,UINT *pnRightsCount,
  444. BYTE abMac[WMDM_MAC_LENGTH])
  445. {
  446. HRESULT hr;
  447. CFRg(g_pAppSCServer);
  448. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  449. {
  450. CORg(WMDM_E_NOTCERTIFIED);
  451. }
  452. CORg(WMDM_E_NOTSUPPORTED);
  453. Error:
  454. hrLogDWORD("IMSDPStorage::GetRights returned 0x%08lx", hr, hr);
  455. return hr;
  456. }
  457. STDMETHODIMP CMDSPStorage::CreateStorage(DWORD dwAttributes, _WAVEFORMATEX * pFormat, LPWSTR pwszName, IMDSPStorage * * ppNewStorage)
  458. {
  459. HRESULT hr = E_FAIL;
  460. HANDLE hFile;
  461. CHAR *psz;
  462. CHAR szNew[MAX_PATH];
  463. DWORD curAttr = 0;
  464. DWORD fsAttrib = FILE_ATTRIBUTE_NORMAL;
  465. CFRg(g_pAppSCServer);
  466. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  467. {
  468. CORg(WMDM_E_NOTCERTIFIED);
  469. }
  470. CONEg(m_wcsName[0]);
  471. CARg(pwszName);
  472. CARg(ppNewStorage);
  473. CWRg(WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL));
  474. if( m_szTmp[strlen(m_szTmp)-1] == 0x5c )
  475. {
  476. m_szTmp[strlen(m_szTmp)-1] = NULL; // trim the last backslash;
  477. }
  478. curAttr = GetFileAttributesA(m_szTmp);
  479. if (curAttr == INVALID_FILE_ATTRIBUTES)
  480. {
  481. hr = HRESULT_FROM_WIN32(GetLastError());
  482. goto Error;
  483. }
  484. if( !(curAttr & FILE_ATTRIBUTE_DIRECTORY ) ) // if current storage is a file
  485. {
  486. if( dwAttributes & WMDM_STORAGECONTROL_INSERTINTO )
  487. {
  488. CORg(WMDM_E_NOTSUPPORTED); // can't do InsertInto
  489. }
  490. else
  491. { // for file, the default is Before&After
  492. psz = strrchr(m_szTmp, g_szBackslash[0]);
  493. CFRg(psz);
  494. }
  495. }
  496. else
  497. { // current storage is a dir
  498. if( (dwAttributes & WMDM_STORAGECONTROL_INSERTBEFORE) ||
  499. (dwAttributes & WMDM_STORAGECONTROL_INSERTAFTER) ) // before or after
  500. {
  501. psz=strrchr(m_szTmp, g_szBackslash[0]);
  502. CFRg(psz);
  503. }
  504. else
  505. { // for dir, the default is InsertInto
  506. psz=m_szTmp+strlen(m_szTmp);
  507. }
  508. }
  509. CWRg(WideCharToMultiByte(CP_ACP, NULL, pwszName, -1, szNew, MAX_PATH, NULL, NULL));
  510. // strcpy(psz, g_szBackslash);
  511. HRESULT hrTemp = StringCchCopyA(psz, ARRAYSIZE(m_szTmp) - (psz - m_szTmp), g_szBackslash);
  512. if (FAILED(hrTemp))
  513. {
  514. hr = hrTemp;
  515. goto Error;
  516. }
  517. // strcat(psz, szNew);
  518. hrTemp = StringCchCatA(psz, ARRAYSIZE(m_szTmp) - (psz - m_szTmp), szNew);
  519. if (FAILED(hrTemp))
  520. {
  521. hr = hrTemp;
  522. goto Error;
  523. }
  524. // Find what file system attribute the intend storage should be
  525. if( dwAttributes & WMDM_FILE_ATTR_HIDDEN )
  526. {
  527. fsAttrib |= FILE_ATTRIBUTE_HIDDEN;
  528. }
  529. if( dwAttributes & WMDM_FILE_ATTR_SYSTEM )
  530. {
  531. fsAttrib |= FILE_ATTRIBUTE_SYSTEM;
  532. }
  533. if( dwAttributes & WMDM_FILE_ATTR_READONLY )
  534. {
  535. fsAttrib |= FILE_ATTRIBUTE_READONLY;
  536. }
  537. if( dwAttributes & WMDM_FILE_ATTR_FOLDER )
  538. {
  539. if(CreateDirectoryA(m_szTmp, NULL))
  540. {
  541. hr = S_OK;
  542. }
  543. else
  544. {
  545. hr = GetLastError();
  546. if( hr == ERROR_ALREADY_EXISTS )
  547. {
  548. if( dwAttributes & WMDM_FILE_CREATE_OVERWRITE )
  549. {
  550. hr = S_OK;
  551. }
  552. else
  553. {
  554. hr = HRESULT_FROM_WIN32(ERROR_ALREADY_EXISTS);
  555. }
  556. }
  557. else
  558. {
  559. hr = HRESULT_FROM_WIN32(hr);
  560. goto Error;
  561. }
  562. }
  563. if( S_OK == hr )
  564. {
  565. SetFileAttributes(m_szTmp, fsAttrib);
  566. }
  567. }
  568. else if ( dwAttributes & WMDM_FILE_ATTR_FILE )
  569. {
  570. // If Overwrite is specified, use CREATE_ALWAYS
  571. if( dwAttributes & WMDM_FILE_CREATE_OVERWRITE )
  572. {
  573. hFile = CreateFileA(
  574. m_szTmp,
  575. GENERIC_WRITE | GENERIC_READ,
  576. FILE_SHARE_READ | FILE_SHARE_WRITE,
  577. NULL,
  578. CREATE_ALWAYS,
  579. fsAttrib,
  580. NULL
  581. );
  582. }
  583. else
  584. {
  585. hFile = CreateFileA(
  586. m_szTmp,
  587. GENERIC_WRITE | GENERIC_READ,
  588. FILE_SHARE_READ | FILE_SHARE_WRITE,
  589. NULL,
  590. CREATE_NEW,
  591. fsAttrib,
  592. NULL
  593. );
  594. }
  595. CWRg(hFile != INVALID_HANDLE_VALUE);
  596. CloseHandle(hFile);
  597. hr = S_OK;
  598. }
  599. else
  600. {
  601. hr = E_INVALIDARG;
  602. goto Error;
  603. }
  604. if( hr == S_OK )
  605. {
  606. CComObject<CMDSPStorage> *pObj;
  607. CORg(CComObject<CMDSPStorage>::CreateInstance(&pObj));
  608. hr = pObj->QueryInterface(
  609. IID_IMDSPStorage,
  610. reinterpret_cast<void**>(ppNewStorage)
  611. );
  612. if( FAILED(hr) )
  613. {
  614. delete pObj;
  615. }
  616. else
  617. {
  618. MultiByteToWideChar(CP_ACP, NULL, m_szTmp, -1, pObj->m_wcsName, MAX_PATH);
  619. }
  620. }
  621. Error:
  622. hrLogDWORD("IMSDPStorage::CreateStorage returned 0x%08lx", hr, hr);
  623. return hr;
  624. }
  625. STDMETHODIMP CMDSPStorage::SendOpaqueCommand(OPAQUECOMMAND *pCommand)
  626. {
  627. HRESULT hr = WMDM_E_NOTSUPPORTED;
  628. CFRg(g_pAppSCServer);
  629. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  630. {
  631. CORg(WMDM_E_NOTCERTIFIED);
  632. }
  633. Error:
  634. hrLogDWORD("IMSDPStorage::SendOpaqueCommand returned 0x%08lx", hr, hr);
  635. return hr;
  636. }
  637. // IMDSPStorage2
  638. STDMETHODIMP CMDSPStorage::GetStorage(
  639. LPCWSTR pszStorageName,
  640. IMDSPStorage** ppStorage )
  641. {
  642. HRESULT hr;
  643. HRESULT hrTemp;
  644. WCHAR pwszFileName[MAX_PATH];
  645. DWORD dwAttrib;
  646. CComObject<CMDSPStorage> *pStg = NULL;
  647. // This storage need to be a folder to contain other storages.
  648. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  649. dwAttrib = GetFileAttributesA(m_szTmp);
  650. if( dwAttrib == (DWORD)0xFFFFFFFF )
  651. {
  652. hr = HRESULT_FROM_WIN32(GetLastError());
  653. goto Error;
  654. }
  655. if( (dwAttrib & FILE_ATTRIBUTE_DIRECTORY) == 0 )
  656. {
  657. // This storage is not a directory/folder
  658. hr = E_FAIL; // @@@@ Is any other value more suitable?
  659. goto Error;
  660. }
  661. // Get name of file asked for
  662. DWORD dwLen = wcslen(m_wcsName);
  663. if (dwLen == 0)
  664. {
  665. hr = E_FAIL;
  666. goto Error;
  667. }
  668. if (dwLen >= ARRAYSIZE(pwszFileName))
  669. {
  670. hr = STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  671. goto Error;
  672. }
  673. // Get name of file asked for
  674. wcscpy( pwszFileName, m_wcsName );
  675. if( pwszFileName[dwLen-1] != L'\\' )
  676. {
  677. if (dwLen >= ARRAYSIZE(pwszFileName) - 1)
  678. {
  679. hr = STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  680. goto Error;
  681. }
  682. wcscat( pwszFileName, L"\\" );
  683. }
  684. hrTemp = StringCchCatW( pwszFileName,
  685. ARRAYSIZE(pwszFileName),
  686. pszStorageName );
  687. if (FAILED(hrTemp))
  688. {
  689. // The file does not exist
  690. hr = E_FAIL; // @@@@ Change this?
  691. goto Error;
  692. }
  693. // Check if the file exists
  694. CWRg(WideCharToMultiByte(CP_ACP, NULL, pwszFileName, -1, m_szTmp, MAX_PATH, NULL, NULL));
  695. if( GetFileAttributesA( m_szTmp ) == -1 )
  696. {
  697. // The file does not exist
  698. hr = S_FALSE; // @@@@ Should this be a failure code?
  699. goto Error;
  700. }
  701. // Create new storage object
  702. hr = CComObject<CMDSPStorage>::CreateInstance(&pStg);
  703. hr = pStg->QueryInterface( IID_IMDSPStorage, reinterpret_cast<void**>(ppStorage));
  704. // wcscpy(pStg->m_wcsName, pwszFileName);
  705. hrTemp = StringCchCopyW(pStg->m_wcsName, ARRAYSIZE(pStg->m_wcsName), pwszFileName);
  706. if (FAILED(hrTemp))
  707. {
  708. hr = hrTemp;
  709. (*ppStorage)->Release();
  710. pStg = NULL; // to prevent its deletion below
  711. goto Error;
  712. }
  713. Error:
  714. if( hr != S_OK )
  715. {
  716. if( pStg ) delete pStg;
  717. *ppStorage = NULL;
  718. }
  719. return hr;
  720. }
  721. STDMETHODIMP CMDSPStorage::CreateStorage2(
  722. DWORD dwAttributes,
  723. DWORD dwAttributesEx,
  724. _WAVEFORMATEX *pAudioFormat,
  725. _VIDEOINFOHEADER *pVideoFormat,
  726. LPWSTR pwszName,
  727. ULONGLONG qwFileSize,
  728. IMDSPStorage **ppNewStorage )
  729. {
  730. // pVideoFormat, dwAttributesEx not used right now
  731. return CreateStorage( dwAttributes, pAudioFormat, pwszName, ppNewStorage );
  732. }
  733. STDMETHODIMP CMDSPStorage::SetAttributes2(
  734. DWORD dwAttributes,
  735. DWORD dwAttributesEx,
  736. _WAVEFORMATEX *pAudioFormat,
  737. _VIDEOINFOHEADER* pVideoFormat )
  738. {
  739. // pVideoFormat, dwAttributesEx not used right now
  740. return SetAttributes( dwAttributes, pAudioFormat );
  741. }
  742. STDMETHODIMP CMDSPStorage::GetAttributes2(
  743. DWORD *pdwAttributes,
  744. DWORD *pdwAttributesEx,
  745. _WAVEFORMATEX *pAudioFormat,
  746. _VIDEOINFOHEADER* pVideoFormat )
  747. {
  748. HRESULT hr = S_OK;
  749. CARg( pdwAttributesEx );
  750. *pdwAttributesEx = 0;
  751. // pVideoFormat, dwAttributesEx not used right now
  752. hr = GetAttributes( pdwAttributes, pAudioFormat );
  753. Error:
  754. return hr;
  755. }
  756. // IMDSPObjectInfo
  757. STDMETHODIMP CMDSPStorage::GetPlayLength(/*[out]*/ DWORD *pdwLength)
  758. {
  759. HRESULT hr;
  760. CFRg(g_pAppSCServer);
  761. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  762. {
  763. CORg(WMDM_E_NOTCERTIFIED);
  764. }
  765. if ( !pdwLength )
  766. {
  767. hr = E_INVALIDARG;
  768. }
  769. else
  770. {
  771. hr = WMDM_E_NOTSUPPORTED;
  772. }
  773. Error:
  774. hrLogDWORD("IMDSPObjectInfo::GetPlayLength returned 0x%08lx", hr, hr);
  775. return hr;
  776. }
  777. STDMETHODIMP CMDSPStorage::SetPlayLength(/*[in]*/ DWORD dwLength)
  778. {
  779. HRESULT hr = WMDM_E_NOTSUPPORTED;
  780. CFRg(g_pAppSCServer);
  781. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  782. {
  783. CORg(WMDM_E_NOTCERTIFIED);
  784. }
  785. Error:
  786. hrLogDWORD("IMDSPObjectInfo::SetPlayLength returned 0x%08lx", hr, hr);
  787. return hr;
  788. }
  789. STDMETHODIMP CMDSPStorage::GetPlayOffset(/*[out]*/ DWORD *pdwOffset)
  790. {
  791. HRESULT hr;
  792. CFRg(g_pAppSCServer);
  793. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  794. {
  795. CORg(WMDM_E_NOTCERTIFIED);
  796. }
  797. if ( !pdwOffset )
  798. {
  799. hr = E_INVALIDARG;
  800. }
  801. else
  802. {
  803. hr = WMDM_E_NOTSUPPORTED;
  804. }
  805. Error:
  806. hrLogDWORD("IMDSPObjectInfo::GetPlayOffset returned 0x%08lx", hr, hr);
  807. return hr;
  808. }
  809. STDMETHODIMP CMDSPStorage::SetPlayOffset(/*[in]*/ DWORD dwOffset)
  810. {
  811. HRESULT hr = WMDM_E_NOTSUPPORTED;
  812. CFRg(g_pAppSCServer);
  813. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  814. {
  815. CORg(WMDM_E_NOTCERTIFIED);
  816. }
  817. Error:
  818. hrLogDWORD("IMDSPObjectInfo::SetPlayOffset returned 0x%08lx", hr, hr);
  819. return hr;
  820. }
  821. STDMETHODIMP CMDSPStorage::GetTotalLength(/*[out]*/ DWORD *pdwLength)
  822. {
  823. HRESULT hr;
  824. CFRg(g_pAppSCServer);
  825. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  826. {
  827. CORg(WMDM_E_NOTCERTIFIED);
  828. }
  829. if ( !pdwLength )
  830. {
  831. hr = E_INVALIDARG;
  832. }
  833. else
  834. {
  835. hr = WMDM_E_NOTSUPPORTED;
  836. }
  837. Error:
  838. hrLogDWORD("IMDSPObjectInfo::GetTotalLength returned 0x%08lx", hr, hr);
  839. return hr;
  840. }
  841. STDMETHODIMP CMDSPStorage::GetLastPlayPosition(/*[out]*/ DWORD *pdwLastPos)
  842. {
  843. HRESULT hr;
  844. CFRg(g_pAppSCServer);
  845. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  846. {
  847. CORg(WMDM_E_NOTCERTIFIED);
  848. }
  849. if ( !pdwLastPos )
  850. {
  851. hr = E_INVALIDARG;
  852. }
  853. else
  854. {
  855. hr = WMDM_E_NOTSUPPORTED;
  856. }
  857. Error:
  858. hrLogDWORD("IMDSPObjectInfo::GetLastPlayPosition returned 0x%08lx", hr, hr);
  859. return hr;
  860. }
  861. STDMETHODIMP CMDSPStorage::GetLongestPlayPosition(/*[out]*/ DWORD *pdwLongestPos)
  862. {
  863. HRESULT hr;
  864. CFRg(g_pAppSCServer);
  865. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  866. {
  867. CORg(WMDM_E_NOTCERTIFIED);
  868. }
  869. if ( !pdwLongestPos )
  870. {
  871. hr = E_INVALIDARG;
  872. }
  873. else
  874. {
  875. hr = WMDM_E_NOTSUPPORTED;
  876. }
  877. Error:
  878. hrLogDWORD("IMDSPObjectInfo::GetLongestPlayPosition returned 0x%08lx", hr, hr);
  879. return hr;
  880. }
  881. // IMDSPObject
  882. STDMETHODIMP CMDSPStorage::Open(/*[in]*/ UINT fuMode)
  883. {
  884. HRESULT hr;
  885. DWORD dwMode;
  886. CFRg(g_pAppSCServer);
  887. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  888. {
  889. CORg(WMDM_E_NOTCERTIFIED);
  890. }
  891. CONEg(m_wcsName[0]);
  892. if( m_hFile != INVALID_HANDLE_VALUE )
  893. {
  894. hr = WMDM_E_BUSY;
  895. goto Error;
  896. }
  897. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  898. dwMode = GetFileAttributesA(m_szTmp);
  899. if( (dwMode & FILE_ATTRIBUTE_DIRECTORY) )
  900. {
  901. hr=WMDM_E_NOTSUPPORTED;
  902. }
  903. else
  904. {
  905. dwMode = 0;
  906. if(fuMode & MDSP_WRITE )
  907. {
  908. dwMode |= GENERIC_WRITE;
  909. }
  910. if(fuMode & MDSP_READ )
  911. {
  912. dwMode |= GENERIC_READ;
  913. }
  914. m_hFile = CreateFileA(
  915. m_szTmp,
  916. dwMode,
  917. FILE_SHARE_READ | FILE_SHARE_WRITE,
  918. NULL,
  919. OPEN_EXISTING,
  920. FILE_ATTRIBUTE_NORMAL,
  921. NULL
  922. );
  923. hr = ( m_hFile == INVALID_HANDLE_VALUE ) ? E_FAIL : S_OK;
  924. }
  925. Error:
  926. hrLogDWORD("IMDSPObject::Open returned 0x%08lx", hr, hr);
  927. return hr;
  928. }
  929. STDMETHODIMP CMDSPStorage::Read(
  930. BYTE *pData,
  931. DWORD *pdwSize,
  932. BYTE abMac[WMDM_MAC_LENGTH])
  933. {
  934. HRESULT hr;
  935. DWORD dwToRead;
  936. DWORD dwRead = NULL;
  937. BYTE *pTmpData = NULL;
  938. CFRg(g_pAppSCServer);
  939. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  940. {
  941. CORg(WMDM_E_NOTCERTIFIED);
  942. }
  943. CARg(pData);
  944. CARg(pdwSize);
  945. dwToRead = *pdwSize;
  946. if( m_hFile == INVALID_HANDLE_VALUE )
  947. {
  948. return E_FAIL;
  949. }
  950. pTmpData = new BYTE [dwToRead] ;
  951. CPRg(pTmpData);
  952. if( ReadFile(m_hFile,(LPVOID)pTmpData,dwToRead,&dwRead,NULL) )
  953. {
  954. *pdwSize = dwRead;
  955. if( dwRead )
  956. {
  957. // MAC the parameters
  958. HMAC hMAC;
  959. CORg(g_pAppSCServer->MACInit(&hMAC));
  960. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), dwRead));
  961. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(DWORD)));
  962. CORg(g_pAppSCServer->MACFinal(hMAC, abMac));
  963. CORg(g_pAppSCServer->EncryptParam(pTmpData, dwRead));
  964. memcpy(pData, pTmpData, dwRead);
  965. }
  966. hr = S_OK;
  967. }
  968. else
  969. {
  970. *pdwSize = 0;
  971. hr = E_FAIL;
  972. }
  973. Error:
  974. if(pTmpData)
  975. {
  976. delete [] pTmpData;
  977. }
  978. hrLogDWORD("IMDSPObject::Read returned 0x%08lx", hr, hr);
  979. return hr;
  980. }
  981. STDMETHODIMP CMDSPStorage::Write(BYTE *pData, DWORD *pdwSize,
  982. BYTE abMac[WMDM_MAC_LENGTH])
  983. {
  984. HRESULT hr;
  985. DWORD dwWritten = 0;
  986. BYTE *pTmpData = NULL;
  987. BYTE pSelfMac[WMDM_MAC_LENGTH];
  988. CARg(pData);
  989. CARg(pdwSize);
  990. if( m_hFile == INVALID_HANDLE_VALUE )
  991. {
  992. return E_FAIL;
  993. }
  994. pTmpData = new BYTE [*pdwSize];
  995. CPRg(pTmpData);
  996. memcpy(pTmpData, pData, *pdwSize);
  997. // Decrypt the pData Parameter
  998. CHRg(g_pAppSCServer->DecryptParam(pTmpData, *pdwSize));
  999. HMAC hMAC;
  1000. CORg(g_pAppSCServer->MACInit(&hMAC));
  1001. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pTmpData), *pdwSize));
  1002. CORg(g_pAppSCServer->MACUpdate(hMAC, (BYTE*)(pdwSize), sizeof(*pdwSize)));
  1003. CORg(g_pAppSCServer->MACFinal(hMAC, pSelfMac));
  1004. if (memcmp(abMac, pSelfMac, WMDM_MAC_LENGTH) != 0)
  1005. {
  1006. hr = WMDM_E_MAC_CHECK_FAILED;
  1007. goto Error;
  1008. }
  1009. if( WriteFile(m_hFile,pTmpData,*pdwSize,&dwWritten,NULL) )
  1010. {
  1011. hr = S_OK;
  1012. }
  1013. else
  1014. {
  1015. hr = HRESULT_FROM_WIN32(GetLastError());
  1016. }
  1017. *pdwSize = dwWritten;
  1018. Error:
  1019. if( pTmpData )
  1020. {
  1021. delete [] pTmpData;
  1022. }
  1023. hrLogDWORD("IMDSPObject::Write returned 0x%08lx", hr, hr);
  1024. return hr;
  1025. }
  1026. STDMETHODIMP CMDSPStorage::Delete(UINT fuMode, IWMDMProgress *pProgress)
  1027. {
  1028. HRESULT hr = E_FAIL;
  1029. BOOL bProgressStarted = FALSE;
  1030. BOOL bBusyStatusSet = FALSE;
  1031. DWORD dwStatus = NULL;
  1032. if( pProgress )
  1033. {
  1034. CORg(pProgress->Begin(100));
  1035. bProgressStarted=TRUE;
  1036. }
  1037. CFRg(g_pAppSCServer);
  1038. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1039. {
  1040. CORg(WMDM_E_NOTCERTIFIED);
  1041. }
  1042. CONEg(m_wcsName[0]);
  1043. if ( m_hFile != INVALID_HANDLE_VALUE )
  1044. {
  1045. CloseHandle(m_hFile);
  1046. m_hFile = INVALID_HANDLE_VALUE;
  1047. }
  1048. CHRg(GetGlobalDeviceStatus(m_wcsName, &dwStatus));
  1049. if( dwStatus & WMDM_STATUS_BUSY )
  1050. {
  1051. hr = WMDM_E_BUSY;
  1052. goto Error;
  1053. }
  1054. dwStatus |= (WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_DELETING );
  1055. CHRg(SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE));
  1056. bBusyStatusSet=TRUE;
  1057. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  1058. if( fuMode & WMDM_MODE_RECURSIVE )
  1059. {
  1060. CORg(DeleteFileRecursive(m_szTmp));
  1061. }
  1062. else
  1063. {
  1064. if( FILE_ATTRIBUTE_DIRECTORY & GetFileAttributesA(m_szTmp) )
  1065. {
  1066. CWRg(RemoveDirectory(m_szTmp));
  1067. }
  1068. else
  1069. {
  1070. CWRg(DeleteFileA(m_szTmp));
  1071. }
  1072. }
  1073. hr = S_OK;
  1074. Error:
  1075. if( bBusyStatusSet )
  1076. {
  1077. dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_DELETING ));
  1078. SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE);
  1079. }
  1080. if( hr == S_OK )
  1081. {
  1082. m_wcsName[0] = NULL; // Nullify the storage name
  1083. }
  1084. if( bProgressStarted )
  1085. {
  1086. pProgress->Progress( 100 );
  1087. pProgress->End();
  1088. }
  1089. hrLogDWORD("IMDSPObject::Delete returned 0x%08lx", hr, hr);
  1090. return hr;
  1091. }
  1092. STDMETHODIMP CMDSPStorage::Seek(/*[in]*/ UINT fuFlags, /*[in]*/ DWORD dwOffset)
  1093. {
  1094. HRESULT hr = S_OK;
  1095. CFRg(g_pAppSCServer);
  1096. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1097. {
  1098. CORg(WMDM_E_NOTCERTIFIED);
  1099. }
  1100. CONEg(m_wcsName[0]);
  1101. CFRg( m_hFile != INVALID_HANDLE_VALUE );
  1102. DWORD dwMoveMethod;
  1103. switch (fuFlags)
  1104. {
  1105. case MDSP_SEEK_BOF:
  1106. dwMoveMethod = FILE_BEGIN;
  1107. break;
  1108. case MDSP_SEEK_CUR:
  1109. dwMoveMethod = FILE_CURRENT;
  1110. break;
  1111. case MDSP_SEEK_EOF:
  1112. dwMoveMethod = FILE_END;
  1113. break;
  1114. default:
  1115. return E_INVALIDARG;
  1116. }
  1117. CWRg( (DWORD)0xFFFFFFFF != SetFilePointer(m_hFile, dwOffset, NULL, dwMoveMethod ) );
  1118. Error:
  1119. hrLogDWORD("IMDSPObject::Seek returned 0x%08lx", hr, hr);
  1120. return hr;
  1121. }
  1122. STDMETHODIMP CMDSPStorage::Rename(/*[in]*/ LPWSTR pwszNewName, IWMDMProgress *pProgress)
  1123. {
  1124. HRESULT hr;
  1125. BOOL bProgressStarted = FALSE;
  1126. BOOL bBusyStatusSet = FALSE;
  1127. DWORD dwStatus;
  1128. if( pProgress )
  1129. {
  1130. CORg(pProgress->Begin(100));
  1131. bProgressStarted=TRUE;
  1132. }
  1133. CFRg(g_pAppSCServer);
  1134. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1135. {
  1136. CORg(WMDM_E_NOTCERTIFIED);
  1137. }
  1138. CARg(pwszNewName);
  1139. CONEg(m_wcsName[0]);
  1140. CFRg(wcslen(m_wcsName)>3); // cannot rename a root storage
  1141. if ( m_hFile != INVALID_HANDLE_VALUE )
  1142. {
  1143. CloseHandle(m_hFile);
  1144. m_hFile = INVALID_HANDLE_VALUE;
  1145. }
  1146. CHRg(GetGlobalDeviceStatus(m_wcsName, &dwStatus));
  1147. if( dwStatus & WMDM_STATUS_BUSY )
  1148. {
  1149. hr=WMDM_E_BUSY;
  1150. goto Error;
  1151. }
  1152. dwStatus |= (WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING );
  1153. CHRg(SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE));
  1154. bBusyStatusSet = TRUE;
  1155. char *pDirOffset;
  1156. char szUpper[MAX_PATH], szNewFullPath[MAX_PATH], szNew[MAX_PATH];
  1157. CWRg(WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL));
  1158. CWRg(WideCharToMultiByte(CP_ACP, NULL, pwszNewName, -1, szNew, MAX_PATH, NULL, NULL));
  1159. // From m_szTmp, find the upper level dir, and put it in szUpper.
  1160. strcpy(szUpper, m_szTmp);
  1161. if( szUpper[strlen(szUpper)-1] == 0x5c )
  1162. {
  1163. szUpper[strlen(szUpper)-1] = 0;
  1164. }
  1165. pDirOffset = strrchr(szUpper, 0x5c);
  1166. if( pDirOffset )
  1167. {
  1168. *((char *)pDirOffset+1) = 0;
  1169. }
  1170. // From szUpper and szNew, form the full path for szNewFullPath
  1171. strcpy(szNewFullPath, szUpper);
  1172. pDirOffset=strrchr(szNew, 0x5c);
  1173. if( pDirOffset )
  1174. {
  1175. // strcat(szNewFullPath, (char*)pDirOffset+1);
  1176. hr = StringCchCatA(szNewFullPath, ARRAYSIZE(szNewFullPath), (char*)pDirOffset+1);
  1177. if (FAILED(hr))
  1178. {
  1179. goto Error;
  1180. }
  1181. }
  1182. else
  1183. {
  1184. // strcat(szNewFullPath, szNew);
  1185. hr = StringCchCatA(szNewFullPath, ARRAYSIZE(szNewFullPath), szNew);
  1186. if (FAILED(hr))
  1187. {
  1188. goto Error;
  1189. }
  1190. }
  1191. // Now move
  1192. CWRg ( MoveFileA(m_szTmp, szNewFullPath) );
  1193. MultiByteToWideChar(CP_ACP, NULL, szNewFullPath, -1, m_wcsName, MAX_PATH);
  1194. hr = S_OK;
  1195. Error:
  1196. if( bBusyStatusSet )
  1197. {
  1198. dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING ));
  1199. SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE);
  1200. }
  1201. if( bProgressStarted )
  1202. {
  1203. pProgress->Progress( 100 );
  1204. pProgress->End();
  1205. }
  1206. hrLogDWORD("IMDSPObject::Rename returned 0x%08lx", hr, hr);
  1207. return hr;
  1208. }
  1209. STDMETHODIMP CMDSPStorage::EnumStorage(IMDSPEnumStorage * * ppEnumStorage)
  1210. {
  1211. HRESULT hr;
  1212. CFRg(g_pAppSCServer);
  1213. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1214. {
  1215. CORg(WMDM_E_NOTCERTIFIED);
  1216. }
  1217. CARg(ppEnumStorage);
  1218. CONEg(m_wcsName[0]);
  1219. DWORD dwAttrib;
  1220. CORg(GetAttributes(&dwAttrib, NULL));
  1221. if( dwAttrib & WMDM_FILE_ATTR_FILE )
  1222. {
  1223. return WMDM_E_NOTSUPPORTED;
  1224. }
  1225. CComObject<CMDSPEnumStorage> *pEnumObj;
  1226. CORg(CComObject<CMDSPEnumStorage>::CreateInstance(&pEnumObj));
  1227. hr = pEnumObj->QueryInterface(
  1228. IID_IMDSPEnumStorage,
  1229. reinterpret_cast<void**>(ppEnumStorage)
  1230. );
  1231. if( FAILED(hr) )
  1232. {
  1233. delete pEnumObj;
  1234. }
  1235. else
  1236. {
  1237. // wcscpy(pEnumObj->m_wcsPath, m_wcsName);
  1238. hr = StringCchCopyW(pEnumObj->m_wcsPath,
  1239. ARRAYSIZE(pEnumObj->m_wcsPath), m_wcsName);
  1240. if (FAILED(hr))
  1241. {
  1242. (*ppEnumStorage)->Release();
  1243. *ppEnumStorage = NULL;
  1244. }
  1245. }
  1246. Error:
  1247. hrLogDWORD("IMDSPStorage::EnumStorage returned 0x%08lx", hr, hr);
  1248. return hr;
  1249. }
  1250. STDMETHODIMP CMDSPStorage::Close()
  1251. {
  1252. HRESULT hr = S_OK;
  1253. CFRg(g_pAppSCServer);
  1254. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1255. {
  1256. CORg(WMDM_E_NOTCERTIFIED);
  1257. }
  1258. CONEg(m_wcsName[0]);
  1259. if( m_hFile != INVALID_HANDLE_VALUE )
  1260. {
  1261. CloseHandle(m_hFile);
  1262. m_hFile=INVALID_HANDLE_VALUE;
  1263. }
  1264. Error:
  1265. hrLogDWORD("IMDSPObject::Close returned 0x%08lx", hr, hr);
  1266. return hr;
  1267. }
  1268. DWORD MoveFunc( void *args )
  1269. {
  1270. HRESULT hr = S_OK;
  1271. MOVETHREADARGS *pCMArgs;
  1272. WCHAR *pWcs;
  1273. CHAR szDst[MAX_PATH];
  1274. CHAR szSrc[MAX_PATH];
  1275. pCMArgs = (MOVETHREADARGS *)args;
  1276. if( pCMArgs->bNewThread )
  1277. {
  1278. CORg(CoInitializeEx(NULL, COINIT_APARTMENTTHREADED));
  1279. if( pCMArgs->pProgress )
  1280. {
  1281. CORg(CoGetInterfaceAndReleaseStream(
  1282. pCMArgs->pStream,
  1283. IID_IWMDMProgress,
  1284. (LPVOID *)&(pCMArgs->pProgress))
  1285. );
  1286. }
  1287. }
  1288. pWcs = wcsrchr(pCMArgs->wcsSrc, 0x5c);
  1289. if(!pWcs)
  1290. {
  1291. hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  1292. goto Error;
  1293. }
  1294. DWORD dwDestLen = wcslen(pCMArgs->wcsDst);
  1295. if (dwDestLen == 0)
  1296. {
  1297. // Code below assumes this string is at least one long
  1298. hr = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
  1299. goto Error;
  1300. }
  1301. // Validate buffer sizes before the string copies
  1302. int nHave = ARRAYSIZE(pCMArgs->wcsDst) - 1; // -1 for NULL terminator
  1303. nHave -= dwDestLen;
  1304. if( pCMArgs->wcsDst[dwDestLen-1] != 0x5c )
  1305. {
  1306. nHave -= BACKSLASH_STRING_LENGTH;
  1307. }
  1308. nHave -= wcslen(pWcs+1);
  1309. if (nHave < 0)
  1310. {
  1311. hr = STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  1312. goto Error;
  1313. }
  1314. // Validate the buffer size of pCMArgs->pThis->m_wcsName before
  1315. // calling UtilMoveFile. ARRAYSIZE(pCMArgs->wcsDst) - nHave is
  1316. // the length of the string (including the NULL terminator)
  1317. // that will be constructed in pCMArgs->wcsDst and copied over to
  1318. // pCMArgs->pThis->m_wcsName
  1319. if (ARRAYSIZE(pCMArgs->wcsDst) - nHave > ARRAYSIZE(pCMArgs->pThis->m_wcsName))
  1320. {
  1321. hr = STRSAFE_E_INSUFFICIENT_BUFFER; // defined in strsafe.h
  1322. goto Error;
  1323. }
  1324. if( pCMArgs->wcsDst[dwDestLen-1] != 0x5c )
  1325. {
  1326. wcscat(pCMArgs->wcsDst,g_wcsBackslash);
  1327. }
  1328. wcscat(pCMArgs->wcsDst, pWcs+1);
  1329. WideCharToMultiByte(CP_ACP, NULL, pCMArgs->wcsDst, -1, szDst, MAX_PATH, NULL, NULL);
  1330. WideCharToMultiByte(CP_ACP, NULL, pCMArgs->wcsSrc, -1, szSrc, MAX_PATH, NULL, NULL);
  1331. CWRg( MoveFileA(szSrc,szDst) );
  1332. // Substitute current object name with the moved one
  1333. wcscpy(pCMArgs->pThis->m_wcsName, pCMArgs->wcsDst);
  1334. hr = S_OK;
  1335. Error:
  1336. if( pCMArgs->bNewThread )
  1337. {
  1338. // Reset status, we've got here we must have set the status busy before
  1339. pCMArgs->dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING));
  1340. SetGlobalDeviceStatus(pCMArgs->wcsSrc, pCMArgs->dwStatus, TRUE);
  1341. // Reset progress, we've got here we must have set the progress before
  1342. if( pCMArgs->pProgress )
  1343. {
  1344. pCMArgs->pProgress->Progress(100);
  1345. pCMArgs->pProgress->End();
  1346. pCMArgs->pProgress->Release(); // since we did AddRef to get here
  1347. }
  1348. if( pCMArgs )
  1349. {
  1350. delete pCMArgs;
  1351. }
  1352. CoUninitialize();
  1353. }
  1354. return hr;
  1355. }
  1356. STDMETHODIMP CMDSPStorage::Move(UINT fuMode, IWMDMProgress *pProgress,
  1357. IMDSPStorage *pTarget)
  1358. {
  1359. HRESULT hr = E_FAIL;
  1360. WCHAR *wcsSrc = NULL;
  1361. WCHAR *wcsDst = NULL;
  1362. WCHAR wcsTmp[MAX_PATH];
  1363. WCHAR *pWcs = NULL;
  1364. CMDSPStorage *pStg = NULL;
  1365. MOVETHREADARGS *pMoveArgs = NULL;
  1366. DWORD dwThreadID;
  1367. DWORD dwStatus = NULL;
  1368. BOOL bProgStarted = FALSE;
  1369. BOOL bBusyStatusSet = FALSE;
  1370. BOOL bThreadFailed = TRUE;
  1371. BOOL bAddRefed = FALSE;
  1372. // Start the progress
  1373. if( pProgress )
  1374. {
  1375. CORg(pProgress->Begin(100));
  1376. bProgStarted=TRUE;
  1377. }
  1378. CFRg(g_pAppSCServer);
  1379. if ( !(g_pAppSCServer->fIsAuthenticated()) )
  1380. {
  1381. CORg(WMDM_E_NOTCERTIFIED);
  1382. }
  1383. CONEg(m_wcsName[0]);
  1384. CHRg(GetGlobalDeviceStatus(m_wcsName, &dwStatus));
  1385. if( dwStatus & WMDM_STATUS_BUSY )
  1386. {
  1387. hr = WMDM_E_BUSY;
  1388. goto Error;
  1389. }
  1390. pMoveArgs = new MOVETHREADARGS;
  1391. CPRg(pMoveArgs);
  1392. ZeroMemory(pMoveArgs, sizeof(MOVETHREADARGS));
  1393. dwStatus |= (WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING );
  1394. CHRg(SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE));
  1395. bBusyStatusSet = TRUE;
  1396. // setup MoveArgs for MoveFunc
  1397. pMoveArgs->dwStatus = dwStatus;
  1398. CARg(pTarget);
  1399. pStg = (CMDSPStorage *)pTarget;
  1400. wcsSrc = (WCHAR *)&(pMoveArgs->wcsSrc[0]);
  1401. CPRg(wcsSrc);
  1402. wcsDst = (WCHAR *)&(pMoveArgs->wcsDst[0]);
  1403. CPRg(wcsDst);
  1404. // Make sure the source and destination are on the same device
  1405. hr = wcsParseDeviceName(m_wcsName, wcsSrc, ARRAYSIZE(pMoveArgs->wcsSrc));
  1406. if (FAILED(hr))
  1407. {
  1408. goto Error;
  1409. }
  1410. hr = wcsParseDeviceName(pStg->m_wcsName, wcsDst, ARRAYSIZE(pMoveArgs->wcsDst));
  1411. if (FAILED(hr))
  1412. {
  1413. goto Error;
  1414. }
  1415. if( wcscmp(wcsSrc, wcsDst) )
  1416. {
  1417. hr = WMDM_E_NOTSUPPORTED; // do not support move out of the same device
  1418. goto Error;
  1419. }
  1420. // Now check for target's attributes
  1421. DWORD dwDstAttrib, dwSrcAttrib;
  1422. CHRg(GetAttributes(&dwSrcAttrib, NULL));
  1423. // wcscpy(wcsSrc, m_wcsName);
  1424. hr = StringCchCopyW(wcsSrc, ARRAYSIZE(pMoveArgs->wcsSrc), m_wcsName);
  1425. if (FAILED(hr))
  1426. {
  1427. goto Error;
  1428. }
  1429. // wcscpy(wcsDst, pStg->m_wcsName);
  1430. hr = StringCchCopyW(wcsDst, ARRAYSIZE(pMoveArgs->wcsDst), pStg->m_wcsName);
  1431. if (FAILED(hr))
  1432. {
  1433. goto Error;
  1434. }
  1435. if ( fuMode & WMDM_STORAGECONTROL_INSERTINTO )
  1436. {
  1437. CHRg(pTarget->GetAttributes(&dwDstAttrib, NULL));
  1438. CARg( dwDstAttrib & WMDM_FILE_ATTR_FOLDER ); // INSERTINFO must be to a folder
  1439. }
  1440. else
  1441. {
  1442. // Get the folder one level up
  1443. pWcs = wcsrchr(wcsDst, 0x5c);
  1444. CFRg(pWcs);
  1445. *pWcs=NULL;
  1446. WideCharToMultiByte(CP_ACP, NULL, m_wcsName, -1, m_szTmp, MAX_PATH, NULL, NULL);
  1447. DWORD dwAttribs = GetFileAttributesA(m_szTmp);
  1448. if (dwAttribs == INVALID_FILE_ATTRIBUTES)
  1449. {
  1450. goto Error;
  1451. }
  1452. CWRg( FILE_ATTRIBUTE_DIRECTORY & dwAttribs );
  1453. }
  1454. wcscpy(wcsTmp, wcsDst); // Store the destination folder
  1455. pMoveArgs->pThis = this;
  1456. pMoveArgs->bNewThread =(fuMode & WMDM_MODE_THREAD)?TRUE:FALSE;
  1457. // Now handle Progress marshaling
  1458. if( pProgress )
  1459. {
  1460. pMoveArgs->pProgress = pProgress;
  1461. pProgress->AddRef(); // since we are going to use it in MoveFunc()
  1462. bAddRefed=TRUE;
  1463. if( pMoveArgs->bNewThread )
  1464. {
  1465. CORg(CoMarshalInterThreadInterfaceInStream(
  1466. IID_IWMDMProgress,
  1467. (LPUNKNOWN)pProgress,
  1468. (LPSTREAM *)&(pMoveArgs->pStream))
  1469. );
  1470. }
  1471. }
  1472. if ( m_hFile != INVALID_HANDLE_VALUE )
  1473. {
  1474. CloseHandle(m_hFile);
  1475. m_hFile = INVALID_HANDLE_VALUE;
  1476. }
  1477. if( fuMode & WMDM_MODE_BLOCK )
  1478. {
  1479. hr = MoveFunc((void *)pMoveArgs);
  1480. }
  1481. else if ( fuMode & WMDM_MODE_THREAD )
  1482. {
  1483. if( CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MoveFunc,
  1484. (void *)pMoveArgs, 0, &dwThreadID))
  1485. {
  1486. bThreadFailed=FALSE;
  1487. hr = S_OK;
  1488. }
  1489. else
  1490. {
  1491. hr = HRESULT_FROM_WIN32(GetLastError());
  1492. }
  1493. }
  1494. else
  1495. {
  1496. hr = E_INVALIDARG;
  1497. }
  1498. Error:
  1499. if( (fuMode&WMDM_MODE_BLOCK) || bThreadFailed ) // otherwise these will be in MoveFunc()
  1500. {
  1501. if( bBusyStatusSet )
  1502. {
  1503. dwStatus &= (~(WMDM_STATUS_BUSY | WMDM_STATUS_STORAGECONTROL_MOVING));
  1504. SetGlobalDeviceStatus(m_wcsName, dwStatus, TRUE);
  1505. }
  1506. if( bProgStarted )
  1507. {
  1508. pProgress->Progress(100);
  1509. pProgress->End();
  1510. }
  1511. if( bAddRefed )
  1512. {
  1513. pProgress->Release(); // since we called AddRef before calling MoveFunc()
  1514. }
  1515. if( pMoveArgs )
  1516. {
  1517. delete pMoveArgs;
  1518. }
  1519. }
  1520. hrLogDWORD("IMDSPObject::Move returned 0x%08lx", hr, hr);
  1521. return hr;
  1522. }