ReactOS  0.4.15-dev-321-g2d9b385
CSHEnumClassesOfCategories.cpp
Go to the documentation of this file.
1 /*
2  * ReactOS Explorer
3  *
4  * Copyright 2016 Sylvain Deverre <deverre dot sylv at gmail dot com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * Wraps the component categories manager enum
23  */
24 
25 #include "shellbars.h"
26 
27 #define REGPATH L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Discardable\\PostSetup\\Component Categories"
28 #define IMPLEMENTING L"Implementing"
29 #define REQUIRING L"Requiring"
30 
31 typedef struct categoryCacheHeader
32 {
33  DWORD dwSize; // size of header only
34  DWORD version; // currently 1
35  SYSTEMTIME writeTime; // time we were written to registry
36  DWORD classCount; // number of classes following
38 
39 /*
40  * This class manages a cached explorer component categories items, writing cache if it
41  * doesn't exist yet.
42  * It is used by CSHEnumClassesOfCategories internally.
43  */
45 {
46  public:
48  virtual ~CComCatCachedCategory();
50  HRESULT STDMETHODCALLTYPE Initialize(CATID &catID, BOOL reloadCache);
51  private:
54  HRESULT CacheDSA();
57 };
58 
60 {
61  fLocalDsa = DSA_Create(sizeof(GUID), 5);
62 }
63 
65 {
66  HRESULT hr;
67 
68  fCategory = catID;
69  if (reloadCache || !LoadFromRegistry())
70  {
73  return hr;
74 
75  hr = CacheDSA();
77  return hr;
78  }
79  return S_OK;
80 }
81 
83 {
85 }
86 
88 {
89  WCHAR bufKey[MAX_PATH];
91  DWORD dataSize, i;
92  CComHeapPtr<CATCACHEHDR> buffer;
93  GUID *guidArray;
94 
95  if (!fLocalDsa)
96  return FALSE;
97 
98  dataSize = 0;
100  return FALSE;
101 
102  wsprintf(bufKey, L"%s\\%s\\%s", REGPATH , guidStr, L"Enum");
103 
104  // Try to read key and get proper value size
106  return FALSE;
107 
109 
111  guidArray = (GUID*)(buffer + 1);
112  for (i = 0; i < buffer->classCount; i++)
113  {
114  // Add class to cache
115  DSA_InsertItem(fLocalDsa, DSA_APPEND, guidArray + i);
116  }
117 
118  return TRUE;
119 }
120 
122 {
123  WCHAR bufKey[MAX_PATH];
125  UINT elemCount;
126  UINT i;
127  UINT bufferSize;
128  CComHeapPtr<CATCACHEHDR> buffer;
129  GUID *guidArray;
130  GUID *tmp;
131 
132  elemCount = DSA_GetItemCount(fLocalDsa);
133  bufferSize = sizeof(CATCACHEHDR) + elemCount * sizeof(GUID);
135  return E_FAIL;
136 
137  buffer.Attach((PCATCACHEHDR)CoTaskMemAlloc(bufferSize));
138  if (!buffer)
139  return E_OUTOFMEMORY;
140 
141  // Correctly fill cache header
142  buffer->dwSize = sizeof(CATCACHEHDR);
143  buffer->version = 1;
144  GetSystemTime(&buffer->writeTime);
145  buffer->classCount = (DWORD)elemCount;
146 
147  guidArray = (GUID*)(buffer + 1);
148  wsprintf(bufKey, L"%s\\%s\\%s", REGPATH , guidStr, L"Enum");
149 
150  // Write DSA contents inside the memory buffer allocated
151  for(i = 0; i < elemCount; i++)
152  {
153  tmp = (GUID*)DSA_GetItemPtr(fLocalDsa, i);
154  if (tmp)
155  {
156  guidArray[i] = *tmp;
157  }
158  }
159 
160  // Save items to registry
162 
163  guidArray = NULL;
164  return S_OK;
165 }
166 
168 {
169  HRESULT hr;
170  CComPtr<ICatInformation> pCatInformation;
171  CComPtr<IEnumGUID> pEnumGUID;
172  ULONG pFetched;
173  CLSID tmp;
174 
175  // Get component categories manager instance
176  hr = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_INPROC_SERVER,
177  IID_PPV_ARG(ICatInformation, &pCatInformation));
178  if (FAILED_UNEXPECTEDLY(hr))
179  return hr;
180 
181  // Get the proper enumerator
182  hr = pCatInformation->EnumClassesOfCategories(1, &fCategory, NULL, NULL, &pEnumGUID);
183  if (FAILED_UNEXPECTEDLY(hr))
184  return hr;
185 
186  // Enumerate elements
187  do
188  {
189  pFetched = 0;
190  pEnumGUID->Next(1, &tmp, &pFetched);
191  if (pFetched)
192  {
194  return E_OUTOFMEMORY;
195  }
196  }
197  while (pFetched > 0);
198  return S_OK;
199 }
200 
202 {
203  INT i;
204  for(i = 0; i < DSA_GetItemCount(fLocalDsa); i++)
205  {
207  return E_OUTOFMEMORY;
208  }
209  return S_OK;
210 }
211 
213  public CComCoClass<CSHEnumClassesOfCategories>,
214  public CComObjectRootEx<CComMultiThreadModelNoCS>,
215  public IEnumGUID
216 {
217  private:
218  CComPtr<ICatInformation> fCatInformation;
221 
222  public:
224  virtual ~CSHEnumClassesOfCategories();
225  virtual HRESULT STDMETHODCALLTYPE Initialize(ULONG cImplemented, CATID *pImplemented, ULONG cRequired, CATID *pRequired);
226  // *** IEnumGUID methods ***
227  virtual HRESULT STDMETHODCALLTYPE Clone(IEnumCLSID **ppvOut);
228  virtual HRESULT STDMETHODCALLTYPE Next(ULONG cElt, CLSID *pElts, ULONG *pFetched);
229  virtual HRESULT STDMETHODCALLTYPE Reset();
230  virtual HRESULT STDMETHODCALLTYPE Skip(ULONG nbElts);
231 
233  COM_INTERFACE_ENTRY_IID(IID_IEnumGUID, IEnumGUID)
234  END_COM_MAP()
235 };
236 
238 {
239  fCursor = 0;
240  fDsa = DSA_Create(sizeof(GUID), 5);
241 }
242 
244 {
245  if (fDsa)
246  DSA_Destroy(fDsa);
247 }
248 
249 HRESULT CSHEnumClassesOfCategories::Initialize(ULONG cImplemented, CATID *pImplemented, ULONG cRequired, CATID *pRequired)
250 {
251  UINT i;
252  HRESULT hr;
253 
254  if (!fDsa)
255  return E_FAIL;
256 
257  // Parameter validation:
258  // - We must have at least one category to manage.
259  // - The array pointers must not be NULL if there is a non-zero
260  // element count specified for them.
261  if (cImplemented == 0 && cRequired == 0)
262  return E_INVALIDARG;
263  if ((cImplemented && !pImplemented) || (cRequired && !pRequired))
264  return E_INVALIDARG;
265 
266  // For each implemented category, create a cache and add it to our local DSA.
267  for (i = 0; i < cImplemented; i++)
268  {
269  CComCatCachedCategory cachedCat;
270  hr = cachedCat.Initialize(pImplemented[i], FALSE);
271  if (FAILED_UNEXPECTEDLY(hr))
272  return hr;
273  cachedCat.WriteCacheToDSA(fDsa);
274  }
275 
276  // TODO: Implement caching of the required categories.
277  if (cRequired > 0)
278  {
279  FIXME("Implement required categories class enumeration\n");
280 
281  // Only fail in case we didn't look at the implemented categories.
282  if (cImplemented == 0)
283  return E_NOTIMPL;
284  }
285 
286  return S_OK;
287 }
288 
289 // *** IEnumGUID methods ***
290 
292 {
293  return E_NOTIMPL;
294 }
295 
297 {
298  ULONG i;
299  ULONG read;
300  GUID *tmp;
301 
302  if (!pElts)
303  return E_INVALIDARG;
304  read = 0;
305  for (i = 0; i < cElt && (fCursor < (ULONG)DSA_GetItemCount(fDsa)); i++)
306  {
307  tmp = (GUID*)DSA_GetItemPtr(fDsa, fCursor + i);
308  if (!tmp)
309  break;
310  pElts[i] = *tmp;
311  read++;
312  }
313  fCursor += read;
314  if (pFetched)
315  *pFetched = read;
316  return S_OK;
317 }
318 
320 {
321  fCursor = 0;
322  return S_OK;
323 }
324 
326 {
327  if (fCursor + nbElts >= (ULONG)DSA_GetItemCount(fDsa))
328  return E_INVALIDARG;
329  fCursor += nbElts;
330  return S_OK;
331 }
332 
333 /*************************************************************************
334  * SHEnumClassesOfCategories [BROWSEUI.136]
335  */
336 extern "C" HRESULT WINAPI SHEnumClassesOfCategories(ULONG cImplemented, CATID *pImplemented, ULONG cRequired, CATID *pRequired, IEnumGUID **out)
337 {
338  HRESULT hr;
339 
340  if (!out)
341  return E_INVALIDARG;
342 
343  hr = ShellObjectCreatorInit<CSHEnumClassesOfCategories>(
344  cImplemented, pImplemented, cRequired, pRequired, IID_PPV_ARG(IEnumGUID, out));
345  if (FAILED_UNEXPECTEDLY(hr))
346  return hr;
347  return S_OK;
348 }
virtual HRESULT STDMETHODCALLTYPE Clone(IEnumCLSID **ppvOut)
#define TRUE
Definition: types.h:120
HRESULT hr
Definition: shlfolder.c:183
#define REG_BINARY
Definition: nt_native.h:1496
#define HKEY_CURRENT_USER
Definition: winreg.h:11
BOOL WINAPI DSA_Destroy(HDSA hdsa)
Definition: dsa.c:103
GLuint buffer
Definition: glext.h:5915
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
#define DWORD
Definition: nt_native.h:44
int32_t INT
Definition: typedefs.h:57
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static WCHAR guidStr[]
Definition: asn.c:531
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
Definition: dsa.c:44
HRESULT STDMETHODCALLTYPE Initialize(CATID &catID, BOOL reloadCache)
unsigned int BOOL
Definition: ntddk_ex.h:94
HRESULT WINAPI SHEnumClassesOfCategories(ULONG cImplemented, CATID *pImplemented, ULONG cRequired, CATID *pRequired, IEnumGUID **out)
#define FIXME(fmt,...)
Definition: debug.h:111
#define E_INVALIDARG
Definition: ddrawi.h:101
#define IEnumCLSID
Definition: comcat.idl:39
smooth NULL
Definition: ftsmooth.c:416
HDSA WINAPI DSA_Create(INT nSize, INT nGrow)
Definition: dsa.c:71
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:541
virtual HRESULT STDMETHODCALLTYPE Initialize(ULONG cImplemented, CATID *pImplemented, ULONG cRequired, CATID *pRequired)
VOID WINAPI GetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:327
#define DSA_GetItemCount(hdsa)
Definition: commctrl.h:4822
#define SHSetValue
Definition: shlwapi.h:92
#define SHGetValue
Definition: shlwapi.h:70
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:78
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
CComPtr< ICatInformation > fCatInformation
static const WCHAR L[]
Definition: oid.c:1250
#define DSA_APPEND
Definition: commctrl.h:4783
virtual HRESULT STDMETHODCALLTYPE Next(ULONG cElt, CLSID *pElts, ULONG *pFetched)
struct categoryCacheHeader * PCATCACHEHDR
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
virtual HRESULT STDMETHODCALLTYPE Skip(ULONG nbElts)
#define S_OK
Definition: intsafe.h:59
#define REGPATH
#define DSA_ERR
Definition: commctrl.h:4784
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:561
#define E_NOTIMPL
Definition: ddrawi.h:99
LPVOID WINAPI DSA_GetItemPtr(HDSA hdsa, INT nIndex)
Definition: dsa.c:162
unsigned int UINT
Definition: ndis.h:50
GLenum GLsizei dataSize
Definition: glext.h:11123
struct categoryCacheHeader CATCACHEHDR
unsigned int ULONG
Definition: retypes.h:1
virtual HRESULT STDMETHODCALLTYPE Reset()
#define END_COM_MAP()
Definition: atlcom.h:552
INT WINAPI DSA_InsertItem(HDSA hdsa, INT nIndex, LPVOID pSrc)
Definition: dsa.c:251
#define IMPLEMENTING
#define wsprintf
Definition: winuser.h:5840
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)