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.

129 lines
3.5 KiB

  1. #include "shellprv.h"
  2. #include "treewkcb.h"
  3. #include "propsht.h"
  4. CBaseTreeWalkerCB::CBaseTreeWalkerCB(): _cRef(1)
  5. {
  6. }
  7. CBaseTreeWalkerCB::~CBaseTreeWalkerCB()
  8. {
  9. }
  10. HRESULT CBaseTreeWalkerCB::QueryInterface(REFIID riid, void **ppv)
  11. {
  12. static const QITAB qit[] = {
  13. QITABENT(CBaseTreeWalkerCB, IShellTreeWalkerCallBack),
  14. { 0 },
  15. };
  16. return QISearch(this, qit, riid, ppv);
  17. }
  18. ULONG CBaseTreeWalkerCB::AddRef()
  19. {
  20. return InterlockedIncrement(&_cRef);
  21. }
  22. ULONG CBaseTreeWalkerCB::Release()
  23. {
  24. ASSERT( 0 != _cRef );
  25. ULONG cRef = InterlockedDecrement(&_cRef);
  26. if ( 0 == cRef )
  27. {
  28. delete this;
  29. }
  30. return cRef;
  31. }
  32. HRESULT CBaseTreeWalkerCB::FoundFile(LPCWSTR pwszPath, TREEWALKERSTATS *ptws, WIN32_FIND_DATAW * pwfd)
  33. {
  34. return E_NOTIMPL;
  35. }
  36. HRESULT CBaseTreeWalkerCB::EnterFolder(LPCWSTR pwszPath, TREEWALKERSTATS *ptws, WIN32_FIND_DATAW * pwfd)
  37. {
  38. return E_NOTIMPL;
  39. }
  40. HRESULT CBaseTreeWalkerCB::LeaveFolder(LPCWSTR pwszPath, TREEWALKERSTATS *ptws)
  41. {
  42. return E_NOTIMPL;
  43. }
  44. HRESULT CBaseTreeWalkerCB::HandleError(LPCWSTR pwszPath, TREEWALKERSTATS *ptws, HRESULT ErrorCode)
  45. {
  46. return E_NOTIMPL;
  47. }
  48. //
  49. // Folder size computation tree walker callback class
  50. //
  51. class CFolderSizeTreeWalkerCB : public CBaseTreeWalkerCB
  52. {
  53. public:
  54. CFolderSizeTreeWalkerCB(FOLDERCONTENTSINFO * pfci);
  55. // IShellTreeWalkerCallBack
  56. STDMETHODIMP FoundFile(LPCWSTR pwszPath, TREEWALKERSTATS *ptws, WIN32_FIND_DATAW * pwfd);
  57. STDMETHODIMP EnterFolder(LPCWSTR pwszPath, TREEWALKERSTATS *ptws, WIN32_FIND_DATAW * pwfd);
  58. protected:
  59. FOLDERCONTENTSINFO * _pfci;
  60. TREEWALKERSTATS _twsInitial;
  61. };
  62. CFolderSizeTreeWalkerCB::CFolderSizeTreeWalkerCB(FOLDERCONTENTSINFO * pfci): _pfci(pfci)
  63. {
  64. // set the starting values for the twsInitial so we can have cumulative results
  65. _twsInitial.nFiles = _pfci->cFiles;
  66. _twsInitial.nFolders = _pfci->cFolders;
  67. _twsInitial.ulTotalSize = _pfci->cbSize;
  68. _twsInitial.ulActualSize = _pfci->cbActualSize;
  69. }
  70. HRESULT CFolderSizeTreeWalkerCB::FoundFile(LPCWSTR pwszPath, TREEWALKERSTATS *ptws, WIN32_FIND_DATAW * pwfd)
  71. {
  72. if (_pfci->bContinue)
  73. {
  74. _pfci->cbSize = _twsInitial.ulTotalSize + ptws->ulTotalSize;
  75. _pfci->cbActualSize = _twsInitial.ulActualSize + ptws->ulActualSize;
  76. _pfci->cFiles = _twsInitial.nFiles + ptws->nFiles;
  77. }
  78. return _pfci->bContinue ? S_OK : E_FAIL;
  79. }
  80. HRESULT CFolderSizeTreeWalkerCB::EnterFolder(LPCWSTR pwszPath, TREEWALKERSTATS *ptws, WIN32_FIND_DATAW * pwfd)
  81. {
  82. if (_pfci->bContinue)
  83. {
  84. _pfci->cFolders = _twsInitial.nFolders + ptws->nFolders;
  85. }
  86. return _pfci->bContinue ? S_OK : E_FAIL;
  87. }
  88. //
  89. // Main function for folder size computation
  90. //
  91. STDAPI FolderSize(LPCTSTR pszDir, FOLDERCONTENTSINFO *pfci)
  92. {
  93. HRESULT hrInit = SHCoInitialize(); // in case our caller did not do this
  94. HRESULT hr = E_FAIL;
  95. CFolderSizeTreeWalkerCB *pfstwcb = new CFolderSizeTreeWalkerCB(pfci);
  96. if (pfstwcb)
  97. {
  98. IShellTreeWalker *pstw;
  99. hr = CoCreateInstance(CLSID_CShellTreeWalker, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellTreeWalker, &pstw));
  100. if (SUCCEEDED(hr))
  101. {
  102. hr = pstw->WalkTree(WT_NOTIFYFOLDERENTER, pszDir, NULL, 0, SAFECAST(pfstwcb, IShellTreeWalkerCallBack *));
  103. pstw->Release();
  104. }
  105. pfstwcb->Release();
  106. }
  107. SHCoUninitialize(hrInit);
  108. return hr;
  109. }