PageRenderTime 36ms CodeModel.GetById 20ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 1ms

/Visual Studio 2008/CppExeCOMServer/Reg.cpp

#
C++ | 352 lines | 164 code | 41 blank | 147 comment | 39 complexity | bb14c498b4ae461f56e5c0febd2a740a MD5 | raw file
  1/****************************** Module Header ******************************\
  2Module Name:  Reg.cpp
  3Project:      CppExeCOMServer
  4Copyright (c) Microsoft Corporation.
  5
  6
  7
  8This source is subject to the Microsoft Public License.
  9See http://www.microsoft.com/opensource/licenses.mspx#Ms-PL.
 10All other rights reserved.
 11
 12THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 13EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
 14WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 15\***************************************************************************/
 16
 17#include "Reg.h"
 18#include <strsafe.h>
 19
 20
 21//
 22//   FUNCTION: SetHKCRRegistryKeyAndValue
 23//
 24//   PURPOSE: The function creates a HKCR registry key and sets the specified 
 25//   registry value.
 26//
 27//   PARAMETERS:
 28//   * pszSubKey - specifies the registry key under HKCR. If the key does not 
 29//     exist, the function will create the registry key.
 30//   * pszValueName - specifies the registry value to be set. If pszValueName 
 31//     is NULL, the function will set the default value.
 32//   * pszData - specifies the string data of the registry value.
 33// 
 34HRESULT SetHKCRRegistryKeyAndValue(PCWSTR pszSubKey,
 35                                   PCWSTR pszValueName, 
 36                                   PCWSTR pszData)
 37{
 38    HRESULT hr;
 39    HKEY hKey = NULL;
 40
 41    // Creates the specified registry key. If the key already exists, the 
 42    // function opens it. 
 43    hr = HRESULT_FROM_WIN32(RegCreateKeyEx(HKEY_CLASSES_ROOT, pszSubKey, 0, 
 44        NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, NULL));
 45
 46    // Set the value of the key.
 47    if (SUCCEEDED(hr))
 48    {
 49        DWORD cbData = (pszData == NULL) ? 0 : (lstrlen(pszData) * sizeof(*pszData));
 50        hr = HRESULT_FROM_WIN32(RegSetValueEx(hKey, pszValueName, 0, REG_SZ, 
 51            (LPBYTE)pszData, cbData));
 52        
 53        RegCloseKey(hKey);
 54    }
 55
 56    return hr;
 57}
 58
 59
 60//
 61//   FUNCTION: RegisterLocalServer
 62//
 63//   PURPOSE: This helper function registers the out-of-process component in 
 64//   the registry.
 65//
 66//   PARAMETERS:
 67//   * pszModule - Path of the module that contains the component
 68//   * clsid - Class ID of the component
 69//   * pszFriendlyName - Friendly name
 70//   * pszThreadModel - Threading model
 71//   * libid - Type library ID
 72//   * pszProgID - ProgID of the component
 73//   * pszVerIndProgID - Version independent ProgID
 74//
 75//   NOTE: The function creates the HKCR\CLSID\{<CLSID>} key and the 
 76//   HKCR\<ProgID> key in the registry.
 77// 
 78//   HKCR
 79//   {
 80//      <ProgID> = s '<Friendly Name>'
 81//      {
 82//          CLSID = s '{<CLSID>}'
 83//      }
 84//      <VersionIndependentProgID> = s '<Friendly Name>'
 85//      {
 86//          CLSID = s '{<CLSID>}'
 87//          CurVer = s '<ProgID>'
 88//      }
 89//      NoRemove CLSID
 90//      {
 91//          ForceRemove {<CLSID>} = s '<Friendly Name>'
 92//          {
 93//              ProgID = s '<ProgID>'
 94//              VersionIndependentProgID = s '<VersionIndependentProgID>'
 95//              LocalServer32 = s '%MODULE%'
 96//              TypeLib = s '{<LIBID>}'
 97//          }
 98//      }
 99//   }
