xref: /AOO41X/main/xmerge/source/activesync/XMergeSync.cpp (revision 800f9471bc2fa4e127f322a90b5f7dce660a1adc)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include "stdafx.h"
24 
25 #include "XMergeFilter.h"
26 #include "XMergeFactory.h"
27 
28 
29 CXMergeSyncModule _Module;
30 
31 
32 //////////////////////////////////////////////////////////////////////
33 // DLL Functions
34 //////////////////////////////////////////////////////////////////////
DllMain(HANDLE hInst,ULONG ulReason,LPVOID lpReserved)35 BOOL WINAPI DllMain(HANDLE hInst, ULONG ulReason, LPVOID lpReserved)
36 {
37     switch (ulReason)
38     {
39         case DLL_PROCESS_ATTACH:
40             _Module.m_hInst = reinterpret_cast<HINSTANCE>(hInst);
41             break;
42 
43         case DLL_PROCESS_DETACH:
44             _Module.m_hInst = NULL;
45             break;
46 
47         case DLL_THREAD_ATTACH:
48             break;
49 
50         case DLL_THREAD_DETACH:
51             break;
52     }
53 
54     return TRUE;
55 }
56 
57 
DllGetClassObject(REFCLSID rclsid,REFIID riid,LPVOID * ppv)58 STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
59 {
60     // Create the factory object
61     CXMergeFactory *pFactory = new CXMergeFactory();
62     if (pFactory == NULL)
63     {
64         *ppv = NULL;
65         return E_OUTOFMEMORY;
66     }
67 
68     HRESULT hr = pFactory->QueryInterface(riid, ppv);
69     pFactory->Release();
70 
71     return hr;
72 }
73 
74 
DllCanUnloadNow()75 STDAPI DllCanUnloadNow()
76 {
77     if (_Module.GetLockCount() == 0)
78         return S_OK;
79 
80     return S_FALSE;
81 }
82 
83 
84 // Utility function to close open keys during registration
_signalRegError(long lRet,HKEY hKey,HKEY hDataKey)85 static _signalRegError(long lRet, HKEY hKey, HKEY hDataKey)
86 {
87     if (hKey)
88         ::RegCloseKey(hKey);
89 
90 
91     if (hDataKey)
92         ::RegCloseKey(hDataKey);
93 
94     return HRESULT_FROM_WIN32(lRet);
95 }
96 
97 
DllRegisterServer()98 STDAPI DllRegisterServer()
99 {
100     HKEY hKey = NULL;
101     HKEY hDataKey = NULL;
102 
103     long lRet = 0;
104     TCHAR sTemp[_MAX_PATH + 1] = "\0";
105 
106 
107     /*
108      * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Writer export filter.
109      *
110      * Note that import are export are relative to the WinCE device, so files are
111      * exported to the desktop format.
112      */
113 
114     // Get a handle to the CLSID key
115     lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
116     if (lRet != ERROR_SUCCESS)
117         return _signalRegError(lRet, hKey, hDataKey);
118 
119     // Create the CLSID key for the XMergeFilter
120     lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPSWExportCLSID, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
121     if (lRet != ERROR_SUCCESS)
122         return _signalRegError(lRet, hKey, hDataKey);
123 
124     lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWExportShortDesc,
125                 (::_tcslen(CXMergeFilter::m_pszPSWExportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
126     if (lRet != ERROR_SUCCESS)
127         return _signalRegError(lRet, hKey, hDataKey);
128 
129 
130     // Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
131     lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
132     if (lRet != ERROR_SUCCESS)
133         return _signalRegError(lRet, hKey, hDataKey);
134 
135     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
136                             (::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
137                                * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
138     if (lRet != ERROR_SUCCESS)
139         return _signalRegError(lRet, hKey, hDataKey);
140     ::RegCloseKey(hDataKey);  hDataKey = NULL;
141 
142     // Create the InprocServer32 key
143     lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
144     if (lRet != ERROR_SUCCESS)
145         return _signalRegError(lRet, hKey, hDataKey);
146 
147     lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
148     if (lRet != ERROR_SUCCESS)
149         return _signalRegError(lRet, hKey, hDataKey);
150 
151     // Create the key for the DLL file.  First find the filename of the dll
152     if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
153     {
154         lRet = ::GetLastError();
155         if (lRet != ERROR_SUCCESS)
156             return _signalRegError(lRet, hKey, hDataKey);
157     }
158 
159 
160     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
161                 (::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
162     if (lRet != ERROR_SUCCESS)
163         return _signalRegError(lRet, hKey, hDataKey);
164     ::RegCloseKey(hDataKey);    hDataKey = NULL;
165 
166 
167     // Setup the PegasusFilter key values
168     lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
169     if (lRet != ERROR_SUCCESS)
170         return _signalRegError(lRet, hKey, hDataKey);
171 
172     lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWExportDesc,
173                 (::_tcslen(CXMergeFilter::m_pszPSWExportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
174     if (lRet != ERROR_SUCCESS)
175         return _signalRegError(lRet, hKey, hDataKey);
176 
177 
178     lRet = ::RegSetValueEx(hDataKey, _T("Export"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
179     if (lRet != ERROR_SUCCESS)
180         return _signalRegError(lRet, hKey, hDataKey);
181 
182 
183     lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWExportExt,
184                 (::_tcslen(CXMergeFilter::m_pszPSWExportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
185     if (lRet != ERROR_SUCCESS)
186         return _signalRegError(lRet, hKey, hDataKey);
187 
188 
189     ::RegCloseKey(hKey);        hKey = NULL;
190     ::RegCloseKey(hDataKey);    hDataKey = NULL;
191 
192 
193 
194 
195     /*
196      * Following calls create the entries for the filter in
197      * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
198      */
199 
200     lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
201                 0, KEY_ALL_ACCESS, &hKey);
202     if (lRet != ERROR_SUCCESS)
203         return _signalRegError(lRet, hKey, hDataKey);
204 
205     _snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPSWImportExt);
206     lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
207                 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
208     if (lRet != ERROR_SUCCESS)
209         return _signalRegError(lRet, hKey, hDataKey);
210 
211     lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPSWExportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
212     if (lRet != ERROR_SUCCESS)
213         return _signalRegError(lRet, hKey, hDataKey);
214 
215     ::RegCloseKey(hKey);        hKey = NULL;
216     ::RegCloseKey(hDataKey);    hDataKey = NULL;
217 
218 
219 
220     /*
221      * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Writer import filter.
222      *
223      * Note that import are export are relative to the WinCE device, so files are
224      * exported to the desktop format.
225      */
226     // Get a handle to the CLSID key
227     lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
228     if (lRet != ERROR_SUCCESS)
229         return _signalRegError(lRet, hKey, hDataKey);
230 
231     // Create the CLSID key for the XMergeFilter
232     lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPSWImportCLSID, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
233     if (lRet != ERROR_SUCCESS)
234         return _signalRegError(lRet, hKey, hDataKey);
235 
236     lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWImportShortDesc,
237                 (::_tcslen(CXMergeFilter::m_pszPSWImportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
238     if (lRet != ERROR_SUCCESS)
239         return _signalRegError(lRet, hKey, hDataKey);
240 
241 
242     // Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
243     lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
244     if (lRet != ERROR_SUCCESS)
245         return _signalRegError(lRet, hKey, hDataKey);
246 
247     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
248                             (::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
249                                * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
250     if (lRet != ERROR_SUCCESS)
251         return _signalRegError(lRet, hKey, hDataKey);
252     ::RegCloseKey(hDataKey);  hDataKey = NULL;
253 
254 
255     // Create the InprocServer32 key
256     lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
257     if (lRet != ERROR_SUCCESS)
258         return _signalRegError(lRet, hKey, hDataKey);
259 
260     lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
261     if (lRet != ERROR_SUCCESS)
262         return _signalRegError(lRet, hKey, hDataKey);
263 
264 
265     // Create the key for the DLL file.  First find the filename of the dll
266     if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
267     {
268         lRet = ::GetLastError();
269         if (lRet != ERROR_SUCCESS)
270             return _signalRegError(lRet, hKey, hDataKey);
271     }
272 
273 
274     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
275                 (::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
276     if (lRet != ERROR_SUCCESS)
277         return _signalRegError(lRet, hKey, hDataKey);
278     ::RegCloseKey(hDataKey);    hDataKey = NULL;
279 
280 
281     // Setup the PegasusFilter key values
282     lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
283     if (lRet != ERROR_SUCCESS)
284         return _signalRegError(lRet, hKey, hDataKey);
285 
286         lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWImportDesc,
287                 (::_tcslen(CXMergeFilter::m_pszPSWImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
288     if (lRet != ERROR_SUCCESS)
289         return _signalRegError(lRet, hKey, hDataKey);
290 
291 
292     lRet = ::RegSetValueEx(hDataKey, _T("Import"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
293     if (lRet != ERROR_SUCCESS)
294         return _signalRegError(lRet, hKey, hDataKey);
295 
296 
297     lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPSWImportExt,
298                 (::_tcslen(CXMergeFilter::m_pszPSWImportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
299     if (lRet != ERROR_SUCCESS)
300         return _signalRegError(lRet, hKey, hDataKey);
301 
302 
303     ::RegCloseKey(hKey);        hKey = NULL;
304     ::RegCloseKey(hDataKey);    hDataKey = NULL;
305 
306 
307     /*
308      * Following calls create the entries for the filter in
309      * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
310      */
311     lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
312                 0, KEY_ALL_ACCESS, &hKey);
313     if (lRet != ERROR_SUCCESS)
314         return _signalRegError(lRet, hKey, hDataKey);
315 
316     // Add in defaults for import and export
317     _snprintf(sTemp, _MAX_PATH +1, "%c%s\0", '.', CXMergeFilter::m_pszPSWExportExt);
318     lRet = ::RegCreateKeyEx(hKey, _T(sTemp), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
319     if (lRet != ERROR_SUCCESS)
320         return _signalRegError(lRet, hKey, hDataKey);
321 
322     lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ,
323                             (LPBYTE)CXMergeFilter::m_pszPSWImportCLSID,
324                             (::_tcslen(CXMergeFilter::m_pszPSWImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
325     if (lRet != ERROR_SUCCESS)
326         return _signalRegError(lRet, hKey, hDataKey);
327 
328 
329     lRet = ::RegSetValueEx(hDataKey, _T("DefaultExport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
330                             (::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
331     if (lRet != ERROR_SUCCESS)
332         return _signalRegError(lRet, hKey, hDataKey);
333 
334     ::RegCloseKey(hDataKey);
335 
336     // Update registered filters
337     _snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPSWExportExt);
338     lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
339                 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
340     if (lRet != ERROR_SUCCESS)
341         return _signalRegError(lRet, hKey, hDataKey);
342 
343 
344     lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPSWImportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
345     if (lRet != ERROR_SUCCESS)
346         return _signalRegError(lRet, hKey, hDataKey);
347 
348     ::RegCloseKey(hKey);        hKey = NULL;
349     ::RegCloseKey(hDataKey);    hDataKey = NULL;
350 
351 
352 
353     /*
354      * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Calc export filter.
355      *
356      * Note that import are export are relative to the WinCE device, so files are
357      * exported to the desktop format.
358      */
359 
360     // Get a handle to the CLSID key
361     lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
362     if (lRet != ERROR_SUCCESS)
363         return _signalRegError(lRet, hKey, hDataKey);
364 
365     // Create the CLSID key for the XMerge Filter
366     lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPXLExportCLSID, 0, _T(""),
367                                 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
368     if (lRet != ERROR_SUCCESS)
369         return _signalRegError(lRet, hKey, hDataKey);
370 
371     lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLExportShortDesc,
372                 (::_tcslen(CXMergeFilter::m_pszPXLExportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
373     if (lRet != ERROR_SUCCESS)
374         return _signalRegError(lRet, hKey, hDataKey);
375 
376 
377     // Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
378     lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
379     if (lRet != ERROR_SUCCESS)
380         return _signalRegError(lRet, hKey, hDataKey);
381 
382     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
383                             (::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
384                                * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
385     if (lRet != ERROR_SUCCESS)
386         return _signalRegError(lRet, hKey, hDataKey);
387     ::RegCloseKey(hDataKey);  hDataKey = NULL;
388 
389 
390     // Create the InprocServer32 key
391     lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
392     if (lRet != ERROR_SUCCESS)
393         return _signalRegError(lRet, hKey, hDataKey);
394 
395     lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
396     if (lRet != ERROR_SUCCESS)
397         return _signalRegError(lRet, hKey, hDataKey);
398 
399 
400     // Create the key for the DLL file.  First find the filename of the dll
401     if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
402     {
403         lRet = ::GetLastError();
404         if (lRet != ERROR_SUCCESS)
405             return _signalRegError(lRet, hKey, hDataKey);
406     }
407 
408 
409     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
410                 (::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
411     if (lRet != ERROR_SUCCESS)
412         return _signalRegError(lRet, hKey, hDataKey);
413     ::RegCloseKey(hDataKey);    hDataKey = NULL;
414 
415 
416     // Setup the PegasusFilter key values
417     lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
418     if (lRet != ERROR_SUCCESS)
419         return _signalRegError(lRet, hKey, hDataKey);
420 
421         lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLExportDesc,
422                 (::_tcslen(CXMergeFilter::m_pszPXLExportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
423     if (lRet != ERROR_SUCCESS)
424         return _signalRegError(lRet, hKey, hDataKey);
425 
426 
427     lRet = ::RegSetValueEx(hDataKey, _T("Export"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
428     if (lRet != ERROR_SUCCESS)
429         return _signalRegError(lRet, hKey, hDataKey);
430 
431 
432     lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLExportExt,
433                 (::_tcslen(CXMergeFilter::m_pszPXLExportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
434     if (lRet != ERROR_SUCCESS)
435         return _signalRegError(lRet, hKey, hDataKey);
436 
437 
438     ::RegCloseKey(hKey);        hKey = NULL;
439     ::RegCloseKey(hDataKey);    hDataKey = NULL;
440 
441 
442 
443 
444     /*
445      * Following calls create the entries for the filter in
446      * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
447      */
448 
449     lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
450                 0, KEY_ALL_ACCESS, &hKey);
451     if (lRet != ERROR_SUCCESS)
452         return _signalRegError(lRet, hKey, hDataKey);
453 
454     _snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPXLImportExt);
455     lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
456                 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
457     if (lRet != ERROR_SUCCESS)
458         return _signalRegError(lRet, hKey, hDataKey);
459 
460     lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPXLExportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
461     if (lRet != ERROR_SUCCESS)
462         return _signalRegError(lRet, hKey, hDataKey);
463 
464     ::RegCloseKey(hKey);        hKey = NULL;
465     ::RegCloseKey(hDataKey);    hDataKey = NULL;
466 
467 
468 
469     /*
470      * Following calls create the HKEY_CLASSES_ROOT\CLSID entry for the Calc import filter.
471      *
472      * Note that import are export are relative to the WinCE device, so files are
473      * exported to the desktop format.
474      */
475     // Get a handle to the CLSID key
476     lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
477     if (lRet != ERROR_SUCCESS)
478         return _signalRegError(lRet, hKey, hDataKey);
479 
480 
481     // Create the CLSID key for the XMergeFilter
482     lRet = ::RegCreateKeyEx(hKey, CXMergeFilter::m_pszPXLImportCLSID, 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hKey, NULL);
483     if (lRet != ERROR_SUCCESS)
484         return _signalRegError(lRet, hKey, hDataKey);
485 
486     lRet = ::RegSetValueEx(hKey, _T(""), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLImportShortDesc,
487                 (::_tcslen(CXMergeFilter::m_pszPXLImportShortDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
488     if (lRet != ERROR_SUCCESS)
489         return _signalRegError(lRet, hKey, hDataKey);
490 
491     // Create the DefaultIcon key.  For the moment, use one of the Async supplied ones
492     lRet = ::RegCreateKeyEx(hKey, _T("DefaultIcon"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
493     if (lRet != ERROR_SUCCESS)
494         return _signalRegError(lRet, hKey, hDataKey);
495 
496     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"),
497                             (::_tcslen(_T("C:\\Program Files\\Microsoft ActiveSync\\pwdcnv.dll,0"))
498                                * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
499     if (lRet != ERROR_SUCCESS)
500         return _signalRegError(lRet, hKey, hDataKey);
501     ::RegCloseKey(hDataKey);  hDataKey = NULL;
502 
503 
504     // Create the InprocServer32 key
505     lRet = ::RegCreateKeyEx(hKey, _T("InProcServer32"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
506     if (lRet != ERROR_SUCCESS)
507         return _signalRegError(lRet, hKey, hDataKey);
508 
509     lRet = ::RegSetValueEx(hDataKey, _T("ThreadingModel"), 0, REG_SZ, (LPBYTE)_T("Apartment"), 10);
510     if (lRet != ERROR_SUCCESS)
511         return _signalRegError(lRet, hKey, hDataKey);
512 
513 
514     // Create the key for the DLL file.  First find the filename of the dll
515     if (!::GetModuleFileName((HMODULE)_Module.m_hInst, sTemp, (_MAX_PATH + 1)))
516     {
517         lRet = ::GetLastError();
518         if (lRet != ERROR_SUCCESS)
519             return _signalRegError(lRet, hKey, hDataKey);
520     }
521 
522 
523     lRet = ::RegSetValueEx(hDataKey, NULL, 0, REG_SZ, (LPBYTE)sTemp,
524                 (::_tcslen(sTemp) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
525     if (lRet != ERROR_SUCCESS)
526         return _signalRegError(lRet, hKey, hDataKey);
527     ::RegCloseKey(hDataKey);    hDataKey = NULL;
528 
529 
530     // Setup the PegasusFilter key values
531     lRet = ::RegCreateKeyEx(hKey, _T("PegasusFilter"), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
532     if (lRet != ERROR_SUCCESS)
533         return _signalRegError(lRet, hKey, hDataKey);
534 
535         lRet = ::RegSetValueEx(hDataKey, _T("Description"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLImportDesc,
536                 (::_tcslen(CXMergeFilter::m_pszPXLImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
537     if (lRet != ERROR_SUCCESS)
538         return _signalRegError(lRet, hKey, hDataKey);
539 
540 
541     lRet = ::RegSetValueEx(hDataKey, _T("Import"), 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
542     if (lRet != ERROR_SUCCESS)
543         return _signalRegError(lRet, hKey, hDataKey);
544 
545 
546     lRet = ::RegSetValueEx(hDataKey, _T("NewExtension"), 0, REG_SZ, (LPBYTE)CXMergeFilter::m_pszPXLImportExt,
547                 (::_tcslen(CXMergeFilter::m_pszPXLImportExt) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
548     if (lRet != ERROR_SUCCESS)
549         return _signalRegError(lRet, hKey, hDataKey);
550 
551 
552     ::RegCloseKey(hKey);        hKey = NULL;
553     ::RegCloseKey(hDataKey);    hDataKey = NULL;
554 
555 
556 
557     /*
558      * Following calls create the entries for the filter in
559      * HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
560      */
561     lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
562                 0, KEY_ALL_ACCESS, &hKey);
563     if (lRet != ERROR_SUCCESS)
564         return _signalRegError(lRet, hKey, hDataKey);
565 
566     // Add in defaults for import and export
567     _snprintf(sTemp, _MAX_PATH +1, "%c%s\0", '.', CXMergeFilter::m_pszPXLExportExt);
568     lRet = ::RegCreateKeyEx(hKey, _T(sTemp), 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
569     if (lRet != ERROR_SUCCESS)
570         return _signalRegError(lRet, hKey, hDataKey);
571 
572     lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ,
573                             (LPBYTE)CXMergeFilter::m_pszPXLImportCLSID,
574                             (::_tcslen(CXMergeFilter::m_pszPSWImportDesc) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
575     if (lRet != ERROR_SUCCESS)
576         return _signalRegError(lRet, hKey, hDataKey);
577 
578 
579     lRet = ::RegSetValueEx(hDataKey, _T("DefaultExport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
580                             (::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
581     if (lRet != ERROR_SUCCESS)
582         return _signalRegError(lRet, hKey, hDataKey);
583 
584     ::RegCloseKey(hDataKey);
585 
586     // Update registered filters
587 
588 
589     _snprintf(sTemp, _MAX_PATH + 1, "%c%s\\InstalledFilters\0", '.', CXMergeFilter::m_pszPXLExportExt);
590     lRet = ::RegCreateKeyEx(hKey, _T(sTemp),
591                 0, _T(""), 0, KEY_ALL_ACCESS, NULL, &hDataKey, NULL);
592     if (lRet != ERROR_SUCCESS)
593         return _signalRegError(lRet, hKey, hDataKey);
594 
595     lRet = ::RegSetValueEx(hDataKey, CXMergeFilter::m_pszPXLImportCLSID, 0, REG_SZ, (LPBYTE)_T(""), (1 * sizeof(TCHAR)));
596     if (lRet != ERROR_SUCCESS)
597         return _signalRegError(lRet, hKey, hDataKey);
598 
599     ::RegCloseKey(hKey);        hKey = NULL;
600     ::RegCloseKey(hDataKey);    hDataKey = NULL;
601 
602 
603 
604     return HRESULT_FROM_WIN32(lRet);
605 }
606 
607 
DllUnregisterServer()608 STDAPI DllUnregisterServer()
609 {
610     long lRet = 0;
611     HKEY hKey = NULL;
612     HKEY hDataKey = NULL;
613 
614     TCHAR szClassName[_MAX_PATH] = "\0";
615     TCHAR szKeyName[_MAX_PATH]   = "\0";
616     DWORD dwClassName            = _MAX_PATH;
617     DWORD dwKeyName              = _MAX_PATH;
618 
619     /*
620      * Remove HKEY_CLASS_ROOT\CLSID\{XXX} entry for the export and import filters
621      *
622      * Windows 95/98/Me allow one step deletion of a key and all subkeys.
623      * Windows NT/2000/XP do not so the subkeys must be deleted individually.
624      */
625     lRet = ::RegOpenKeyEx(HKEY_CLASSES_ROOT, _T("CLSID"), 0, KEY_ALL_ACCESS, &hKey);
626     if (lRet != ERROR_SUCCESS)
627         return _signalRegError(lRet, hKey, hDataKey);
628 
629 
630     // First up, the Writer export filter
631     lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPSWExportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
632     if (lRet != ERROR_SUCCESS)
633         return _signalRegError(lRet, hKey, hDataKey);
634 
635 
636     while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
637                 != ERROR_NO_MORE_ITEMS)
638     {
639         lRet = ::RegDeleteKey(hDataKey, szKeyName);
640 
641         ::lstrcpy(szKeyName, "\0");
642         ::lstrcpy(szClassName, "\0");
643 
644         dwClassName = _MAX_PATH;
645         dwKeyName   = _MAX_PATH;
646     }
647 
648     ::RegCloseKey(hDataKey);  hDataKey = NULL;
649 
650     lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPSWExportCLSID);
651     if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
652         return _signalRegError(lRet, hKey, hDataKey);
653 
654 
655 
656     // Next, the Writer import filter
657     lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPSWImportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
658     if (lRet != ERROR_SUCCESS)
659         return _signalRegError(lRet, hKey, hDataKey);
660 
661 
662     while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
663                 != ERROR_NO_MORE_ITEMS)
664     {
665         lRet = ::RegDeleteKey(hDataKey, szKeyName);
666 
667         ::lstrcpy(szKeyName, "\0");
668         ::lstrcpy(szClassName, "\0");
669 
670         dwClassName = _MAX_PATH;
671         dwKeyName   = _MAX_PATH;
672     }
673 
674     ::RegCloseKey(hDataKey);  hDataKey = NULL;
675 
676     lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPSWImportCLSID);
677     if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
678         return _signalRegError(lRet, hKey, hDataKey);
679 
680 
681     // Next up, the Calc export filter
682     lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPXLExportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
683     if (lRet != ERROR_SUCCESS)
684         return _signalRegError(lRet, hKey, hDataKey);
685 
686 
687     while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
688                 != ERROR_NO_MORE_ITEMS)
689     {
690         lRet = ::RegDeleteKey(hDataKey, szKeyName);
691 
692         ::lstrcpy(szKeyName, "\0");
693         ::lstrcpy(szClassName, "\0");
694 
695         dwClassName = _MAX_PATH;
696         dwKeyName   = _MAX_PATH;
697     }
698 
699     ::RegCloseKey(hDataKey);  hDataKey = NULL;
700 
701     lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPXLExportCLSID);
702     if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
703         return _signalRegError(lRet, hKey, hDataKey);
704 
705 
706     // Next, the Calc import filter
707     lRet = ::RegOpenKeyEx(hKey, CXMergeFilter::m_pszPXLImportCLSID, 0, KEY_ALL_ACCESS, &hDataKey);
708     if (lRet != ERROR_SUCCESS)
709         return _signalRegError(lRet, hKey, hDataKey);
710 
711 
712     while ((lRet = ::RegEnumKeyEx(hDataKey, 0, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL))
713                 != ERROR_NO_MORE_ITEMS)
714     {
715         lRet = ::RegDeleteKey(hDataKey, szKeyName);
716 
717         ::lstrcpy(szKeyName, "\0");
718         ::lstrcpy(szClassName, "\0");
719 
720         dwClassName = _MAX_PATH;
721         dwKeyName   = _MAX_PATH;
722     }
723 
724     ::RegCloseKey(hDataKey);  hDataKey = NULL;
725 
726     lRet = ::RegDeleteKey(hKey, CXMergeFilter::m_pszPXLImportCLSID);
727     if (lRet != ERROR_SUCCESS && lRet != ERROR_FILE_NOT_FOUND)
728         return _signalRegError(lRet, hKey, hDataKey);
729 
730     ::RegCloseKey(hKey);  hKey = NULL;
731 
732 
733 
734     /*
735      * Remove the HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows CE Services\Filters
736      */
737     lRet = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows CE Services\\Filters"),
738                             0, KEY_ALL_ACCESS, &hKey);
739     if (lRet != ERROR_SUCCESS)
740         return _signalRegError(lRet, hKey, hDataKey);
741 
742 
743     // Remove the Writer export filter from the Writer import file extension subkey.
744     _snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPSWImportExt);
745     lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
746     if (lRet != ERROR_SUCCESS)
747         return _signalRegError(lRet, hKey, hDataKey);
748 
749     lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPSWExportCLSID);
750     if (lRet != ERROR_SUCCESS)
751         return _signalRegError(lRet, hKey, hDataKey);
752 
753     ::lstrcpyn(szKeyName, "\0", _MAX_PATH);
754     ::RegCloseKey(hDataKey);    hDataKey = NULL;
755 
756 
757     // Remove the Writer import filter from the Writer export file extension subkey.
758     _snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPSWExportExt);
759     lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
760     if (lRet != ERROR_SUCCESS)
761         return _signalRegError(lRet, hKey, hDataKey);
762 
763     lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPSWImportCLSID);
764     if (lRet != ERROR_SUCCESS)
765         return _signalRegError(lRet, hKey, hDataKey);
766 
767     ::lstrcpyn(szKeyName, "\0", _MAX_PATH);
768     ::RegCloseKey(hDataKey);    hDataKey = NULL;
769 
770 
771     // Make Binary Copy the default for Writer export file extension subkey DefaultImport
772     _snprintf(szKeyName, _MAX_PATH, ".%s\0", CXMergeFilter::m_pszPSWExportExt);
773     lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
774     if (lRet != ERROR_SUCCESS)
775         return _signalRegError(lRet, hKey, hDataKey);
776 
777     lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
778                             (::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
779     if (lRet != ERROR_SUCCESS)
780         return _signalRegError(lRet, hKey, hDataKey);
781 
782     ::lstrcpyn(szKeyName, "\0", _MAX_PATH);
783     ::RegCloseKey(hDataKey);    hDataKey = NULL;
784 
785 
786     // Remove the Calc export filter from the Calc import file extension subkey.
787     _snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPXLImportExt);
788     lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
789     if (lRet != ERROR_SUCCESS)
790         return _signalRegError(lRet, hKey, hDataKey);
791 
792     lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPXLExportCLSID);
793     if (lRet != ERROR_SUCCESS)
794         return _signalRegError(lRet, hKey, hDataKey);
795 
796     ::lstrcpyn(szKeyName, "\0", _MAX_PATH);
797     ::RegCloseKey(hDataKey);    hDataKey = NULL;
798 
799     // Remove the Calc import filter from the Calc export file extension subkey.
800     _snprintf(szKeyName, _MAX_PATH, ".%s\\InstalledFilters", CXMergeFilter::m_pszPXLExportExt);
801     lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
802     if (lRet != ERROR_SUCCESS)
803         return _signalRegError(lRet, hKey, hDataKey);
804 
805     lRet = ::RegDeleteValue(hDataKey, CXMergeFilter::m_pszPXLImportCLSID);
806     if (lRet != ERROR_SUCCESS)
807         return _signalRegError(lRet, hKey, hDataKey);
808 
809     ::lstrcpyn(szKeyName, "\0", _MAX_PATH);
810     ::RegCloseKey(hDataKey);    hDataKey = NULL;
811 
812 
813     // Make Binary Copy the default for Calc export file extension subkey DefaultImport
814     _snprintf(szKeyName, _MAX_PATH, ".%s\0", CXMergeFilter::m_pszPXLExportExt);
815     lRet = ::RegOpenKeyEx(hKey, _T(szKeyName), 0, KEY_ALL_ACCESS, &hDataKey);
816     if (lRet != ERROR_SUCCESS)
817         return _signalRegError(lRet, hKey, hDataKey);
818 
819     lRet = ::RegSetValueEx(hDataKey, _T("DefaultImport"), 0, REG_SZ, (LPBYTE)_T("Binary Copy"),
820                             (::_tcslen(_T("Binary Copy")) * sizeof(TCHAR) + (1 * sizeof(TCHAR))));
821     if (lRet != ERROR_SUCCESS)
822         return _signalRegError(lRet, hKey, hDataKey);
823 
824     ::lstrcpyn(szKeyName, "\0", _MAX_PATH);
825     ::RegCloseKey(hDataKey);    hDataKey = NULL;
826 
827 
828 
829     ::RegCloseKey(hKey);        hKey     = NULL;
830 
831     return HRESULT_FROM_WIN32(lRet);
832 }
833 
834 
835 //////////////////////////////////////////////////////////////////////
836 // CXMergeSyncModule methods
837 //////////////////////////////////////////////////////////////////////
CXMergeSyncModule()838 CXMergeSyncModule::CXMergeSyncModule ()
839 {
840 }
841 
~CXMergeSyncModule()842 CXMergeSyncModule::~CXMergeSyncModule ()
843 {
844 }
845 
LockServer(BOOL fLock)846 long CXMergeSyncModule::LockServer(BOOL fLock)
847 {
848     if(fLock)
849         return ::InterlockedIncrement(&m_lLocks);
850     else
851         return ::InterlockedDecrement(&m_lLocks);
852 }
853 
GetLockCount()854 long CXMergeSyncModule::GetLockCount()
855 {
856     return m_lLocks + m_lObjs;
857 }
858 
859