[Libreoffice-commits] core.git: Branch 'distro/collabora/cp-4.3' - filter/source include/vcl vcl/Library_vcl.mk vcl/source

Tor Lillqvist tml at collabora.com
Fri Dec 12 13:58:01 PST 2014


 filter/source/pdf/impdialog.cxx   |   18 +--
 filter/source/pdf/impdialog.hrc   |    4 
 filter/source/pdf/impdialog.src   |   10 +
 filter/source/pdf/pdfexport.cxx   |    2 
 include/vcl/pdfwriter.hxx         |    5 
 vcl/Library_vcl.mk                |    4 
 vcl/source/gdi/pdfwriter_impl.cxx |  202 ++++++++++++++++++++++++++++++++------
 7 files changed, 203 insertions(+), 42 deletions(-)

New commits:
commit 4ffc81782072148f8ffeb9793c4bf4421866eefe
Author: Tor Lillqvist <tml at collabora.com>
Date:   Wed Dec 3 14:00:38 2014 +0200

    PDF signing feature backported from 4.4
    
    Cherry picked from:
    840f75065918c4584fa9159fdc90242b5374ab37
    1fe9ee73a758603ee0e1465931352c41ef8bd999
    d8a8ff8177df628636d80c4dc1d8f597f6677dfc
    bfa01d8a8248f7e44675de5ed1f85a1d17105022
    bbb18f679f5a50e9c709520d6c3260d3d9db5aa9
    c4cc31b5b55019aabad4045c8174b45e1b27073a
    7e3c931786c3cbe83ee170b8b0746d141b520ce6
    070c93af73df9aa4eb333265c81060d123b530b9
    6e91763769a562b88882a4c2a94b1367c6ed4866
    
    Change-Id: Ie8ac5e1e067f8e3b15e2f11389bd0517d348f1e3

diff --git a/filter/source/pdf/impdialog.cxx b/filter/source/pdf/impdialog.cxx
index 0825ea0..7cffddd 100644
--- a/filter/source/pdf/impdialog.cxx
+++ b/filter/source/pdf/impdialog.cxx
@@ -251,11 +251,6 @@ ImpPDFTabDialog::ImpPDFTabDialog(Window* pParent, Sequence< PropertyValue >& rFi
     mnInterfacePageId = AddTabPage("userinterface", ImpPDFTabViewerPage::Create, 0);
     mnViewPageId = AddTabPage("initialview", ImpPDFTabOpnFtrPage::Create, 0);
 
-//remove tabpage if experimentalmode is not set
-    SvtMiscOptions aMiscOptions;
-    if (!aMiscOptions.IsExperimentalMode())
-        RemoveTabPage(mnSigningPageId);
-
     //last queued is the first to be displayed (or so it seems..)
     mnGeneralPageId = AddTabPage("general", ImpPDFTabGeneralPage::Create, 0 );
 
@@ -322,11 +317,7 @@ ImpPDFTabDialog::~ImpPDFTabDialog()
     RemoveTabPage(mnViewPageId);
     RemoveTabPage(mnLinksPage);
     RemoveTabPage(mnSecurityPageId);
-
-//remove tabpage if experimentalmode is set
-    SvtMiscOptions aMiscOptions;
-    if (aMiscOptions.IsExperimentalMode())
-        RemoveTabPage(mnSigningPageId);
+    RemoveTabPage(mnSigningPageId);
 }
 
 
@@ -1495,6 +1486,13 @@ ImplErrorDialog::ImplErrorDialog(const std::set< vcl::PDFWriter::ErrorCode >& rE
             m_pErrors->SetEntryData( nPos, new OUString( PDFFilterResId( STR_WARN_TRANSP_CONVERTED ) ) );
         }
         break;
+        case vcl::PDFWriter::Error_Signature_Failed:
+        {
+            sal_uInt16 nPos = m_pErrors->InsertEntry( OUString( PDFFilterResId( STR_ERR_SIGNATURE_FAILED ) ),
+                                                aErrImg );
+            m_pErrors->SetEntryData( nPos, new OUString( PDFFilterResId( STR_ERR_PDF_EXPORT_ABORTED ) ) );
+        }
+        break;
         default:
             break;
         }
diff --git a/filter/source/pdf/impdialog.hrc b/filter/source/pdf/impdialog.hrc
index 0927cb0..3b03503 100644
--- a/filter/source/pdf/impdialog.hrc
+++ b/filter/source/pdf/impdialog.hrc
@@ -19,6 +19,9 @@
 
 #include <filter.hrc>
 
