Source code of Windows XP (NT5)
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.

129 lines
2.7 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. #include "filefldr.h"
  4. #include "stgenum.h"
  5. // Construction / Destruction
  6. CFSFolderEnumSTATSTG::CFSFolderEnumSTATSTG(CFSFolder* psf) :
  7. _cRef(1),
  8. _pfsf(psf),
  9. _cIndex(0)
  10. {
  11. _pfsf->AddRef();
  12. _pfsf->_GetPath(_szSearch);
  13. PathAppend(_szSearch, TEXT("*")); // we're looking for everything.
  14. _hFindFile = INVALID_HANDLE_VALUE;
  15. DllAddRef();
  16. }
  17. CFSFolderEnumSTATSTG::~CFSFolderEnumSTATSTG()
  18. {
  19. _pfsf->Release();
  20. if (_hFindFile != INVALID_HANDLE_VALUE)
  21. FindClose(_hFindFile);
  22. DllRelease();
  23. }
  24. //-----------------------------------------------------------------------------
  25. // IUnknown
  26. //-----------------------------------------------------------------------------
  27. STDMETHODIMP_(ULONG) CFSFolderEnumSTATSTG::AddRef()
  28. {
  29. return InterlockedIncrement(&_cRef);
  30. }
  31. STDMETHODIMP_(ULONG) CFSFolderEnumSTATSTG::Release()
  32. {
  33. if (InterlockedDecrement(&_cRef))
  34. return _cRef;
  35. delete this;
  36. return 0;
  37. }
  38. STDMETHODIMP CFSFolderEnumSTATSTG::QueryInterface(REFIID riid, void **ppv)
  39. {
  40. static const QITAB qit[] = {
  41. QITABENT(CFSFolderEnumSTATSTG, IEnumSTATSTG), // IEnumSTATSTG
  42. { 0 },
  43. };
  44. return QISearch(this, qit, riid, ppv);
  45. }
  46. // IEnumSTATSTG
  47. STDMETHODIMP CFSFolderEnumSTATSTG::Next(ULONG celt, STATSTG *rgelt, ULONG *pceltFetched)
  48. {
  49. HRESULT hr = S_FALSE; // assume end of the enum
  50. ASSERT(rgelt);
  51. ZeroMemory(rgelt, sizeof(STATSTG)); // per COM conventions
  52. if (pceltFetched)
  53. *pceltFetched = 0;
  54. WIN32_FIND_DATA fd;
  55. BOOL fFound = FALSE;
  56. BOOL fGotFD = FALSE;
  57. do
  58. {
  59. if (_cIndex == 0)
  60. {
  61. // this is the first file we look at.
  62. fGotFD = S_OK == SHFindFirstFile(_szSearch, &fd, &_hFindFile);
  63. }
  64. else
  65. {
  66. fGotFD = FindNextFile(_hFindFile, &fd);
  67. }
  68. _cIndex++;
  69. if (fGotFD)
  70. {
  71. ASSERT(fd.cFileName[0]);
  72. if (!PathIsDotOrDotDot(fd.cFileName))
  73. fFound = TRUE;
  74. }
  75. } while (fGotFD && !fFound);
  76. if (fFound)
  77. {
  78. hr = StatStgFromFindData(&fd, STATFLAG_DEFAULT, rgelt);
  79. if (SUCCEEDED(hr))
  80. {
  81. if (pceltFetched)
  82. *pceltFetched = 1;
  83. }
  84. }
  85. else if (_hFindFile != INVALID_HANDLE_VALUE)
  86. {
  87. // we'll be nice and close the handle as early as possible.
  88. FindClose(_hFindFile);
  89. _hFindFile = INVALID_HANDLE_VALUE;
  90. }
  91. return hr;
  92. }
  93. STDMETHODIMP CFSFolderEnumSTATSTG::Reset()
  94. {
  95. HRESULT hr = S_OK;
  96. _cIndex = 0;
  97. if (_hFindFile != INVALID_HANDLE_VALUE)
  98. {
  99. FindClose(_hFindFile);
  100. _hFindFile = INVALID_HANDLE_VALUE;
  101. }
  102. return hr;
  103. }