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.

450 lines
11 KiB

  1. #include "stdafx.h"
  2. #include "enumStorage.h"
  3. #include <stdio.h>
  4. //#include "findleak.h"
  5. //DECLARE_THIS_FILE;
  6. //
  7. // Construction/Destruction
  8. //
  9. CEnumStorage::CEnumStorage()
  10. {
  11. m_rgFindData = NULL;
  12. m_iCurItem = 0;
  13. m_cItems = 0;
  14. m_fIsDevice = FALSE;
  15. memset( m_szStartPath, 0, sizeof(m_szStartPath) );
  16. }
  17. HRESULT CEnumStorage::Init(LPCWSTR startPath, BOOL fIsDevice, IMDSPDevice *pDevice)
  18. {
  19. HRESULT hr = S_OK;
  20. CE_FIND_DATA *rgFindData = NULL;
  21. WCHAR szSearchPath[MAX_PATH];
  22. DWORD cItems = 0;
  23. DWORD cStorageCardItems = 0;
  24. DWORD i = 0;
  25. BOOL fIsRootDevice = FALSE;
  26. if( NULL == pDevice ||
  27. NULL == startPath )
  28. {
  29. return( E_INVALIDARG );
  30. }
  31. m_spDevice = pDevice;
  32. m_fIsDevice = fIsDevice;
  33. if( startPath[0] != L'\\' )
  34. {
  35. wcscpy( m_szStartPath, L"\\" );
  36. hr = StringCbCatW(m_szStartPath, sizeof(m_szStartPath), startPath);
  37. }
  38. else
  39. {
  40. hr = StringCbCopyW(m_szStartPath, sizeof(m_szStartPath), startPath);
  41. }
  42. if (FAILED(hr))
  43. {
  44. return HRESULT_FROM_WIN32(HRESULT_CODE(hr)) ;
  45. }
  46. //
  47. // Check for root!
  48. //
  49. fIsRootDevice = ( 0 == _wcsicmp( L"\\", m_szStartPath ) );
  50. //
  51. // Make SURE there is a "My Documents" directory so that Cyprus's default storage lookup
  52. // stuff works properly
  53. //
  54. if( fIsDevice )
  55. {
  56. WCHAR szCreateDir[MAX_PATH];
  57. if( fIsRootDevice )
  58. {
  59. hr = StringCbPrintfW(szCreateDir, sizeof(szCreateDir), L"\\%s", L"My Documents");
  60. }
  61. else
  62. {
  63. hr = StringCbPrintfW(szCreateDir, sizeof(szCreateDir), L"%s\\%s", m_szStartPath, L"My Documents");
  64. }
  65. if (FAILED(hr))
  66. {
  67. return HRESULT_FROM_WIN32(HRESULT_CODE(hr)) ;
  68. }
  69. CeCreateDirectory( szCreateDir, NULL );
  70. }
  71. if( !m_fIsDevice || // Are we a device at all?
  72. (m_fIsDevice && !fIsRootDevice) ) // Are we a storage card?
  73. {
  74. if( !m_fIsDevice )
  75. {
  76. if( fIsRootDevice )
  77. {
  78. hr = StringCbPrintfW(szSearchPath, sizeof(szSearchPath), L"%s*.*", m_szStartPath );
  79. }
  80. else
  81. {
  82. hr = StringCbPrintfW (szSearchPath, sizeof(szSearchPath), L"%s\\*.*", m_szStartPath );
  83. }
  84. }
  85. else
  86. {
  87. hr = StringCbCopyW(szSearchPath, sizeof(szSearchPath), m_szStartPath);
  88. }
  89. if (FAILED(hr))
  90. {
  91. return HRESULT_FROM_WIN32(HRESULT_CODE(hr)) ;
  92. }
  93. if( !CeFindAllFiles( szSearchPath,
  94. FAF_ATTRIBUTES |
  95. FAF_CREATION_TIME |
  96. FAF_LASTACCESS_TIME |
  97. FAF_LASTWRITE_TIME |
  98. FAF_SIZE_HIGH |
  99. FAF_SIZE_LOW |
  100. FAF_OID |
  101. FAF_NAME,
  102. &cItems,
  103. &rgFindData ) )
  104. {
  105. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  106. if( SUCCEEDED( hr ) )
  107. {
  108. hr = CeRapiGetError();
  109. }
  110. }
  111. //
  112. // if this is the CE device, then skip storage cards
  113. //
  114. if( SUCCEEDED( hr ) && fIsRootDevice )
  115. {
  116. for( i = 0; i < cItems; i ++ )
  117. {
  118. if( rgFindData[i].dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY )
  119. {
  120. cStorageCardItems++;
  121. }
  122. }
  123. }
  124. if( SUCCEEDED( hr ) )
  125. {
  126. m_rgFindData = new CE_FIND_DATA[cItems - cStorageCardItems];
  127. if( NULL == m_rgFindData )
  128. {
  129. hr = E_OUTOFMEMORY;
  130. }
  131. else
  132. {
  133. if( fIsRootDevice )
  134. {
  135. m_cItems = 0;
  136. for( i = 0; i < cItems; i++ )
  137. {
  138. if( !(rgFindData[i].dwFileAttributes & FILE_ATTRIBUTE_TEMPORARY) )
  139. {
  140. memcpy( &m_rgFindData[m_cItems], &rgFindData[i], sizeof(rgFindData[i]) );
  141. m_cItems++;
  142. }
  143. }
  144. }
  145. else
  146. {
  147. m_cItems = cItems;
  148. memcpy( m_rgFindData, rgFindData, cItems * sizeof(rgFindData[0]) );
  149. }
  150. }
  151. if( rgFindData )
  152. {
  153. CeRapiFreeBuffer( rgFindData );
  154. rgFindData = NULL;
  155. }
  156. //
  157. // Since CE doesn't set the FILE_ATTRIBUTE_HAS_CHILDREN, then I have to do it myself
  158. //
  159. DWORD idxItems = m_cItems;
  160. while( SUCCEEDED( hr ) && idxItems-- )
  161. {
  162. WCHAR szDirPath[MAX_PATH];
  163. DWORD dirItems = 0;
  164. if( !( m_rgFindData[idxItems].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
  165. {
  166. continue;
  167. }
  168. memset( szDirPath, 0, sizeof(szDirPath) );
  169. if( !m_fIsDevice )
  170. {
  171. if( fIsRootDevice )
  172. {
  173. hr = StringCbPrintfW(szDirPath, sizeof(szDirPath), L"\\%s\\*.*", m_rgFindData[idxItems].cFileName );
  174. }
  175. else
  176. {
  177. hr = StringCbPrintfW(szDirPath, sizeof(szDirPath), L"%s\\%s\\*.*", m_szStartPath, m_rgFindData[idxItems].cFileName );
  178. }
  179. }
  180. else
  181. {
  182. hr = StringCbPrintf(szDirPath, sizeof(szDirPath), L"%s\\*.*", m_szStartPath ); // , m_rgFindData[idxItems].cFileName );
  183. }
  184. if (FAILED(hr))
  185. {
  186. continue;
  187. }
  188. if( !CeFindAllFiles( szDirPath,
  189. FAF_FOLDERS_ONLY,
  190. &dirItems,
  191. &rgFindData ) )
  192. {
  193. hr = HRESULT_FROM_WIN32( CeGetLastError() );
  194. if( SUCCEEDED( hr ) )
  195. {
  196. hr = CeRapiGetError();
  197. }
  198. }
  199. if( SUCCEEDED( hr ) )
  200. {
  201. if( 0 != dirItems &&
  202. dirItems != cStorageCardItems )
  203. {
  204. m_rgFindData[idxItems].dwFileAttributes |= FILE_ATTRIBUTE_HAS_CHILDREN;
  205. }
  206. if( rgFindData )
  207. {
  208. CeRapiFreeBuffer( rgFindData );
  209. rgFindData = NULL;
  210. }
  211. }
  212. }
  213. }
  214. }
  215. else
  216. {
  217. m_cItems = 1;
  218. m_rgFindData = new CE_FIND_DATA[m_cItems];
  219. if( NULL == m_rgFindData )
  220. {
  221. hr = E_OUTOFMEMORY;
  222. }
  223. if( SUCCEEDED( hr ) )
  224. {
  225. memset( &m_rgFindData[0], 0, sizeof(m_rgFindData[0]) );
  226. if( fIsRootDevice )
  227. {
  228. //
  229. // We must make up a date, and set attributes & name
  230. //
  231. if( SUCCEEDED( hr ) )
  232. {
  233. m_rgFindData[0].dwFileAttributes = FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_HAS_CHILDREN;
  234. wcscpy(m_rgFindData[0].cFileName, L"\\");
  235. GetSystemTimeAsFileTime( &m_rgFindData[0].ftCreationTime );
  236. GetSystemTimeAsFileTime( &m_rgFindData[0].ftLastAccessTime );
  237. GetSystemTimeAsFileTime( &m_rgFindData[0].ftLastWriteTime );
  238. }
  239. }
  240. }
  241. }
  242. return( hr );
  243. }
  244. HRESULT CEnumStorage::Init(CEnumStorage *pCopy, IMDSPDevice *pDevice)
  245. {
  246. HRESULT hr = S_OK;
  247. if( NULL == pCopy || NULL == pDevice)
  248. {
  249. return( E_INVALIDARG );
  250. }
  251. m_spDevice = pDevice;
  252. m_cItems = pCopy->m_cItems;
  253. m_iCurItem = pCopy->m_iCurItem;
  254. wcsncpy(m_szStartPath, pCopy->m_szStartPath, sizeof(m_szStartPath)/sizeof(m_szStartPath[0]) - 1 );
  255. m_rgFindData = new CE_FIND_DATA[ m_cItems ];
  256. if( NULL == m_rgFindData )
  257. {
  258. hr = E_OUTOFMEMORY;
  259. }
  260. if( SUCCEEDED( hr ) )
  261. {
  262. memcpy(m_rgFindData, pCopy->m_rgFindData, m_cItems * sizeof(m_rgFindData[0]) );
  263. }
  264. return( hr );
  265. }
  266. void CEnumStorage::FinalRelease()
  267. {
  268. if( m_rgFindData )
  269. {
  270. delete [] m_rgFindData;
  271. }
  272. }
  273. //
  274. // IMDSPEnumStorage
  275. //
  276. STDMETHODIMP CEnumStorage::Next( ULONG celt, IMDSPStorage ** ppStorage, ULONG *pceltFetched )
  277. {
  278. ULONG celtFetched = 0;
  279. HRESULT hr = S_OK;
  280. ULONG i;
  281. if( NULL == pceltFetched && celt != 1 )
  282. {
  283. return( E_INVALIDARG );
  284. }
  285. if( NULL == ppStorage )
  286. {
  287. return( E_POINTER );
  288. }
  289. for( i = 0; i < celt; i++ )
  290. {
  291. ppStorage[i] = NULL;
  292. }
  293. while( celtFetched != celt && SUCCEEDED( hr ) )
  294. {
  295. if( m_iCurItem >= m_cItems )
  296. {
  297. hr = S_FALSE;
  298. break;
  299. }
  300. CComStorage *pNewStorage = NULL;
  301. hr = CComStorage::CreateInstance( &pNewStorage );
  302. if( SUCCEEDED( hr ) )
  303. {
  304. hr = pNewStorage->Init(&m_rgFindData[m_iCurItem], m_szStartPath, m_fIsDevice, m_spDevice);
  305. }
  306. if( SUCCEEDED( hr ) )
  307. {
  308. ppStorage[celtFetched] = pNewStorage;
  309. ppStorage[celtFetched++]->AddRef();
  310. m_iCurItem++;
  311. }
  312. }
  313. if( FAILED(hr) )
  314. {
  315. while( celtFetched-- )
  316. {
  317. ppStorage[celtFetched]->Release();
  318. ppStorage[celtFetched] = NULL;
  319. m_iCurItem--;
  320. }
  321. celtFetched = 0;
  322. }
  323. if( NULL != pceltFetched )
  324. {
  325. *pceltFetched = celtFetched;
  326. }
  327. return( hr );
  328. }
  329. STDMETHODIMP CEnumStorage::Skip( ULONG celt, ULONG *pceltFetched )
  330. {
  331. ULONG celtSkipped = 0;
  332. HRESULT hr = S_OK;
  333. if( celt + m_iCurItem >= m_cItems )
  334. {
  335. celtSkipped = m_cItems - m_iCurItem;
  336. m_iCurItem = m_cItems;
  337. hr = S_FALSE;
  338. }
  339. else
  340. {
  341. celtSkipped = celt;
  342. m_iCurItem += celt;
  343. }
  344. if( NULL != pceltFetched )
  345. {
  346. *pceltFetched = celtSkipped;
  347. }
  348. return( hr );
  349. }
  350. STDMETHODIMP CEnumStorage::Reset( void )
  351. {
  352. m_iCurItem = 0;
  353. return( S_OK );
  354. }
  355. STDMETHODIMP CEnumStorage::Clone( IMDSPEnumStorage ** ppStorage )
  356. {
  357. CComEnumStorage *pNewEnum;
  358. CComPtr<IMDSPEnumStorage> spEnum;
  359. HRESULT hr = S_OK;
  360. if( SUCCEEDED(hr) )
  361. {
  362. hr = CComEnumStorage ::CreateInstance(&pNewEnum);
  363. spEnum = pNewEnum;
  364. }
  365. if( SUCCEEDED(hr) )
  366. {
  367. hr = pNewEnum->Init( this , m_spDevice );
  368. }
  369. if( SUCCEEDED(hr) )
  370. {
  371. *ppStorage = spEnum;
  372. spEnum.Detach();
  373. }
  374. return( hr );
  375. }