walk.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 10k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. // walk.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include <shlobj.h>
  5. #include <shellapi.h>
  6. #include <shlwapi.h>
  7. #include "idlist.h"
  8. #define ARRAYSIZE(a)                (sizeof(a)/sizeof(a[0]))
  9. HRESULT RefreshFolder(LPCTSTR pszFolder, UINT uFlushFlags)
  10. {
  11.     IShellFolder *psf;
  12.     HRESULT hr = SHGetDesktopFolder(&psf);
  13.     if (SUCCEEDED(hr))
  14.     {
  15.         ULONG ulCount;
  16.         LPITEMIDLIST pidl;
  17.         WCHAR wszPath[MAX_PATH];
  18.         SHAnsiToUnicode(pszFolder, wszPath, ARRAYSIZE(wszPath));
  19.         hr = psf->ParseDisplayName(NULL, 0, wszPath, &ulCount, &pidl, NULL);
  20.         if (SUCCEEDED(hr))
  21.         {
  22.             SHChangeNotify(SHCNE_UPDATEDIR, SHCNF_IDLIST | uFlushFlags, pidl, NULL);
  23.             CoTaskMemFree(pidl);
  24.         }
  25.         psf->Release();
  26.     }
  27.     return hr;
  28. }
  29. STDAPI SHGetIDListFromUnk(IUnknown *punk, LPITEMIDLIST *ppidl)
  30. {
  31.     HRESULT hres = E_NOINTERFACE;
  32.     *ppidl = NULL;
  33.     IPersistFolder2 *ppf;
  34.     if (punk && SUCCEEDED(punk->QueryInterface(IID_IPersistFolder2, (void **)&ppf)))
  35.     {
  36.         hres = ppf->GetCurFolder(ppidl);
  37.         ppf->Release();
  38.     }
  39.     return hres;
  40. }
  41. void DumpItemInfo(IShellFolder *psf, LPCITEMIDLIST pidl, DWORD dwAttribs, UINT cDepth)
  42. {
  43.     HRESULT hres;
  44.     STRRET strret;
  45.     WCHAR szName[MAX_PATH];
  46.     for (UINT i = 0; i < cDepth; i++)
  47.         printf("  ");
  48.     // try a name -> parse -> name round trip of the in folder name
  49.     hres = psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING | SHGDN_INFOLDER, &strret);
  50.     if (SUCCEEDED(hres) && SUCCEEDED(StrRetToBufW(&strret, pidl, szName, ARRAYSIZE(szName))))
  51.     {
  52.         LPITEMIDLIST pidl;
  53.         hres = psf->ParseDisplayName(NULL, NULL, szName, NULL, &pidl, NULL);
  54.         if (SUCCEEDED(hres))
  55.         {
  56.             hres = psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING | SHGDN_INFOLDER, &strret);
  57.             if (SUCCEEDED(hres) && SUCCEEDED(StrRetToBufW(&strret, pidl, szName, ARRAYSIZE(szName))))
  58.             {
  59.             }
  60.             CoTaskMemFree(pidl);
  61.         }
  62.     }
  63.     hres = psf->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
  64.     if (SUCCEEDED(hres) && SUCCEEDED(StrRetToBufW(&strret, pidl, szName, ARRAYSIZE(szName))))
  65.     {
  66.         LPITEMIDLIST pidl;
  67.         IShellFolder *psfDesktop;
  68.         if (SUCCEEDED(SHGetDesktopFolder(&psfDesktop)))
  69.         {
  70.             hres = psfDesktop->ParseDisplayName(NULL, NULL, szName, NULL, &pidl, NULL);
  71.             if (SUCCEEDED(hres))
  72.             {
  73.                 hres = psfDesktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
  74.                 if (SUCCEEDED(hres) && SUCCEEDED(StrRetToBufW(&strret, pidl, szName, ARRAYSIZE(szName))))
  75.                 {
  76.                 }
  77.                 CoTaskMemFree(pidl);
  78.             }
  79.             psfDesktop->Release();
  80.         }
  81.     }
  82.     hres = psf->GetDisplayNameOf(pidl, SHGDN_INFOLDER, &strret);
  83.     if (SUCCEEDED(hres))
  84.     {
  85.         TCHAR szName[MAX_PATH];
  86.         StrRetToBuf(&strret, pidl, szName, ARRAYSIZE(szName));
  87.         printf("name:'%s'", szName);
  88.     }
  89.     LPITEMIDLIST pidlFolder;
  90.     if (SUCCEEDED(SHGetIDListFromUnk(psf, &pidlFolder)))
  91.     {
  92.         LPITEMIDLIST pidlFull = ILCombine(pidlFolder, pidl);
  93.         if (pidlFull)
  94.         {
  95.             SHFILEINFO sfi;
  96.             SHGetFileInfo((LPCTSTR)pidlFull, 0, &sfi, sizeof(sfi), SHGFI_PIDL | SHGFI_TYPENAME | SHGFI_ATTRIBUTES | SHGFI_DISPLAYNAME);
  97.             printf("type:'%s'", sfi.szTypeName);
  98.             CoTaskMemFree(pidlFull);
  99.         }
  100.         CoTaskMemFree(pidlFolder);
  101.     }
  102.     if (dwAttribs)
  103.         printf(TEXT("attribs: "));
  104.     if (dwAttribs & SFGAO_FILESYSTEM)
  105.         printf(TEXT("SFGAO_FILESYSTEM "));
  106.     if (dwAttribs & SFGAO_FILESYSANCESTOR)
  107.         printf(TEXT("SFGAO_FILESYSANCESTOR "));
  108.     if (dwAttribs & SFGAO_FOLDER)
  109.         printf(TEXT("SFGAO_FOLDER "));
  110.     printf(TEXT("rn"));
  111. }
  112. void DumpFullPath(LPCITEMIDLIST pidlFull, DWORD dwAttribs)
  113. {
  114.     TCHAR szPath[MAX_PATH];
  115.     if (SHGetPathFromIDList(pidlFull, szPath))
  116.     {
  117.         if (!(dwAttribs & SFGAO_FILESYSTEM))
  118.             printf(TEXT("non file system object returned from SHGetPathFromIDList() %srn"), szPath);
  119.     }
  120.     else
  121.     {
  122.         if (dwAttribs & SFGAO_FILESYSTEM)
  123.             printf(TEXT("file system object not returned from SHGetPathFromIDList() %srn"), szPath);
  124.     }
  125. }
  126. // STDAPI_(LPITEMIDLIST) SHLogILFromFSIL(LPCITEMIDLIST pidlFS);
  127. HRESULT WalkFolder(IShellFolder *psf, LPCITEMIDLIST pidlFolder, UINT cDepth, UINT cDepthLimit)
  128. {
  129.     if (cDepth == cDepthLimit)
  130.         return S_FALSE;     // done
  131.     IEnumIDList *penum;
  132.     HRESULT hres = psf->EnumObjects(NULL, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &penum);
  133.     if (SUCCEEDED(hres))
  134.     {
  135.         LPITEMIDLIST pidl;
  136.         ULONG c;
  137.         while (penum->Next(1, &pidl, &c) == NOERROR)
  138.         {
  139.             DWORD dwAttribs = SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER;
  140.             hres = psf->GetAttributesOf(1, (LPCITEMIDLIST *)&pidl, &dwAttribs);
  141.             DumpItemInfo(psf, pidl, dwAttribs, cDepth);
  142.             CoTaskMemFree(pidl);
  143.         }
  144.         penum->Release();
  145.     }
  146.     hres = psf->EnumObjects(NULL, SHCONTF_NONFOLDERS | SHCONTF_FOLDERS, &penum);
  147.     if (SUCCEEDED(hres))
  148.     {
  149.         LPITEMIDLIST pidl;
  150.         ULONG c;
  151.         while (penum->Next(1, &pidl, &c) == NOERROR)
  152.         {
  153.             DWORD dwAttribs = SFGAO_FILESYSTEM | SFGAO_FILESYSANCESTOR | SFGAO_FOLDER;
  154.             hres = psf->GetAttributesOf(1, (LPCITEMIDLIST *)&pidl, &dwAttribs);
  155.             IShellFolder *psfNew;
  156.             hres = psf->BindToObject(pidl, NULL, IID_IShellFolder, (void **)&psfNew);
  157.             if (SUCCEEDED(hres) && psfNew)  // work around Web Fodlers bug, success but NULL
  158.             {
  159.                 LPITEMIDLIST pidlFull = ILCombine(pidlFolder, pidl);
  160.                 if (pidlFull)
  161.                 {
  162.                     DumpFullPath(pidlFull, dwAttribs);
  163. //                    LPITEMIDLIST pidlT = SHLogILFromFSIL(pidlFull);
  164. //                    if (pidlT)
  165. //                        CoTaskMemFree(pidlT);
  166.                     hres = WalkFolder(psfNew, pidlFull, cDepth + 1, cDepthLimit);
  167.                     CoTaskMemFree(pidlFull);
  168.                 }
  169.                 psfNew->Release();
  170.             }
  171.             CoTaskMemFree(pidl);
  172.         }
  173.         penum->Release();
  174.     }
  175.     return hres;
  176. }
  177. HRESULT SetStartFolder(int argc, char* argv[], IShellFolder **ppsf, LPITEMIDLIST *ppidl)
  178. {
  179.     *ppsf = NULL;
  180.     *ppidl = NULL;
  181.     IShellFolder *psfDesktop;
  182.     HRESULT hres = SHGetDesktopFolder(&psfDesktop);
  183.     if (SUCCEEDED(hres))
  184.     {
  185.         if (argc <= 1)
  186.         {
  187.             hres = SHGetSpecialFolderLocation(NULL, CSIDL_DESKTOP, ppidl);
  188.             if (SUCCEEDED(hres))
  189.             {
  190.                 *ppsf = psfDesktop;
  191.                 return hres;
  192.             }
  193.         }
  194.         else 
  195.         {
  196.             int csidl = atoi(argv[1]);
  197.             if (csidl)
  198.             {
  199.                 hres = SHGetSpecialFolderLocation(NULL, csidl, ppidl);
  200.                 if (SUCCEEDED(hres))
  201.                 {
  202.                     hres = psfDesktop->BindToObject(*ppidl, NULL, IID_IShellFolder, (void **)ppsf);
  203.                     if (SUCCEEDED(hres))
  204.                         return hres;
  205.                     CoTaskMemFree(*ppidl);
  206.                     *ppidl = NULL;
  207.                 }
  208.             }
  209.             else
  210.             {
  211.                 WCHAR wszPath[MAX_PATH];
  212.                 SHAnsiToUnicode(argv[1], wszPath, ARRAYSIZE(wszPath));
  213.                 hres = psfDesktop->ParseDisplayName(NULL, NULL, wszPath, NULL, ppidl, NULL);
  214.                 if (SUCCEEDED(hres))
  215.                 {
  216.                     hres = psfDesktop->BindToObject(*ppidl, NULL, IID_IShellFolder, (void **)ppsf);
  217.                     if (FAILED(hres))
  218.                     {
  219.                         CoTaskMemFree(*ppidl);
  220.                         *ppidl = NULL;
  221.                     }
  222.                 }
  223.             }
  224.         }
  225.     }
  226.     return hres;
  227. }
  228. // use these as cmd line args
  229. // CLSID_MyComputerCLSID_ControlPanel
  230. // "notify.exe ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}::{21EC2020-3AEA-1069-A2DD-08002B30309D}"
  231. // CLSID_MyComputerCLSID_ControlPanelCLSID_ConnectionsFolder
  232. // "notify.exe ::{20D04FE0-3AEA-1069-A2D8-08002B30309D}::{21EC2020-3AEA-1069-A2DD-08002B30309D}::{7007acc7-3202-11d1-aad2-00805fc1270e}"
  233. // CLSID_MyComputerCLSID_ControlPanelCLSID_Printers
  234. // "::{20D04FE0-3AEA-1069-A2D8-08002B30309D}::{21EC2020-3AEA-1069-A2DD-08002B30309D}::{2227A280-3AEA-1069-A2DE-08002B30309D}";
  235. // 
  236. int _cdecl main(int argc, char* argv[])
  237. {
  238.     CoInitialize(0);
  239. #if 0
  240.     IShellFolder *psfDesktop;
  241.     HRESULT hres = SHGetDesktopFolder(&psfDesktop);
  242.     if (SUCCEEDED(hres))
  243.     {
  244.         LPITEMIDLIST pidl;
  245.         psfDesktop->ParseDisplayName(NULL, NULL, L"F:\Can't Enum\Can Enum", NULL, &pidl, NULL);
  246. //        psfDesktop->ParseDisplayName(NULL, NULL, L"\\chrisg06\public\non existant", NULL, &pidl, NULL);
  247. //        psfDesktop->ParseDisplayName(NULL, NULL, L"\\chrisg06\public\no access", NULL, &pidl, NULL);
  248.         psfDesktop->ParseDisplayName(NULL, NULL, L"\desktop", NULL, &pidl, NULL);
  249.         psfDesktop->ParseDisplayName(NULL, NULL, L"\desktop", NULL, &pidl, NULL);
  250.         STRRET strret;
  251.         psfDesktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
  252.     }
  253. #endif
  254.     IShellFolder *psfStart;
  255.     LPITEMIDLIST pidlStart;
  256.     if (SUCCEEDED(SetStartFolder(argc, argv, &psfStart, &pidlStart)))
  257.     {
  258.         WalkFolder(psfStart, pidlStart, 0, 60);
  259.         psfStart->Release();
  260.         CoTaskMemFree(pidlStart);
  261.     }
  262.     CoUninitialize();
  263.     return 0;
  264. }