1 /*
2  * PROJECT:     ReactOS Compatibility Layer Shell Extension
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     CLayerStringList implementation
5  * COPYRIGHT:   Copyright 2015-2018 Mark Jansen (mark.jansen@reactos.org)
6  */
7 
8 #pragma once
9 
10 /* TODO: Use HSDB instead of PDB */
11 class CLayerStringList :
12     public CComObjectRootEx<CComMultiThreadModelNoCS>,
13     public IEnumString
14 {
15 public:
16     CLayerStringList()
17         :m_root(TAGID_NULL), m_layer(TAGID_NULL)
18     {
19         WCHAR buf[MAX_PATH];
20         SdbGetAppPatchDir(NULL, buf, MAX_PATH);
21         StringCchCatW(buf, _countof(buf), L"\\sysmain.sdb");
22         m_db = SdbOpenDatabase(buf, DOS_PATH);
23         Reset();
24     }
25 
26     ~CLayerStringList()
27     {
28         SdbCloseDatabase(m_db);
29     }
30 
31     virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, LPOLESTR *rgelt, ULONG *pceltFetched)
32     {
33         if (pceltFetched)
34             *pceltFetched = 0;
35 
36         while (celt && m_layer)
37         {
38             TAGID nameid = SdbFindFirstTag(m_db, m_layer, TAG_NAME);
39             if (nameid)
40             {
41                 LPWSTR name = SdbGetStringTagPtr(m_db, nameid);
42                 if (name && !IsBuiltinLayer(name))
43                 {
44                     ULONG Size = wcslen(name) + 1;
45 
46                     *rgelt = (LPOLESTR)::CoTaskMemAlloc(Size * sizeof(WCHAR));
47                     StringCchCopyW(*rgelt, Size, name);
48 
49                     if (pceltFetched)
50                         (*pceltFetched)++;
51 
52                     celt--;
53                     rgelt++;
54                 }
55             }
56             m_layer = SdbFindNextTag(m_db, m_root, m_layer);
57         }
58         return celt ? S_FALSE : S_OK;
59     }
60 
61     virtual HRESULT STDMETHODCALLTYPE Skip(ULONG celt)
62     {
63         while (m_layer && celt)
64         {
65             m_layer = SdbFindNextTag(m_db, m_root, m_layer);
66             --celt;
67         }
68         return celt ? S_FALSE : S_OK;
69     }
70 
71     virtual HRESULT STDMETHODCALLTYPE Reset()
72     {
73         m_root = m_layer = TAGID_NULL;
74         if (m_db)
75         {
76             m_root = SdbFindFirstTag(m_db, TAGID_ROOT, TAG_DATABASE);
77             if (m_root != TAGID_NULL)
78             {
79                 m_layer = SdbFindFirstTag(m_db, m_root, TAG_LAYER);
80                 return S_OK;
81             }
82         }
83         return E_FAIL;
84     }
85 
86     virtual HRESULT STDMETHODCALLTYPE Clone(IEnumString **ppenum)
87     {
88         return E_NOTIMPL;
89     }
90 
91 protected:
92     PDB m_db;
93     TAGID m_root;
94     TAGID m_layer;
95 
96 public:
97     BEGIN_COM_MAP(CLayerStringList)
98         COM_INTERFACE_ENTRY_IID(IID_IEnumString, IEnumString)
99     END_COM_MAP()
100 };
101 
102