1 //  ----------------------------------------------------------------------------
2 //  MODULE    : OLECore.cpp
3 //  LANGUAGE  : C++
4 //  AUTHOR    : Yue Zhang
5 //  DATE    : Tuesday, Janurary 23, 1996
6 //  DESCRIPTION : This file defines an object which is common to all enhanced
7 //          OLE objects
8 //  COMMENT   : Enhanced OLE objects which are platform independent
9 //    SCCSID            : @(#)olecore.cpp 1.5 10:45:11 12 Sep 1997
10 //  ----------------------------------------------------------------------------
11 //  Copyright (c) 1999 Digital Imaging Group, Inc.
12 //  For conditions of distribution and use, see copyright notice
13 //  in Flashpix.h
14 
15 
16 //  Includes
17 //  --------
18 #ifndef Debug_h
19   #include "debug.h"
20 #endif
21 
22 #if defined(_WINDOWS)
23   #include "b_error.h"
24 #endif
25 #ifndef OLECommun_h
26   #include "olecomm.h"
27 #endif
28 #ifndef OLECore_h
29   #include "olecore.h"
30 #endif
31 #ifndef OLEProperties_h
32   #include "oleprop.h"
33 #endif
34 
35 //  Constants
36 //  ---------
37 // These strings are used to print the types of the properties in the test code
38 
39 static const char* variantName[] =
40 {
41 	"VT_EMPTY",     // 0
42 	"VT_NULL",
43 	"VT_I2",
44 	"VT_I4",
45 	"VT_R4",
46 	"VT_R8",      // 5
47 	"VT_CY",
48 	"VT_DATE",
49 	"VT_BSTR",
50 	"VT_DISPATCH",
51 	"VT_ERROR",     // 10
52 	"VT_BOOL",
53 	"VT_VARIANT",
54 	"VT_UNKNOWN",
55 	"?",
56 	"?",        // 15
57 	"VT_I1",
58 	"VT_UI1",
59 	"VT_UI2",
60 	"VT_UI4",
61 	"VT_I8",      // 20
62 	"VT_UI8",
63 	"VT_INT",
64 	"VT_UINT",
65 	"VT_VOID",
66 	"VT_HRESULT",   // 25
67 	"VT_PTR",
68 	"VT_SAFEARRAY",
69 	"VT_CARRAY",
70 	"VT_USERDEFINED",
71 	"VT_LPSTR",     // 30
72 	"VT_LPWSTR",
73 	"?",
74 	"?",
75 	"?",
76 	"?",        // 35
77 	"?",
78 	"?",
79 	"?",
80 	"?",
81 	"?",        // 40
82 	"?",
83 	"?",
84 	"?",
85 	"?",
86 	"?",        // 45
87 	"?",
88 	"?",
89 	"?",
90 	"?",
91 	"?",        // 50
92 	"?",
93 	"?",
94 	"?",
95 	"?",
96 	"?",        // 55
97 	"?",
98 	"?",
99 	"?",
100 	"?",
101 	"?",        // 60
102 	"?",
103 	"?",
104 	"?",
105 	"VT_FILETIME",    // 64
106 	"VT_BLOB",
107 	"VT_STREAM",
108 	"VT_STORAGE",
109 	"VT_STREAMED_OBJECT",
110 	"VT_STORED_OBJECT",
111 	"VT_BLOB_OBJECT", // 70
112 	"VT_CF",
113 	"VT_CLSID",
114 	"VT_VECTOR",
115 	"VT_ARRAY"
116 };
117 
118 //  ----------------------------------------------------------------------------
119 
120 //  Global variables
121 //  ----------------
122 
123   List * openRootStorageList = NULL;
124 
125 //  ----------------------------------------------------------------------------
126 
127 //  ----------------------------------------------------------------------------
128 //  Methods of OLECore
129 //  ----------------------------------------------------------------------------
130 
OLECore()131 OLECore::OLECore( )
132 {
133   lastError = noErr;
134   fpxStatus = FPX_OK;
135   userCount  = 1;
136 }
137 
~OLECore()138 OLECore::~OLECore( )
139 {
140 
141 }
142 
AddRef()143 void OLECore::AddRef()
144 {
145   userCount++;
146 }
147 
Release()148 void OLECore::Release()
149 {
150   userCount--;
151 }
152 
OLEtoFPXError(HRESULT err)153 FPXStatus OLECore::OLEtoFPXError(HRESULT err)
154 {
155   FPXStatus terr;
156   SCODE sCode = GetScode(err);
157 
158   switch (sCode) {
159     case S_OK:  terr = FPX_OK;
160           break;
161     case STG_E_INVALIDFUNCTION:
162           terr = FPX_OLE_FILE_ERROR;
163           break;
164     case STG_E_FILENOTFOUND:
165           terr = FPX_FILE_NOT_FOUND;
166           break;
167     case STG_E_PATHNOTFOUND:
168           terr = FPX_FILE_NOT_FOUND;
169           break;
170     case STG_E_TOOMANYOPENFILES:
171           terr = FPX_FILE_SYSTEM_FULL;
172           break;
173     case STG_E_ACCESSDENIED:
174           terr = FPX_FILE_WRITE_ERROR;
175           break;
176     case STG_E_INVALIDHANDLE:
177           terr = FPX_OLE_FILE_ERROR;
178           break;
179     case STG_E_INSUFFICIENTMEMORY:
180           terr = FPX_MEMORY_ALLOCATION_FAILED;
181           break;
182     case STG_E_INVALIDPOINTER:
183           terr = FPX_OLE_FILE_ERROR;
184           break;
185     case STG_E_NOMOREFILES:
186           terr = FPX_FILE_SYSTEM_FULL;
187           break;
188     case STG_E_DISKISWRITEPROTECTED:
189           terr = FPX_ERROR;
190           break;
191     case STG_E_SEEKERROR:
192           terr = FPX_OLE_FILE_ERROR;
193           break;
194     case STG_E_WRITEFAULT:
195           terr = FPX_FILE_WRITE_ERROR;
196           break;
197     case STG_E_READFAULT:
198           terr = FPX_FILE_READ_ERROR;
199           break;
200     case STG_E_SHAREVIOLATION:
201           terr = FPX_FILE_IN_USE;
202           break;
203     case STG_E_LOCKVIOLATION:
204           terr = FPX_FILE_IN_USE;
205           break;
206     case STG_E_FILEALREADYEXISTS:
207           terr = FPX_INVALID_FORMAT_ERROR;
208           break;
209     case STG_E_INVALIDPARAMETER:
210           terr = FPX_OLE_FILE_ERROR;
211           break;
212     case STG_E_MEDIUMFULL:
213           terr = FPX_FILE_SYSTEM_FULL;
214           break;
215     case STG_E_ABNORMALAPIEXIT:
216           terr = FPX_OLE_FILE_ERROR;
217           break;
218     case STG_E_INVALIDHEADER:
219           terr = FPX_INVALID_FORMAT_ERROR;
220           break;
221     case STG_E_INVALIDNAME:
222           terr = FPX_INVALID_FORMAT_ERROR;
223           break;
224     case STG_E_UNKNOWN:
225           terr = FPX_OLE_FILE_ERROR;
226           break;
227     case STG_E_UNIMPLEMENTEDFUNCTION:
228           terr = FPX_OLE_FILE_ERROR;
229           break;
230     case STG_E_INVALIDFLAG:
231           terr = FPX_OLE_FILE_ERROR;
232           break;
233     case STG_E_INUSE:
234           terr = FPX_FILE_IN_USE;
235           break;
236     case STG_E_NOTCURRENT:
237           terr = FPX_FILE_NOT_OPEN_ERROR;
238           break;
239     case STG_E_REVERTED:
240           terr = FPX_OLE_FILE_ERROR;
241           break;
242     case STG_E_CANTSAVE:
243           terr = FPX_OLE_FILE_ERROR;
244           break;
245     case STG_E_OLDFORMAT:
246           terr = FPX_INVALID_FORMAT_ERROR;
247           break;
248     case STG_E_OLDDLL:
249           terr = FPX_INVALID_FORMAT_ERROR;
250           break;
251     case STG_E_SHAREREQUIRED:
252           terr = FPX_FILE_IN_USE;
253           break;
254     case STG_E_NOTFILEBASEDSTORAGE:
255           terr = FPX_OLE_FILE_ERROR;
256           break;
257     case STG_E_EXTANTMARSHALLINGS:
258           terr = FPX_OLE_FILE_ERROR;
259           break;
260     case E_UNEXPECTED:
261           terr = FPX_OLE_FILE_ERROR;
262           break;
263     case E_NOTIMPL:
264           terr = FPX_UNIMPLEMENTED_FUNCTION;
265           break;
266     case E_OUTOFMEMORY:
267           terr = FPX_MEMORY_ALLOCATION_FAILED;
268           break;
269     case E_INVALIDARG:
270           terr = FPX_OLE_FILE_ERROR;
271           break;
272     case E_NOINTERFACE:
273           terr = FPX_OLE_FILE_ERROR;
274           break;
275     case E_POINTER:
276           terr = FPX_OLE_FILE_ERROR;
277           break;
278     case E_HANDLE:
279           terr = FPX_OLE_FILE_ERROR;
280           break;
281     case E_ABORT:
282           terr = FPX_OLE_FILE_ERROR;
283           break;
284     case E_FAIL:
285           terr = FPX_OLE_FILE_ERROR;
286           break;
287     case E_ACCESSDENIED:
288           terr = FPX_FILE_WRITE_ERROR;
289           break;
290     case OLE_E_OLEVERB:
291           terr = FPX_OLE_FILE_ERROR;
292           break;
293     case OLE_E_ADVF:
294           terr = FPX_OLE_FILE_ERROR;
295           break;
296     case OLE_E_ENUM_NOMORE:
297           terr = FPX_OLE_FILE_ERROR;
298           break;
299     case OLE_E_ADVISENOTSUPPORTED:
300           terr = FPX_UNIMPLEMENTED_FUNCTION;
301           break;
302     case OLE_E_NOCONNECTION:
303           terr = FPX_OLE_FILE_ERROR;
304           break;
305     case OLE_E_NOTRUNNING:
306           terr = FPX_SEVER_INIT_ERROR;
307           break;
308     case OLE_E_NOCACHE:
309           terr = FPX_OLE_FILE_ERROR;
310           break;
311     case OLE_E_BLANK:
312           terr = FPX_OLE_FILE_ERROR;
313           break;
314     case OLE_E_CLASSDIFF:
315           terr = FPX_INVALID_FORMAT_ERROR;
316           break;
317     case OLE_E_CANT_GETMONIKER:
318           terr = FPX_INVALID_FORMAT_ERROR;
319           break;
320     case OLE_E_CANT_BINDTOSOURCE:
321           terr = FPX_OLE_FILE_ERROR;
322           break;
323     case OLE_E_STATIC:
324           terr = FPX_OLE_FILE_ERROR;
325           break;
326     case OLE_E_PROMPTSAVECANCELLED:
327           terr = FPX_USER_ABORT;
328           break;
329     case OLE_E_INVALIDRECT:
330           terr = FPX_OLE_FILE_ERROR;
331           break;
332     case OLE_E_WRONGCOMPOBJ:
333           terr = FPX_OLE_FILE_ERROR;
334           break;
335     case OLE_E_INVALIDHWND:
336           terr = FPX_OLE_FILE_ERROR;
337           break;
338     case OLE_E_NOT_INPLACEACTIVE:
339           terr = FPX_OLE_FILE_ERROR;
340           break;
341     case OLE_E_CANTCONVERT:
342           terr = FPX_OLE_FILE_ERROR;
343           break;
344     case OLE_E_NOSTORAGE:
345           terr = FPX_FILE_NOT_OPEN_ERROR;
346           break;
347 #ifdef macintosh  // Mac specific errors from ole2.h
348     case OLE_E_NOEXTENSION:
349           terr = FPX_SEVER_INIT_ERROR;
350           break;
351     case OLE_E_VERSEXTENSION:
352           terr = FPX_SEVER_INIT_ERROR;
353           break;
354     case OLE_E_IPBUSY:
355           terr = FPX_OLE_FILE_ERROR;
356           break;
357     case OLE_E_NOT_FRONT_PROCESS:
358           terr = FPX_OLE_FILE_ERROR;
359           break;
360     case OLE_E_WRONG_MENU:
361           terr = FPX_OLE_FILE_ERROR;
362           break;
363     case OLE_E_MENU_NOT_PATCHED:
364           terr = FPX_OLE_FILE_ERROR;
365           break;
366     case OLE_E_MENUID_NOT_HASHED:
367           terr = FPX_OLE_FILE_ERROR;
368           break;
369 #endif // macintosh
370     default:  terr = FPX_OLE_FILE_ERROR;
371 
372           break;
373   }
374 
375   return terr;
376 }
377 
378 // This function translates the error in form of scode to normal error code
TranslateOLEError(HRESULT err)379 OSErr OLECore::TranslateOLEError(HRESULT err)
380 {
381   OSErr terr;
382   SCODE sCode = GetScode(err);
383 
384   switch (sCode) {
385     case S_OK:  terr = noErr;
386           break;
387     case STG_E_INVALIDFUNCTION:
388           terr = SEVERITY_ERROR;
389           break;
390     case STG_E_FILENOTFOUND:
391           terr = SEVERITY_ERROR;
392           break;
393     case STG_E_PATHNOTFOUND:
394           terr = SEVERITY_ERROR;
395           break;
396     case STG_E_TOOMANYOPENFILES:
397           terr = SEVERITY_ERROR;
398           break;
399     case STG_E_ACCESSDENIED:
400           terr = SEVERITY_ERROR;
401           break;
402     case STG_E_INVALIDHANDLE:
403           terr = SEVERITY_ERROR;
404           break;
405     case STG_E_INSUFFICIENTMEMORY:
406           terr = SEVERITY_ERROR;
407           break;
408     case STG_E_INVALIDPOINTER:
409           terr = -1;
410           break;
411     case STG_E_NOMOREFILES:
412           terr = -1;
413           break;
414     case STG_E_DISKISWRITEPROTECTED:
415           terr = -1;
416           break;
417     case STG_E_SEEKERROR:
418           terr = -1;
419           break;
420     case STG_E_WRITEFAULT:
421           terr = -1;
422           break;
423     case STG_E_READFAULT:
424           terr = -1;
425           break;
426     case STG_E_SHAREVIOLATION:
427           terr = -1;
428           break;
429     case STG_E_LOCKVIOLATION:
430           terr = -1;
431           break;
432     case STG_E_FILEALREADYEXISTS:
433           terr = -1;
434           break;
435     case STG_E_INVALIDPARAMETER:
436           terr = -1;
437           break;
438     case STG_E_MEDIUMFULL:
439           terr = -1;
440           break;
441     case STG_E_ABNORMALAPIEXIT:
442           terr = -1;
443           break;
444     case STG_E_INVALIDHEADER:
445           terr = -1;
446           break;
447     case STG_E_INVALIDNAME:
448           terr = -1;
449           break;
450     case STG_E_UNKNOWN:
451           terr = -1;
452           break;
453     case STG_E_UNIMPLEMENTEDFUNCTION:
454           terr = -1;
455           break;
456     case STG_E_INVALIDFLAG:
457           terr = -1;
458           break;
459     case STG_E_INUSE:
460           terr = -1;
461           break;
462     case STG_E_NOTCURRENT:
463           terr = -1;
464           break;
465     case STG_E_REVERTED:
466           terr = -1;
467           break;
468     case STG_E_CANTSAVE:
469           terr = -1;
470           break;
471     case STG_E_OLDFORMAT:
472           terr = -1;
473           break;
474     case STG_E_OLDDLL:
475           terr = -1;
476           break;
477     case STG_E_SHAREREQUIRED:
478           terr = -1;
479           break;
480     case STG_E_NOTFILEBASEDSTORAGE:
481           terr = -1;
482           break;
483     case STG_E_EXTANTMARSHALLINGS:
484           terr = -1;
485           break;
486     case E_UNEXPECTED:
487           terr = -1;
488           break;
489     case E_NOTIMPL:
490           terr = -1;
491           break;
492     case E_OUTOFMEMORY:
493           terr = -1;
494           break;
495     case E_INVALIDARG:
496           terr = -1;
497           break;
498     case E_NOINTERFACE:
499           terr = -1;
500           break;
501     case E_POINTER:
502           terr = -1;
503           break;
504     case E_HANDLE:
505           terr = -1;
506           break;
507     case E_ABORT:
508           terr = -1;
509           break;
510     case E_FAIL:
511           terr = -1;
512           break;
513     case E_ACCESSDENIED:
514           terr = -1;
515           break;
516     case OLE_E_OLEVERB:
517           terr = -1;
518           break;
519     case OLE_E_ADVF:
520           terr = -1;
521           break;
522     case OLE_E_ENUM_NOMORE:
523           terr = -1;
524           break;
525     case OLE_E_ADVISENOTSUPPORTED:
526           terr = -1;
527           break;
528     case OLE_E_NOCONNECTION:
529           terr = -1;
530           break;
531     case OLE_E_NOTRUNNING:
532           terr = -1;
533           break;
534     case OLE_E_NOCACHE:
535           terr = -1;
536           break;
537     case OLE_E_BLANK:
538           terr = -1;
539           break;
540     case OLE_E_CLASSDIFF:
541           terr = -1;
542           break;
543     case OLE_E_CANT_GETMONIKER:
544           terr = -1;
545           break;
546     case OLE_E_CANT_BINDTOSOURCE:
547           terr = -1;
548           break;
549     case OLE_E_STATIC:
550           terr = -1;
551           break;
552     case OLE_E_PROMPTSAVECANCELLED:
553           terr = -1;
554           break;
555     case OLE_E_INVALIDRECT:
556           terr = -1;
557           break;
558     case OLE_E_WRONGCOMPOBJ:
559           terr = -1;
560           break;
561     case OLE_E_INVALIDHWND:
562           terr = -1;
563           break;
564     case OLE_E_NOT_INPLACEACTIVE:
565           terr = -1;
566           break;
567     case OLE_E_CANTCONVERT:
568           terr = -1;
569           break;
570     case OLE_E_NOSTORAGE:
571           terr = -1;
572           break;
573 #ifdef macintosh  // Mac specific errors from ole2.h
574     case OLE_E_NOEXTENSION:
575           terr = -1;
576           break;
577     case OLE_E_VERSEXTENSION:
578           terr = -1;
579           break;
580     case OLE_E_IPBUSY:
581           terr = -1;
582           break;
583     case OLE_E_NOT_FRONT_PROCESS:
584           terr = -1;
585           break;
586     case OLE_E_WRONG_MENU:
587           terr = -1;
588           break;
589     case OLE_E_MENU_NOT_PATCHED:
590           terr = -1;
591           break;
592     case OLE_E_MENUID_NOT_HASHED:
593           terr = -1;
594           break;
595 #endif // macintosh
596     default:  terr = -1;
597           break;
598   }
599 
600   return terr;
601 }
602 
603 
604 //-------------------------------------------------------------------------------------------
605 //          OLEBlob functions
606 //-------------------------------------------------------------------------------------------
607 
608 // Create a blob by default size
OLEBlob()609 OLEBlob::OLEBlob()
610 {
611   // Set size and allocate memory for blob
612   blob.cbSize = 0;
613   buffer = NULL;
614   blob.pBlobData = buffer;
615 
616   // Set the pointer to the beginning of blob data
617   ResetPointer();
618 }
619 
620 // Create a blob by size
OLEBlob(const unsigned long size)621 OLEBlob::OLEBlob(const unsigned long size)
622 {
623   // Set size and allocate memory for blob
624   blob.cbSize = size;
625   buffer = new BYTE[size];
626   if (buffer==NULL) {
627     blob.cbSize=0;
628   }
629 
630   blob.pBlobData = buffer;
631 
632   // Set the pointer to the beginning of blob data
633   ResetPointer();
634 }
635 
636 // Create a blob from another blob
OLEBlob(const BLOB * inputBlob)637 OLEBlob::OLEBlob(const BLOB* inputBlob)
638 {
639   // Set size and allocate memory for blob
640   blob.cbSize = inputBlob->cbSize;
641   buffer = new BYTE[blob.cbSize];
642   if (buffer==NULL) {
643     blob.cbSize=0;
644   }
645   else {
646     // Copy memory
647     memcpy(buffer, inputBlob->pBlobData, inputBlob->cbSize);
648   }
649   blob.pBlobData = buffer;
650 
651   // Set the pointer to the beginning of blob data
652   ResetPointer();
653 }
654 
~OLEBlob()655 OLEBlob::~OLEBlob()
656 {
657   if (blob.cbSize)
658     delete[] buffer;
659 }
660 
661 // Assign a blob
operator =(BLOB * inputBlob)662 Boolean OLEBlob::operator=(BLOB* inputBlob)
663 {
664   // Check the validity of input blob
665   if ( !inputBlob)
666     return false;
667 
668   if (blob.cbSize)
669     delete buffer;
670 
671   // Set size and allocate memory for blob
672   blob.cbSize = inputBlob->cbSize;
673   buffer = new BYTE[blob.cbSize];
674 
675   if ( !buffer)
676     return false;
677 
678   // Copy memory
679   memcpy(buffer, inputBlob->pBlobData, inputBlob->cbSize);
680   blob.pBlobData = buffer;
681 
682   // Set the pointer to the beginning of blob data
683   ResetPointer();
684 
685   return true;
686 }
687 
688 // Generic read function for blob
Read(void * dataPtr,const long size)689 Boolean OLEBlob::Read(void *dataPtr, const long size)
690 {
691   if ((long)(bufPtr + size - buffer) > (long)blob.cbSize)
692     return false;
693 
694   // Read the data from the blob buffer referenced by bufPtr
695   memcpy(dataPtr, bufPtr, size);
696   bufPtr += size;
697 
698   return true;
699 }
700 
701 // Read a unsigned char type from blob. Return the total bytes read, which is 1 bytes ( char )
ReadVT_I1(BYTE * pb)702 DWORD OLEBlob::ReadVT_I1(BYTE *pb)
703 {
704   // Read a unsigned char type from the blob buffer referenced by bufPtr
705   if ( !Read(pb, sizeof(char)) )
706     return false;
707 
708   return sizeof(char);
709 }
710 
711 // Read a short type from blob. Return the total bytes read, which is 2 bytes ( short )
ReadVT_I2(WORD * pw)712 DWORD OLEBlob::ReadVT_I2(WORD *pw)
713 {
714   // Read a short type from the blob buffer referenced by bufPtr
715   if ( !Read(pw, sizeof(*pw)) )
716     return false;
717 
718   // Swap bytes if necessary
719   #ifdef  IN_BIG_ENDIAN
720     SwapBytes((BYTE *)pw, sizeof(*pw));
721   #endif
722 
723   return sizeof(*pw);
724 }
725 
726 // Read a long type from blob. Return the total bytes read, which is 4 bytes ( long )
ReadVT_I4(DWORD * pdw)727 DWORD OLEBlob::ReadVT_I4(DWORD *pdw)
728 {
729   // Read a long type from the blob buffer referenced by bufPtr
730   if ( !Read(pdw, sizeof(*pdw)) )
731     return false;
732 
733   // Swap bytes if necessary
734   #ifdef  IN_BIG_ENDIAN
735     SwapBytes((BYTE *)pdw, sizeof(*pdw));
736   #endif
737 
738   return sizeof(*pdw);
739 }
740 
741 // Read a float type from blob. Return the total bytes read, which is 4 bytes ( float )
ReadVT_R4(float * pflt)742 DWORD OLEBlob::ReadVT_R4(float *pflt)
743 {
744   // Read a float type from the blob buffer referenced by bufPtr
745   if ( !Read(pflt, sizeof(float)) )
746     return false;
747 
748   // Swap bytes if necessary
749   #ifdef  IN_BIG_ENDIAN
750     SwapBytes((BYTE *)pflt, sizeof(float));
751   #endif
752 
753   return sizeof(float);
754 }
755 
756 // Read a double type from blob. Return the total bytes read, which is 8 bytes ( double )
ReadVT_R8(double * pdbl)757 DWORD OLEBlob::ReadVT_R8(double *pdbl)
758 {
759   // Read a double type from the blob buffer referenced by bufPtr
760   if ( !Read(pdbl, sizeof(double)) )
761     return false;
762 
763   // Swap bytes if necessary
764   #ifdef  IN_BIG_ENDIAN
765     SwapBytes((BYTE *)pdbl, sizeof(double));
766   #endif
767 
768   return sizeof(double);
769 }
770 
771 // Read a byte array from blob. Return the total array length
ReadVT_VECTOR(BYTE ** ppByte)772 DWORD OLEBlob::ReadVT_VECTOR(BYTE **ppByte)
773 {
774   // Allocating memory for string
775   *ppByte = new BYTE[blob.cbSize];
776   if (*ppByte==NULL) {
777     return false;
778   }
779 
780   // Read the string
781   if ( !Read(*ppByte, blob.cbSize) )
782     return false;
783 
784   return blob.cbSize;
785 }
786 
787 // Read a string from blob. Return the total string length
ReadVT_LPSTR(char ** ppsz)788 DWORD OLEBlob::ReadVT_LPSTR(char **ppsz)
789 {
790   DWORD dwLength;
791 
792   // Read the string length first including the terminating NULL
793   if ( !ReadVT_I4(&dwLength) )
794     return false;
795 
796   // Allocating memory for string
797   *ppsz = new char[dwLength];
798   if (*ppsz==NULL) {
799     return false;
800   }
801 
802   // Read the string
803   if ( !Read(*ppsz, dwLength) )
804     return false;
805 
806   return dwLength;
807 }
808 
809 // Read a wide string from blob. Return the total length ( bytes count )
ReadVT_LPWSTR(WCHAR ** ppwsz)810 DWORD OLEBlob::ReadVT_LPWSTR(WCHAR **ppwsz)
811 {
812   DWORD dwLength;
813 
814   // Read the WCHAR count first including the terminating NULL
815   if ( !ReadVT_I4(&dwLength) )
816     return false;
817 
818   // Allocating memory for LPWSTR
819   *ppwsz = new WCHAR[dwLength];
820   if (*ppwsz==NULL) {
821     return false;
822   }
823 
824   // Read the LPWSTR
825   if ( !Read(*ppwsz, dwLength * sizeof(WCHAR)) )
826     return false;
827 
828   return dwLength * sizeof(WCHAR);
829 }
830 
831 // Generic write function for blob
Write(const void * dataPtr,const long size)832 Boolean OLEBlob::Write(const void *dataPtr, const long size)
833 {
834   // Get the already used buffer length
835   DWORD usedSize = bufPtr - buffer;
836 
837   // If current allocate memory is not enough for new data, reallocate memory
838   if (( usedSize + size ) > blob.cbSize)  {
839 
840     // Allocate memory for new length
841     BYTE *tempBuf = new BYTE[usedSize + size];
842     if ( !tempBuf)
843       return false;
844 
845     // Copy the old buffer to new one and delete it
846     memcpy(tempBuf, buffer, usedSize * sizeof(char));
847     if ( buffer )
848       delete buffer;
849 
850     // Reset the buffer and buffer pointer
851     buffer = tempBuf;
852     bufPtr = buffer + usedSize;
853 
854     // Reset the blob size and buffer
855     blob.cbSize = usedSize + size;
856     blob.pBlobData = buffer;
857   }
858 
859   // Write the data to the blob buffer referenced by bufPtr
860   memcpy(bufPtr, dataPtr, size);
861   bufPtr += size;
862 
863   return true;
864 }
865 
866 // Write a unsigned char type to blob. Return the total bytes write, which is 1 bytes ( char )
WriteVT_I1(BYTE b)867 DWORD OLEBlob::WriteVT_I1(BYTE b)
868 {
869   // Write a unsigned char type to the blob buffer referenced by bufPtr
870   if ( !Write(&b, sizeof(char)) )
871     return false;
872 
873   return sizeof(char);
874 }
875 
876 // Write a short type to blob. Return the total bytes write, which is 2 bytes ( short )
WriteVT_I2(WORD pw)877 DWORD OLEBlob::WriteVT_I2(WORD pw)
878 {
879   WORD w = pw;
880 
881   // Swap bytes if necessary
882   #ifdef  IN_BIG_ENDIAN
883     SwapBytes((BYTE *)&w, sizeof(pw));
884   #endif
885 
886   // Write a short type to the blob buffer referenced by bufPtr
887   if ( !Write(&w, sizeof(pw)) )
888     return false;
889 
890   return sizeof(pw);
891 }
892 
893 // Write a long type to blob. Return the total bytes write, which is 4 bytes ( long )
WriteVT_I4(DWORD pdw)894 DWORD OLEBlob::WriteVT_I4(DWORD pdw)
895 {
896   DWORD dw = pdw;
897 
898   // Swap bytes if necessary
899   #ifdef  IN_BIG_ENDIAN
900     SwapBytes((BYTE *)&dw, sizeof(pdw));
901   #endif
902 
903   // Write a long type to the blob buffer referenced by bufPtr
904   if ( !Write(&dw, sizeof(pdw)) )
905     return false;
906 
907   return sizeof(pdw);
908 }
909 
910 // Write a float type to blob. Return the total bytes write, which is 4 bytes ( float )
WriteVT_R4(float pflt)911 DWORD OLEBlob::WriteVT_R4(float pflt)
912 {
913   float flt = pflt;
914 
915   // Swap bytes if necessary
916   #ifdef  IN_BIG_ENDIAN
917     SwapBytes((BYTE *)&flt, sizeof(float));
918   #endif
919 
920   // Write a float type to the blob buffer referenced by bufPtr
921   if ( !Write(&flt, sizeof(float)) )
922     return false;
923 
924   return sizeof(float);
925 }
926 
927 // Write a double type to blob. Return the total bytes write, which is 8 bytes ( double )
WriteVT_R8(double pdbl)928 DWORD OLEBlob::WriteVT_R8(double pdbl)
929 {
930   double dbl = pdbl;
931 
932   // Swap bytes if necessary
933   #ifdef  IN_BIG_ENDIAN
934     SwapBytes((BYTE *)&dbl, sizeof(double));
935   #endif
936 
937   // Write a double type to the blob buffer referenced by bufPtr
938   if ( !Write(&dbl, sizeof(double)) )
939     return false;
940 
941   return sizeof(double);
942 }
943 
944 // Write a byte array to blob. Return the total array length
WriteVT_VECTOR(BYTE * pbyte,DWORD veclen)945 DWORD OLEBlob::WriteVT_VECTOR(BYTE *pbyte, DWORD veclen)
946 {
947   // Write the byte array to the blob buffer referenced by bufPtr
948   if ( !Write(pbyte, veclen * sizeof(char)) )
949     return false;
950 
951   return veclen * sizeof(char);
952 }
953 
954 // Write a string to blob. Return the total string length
WriteVT_LPSTR(char * psz)955 DWORD OLEBlob::WriteVT_LPSTR(char *psz)
956 {
957   DWORD dwLength = strlen(psz) + 1; // Count includes terminating zero
958 
959   // Write the string length, including terminating NULL
960   if ( !WriteVT_I4(dwLength) )
961     return false;
962 
963   // Write the string to the blob buffer referenced by bufPtr
964   if ( !Write(psz, dwLength * sizeof(char)) )
965     return false;
966 
967   return dwLength * sizeof(char);
968 }
969 
970 // Write a wide string to blob. Return the total length in bytes
WriteVT_LPWSTR(WCHAR * pwsz)971 DWORD OLEBlob::WriteVT_LPWSTR(WCHAR *pwsz)
972 {
973   DWORD wcount;
974 
975   wcount = wcslen(pwsz) + 1;        // Get the WCHAR count
976 
977   // Write the WCHAR count, including terminating NULL
978   if ( !WriteVT_I4(wcount) )
979     return false;
980 
981   // Write the wide string to the blob buffer referenced by bufPtr
982   if ( !Write(pwsz, wcount * sizeof(WCHAR)) )
983     return false;
984 
985   return wcount * sizeof(WCHAR);
986 }
987 
988 //  ----------------------------------------------------------------------------
989 //  Methods of List
990 //  ----------------------------------------------------------------------------
991 
992 // Create a list. This constructor should be used only for the list root
List()993 List::List()
994 {
995   // Set the initial reference count to one
996   userCount = 1;
997 
998   // Set the initial pointer to null
999   name = DuplicateStr("");
1000   ptr  = NULL;
1001   next = NULL;
1002 }
1003 
1004 // Create a new record in the list
List(void * thePtr,const char * theName,Boolean _freeme)1005 List::List(void* thePtr, const char *theName, Boolean _freeme)
1006 {
1007   // Set the initial reference count to one
1008   userCount = 1;
1009 
1010   // Set the initial pointer to the passed values
1011   name = DuplicateStr(theName);
1012   ptr  = thePtr;
1013   next = NULL;
1014   freeme = _freeme;
1015 }
1016 
1017 // Delete a list
~List()1018 List::~List()
1019 {
1020   List *pl = next, *nextpl;
1021   assert(userCount >= 0);
1022   delete[] name;
1023   if (userCount == 0) /* we are already dead */
1024     return;
1025   while (pl) {
1026      nextpl = pl->next;
1027      pl->Release();
1028      if (pl->userCount == 0)
1029        delete pl;
1030      pl = nextpl;
1031   }
1032 }
1033 
AddRef()1034 void List::AddRef()
1035 {
1036   userCount++;
1037 }
1038 
Release()1039 void List::Release()
1040 {
1041   assert(userCount > 0);
1042   userCount--;
1043   if ( userCount <= 0 ) {
1044     delete[] name;
1045     name = NULL;
1046     /*
1047      * XXX This is a TERRIBLE hack. We presume, the ptr marked by
1048      * XXX freeme is coming from the OLEStorage::OpenPropertySet(),
1049      * XXX where it is of type LPSTREAM*. This is true at the moment,
1050      * XXX but should anyone begin to develop this horrible code
1051      * XXX further, the assumption is likely to break...
1052      *
1053      *	-mi, Oct 9, 2007
1054      */
1055     if (freeme)
1056       delete (LPSTREAM *)ptr;
1057     ptr  = NULL;
1058     userCount = 0;
1059   }
1060 }
1061 
1062 // Add an ole object to the list
Add(void * thePtr,const char * theName,Boolean _freeme)1063 Boolean List::Add(void* thePtr, const char *theName, Boolean _freeme)
1064 {
1065   // Add the ole object to the list only if it is not in the list yet.
1066   if ( !Search(theName) ) {
1067 
1068     // Add the ole object to the end of list
1069     List* pl = GetEndOfList();
1070 
1071     pl->next = new List(thePtr, theName, _freeme);
1072 
1073     if ( pl->next == NULL )
1074       return FALSE;
1075   }
1076 
1077   return TRUE;
1078 }
1079 
1080 // Delete an ole object in the list
Delete(const char * theName)1081 Boolean List::Delete(const char *theName)
1082 {
1083   List* pl = NULL;
1084 
1085   // Delete the ole object to the list only if it is in the list.
1086   if ( (pl = Locate(theName)) != NULL ) {
1087 
1088     // Store the next list pointer in a temporary place
1089     List* tmp = pl->next->next;
1090 
1091     // Delete current list pointer
1092     delete  pl->next;
1093 
1094     // Save the next list pointer
1095     pl->next = tmp;
1096 
1097   } else {
1098     return FALSE;
1099   }
1100 
1101   return TRUE;
1102 }
1103 
1104 // Locate a List object in the list.
1105 // Return the address of the List object immediately BEFORE the searched object.
1106 // TRICK: this works ONLY because there is ALWAYS a dummy record at the beginning of the list.
Locate(const char * theName)1107 List* List::Locate(const char *theName)
1108 {
1109   if (next == NULL)
1110     return NULL;
1111   else if ( !strcmp(next->name, theName) )
1112     return this;
1113   else
1114     return next->Locate (theName);
1115 }
1116 
1117 // Search an ole object in the list. Return NULL if none found
Search(const char * theName)1118 void* List::Search(const char *theName)
1119 {
1120   if ( !strcmp (name, theName) )
1121     return ptr;
1122   else if (next)
1123     return next->Search(theName);
1124   else
1125     return NULL;
1126 }
1127 
1128 // Find the last element in the list
GetEndOfList()1129 List* List::GetEndOfList()
1130 {
1131   if (next)
1132     return next->GetEndOfList();
1133   else
1134     return this;
1135 }
1136 
1137 
1138 //  ----------------------------------------------------------------------------
1139 //  Global Functions
1140 //  ----------------------------------------------------------------------------
1141 
1142 // This function replaces substring with another one in a specified string, return NULL
1143 // if failed
strrep(const char * s1,const char * t1,const char * t2,char * s2)1144 char* strrep(const char* s1, const char *t1, const char *t2, char *s2)
1145 {
1146   const char *ptr;
1147         char *newstr;
1148 
1149   // If the substring don't exist, return NULL
1150   if ( !(ptr=strstr(s1, t1)))   return NULL;
1151 
1152   newstr = new char[strlen(s1)+strlen(t2)+1];
1153   if (newstr==NULL) {
1154     return NULL;
1155   }
1156   strcpy(newstr, s1);
1157   newstr[ptr-s1]= '\0';
1158   strcat(newstr, t2);
1159   newstr[ptr-s1 + strlen(t2)]= '\0';
1160   strcpy(s2, newstr);
1161   delete newstr;
1162 
1163   return s2;
1164 }
1165 
1166 // This function duplicate a string. Notice: the returned string is allocated and should be deleted
1167 // after use. Return null if fails
DuplicateStr(const char * s)1168 char* DuplicateStr(const char* s)
1169 {
1170   char *str = new char[strlen(s) + 1];
1171 
1172   if ( !str )
1173     return NULL;
1174 
1175   strcpy(str, s);
1176   return str;
1177 }
1178 
1179 // This function duplicate a wide char string. Notice: the returned string is allocated and should be deleted
1180 // after use. Return null if fails
DuplicateWideStr(const WCHAR * ws)1181 WCHAR* DuplicateWideStr(const WCHAR* ws)
1182 {
1183   WCHAR *wstr = new WCHAR[wcslen(ws) + 1];
1184 
1185   if ( !wstr )
1186     return NULL;
1187 
1188   memcpy(wstr, ws, sizeof(WCHAR) * (wcslen(ws) + 1));
1189   return wstr;
1190 }
1191 
1192 // This function duplicate a blob. Notice: the returned blob is allocated and should be deleted
1193 // after use. Return null if fails
DuplicateBLOB(const BLOB * pblob)1194 BLOB* DuplicateBLOB(const BLOB* pblob)
1195 {
1196   BLOB *pb = NULL;
1197 
1198   if ( pblob ) {
1199     pb = new BLOB;
1200     pb->cbSize = pblob->cbSize;
1201     pb->pBlobData= new BYTE [pb->cbSize];
1202 
1203     if ( !pb->pBlobData )
1204       return NULL;
1205 
1206     memcpy(pb->pBlobData, pblob->pBlobData, pb->cbSize);
1207   }
1208   else
1209     return NULL;
1210 
1211   return pb;
1212 }
1213 
1214 // This function delete a blob
DeleteBLOB(BLOB * pblob)1215 void DeleteBLOB(BLOB* pblob)
1216 {
1217   if ( pblob ) {
1218     if ( pblob->pBlobData ) {
1219       delete[] pblob->pBlobData;
1220       pblob->cbSize = 0;
1221     }
1222     delete pblob;
1223   }
1224 }
1225 
1226 // This function duplicate a clipdata. Notice: the returned clipdata is allocated and should be deleted
1227 // after use. Return null if fails
DuplicateCF(const CLIPDATA * pClipData)1228 CLIPDATA* DuplicateCF(const CLIPDATA* pClipData)
1229 {
1230   CLIPDATA *pcf = NULL;
1231 
1232   if ( pClipData ) {
1233     pcf = new CLIPDATA;
1234     pcf->cbSize = pClipData->cbSize;
1235     pcf->pClipData= new BYTE [pcf->cbSize];
1236 
1237     if ( !pcf->pClipData )
1238       return NULL;
1239 
1240     memcpy(pcf->pClipData, pClipData->pClipData, pcf->cbSize);
1241   }
1242   else
1243     return NULL;
1244 
1245   return pcf;
1246 }
1247 
1248 // This function delete a clipdata
DeleteCF(CLIPDATA * pcf)1249 void DeleteCF(CLIPDATA* pcf)
1250 {
1251   if ( pcf ) {
1252     if ( pcf->pClipData ) {
1253       delete[] pcf->pClipData;
1254       pcf->cbSize = 0;
1255     }
1256     delete pcf;
1257   }
1258 }
1259 
1260 // This function allocate memory for vector. Notice: the returned vector is allocated and should be deleted
1261 // after use. Return null if fails
AllocVECTOR(long type,long elemCount)1262 VECTOR* AllocVECTOR(long type, long elemCount)
1263 {
1264   VECTOR *pvec = new VECTOR;
1265   if ( !pvec )
1266     return NULL;
1267 
1268   pvec->cElements = elemCount;
1269 
1270   // Erase the VT_VECTOR bit, so remaining is the data type in vector
1271   if (type & VT_VECTOR)
1272     type ^= VT_VECTOR;
1273 
1274   switch (type)
1275   {
1276     // If the subtype is char/unsigned char, use BYTE *prgb
1277     case VT_I1:
1278     case VT_UI1: {
1279       pvec->prgb = new BYTE[pvec->cElements * sizeof(char)];
1280       if ( !pvec->prgb )
1281         return NULL;
1282       break;
1283     }
1284 
1285     // If the subtype is short/unsigned short, use WORD *prgw
1286     case VT_I2:
1287     case VT_UI2:
1288     case VT_BOOL: {
1289       pvec->prgw = new WORD [pvec->cElements];
1290       if ( !pvec->prgw )
1291         return NULL;
1292       break;
1293     }
1294 
1295     // If the subtype is long/unsigned long, use DWORD *prgdw
1296     case VT_I4:
1297     case VT_UI4:
1298     case VT_ERROR: {
1299       pvec->prgdw = new DWORD [pvec->cElements];
1300       if ( !pvec->prgdw )
1301         return NULL;
1302       break;
1303     }
1304 
1305     // If the subtype is float, use float *prgflt
1306     case VT_R4: {
1307       pvec->prgflt = new float [pvec->cElements];
1308       if ( !pvec->prgflt )
1309         return NULL;
1310       break;
1311     }
1312 
1313     // If the subtype is double, use double *prgdbl
1314     case VT_R8: {
1315       pvec->prgdbl = new double [pvec->cElements];
1316       if ( !pvec->prgdbl )
1317         return NULL;
1318       break;
1319     }
1320 
1321     // If the subtype is LPSTR, use char **prgpsz
1322     case VT_LPSTR: {
1323       pvec->prgpsz = new char* [pvec->cElements];
1324       if (pvec->prgpsz==NULL)
1325         return NULL;
1326       break;
1327     }
1328 
1329     // If the subtype is LPSTR/BSTR, use char **prgpwz
1330     case VT_LPWSTR:
1331     case VT_BSTR: {
1332       pvec->prgpwz = new WCHAR* [pvec->cElements];
1333       if (pvec->prgpwz==NULL)
1334         return NULL;
1335       break;
1336     }
1337 
1338     // If the subtype is BLOB, use BLOB **prgblob
1339     case VT_BLOB: {
1340       pvec->prgblob = new BLOB* [pvec->cElements];
1341       if ( !pvec->prgblob )
1342         return NULL;
1343       break;
1344     }
1345 
1346     // If the subtype is CLIPDATA, use CLIPDATA **pcd
1347     case VT_CF: {
1348       pvec->pcd = new CLIPDATA* [pvec->cElements];
1349       if ( !pvec->pcd )
1350         return NULL;
1351       break;
1352     }
1353 
1354     // If the subtype is CLSID, use CLSID *pclsid
1355     case VT_CLSID: {
1356       pvec->pclsid = new CLSID [pvec->cElements];
1357       if ( !pvec->pclsid )
1358         return NULL;
1359       break;
1360     }
1361 
1362     // If the subtype is VARIANT, use VARIANT *pvar
1363     case VT_VARIANT: {
1364       pvec->pvar = new VARIANT [pvec->cElements];
1365       if ( !pvec->pvar )
1366         return NULL;
1367       break;
1368     }
1369 
1370     default:
1371       return NULL;
1372   }
1373 
1374   return pvec;
1375 }
1376 
1377 // This function duplicate a vector. Notice: the returned vector is allocated and should be deleted
1378 // after use. Return null if fails
DuplicateVECTOR(const VECTOR * pvector,long type)1379 VECTOR* DuplicateVECTOR(const VECTOR* pvector, long type)
1380 {
1381   DWORD len;
1382 
1383   // If original vector is invalid, return false
1384   if ( !pvector )
1385     return NULL;
1386 
1387   // Allocate the memory for a new vector
1388   VECTOR* pvec = AllocVECTOR(type, pvector->cElements);
1389   if ( !pvec )
1390     return NULL;
1391 
1392   // Erase the VT_VECTOR bit, so remaining is the data type in vector
1393   if (type & VT_VECTOR)
1394     type ^= VT_VECTOR;
1395 
1396   // Duplicate the vector according to its type
1397   switch (type)
1398   {
1399     // If the subtype is char/unsigned char, use BYTE *prgb
1400     case VT_I1:
1401     case VT_UI1: {
1402       memcpy(pvec->prgb, pvector->prgb, pvec->cElements * sizeof(char));
1403 
1404       // Set the size of vector
1405       len =  pvec->cElements * sizeof(char) + sizeof(DWORD);
1406       break;
1407     }
1408 
1409     // If the subtype is short/unsigned short, use WORD *prgw
1410     case VT_I2:
1411     case VT_UI2:
1412     case VT_BOOL: {
1413       memcpy(pvec->prgw, pvector->prgw, pvec->cElements * 2);
1414 
1415       // Set the size of vector
1416       len =  pvec->cElements * sizeof(short) + sizeof(DWORD);
1417       break;
1418     }
1419 
1420     // If the subtype is long/unsigned long, use DWORD *prgdw
1421     case VT_I4:
1422     case VT_UI4:
1423     case VT_ERROR: {
1424       memcpy(pvec->prgdw, pvector->prgdw, pvec->cElements * 4);
1425 
1426       // Set the size of vector
1427       len =  pvec->cElements * 4 + sizeof(DWORD);
1428       break;
1429     }
1430 
1431     // If the subtype is float, use float *prgflt
1432     case VT_R4: {
1433       memcpy(pvec->prgflt, pvector->prgflt, pvec->cElements * sizeof(float));
1434 
1435       // Set the size of vector
1436       len =  pvec->cElements * sizeof(float) + sizeof(DWORD);
1437       break;
1438     }
1439 
1440     // If the subtype is double, use double *prgdbl
1441     case VT_R8: {
1442       memcpy(pvec->prgdbl, pvector->prgdbl, pvec->cElements * sizeof(double));
1443 
1444       // Set the size of vector
1445       len =  pvec->cElements * sizeof(double) + sizeof(DWORD);
1446       break;
1447     }
1448 
1449     // If the subtype is LPSTR/BSTR, use char **prgpsz
1450     case VT_LPSTR: {
1451       for ( DWORD i = 0; i < pvec->cElements; i++ ) {
1452 
1453         // Duplicate each string in the array
1454         if ( !(pvec->prgpsz[i] = DuplicateStr(pvector->prgpsz[i])) ) {
1455           pvec->cElements = i - 1;
1456           break;
1457         }
1458       }
1459       break;
1460     }
1461 
1462     // If the subtype is LPWSTR, use char **prgpwz
1463     case VT_LPWSTR:
1464     case VT_BSTR: {
1465       for ( DWORD i = 0; i < pvec->cElements; i++ ) {
1466 
1467         // Duplicate each wide string in the array
1468         if ( !(pvec->prgpwz[i] = DuplicateWideStr(pvector->prgpwz[i])) ) {
1469           pvec->cElements = i - 1;
1470           break;
1471         }
1472       }
1473       break;
1474     }
1475 
1476     // If the subtype is BLOB, use BLOB **prgblob
1477     case VT_BLOB: {
1478       for ( DWORD i = 0; i < pvec->cElements; i++ ) {
1479 
1480         // Duplicate each BLOB in the array
1481         if ( !(pvec->prgblob[i] = DuplicateBLOB(pvector->prgblob[i])) ) {
1482           pvec->cElements = i - 1;
1483           break;
1484         }
1485       }
1486       break;
1487     }
1488 
1489     // If the subtype is CLIPDATA, use CLIPDATA **pcd
1490     case VT_CF: {
1491       for ( DWORD i = 0; i < pvec->cElements; i++ ) {
1492 
1493         // Duplicate each CLIPDATA in the array
1494         if ( !(pvec->pcd[i] = DuplicateCF(pvector->pcd[i])) ) {
1495           pvec->cElements = i - 1;
1496           break;
1497         }
1498       }
1499       break;
1500     }
1501 
1502     // If the subtype is CLSID, use CLSID *pclsid
1503     case VT_CLSID: {
1504       memcpy(pvec->pclsid, pvector->pclsid, sizeof(CLSID) * pvec->cElements);
1505       break;
1506     }
1507 
1508     // If the subtype is VARIANT, use VARIANT *pvar
1509     case VT_VARIANT: {
1510       memcpy(pvec->pvar, pvector->pvar, pvec->cElements * sizeof(VARIANT));
1511 
1512       // Copy the variable length elements in the vector
1513       for ( DWORD i = 0; i < pvec->cElements; i++ ) {
1514 
1515         // If variant type is vector, recursively duplicate vector
1516         if ( pvec->pvar[i].vt & VT_VECTOR ) {
1517 
1518           VECTOR *pv = (VECTOR *)V_BYREF(&pvector->pvar[i]);
1519           len = VTtoVariant(&pvec->pvar[i], pv);
1520           continue;
1521         }
1522 
1523         // Duplicate according to type in variant
1524         switch(pvec->pvar[i].vt)
1525         {
1526           case VT_LPSTR:
1527             len = VTtoVariant(&pvec->pvar[i], (char*)V_UI1REF(&pvector->pvar[i]));
1528             break;
1529 
1530           case VT_LPWSTR:
1531             len = VTtoVariant(&pvec->pvar[i], (LPWSTR)V_BYREF(&pvector->pvar[i]));
1532             break;
1533 
1534           case VT_BLOB:
1535             len = VTtoVariant(&pvec->pvar[i], (BLOB *)V_BYREF(&pvector->pvar[i]));
1536             break;
1537 
1538           case VT_CF:
1539             len = VTtoVariant(&pvec->pvar[i], (CLIPDATA *)V_BYREF(&pvector->pvar[i]));
1540             break;
1541 
1542           case VT_CLSID:
1543             VTtoVariant(&pvec->pvar[i], (CLSID *)V_BYREF(&pvector->pvar[i]));
1544             break;
1545 
1546         }
1547 
1548         if ( !len ) {
1549           pvec->cElements = i - 1;
1550           break;
1551         }
1552       }
1553       break;
1554     }
1555 
1556     default:
1557       return NULL;
1558   }
1559 
1560   return pvec;
1561 }
1562 
1563 // This function delete a vector
DeleteVECTOR(VECTOR * pvec,long type)1564 void  DeleteVECTOR(VECTOR* pvec, long type)
1565 {
1566   // Erase the VT_VECTOR bit, so remaining is the data type in vector
1567   if (type & VT_VECTOR)
1568     type ^= VT_VECTOR;
1569 
1570   if ( !pvec )
1571     return;
1572 
1573   switch(type)
1574   {
1575     case VT_I1:
1576     case VT_UI1: {
1577       if (pvec->cElements)  delete [] pvec->prgb;
1578       break;
1579     }
1580     case VT_I2:
1581     case VT_UI2:
1582     case VT_BOOL: {
1583       if (pvec->cElements)  delete [] pvec->prgw;
1584       break;
1585     }
1586     case VT_I4:
1587     case VT_UI4:
1588     case VT_ERROR: {
1589       if (pvec->cElements)  delete [] pvec->prgdw;
1590       break;
1591     }
1592     case VT_R4: {
1593       if (pvec->cElements)  delete [] pvec->prgflt;
1594       break;
1595     }
1596     case VT_R8: {
1597       if (pvec->cElements)  delete [] pvec->prgdbl;
1598       break;
1599     }
1600     case VT_LPSTR:
1601     {
1602       for ( DWORD i = 0; i < pvec->cElements; i++ )
1603         delete [] pvec->prgpsz[i];
1604       if (pvec->cElements)  delete [] pvec->prgpsz;
1605       break;
1606     }
1607     case VT_LPWSTR:
1608     case VT_BSTR:
1609     {
1610       for ( DWORD i = 0; i < pvec->cElements; i++ )
1611         delete [] pvec->prgpwz[i];
1612       if (pvec->cElements)
1613         delete [] pvec->prgpwz;
1614       break;
1615     }
1616     case VT_BLOB: {
1617       for ( DWORD i = 0; i < pvec->cElements; i++ )
1618         DeleteBLOB(pvec->prgblob[i]);
1619       if (pvec->cElements)
1620         delete pvec->prgblob;
1621       break;
1622     }
1623     case VT_CF: {
1624       for ( DWORD i = 0; i < pvec->cElements; i++ )
1625         DeleteCF(pvec->pcd[i]);
1626       if (pvec->cElements)
1627         delete pvec->pcd;
1628       break;
1629     }
1630     case VT_CLSID: {
1631       if (pvec->cElements)
1632         delete [] pvec->pclsid;
1633       break;
1634     }
1635     case VT_VARIANT: {
1636       if (pvec->cElements)
1637         delete [] pvec->pvar;
1638       break;
1639     }
1640   }
1641 
1642   if ( pvec )
1643     delete pvec;
1644 }
1645 
1646 
1647 // FIX_DICT_PROP - Added allocator and deallocator for dictionary property content.
1648 
1649 // This function allocate memory for dictionary. An array of entries is allocated.
1650 //  each entry is initialized to null. The caller must allocate the strings for the
1651 //  entries and fill-in the entries.
1652 // Returns pointer to allocated & initialized dictionary (or null)
AllocDICTIONARY(long elemCount)1653 DICTIONARY* AllocDICTIONARY(long elemCount)
1654 {
1655   // Allocate/construct the property
1656   DICTIONARY *pDict = new DICTIONARY;
1657   if ( !pDict )
1658     return NULL;
1659 
1660   // Allocate the array of entries and then initialize it.
1661   pDict->rgEntry = new ENTRY [elemCount];
1662   if ( !pDict->rgEntry ) {
1663     delete pDict;
1664     return NULL;
1665   }
1666   pDict->cbEntries = elemCount;
1667 
1668   // Initialize the array of entries.
1669   for(unsigned long i = 0; i < pDict->cbEntries; i++) {
1670     pDict->rgEntry[i].dwPropID  = 0;
1671     pDict->rgEntry[i].cb    = 0;
1672     pDict->rgEntry[i].sz    = 0;
1673   }
1674 
1675   return pDict;
1676 }
1677 
1678 
1679 // This function deletes a dictionary property -- including all of it's contents
DeleteDICTIONARY(DICTIONARY * pDict)1680 void  DeleteDICTIONARY(DICTIONARY* pDict)
1681 {
1682   if ( !pDict )
1683     return;
1684 
1685   if (pDict->rgEntry) {
1686     // Deallocate all of the strings contained in the array of entries
1687     for(unsigned long i = 0; i < pDict->cbEntries; i++)
1688       if( pDict->rgEntry[i].sz )
1689         delete [] pDict->rgEntry[i].sz;
1690 
1691     // Deallocate the array of entries
1692     delete pDict->rgEntry;
1693   }
1694 
1695   delete pDict;   // Delete the dictonary
1696 }
1697 
1698 
1699 #ifndef USE_UNICODE
1700 // WideCharToMultiByte()
1701 // Generic routine for converting UniCode string to ASCII string. Return the ASCII string,
1702 // NULL if failed. The ASCII string is allocated, so should be deleted after use
WideCharToMultiByte(const WCHAR * pwchar)1703 char* WideCharToMultiByte(const WCHAR * pwchar)
1704 {
1705   // Determine the length of wide char string
1706   DWORD wcharlen = wcslen(pwchar);
1707 
1708   // Allocate memory including terminating NULL
1709   char *pchar = new char[wcharlen + 1];
1710 
1711   // Return if fails
1712   if ( !pchar ) return NULL;
1713 
1714   for (DWORD i = 0; i < wcharlen; i++ )
1715   {
1716     // Only low byte of Unicode is used
1717     pchar[i] = pwchar[i] & 0x00FF;
1718   }
1719 
1720   // Add a '\0' to the end of string
1721   pchar[wcharlen] = '\0';
1722 
1723   return pchar;
1724 }
1725 
1726 // MultiByteToWideChar()
1727 // Generic routine for converting ASCII string to Unicode string. Returned the wide char
1728 // string, NULL if fails. The wide char string is allocated, and so should be deleted after use
MultiByteToWideChar(const char * pchar)1729 LPWSTR MultiByteToWideChar(const char * pchar)
1730 {
1731   // Determine the length of string
1732   DWORD charlen = strlen(pchar);
1733 
1734   // Allocate memory including terminating NULLs
1735   LPWSTR pwchar = new WCHAR[charlen+1];
1736 
1737   // Return if fails
1738   if ( !pwchar )  return NULL;
1739 
1740   for (DWORD i = 0; i < charlen; i++ )
1741   {
1742     // Unicode's high byte is set to 0, and low byte same as the string byte
1743     pwchar[i] = pchar[i] | 0x00 << 8;
1744   }
1745 
1746   // Last wide character is set to zero
1747   pwchar[charlen] = 0;
1748 
1749   return pwchar;
1750 }
1751 
1752 // This function calculates the length of Unicode string which is terminated by two consecutive NULLs
1753 // DWORD wcslen(const WCHAR * pwchar)
1754 // {
1755 //  DWORD i= 0;
1756 
1757 //  while (pwchar[i] != 0)
1758 //    i++;
1759 //  return i;
1760 // }
1761 
1762 #endif
1763 
1764 // This function returns the name string of a variant type, return NULL if no match
1765 // given type
1766 const char *
VariantName(VARTYPE vtType)1767 VariantName(VARTYPE vtType)
1768 {
1769   if ( vtType & VT_VECTOR ) return (char *)variantName[73];
1770 
1771   if ( vtType & VT_ARRAY )  return (char *)variantName[74];
1772 
1773   return variantName[vtType];
1774 }
1775 
1776 // SwapBytes()
1777 // Generic routine for switching endian order in an arbitrary data type.
SwapBytes(unsigned char * pbData,short cBytes)1778 void SwapBytes(unsigned char *pbData, short cBytes)
1779 {
1780   unsigned char bSwap;
1781 
1782   if (cBytes < 2)
1783     return;
1784 
1785   for (short ib = cBytes - 1; ib >= 1; ib -= 2)
1786   {
1787     bSwap = pbData[cBytes - 1 - ib];
1788     pbData[cBytes - 1 - ib] = pbData[ib];
1789     pbData[ib] = bSwap;
1790   }
1791 }
1792 
OLEInit()1793 HRESULT OLEInit()
1794 {
1795   HRESULT res = S_OK;
1796 
1797 #ifdef macintosh
1798 #ifndef powerc        // If Code Warrior 68k
1799 
1800   res = InitOleManager(OLEMGR_BIND_NORMAL);
1801   if(res != S_OK)
1802     res = InitOleManager(OLEMGR_BIND_NORMAL);
1803   if (res == S_OK)
1804 #endif // powerc
1805 #endif // macintosh
1806 #ifdef _WINDOWS
1807   res = OleInitialize(NULL);
1808 #endif
1809 // on UNIX, for now, there is no need for OleInitialize
1810 
1811   return res;
1812 }
1813 //This function uninitializes the OLE library
OLEUninit()1814 Boolean OLEUninit()
1815 {
1816 #ifdef macintosh
1817   #ifndef powerc
1818     UninitOleManager();
1819   #endif // powerc
1820 #endif // macintosh
1821 #ifdef _WINDOWS
1822         OleUninitialize();
1823 #endif
1824 
1825   return true;
1826 }
1827