+#define STR_ERR_SIGNATURE_FAILED        (RID_PDF_DIALOG_START + 0)
+#define STR_ERR_PDF_EXPORT_ABORTED      (RID_PDF_DIALOG_START + 1)
+
 #define RID_PDF_WARNPDFAPASSWORD        (RID_PDF_DIALOG_START + 6)
 
 //strings for PDF security, user password management
@@ -39,5 +42,6 @@
 #define IMG_ERR                         (RID_PDF_DIALOG_START + 18)
 
 //ATTENTION: maximum allowed value is   (RID_PDF_DIALOG_START + 19)
+//(see filter/inc/filter.hrc)
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/filter/source/pdf/impdialog.src b/filter/source/pdf/impdialog.src
index 32d81a4..1aee2df 100644
--- a/filter/source/pdf/impdialog.src
+++ b/filter/source/pdf/impdialog.src
@@ -79,6 +79,16 @@ String STR_WARN_TRANSP_CONVERTED_SHORT
     Text [en-US] = "Transparencies removed";
 };
 
+String STR_ERR_SIGNATURE_FAILED
+{
+    Text [en-US] = "Signature generation failed";
+};
+
+String STR_ERR_PDF_EXPORT_ABORTED
+{
+    Text [en-US] = "PDF export aborted";
+};
+
 Bitmap IMG_WARN
 {
     File = "ballgreen_7.png";
diff --git a/filter/source/pdf/pdfexport.cxx b/filter/source/pdf/pdfexport.cxx
index 8aceae6..164eff9 100644
--- a/filter/source/pdf/pdfexport.cxx
+++ b/filter/source/pdf/pdfexport.cxx
@@ -915,7 +915,7 @@ bool PDFExport::Export( const OUString& rFile, const Sequence< PropertyValue >&
                 if( bRet )
                 {
                     pPDFExtOutDevData->PlayGlobalActions( *pPDFWriter );
-                    pPDFWriter->Emit();
+                    bRet = pPDFWriter->Emit();
                     aErrors = pPDFWriter->GetErrors();
                 }
                 pOut->SetExtOutDevData( NULL );
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index d4b6e90..9357c91 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -215,7 +215,10 @@ public:
 
         // transparent objects were converted to a bitmap in order
         // to removetransparencies from the output
-        Warning_Transparency_Converted
+        Warning_Transparency_Converted,
+
+        // signature generation failed
+        Error_Signature_Failed,
     };
 
     struct VCL_DLLPUBLIC AnyWidget
diff --git a/vcl/Library_vcl.mk b/vcl/Library_vcl.mk
index 4e53256..aed7a60 100644
--- a/vcl/Library_vcl.mk
+++ b/vcl/Library_vcl.mk
@@ -55,7 +55,8 @@ $(eval $(call gb_Library_use_custom_headers,vcl,\
 
 $(eval $(call gb_Library_use_externals,vcl,\
 	jpeg \
-	nss3 \
+	$(if $(filter-out WNT,$(OS)), \
+		nss3) \
 	libeot \
 ))
 
@@ -625,6 +626,7 @@ $(eval $(call gb_Library_add_exception_objects,vcl,\
 
 $(eval $(call gb_Library_use_system_win32_libs,vcl,\
 	advapi32 \
+	crypt32 \
 	gdi32 \
 	gdiplus \
 	imm32 \
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 5548629..7d7b779 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -66,8 +66,8 @@
 
 #include "pdfwriter_impl.hxx"
 
-#if !defined(ANDROID) && !defined(IOS)
-// NSS header files for PDF signing support
+#if !defined(ANDROID) && !defined(IOS) && !defined(_WIN32)
+// NSS headers for PDF signing
 #include "nss.h"
 #include "cert.h"
 #include "hasht.h"
@@ -76,6 +76,13 @@
 #include "cmst.h"
 #endif
 
+#ifdef _WIN32
+// WinCrypt headers for PDF signing
+#include <prewin.h>
+#include <wincrypt.h>
+#include <postwin.h>
+#endif
+
 #include <config_eot.h>
 
 #if ENABLE_EOT
@@ -5940,6 +5947,8 @@ bool PDFWriterImpl::emitSignature()
     return true;
 }
 
+#if !defined(ANDROID) && !defined(IOS) && !defined(_WIN32)
+
 char *PDFSigningPKCS7PasswordCallback(PK11SlotInfo * /*slot*/, PRBool /*retry*/, void *arg)
 {
     return (char *)arg;
@@ -5956,6 +5965,39 @@ namespace {
     };
 }
 
+#endif
+
+#ifdef _WIN32
+
+namespace {
+
+OUString WindowsError(DWORD nErrorCode)
+{
+    LPWSTR pMsgBuf;
+
+    if (FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                       NULL,
+                       nErrorCode,
+                       MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+                       (LPWSTR)&pMsgBuf,
+                       0,
+                       NULL) == 0)
+        return OUString::number(nErrorCode, 16);
+
+    if (pMsgBuf[wcslen(pMsgBuf)-1] == '\n')
+        pMsgBuf[wcslen(pMsgBuf)-1] = '\0';
+
+    OUString result(pMsgBuf);
+
+    LocalFree(pMsgBuf);
+
+    return result;
+}
+
+}
+
+#endif
+
 bool PDFWriterImpl::finalizeSignature()
 {
 
@@ -5990,25 +6032,23 @@ bool PDFWriterImpl::finalizeSignature()
     sal_Int8* n_derArray = derEncoded.getArray();
     sal_Int32 n_derLength = derEncoded.getLength();
 
-    NSS_NoDB_Init(".");
+#ifndef _WIN32
 
     CERTCertificate *cert = CERT_DecodeCertFromPackage(reinterpret_cast<char *>(n_derArray), n_derLength);
 
     if (!cert)
     {
-        SAL_WARN("vcl.gdi", "PDF Signing: Error occurred, certificate cannot be reconstructed.");
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: Error occurred, certificate cannot be reconstructed.");
         return false;
     }
 
-    SAL_WARN("vcl.gdi", "PDF Signing: Certificate Subject: " <<  cert->subjectName << "\n\tCertificate Issuer: " << cert->issuerName);
-
     // Prepare buffer and calculate PDF file digest
     CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, 0) ) );
 
     HashContextScope hc(HASH_Create(HASH_AlgSHA1));
     if (!hc.get())
     {
-        SAL_WARN("vcl.gdi", "PDF Signing: SHA1 HASH_Create failed!");
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: SHA1 HASH_Create failed!");
         return false;
     }
 
@@ -6021,7 +6061,7 @@ bool PDFWriterImpl::finalizeSignature()
 
     CHECK_RETURN( (osl_File_E_None == osl_readFile( m_aFile, buffer.get(), m_nSignatureContentOffset - 1 , &bytesRead ) ) );
     if (bytesRead != (sal_uInt64)m_nSignatureContentOffset - 1)
-        SAL_WARN("vcl.gdi", "PDF Signing: First buffer read failed!");
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: First buffer read failed!");
 
     HASH_Update(hc.get(), reinterpret_cast<const unsigned char*>(buffer.get()), bytesRead);
 
@@ -6029,7 +6069,7 @@ bool PDFWriterImpl::finalizeSignature()
     buffer.reset(new char[nLastByteRangeNo + 1]);
     CHECK_RETURN( (osl_File_E_None == osl_readFile( m_aFile, buffer.get(), nLastByteRangeNo, &bytesRead ) ) );
     if (bytesRead != (sal_uInt64) nLastByteRangeNo)
-        SAL_WARN("vcl.gdi", "PDF Signing: Second buffer read failed!");
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: Second buffer read failed!");
 
     HASH_Update(hc.get(), reinterpret_cast<const unsigned char*>(buffer.get()), bytesRead);
 
@@ -6044,21 +6084,21 @@ bool PDFWriterImpl::finalizeSignature()
     NSSCMSMessage *cms_msg = NSS_CMSMessage_Create(NULL);
     if (!cms_msg)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't create new CMS message.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't create new CMS message.");
         return false;
     }
 
     NSSCMSSignedData *cms_sd = NSS_CMSSignedData_Create(cms_msg);
     if (!cms_sd)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't create CMS SignedData.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't create CMS SignedData.");
         return false;
     }
 
     NSSCMSContentInfo *cms_cinfo = NSS_CMSMessage_GetContentInfo(cms_msg);
     if (NSS_CMSContentInfo_SetContent_SignedData(cms_msg, cms_cinfo, cms_sd) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: Can't set CMS content signed data.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: Can't set CMS content signed data.");
         return false;
     }
 
@@ -6066,49 +6106,47 @@ bool PDFWriterImpl::finalizeSignature()
     //attach NULL data as detached data
     if (NSS_CMSContentInfo_SetContent_Data(cms_msg, cms_cinfo, NULL, PR_TRUE) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: Can't set CMS content data.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: Can't set CMS content data.");
         return false;
     }
 
     NSSCMSSignerInfo *cms_signer = NSS_CMSSignerInfo_Create(cms_msg, cert, SEC_OID_SHA1);
     if (!cms_signer)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't create CMS SignerInfo.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't create CMS SignerInfo.");
         return false;
     }
 
     if (NSS_CMSSignerInfo_IncludeCerts(cms_signer, NSSCMSCM_CertChain, certUsageEmailSigner) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't include cert chain.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't include cert chain.");
         return false;
     }
 
     if (NSS_CMSSignerInfo_AddSigningTime(cms_signer, PR_Now()) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't add signing time.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't add signing time.");
         return false;
     }
 
     if (NSS_CMSSignedData_AddCertificate(cms_sd, cert) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't add signer certificate.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't add signer certificate.");
         return false;
     }
 
     if (NSS_CMSSignedData_AddSignerInfo(cms_sd, cms_signer) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't add signer info.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't add signer info.");
         return false;
     }
 
     if (NSS_CMSSignedData_SetDigestValue(cms_sd, SEC_OID_SHA1, &digest) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF signing: can't set PDF digest value.");
+        SAL_WARN("vcl.pdfwriter", "PDF signing: can't set PDF digest value.");
         return false;
     }
 