100//
101HRESULT RegisterLocalServer(PCWSTR pszModule, 
102                           const CLSID& clsid, 
103                           PCWSTR pszFriendlyName,
104                           const IID& libid,
105                           PCWSTR pszProgID, 
106                           PCWSTR pszVerIndProgID)
107{
108    HRESULT hr;
109
110    wchar_t szCLSID[MAX_PATH];
111    StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
112
113    wchar_t szLIBID[MAX_PATH];
114    StringFromGUID2(libid, szLIBID, ARRAYSIZE(szLIBID));
115
116    wchar_t szSubkey[MAX_PATH];
117
118    // Create the HKCR\CLSID\{<CLSID>} key.
119    hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
120    if (SUCCEEDED(hr))
121    {
122        hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszFriendlyName);
123
124        // Create the HKCR\CLSID\{<CLSID>}\ProgID key with the default value 
125        // '<ProgID>'
126        if (SUCCEEDED(hr) && pszProgID != NULL)
127        {
128            hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey),
129                L"CLSID\\%s\\ProgID", szCLSID);
130            if (SUCCEEDED(hr))
131            {
132                hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszProgID);
133            }
134        }
135
136        // Create the HKCR\CLSID\{<CLSID>}\VersionIndependentProgID key with 
137        // the default value '<VersionIndependentProgID>'.
138        if (SUCCEEDED(hr) && pszVerIndProgID != NULL)
139        {
140            hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), 
141                L"CLSID\\%s\\VersionIndependentProgID", szCLSID);
142            if (SUCCEEDED(hr))
143            {
144                hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszVerIndProgID);
145            }
146        }
147
148        // Create the HKCR\CLSID\{<CLSID>}\TypeLib key with the default value 
149        // '{<LIBID>}'
150        if (SUCCEEDED(hr))
151        {
152            hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), 
153                L"CLSID\\%s\\TypeLib", szCLSID);
154            if (SUCCEEDED(hr))
155            {
156                hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, szLIBID);
157            }
158        }
159
160        // Create the HKCR\CLSID\{<CLSID>}\LocalServer32 key.
161        if (SUCCEEDED(hr))
162        {
163            hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), 
164                L"CLSID\\%s\\LocalServer32", szCLSID);
165            if (SUCCEEDED(hr))
166            {
167                // Set the default value of the LocalServer32 key to the path 
168                // of the COM module.
169                hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszModule);
170            }
171        }
172    }
173
174    // Create the HKCR\<ProgId> key.
175    if (SUCCEEDED(hr) && pszProgID != NULL)
176    {
177        hr = SetHKCRRegistryKeyAndValue(pszProgID, NULL, pszFriendlyName);
178
179        // Create the HKCR\<ProgId>\CLSID key with the default value 
180        // '{<CLSID>}'.
181        if (SUCCEEDED(hr))
182        {
183            hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"%s\\CLSID", 
184                pszProgID);
185            if (SUCCEEDED(hr))
186            {
187                hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, szCLSID);
188            }
189        }
190    }
191
192    // Create the HKCR\<VersionIndependentProgID> key.
193    if (SUCCEEDED(hr) && pszVerIndProgID != NULL)
194    {
195        hr = SetHKCRRegistryKeyAndValue(pszVerIndProgID, NULL, pszFriendlyName);
196
197        // Create the HKCR\<VersionIndependentProgID>\CLSID key with the 
198        // default value '{<CLSID>}'.
199        if (SUCCEEDED(hr))
200        {
201            hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"%s\\CLSID", 
202                pszVerIndProgID);
203            if (SUCCEEDED(hr))
204            {
205                hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, szCLSID);
206            }
207        }
208
209        // Create the HKCR\<VersionIndependentProgID>\CurVer key with the 
210        // default value '<ProgID>'.
211        if (SUCCEEDED(hr) && pszProgID != NULL)
212        {
213            hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"%s\\CurVer", 
214                pszVerIndProgID);
215            if (SUCCEEDED(hr))
216            {
217                hr = SetHKCRRegistryKeyAndValue(szSubkey, NULL, pszProgID);
218            }
219        }
220    }
221
222    return hr;
223}
224
225
226//
227//   FUNCTION: RegisterTypeLib
228//
229//   PURPOSE: This helper function registers the type library.
230//
231//   PARAMETERS:
232//   * pszTypeLib - The type library file.
233//
234//   NOTE: The function creates the HKCR\TypeLib\{<LIBID>} key and the 
235//   HKCR\Interface\{<IID>} key in the registry.
236// 
237//   HKCR
238//   {
239//      NoRemove TypeLib
240//      {
241...
242//      }
243//      NoRemove Interface
244//      {
245//          ForceRemove {<IID>} = s '<Interface Name>'
246//          {
247//              ProxyStubClsid = s '<ProgID>'
248//              ProxyStubClsid32 = s '<VersionIndependentProgID>'
249//              TypeLib = s '{<LIBID>}'
250//              {
251//                  val Version = s '<TypeLib Version>'
252//              }
253//          }
254//      }
255//   }
256//
257HRESULT RegisterTypeLib(PCWSTR pszTypeLib)
258{
259    HRESULT hr;
260    ITypeLib *pTLB = NULL;
261
262    hr = LoadTypeLibEx(pszTypeLib, REGKIND_REGISTER, &pTLB);
263    if (SUCCEEDED(hr))
264    {
265        pTLB->Release();
266    }
267
268    return hr;
269}
270
271
272//
273//   FUNCTION: UnregisterLocalServer(void)
274//
275//   PURPOSE: Unegister the out-of-process component in the registry.
276//
277//   PARAMETERS:
278//   * clsid - Class ID of the component
279//   * pszProgID - ProgID of the component
280//   * pszVerIndProgID - Version independent ProgID
281//
282//   NOTE: The function deletes the HKCR\CLSID\{<CLSID>} key and the 
283//   HKCR\<ProgID> key in the registry.
284//
285HRESULT UnregisterLocalServer(const CLSID& clsid, 
286                              PCWSTR pszProgID, 
287                              PCWSTR pszVerIndProgID)
288{
289    HRESULT hr = S_OK;
290
291    wchar_t szCLSID[MAX_PATH];
292    StringFromGUID2(clsid, szCLSID, ARRAYSIZE(szCLSID));
293
294    wchar_t szSubkey[MAX_PATH];
295
296    // Delete the HKCR\CLSID\{<CLSID>} key.
297    hr = StringCchPrintf(szSubkey, ARRAYSIZE(szSubkey), L"CLSID\\%s", szCLSID);
298    if (SUCCEEDED(hr))
299    {
300        hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, szSubkey));
301    }
302
303    // Delete the HKCR\<ProgID> key.
304    if (SUCCEEDED(hr) && pszProgID != NULL)
305    {
306        hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, pszProgID));
307    }
308
309    // Delete the HKCR\<VersionIndependentProgID> key.
310    if (SUCCEEDED(hr) && pszVerIndProgID != NULL)
311    {
312        hr = HRESULT_FROM_WIN32(RegDeleteTree(HKEY_CLASSES_ROOT, pszVerIndProgID));
313    }
314
315    return hr;
316}
317
318
319//
320//   FUNCTION: UnregisterTypeLib
321//
322//   PURPOSE: This helper function unregisters the type library.
323//
324//   PARAMETERS:
325//   * pszTypeLib - The type library file.
326//
327//   NOTE: The function deletes the HKCR\TypeLib\{<LIBID>} key and the 
328//   HKCR\Interface\{<IID>} key in the registry.
329//
330HRESULT UnregisterTypeLib(PCWSTR pszTypeLib)
331{
332    HRESULT hr;
333
334    ITypeLib *pTLB = NULL;
335    hr = LoadTypeLibEx(pszTypeLib, REGKIND_NONE, &pTLB);
336    if (SUCCEEDED(hr))
337    {
338        TLIBATTR *pAttr = NULL;
339		hr = pTLB->GetLibAttr(&pAttr);
340        if (SUCCEEDED(hr))
341        {
342            hr = UnRegisterTypeLib(pAttr->guid, pAttr->wMajorVerNum, 
343                pAttr->wMinorVerNum, pAttr->lcid, pAttr->syskind);
344
345            pTLB->ReleaseTLibAttr(pAttr);
346        }
347
348        pTLB->Release();
349    }
350
351    return hr;
352}