1 // XMergeFilter.cpp: implementation of the CXMergeFilter class.
3 //////////////////////////////////////////////////////////////////////
8 #include "XMergeFilter.h"
14 #define ERR_BADCLASSPATH 2
15 #define ERR_INITJAVA 3
18 const LPTSTR
CXMergeFilter::m_pszPSWExportCLSID
= _T("{BDD611C3-7BAB-460F-8711-5B9AC9EF6020}");
19 const LPTSTR
CXMergeFilter::m_pszPSWExportExt
= _T("sxw");
20 const LPTSTR
CXMergeFilter::m_pszPSWExportDesc
= _T("OpenOffice.org Writer XML Document");
21 const LPTSTR
CXMergeFilter::m_pszPSWExportShortDesc
= _T("OpenOffice.org Writer");
23 const LPTSTR
CXMergeFilter::m_pszPSWImportCLSID
= _T("{CB43F086-838D-4FA4-B5F6-3406B9A57439}");
24 const LPTSTR
CXMergeFilter::m_pszPSWImportExt
= _T("psw");
25 const LPTSTR
CXMergeFilter::m_pszPSWImportDesc
= _T("Pocket Word Document - Pocket PC");
26 const LPTSTR
CXMergeFilter::m_pszPSWImportShortDesc
= _T("Pocket Word");
28 const LPTSTR
CXMergeFilter::m_pszPXLExportCLSID
= _T("{C6AB3E74-9F4F-4370-8120-A8A6FABB7A7C}");
29 const LPTSTR
CXMergeFilter::m_pszPXLExportExt
= _T("sxc");
30 const LPTSTR
CXMergeFilter::m_pszPXLExportDesc
= _T("OpenOffice.org Calc XML Document");
31 const LPTSTR
CXMergeFilter::m_pszPXLExportShortDesc
= _T("OpenOffice.org Calc");
33 const LPTSTR
CXMergeFilter::m_pszPXLImportCLSID
= _T("{43887C67-4D5D-4127-BAAC-87A288494C7C}");
34 const LPTSTR
CXMergeFilter::m_pszPXLImportExt
= _T("pxl");
35 const LPTSTR
CXMergeFilter::m_pszPXLImportDesc
= _T("Pocket Excel Document - Pocket PC");
36 const LPTSTR
CXMergeFilter::m_pszPXLImportShortDesc
= _T("Pocket Excel");
39 //////////////////////////////////////////////////////////////////////
40 // Construction/Destruction
41 //////////////////////////////////////////////////////////////////////
43 CXMergeFilter::CXMergeFilter() : m_cRef(1)
49 m_szJavaBaseDir
= NULL
;
52 CXMergeFilter::~CXMergeFilter()
54 if (m_szClasspath
!= NULL
)
59 if (m_szJavaBaseDir
!= NULL
)
61 delete m_szJavaBaseDir
;
67 //////////////////////////////////////////////////////////////////////
69 //////////////////////////////////////////////////////////////////////
71 STDMETHODIMP
CXMergeFilter::QueryInterface(REFIID riid
, void **ppvObject
)
76 if (::IsEqualIID(riid
, IID_IUnknown
))
78 *ppvObject
= static_cast<IUnknown
*>(this);
80 else if (::IsEqualIID(riid
, IID_ICeFileFilter
))
82 *ppvObject
= static_cast<ICeFileFilter
*>(this);
90 reinterpret_cast<IUnknown
*>(*ppvObject
)->AddRef();
95 STDMETHODIMP_(ULONG
) CXMergeFilter::AddRef()
97 return ::InterlockedIncrement(&m_cRef
);
101 STDMETHODIMP_(ULONG
) CXMergeFilter::Release()
103 if(::InterlockedDecrement(&m_cRef
) == 0)
112 //////////////////////////////////////////////////////////////////////
114 //////////////////////////////////////////////////////////////////////
116 STDMETHODIMP
CXMergeFilter::FilterOptions(HWND hwndParent
)
118 // We don't currently allow any options
119 return HRESULT_FROM_WIN32(NOERROR
);
122 STDMETHODIMP
CXMergeFilter::FormatMessage(DWORD dwFlags
, DWORD dwMessageId
,
123 DWORD dwLanguageId
, LPTSTR lpBuffer
, DWORD nSize
,
124 va_list *Arguments
, DWORD
*pcb
)
134 // Attempt to find the messages in the registry
135 lRet
= ::RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\Sun Microsystems\\StarOffice\\XMergeSync\\Messages\\Error"),
137 if (lRet
!= ERROR_SUCCESS
)
139 // Try the user's portion of the registry
140 lRet
= ::RegOpenKeyEx(HKEY_CURRENT_USER
, _T("Software\\Sun Microsystems\\StarOffice\\XMergeSync\\Messages\\Error"),
142 if (lRet
!= ERROR_SUCCESS
)
152 lRet
= ::RegQueryValueEx(hKey
, _T("Java"), 0, NULL
, (LPBYTE
)errMsg
, &dwSize
);
153 if (lRet
!= ERROR_SUCCESS
)
155 lstrcpy(errMsg
, "Unable to locate Java 1.4/1.5 installation.");
159 case ERR_BADCLASSPATH
:
160 lRet
= ::RegQueryValueEx(hKey
, _T("Classpath"), 0, NULL
, (LPBYTE
)errMsg
, &dwSize
);
161 if (lRet
!= ERROR_SUCCESS
)
163 lstrcpy(errMsg
, "Unable to locate XMerge Jar files.");
168 lRet
= ::RegQueryValueEx(hKey
, _T("JavaInit"), 0, NULL
, (LPBYTE
)errMsg
, &dwSize
);
169 if (lRet
!= ERROR_SUCCESS
)
171 lstrcpy(errMsg
, "Error initialising the Java Runtime Environment.");
176 char* buf
= (char*)LocalAlloc(LMEM_FIXED
| LMEM_ZEROINIT
, (lstrlen(errMsg
) + 1) * sizeof(TCHAR
));
177 lstrcpyn(buf
, errMsg
, lstrlen(errMsg
));
179 *(char**)lpBuffer
= buf
;
180 *pcb
= strlen(errMsg
);
182 return HRESULT_FROM_WIN32(NOERROR
);
186 STDMETHODIMP
CXMergeFilter::NextConvertFile(int nConversion
, CFF_CONVERTINFO
*pci
,
187 CFF_SOURCEFILE
*psf
, CFF_DESTINATIONFILE
*pdf
,
188 volatile BOOL
*pbCancel
, CF_ERROR
*perr
)
194 PROCESS_INFORMATION pi
;
196 ZeroMemory( &si
, sizeof(si
) );
197 ZeroMemory( &pi
, sizeof(pi
) );
203 * First step: Locate Java and establish the classpath. If these can't
204 * be done succesfully, then avoid all further processing.
207 // Locate Java Home if it hasn't already been done.
208 if (m_szJavaBaseDir
== NULL
)
210 m_szJavaBaseDir
= GetJavaBaseDir();
212 if (m_szJavaBaseDir
== NULL
)
215 return HRESULT_FROM_WIN32(E_FAIL
);
219 // Get the StarOffice/OpenOffice class directory
220 if (m_szClasspath
== NULL
)
222 m_szClasspath
= GetXMergeClassPath();
224 if (m_szClasspath
== NULL
)
226 *perr
= ERR_BADCLASSPATH
;
227 return HRESULT_FROM_WIN32(E_FAIL
);
233 * Second step: Check the files we're going to process. If we don't have
234 * an XMerge plugin for the file then we can't convert.
236 if ((!lstrcmp(psf
->szExtension
, "sxw") || !lstrcmp(psf
->szExtension
, "psw"))
239 *perr
= ERR_BADCLASSPATH
;
240 return HRESULT_FROM_WIN32(E_FAIL
);
242 else if ((!lstrcmp(psf
->szExtension
, "sxc") || !lstrcmp(psf
->szExtension
, "pxl"))
245 *perr
= ERR_BADCLASSPATH
;
246 return HRESULT_FROM_WIN32(E_FAIL
);
251 * Third step: Locate the Java executable and build and execute the command
252 * line to carry out the conversion.
255 // Find the Java executable and make sure it exists
256 appName
+= m_szJavaBaseDir
;
257 appName
+= "\\bin\\javaw.exe";
259 if (GetFileAttributes(appName
.c_str()) == INVALID_FILE_SIZE
)
262 return HRESULT_FROM_WIN32(E_FAIL
);
265 // Wrap the executable path in quotes in case of spaces
266 appName
.insert(0, "\"");
267 appName
.append("\"");
271 // Need to build the entire command line for calling out to Java
272 appArgs
= appName
+ " -Djava.class.path=";
273 appArgs
+= m_szClasspath
;
274 appArgs
+= " org.openoffice.xmerge.util.ActiveSyncDriver ";
276 if (!lstrcmp(psf
->szExtension
, "sxw"))
278 appArgs
+= "staroffice/sxw ";
279 appArgs
+= "application/x-pocket-word ";
281 else if(!lstrcmp(psf
->szExtension
, "psw"))
283 appArgs
+= "application/x-pocket-word ";
284 appArgs
+= "staroffice/sxw ";
286 else if(!lstrcmp(psf
->szExtension
, "sxc"))
288 appArgs
+= "staroffice/sxc ";
289 appArgs
+= "application/x-pocket-excel ";
291 else if(!lstrcmp(psf
->szExtension
, "pxl"))
293 appArgs
+= "application/x-pocket-excel ";
294 appArgs
+= "staroffice/sxc ";
298 // ActiveSync sometimes gives out long file names, especially when automatically syncing
300 appArgs
+= psf
->szFullpath
;
302 appArgs
+= pdf
->szFullpath
;
305 if(!CreateProcess(NULL
,
306 (char*)appArgs
.c_str(),
307 NULL
, // No Process Attributes
308 NULL
, // No Thread Attributes
309 FALSE
, // Don't want this process getting handles
310 CREATE_NO_WINDOW
, // No console
311 NULL
, // No special environment
312 NULL
, // Current Working Directory is okay
316 *perr
= ERR_INITJAVA
;
317 return HRESULT_FROM_WIN32(E_FAIL
);
320 // Wait for the new process to work
321 WaitForSingleObject(pi
.hProcess
, INFINITE
);
323 CloseHandle(pi
.hProcess
);
324 CloseHandle(pi
.hThread
);
326 return HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS
);
330 typedef HRESULT (WINAPI
*SHGETFOLDERPATH
)( HWND
, int, HANDLE
, DWORD
, LPTSTR
);
333 TCHAR
* CXMergeFilter::GetJavaBaseDir()
338 HKEY hDataKey
= NULL
;
340 TCHAR szClassName
[_MAX_PATH
] = "\0";
341 TCHAR szKeyName
[_MAX_PATH
] = "\0";
342 TCHAR szCurrentJava
[_MAX_PATH
] = "\0";
343 DWORD dwClassName
= _MAX_PATH
;
344 DWORD dwKeyName
= _MAX_PATH
;
346 // Locations shouldn't be greater than _MAX_PATH
347 TCHAR
* szJavaHome
= new TCHAR
[_MAX_PATH
+ 1];
348 DWORD dwSize
= _MAX_PATH
+ 1;
352 * Java leaves registry keys at HKLM\SOFTWARE\JavaSoft.
354 * Check for a JRE installation first
356 lRet
= ::RegOpenKeyEx(HKEY_LOCAL_MACHINE
, _T("SOFTWARE\\JavaSoft\\Java Runtime Environment"), 0, KEY_READ
, &hKey
);
357 if (lRet
!= ERROR_SUCCESS
)
360 /* use current version */
361 lRet
= ::RegQueryValueEx(hKey
, _T("CurrentVersion"), 0, NULL
, (LPBYTE
)szCurrentJava
, &dwSize
);
364 for (DWORD i = 0; lRet != ERROR_NO_MORE_ITEMS; i++)
366 lRet = ::RegEnumKeyEx(hKey, i, szKeyName, &dwKeyName, 0, szClassName, &dwClassName, NULL);
367 if(!strncmp(szKeyName, "1.4", 3))
369 dwKeyName = _MAX_PATH;
371 // Found a Java 1.4 installation. Can now read its home directory.
375 lRet
= ::RegOpenKeyEx(hKey
, _T(szCurrentJava
), 0, KEY_READ
, &hDataKey
);
376 if (lRet
!= ERROR_SUCCESS
)
383 // Now read the JavaHome value
384 dwSize
= _MAX_PATH
+ 1;
385 lRet
= ::RegQueryValueEx(hDataKey
, _T("JavaHome"), 0, NULL
, (LPBYTE
)szJavaHome
, &dwSize
);
386 if (lRet
!= ERROR_SUCCESS
)
388 RegCloseKey(hDataKey
);
394 RegCloseKey(hDataKey
);
398 // Check that the directory exists before returning it
399 DWORD dwAttrs
= GetFileAttributes(szJavaHome
);
401 if (((dwAttrs
& FILE_ATTRIBUTE_DIRECTORY
) != FILE_ATTRIBUTE_DIRECTORY
) || dwAttrs
== INVALID_FILE_SIZE
)
412 TCHAR
* CXMergeFilter::GetXMergeClassPath()
415 * The DLL will be installed by setup in the program directory of
416 * the installation. The XMerge Jar files, if present, will be
417 * located in the classes directory below program.
420 TCHAR szJarPath
[MAX_PATH
];
421 TCHAR szTmpPath
[MAX_PATH
];
423 ZeroMemory(szJarPath
, MAX_PATH
);
424 ZeroMemory(szTmpPath
, MAX_PATH
);
426 WIN32_FILE_ATTRIBUTE_DATA fInfo
;
431 // Get the location of the module.
432 GetModuleFileName(_Module
.m_hInst
, szTmpPath
, MAX_PATH
);
434 // Strip off the xmergesync.dll component
436 char* modName
= strstr(szTmpPath
, "xmergesync.dll");
437 strncpy(szJarPath
, szTmpPath
, modName
- szTmpPath
);
439 // Append the classes directory
440 strncat(szJarPath
, "classes\\", 8);
443 // The core xmerge.jar must be present
444 ZeroMemory(szTmpPath
, MAX_PATH
);
445 _snprintf(szTmpPath
, MAX_PATH
, "%s%s\0", szJarPath
, "xmerge.jar");
447 if (!GetFileAttributesEx(szTmpPath
, GetFileExInfoStandard
, &fInfo
))
453 clsPath
+= szTmpPath
;
458 // Now check for Pocket Word
459 ZeroMemory(szTmpPath
, MAX_PATH
);
460 _snprintf(szTmpPath
, MAX_PATH
, "%s%s\0", szJarPath
, "pocketword.jar");
462 if (!GetFileAttributesEx(szTmpPath
, GetFileExInfoStandard
, &fInfo
))
469 clsPath
+= szTmpPath
;
473 // Now check for Pocket Excel
474 ZeroMemory(szTmpPath
, MAX_PATH
);
475 _snprintf(szTmpPath
, MAX_PATH
, "%s%s\0", szJarPath
, "pexcel.jar");
477 if (!GetFileAttributesEx(szTmpPath
, GetFileExInfoStandard
, &fInfo
))
479 m_bHaveExcel
= FALSE
;
484 clsPath
+= szTmpPath
;
488 // Quotes may be need around the ClassPath
489 clsPath
.insert(0, "\"");
494 return _strdup(clsPath
.c_str());