-    SAL_WARN("vcl.gdi","PKCS7 Object created successfully!");
-
     SECItem cms_output;
     cms_output.data = 0;
     cms_output.len = 0;
@@ -6120,25 +6158,21 @@ bool PDFWriterImpl::finalizeSignature()
 
     if (!cms_ecx)
     {
-        SAL_WARN("vcl.gdi", "PDF Signing: can't start DER encoder.");
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: can't start DER encoder.");
         return false;
     }
-    SAL_WARN("vcl.gdi", "PDF Signing: Started DER encoding.");
 
     if (NSS_CMSEncoder_Finish(cms_ecx) != SECSuccess)
     {
-        SAL_WARN("vcl.gdi", "PDF Signing: can't finish DER encoder.");
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: can't finish DER encoder.");
         return false;
     }
-    SAL_WARN("vcl.gdi", "PDF Signing: Finished DER encoding.");
 
     OStringBuffer cms_hexbuffer;
 
     for (unsigned int i = 0; i < cms_output.len ; i++)
         appendHex(cms_output.data[i], cms_hexbuffer);
 
-    SAL_WARN("vcl.gdi","PKCS7 object encoded successfully!");
-
     // Set file pointer to the m_nSignatureContentOffset, we're ready to overwrite PKCS7 object
     nWritten = 0;
     CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset) ) );
