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.

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