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