summaryrefslogtreecommitdiffstats
path: root/bundles/org.eclipse.swt/Eclipse SWT OLE Win32
diff options
context:
space:
mode:
authorFelipe Heidrich <fheidric>2009-10-07 20:28:51 +0000
committerFelipe Heidrich <fheidric>2009-10-07 20:28:51 +0000
commit8c113a426e5f05549192616bd0df00498451eac3 (patch)
tree610c48ad5bd2fa64f9a7c648d80eb4af44a12cbe /bundles/org.eclipse.swt/Eclipse SWT OLE Win32
parent647ee8ac0b4674688a64286f665d0bc51c0718e8 (diff)
downloadeclipse.platform.swt-8c113a426e5f05549192616bd0df00498451eac3.tar.gz
eclipse.platform.swt-8c113a426e5f05549192616bd0df00498451eac3.tar.xz
eclipse.platform.swt-8c113a426e5f05549192616bd0df00498451eac3.zip
Bug 288474 - Saving a docx file fails silently due to not killing WINWORD process on close
Diffstat (limited to 'bundles/org.eclipse.swt/Eclipse SWT OLE Win32')
-rwxr-xr-xbundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java138
1 files changed, 57 insertions, 81 deletions
diff --git a/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java b/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java
index 2802c7a739..fb9d3f73d9 100755
--- a/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java
+++ b/bundles/org.eclipse.swt/Eclipse SWT OLE Win32/win32/org/eclipse/swt/ole/win32/OleClientSite.java
@@ -183,28 +183,12 @@ public OleClientSite(Composite parent, int style, File file) {
GUID fileClsid = new GUID();
char[] fileName = (file.getAbsolutePath()+"\0").toCharArray();
int result = COM.GetClassFile(fileName, fileClsid);
- if (result != COM.S_OK)
- OLE.error(OLE.ERROR_INVALID_CLASSID, result);
+ if (result != COM.S_OK) OLE.error(OLE.ERROR_INVALID_CLASSID, result);
// associated CLSID may not be installed on this machine
- appClsid = fileClsid;
- String progID = getProgramID();
- if (progID == null)
- OLE.error(OLE.ERROR_INVALID_CLASSID, result);
+ String progID = getProgID(fileClsid);
+ if (progID == null) OLE.error(OLE.ERROR_INVALID_CLASSID, result);
- /* Bug in Windows. In some machines running Windows Vista and
- * Office 2007, OleCreateFromFile() fails to open files from
- * Office Word 97 - 2003. The fix is to detect this case and create
- * the activeX using CoCreateInstance() and then load the file
- * using IPersistStorage.Load().
- */
- if (progID.equals("Word.Document.8")) { //$NON-NLS-1$
- GUID clsid = getClassID(WORDPROGID);
- String latestProgID = getProgID(clsid);
- if (latestProgID.equals("Word.Document.12")) { //$NON-NLS-1$
- appClsid = clsid;
- }
- }
-
+ appClsid = fileClsid;
OleCreate(appClsid, fileClsid, fileName, file);
} catch (SWTException e) {
dispose();
@@ -312,7 +296,15 @@ public OleClientSite(Composite parent, int style, String progId, File file) {
}
void OleCreate(GUID appClsid, GUID fileClsid, char[] fileName, File file) {
- if (COM.IsEqualGUID(appClsid, fileClsid)){
+
+ /* Bug in Windows. In some machines running Windows Vista and
+ * Office 2007, OleCreateFromFile() fails to open files from
+ * Office Word 97 - 2003 and in some other cases it fails to
+ * save files due to a lock. The fix is to detect this case and
+ * create the activeX using CoCreateInstance().
+ */
+ boolean isOffice2007 = isOffice2007(true);
+ if (!isOffice2007 && COM.IsEqualGUID(appClsid, fileClsid)){
// Using the same application that created file, therefore, use default mechanism.
tempStorage = createTempStorage();
// Create ole object with storage object
@@ -342,6 +334,7 @@ void OleCreate(GUID appClsid, GUID fileClsid, char[] fileName, File file) {
String streamName = "CONTENTS"; //$NON-NLS-1$
GUID wordGUID = getClassID(WORDPROGID);
if (wordGUID != null && COM.IsEqualGUID(appClsid, wordGUID)) streamName = "WordDocument"; //$NON-NLS-1$
+ if (isOffice2007) streamName = "Package"; //$NON-NLS-1$
address = new int /*long*/[1];
result = storage.CreateStream(streamName, mode, 0, 0, address); // Increments ref count if successful
if (result != COM.S_OK) {
@@ -864,9 +857,17 @@ public boolean isFocusControl () {
}
return false;
}
-private boolean isOffice2007() {
+private boolean isOffice2007(boolean program) {
String programID = getProgramID();
if (programID == null) return false;
+ if (program) {
+ int lastDot = programID.lastIndexOf('.');
+ if (lastDot != -1) {
+ programID = programID.substring(0, lastDot);
+ GUID guid = getClassID(programID);
+ programID = getProgID(guid);
+ }
+ }
if (programID.equals("Word.Document.12")) return true; //$NON-NLS-1$
if (programID.equals("Excel.Sheet.12")) return true; //$NON-NLS-1$
if (programID.equals("PowerPoint.Show.12")) return true; //$NON-NLS-1$
@@ -1139,6 +1140,14 @@ protected void releaseObjectInterfaces() {
* @return true if the save was successful
*/
public boolean save(File file, boolean includeOleInfo) {
+ /*
+ * Bug in Office 2007. Saving Office 2007 documents to compound file storage object
+ * causes the output file to be corrupted. The fix is to detect Office 2007 documents
+ * using the program ID and save only the content of the 'Package' stream.
+ */
+ if (isOffice2007(false)) {
+ return saveOffice2007(file);
+ }
if (includeOleInfo)
return saveToStorageFile(file);
return saveToTraditionalFile(file);
@@ -1217,6 +1226,31 @@ private int SaveObject() {
return COM.S_OK;
}
+private boolean saveOffice2007(File file) {
+ if (file == null || file.isDirectory()) return false;
+ if (!updateStorage()) return false;
+ boolean result = false;
+
+ /* Excel fails to open the package stream when the PersistStorage is not in hands off mode */
+ int /*long*/[] ppv = new int /*long*/[1];
+ IPersistStorage iPersistStorage = null;
+ if (objIUnknown.QueryInterface(COM.IIDIPersistStorage, ppv) == COM.S_OK) {
+ iPersistStorage = new IPersistStorage(ppv[0]);
+ tempStorage.AddRef();
+ iPersistStorage.HandsOffStorage();
+ }
+ int /*long*/[] address = new int /*long*/[1];
+ int grfMode = COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE;
+ if (tempStorage.OpenStream("Package", 0, grfMode, 0, address) == COM.S_OK) { //$NON-NLS-1$
+ result = saveFromContents(address[0], file);
+ }
+ if (iPersistStorage != null) {
+ iPersistStorage.SaveCompleted(tempStorage.getAddress());
+ tempStorage.Release();
+ iPersistStorage.Release();
+ }
+ return result;
+}
/**
* Saves the document to the specified file and includes OLE specific information. This method
* must <b>only</b> be used for files that have an OLE Storage format. For example, a word file
@@ -1238,38 +1272,8 @@ private boolean saveToStorageFile(File file) {
if (file == null || file.isDirectory()) return false;
if (!updateStorage()) return false;
- int /*long*/[] address = new int /*long*/[1];
- if (objIOleObject.QueryInterface(COM.IIDIPersistFile, address) == COM.S_OK) {
- String fileName = null;
- IPersistFile persistFile = new IPersistFile(address[0]);
- int /*long*/[] ppszFileName = new int /*long*/[1];
- if (persistFile.GetCurFile(ppszFileName) == COM.S_OK) {
- int /*long*/ pszFileName = ppszFileName [0];
- int length = OS.wcslen(pszFileName);
- char[] buffer = new char[length];
- OS.MoveMemory(buffer, pszFileName, length * 2);
- fileName = new String(buffer, 0, length);
- // Doc says to use IMalloc::Free, but CoTaskMemFree() does the same
- COM.CoTaskMemFree(pszFileName);
- }
- int result;
- String newFile = file.getAbsolutePath();
- if (fileName != null && fileName.equalsIgnoreCase(newFile)) {
- result = persistFile.Save(0, false);
- } else {
- int length = newFile.length();
- char[] buffer = new char[length + 1];
- newFile.getChars(0, length, buffer, 0);
- int /*long*/ lpszNewFile = COM.CoTaskMemAlloc(buffer.length * 2);
- COM.MoveMemory(lpszNewFile, buffer, buffer.length * 2);
- result = persistFile.Save(lpszNewFile, false);
- COM.CoTaskMemFree(lpszNewFile);
- }
- persistFile.Release();
- if (result == COM.S_OK) return true;
- }
-
// get access to the persistent storage mechanism
+ int /*long*/[] address = new int /*long*/[1];
if (objIOleObject.QueryInterface(COM.IIDIPersistStorage, address) != COM.S_OK) return false;
IPersistStorage permStorage = new IPersistStorage(address[0]);
try {
@@ -1312,34 +1316,6 @@ private boolean saveToTraditionalFile(File file) {
if (!updateStorage())
return false;
- /*
- * Bug in Office 2007. Saving Office 2007 documents to compound file storage object
- * causes the output file to be corrupted. The fix is to detect Office 2007 documents
- * using the program ID and save only the content of the 'Package' stream.
- */
- if (isOffice2007()) {
- /* Excel fails to open the package stream when the PersistStorage is not in hands off mode */
- int /*long*/[] ppv = new int /*long*/[1];
- IPersistStorage iPersistStorage = null;
- if (objIUnknown.QueryInterface(COM.IIDIPersistStorage, ppv) == COM.S_OK) {
- iPersistStorage = new IPersistStorage(ppv[0]);
- tempStorage.AddRef();
- iPersistStorage.HandsOffStorage();
- }
- boolean result = false;
- int /*long*/[] address = new int /*long*/[1];
- int grfMode = COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE;
- if (tempStorage.OpenStream("Package", 0, grfMode, 0, address) == COM.S_OK) { //$NON-NLS-1$
- result = saveFromContents(address[0], file);
- }
- if (iPersistStorage != null) {
- iPersistStorage.SaveCompleted(tempStorage.getAddress());
- tempStorage.Release();
- iPersistStorage.Release();
- }
- return result;
- }
-
int /*long*/[] address = new int /*long*/[1];
// Look for a CONTENTS stream
if (tempStorage.OpenStream("CONTENTS", 0, COM.STGM_DIRECT | COM.STGM_READ | COM.STGM_SHARE_EXCLUSIVE, 0, address) == COM.S_OK) //$NON-NLS-1$