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.

1635 lines
39 KiB

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