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