LibreOffice Module oox (master) 1
vbaexport.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10#include <sal/config.h>
11
12#include <cassert>
13#include <random>
14#include <string_view>
15
16#include <oox/ole/vbaexport.hxx>
17
18#include <tools/stream.hxx>
19
20#include <com/sun/star/beans/XPropertySet.hpp>
21#include <com/sun/star/script/XLibraryContainer.hpp>
22#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
23#include <com/sun/star/script/vba/XVBACompatibility.hpp>
24#include <com/sun/star/frame/XModel.hpp>
25
26#include <ooo/vba/excel/XWorkbook.hpp>
27
29#include <oox/token/properties.hxx>
30
31#include <sot/storage.hxx>
32
34#include <utility>
35#include <rtl/tencinfo.h>
36#include <osl/thread.h>
37
38#define VBA_EXPORT_DEBUG 0
39#define VBA_USE_ORIGINAL_WM_STREAM 0
40#define VBA_USE_ORIGINAL_DIR_STREAM 0
41#define VBA_USE_ORIGINAL_PROJECT_STREAM 0
42#define VBA_USE_ORIGINAL_VBA_PROJECT 0
43
44/* Enable to see VBA Encryption work. For now the input data and length values
45 * for encryption correspond to the case when the VBA macro is not protected.
46 */
47#define VBA_ENCRYPTION 1
48
49namespace {
50
51void exportString(SvStream& rStrm, std::u16string_view rString,
52 const rtl_TextEncoding eTextEncoding)
53{
54 OString aStringCorrectCodepage = OUStringToOString(rString, eTextEncoding);
55 rStrm.WriteOString(aStringCorrectCodepage);
56}
57
58void exportUTF16String(SvStream& rStrm, const OUString& rString)
59{
60 sal_Int32 n = rString.getLength();
61 const sal_Unicode* pString = rString.getStr();
62 for (sal_Int32 i = 0; i < n; ++i)
63 {
64 sal_Unicode character = pString[i];
66 }
67}
68
69bool isWorkbook(const css::uno::Reference<css::uno::XInterface>& xInterface)
70{
71 css::uno::Reference<ooo::vba::excel::XWorkbook> xWorkbook(xInterface, css::uno::UNO_QUERY);
72 return xWorkbook.is();
73}
74
75OUString createHexStringFromDigit(sal_uInt8 nDigit)
76{
77 OUString aString = OUString::number( nDigit, 16 );
78 if(aString.getLength() == 1)
79 aString = OUString::number(0) + aString;
80 return aString.toAsciiUpperCase();
81}
82
83}
84
85VBACompressionChunk::VBACompressionChunk(SvStream& rCompressedStream, const sal_uInt8* pData, std::size_t nChunkSize)
86 : mrCompressedStream(rCompressedStream)
87 , mpUncompressedData(pData)
88 , mpCompressedChunkStream(nullptr)
89 , mnChunkSize(nChunkSize)
90 , mnCompressedCurrent(0)
91 , mnCompressedEnd(0)
92 , mnDecompressedCurrent(0)
93 , mnDecompressedEnd(0)
94{
95}
96
97static void setUInt16(sal_uInt8* pBuffer, size_t nPos, sal_uInt16 nVal)
98{
99 pBuffer[nPos] = nVal & 0xFF;
100 pBuffer[nPos+1] = (nVal & 0xFF00) >> 8;
101}
102
103sal_uInt16 VBACompressionChunk::handleHeader(bool bCompressed)
104{
105 // handle header bytes
106 size_t nSize = mnCompressedCurrent;
107 sal_uInt16 nHeader = 0;
108 PackCompressedChunkSize(nSize, nHeader);
109 PackCompressedChunkFlag(bCompressed, nHeader);
111
112 return nHeader;
113}
114
115// section 2.4.1.3.7
117{
118
121 mnCompressedEnd = 4098;
122 mnDecompressedEnd = std::min<sal_uInt64>(4096, mnChunkSize);
123
124 // if that stream becomes larger than 4096 bytes then
125 // we use the uncompressed stream
126 sal_uInt8 pCompressedChunkStream[4098];
127 mpCompressedChunkStream = pCompressedChunkStream;
128
131 {
132 // compress token sequence
134 }
135
137 {
138 sal_uInt64 nChunkStart = mrCompressedStream.Tell();
141 mrCompressedStream.Seek(nChunkStart);
142 sal_uInt16 nHeader = handleHeader(false);
144 }
145 else
146 {
147 sal_uInt16 nHeader = handleHeader(true);
148 setUInt16(pCompressedChunkStream, 0, nHeader);
149 // copy the compressed stream to our output stream
150 mrCompressedStream.WriteBytes(pCompressedChunkStream, mnCompressedCurrent);
151 }
152}
153
154// section 2.4.1.3.13
155void VBACompressionChunk::PackCompressedChunkSize(size_t nSize, sal_uInt16& rHeader)
156{
157 sal_uInt16 nTemp1 = rHeader & 0xF000;
158 sal_uInt16 nTemp2 = nSize - 3;
159 rHeader = nTemp1 | nTemp2;
160}
161
162// section 2.4.1.3.16
163void VBACompressionChunk::PackCompressedChunkFlag(bool bCompressed, sal_uInt16& rHeader)
164{
165 sal_uInt16 nTemp1 = rHeader & 0x7FFF;
166 sal_uInt16 nTemp2 = static_cast<sal_uInt16>(bCompressed) << 15;
167 rHeader = nTemp1 | nTemp2;
168}
169
170// section 2.4.1.3.14
172{
173 sal_Int32 nTemp = rHeader & 0x8FFFF;
174 rHeader = nTemp | 0x3000;
175}
176
177// section 2.4.1.3.8
179{
180 sal_uInt64 nFlagByteIndex = mnCompressedCurrent;
181 sal_uInt8 nFlagByte = 0;
183 for (size_t index = 0; index <= 7; ++index)
184 {
187 {
188 compressToken(index, nFlagByte);
189 }
190 }
191 mpCompressedChunkStream[nFlagByteIndex] = nFlagByte;
192}
193
194// section 2.4.1.3.9
195void VBACompressionChunk::compressToken(size_t index, sal_uInt8& nFlagByte)
196{
197 size_t nLength = 0;
198 size_t nOffset = 0;
199 match(nLength, nOffset);
200 if (nOffset != 0)
201 {
203 {
204 sal_uInt16 nToken = CopyToken(nLength, nOffset);
206 SetFlagBit(index, true, nFlagByte);
209 }
210 else
211 {
213 }
214 }
215 else
216 {
218 {
222 }
223 else
224 {
226 }
227 }
228}
229
230// section 2.4.1.3.18
231void VBACompressionChunk::SetFlagBit(size_t index, bool bVal, sal_uInt8& rFlag)
232{
233 size_t nTemp1 = static_cast<int>(bVal) << index;
234 sal_uInt8 nTemp2 = rFlag & (~nTemp1);
235 rFlag = nTemp2 | nTemp1;
236}
237
238// section 2.4.1.3.19.3
239sal_uInt16 VBACompressionChunk::CopyToken(size_t nLength, size_t nOffset)
240{
241 sal_uInt16 nLengthMask = 0;
242 sal_uInt16 nOffsetMask = 0;
243 sal_uInt16 nBitCount = 0;
244 sal_uInt16 nMaxLength;
245 CopyTokenHelp(nLengthMask, nOffsetMask, nBitCount, nMaxLength);
246 sal_uInt16 nTemp1 = nOffset -1;
247 sal_uInt16 nTemp2 = 16 - nBitCount;
248 sal_uInt16 nTemp3 = nLength - 3;
249 sal_uInt16 nToken = (nTemp1 << nTemp2) | nTemp3;
250 return nToken;
251}
252
253// section 2.4.1.3.19.4
254void VBACompressionChunk::match(size_t& rLength, size_t& rOffset)
255{
256 size_t nBestLen = 0;
257 sal_Int32 nCandidate = mnDecompressedCurrent - 1;
258 sal_Int32 nBestCandidate = nCandidate;
259 while (nCandidate >= 0)
260 {
261 sal_Int32 nC = nCandidate;
262 sal_Int32 nD = mnDecompressedCurrent;
263 size_t nLen = 0;
264 while (nD < static_cast<sal_Int32>(mnChunkSize) // TODO: check if this needs to be including a minus -1
266 {
267 ++nLen;
268 ++nC;
269 ++nD;
270 }
271 if (nLen > nBestLen)
272 {
273 nBestLen = nLen;
274 nBestCandidate = nCandidate;
275 }
276 --nCandidate;
277 }
278
279 if (nBestLen >= 3)
280 {
281 sal_uInt16 nMaximumLength = 0;
282 sal_uInt16 nLengthMask, nOffsetMask, nBitCount;
283 CopyTokenHelp(nLengthMask, nOffsetMask, nBitCount, nMaximumLength);
284 rLength = std::min<sal_uInt16>(nMaximumLength, nBestLen);
285 rOffset = mnDecompressedCurrent - nBestCandidate;
286 }
287 else
288 {
289 rLength = 0;
290 rOffset = 0;
291 }
292}
293
294// section 2.4.1.3.19.1
295void VBACompressionChunk::CopyTokenHelp(sal_uInt16& rLengthMask, sal_uInt16& rOffsetMask,
296 sal_uInt16& rBitCount, sal_uInt16& rMaximumLength)
297{
298 sal_uInt16 nDifference = mnDecompressedCurrent;
299 assert(nDifference <= 4096);
300 assert(nDifference >= 1);
301 if (nDifference >= 2049)
302 rBitCount = 12;
303 else if (nDifference >= 1025)
304 rBitCount = 11;
305 else if (nDifference >= 513)
306 rBitCount = 10;
307 else if (nDifference >= 257)
308 rBitCount = 9;
309 else if (nDifference >= 129)
310 rBitCount = 8;
311 else if (nDifference >= 65)
312 rBitCount = 7;
313 else if (nDifference >= 33)
314 rBitCount = 6;
315 else if (nDifference >= 17)
316 rBitCount = 5;
317 else
318 rBitCount = 4;
319 rLengthMask = 0xffff >> rBitCount;
320 rOffsetMask = ~rLengthMask;
321 rMaximumLength = rLengthMask + 3;
322}
323
324// section 2.4.1.3.10
326{
327 // we need to use up to 4096 bytes of the original stream
328 // and fill the rest with padding
330 std::size_t nPadding = 4096 - mnChunkSize;
331 for (size_t i = 0; i < nPadding; ++i)
332 {
334 }
335}
336
338 SvMemoryStream& rUncompressedStream):
339 mrCompressedStream(rCompressedStream),
340 mrUncompressedStream(rUncompressedStream)
341{
342}
343
344// section 2.4.1.3.6
346{
347 // section 2.4.1.1.1
348 mrCompressedStream.WriteUInt8(0x01); // signature byte of a compressed container
349 bool bStreamNotEnded = true;
350 const sal_uInt8* pData = static_cast<const sal_uInt8*>(mrUncompressedStream.GetData());
351 std::size_t nSize = mrUncompressedStream.GetEndOfData();
352 std::size_t nRemainingSize = nSize;
353 while(bStreamNotEnded)
354 {
355 std::size_t nChunkSize = std::min<size_t>(nRemainingSize, 4096);
356 VBACompressionChunk aChunk(mrCompressedStream, &pData[nSize - nRemainingSize], nChunkSize);
357 aChunk.write();
358
359 // update the uncompressed chunk start marker
360 nRemainingSize -= nChunkSize;
361 bStreamNotEnded = nRemainingSize != 0;
362 }
363}
364
365// section 2.4.3
366#if VBA_ENCRYPTION
367
368VBAEncryption::VBAEncryption(const sal_uInt8* pData, const sal_uInt16 length,
369 SvStream& rEncryptedData, sal_uInt8 nProjKey,
370 const rtl_TextEncoding eTextEncoding)
371 :mpData(pData)
372 ,mnLength(length)
373 ,mrEncryptedData(rEncryptedData)
374 ,mnUnencryptedByte1(0)
375 ,mnEncryptedByte1(0)
376 ,mnEncryptedByte2(0)
377 ,mnProjKey(nProjKey)
378 ,mnIgnoredLength(0)
379 ,mnSeed(0x00)
380 ,mnVersionEnc(0)
381 ,meTextEncoding(eTextEncoding)
382{
383 std::random_device rd;
384 std::mt19937 gen(rd());
385 std::uniform_int_distribution<> dis(0, 255);
386 mnSeed = dis(gen);
387}
388
390{
391 exportString(mrEncryptedData, createHexStringFromDigit(mnSeed), meTextEncoding);
392}
393
395{
396 static const sal_uInt8 mnVersion = 2; // the encrypted version
397 mnVersionEnc = mnSeed ^ mnVersion;
398 exportString(mrEncryptedData, createHexStringFromDigit(mnVersionEnc), meTextEncoding);
399}
400
401sal_uInt8 VBAEncryption::calculateProjKey(const OUString& rProjectKey)
402{
403 sal_uInt8 nProjKey = 0;
404 sal_Int32 n = rProjectKey.getLength();
405 const sal_Unicode* pString = rProjectKey.getStr();
406 for (sal_Int32 i = 0; i < n; ++i)
407 {
408 sal_Unicode character = pString[i];
409 nProjKey += character;
410 }
411
412 return nProjKey;
413}
414
416{
417 sal_uInt8 nProjKeyEnc = mnSeed ^ mnProjKey;
418 exportString(mrEncryptedData, createHexStringFromDigit(nProjKeyEnc), meTextEncoding);
420 mnEncryptedByte1 = nProjKeyEnc; // ProjKeyEnc
421 mnEncryptedByte2 = mnVersionEnc; // VersionEnc
422}
423
425{
426 mnIgnoredLength = (mnSeed & 6) / 2;
427 for(sal_Int32 i = 1; i <= mnIgnoredLength; ++i)
428 {
429 sal_uInt8 nTempValue = 0xBE; // Any value can be assigned here
430 sal_uInt8 nByteEnc = nTempValue ^ (mnEncryptedByte2 + mnUnencryptedByte1);
431 exportString(mrEncryptedData, createHexStringFromDigit(nByteEnc), meTextEncoding);
433 mnEncryptedByte1 = nByteEnc;
434 mnUnencryptedByte1 = nTempValue;
435 }
436}
437
439{
440 sal_uInt16 temp = mnLength;
441 for(sal_Int8 i = 0; i < 4; ++i)
442 {
443 sal_uInt8 nByte = temp & 0xFF;
444 sal_uInt8 nByteEnc = nByte ^ (mnEncryptedByte2 + mnUnencryptedByte1);
445 exportString(mrEncryptedData, createHexStringFromDigit(nByteEnc), meTextEncoding);
447 mnEncryptedByte1 = nByteEnc;
448 mnUnencryptedByte1 = nByte;
449 temp >>= 8;
450 }
451}
452
454{
455 for(sal_Int16 i = 0; i < mnLength; i++)
456 {
458 exportString(mrEncryptedData, createHexStringFromDigit(nByteEnc), meTextEncoding);
460 mnEncryptedByte1 = nByteEnc;
462 }
463}
464
466{
467 writeSeed();
472 writeDataEnc();
473}
474
475#endif
476
477VbaExport::VbaExport(css::uno::Reference<css::frame::XModel> xModel):
478 mxModel(std::move(xModel))
479{
480}
481
482namespace {
483
484// section 2.3.4.2.1.1
485void writePROJECTSYSKIND(SvStream& rStrm)
486{
487 rStrm.WriteUInt16(0x0001); // id
488 rStrm.WriteUInt32(0x00000004); // size
489 rStrm.WriteUInt32(0x00000001); // SysKind, hard coded to 32-bin windows for now
490}
491
492// section 2.3.4.2.1.2
493void writePROJECTLCID(SvStream& rStrm)
494{
495 rStrm.WriteUInt16(0x0002); // id
496 rStrm.WriteUInt32(0x00000004); // size
497 rStrm.WriteUInt32(0x00000409); // Lcid
498}
499
500// section 2.3.4.2.1.3
501void writePROJECTLCIDINVOKE(SvStream& rStrm)
502{
503 rStrm.WriteUInt16(0x0014); // id
504 rStrm.WriteUInt32(0x00000004); // size
505 rStrm.WriteUInt32(0x00000409); // LcidInvoke
506}
507
508// section 2.3.4.2.1.4
509void writePROJECTCODEPAGE(SvStream& rStrm, const rtl_TextEncoding eTextEncoding)
510{
511 rStrm.WriteUInt16(0x0003); // id
512 rStrm.WriteUInt32(0x00000002); // size
513 rStrm.WriteUInt16(rtl_getWindowsCodePageFromTextEncoding(eTextEncoding)); // CodePage
514}
515
516//section 2.3.4.2.1.5
517void writePROJECTNAME(SvStream& rStrm, const OUString& name, const rtl_TextEncoding eTextEncoding)
518{
519 rStrm.WriteUInt16(0x0004); // id
520 sal_uInt32 sizeOfProjectName = name.getLength();
521 rStrm.WriteUInt32(sizeOfProjectName); // sizeOfProjectName
522 exportString(rStrm, name, eTextEncoding); // ProjectName
523}
524
525//section 2.3.4.2.1.6
526void writePROJECTDOCSTRING(SvStream& rStrm)
527{
528 rStrm.WriteUInt16(0x0005); // id
529 rStrm.WriteUInt32(0x00000000); // sizeOfDocString
530 rStrm.WriteUInt16(0x0040); // Reserved
531 rStrm.WriteUInt32(0x00000000); // sizeOfDocStringUnicode, MUST be even
532}
533
534//section 2.3.4.2.1.7
535void writePROJECTHELPFILEPATH(SvStream& rStrm)
536{
537 rStrm.WriteUInt16(0x0006); // id
538 rStrm.WriteUInt32(0x00000000); // sizeOfHelpFile1
539 rStrm.WriteUInt16(0x003D); // Reserved
540 rStrm.WriteUInt32(0x00000000); // sizeOfHelpFile2
541}
542
543//section 2.3.4.2.1.8
544void writePROJECTHELPCONTEXT(SvStream& rStrm)
545{
546 rStrm.WriteUInt16(0x0007); // id
547 rStrm.WriteUInt32(0x00000004); // size
548 rStrm.WriteUInt32(0x00000000); // HelpContext
549}
550
551//section 2.3.4.2.1.9
552void writePROJECTLIBFLAGS(SvStream& rStrm)
553{
554 rStrm.WriteUInt16(0x0008); // id
555 rStrm.WriteUInt32(0x00000004); // size
556 rStrm.WriteUInt32(0x00000000); // ProjectLibFlags
557}
558
559//section 2.3.4.2.1.10
560void writePROJECTVERSION(SvStream& rStrm)
561{
562 rStrm.WriteUInt16(0x0009); // id
563 rStrm.WriteUInt32(0x00000004); // Reserved
564 rStrm.WriteUInt32(1467127224); // VersionMajor // TODO: where is this magic number coming from
565 rStrm.WriteUInt16(5); // VersionMinor // TODO: where is this magic number coming from
566}
567
568//section 2.3.4.2.1.11
569void writePROJECTCONSTANTS(SvStream& rStrm)
570{
571 rStrm.WriteUInt16(0x000C); // id
572 rStrm.WriteUInt32(0x00000000); // sizeOfConstants
573 rStrm.WriteUInt16(0x003C); // Reserved
574 rStrm.WriteUInt32(0x00000000); // sizeOfConstantsUnicode
575}
576
577// section 2.3.4.2.1
578void writePROJECTINFORMATION(SvStream& rStrm, const OUString& projectName,
579 const rtl_TextEncoding eTextEncoding)
580{
581 writePROJECTSYSKIND(rStrm);
582 writePROJECTLCID(rStrm);
583 writePROJECTLCIDINVOKE(rStrm);
584 writePROJECTCODEPAGE(rStrm, eTextEncoding);
585 writePROJECTNAME(rStrm, projectName, eTextEncoding);
586 writePROJECTDOCSTRING(rStrm);
587 writePROJECTHELPFILEPATH(rStrm);
588 writePROJECTHELPCONTEXT(rStrm);
589 writePROJECTLIBFLAGS(rStrm);
590 writePROJECTVERSION(rStrm);
591 writePROJECTCONSTANTS(rStrm);
592}
593
594// section 2.3.4.2.2.2
595void writeREFERENCENAME(SvStream& rStrm, const OUString& name, const rtl_TextEncoding eTextEncoding)
596{
597 rStrm.WriteUInt16(0x0016); // id
598 sal_Int32 size = name.getLength();
599 rStrm.WriteUInt32(size); // sizeOfName
600 exportString(rStrm, name, eTextEncoding); // name
601 rStrm.WriteUInt16(0x003E); // reserved
602 sal_Int32 unicodesize = size * 2;
603 rStrm.WriteUInt32(unicodesize); // sizeOfNameUnicode
604 exportUTF16String(rStrm, name); // nameUnicode
605}
606
607// section 2.3.4.2.2.5
608void writeREFERENCEREGISTERED(SvStream& rStrm, const OUString& libid,
609 const rtl_TextEncoding eTextEncoding)
610{
611 rStrm.WriteUInt16(0x000D); // id
612 sal_Int32 sizeOfLibid = libid.getLength();
613 sal_Int32 size = sizeOfLibid + 10; // size of Libid, sizeOfLibid(4 bytes), reserved 1(4 bytes) and reserved 2(2 bytes)
614 rStrm.WriteUInt32(size); // size
615 rStrm.WriteUInt32(sizeOfLibid); // sizeOfLibid
616 exportString(rStrm, libid, eTextEncoding); // Libid
617 rStrm.WriteUInt32(0x00000000); // reserved 1
618 rStrm.WriteUInt16(0x0000); // reserved 2
619}
620
621// section 2.3.4.2.2.1
622void writeREFERENCE(SvStream& rStrm, const OUString& name, const OUString& libid,
623 const rtl_TextEncoding eTextEncoding)
624{
625 writeREFERENCENAME(rStrm, name, eTextEncoding);
626 writeREFERENCEREGISTERED(rStrm, libid, eTextEncoding);
627}
628
629// section 2.3.4.2.2
630void writePROJECTREFERENCES(SvStream& rStrm, const rtl_TextEncoding eTextEncoding)
631{
632 // TODO: find out where these references are coming from
633 writeREFERENCE(rStrm, "stdole", "*\\G{00020430-0000-0000-C000-000000000046}#2.0#0#C:\\Windows\\SysWOW64\\stdole2.tlb#OLE Automation", eTextEncoding);
634 writeREFERENCE(rStrm, "Office", "*\\G{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}#2.0#0#C:\\Program Files (x86)\\Common Files\\Microsoft Shared\\OFFICE14\\MSO.DLL#Microsoft Office 14.0 Object Library", eTextEncoding);
635}
636
637// section 2.3.4.2.3.1
638void writePROJECTCOOKIE(SvStream& rStrm)
639{
640 rStrm.WriteUInt16(0x0013); // id
641 rStrm.WriteUInt32(0x00000002); // size
642 rStrm.WriteUInt16(0xFFFF); // cookie
643}
644
645// section 2.3.4.2.3.2.1
646void writeMODULENAME(SvStream& rStrm, const OUString& name, const rtl_TextEncoding eTextEncoding)
647{
648 rStrm.WriteUInt16(0x0019); // id
649 sal_Int32 n = name.getLength(); // sizeOfModuleName
651 exportString(rStrm, name, eTextEncoding); // ModuleName
652}
653
654// section 2.3.4.2.3.2.2
655void writeMODULENAMEUNICODE(SvStream& rStrm, const OUString& name)
656{
657 rStrm.WriteUInt16(0x0047); // id
658 sal_Int32 n = name.getLength() * 2; // sizeOfModuleNameUnicode // TODO: better calculation for unicode string length
660 exportUTF16String(rStrm, name); // ModuleNameUnicode
661}
662
663// section 2.3.4.2.3.2.3
664void writeMODULESTREAMNAME(SvStream& rStrm, const OUString& streamName,
665 const rtl_TextEncoding eTextEncoding)
666{
667 rStrm.WriteUInt16(0x001A); // id
668 sal_Int32 n = streamName.getLength(); // sizeOfStreamName
670 exportString(rStrm, streamName, eTextEncoding); // StreamName
671 rStrm.WriteUInt16(0x0032); // reserved
672 rStrm.WriteUInt32(n * 2); // sizeOfStreamNameUnicode // TODO: better calculation for unicode string length
673 exportUTF16String(rStrm, streamName); // StreamNameUnicode
674}
675
676// section 2.3.4.2.3.2.4
677void writeMODULEDOCSTRING(SvStream& rStrm)
678{
679 rStrm.WriteUInt16(0x001C); // id
680 rStrm.WriteUInt32(0x00000000); // sizeOfDocString
681 rStrm.WriteUInt16(0x0048); // reserved
682 rStrm.WriteUInt32(0x00000000); // sizeOfDocStringUnicode
683}
684
685// section 2.3.4.2.3.2.5
686void writeMODULEOFFSET(SvStream& rStrm)
687{
688 rStrm.WriteUInt16(0x0031); // id
689 rStrm.WriteUInt32(0x00000004); // sizeOfTextOffset
690 rStrm.WriteUInt32(0x00000000); // TextOffset
691}
692
693// section 2.3.4.2.3.2.6
694void writeMODULEHELPCONTEXT(SvStream& rStrm)
695{
696 rStrm.WriteUInt16(0x001E); // id
697 rStrm.WriteUInt32(0x00000004); // sizeOfHelpContext
698 rStrm.WriteUInt32(0x00000000); // HelpContext
699}
700
701// section 2.3.4.2.3.2.7
702void writeMODULECOOKIE(SvStream& rStrm)
703{
704 rStrm.WriteUInt16(0x002C); // id
705 rStrm.WriteUInt32(0x00000002); // sizeOfHelpContext
706 rStrm.WriteUInt16(0xFFFF); // HelpContext
707}
708
709// section 2.3.4.2.3.2.8
710void writeMODULETYPE(SvStream& rStrm, const sal_uInt16 type)
711{
712 if(type == 1)
713 rStrm.WriteUInt16(0x0021); // id for a procedural module
714 else
715 rStrm.WriteUInt16(0x0022); // id for document, class or design module
716 rStrm.WriteUInt32(0x00000000); // reserved
717}
718
719// section 2.3.4.2.3.2
720void writePROJECTMODULE(SvStream& rStrm, const OUString& name, const sal_uInt16 type,
721 const rtl_TextEncoding eTextEncoding)
722{
723 writeMODULENAME(rStrm, name, eTextEncoding);
724 writeMODULENAMEUNICODE(rStrm, name);
725 writeMODULESTREAMNAME(rStrm, name, eTextEncoding);
726 writeMODULEDOCSTRING(rStrm);
727 writeMODULEOFFSET(rStrm);
728 writeMODULEHELPCONTEXT(rStrm);
729 writeMODULECOOKIE(rStrm);
730 writeMODULETYPE(rStrm, type);
731 rStrm.WriteUInt16(0x002B); // terminator
732 rStrm.WriteUInt32(0x00000000); // reserved
733}
734
735// section 2.3.4.2.3
736void writePROJECTMODULES(SvStream& rStrm,
737 const css::uno::Reference<css::container::XNameContainer>& xNameContainer,
738 const std::vector<sal_Int32>& rLibraryMap,
739 const rtl_TextEncoding eTextEncoding)
740{
741 const css::uno::Sequence<OUString> aElementNames = xNameContainer->getElementNames();
742 sal_Int32 n = aElementNames.getLength();
743 css::uno::Reference<css::script::vba::XVBAModuleInfo> xModuleInfo(xNameContainer, css::uno::UNO_QUERY);
744 assert(xModuleInfo.is());
745
746 // TODO: this whole part is document specific
747 rStrm.WriteUInt16(0x000F); // id
748 rStrm.WriteUInt32(0x00000002); // size of Count
749 sal_Int16 count = n; // Number of modules // TODO: this is dependent on the document
750 rStrm.WriteUInt16(count); // Count
751 writePROJECTCOOKIE(rStrm);
752
753 for (sal_Int32 i = 0; i < n; ++i)
754 {
755 const OUString& rModuleName = aElementNames[rLibraryMap[i]];
756 css::script::ModuleInfo aModuleInfo = xModuleInfo->getModuleInfo(rModuleName);
757 writePROJECTMODULE(rStrm, rModuleName, aModuleInfo.ModuleType, eTextEncoding);
758 }
759}
760
761// section 2.3.4.2
762void exportDirStream(SvStream& rStrm,
763 const css::uno::Reference<css::container::XNameContainer>& xNameContainer,
764 const std::vector<sal_Int32>& rLibraryMap, const OUString& projectName,
765 const rtl_TextEncoding eTextEncoding)
766{
767 SvMemoryStream aDirStream(4096, 4096);
768
769 writePROJECTINFORMATION(aDirStream, projectName, eTextEncoding);
770 writePROJECTREFERENCES(aDirStream, eTextEncoding);
771 writePROJECTMODULES(aDirStream, xNameContainer, rLibraryMap, eTextEncoding);
772 aDirStream.WriteUInt16(0x0010); // terminator
773 aDirStream.WriteUInt32(0x00000000); // reserved
774
775#if VBA_EXPORT_DEBUG
776 static const OUStringLiteral aDirFileName(u"/tmp/vba_dir_out.bin");
777 SvFileStream aDirStreamDebug(aDirFileName, StreamMode::READWRITE);
778 aDirStream.Seek(0);
779 aDirStreamDebug.WriteStream(aDirStream);
780#endif
781
782 VBACompression aCompression(rStrm, aDirStream);
783 aCompression.write();
784}
785
786// section 2.3.4.3 Module Stream
787void exportModuleStream(SvStream& rStrm, const OUString& rSourceCode, const OUString& aElementName,
788 css::script::ModuleInfo const& rInfo, const rtl_TextEncoding eTextEncoding)
789{
790 SvMemoryStream aModuleStream(4096, 4096);
791
792 exportString(aModuleStream, OUStringConcatenation("Attribute VB_Name = \"" + aElementName + "\"\r\n"), eTextEncoding);
793 if (rInfo.ModuleType == 4)
794 {
795 if (isWorkbook(rInfo.ModuleObject))
796 exportString(aModuleStream, u"Attribute VB_Base = \"0{00020819-0000-0000-C000-000000000046}\"\r\n", eTextEncoding);
797 else
798 exportString(aModuleStream, u"Attribute VB_Base = \"0{00020820-0000-0000-C000-000000000046}\"\r\n", eTextEncoding);
799
800 exportString(aModuleStream, u"Attribute VB_GlobalNameSpace = False\r\n", eTextEncoding);
801 exportString(aModuleStream, u"Attribute VB_Creatable = False\r\n", eTextEncoding);
802 exportString(aModuleStream, u"Attribute VB_PredeclaredId = True\r\n", eTextEncoding);
803 exportString(aModuleStream, u"Attribute VB_Exposed = True\r\n", eTextEncoding);
804 exportString(aModuleStream, u"Attribute VB_TemplateDerived = False\r\n", eTextEncoding);
805 exportString(aModuleStream, u"Attribute VB_Customizable = True\r\n", eTextEncoding);
806 }
807 OUString aSourceCode = rSourceCode.replaceFirst("Option VBASupport 1\n", "");
808 const sal_Int32 nPos = aSourceCode.indexOf("Rem Attribute VBA_ModuleType=");
809 const sal_Int32 nEndPos = nPos != -1 ? aSourceCode.indexOf("\n", nPos) : -1;
810 if (nPos != -1 && nEndPos != -1)
811 aSourceCode = aSourceCode.replaceAt(nPos, nEndPos - nPos+1, u"");
812 aSourceCode = aSourceCode.replaceAll("\n", "\r\n");
813 exportString(aModuleStream, aSourceCode, eTextEncoding);
814
815#if VBA_EXPORT_DEBUG
816 OUString aModuleFileName("/tmp/vba_" + aElementName + "_out.bin");
817 SvFileStream aModuleStreamDebug(aModuleFileName, StreamMode::READWRITE);
818 aModuleStream.Seek(0);
819 aModuleStreamDebug.WriteStream(aModuleStream);
820#endif
821
822 VBACompression aCompression(rStrm, aModuleStream);
823 aCompression.write();
824}
825
826// section 2.3.4.1 _VBA_PROJECT Stream
827void exportVBAProjectStream(SvStream& rStrm)
828{
829 rStrm.WriteUInt16(0x61CC); // Reserved1
830 rStrm.WriteUInt16(0xFFFF); // Version
831 rStrm.WriteUInt8(0x00); // Reserved2
832 rStrm.WriteUInt16(0x0000); // Undefined
833}
834
835// section 2.3.1 PROJECT Stream
836void exportPROJECTStream(SvStream& rStrm,
837 const css::uno::Reference<css::container::XNameContainer>& xNameContainer,
838 const OUString& projectName, const std::vector<sal_Int32>& rLibraryMap,
839 const rtl_TextEncoding eTextEncoding)
840{
841 const css::uno::Sequence<OUString> aElementNames = xNameContainer->getElementNames();
842 sal_Int32 n = aElementNames.getLength();
843 css::uno::Reference<css::script::vba::XVBAModuleInfo> xModuleInfo(xNameContainer, css::uno::UNO_QUERY);
844 assert(xModuleInfo.is());
845
846 // section 2.3.1.1ProjectProperties
847
848 // section 2.3.1.2 ProjectId
849 exportString(rStrm, u"ID=\"", eTextEncoding);
850 OUString aProjectID
851 = OStringToOUString(comphelper::xml::generateGUIDString(), RTL_TEXTENCODING_UTF8);
852 exportString(rStrm, aProjectID, eTextEncoding);
853 exportString(rStrm, u"\"\r\n", eTextEncoding);
854
855 // section 2.3.1.3 ProjectModule
856 for (sal_Int32 i = 0; i < n; ++i)
857 {
858 const OUString& rModuleName = aElementNames[rLibraryMap[i]];
859 css::script::ModuleInfo aModuleInfo = xModuleInfo->getModuleInfo(rModuleName);
860 if(aModuleInfo.ModuleType == 1)
861 {
862 exportString(rStrm, OUStringConcatenation("Module=" + rModuleName + "\r\n"),
863 eTextEncoding);
864 }
865 else if(aModuleInfo.ModuleType == 4)
866 {
867 exportString(rStrm,
868 OUStringConcatenation("Document=" + rModuleName + "/&H00000000\r\n"),
869 eTextEncoding);
870 }
871 }
872
873 // section 2.3.1.11 ProjectName
874 exportString(rStrm, OUStringConcatenation("Name=\"" + projectName + "\"\r\n"), eTextEncoding);
875
876 // section 2.3.1.12 ProjectHelpId
877 exportString(rStrm, u"HelpContextID=\"0\"\r\n", eTextEncoding);
878
879 // section 2.3.1.14 ProjectVersionCompat32
880 exportString(rStrm, u"VersionCompatible32=\"393222000\"\r\n", eTextEncoding);
881
882 // section 2.3.1.15 ProjectProtectionState
883#if VBA_ENCRYPTION
884 exportString(rStrm, u"CMG=\"", eTextEncoding);
885 SvMemoryStream aProtectedStream(4096, 4096);
886 aProtectedStream.WriteUInt32(0x00000000);
887 const sal_uInt8* pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
888 sal_uInt8 nProjKey = VBAEncryption::calculateProjKey(aProjectID);
889 VBAEncryption aProtectionState(pData, 4, rStrm, nProjKey, eTextEncoding);
890 aProtectionState.write();
891 exportString(rStrm, u"\"\r\n", eTextEncoding);
892#else
893 exportString(rStrm, "CMG=\"BEBC9256EEAAA8AEA8AEA8AEA8AE\"\r\n", eTextEncoding);
894#endif
895
896 // section 2.3.1.16 ProjectPassword
897#if VBA_ENCRYPTION
898 exportString(rStrm, u"DPB=\"", eTextEncoding);
899 aProtectedStream.Seek(0);
900 aProtectedStream.WriteUInt8(0x00);
901 pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
902 VBAEncryption aProjectPassword(pData, 1, rStrm, nProjKey, eTextEncoding);
903 aProjectPassword.write();
904 exportString(rStrm, u"\"\r\n", eTextEncoding);
905#else
906 exportString(rStrm, "DPB=\"7C7E5014B0D3B1D3B1D3\"\r\n", eTextEncoding);
907#endif
908
909 // section 2.3.1.17 ProjectVisibilityState
910#if VBA_ENCRYPTION
911 exportString(rStrm, u"GC=\"", eTextEncoding);
912 aProtectedStream.Seek(0);
913 aProtectedStream.WriteUInt8(0xFF);
914 pData = static_cast<const sal_uInt8*>(aProtectedStream.GetData());
915 VBAEncryption aVisibilityState(pData, 1, rStrm, nProjKey, eTextEncoding);
916 aVisibilityState.write();
917 exportString(rStrm, u"\"\r\n\r\n", eTextEncoding);
918#else
919 exportString(rStrm, "GC=\"3A3816DAD5DBD5DB2A\"\r\n\r\n", eTextEncoding);
920#endif
921
922 // section 2.3.1.18 HostExtenders
923 exportString(rStrm,
924 u"[Host Extender Info]\r\n"
925 "&H00000001={3832D640-CF90-11CF-8E43-00A0C911005A};VBE;&H00000000\r\n\r\n",
926 eTextEncoding);
927
928 // section 2.3.1.19 ProjectWorkspace
929 exportString(rStrm, u"[Workspace]\r\n", eTextEncoding);
930 for (sal_Int32 i = 0; i < n; ++i)
931 {
932 const OUString& rModuleName = aElementNames[rLibraryMap[i]];
933 css::script::ModuleInfo aModuleInfo = xModuleInfo->getModuleInfo(rModuleName);
934 if(aModuleInfo.ModuleType == 1)
935 {
936 exportString(rStrm, OUStringConcatenation(rModuleName + "=25, 25, 1439, 639, \r\n"),
937 eTextEncoding);
938 }
939 else
940 {
941 exportString(rStrm, OUStringConcatenation(rModuleName + "=0, 0, 0, 0, C\r\n"),
942 eTextEncoding);
943 }
944 }
945}
946
947// section 2.3.3.1 NAMEMAP
948void writeNAMEMAP(SvStream& rStrm, const css::uno::Sequence<OUString>& rElementNames,
949 const std::vector<sal_Int32>& rLibraryMap, const rtl_TextEncoding eTextEncoding)
950{
951 int n = rElementNames.getLength();
952 for(sal_Int32 i = 0; i < n; ++i)
953 {
954 const OUString& rModuleName = rElementNames[rLibraryMap[i]];
955 exportString(rStrm, rModuleName, eTextEncoding);
956 rStrm.WriteUInt8(0x00); // terminator
957 exportUTF16String(rStrm, rModuleName);
958 rStrm.WriteUInt16(0x0000); // terminator
959 }
960}
961
962// section 2.3.3 PROJECTwm Stream
963void exportPROJECTwmStream(SvStream& rStrm, const css::uno::Sequence<OUString>& rElementNames,
964 const std::vector<sal_Int32>& rLibraryMap, const rtl_TextEncoding eTextEncoding)
965{
966 writeNAMEMAP(rStrm, rElementNames, rLibraryMap, eTextEncoding);
967 rStrm.WriteUInt16(0x0000); // terminator
968}
969
970void getCorrectExportOrder(const css::uno::Reference<css::container::XNameContainer>& xNameContainer, std::vector<sal_Int32>& rLibraryMap)
971{
972 const css::uno::Sequence<OUString> aElementNames = xNameContainer->getElementNames();
973 sal_Int32 n = aElementNames.getLength();
974 css::uno::Reference<css::script::vba::XVBAModuleInfo> xModuleInfo(xNameContainer, css::uno::UNO_QUERY);
975
976 sal_Int32 nCurrentId = 0;
977 // first all the non-document modules
978 for (sal_Int32 i = 0; i < n; ++i)
979 {
980 css::script::ModuleInfo aModuleInfo = xModuleInfo->getModuleInfo(aElementNames[i]);
981 if (aModuleInfo.ModuleType != 4)
982 {
983 rLibraryMap[nCurrentId] = i;
984 ++nCurrentId;
985 }
986 }
987
988 sal_Int32 nWorkbookIndex = -1;
989 // then possibly the workbook module
990 for (sal_Int32 i = 0; i < n; ++i)
991 {
992 css::script::ModuleInfo aModuleInfo = xModuleInfo->getModuleInfo(aElementNames[i]);
993 bool bWorkbook = isWorkbook(aModuleInfo.ModuleObject);
994 if (bWorkbook)
995 {
996 nWorkbookIndex = i;
997 rLibraryMap[nCurrentId] = i;
998 ++nCurrentId;
999 }
1000 }
1001
1002 // then the remaining modules
1003 for (sal_Int32 i = 0; i < n; ++i)
1004 {
1005 if (i == nWorkbookIndex)
1006 continue;
1007
1008 css::script::ModuleInfo aModuleInfo = xModuleInfo->getModuleInfo(aElementNames[i]);
1009 if (aModuleInfo.ModuleType == 4)
1010 {
1011 rLibraryMap[nCurrentId] = i;
1012 ++nCurrentId;
1013 }
1014 }
1015}
1016
1017}
1018
1019#if VBA_USE_ORIGINAL_WM_STREAM || VBA_USE_ORIGINAL_DIR_STREAM \
1020 || VBA_USE_ORIGINAL_PROJECT_STREAM || VBA_USE_ORIGINAL_VBA_PROJECT \
1021 || VBA_USE_ORIGINAL_DIR_STREAM
1022void addFileStreamToSotStream(const OUString& rPath, SotStorageStream& rStream)
1023{
1024 SvFileStream aFileStream(rPath, StreamMode::READWRITE);
1025 rStream.WriteStream(aFileStream);
1026}
1027#endif
1028
1030{
1031 css::uno::Reference<css::container::XNameContainer> xNameContainer = getBasicLibrary();
1032 if (!xNameContainer.is()) {
1033 return;
1034 }
1035 const css::uno::Sequence<OUString> aElementNames = xNameContainer->getElementNames();
1036 sal_Int32 n = aElementNames.getLength(); // get the number of modules
1037 // export the elements in the order MSO expects them
1038 // we store the index of the
1039 std::vector<sal_Int32> aLibraryMap(n, 0);
1040 getCorrectExportOrder(xNameContainer, aLibraryMap);
1041
1042 // start here with the VBA export
1043 tools::SvRef<SotStorage> xVBAStream = pRootStorage->OpenSotStorage("VBA", StreamMode::READWRITE);
1044 tools::SvRef<SotStorageStream> pDirStream = xVBAStream->OpenSotStream("dir", StreamMode::READWRITE);
1045
1046 tools::SvRef<SotStorageStream> pVBAProjectStream = xVBAStream->OpenSotStream("_VBA_PROJECT", StreamMode::READWRITE);
1047 tools::SvRef<SotStorageStream> pPROJECTStream = pRootStorage->OpenSotStream("PROJECT", StreamMode::READWRITE);
1048 tools::SvRef<SotStorageStream> pPROJECTwmStream = pRootStorage->OpenSotStream("PROJECTwm", StreamMode::READWRITE);
1049
1050 const rtl_TextEncoding eTextEncoding = getVBATextEncoding();
1051
1052#if VBA_USE_ORIGINAL_WM_STREAM
1053 OUString aProjectwmPath = "/home/moggi/Documents/testfiles/vba/PROJECTwm";
1054 addFileStreamToSotStream(aProjectwmPath, *pPROJECTwmStream);
1055#else
1056 exportPROJECTwmStream(*pPROJECTwmStream, aElementNames, aLibraryMap, eTextEncoding);
1057#endif
1058
1059#if VBA_USE_ORIGINAL_DIR_STREAM
1060 OUString aDirPath = "/home/moggi/Documents/testfiles/vba/VBA/dir";
1061 addFileStreamToSotStream(aDirPath, *pDirStream);
1062#else
1063 exportDirStream(*pDirStream, xNameContainer, aLibraryMap, getProjectName(), eTextEncoding);
1064#endif
1065
1066#if VBA_USE_ORIGINAL_PROJECT_STREAM
1067 OUString aProjectPath = "/home/moggi/Documents/testfiles/vba/PROJECT";
1068 addFileStreamToSotStream(aProjectPath, *pPROJECTStream);
1069#else
1070 exportPROJECTStream(*pPROJECTStream, xNameContainer, getProjectName(), aLibraryMap,
1071 eTextEncoding);
1072#endif
1073
1074#if VBA_USE_ORIGINAL_VBA_PROJECT
1075 OUString a_VBA_ProjectPath = "/home/moggi/Documents/testfiles/vba/VBA/_VBA_PROJECT";
1076 addFileStreamToSotStream(a_VBA_ProjectPath, *pVBAProjectStream);
1077#else
1078 exportVBAProjectStream(*pVBAProjectStream);
1079#endif
1080
1081#if VBA_USE_ORIGINAL_DIR_STREAM
1082 OUString aModule1Path = "/home/moggi/Documents/testfiles/vba/VBA/Module1";
1083 OUString aSheet1Path = "/home/moggi/Documents/testfiles/vba/VBA/Sheet1";
1084 OUString aSheet2Path = "/home/moggi/Documents/testfiles/vba/VBA/Sheet2";
1085 OUString aSheet3Path = "/home/moggi/Documents/testfiles/vba/VBA/Sheet3";
1086 OUString aWorkbookPath = "/home/moggi/Documents/testfiles/vba/VBA/ThisWorkbook";
1087 tools::SvRef<SotStorageStream> pModule1Stream = xVBAStream->OpenSotStream("Module1", StreamMode::READWRITE);
1088 tools::SvRef<SotStorageStream> pSheet1Stream = xVBAStream->OpenSotStream("Sheet1", StreamMode::READWRITE);
1089 tools::SvRef<SotStorageStream> pSheet2Stream = xVBAStream->OpenSotStream("Sheet2", StreamMode::READWRITE);
1090 tools::SvRef<SotStorageStream> pSheet3Stream = xVBAStream->OpenSotStream("Sheet3", StreamMode::READWRITE);
1091 tools::SvRef<SotStorageStream> pWorkbookStream = xVBAStream->OpenSotStream("ThisWorkbook", StreamMode::READWRITE);
1092 addFileStreamToSotStream(aModule1Path, *pModule1Stream);
1093 addFileStreamToSotStream(aSheet1Path, *pSheet1Stream);
1094 addFileStreamToSotStream(aSheet2Path, *pSheet2Stream);
1095 addFileStreamToSotStream(aSheet3Path, *pSheet3Stream);
1096 addFileStreamToSotStream(aWorkbookPath, *pWorkbookStream);
1097
1098 pModule1Stream->Commit();
1099 pSheet1Stream->Commit();
1100 pSheet2Stream->Commit();
1101 pSheet3Stream->Commit();
1102 pWorkbookStream->Commit();
1103#else
1104
1105 css::uno::Reference<css::script::vba::XVBAModuleInfo> xModuleInfo(xNameContainer, css::uno::UNO_QUERY);
1106 for (sal_Int32 i = 0; i < n; ++i)
1107 {
1108 const OUString& rModuleName = aElementNames[aLibraryMap[i]];
1109 tools::SvRef<SotStorageStream> pModuleStream = xVBAStream->OpenSotStream(rModuleName, StreamMode::READWRITE);
1110 css::uno::Any aCode = xNameContainer->getByName(rModuleName);
1111 css::script::ModuleInfo aModuleInfo = xModuleInfo->getModuleInfo(rModuleName);
1112 OUString aSourceCode;
1113 aCode >>= aSourceCode;
1114 exportModuleStream(*pModuleStream, aSourceCode, rModuleName, aModuleInfo, eTextEncoding);
1115 pModuleStream->Commit();
1116 }
1117
1118#endif
1119
1120 pVBAProjectStream->Commit();
1121
1122 pDirStream->Commit();
1123 xVBAStream->Commit();
1124 pPROJECTStream->Commit();
1125 pPROJECTwmStream->Commit();
1126 pRootStorage->Commit();
1127}
1128
1129css::uno::Reference<css::script::XLibraryContainer> VbaExport::getLibraryContainer() const
1130{
1131 oox::PropertySet aDocProp(mxModel);
1132 css::uno::Reference<css::script::XLibraryContainer> xLibContainer(aDocProp.getAnyProperty(oox::PROP_BasicLibraries), css::uno::UNO_QUERY);
1133
1134 return xLibContainer;
1135}
1136
1137css::uno::Reference<css::container::XNameContainer> VbaExport::getBasicLibrary() const
1138{
1139 css::uno::Reference<css::container::XNameContainer> xLibrary;
1140 try
1141 {
1142 css::uno::Reference<css::script::XLibraryContainer> xLibContainer = getLibraryContainer();
1143 OUString aProjectName = getProjectName();
1144 xLibrary.set( xLibContainer->getByName(aProjectName), css::uno::UNO_QUERY_THROW );
1145 }
1146 catch(...)
1147 {
1148 }
1149
1150 return xLibrary;
1151}
1152
1154{
1155 css::uno::Reference<css::script::XLibraryContainer> xLibContainer = getLibraryContainer();
1156 if (!xLibContainer.is())
1157 return false;
1158
1159 css::uno::Reference<css::script::vba::XVBACompatibility> xVbaCompatibility (xLibContainer, css::uno::UNO_QUERY);
1160 if (!xVbaCompatibility.is())
1161 return false;
1162
1163 bool bVBACompatibility = xVbaCompatibility->getVBACompatibilityMode();
1164
1165 return bVBACompatibility;
1166}
1167
1169{
1170 css::uno::Reference<css::script::vba::XVBACompatibility> xVbaCompatibility(getLibraryContainer(), css::uno::UNO_QUERY);
1171 if (xVbaCompatibility.is())
1172 return xVbaCompatibility->getProjectName();
1173
1174 return OUString();
1175}
1176
1177rtl_TextEncoding VbaExport::getVBATextEncoding() const
1178{
1179 rtl_TextEncoding aTextEncoding = osl_getThreadTextEncoding();
1180 css::uno::Reference<css::beans::XPropertySet> xProps(getLibraryContainer(),
1181 css::uno::UNO_QUERY);
1182 if (xProps.is())
1183 try
1184 {
1185 xProps->getPropertyValue("VBATextEncoding") >>= aTextEncoding;
1186 }
1187 catch (const css::uno::Exception&)
1188 {
1189 }
1190
1191 return aTextEncoding;
1192}
1193
1194/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
css::uno::Reference< css::frame::XModel2 > mxModel
tools::SvRef< SotStorageStream > OpenSotStream(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE)
bool Commit()
SotStorage * OpenSotStorage(const OUString &rEleName, StreamMode=StreamMode::STD_READWRITE, bool transacted=true)
const void * GetData()
std::size_t GetEndOfData() const
sal_uInt64 Tell() const
SvStream & WriteUnicode(sal_Unicode)
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteUInt16(sal_uInt16 nUInt16)
SvStream & WriteOString(std::string_view rStr)
SvStream & WriteUInt32(sal_uInt32 nUInt32)
SvStream & WriteUInt8(sal_uInt8 nuInt8)
sal_uInt64 Seek(sal_uInt64 nPos)
void compressToken(size_t index, sal_uInt8 &nFlagByte)
Definition: vbaexport.cxx:195
sal_uInt64 mnDecompressedEnd
Definition: vbaexport.hxx:79
VBACompressionChunk(SvStream &rCompressedStream, const sal_uInt8 *pData, std::size_t nChunkSize)
Definition: vbaexport.cxx:85
void CopyTokenHelp(sal_uInt16 &rLengthMask, sal_uInt16 &rOffsetMask, sal_uInt16 &rBitCount, sal_uInt16 &rMaximumLength)
Definition: vbaexport.cxx:295
static void PackCompressedChunkSignature(sal_uInt16 &rHeader)
Definition: vbaexport.cxx:171
sal_uInt16 CopyToken(size_t nLength, size_t nOffset)
Definition: vbaexport.cxx:239
const sal_uInt8 * mpUncompressedData
Definition: vbaexport.hxx:63
void match(size_t &rLength, size_t &rOffset)
Definition: vbaexport.cxx:254
SvStream & mrCompressedStream
Definition: vbaexport.hxx:62
std::size_t mnChunkSize
Definition: vbaexport.hxx:67
static void SetFlagBit(size_t index, bool bVal, sal_uInt8 &rFlag)
Definition: vbaexport.cxx:231
sal_uInt64 mnCompressedEnd
Definition: vbaexport.hxx:73
sal_uInt16 handleHeader(bool bCompressed)
Definition: vbaexport.cxx:103
sal_uInt64 mnCompressedCurrent
Definition: vbaexport.hxx:70
sal_uInt8 * mpCompressedChunkStream
Definition: vbaexport.hxx:64
static void PackCompressedChunkFlag(bool bCompressed, sal_uInt16 &rHeader)
Definition: vbaexport.cxx:163
static void PackCompressedChunkSize(size_t nSize, sal_uInt16 &rHeader)
Definition: vbaexport.cxx:155
void compressTokenSequence()
Definition: vbaexport.cxx:178
sal_uInt64 mnDecompressedCurrent
Definition: vbaexport.hxx:76
SvStream & mrCompressedStream
Definition: vbaexport.hxx:114
SvMemoryStream & mrUncompressedStream
Definition: vbaexport.hxx:115
VBACompression(SvStream &rCompressedStream, SvMemoryStream &rUncompressedStream)
Definition: vbaexport.cxx:337
void writeProjKeyEnc()
Definition: vbaexport.cxx:415
SvStream & mrEncryptedData
Definition: vbaexport.hxx:134
sal_uInt8 mnEncryptedByte2
Definition: vbaexport.hxx:137
void writeDataLengthEnc()
Definition: vbaexport.cxx:438
sal_uInt8 mnEncryptedByte1
Definition: vbaexport.hxx:136
sal_uInt8 mnIgnoredLength
Definition: vbaexport.hxx:139
const sal_uInt16 mnLength
Definition: vbaexport.hxx:133
sal_Unicode mnProjKey
Definition: vbaexport.hxx:138
const sal_uInt8 * mpData
Definition: vbaexport.hxx:132
sal_uInt8 mnSeed
Definition: vbaexport.hxx:141
void writeDataEnc()
Definition: vbaexport.cxx:453
void writeVersionEnc()
Definition: vbaexport.cxx:394
VBAEncryption(const sal_uInt8 *pData, const sal_uInt16 nLength, SvStream &rEncryptedData, sal_uInt8 nProjKey, rtl_TextEncoding eTextEncoding)
Definition: vbaexport.cxx:368
static sal_uInt8 calculateProjKey(const OUString &rString)
Definition: vbaexport.cxx:401
void writeSeed()
Definition: vbaexport.cxx:389
rtl_TextEncoding meTextEncoding
Definition: vbaexport.hxx:143
void writeIgnoredEnc()
Definition: vbaexport.cxx:424
sal_uInt8 mnVersionEnc
Definition: vbaexport.hxx:142
sal_uInt8 mnUnencryptedByte1
Definition: vbaexport.hxx:135
css::uno::Reference< css::script::XLibraryContainer > getLibraryContainer() const
Definition: vbaexport.cxx:1129
rtl_TextEncoding getVBATextEncoding() const
Definition: vbaexport.cxx:1177
bool containsVBAProject()
Definition: vbaexport.cxx:1153
css::uno::Reference< css::container::XNameContainer > getBasicLibrary() const
Definition: vbaexport.cxx:1137
void exportVBA(SotStorage *pRootStorage)
Definition: vbaexport.cxx:1029
VbaExport(css::uno::Reference< css::frame::XModel > xModel)
Definition: vbaexport.cxx:477
OUString getProjectName() const
Definition: vbaexport.cxx:1168
css::uno::Reference< css::frame::XModel > mxModel
Definition: vbaexport.hxx:50
A wrapper for a UNO property set.
Definition: propertyset.hxx:58
css::uno::Any getAnyProperty(sal_Int32 nPropId) const
Gets the specified property from the property set.
Definition: propertyset.cxx:62
const char * name
short nBitCount
sal_Int64 n
sal_uInt16 nPos
std::unique_ptr< sal_Int32[]> pData
@ character
size
OString generateGUIDString()
index
void SvStream & rStrm
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
DefTokenId nToken
Reference< XModel > xModel
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
signed char sal_Int8
static void setUInt16(sal_uInt8 *pBuffer, size_t nPos, sal_uInt16 nVal)
Definition: vbaexport.cxx:97
sal_Int32 nLength