@@ -6148,6 +6182,104 @@ bool PDFWriterImpl::finalizeSignature()
 
     CHECK_RETURN( (osl_File_E_None == osl_setFilePos( m_aFile, osl_Pos_Absolut, nOffset ) ) );
     return true;
+
+#else
+
+    // Prepare buffer and calculate PDF file digest
+    CHECK_RETURN( (osl_File_E_None == osl_setFilePos(m_aFile, osl_Pos_Absolut, 0)));
+
+    PCCERT_CONTEXT pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, reinterpret_cast<const BYTE*>(n_derArray), n_derLength);
+    if (pCertContext == NULL)
+    {
+        SAL_WARN("vcl.pdfwriter", "CertCreateCertificateContext failed: " << WindowsError(GetLastError()));
+        return false;
+    }
+
+    boost::scoped_array<char> buffer1(new char[m_nSignatureContentOffset - 1]);
+    sal_uInt64 bytesRead1;
+
+    if (osl_File_E_None != osl_readFile(m_aFile, buffer1.get(), m_nSignatureContentOffset - 1 , &bytesRead1) ||
+        bytesRead1 != (sal_uInt64)m_nSignatureContentOffset - 1)
+    {
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: First buffer read failed!");
+        CertFreeCertificateContext(pCertContext);
+        return false;
+    }
+
+    boost::scoped_array<char> buffer2(new char[nLastByteRangeNo]);
+    sal_uInt64 bytesRead2;
+
+    if (osl_File_E_None != osl_setFilePos(m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset + MAX_SIGNATURE_CONTENT_LENGTH + 1) ||
+        osl_File_E_None != osl_readFile(m_aFile, buffer2.get(), nLastByteRangeNo, &bytesRead2) ||
+        bytesRead2 != (sal_uInt64) nLastByteRangeNo)
+    {
+        SAL_WARN("vcl.pdfwriter", "PDF Signing: Second buffer read failed!");
+        CertFreeCertificateContext(pCertContext);
+        return false;
+    }
+
+    OString pass = OUStringToOString( m_aContext.SignPassword, RTL_TEXTENCODING_UTF8 );
+
+    CRYPT_SIGN_MESSAGE_PARA aPara;
+
+    memset(&aPara, 0, sizeof(aPara));
+    aPara.cbSize = sizeof(aPara);
+    aPara.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
+    aPara.pSigningCert = pCertContext;
+    aPara.HashAlgorithm.pszObjId = szOID_RSA_SHA1RSA;
+    aPara.HashAlgorithm.Parameters.cbData = 0;
+    aPara.cMsgCert = 1;
+    aPara.rgpMsgCert = &pCertContext;
+
+    const BYTE *aBuffers[] =
+        { reinterpret_cast<BYTE*>(buffer1.get()), reinterpret_cast<BYTE*>(buffer2.get()) };
+    DWORD aBufferLens[] =
+        { bytesRead1, bytesRead2 };
+    assert(SAL_N_ELEMENTS(aBuffers) == SAL_N_ELEMENTS(aBufferLens));
+
+    DWORD nSigLen(0);
+
+    if (!CryptSignMessage(&aPara, TRUE, SAL_N_ELEMENTS(aBuffers), aBuffers, aBufferLens, NULL, &nSigLen))
+    {
+        SAL_WARN("vcl.pdfwriter", "CryptSignMessage failed: " << WindowsError(GetLastError()));
+        CertFreeCertificateContext(pCertContext);
+        return false;
+    }
+
+    if (nSigLen*2 > MAX_SIGNATURE_CONTENT_LENGTH)
+    {
+        SAL_WARN("vcl.pdfwriter", "Signature requires more space (" << nSigLen*2 << ") than we reserved (" << MAX_SIGNATURE_CONTENT_LENGTH << ")");
+        CertFreeCertificateContext(pCertContext);
+        return false;
+    }
+
+    SAL_INFO("vcl.pdfwriter", "Signature size is " << nSigLen << " bytes");
+
+    boost::scoped_array<BYTE> pSig(new BYTE[nSigLen]);
+    if (!CryptSignMessage(&aPara, TRUE, SAL_N_ELEMENTS(aBuffers), aBuffers, aBufferLens, pSig.get(), &nSigLen))
+    {
+        SAL_WARN("vcl.pdfwriter", "CryptSignMessage failed: " << WindowsError(GetLastError()));
+        CertFreeCertificateContext(pCertContext);
+        return false;
+    }
+
+    // Release resources
+    CertFreeCertificateContext(pCertContext);
+
+    OStringBuffer cms_hexbuffer;
+
+    for (unsigned int i = 0; i < nSigLen ; i++)
+        appendHex(pSig[i], cms_hexbuffer);
+
+    // Set file pointer to the m_nSignatureContentOffset, we're ready to overwrite PKCS7 object
+    nWritten = 0;
+    CHECK_RETURN( (osl_File_E_None == osl_setFilePos(m_aFile, osl_Pos_Absolut, m_nSignatureContentOffset)) );
+    osl_writeFile(m_aFile, cms_hexbuffer.getStr(), cms_hexbuffer.getLength(), &nWritten);
+
+    CHECK_RETURN( (osl_File_E_None == osl_setFilePos(m_aFile, osl_Pos_Absolut, nOffset)) );
+
+    return true;
+#endif
 }
 
 #endif
@@ -6951,7 +7083,13 @@ bool PDFWriterImpl::emit()
 
 #if !defined(ANDROID) && !defined(IOS)
     if (m_nSignatureObject != -1) // if document is signed, emit sigdict
-        CHECK_RETURN( emitSignature() );
+    {
+        if( !emitSignature() )
+        {
+            m_aErrors.insert( PDFWriter::Error_Signature_Failed );
+            return false;
+        }
+    }
 #endif
 
     // emit trailer
@@ -6959,7 +7097,13 @@ bool PDFWriterImpl::emit()
 
 #if !defined(ANDROID) && !defined(IOS)
     if (m_nSignatureObject != -1) // finalize the signature
-        CHECK_RETURN( finalizeSignature() );
+    {
+        if( !finalizeSignature() )
+        {
+            m_aErrors.insert( PDFWriter::Error_Signature_Failed );
+            return false;
+        }
+    }
 #endif
 
     osl_closeFile( m_aFile );


More information about the Libreoffice-commits mailing list