xref: /reactos/dll/win32/shell32/folders.cpp (revision 2b91b296)
1 /*
2  *    Copyright 1997    Marcus Meissner
3  *    Copyright 1998    Juergen Schmied
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 
20 #include "precomp.h"
21 
22 WCHAR swShell32Name[MAX_PATH];
23 
24 DWORD NumIconOverlayHandlers = 0;
25 IShellIconOverlayIdentifier ** Handlers = NULL;
26 
27 static void InitIconOverlays(void)
28 {
29     HKEY hKey;
30     DWORD dwIndex, dwResult, dwSize;
31     WCHAR szName[MAX_PATH];
32     WCHAR szValue[100];
33     CLSID clsid;
34 
35     if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
36         return;
37 
38     if (RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwResult, NULL, NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
39     {
40         RegCloseKey(hKey);
41         return;
42     }
43 
44     Handlers = (IShellIconOverlayIdentifier **)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwResult * sizeof(IShellIconOverlayIdentifier*));
45     if (!Handlers)
46     {
47         RegCloseKey(hKey);
48         return;
49     }
50 
51     dwIndex = 0;
52 
53     CoInitialize(0);
54 
55     do
56     {
57         dwSize = sizeof(szName) / sizeof(WCHAR);
58         dwResult = RegEnumKeyExW(hKey, dwIndex, szName, &dwSize, NULL, NULL, NULL, NULL);
59 
60         if (dwResult == ERROR_NO_MORE_ITEMS)
61             break;
62 
63         if (dwResult == ERROR_SUCCESS)
64         {
65             dwSize = sizeof(szValue) / sizeof(WCHAR);
66             if (RegGetValueW(hKey, szName, NULL, RRF_RT_REG_SZ, NULL, szValue, &dwSize) == ERROR_SUCCESS)
67             {
68                 CComPtr<IShellIconOverlayIdentifier> Overlay;
69 
70                 CLSIDFromString(szValue, &clsid);
71                 dwResult = CoCreateInstance(clsid, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellIconOverlayIdentifier, &Overlay));
72                 if (dwResult == S_OK)
73                 {
74                     Handlers[NumIconOverlayHandlers] = Overlay.Detach();
75                     NumIconOverlayHandlers++;
76                 }
77             }
78         }
79 
80         dwIndex++;
81 
82     } while(1);
83 
84     RegCloseKey(hKey);
85 }
86 
87 BOOL
88 GetIconOverlay(LPCITEMIDLIST pidl, WCHAR * wTemp, int* pIndex)
89 {
90     DWORD Index;
91     HRESULT hResult;
92     int Priority;
93     int HighestPriority;
94     ULONG IconIndex;
95     ULONG Flags;
96     WCHAR szPath[MAX_PATH];
97 
98     if(!SHGetPathFromIDListW(pidl, szPath))
99         return FALSE;
100 
101     if (!Handlers)
102         InitIconOverlays();
103 
104     HighestPriority = 101;
105     IconIndex = NumIconOverlayHandlers;
106     for(Index = 0; Index < NumIconOverlayHandlers; Index++)
107     {
108         hResult = Handlers[Index]->IsMemberOf(szPath, SFGAO_FILESYSTEM);
109         if (hResult == S_OK)
110         {
111             hResult = Handlers[Index]->GetPriority(&Priority);
112             if (hResult == S_OK)
113             {
114                 if (Priority < HighestPriority)
115                 {
116                     HighestPriority = Priority;
117                     IconIndex = Index;
118                 }
119             }
120         }
121     }
122 
123     if (IconIndex == NumIconOverlayHandlers)
124         return FALSE;
125 
126     hResult = Handlers[IconIndex]->GetOverlayInfo(wTemp, MAX_PATH, pIndex, &Flags);
127 
128     if (hResult == S_OK)
129         return TRUE;
130     else
131         return FALSE;
132 }
133