Changeset 6711 for trunk/src/ole32/storage32.c
- Timestamp:
- Sep 15, 2001, 11:32:00 AM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/ole32/storage32.c
r6648 r6711 1 /* $Id: storage32.c,v 1.3 2001-09-05 13:17:12 bird Exp $ */2 1 /* 3 2 * Compound Storage (32 bit version) … … 38 37 #define FILE_BEGIN 0 39 38 39 #ifdef __WIN32OS2__ 40 #undef FIXME 41 #undef TRACE 42 #ifdef DEBUG 43 #define TRACE WriteLog("OLE32: %s", __FUNCTION__); WriteLog 44 #define FIXME WriteLog("FIXME OLE32: %s", __FUNCTION__); WriteLog 45 #else 46 #define TRACE 1 ? (void)0 : (void)((int (*)(char *, ...)) NULL) 47 #define FIXME 1 ? (void)0 : (void)((int (*)(char *, ...)) NULL) 48 #endif 49 #endif 50 40 51 41 52 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ … … 48 59 /* OLESTREAM memory structure to use for Get and Put Routines */ 49 60 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 50 typedef struct 61 typedef struct 51 62 { 52 63 DWORD dwOleID; … … 86 97 DWORD dwExtentX; 87 98 DWORD dwExtentY; 88 DWORD dwSize; 99 DWORD dwSize; 89 100 BYTE *pData; 90 101 }OLECONVERT_ISTORAGE_OLEPRES; … … 111 122 INT typeOfRelation); 112 123 113 static HRESULT adjustPropertyChain( 124 static HRESULT adjustPropertyChain( 114 125 StorageImpl *This, 115 126 StgProperty propertyToDelete, … … 138 149 * Declaration of miscellaneous functions... 139 150 */ 140 static HRESULT validateSTGM(DWORD stgmValue); 151 static HRESULT validateSTGM(DWORD stgmValue); 141 152 142 153 static DWORD GetShareModeFromSTGM(DWORD stgm); … … 224 235 * This method implements the common QueryInterface for all IStorage32 225 236 * implementations contained in this file. 226 * 237 * 227 238 * See Windows documentation for more details on IUnknown methods. 228 239 */ … … 238 249 if ( (This==0) || (ppvObject==0) ) 239 250 return E_INVALIDARG; 240 251 241 252 /* 242 253 * Initialize the return parameter. 243 254 */ 244 255 *ppvObject = 0; 245 256 246 257 /* 247 258 * Compare the riid with the interface IDs implemented by this object. 248 259 */ 249 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 260 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 250 261 { 251 262 *ppvObject = (IStorage*)This; 252 263 } 253 else if (memcmp(&IID_IStorage, riid, sizeof(IID_IStorage)) == 0) 264 else if (memcmp(&IID_IStorage, riid, sizeof(IID_IStorage)) == 0) 254 265 { 255 266 *ppvObject = (IStorage*)This; 256 267 } 257 268 258 269 /* 259 270 * Check that we obtained an interface. … … 261 272 if ((*ppvObject)==0) 262 273 return E_NOINTERFACE; 263 274 264 275 /* 265 276 * Query Interface always increases the reference count by one when it is … … 270 281 return S_OK; 271 282 } 272 283 273 284 /************************************************************************ 274 285 * Storage32BaseImpl_AddRef (IUnknown) … … 276 287 * This method implements the common AddRef for all IStorage32 277 288 * implementations contained in this file. 278 * 289 * 279 290 * See Windows documentation for more details on IUnknown methods. 280 291 */ 281 ULONG WINAPI StorageBaseImpl_AddRef( 292 ULONG WINAPI StorageBaseImpl_AddRef( 282 293 IStorage* iface) 283 294 { … … 287 298 return This->ref; 288 299 } 289 300 290 301 /************************************************************************ 291 302 * Storage32BaseImpl_Release (IUnknown) … … 293 304 * This method implements the common Release for all IStorage32 294 305 * implementations contained in this file. 295 * 306 * 296 307 * See Windows documentation for more details on IUnknown methods. 297 308 */ 298 ULONG WINAPI StorageBaseImpl_Release( 309 ULONG WINAPI StorageBaseImpl_Release( 299 310 IStorage* iface) 300 311 { … … 311 322 { 312 323 /* 313 * Since we are using a system of base-classes, we want to call the 314 * destructor of the appropriate derived class. To do this, we are 324 * Since we are using a system of base-classes, we want to call the 325 * destructor of the appropriate derived class. To do this, we are 315 326 * using virtual functions to implement the destructor. 316 327 */ … … 319 330 return 0; 320 331 } 321 332 322 333 return This->ref; 323 334 } … … 330 341 * See Windows documentation for more details on IStorage methods. 331 342 */ 332 HRESULT WINAPI StorageBaseImpl_OpenStream( 343 HRESULT WINAPI StorageBaseImpl_OpenStream( 333 344 IStorage* iface, 334 345 const OLECHAR* pwcsName, /* [string][in] */ 335 346 void* reserved1, /* [unique][in] */ 336 DWORD grfMode, /* [in] */ 337 DWORD reserved2, /* [in] */ 338 IStream** ppstm) /* [out] */ 347 DWORD grfMode, /* [in] */ 348 DWORD reserved2, /* [in] */ 349 IStream** ppstm) /* [out] */ 339 350 { 340 351 ICOM_THIS(StorageBaseImpl,iface); … … 344 355 ULONG foundPropertyIndex; 345 356 346 TRACE("(%p, %s, %p, %lx, %ld, %p)\n", 347 357 TRACE("(%p, %s, %p, %lx, %ld, %p)\n", 358 iface, debugstr_w(pwcsName), reserved1, grfMode, reserved2, ppstm); 348 359 349 360 /* … … 352 363 if ( (pwcsName==NULL) || (ppstm==0) ) 353 364 return E_INVALIDARG; 354 365 355 366 /* 356 367 * Initialize the out parameter 357 368 */ 358 369 *ppstm = 0; 359 370 360 371 /* 361 372 * Validate the STGM flags … … 376 387 */ 377 388 propertyEnumeration = IEnumSTATSTGImpl_Construct( 378 This->ancestorStorage, 389 This->ancestorStorage, 379 390 This->rootPropertySetIndex); 380 391 381 392 /* 382 393 * Search the enumeration for the property with the given name … … 386 397 pwcsName, 387 398 ¤tProperty); 388 399 389 400 /* 390 401 * Delete the property enumeration since we don't need it anymore 391 402 */ 392 403 IEnumSTATSTGImpl_Destroy(propertyEnumeration); 393 404 394 405 /* 395 406 * If it was found, construct the stream object and return a pointer to it. 396 407 */ 397 if ( (foundPropertyIndex!=PROPERTY_NULL) && 408 if ( (foundPropertyIndex!=PROPERTY_NULL) && 398 409 (currentProperty.propertyType==PROPTYPE_STREAM) ) 399 410 { 400 411 newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex); 401 412 402 413 if (newStream!=0) 403 414 { … … 406 417 407 418 /* 408 * Since we are returning a pointer to the interface, we have to 419 * Since we are returning a pointer to the interface, we have to 409 420 * nail down the reference. 410 421 */ 411 422 StgStreamImpl_AddRef(*ppstm); 412 423 413 424 return S_OK; 414 425 } 415 426 416 427 return E_OUTOFMEMORY; 417 428 } 418 429 419 430 return STG_E_FILENOTFOUND; 420 431 } … … 424 435 * 425 436 * This method will open a new storage object from the current storage. 426 * 437 * 427 438 * See Windows documentation for more details on IStorage methods. 428 */ 429 HRESULT WINAPI StorageBaseImpl_OpenStorage( 439 */ 440 HRESULT WINAPI StorageBaseImpl_OpenStorage( 430 441 IStorage* iface, 431 const OLECHAR* pwcsName, /* [string][unique][in] */ 432 IStorage* pstgPriority, /* [unique][in] */ 433 DWORD grfMode, /* [in] */ 434 SNB snbExclude, /* [unique][in] */ 435 DWORD reserved, /* [in] */ 436 IStorage** ppstg) /* [out] */ 442 const OLECHAR* pwcsName, /* [string][unique][in] */ 443 IStorage* pstgPriority, /* [unique][in] */ 444 DWORD grfMode, /* [in] */ 445 SNB snbExclude, /* [unique][in] */ 446 DWORD reserved, /* [in] */ 447 IStorage** ppstg) /* [out] */ 437 448 { 438 449 ICOM_THIS(StorageBaseImpl,iface); … … 442 453 ULONG foundPropertyIndex; 443 454 444 TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n", 445 iface, debugstr_w(pwcsName), pstgPriority, 446 447 455 TRACE("(%p, %s, %p, %lx, %p, %ld, %p)\n", 456 iface, debugstr_w(pwcsName), pstgPriority, 457 grfMode, snbExclude, reserved, ppstg); 458 448 459 /* 449 460 * Perform a sanity check on the parameters. … … 451 462 if ( (This==0) || (pwcsName==NULL) || (ppstg==0) ) 452 463 return E_INVALIDARG; 453 464 454 465 /* 455 466 * Validate the STGM flags … … 461 472 * As documented. 462 473 */ 463 if ( !(grfMode & STGM_SHARE_EXCLUSIVE) || 474 if ( !(grfMode & STGM_SHARE_EXCLUSIVE) || 464 475 (grfMode & STGM_DELETEONRELEASE) || 465 476 (grfMode & STGM_PRIORITY) ) … … 470 481 */ 471 482 *ppstg = 0; 472 483 473 484 /* 474 485 * Create a property enumeration to search the properties 475 486 */ 476 487 propertyEnumeration = IEnumSTATSTGImpl_Construct( 477 This->ancestorStorage, 488 This->ancestorStorage, 478 489 This->rootPropertySetIndex); 479 490 480 491 /* 481 492 * Search the enumeration for the property with the given name … … 485 496 pwcsName, 486 497 ¤tProperty); 487 498 488 499 /* 489 500 * Delete the property enumeration since we don't need it anymore 490 501 */ 491 502 IEnumSTATSTGImpl_Destroy(propertyEnumeration); 492 503 493 504 /* 494 505 * If it was found, construct the stream object and return a pointer to it. 495 506 */ 496 if ( (foundPropertyIndex!=PROPERTY_NULL) && 507 if ( (foundPropertyIndex!=PROPERTY_NULL) && 497 508 (currentProperty.propertyType==PROPTYPE_STORAGE) ) 498 509 { … … 503 514 This->ancestorStorage, 504 515 foundPropertyIndex); 505 516 506 517 if (newStorage != 0) 507 518 { … … 509 520 510 521 /* 511 * Since we are returning a pointer to the interface, 522 * Since we are returning a pointer to the interface, 512 523 * we have to nail down the reference. 513 524 */ 514 525 StorageBaseImpl_AddRef(*ppstg); 515 526 516 527 return S_OK; 517 528 } 518 529 519 530 return STG_E_INSUFFICIENTMEMORY; 520 531 } 521 532 522 533 return STG_E_FILENOTFOUND; 523 534 } … … 526 537 * Storage32BaseImpl_EnumElements (IStorage) 527 538 * 528 * This method will create an enumerator object that can be used to 539 * This method will create an enumerator object that can be used to 529 540 * retrieve informatino about all the properties in the storage object. 530 * 541 * 531 542 * See Windows documentation for more details on IStorage methods. 532 */ 533 HRESULT WINAPI StorageBaseImpl_EnumElements( 543 */ 544 HRESULT WINAPI StorageBaseImpl_EnumElements( 534 545 IStorage* iface, 535 DWORD reserved1, /* [in] */ 536 void* reserved2, /* [size_is][unique][in] */ 537 DWORD reserved3, /* [in] */ 538 IEnumSTATSTG** ppenum) /* [out] */ 546 DWORD reserved1, /* [in] */ 547 void* reserved2, /* [size_is][unique][in] */ 548 DWORD reserved3, /* [in] */ 549 IEnumSTATSTG** ppenum) /* [out] */ 539 550 { 540 551 ICOM_THIS(StorageBaseImpl,iface); 541 552 IEnumSTATSTGImpl* newEnum; 542 553 543 TRACE("(%p, %ld, %p, %ld, %p)\n", 544 554 TRACE("(%p, %ld, %p, %ld, %p)\n", 555 iface, reserved1, reserved2, reserved3, ppenum); 545 556 546 557 /* … … 549 560 if ( (This==0) || (ppenum==0)) 550 561 return E_INVALIDARG; 551 562 552 563 /* 553 564 * Construct the enumerator. … … 566 577 */ 567 578 IEnumSTATSTGImpl_AddRef(*ppenum); 568 579 569 580 return S_OK; 570 581 } … … 577 588 * 578 589 * This method will retrieve information about this storage object. 579 * 590 * 580 591 * See Windows documentation for more details on IStorage methods. 581 */ 582 HRESULT WINAPI StorageBaseImpl_Stat( 592 */ 593 HRESULT WINAPI StorageBaseImpl_Stat( 583 594 IStorage* iface, 584 STATSTG* pstatstg, /* [out] */ 585 DWORD grfStatFlag) /* [in] */ 595 STATSTG* pstatstg, /* [out] */ 596 DWORD grfStatFlag) /* [in] */ 586 597 { 587 598 ICOM_THIS(StorageBaseImpl,iface); … … 589 600 BOOL readSuccessful; 590 601 591 TRACE("(%p, %p, %lx)\n", 592 602 TRACE("(%p, %p, %lx)\n", 603 iface, pstatstg, grfStatFlag); 593 604 594 605 /* … … 609 620 { 610 621 StorageUtl_CopyPropertyToSTATSTG( 611 pstatstg, 612 &curProperty, 622 pstatstg, 623 &curProperty, 613 624 grfStatFlag); 614 625 615 626 return S_OK; 616 627 } 617 628 618 629 return E_FAIL; 619 630 } … … 622 633 * Storage32BaseImpl_RenameElement (IStorage) 623 634 * 624 * This method will rename the specified element. 635 * This method will rename the specified element. 625 636 * 626 637 * See Windows documentation for more details on IStorage methods. 627 * 628 * Implementation notes: The method used to rename consists of creating a clone 629 * of the deleted StgProperty object setting it with the new name and to 638 * 639 * Implementation notes: The method used to rename consists of creating a clone 640 * of the deleted StgProperty object setting it with the new name and to 630 641 * perform a DestroyElement of the old StgProperty. 631 642 */ … … 640 651 ULONG foundPropertyIndex; 641 652 642 TRACE("(%p, %s, %s)\n", 643 653 TRACE("(%p, %s, %s)\n", 654 iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName)); 644 655 645 656 /* … … 687 698 * Setup a new property for the renamed property 688 699 */ 689 renamedProperty.sizeOfNameString = 700 renamedProperty.sizeOfNameString = 690 701 ( lstrlenW(pwcsNewName)+1 ) * sizeof(WCHAR); 691 702 692 703 if (renamedProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN) 693 704 return STG_E_INVALIDNAME; 694 705 695 706 strcpyW(renamedProperty.name, pwcsNewName); 696 707 697 708 renamedProperty.propertyType = currentProperty.propertyType; 698 709 renamedProperty.startingBlock = currentProperty.startingBlock; 699 710 renamedProperty.size.s.LowPart = currentProperty.size.s.LowPart; 700 711 renamedProperty.size.s.HighPart = currentProperty.size.s.HighPart; 701 712 702 713 renamedProperty.previousProperty = PROPERTY_NULL; 703 714 renamedProperty.nextProperty = PROPERTY_NULL; 704 715 705 716 /* 706 717 * Bring the dirProperty link in case it is a storage and in which … … 708 719 */ 709 720 renamedProperty.dirProperty = currentProperty.dirProperty; 710 711 /* call CoFileTime to get the current time 721 722 /* call CoFileTime to get the current time 712 723 renamedProperty.timeStampS1 713 724 renamedProperty.timeStampD1 714 725 renamedProperty.timeStampS2 715 726 renamedProperty.timeStampD2 716 renamedProperty.propertyUniqueID 727 renamedProperty.propertyUniqueID 717 728 */ 718 719 /* 729 730 /* 720 731 * Obtain a free property in the property chain 721 732 */ 722 733 renamedPropertyIndex = getFreeProperty(This->ancestorStorage); 723 734 724 735 /* 725 736 * Save the new property into the new property spot 726 */ 737 */ 727 738 StorageImpl_WriteProperty( 728 739 This->ancestorStorage, 729 renamedPropertyIndex, 740 renamedPropertyIndex, 730 741 &renamedProperty); 731 732 /* 742 743 /* 733 744 * Find a spot in the property chain for our newly created property. 734 745 */ 735 746 updatePropertyChain( 736 747 (StorageImpl*)This, 737 renamedPropertyIndex, 748 renamedPropertyIndex, 738 749 renamedProperty); 739 750 740 751 /* 741 * At this point the renamed property has been inserted in the tree, 742 * now, before to Destroy the old property we must zeroed it's dirProperty 743 * otherwise the DestroyProperty below will zap it all and we do not want 752 * At this point the renamed property has been inserted in the tree, 753 * now, before to Destroy the old property we must zeroed it's dirProperty 754 * otherwise the DestroyProperty below will zap it all and we do not want 744 755 * this to happen. 745 756 * Also, we fake that the old property is a storage so the DestroyProperty 746 757 * will not do a SetSize(0) on the stream data. 747 * 758 * 748 759 * This means that we need to tweek the StgProperty if it is a stream or a 749 760 * non empty storage. … … 757 768 StorageImpl_WriteProperty( 758 769 This->ancestorStorage, 759 foundPropertyIndex, 770 foundPropertyIndex, 760 771 ¤tProperty); 761 772 762 /* 763 * Invoke Destroy to get rid of the ole property and automatically redo 764 * the linking of it's previous and next members... 765 */ 766 StorageImpl_DestroyElement((IStorage*)This->ancestorStorage, pwcsOldName); 773 /* 774 * Invoke Destroy to get rid of the ole property and automatically redo 775 * the linking of it's previous and next members... 776 */ 777 StorageImpl_DestroyElement((IStorage*)This->ancestorStorage, pwcsOldName); 767 778 768 779 } … … 781 792 * Storage32BaseImpl_CreateStream (IStorage) 782 793 * 783 * This method will create a stream object within this storage 794 * This method will create a stream object within this storage 784 795 * 785 796 * See Windows documentation for more details on IStorage methods. … … 799 810 ULONG foundPropertyIndex, newPropertyIndex; 800 811 801 TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", 802 iface, debugstr_w(pwcsName), grfMode, 803 812 TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", 813 iface, debugstr_w(pwcsName), grfMode, 814 reserved1, reserved2, ppstm); 804 815 805 816 /* … … 846 857 { 847 858 /* 848 * An element with this name already exists 859 * An element with this name already exists 849 860 */ 850 861 if (grfMode & STGM_CREATE) 851 862 { 852 IStorage_DestroyElement(iface, pwcsName); 853 } 854 else 863 IStorage_DestroyElement(iface, pwcsName); 864 } 865 else 855 866 return STG_E_FILEALREADYEXISTS; 856 867 } 857 868 858 /* 859 * memset the empty property 869 /* 870 * memset the empty property 860 871 */ 861 872 memset(&newStreamProperty, 0, sizeof(StgProperty)); … … 878 889 newStreamProperty.dirProperty = PROPERTY_NULL; 879 890 880 /* call CoFileTime to get the current time 891 /* call CoFileTime to get the current time 881 892 newStreamProperty.timeStampS1 882 893 newStreamProperty.timeStampD1 … … 888 899 889 900 /* 890 * Get a free property or create a new one 901 * Get a free property or create a new one 891 902 */ 892 903 newPropertyIndex = getFreeProperty(This->ancestorStorage); … … 894 905 /* 895 906 * Save the new property into the new property spot 896 */ 907 */ 897 908 StorageImpl_WriteProperty( 898 909 This->ancestorStorage, 899 newPropertyIndex, 910 newPropertyIndex, 900 911 &newStreamProperty); 901 912 902 /* 913 /* 903 914 * Find a spot in the property chain for our newly created property. 904 915 */ 905 916 updatePropertyChain( 906 917 (StorageImpl*)This, 907 newPropertyIndex, 918 newPropertyIndex, 908 919 newStreamProperty); 909 920 910 /* 921 /* 911 922 * Open the stream to return it. 912 923 */ … … 934 945 * Storage32BaseImpl_SetClass (IStorage) 935 946 * 936 * This method will write the specified CLSID in the property of this 947 * This method will write the specified CLSID in the property of this 937 948 * storage. 938 949 * … … 949 960 950 961 TRACE("(%p, %p)\n", iface, clsid); 951 962 952 963 success = StorageImpl_ReadProperty(This->ancestorStorage, 953 964 This->rootPropertySetIndex, … … 970 981 ** Storage32Impl implementation 971 982 */ 972 983 973 984 /************************************************************************ 974 985 * Storage32Impl_CreateStorage (IStorage) … … 978 989 * See Windows documentation for more details on IStorage methods. 979 990 */ 980 HRESULT WINAPI StorageImpl_CreateStorage( 991 HRESULT WINAPI StorageImpl_CreateStorage( 981 992 IStorage* iface, 982 const OLECHAR *pwcsName, /* [string][in] */ 983 DWORD grfMode, /* [in] */ 984 DWORD reserved1, /* [in] */ 985 DWORD reserved2, /* [in] */ 986 IStorage **ppstg) /* [out] */ 993 const OLECHAR *pwcsName, /* [string][in] */ 994 DWORD grfMode, /* [in] */ 995 DWORD reserved1, /* [in] */ 996 DWORD reserved2, /* [in] */ 997 IStorage **ppstg) /* [out] */ 987 998 { 988 999 StorageImpl* const This=(StorageImpl*)iface; … … 995 1006 HRESULT hr; 996 1007 997 TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", 998 iface, debugstr_w(pwcsName), grfMode, 999 1000 1008 TRACE("(%p, %s, %lx, %ld, %ld, %p)\n", 1009 iface, debugstr_w(pwcsName), grfMode, 1010 reserved1, reserved2, ppstg); 1011 1001 1012 /* 1002 1013 * Validate parameters … … 1034 1045 { 1035 1046 /* 1036 * An element with this name already exists 1047 * An element with this name already exists 1037 1048 */ 1038 1049 if (grfMode & STGM_CREATE) 1039 IStorage_DestroyElement(iface, pwcsName); 1040 else 1050 IStorage_DestroyElement(iface, pwcsName); 1051 else 1041 1052 return STG_E_FILEALREADYEXISTS; 1042 1053 } 1043 1054 1044 /* 1045 * memset the empty property 1055 /* 1056 * memset the empty property 1046 1057 */ 1047 1058 memset(&newProperty, 0, sizeof(StgProperty)); … … 1063 1074 newProperty.dirProperty = PROPERTY_NULL; 1064 1075 1065 /* call CoFileTime to get the current time 1076 /* call CoFileTime to get the current time 1066 1077 newProperty.timeStampS1 1067 1078 newProperty.timeStampD1 … … 1072 1083 /* newStorageProperty.propertyUniqueID */ 1073 1084 1074 /* 1085 /* 1075 1086 * Obtain a free property in the property chain 1076 1087 */ … … 1079 1090 /* 1080 1091 * Save the new property into the new property spot 1081 */ 1092 */ 1082 1093 StorageImpl_WriteProperty( 1083 1094 This->ancestorStorage, 1084 newPropertyIndex, 1095 newPropertyIndex, 1085 1096 &newProperty); 1086 1097 1087 /* 1098 /* 1088 1099 * Find a spot in the property chain for our newly created property. 1089 1100 */ 1090 1101 updatePropertyChain( 1091 1102 This, 1092 newPropertyIndex, 1103 newPropertyIndex, 1093 1104 newProperty); 1094 1105 1095 /* 1106 /* 1096 1107 * Open it to get a pointer to return. 1097 1108 */ … … 1110 1121 } 1111 1122 1112 1123 1113 1124 return S_OK; 1114 1125 } … … 1141 1152 if (currentProperty.sizeOfNameString == 0) 1142 1153 { 1143 /* 1154 /* 1144 1155 * The property existis and is available, we found it. 1145 1156 */ … … 1158 1169 } while (newPropertyIndex == PROPERTY_NULL); 1159 1170 1160 /* 1161 * grow the property chain 1171 /* 1172 * grow the property chain 1162 1173 */ 1163 1174 if (! readSuccessful) … … 1169 1180 ULONG blockCount = 0; 1170 1181 1171 /* 1172 * obtain the new count of property blocks 1182 /* 1183 * obtain the new count of property blocks 1173 1184 */ 1174 1185 blockCount = BlockChainStream_GetCount( 1175 1186 storage->ancestorStorage->rootBlockChain)+1; 1176 1187 1177 /* 1178 * initialize the size used by the property stream 1188 /* 1189 * initialize the size used by the property stream 1179 1190 */ 1180 1191 newSize.s.HighPart = 0; 1181 1192 newSize.s.LowPart = storage->bigBlockSize * blockCount; 1182 1193 1183 /* 1184 * add a property block to the property chain 1194 /* 1195 * add a property block to the property chain 1185 1196 */ 1186 1197 BlockChainStream_SetSize(storage->ancestorStorage->rootBlockChain, newSize); 1187 1198 1188 /* 1189 * memset the empty property in order to initialize the unused newly 1199 /* 1200 * memset the empty property in order to initialize the unused newly 1190 1201 * created property 1191 1202 */ 1192 1203 memset(&emptyProperty, 0, sizeof(StgProperty)); 1193 1204 1194 /* 1205 /* 1195 1206 * initialize them 1196 1207 */ 1197 lastProperty = storage->bigBlockSize / PROPSET_BLOCK_SIZE * blockCount; 1198 1208 lastProperty = storage->bigBlockSize / PROPSET_BLOCK_SIZE * blockCount; 1209 1199 1210 for( 1200 1211 propertyIndex = newPropertyIndex; … … 1204 1215 StorageImpl_WriteProperty( 1205 1216 storage->ancestorStorage, 1206 propertyIndex, 1217 propertyIndex, 1207 1218 &emptyProperty); 1208 1219 } … … 1216 1227 * Internal Method 1217 1228 * 1218 * Case insensitive comparaison of StgProperty.name by first considering 1229 * Case insensitive comparaison of StgProperty.name by first considering 1219 1230 * their size. 1220 1231 * … … 1229 1240 LONG diff = lstrlenW(newProperty) - lstrlenW(currentProperty); 1230 1241 1231 if (diff == 0) 1232 { 1233 /* 1242 if (diff == 0) 1243 { 1244 /* 1234 1245 * We compare the string themselves only when they are of the same lenght 1235 1246 */ … … 1237 1248 } 1238 1249 1239 return diff; 1250 return diff; 1240 1251 } 1241 1252 … … 1249 1260 StorageImpl *storage, 1250 1261 ULONG newPropertyIndex, 1251 StgProperty newProperty) 1262 StgProperty newProperty) 1252 1263 { 1253 1264 StgProperty currentProperty; … … 1262 1273 if (currentProperty.dirProperty != PROPERTY_NULL) 1263 1274 { 1264 /* 1275 /* 1265 1276 * The root storage contains some element, therefore, start the research 1266 1277 * for the appropriate location. … … 1275 1286 1276 1287 /* 1277 * Read 1288 * Read 1278 1289 */ 1279 1290 StorageImpl_ReadProperty(storage->ancestorStorage, … … 1288 1299 { 1289 1300 LONG diff = propertyNameCmp( newProperty.name, currentProperty.name); 1290 1301 1291 1302 if (diff < 0) 1292 1303 { … … 1327 1338 else 1328 1339 { 1329 1330 1331 1332 1333 1340 /* 1341 * Trying to insert an item with the same name in the 1342 * subtree structure. 1343 */ 1344 assert(FALSE); 1334 1345 } 1335 1346 … … 1340 1351 else 1341 1352 { 1342 /* 1353 /* 1343 1354 * The root storage is empty, link the new property to it's dir property 1344 1355 */ … … 1350 1361 } 1351 1362 1352 1363 1353 1364 /************************************************************************* 1354 1365 * CopyTo (IStorage) 1355 1366 */ 1356 HRESULT WINAPI StorageImpl_CopyTo( 1367 HRESULT WINAPI StorageImpl_CopyTo( 1357 1368 IStorage* iface, 1358 DWORD ciidExclude, /* [in] */ 1359 const IID* rgiidExclude, /* [size_is][unique][in] */ 1360 SNB snbExclude, /* [unique][in] */ 1361 IStorage* pstgDest) /* [unique][in] */ 1369 DWORD ciidExclude, /* [in] */ 1370 const IID* rgiidExclude, /* [size_is][unique][in] */ 1371 SNB snbExclude, /* [unique][in] */ 1372 IStorage* pstgDest) /* [unique][in] */ 1362 1373 { 1363 1374 IEnumSTATSTG *elements = 0; … … 1370 1381 FIXME("Exclude option not implemented\n"); 1371 1382 1372 TRACE("(%p, %ld, %p, %p, %p)\n", 1373 iface, ciidExclude, rgiidExclude, 1374 1383 TRACE("(%p, %ld, %p, %p, %p)\n", 1384 iface, ciidExclude, rgiidExclude, 1385 snbExclude, pstgDest); 1375 1386 1376 1387 /* … … 1380 1391 return STG_E_INVALIDPOINTER; 1381 1392 1382 /* 1393 /* 1383 1394 * Enumerate the elements 1384 1395 */ … … 1393 1404 IStorage_Stat( iface, &curElement, STATFLAG_NONAME); 1394 1405 IStorage_SetClass( pstgDest, &curElement.clsid ); 1395 1406 1396 1407 do 1397 1408 { … … 1413 1424 */ 1414 1425 hr = IStorage_OpenStorage( iface, curElement.pwcsName, NULL, 1415 1416 1426 STGM_READ|STGM_SHARE_EXCLUSIVE, 1427 NULL, 0, &pstgChild ); 1417 1428 1418 1429 if (hr != S_OK) … … 1425 1436 if (pstgChild == pstgDest) 1426 1437 { 1427 1428 1429 1438 IEnumSTATSTG_Release(elements); 1439 1440 return STG_E_ACCESSDENIED; 1430 1441 } 1431 1442 1432 1443 /* 1433 1444 * create a new storage in destination storage … … 1435 1446 hr = IStorage_CreateStorage( pstgDest, curElement.pwcsName, 1436 1447 STGM_FAILIFTHERE|STGM_WRITE|STGM_SHARE_EXCLUSIVE, 1437 1448 0, 0, 1438 1449 &pstgTmp ); 1439 1450 /* … … 1446 1457 NULL, 0, &pstgTmp ); 1447 1458 } 1448 1459 1449 1460 if (hr != S_OK) 1450 1461 break; 1451 1462 1452 1463 1453 1464 /* 1454 1465 * do the copy recursively … … 1456 1467 hr = IStorage_CopyTo( pstgChild, ciidExclude, rgiidExclude, 1457 1468 snbExclude, pstgTmp ); 1458 1469 1459 1470 IStorage_Release( pstgTmp ); 1460 1471 IStorage_Release( pstgChild ); … … 1477 1488 */ 1478 1489 hr = IStorage_OpenStream( iface, curElement.pwcsName, NULL, 1479 1480 1490 STGM_READ|STGM_SHARE_EXCLUSIVE, 1491 0, &pstrChild ); 1481 1492 1482 1493 if (hr != S_OK) … … 1492 1503 */ 1493 1504 IStream_SetSize(pstrTmp, strStat.cbSize); 1494 1505 1495 1506 /* 1496 1507 * do the copy … … 1498 1509 hr = IStream_CopyTo( pstrChild, pstrTmp, strStat.cbSize, 1499 1510 NULL, NULL ); 1500 1511 1501 1512 IStream_Release( pstrTmp ); 1502 1513 IStream_Release( pstrChild ); … … 1513 1524 */ 1514 1525 IEnumSTATSTG_Release(elements); 1515 1526 1516 1527 return hr; 1517 1528 } 1518 1529 1519 1530 /************************************************************************* 1520 1531 * MoveElementTo (IStorage) 1521 1532 */ 1522 HRESULT WINAPI StorageImpl_MoveElementTo( 1533 HRESULT WINAPI StorageImpl_MoveElementTo( 1523 1534 IStorage* iface, 1524 const OLECHAR *pwcsName, /* [string][in] */ 1525 IStorage *pstgDest, /* [unique][in] */ 1526 const OLECHAR *pwcsNewName,/* [string][in] */ 1527 DWORD grfFlags) /* [in] */ 1535 const OLECHAR *pwcsName, /* [string][in] */ 1536 IStorage *pstgDest, /* [unique][in] */ 1537 const OLECHAR *pwcsNewName,/* [string][in] */ 1538 DWORD grfFlags) /* [in] */ 1528 1539 { 1529 1540 FIXME("not implemented!\n"); 1530 1541 return E_NOTIMPL; 1531 1542 } 1532 1543 1533 1544 /************************************************************************* 1534 1545 * Commit (IStorage) 1535 1546 */ 1536 HRESULT WINAPI StorageImpl_Commit( 1547 HRESULT WINAPI StorageImpl_Commit( 1537 1548 IStorage* iface, 1538 DWORD grfCommitFlags)/* [in] */ 1549 DWORD grfCommitFlags)/* [in] */ 1539 1550 { 1540 1551 FIXME("(%ld): stub!\n", grfCommitFlags); 1541 1552 return S_OK; 1542 1553 } 1543 1554 1544 1555 /************************************************************************* 1545 1556 * Revert (IStorage) 1546 1557 */ 1547 HRESULT WINAPI StorageImpl_Revert( 1558 HRESULT WINAPI StorageImpl_Revert( 1548 1559 IStorage* iface) 1549 1560 { … … 1555 1566 * DestroyElement (IStorage) 1556 1567 * 1557 * Stategy: This implementation is build this way for simplicity not for speed. 1568 * Stategy: This implementation is build this way for simplicity not for speed. 1558 1569 * I always delete the top most element of the enumeration and adjust 1559 * the deleted element pointer all the time. This takes longer to 1560 * do but allow to reinvoke DestroyElement whenever we encounter a 1570 * the deleted element pointer all the time. This takes longer to 1571 * do but allow to reinvoke DestroyElement whenever we encounter a 1561 1572 * storage object. The optimisation reside in the usage of another 1562 * enumeration stategy that would give all the leaves of a storage 1573 * enumeration stategy that would give all the leaves of a storage 1563 1574 * first. (postfix order) 1564 1575 */ 1565 HRESULT WINAPI StorageImpl_DestroyElement( 1576 HRESULT WINAPI StorageImpl_DestroyElement( 1566 1577 IStorage* iface, 1567 const OLECHAR *pwcsName)/* [string][in] */ 1578 const OLECHAR *pwcsName)/* [string][in] */ 1568 1579 { 1569 1580 StorageImpl* const This=(StorageImpl*)iface; … … 1578 1589 ULONG parentPropertyId; 1579 1590 1580 TRACE("(%p, %s)\n", 1581 1591 TRACE("(%p, %s)\n", 1592 iface, debugstr_w(pwcsName)); 1582 1593 1583 1594 /* 1584 1595 * Perform a sanity check on the parameters. 1585 1596 */ 1586 if (pwcsName==NULL) 1597 if (pwcsName==NULL) 1587 1598 return STG_E_INVALIDPOINTER; 1588 1599 1589 1600 /* 1590 1601 * Create a property enumeration to search the property with the given name 1591 1602 */ 1592 1603 propertyEnumeration = IEnumSTATSTGImpl_Construct( 1593 This->ancestorStorage, 1604 This->ancestorStorage, 1594 1605 This->rootPropertySetIndex); 1595 1606 1596 1607 foundPropertyIndexToDelete = IEnumSTATSTGImpl_FindProperty( 1597 1608 propertyEnumeration, … … 1601 1612 IEnumSTATSTGImpl_Destroy(propertyEnumeration); 1602 1613 1603 if ( foundPropertyIndexToDelete == PROPERTY_NULL ) 1614 if ( foundPropertyIndexToDelete == PROPERTY_NULL ) 1604 1615 { 1605 1616 return STG_E_FILENOTFOUND; 1606 1617 } 1607 1618 1608 /* 1609 * Find the parent property of the property to delete (the one that 1610 * link to it). If This->dirProperty == foundPropertyIndexToDelete, 1619 /* 1620 * Find the parent property of the property to delete (the one that 1621 * link to it). If This->dirProperty == foundPropertyIndexToDelete, 1611 1622 * the parent is This. Otherwise, the parent is one of it's sibling... 1612 1623 */ 1613 1624 1614 /* 1625 /* 1615 1626 * First, read This's StgProperty.. 1616 1627 */ 1617 res = StorageImpl_ReadProperty( 1628 res = StorageImpl_ReadProperty( 1618 1629 This->ancestorStorage, 1619 1630 This->rootPropertySetIndex, … … 1622 1633 assert(res==TRUE); 1623 1634 1624 /* 1635 /* 1625 1636 * Second, check to see if by any chance the actual storage (This) is not 1626 1637 * the parent of the property to delete... We never know... … … 1628 1639 if ( parentProperty.dirProperty == foundPropertyIndexToDelete ) 1629 1640 { 1630 /* 1641 /* 1631 1642 * Set data as it would have been done in the else part... 1632 1643 */ … … 1634 1645 parentPropertyId = This->rootPropertySetIndex; 1635 1646 } 1636 else 1637 { 1638 /* 1639 * Create a property enumeration to search the parent properties, and 1647 else 1648 { 1649 /* 1650 * Create a property enumeration to search the parent properties, and 1640 1651 * delete it once done. 1641 1652 */ … … 1643 1654 1644 1655 propertyEnumeration2 = IEnumSTATSTGImpl_Construct( 1645 This->ancestorStorage, 1656 This->ancestorStorage, 1646 1657 This->rootPropertySetIndex); 1647 1658 1648 1659 typeOfRelation = IEnumSTATSTGImpl_FindParentProperty( 1649 1660 propertyEnumeration2, … … 1655 1666 } 1656 1667 1657 if ( propertyToDelete.propertyType == PROPTYPE_STORAGE ) 1668 if ( propertyToDelete.propertyType == PROPTYPE_STORAGE ) 1658 1669 { 1659 1670 hr = deleteStorageProperty( 1660 This, 1671 This, 1661 1672 foundPropertyIndexToDelete, 1662 1673 propertyToDelete); 1663 } 1674 } 1664 1675 else if ( propertyToDelete.propertyType == PROPTYPE_STREAM ) 1665 1676 { 1666 1677 hr = deleteStreamProperty( 1667 This, 1678 This, 1668 1679 foundPropertyIndexToDelete, 1669 1680 propertyToDelete); 1670 1681 } 1671 1682 1672 if (hr!=S_OK) 1683 if (hr!=S_OK) 1673 1684 return hr; 1674 1685 … … 1678 1689 hr = adjustPropertyChain( 1679 1690 This, 1680 propertyToDelete, 1691 propertyToDelete, 1681 1692 parentProperty, 1682 1693 parentPropertyId, … … 1722 1733 } 1723 1734 1724 /* 1735 /* 1725 1736 * Enumerate the elements 1726 1737 */ … … 1736 1747 { 1737 1748 destroyHr = StorageImpl_DestroyElement( 1738 (IStorage*)childStorage, 1749 (IStorage*)childStorage, 1739 1750 (OLECHAR*)currentElement.pwcsName); 1740 1751 … … 1761 1772 IStorage_Release(childStorage); 1762 1773 IEnumSTATSTG_Release(elements); 1763 1774 1764 1775 return destroyHr; 1765 1776 } … … 1791 1802 0, 1792 1803 &pis); 1793 1804 1794 1805 if (hr!=S_OK) 1795 1806 { … … 1797 1808 } 1798 1809 1799 /* 1800 * Zap the stream 1801 */ 1802 hr = IStream_SetSize(pis, size); 1810 /* 1811 * Zap the stream 1812 */ 1813 hr = IStream_SetSize(pis, size); 1803 1814 1804 1815 if(hr != S_OK) … … 1812 1823 IStream_Release(pis); 1813 1824 1814 /* 1825 /* 1815 1826 * Invalidate the property by zeroing it's name member. 1816 1827 */ 1817 1828 propertyToDelete.sizeOfNameString = 0; 1818 1829 1819 /* 1830 /* 1820 1831 * Here we should re-read the property so we get the updated pointer 1821 1832 * but since we are here to zap it, I don't do it... 1822 1833 */ 1823 1834 StorageImpl_WriteProperty( 1824 parentStorage->ancestorStorage, 1835 parentStorage->ancestorStorage, 1825 1836 indexOfPropertyToDelete, 1826 1837 &propertyToDelete); … … 1851 1862 res = StorageImpl_ReadProperty( 1852 1863 storage->ancestorStorage, 1853 storePropertyIndex, 1864 storePropertyIndex, 1854 1865 &storeProperty); 1855 1866 … … 1865 1876 return findPlaceholder( 1866 1877 storage, 1867 propertyIndexToStore, 1878 propertyIndexToStore, 1868 1879 storeProperty.previousProperty, 1869 1880 typeOfRelation); … … 1880 1891 return findPlaceholder( 1881 1892 storage, 1882 propertyIndexToStore, 1893 propertyIndexToStore, 1883 1894 storeProperty.nextProperty, 1884 1895 typeOfRelation); … … 1888 1899 storeProperty.nextProperty = propertyIndexToStore; 1889 1900 } 1890 } 1901 } 1891 1902 else if (typeOfRelation == PROPERTY_RELATION_DIR) 1892 1903 { … … 1895 1906 return findPlaceholder( 1896 1907 storage, 1897 propertyIndexToStore, 1908 propertyIndexToStore, 1898 1909 storeProperty.dirProperty, 1899 1910 typeOfRelation); … … 1907 1918 hr = StorageImpl_WriteProperty( 1908 1919 storage->ancestorStorage, 1909 storePropertyIndex, 1920 storePropertyIndex, 1910 1921 &storeProperty); 1911 1922 … … 1922 1933 * Internal Method 1923 1934 * 1924 * This method takes the previous and the next property link of a property 1935 * This method takes the previous and the next property link of a property 1925 1936 * to be deleted and find them a place in the Storage. 1926 1937 */ 1927 static HRESULT adjustPropertyChain( 1938 static HRESULT adjustPropertyChain( 1928 1939 StorageImpl *This, 1929 1940 StgProperty propertyToDelete, … … 1939 1950 HRESULT hr = S_OK; 1940 1951 BOOL res = TRUE; 1941 1942 if (typeOfRelation == PROPERTY_RELATION_PREVIOUS) 1943 { 1944 if (propertyToDelete.previousProperty != PROPERTY_NULL) 1945 { 1946 /* 1952 1953 if (typeOfRelation == PROPERTY_RELATION_PREVIOUS) 1954 { 1955 if (propertyToDelete.previousProperty != PROPERTY_NULL) 1956 { 1957 /* 1947 1958 * Set the parent previous to the property to delete previous 1948 1959 */ 1949 1960 newLinkProperty = propertyToDelete.previousProperty; 1950 1961 1951 if (propertyToDelete.nextProperty != PROPERTY_NULL) 1962 if (propertyToDelete.nextProperty != PROPERTY_NULL) 1952 1963 { 1953 1964 /* 1954 * We also need to find a storage for the other link, setup variables 1965 * We also need to find a storage for the other link, setup variables 1955 1966 * to do this at the end... 1956 */ 1967 */ 1957 1968 needToFindAPlaceholder = TRUE; 1958 1969 storeNode = propertyToDelete.previousProperty; … … 1960 1971 relationType = PROPERTY_RELATION_NEXT; 1961 1972 } 1962 } 1963 else if (propertyToDelete.nextProperty != PROPERTY_NULL) 1964 { 1965 /* 1973 } 1974 else if (propertyToDelete.nextProperty != PROPERTY_NULL) 1975 { 1976 /* 1966 1977 * Set the parent previous to the property to delete next 1967 1978 */ 1968 1979 newLinkProperty = propertyToDelete.nextProperty; 1969 1980 } 1970 1971 /* 1981 1982 /* 1972 1983 * Link it for real... 1973 */ 1984 */ 1974 1985 parentProperty.previousProperty = newLinkProperty; 1975 1976 } 1977 else if (typeOfRelation == PROPERTY_RELATION_NEXT) 1978 { 1979 if (propertyToDelete.previousProperty != PROPERTY_NULL) 1980 { 1981 /* 1986 1987 } 1988 else if (typeOfRelation == PROPERTY_RELATION_NEXT) 1989 { 1990 if (propertyToDelete.previousProperty != PROPERTY_NULL) 1991 { 1992 /* 1982 1993 * Set the parent next to the property to delete next previous 1983 1994 */ 1984 1995 newLinkProperty = propertyToDelete.previousProperty; 1985 1986 if (propertyToDelete.nextProperty != PROPERTY_NULL) 1996 1997 if (propertyToDelete.nextProperty != PROPERTY_NULL) 1987 1998 { 1988 1999 /* 1989 * We also need to find a storage for the other link, setup variables 2000 * We also need to find a storage for the other link, setup variables 1990 2001 * to do this at the end... 1991 */ 2002 */ 1992 2003 needToFindAPlaceholder = TRUE; 1993 2004 storeNode = propertyToDelete.previousProperty; … … 1995 2006 relationType = PROPERTY_RELATION_NEXT; 1996 2007 } 1997 } 1998 else if (propertyToDelete.nextProperty != PROPERTY_NULL) 1999 { 2000 /* 2008 } 2009 else if (propertyToDelete.nextProperty != PROPERTY_NULL) 2010 { 2011 /* 2001 2012 * Set the parent next to the property to delete next 2002 2013 */ … … 2004 2015 } 2005 2016 2006 /* 2017 /* 2007 2018 * Link it for real... 2008 */ 2019 */ 2009 2020 parentProperty.nextProperty = newLinkProperty; 2010 } 2021 } 2011 2022 else /* (typeOfRelation == PROPERTY_RELATION_DIR) */ 2012 2023 { 2013 if (propertyToDelete.previousProperty != PROPERTY_NULL) 2014 { 2015 /* 2024 if (propertyToDelete.previousProperty != PROPERTY_NULL) 2025 { 2026 /* 2016 2027 * Set the parent dir to the property to delete previous 2017 2028 */ 2018 2029 newLinkProperty = propertyToDelete.previousProperty; 2019 2030 2020 if (propertyToDelete.nextProperty != PROPERTY_NULL) 2031 if (propertyToDelete.nextProperty != PROPERTY_NULL) 2021 2032 { 2022 2033 /* 2023 * We also need to find a storage for the other link, setup variables 2034 * We also need to find a storage for the other link, setup variables 2024 2035 * to do this at the end... 2025 */ 2036 */ 2026 2037 needToFindAPlaceholder = TRUE; 2027 2038 storeNode = propertyToDelete.previousProperty; … … 2029 2040 relationType = PROPERTY_RELATION_NEXT; 2030 2041 } 2031 } 2032 else if (propertyToDelete.nextProperty != PROPERTY_NULL) 2033 { 2034 /* 2042 } 2043 else if (propertyToDelete.nextProperty != PROPERTY_NULL) 2044 { 2045 /* 2035 2046 * Set the parent dir to the property to delete next 2036 2047 */ … … 2038 2049 } 2039 2050 2040 /* 2051 /* 2041 2052 * Link it for real... 2042 */ 2053 */ 2043 2054 parentProperty.dirProperty = newLinkProperty; 2044 2055 } 2045 2056 2046 /* 2047 * Write back the parent property 2057 /* 2058 * Write back the parent property 2048 2059 */ 2049 2060 res = StorageImpl_WriteProperty( 2050 This->ancestorStorage, 2061 This->ancestorStorage, 2051 2062 parentPropertyId, 2052 2063 &parentProperty); … … 2057 2068 2058 2069 /* 2059 * If a placeholder is required for the other link, then, find one and 2070 * If a placeholder is required for the other link, then, find one and 2060 2071 * get out of here... 2061 2072 */ 2062 if (needToFindAPlaceholder) 2073 if (needToFindAPlaceholder) 2063 2074 { 2064 2075 hr = findPlaceholder( 2065 This, 2066 toStoreNode, 2076 This, 2077 toStoreNode, 2067 2078 storeNode, 2068 2079 relationType); … … 2076 2087 * SetElementTimes (IStorage) 2077 2088 */ 2078 HRESULT WINAPI StorageImpl_SetElementTimes( 2089 HRESULT WINAPI StorageImpl_SetElementTimes( 2079 2090 IStorage* iface, 2080 const OLECHAR *pwcsName,/* [string][in] */ 2081 const FILETIME *pctime, /* [in] */ 2082 const FILETIME *patime, /* [in] */ 2083 const FILETIME *pmtime) /* [in] */ 2091 const OLECHAR *pwcsName,/* [string][in] */ 2092 const FILETIME *pctime, /* [in] */ 2093 const FILETIME *patime, /* [in] */ 2094 const FILETIME *pmtime) /* [in] */ 2084 2095 { 2085 2096 FIXME("not implemented!\n"); … … 2090 2101 * SetStateBits (IStorage) 2091 2102 */ 2092 HRESULT WINAPI StorageImpl_SetStateBits( 2103 HRESULT WINAPI StorageImpl_SetStateBits( 2093 2104 IStorage* iface, 2094 DWORD grfStateBits,/* [in] */ 2095 DWORD grfMask) /* [in] */ 2105 DWORD grfStateBits,/* [in] */ 2106 DWORD grfMask) /* [in] */ 2096 2107 { 2097 2108 FIXME("not implemented!\n"); … … 2111 2122 BOOL readSuccessful; 2112 2123 ULONG currentPropertyIndex; 2113 2124 2114 2125 if ( FAILED( validateSTGM(openFlags) )) 2115 2126 return STG_E_INVALIDFLAG; 2116 2127 2117 2128 memset(This, 0, sizeof(StorageImpl)); 2118 2129 2119 2130 /* 2120 2131 * Initialize the virtual fgunction table. … … 2122 2133 ICOM_VTBL(This) = &Storage32Impl_Vtbl; 2123 2134 This->v_destructor = &StorageImpl_Destroy; 2124 2135 2125 2136 /* 2126 2137 * This is the top-level storage so initialize the ancester pointer … … 2128 2139 */ 2129 2140 This->ancestorStorage = This; 2130 2141 2131 2142 /* 2132 2143 * Initialize the physical support of the storage. 2133 2144 */ 2134 2145 This->hFile = hFile; 2135 2146 2136 2147 /* 2137 2148 * Initialize the big block cache. … … 2147 2158 if (This->bigBlockFile == 0) 2148 2159 return E_FAIL; 2149 2160 2150 2161 if (fileCreate) 2151 2162 { … … 2159 2170 * - There is no small block depot 2160 2171 */ 2161 memset( This->bigBlockDepotStart, 2162 BLOCK_UNUSED, 2172 memset( This->bigBlockDepotStart, 2173 BLOCK_UNUSED, 2163 2174 sizeof(This->bigBlockDepotStart)); 2164 2175 … … 2214 2225 */ 2215 2226 This->prevFreeBlock = 0; 2216 2227 2217 2228 /* 2218 2229 * Create the block chain abstractions. 2219 2230 */ 2220 This->rootBlockChain = 2231 This->rootBlockChain = 2221 2232 BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL); 2222 2233 2223 2234 This->smallBlockDepotChain = BlockChainStream_Construct( 2224 This, 2225 &This->smallBlockDepotStart, 2235 This, 2236 &This->smallBlockDepotStart, 2226 2237 PROPERTY_NULL); 2227 2238 2228 2239 /* 2229 * Write the root property 2240 * Write the root property 2230 2241 */ 2231 2242 if (fileCreate) … … 2254 2265 */ 2255 2266 currentPropertyIndex = 0; 2256 2267 2257 2268 do 2258 2269 { 2259 2270 readSuccessful = StorageImpl_ReadProperty( 2260 This, 2261 currentPropertyIndex, 2271 This, 2272 currentPropertyIndex, 2262 2273 ¤tProperty); 2263 2274 2264 2275 if (readSuccessful) 2265 2276 { … … 2272 2283 2273 2284 currentPropertyIndex++; 2274 2285 2275 2286 } while (readSuccessful && (This->rootPropertySetIndex == PROPERTY_NULL) ); 2276 2287 2277 2288 if (!readSuccessful) 2278 2289 { … … 2285 2296 */ 2286 2297 This->smallBlockRootChain = BlockChainStream_Construct( 2287 This, 2288 NULL, 2298 This, 2299 NULL, 2289 2300 This->rootPropertySetIndex); 2290 2301 2291 2302 return hr; 2292 2303 } … … 2821 2832 2822 2833 StorageUtl_ReadWord( 2823 headerBigBlock, 2824 OFFSET_BIGBLOCKSIZEBITS, 2834 headerBigBlock, 2835 OFFSET_BIGBLOCKSIZEBITS, 2825 2836 &This->bigBlockSizeBits); 2826 2837 2827 2838 StorageUtl_ReadWord( 2828 headerBigBlock, 2829 OFFSET_SMALLBLOCKSIZEBITS, 2839 headerBigBlock, 2840 OFFSET_SMALLBLOCKSIZEBITS, 2830 2841 &This->smallBlockSizeBits); 2831 2842 2832 2843 StorageUtl_ReadDWord( 2833 headerBigBlock, 2834 OFFSET_BBDEPOTCOUNT, 2844 headerBigBlock, 2845 OFFSET_BBDEPOTCOUNT, 2835 2846 &This->bigBlockDepotCount); 2836 2847 2837 2848 StorageUtl_ReadDWord( 2838 headerBigBlock, 2839 OFFSET_ROOTSTARTBLOCK, 2849 headerBigBlock, 2850 OFFSET_ROOTSTARTBLOCK, 2840 2851 &This->rootStartBlock); 2841 2852 2842 2853 StorageUtl_ReadDWord( 2843 headerBigBlock, 2844 OFFSET_SBDEPOTSTART, 2854 headerBigBlock, 2855 OFFSET_SBDEPOTSTART, 2845 2856 &This->smallBlockDepotStart); 2846 2857 2858 StorageUtl_ReadDWord( 2859 headerBigBlock, 2860 OFFSET_EXTBBDEPOTSTART, 2861 &This->extBigBlockDepotStart); 2862 2847 2863 StorageUtl_ReadDWord( 2848 headerBigBlock, 2849 OFFSET_EXTBBDEPOTSTART, 2850 &This->extBigBlockDepotStart); 2851 2852 StorageUtl_ReadDWord( 2853 headerBigBlock, 2854 OFFSET_EXTBBDEPOTCOUNT, 2864 headerBigBlock, 2865 OFFSET_EXTBBDEPOTCOUNT, 2855 2866 &This->extBigBlockDepotCount); 2856 2867 2857 2868 for (index = 0; index < COUNT_BBDEPOTINHEADER; index ++) 2858 2869 { 2859 2870 StorageUtl_ReadDWord( 2860 headerBigBlock, 2871 headerBigBlock, 2861 2872 OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index), 2862 2873 &(This->bigBlockDepotStart[index])); 2863 2874 } 2864 2875 2865 2876 /* 2866 2877 * Make the bitwise arithmetic to get the size of the blocks in bytes. … … 2876 2887 This->smallBlockSize = 0x000000001 >> (DWORD)This->smallBlockSizeBits; 2877 2888 } 2878 2879 /* 2880 * Right now, the code is making some assumptions about the size of the 2889 2890 /* 2891 * Right now, the code is making some assumptions about the size of the 2881 2892 * blocks, just make sure they are what we're expecting. 2882 2893 */ 2883 assert( (This->bigBlockSize==DEF_BIG_BLOCK_SIZE) && 2894 assert( (This->bigBlockSize==DEF_BIG_BLOCK_SIZE) && 2884 2895 (This->smallBlockSize==DEF_SMALL_BLOCK_SIZE)); 2885 2896 2886 2897 /* 2887 2898 * Release the block. … … 2891 2902 hr = S_OK; 2892 2903 } 2893 2904 2894 2905 return hr; 2895 2906 } … … 2911 2922 */ 2912 2923 success = StorageImpl_ReadBigBlock(This, -1, headerBigBlock); 2913 2924 2914 2925 /* 2915 2926 * If the block read failed, the file is probably new. … … 2921 2932 */ 2922 2933 memset(headerBigBlock, 0, BIG_BLOCK_SIZE); 2923 2934 2924 2935 /* 2925 2936 * Initialize the magic number. 2926 2937 */ 2927 2938 memcpy(headerBigBlock, STORAGE_magic, sizeof(STORAGE_magic)); 2928 2939 2929 2940 /* 2930 2941 * And a bunch of things we don't know what they mean … … 2936 2947 StorageUtl_WriteDWord(headerBigBlock, 0x40, (DWORD)0x0001); 2937 2948 } 2938 2949 2939 2950 /* 2940 2951 * Write the information to the header. … … 2943 2954 { 2944 2955 StorageUtl_WriteWord( 2945 headerBigBlock, 2946 OFFSET_BIGBLOCKSIZEBITS, 2956 headerBigBlock, 2957 OFFSET_BIGBLOCKSIZEBITS, 2947 2958 This->bigBlockSizeBits); 2948 2959 2949 2960 StorageUtl_WriteWord( 2950 headerBigBlock, 2951 OFFSET_SMALLBLOCKSIZEBITS, 2961 headerBigBlock, 2962 OFFSET_SMALLBLOCKSIZEBITS, 2952 2963 This->smallBlockSizeBits); 2953 2964 2954 2965 StorageUtl_WriteDWord( 2955 headerBigBlock, 2956 OFFSET_BBDEPOTCOUNT, 2966 headerBigBlock, 2967 OFFSET_BBDEPOTCOUNT, 2957 2968 This->bigBlockDepotCount); 2958 2969 2959 2970 StorageUtl_WriteDWord( 2960 headerBigBlock, 2961 OFFSET_ROOTSTARTBLOCK, 2971 headerBigBlock, 2972 OFFSET_ROOTSTARTBLOCK, 2962 2973 This->rootStartBlock); 2963 2974 2964 2975 StorageUtl_WriteDWord( 2965 headerBigBlock, 2966 OFFSET_SBDEPOTSTART, 2976 headerBigBlock, 2977 OFFSET_SBDEPOTSTART, 2967 2978 This->smallBlockDepotStart); 2968 2979 2969 2980 StorageUtl_WriteDWord( 2970 headerBigBlock, 2971 OFFSET_EXTBBDEPOTSTART, 2981 headerBigBlock, 2982 OFFSET_EXTBBDEPOTSTART, 2972 2983 This->extBigBlockDepotStart); 2973 2984 2974 2985 StorageUtl_WriteDWord( 2975 headerBigBlock, 2976 OFFSET_EXTBBDEPOTCOUNT, 2986 headerBigBlock, 2987 OFFSET_EXTBBDEPOTCOUNT, 2977 2988 This->extBigBlockDepotCount); 2978 2989 … … 2980 2991 { 2981 2992 StorageUtl_WriteDWord( 2982 headerBigBlock, 2993 headerBigBlock, 2983 2994 OFFSET_BBDEPOTSTART + (sizeof(ULONG)*index), 2984 2995 (This->bigBlockDepotStart[index])); 2985 2996 } 2986 2997 } 2987 2998 2988 2999 /* 2989 3000 * Write the big block back to the file. … … 3009 3020 offsetInPropSet.s.HighPart = 0; 3010 3021 offsetInPropSet.s.LowPart = index * PROPSET_BLOCK_SIZE; 3011 3022 3012 3023 readSuccessful = BlockChainStream_ReadAt( 3013 3024 This->rootBlockChain, … … 3016 3027 currentProperty, 3017 3028 &bytesRead); 3018 3029 3019 3030 if (readSuccessful) 3020 3031 { 3021 3032 memset(buffer->name, 0, sizeof(buffer->name)); 3022 3033 memcpy( 3023 buffer->name, 3024 currentProperty+OFFSET_PS_NAME, 3034 buffer->name, 3035 currentProperty+OFFSET_PS_NAME, 3025 3036 PROPERTY_NAME_BUFFER_LEN ); 3026 3037 3027 3038 memcpy(&buffer->propertyType, currentProperty + OFFSET_PS_PROPERTYTYPE, 1); 3028 3039 3029 3040 StorageUtl_ReadWord( 3030 currentProperty, 3031 OFFSET_PS_NAMELENGTH, 3041 currentProperty, 3042 OFFSET_PS_NAMELENGTH, 3032 3043 &buffer->sizeOfNameString); 3033 3044 3034 3045 StorageUtl_ReadDWord( 3035 currentProperty, 3036 OFFSET_PS_PREVIOUSPROP, 3046 currentProperty, 3047 OFFSET_PS_PREVIOUSPROP, 3037 3048 &buffer->previousProperty); 3038 3049 3039 3050 StorageUtl_ReadDWord( 3040 currentProperty, 3041 OFFSET_PS_NEXTPROP, 3051 currentProperty, 3052 OFFSET_PS_NEXTPROP, 3042 3053 &buffer->nextProperty); 3043 3054 3044 3055 StorageUtl_ReadDWord( 3045 currentProperty, 3046 OFFSET_PS_DIRPROP, 3056 currentProperty, 3057 OFFSET_PS_DIRPROP, 3047 3058 &buffer->dirProperty); 3048 3059 3049 3060 StorageUtl_ReadGUID( 3050 currentProperty, 3051 OFFSET_PS_GUID, 3061 currentProperty, 3062 OFFSET_PS_GUID, 3052 3063 &buffer->propertyUniqueID); 3053 3064 3054 3065 StorageUtl_ReadDWord( 3055 currentProperty, 3056 OFFSET_PS_TSS1, 3066 currentProperty, 3067 OFFSET_PS_TSS1, 3057 3068 &buffer->timeStampS1); 3058 3069 3059 3070 StorageUtl_ReadDWord( 3060 currentProperty, 3061 OFFSET_PS_TSD1, 3071 currentProperty, 3072 OFFSET_PS_TSD1, 3062 3073 &buffer->timeStampD1); 3063 3074 3064 3075 StorageUtl_ReadDWord( 3065 currentProperty, 3066 OFFSET_PS_TSS2, 3076 currentProperty, 3077 OFFSET_PS_TSS2, 3067 3078 &buffer->timeStampS2); 3068 3079 3069 3080 StorageUtl_ReadDWord( 3070 currentProperty, 3071 OFFSET_PS_TSD2, 3081 currentProperty, 3082 OFFSET_PS_TSD2, 3072 3083 &buffer->timeStampD2); 3073 3084 3074 3085 StorageUtl_ReadDWord( 3075 currentProperty, 3076 OFFSET_PS_STARTBLOCK, 3086 currentProperty, 3087 OFFSET_PS_STARTBLOCK, 3077 3088 &buffer->startingBlock); 3078 3089 3079 3090 StorageUtl_ReadDWord( 3080 currentProperty, 3081 OFFSET_PS_SIZE, 3091 currentProperty, 3092 OFFSET_PS_SIZE, 3082 3093 &buffer->size.s.LowPart); 3083 3094 … … 3107 3118 3108 3119 memcpy( 3109 currentProperty + OFFSET_PS_NAME, 3110 buffer->name, 3120 currentProperty + OFFSET_PS_NAME, 3121 buffer->name, 3111 3122 PROPERTY_NAME_BUFFER_LEN ); 3112 3123 … … 3114 3125 3115 3126 StorageUtl_WriteWord( 3116 currentProperty, 3117 OFFSET_PS_NAMELENGTH, 3127 currentProperty, 3128 OFFSET_PS_NAMELENGTH, 3118 3129 buffer->sizeOfNameString); 3119 3130 3120 3131 StorageUtl_WriteDWord( 3121 currentProperty, 3122 OFFSET_PS_PREVIOUSPROP, 3132 currentProperty, 3133 OFFSET_PS_PREVIOUSPROP, 3123 3134 buffer->previousProperty); 3124 3135 3125 3136 StorageUtl_WriteDWord( 3126 currentProperty, 3127 OFFSET_PS_NEXTPROP, 3137 currentProperty, 3138 OFFSET_PS_NEXTPROP, 3128 3139 buffer->nextProperty); 3129 3140 3130 3141 StorageUtl_WriteDWord( 3131 currentProperty, 3132 OFFSET_PS_DIRPROP, 3142 currentProperty, 3143 OFFSET_PS_DIRPROP, 3133 3144 buffer->dirProperty); 3134 3145 3135 3146 StorageUtl_WriteGUID( 3136 currentProperty, 3137 OFFSET_PS_GUID, 3147 currentProperty, 3148 OFFSET_PS_GUID, 3138 3149 &buffer->propertyUniqueID); 3139 3150 3140 3151 StorageUtl_WriteDWord( 3141 currentProperty, 3142 OFFSET_PS_TSS1, 3152 currentProperty, 3153 OFFSET_PS_TSS1, 3143 3154 buffer->timeStampS1); 3144 3155 3145 3156 StorageUtl_WriteDWord( 3146 currentProperty, 3147 OFFSET_PS_TSD1, 3157 currentProperty, 3158 OFFSET_PS_TSD1, 3148 3159 buffer->timeStampD1); 3149 3160 3150 3161 StorageUtl_WriteDWord( 3151 currentProperty, 3152 OFFSET_PS_TSS2, 3162 currentProperty, 3163 OFFSET_PS_TSS2, 3153 3164 buffer->timeStampS2); 3154 3165 3155 3166 StorageUtl_WriteDWord( 3156 currentProperty, 3157 OFFSET_PS_TSD2, 3167 currentProperty, 3168 OFFSET_PS_TSD2, 3158 3169 buffer->timeStampD2); 3159 3170 3160 3171 StorageUtl_WriteDWord( 3161 currentProperty, 3162 OFFSET_PS_STARTBLOCK, 3172 currentProperty, 3173 OFFSET_PS_STARTBLOCK, 3163 3174 buffer->startingBlock); 3164 3175 3165 3176 StorageUtl_WriteDWord( 3166 currentProperty, 3167 OFFSET_PS_SIZE, 3177 currentProperty, 3178 OFFSET_PS_SIZE, 3168 3179 buffer->size.s.LowPart); 3169 3180 … … 3211 3222 3212 3223 StorageImpl_ReleaseBigBlock(This, bigBlockBuffer); 3213 3224 3214 3225 return TRUE; 3215 3226 } 3216 3227 3217 3228 return FALSE; 3218 3229 } … … 3344 3355 3345 3356 StorageInternalImpl* StorageInternalImpl_Construct( 3346 StorageImpl* ancestorStorage, 3357 StorageImpl* ancestorStorage, 3347 3358 ULONG rootPropertyIndex) 3348 3359 { … … 3395 3406 ** does nothing. 3396 3407 */ 3397 HRESULT WINAPI StorageInternalImpl_Commit( 3408 HRESULT WINAPI StorageInternalImpl_Commit( 3398 3409 IStorage* iface, 3399 DWORD grfCommitFlags) /* [in] */ 3410 DWORD grfCommitFlags) /* [in] */ 3400 3411 { 3401 3412 return S_OK; 3402 3413 } 3403 3414 3404 3415 /****************************************************************************** 3405 3416 ** … … 3409 3420 ** does nothing. 3410 3421 */ 3411 HRESULT WINAPI StorageInternalImpl_Revert( 3422 HRESULT WINAPI StorageInternalImpl_Revert( 3412 3423 IStorage* iface) 3413 3424 { … … 3426 3437 3427 3438 newEnumeration = HeapAlloc(GetProcessHeap(), 0, sizeof(IEnumSTATSTGImpl)); 3428 3439 3429 3440 if (newEnumeration!=0) 3430 3441 { … … 3434 3445 ICOM_VTBL(newEnumeration) = &IEnumSTATSTGImpl_Vtbl; 3435 3446 newEnumeration->ref = 0; 3436 3447 3437 3448 /* 3438 3449 * We want to nail-down the reference to the storage in case the … … 3441 3452 newEnumeration->parentStorage = parentStorage; 3442 3453 IStorage_AddRef((IStorage*)newEnumeration->parentStorage); 3443 3454 3444 3455 newEnumeration->firstPropertyNode = firstPropertyNode; 3445 3456 3446 3457 /* 3447 3458 * Initialize the search stack … … 3449 3460 newEnumeration->stackSize = 0; 3450 3461 newEnumeration->stackMaxSize = ENUMSTATSGT_SIZE_INCREMENT; 3451 newEnumeration->stackToVisit = 3462 newEnumeration->stackToVisit = 3452 3463 HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG)*ENUMSTATSGT_SIZE_INCREMENT); 3453 3464 3454 3465 /* 3455 3466 * Make sure the current node of the iterator is the first one. … … 3457 3468 IEnumSTATSTGImpl_Reset((IEnumSTATSTG*)newEnumeration); 3458 3469 } 3459 3470 3460 3471 return newEnumeration; 3461 3472 } … … 3489 3500 * Compare the riid with the interface IDs implemented by this object. 3490 3501 */ 3491 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 3502 if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0) 3492 3503 { 3493 3504 *ppvObject = (IEnumSTATSTG*)This; 3494 3505 } 3495 else if (memcmp(&IID_IStorage, riid, sizeof(IID_IEnumSTATSTG)) == 0) 3506 else if (memcmp(&IID_IStorage, riid, sizeof(IID_IEnumSTATSTG)) == 0) 3496 3507 { 3497 3508 *ppvObject = (IEnumSTATSTG*)This; … … 3512 3523 return S_OK; 3513 3524 } 3514 3525 3515 3526 ULONG WINAPI IEnumSTATSTGImpl_AddRef( 3516 3527 IEnumSTATSTG* iface) … … 3521 3532 return This->ref; 3522 3533 } 3523 3534 3524 3535 ULONG WINAPI IEnumSTATSTGImpl_Release( 3525 3536 IEnumSTATSTG* iface) … … 3560 3571 */ 3561 3572 if ( (rgelt==0) || ( (celt!=1) && (pceltFetched==0) ) ) 3562 return E_INVALIDARG; 3563 3573 return E_INVALIDARG; 3574 3564 3575 /* 3565 3576 * To avoid the special case, get another pointer to a ULONG value if … … 3568 3579 if (pceltFetched==0) 3569 3580 pceltFetched = &objectFetched; 3570 3581 3571 3582 /* 3572 3583 * Start the iteration, we will iterate until we hit the end of the … … 3580 3591 currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); 3581 3592 3582 while ( ( *pceltFetched < celt) && 3593 while ( ( *pceltFetched < celt) && 3583 3594 ( currentSearchNode!=PROPERTY_NULL) ) 3584 3595 { 3585 /* 3596 /* 3586 3597 * Remove the top node from the stack 3587 3598 */ … … 3592 3603 */ 3593 3604 StorageImpl_ReadProperty(This->parentStorage, 3594 currentSearchNode, 3605 currentSearchNode, 3595 3606 ¤tProperty); 3596 3607 … … 3601 3612 ¤tProperty, 3602 3613 STATFLAG_DEFAULT); 3603 3614 3604 3615 /* 3605 3616 * Step to the next item in the iteration … … 3625 3636 } 3626 3637 3627 3638 3628 3639 HRESULT WINAPI IEnumSTATSTGImpl_Skip( 3629 3640 IEnumSTATSTG* iface, … … 3641 3652 currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); 3642 3653 3643 while ( (objectFetched < celt) && 3654 while ( (objectFetched < celt) && 3644 3655 (currentSearchNode!=PROPERTY_NULL) ) 3645 3656 { 3646 /* 3657 /* 3647 3658 * Remove the top node from the stack 3648 3659 */ … … 3653 3664 */ 3654 3665 StorageImpl_ReadProperty(This->parentStorage, 3655 currentSearchNode, 3666 currentSearchNode, 3656 3667 ¤tProperty); 3657 3668 3658 3669 /* 3659 3670 * Step to the next item in the iteration … … 3677 3688 return S_FALSE; 3678 3689 } 3679 3690 3680 3691 HRESULT WINAPI IEnumSTATSTGImpl_Reset( 3681 3692 IEnumSTATSTG* iface) … … 3696 3707 readSuccessful = StorageImpl_ReadProperty( 3697 3708 This->parentStorage, 3698 This->firstPropertyNode, 3709 This->firstPropertyNode, 3699 3710 &rootProperty); 3700 3711 … … 3711 3722 return S_OK; 3712 3723 } 3713 3724 3714 3725 HRESULT WINAPI IEnumSTATSTGImpl_Clone( 3715 3726 IEnumSTATSTG* iface, … … 3725 3736 if (ppenum==0) 3726 3737 return E_INVALIDARG; 3727 3738 3728 3739 newClone = IEnumSTATSTGImpl_Construct(This->parentStorage, 3729 3740 This->firstPropertyNode); 3730 3741 3731 3742 3732 3743 /* 3733 3744 * The new clone enumeration must point to the same current node as … … 3736 3747 newClone->stackSize = This->stackSize ; 3737 3748 newClone->stackMaxSize = This->stackMaxSize ; 3738 newClone->stackToVisit = 3749 newClone->stackToVisit = 3739 3750 HeapAlloc(GetProcessHeap(), 0, sizeof(ULONG) * newClone->stackMaxSize); 3740 3751 3741 3752 memcpy( 3742 newClone->stackToVisit, 3743 This->stackToVisit, 3753 newClone->stackToVisit, 3754 This->stackToVisit, 3744 3755 sizeof(ULONG) * newClone->stackSize); 3745 3756 … … 3757 3768 INT IEnumSTATSTGImpl_FindParentProperty( 3758 3769 IEnumSTATSTGImpl *This, 3759 ULONG childProperty, 3770 ULONG childProperty, 3760 3771 StgProperty *currentProperty, 3761 3772 ULONG *thisNodeId) … … 3775 3786 */ 3776 3787 currentSearchNode = IEnumSTATSTGImpl_PopSearchNode(This, FALSE); 3777 3788 3778 3789 3779 3790 while (currentSearchNode!=PROPERTY_NULL) … … 3784 3795 *thisNodeId = currentSearchNode; 3785 3796 3786 /* 3797 /* 3787 3798 * Remove the top node from the stack 3788 3799 */ … … 3794 3805 StorageImpl_ReadProperty( 3795 3806 This->parentStorage, 3796 currentSearchNode, 3807 currentSearchNode, 3797 3808 currentProperty); 3798 3809 3799 3810 if (currentProperty->previousProperty == childProperty) 3800 3811 return PROPERTY_RELATION_PREVIOUS; 3801 3812 3802 else if (currentProperty->nextProperty == childProperty) 3813 else if (currentProperty->nextProperty == childProperty) 3803 3814 return PROPERTY_RELATION_NEXT; 3804 3815 3805 3816 else if (currentProperty->dirProperty == childProperty) 3806 3817 return PROPERTY_RELATION_DIR; 3807 3818 3808 3819 /* 3809 3820 * Push the next search node in the search stack. … … 3834 3845 while (currentSearchNode!=PROPERTY_NULL) 3835 3846 { 3836 /* 3847 /* 3837 3848 * Remove the top node from the stack 3838 3849 */ … … 3843 3854 */ 3844 3855 StorageImpl_ReadProperty(This->parentStorage, 3845 currentSearchNode, 3856 currentSearchNode, 3846 3857 currentProperty); 3847 3858 3848 3859 if ( propertyNameCmp( 3849 (OLECHAR*)currentProperty->name, 3860 (OLECHAR*)currentProperty->name, 3850 3861 (OLECHAR*)lpszPropName) == 0) 3851 3862 return currentSearchNode; … … 3886 3897 3887 3898 This->stackToVisit = HeapReAlloc( 3888 GetProcessHeap(), 3899 GetProcessHeap(), 3889 3900 0, 3890 3901 This->stackToVisit, … … 3900 3911 readSuccessful = StorageImpl_ReadProperty( 3901 3912 This->parentStorage, 3902 nodeToPush, 3913 nodeToPush, 3903 3914 &rootProperty); 3904 3915 … … 3987 3998 else 3988 3999 { 3989 destination->pwcsName = 4000 destination->pwcsName = 3990 4001 CoTaskMemAlloc((lstrlenW(source->name)+1)*sizeof(WCHAR)); 3991 4002 3992 4003 strcpyW((LPWSTR)destination->pwcsName, source->name); 3993 4004 } 3994 4005 3995 4006 switch (source->propertyType) 3996 4007 { … … 4004 4015 default: 4005 4016 destination->type = STGTY_STREAM; 4006 break; 4017 break; 4007 4018 } 4008 4019 4009 4020 destination->cbSize = source->size; 4010 /* 4021 /* 4011 4022 currentReturnStruct->mtime = {0}; TODO 4012 4023 currentReturnStruct->ctime = {0}; 4013 currentReturnStruct->atime = {0}; 4024 currentReturnStruct->atime = {0}; 4014 4025 */ 4015 4026 destination->grfMode = 0; 4016 destination->grfLocksSupported = 0; 4027 destination->grfLocksSupported = 0; 4017 4028 destination->clsid = source->propertyUniqueID; 4018 destination->grfStateBits = 0; 4019 destination->reserved = 0; 4029 destination->grfStateBits = 0; 4030 destination->reserved = 0; 4020 4031 } 4021 4032 … … 4025 4036 4026 4037 BlockChainStream* BlockChainStream_Construct( 4027 StorageImpl* parentStorage, 4038 StorageImpl* parentStorage, 4028 4039 ULONG* headOfStreamPlaceHolder, 4029 4040 ULONG propertyIndex) … … 4098 4109 * Returns the number of blocks that comprises this chain. 4099 4110 * This is not the size of the stream as the last block may not be full! 4100 * 4111 * 4101 4112 */ 4102 4113 ULONG BlockChainStream_GetCount(BlockChainStream* This) … … 4112 4123 4113 4124 blockIndex = StorageImpl_GetNextBlockInChain( 4114 This->parentStorage, 4125 This->parentStorage, 4115 4126 blockIndex); 4116 4127 } … … 4120 4131 4121 4132 /****************************************************************************** 4122 * BlockChainStream_ReadAt 4133 * BlockChainStream_ReadAt 4123 4134 * 4124 4135 * Reads a specified number of bytes from this chain at the specified offset. … … 4160 4171 while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) 4161 4172 { 4162 blockIndex = 4173 blockIndex = 4163 4174 StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); 4164 4175 4165 4176 blockNoInSequence--; 4166 4177 } … … 4173 4184 *bytesRead = 0; 4174 4185 bufferWalker = buffer; 4175 4186 4176 4187 while ( (size > 0) && (blockIndex != BLOCK_END_OF_CHAIN) ) 4177 4188 { … … 4179 4190 * Calculate how many bytes we can copy from this big block. 4180 4191 */ 4181 bytesToReadInBuffer = 4192 bytesToReadInBuffer = 4182 4193 min(This->parentStorage->bigBlockSize - offsetInBlock, size); 4183 4194 4184 4195 /* 4185 4196 * Copy those bytes to the buffer 4186 4197 */ 4187 bigBlockBuffer = 4198 bigBlockBuffer = 4188 4199 StorageImpl_GetROBigBlock(This->parentStorage, blockIndex); 4189 4200 4190 4201 memcpy(bufferWalker, bigBlockBuffer + offsetInBlock, bytesToReadInBuffer); 4191 4202 4192 4203 StorageImpl_ReleaseBigBlock(This->parentStorage, bigBlockBuffer); 4193 4204 4194 4205 /* 4195 4206 * Step to the next big block. 4196 4207 */ 4197 blockIndex = 4208 blockIndex = 4198 4209 StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); 4199 4210 … … 4204 4215 4205 4216 } 4206 4217 4207 4218 return (size == 0); 4208 4219 } … … 4249 4260 while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) 4250 4261 { 4251 blockIndex = 4262 blockIndex = 4252 4263 StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); 4253 4264 4254 4265 blockNoInSequence--; 4255 4266 } … … 4269 4280 * Calculate how many bytes we can copy from this big block. 4270 4281 */ 4271 bytesToWrite = 4282 bytesToWrite = 4272 4283 min(This->parentStorage->bigBlockSize - offsetInBlock, size); 4273 4284 4274 4285 /* 4275 4286 * Copy those bytes to the buffer 4276 4287 */ 4277 4288 bigBlockBuffer = StorageImpl_GetBigBlock(This->parentStorage, blockIndex); 4278 4289 4279 4290 memcpy(bigBlockBuffer + offsetInBlock, bufferWalker, bytesToWrite); 4280 4291 4281 4292 StorageImpl_ReleaseBigBlock(This->parentStorage, bigBlockBuffer); 4282 4293 4283 4294 /* 4284 4295 * Step to the next big block. 4285 4296 */ 4286 blockIndex = 4297 blockIndex = 4287 4298 StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); 4288 4299 … … 4292 4303 offsetInBlock = 0; /* There is no offset on the next block */ 4293 4304 } 4294 4305 4295 4306 return (size == 0); 4296 4307 } … … 4329 4340 while (count < numBlocks) 4330 4341 { 4331 blockIndex = 4342 blockIndex = 4332 4343 StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); 4333 4344 … … 4336 4347 4337 4348 /* Get the next block before marking the new end */ 4338 extraBlock = 4349 extraBlock = 4339 4350 StorageImpl_GetNextBlockInChain(This->parentStorage, blockIndex); 4340 4351 4341 4352 /* Mark the new end of chain */ 4342 4353 StorageImpl_SetNextBlockInChain( 4343 This->parentStorage, 4344 blockIndex, 4354 This->parentStorage, 4355 blockIndex, 4345 4356 BLOCK_END_OF_CHAIN); 4346 4357 … … 4353 4364 while (extraBlock != BLOCK_END_OF_CHAIN) 4354 4365 { 4355 blockIndex = 4366 blockIndex = 4356 4367 StorageImpl_GetNextBlockInChain(This->parentStorage, extraBlock); 4357 4368 … … 4397 4408 4398 4409 StorageImpl_ReadProperty( 4399 This->parentStorage, 4410 This->parentStorage, 4400 4411 This->ownerPropertyIndex, 4401 4412 &chainProp); 4402 4413 4403 chainProp.startingBlock = blockIndex; 4414 chainProp.startingBlock = blockIndex; 4404 4415 4405 4416 StorageImpl_WriteProperty( 4406 This->parentStorage, 4417 This->parentStorage, 4407 4418 This->ownerPropertyIndex, 4408 4419 &chainProp); … … 4453 4464 4454 4465 StorageImpl_SetNextBlockInChain( 4455 This->parentStorage, 4456 currentBlock, 4457 4466 This->parentStorage, 4467 currentBlock, 4468 blockIndex); 4458 4469 4459 4470 StorageImpl_SetNextBlockInChain( 4460 This->parentStorage, 4461 blockIndex, 4462 4471 This->parentStorage, 4472 blockIndex, 4473 BLOCK_END_OF_CHAIN); 4463 4474 4464 4475 currentBlock = blockIndex; … … 4481 4492 * TODO: Free the actual blocks in the file when we shrink the chain. 4482 4493 * Currently, the blocks are still in the file. So the file size 4483 * doesn't shrink even if we shrink streams. 4494 * doesn't shrink even if we shrink streams. 4484 4495 */ 4485 4496 BOOL BlockChainStream_SetSize( … … 4498 4509 else 4499 4510 { 4500 ULARGE_INTEGER fileSize = 4511 ULARGE_INTEGER fileSize = 4501 4512 BIGBLOCKFILE_GetSize(This->parentStorage->bigBlockFile); 4502 4513 … … 4507 4518 */ 4508 4519 if ((diff % This->parentStorage->bigBlockSize) != 0) 4509 diff += (This->parentStorage->bigBlockSize - 4520 diff += (This->parentStorage->bigBlockSize - 4510 4521 (diff % This->parentStorage->bigBlockSize) ); 4511 4522 … … 4531 4542 if(This->headOfStreamPlaceHolder == NULL) 4532 4543 { 4533 /* 4534 * This chain is a data stream read the property and return 4544 /* 4545 * This chain is a data stream read the property and return 4535 4546 * the appropriate size 4536 4547 */ … … 4545 4556 { 4546 4557 /* 4547 * this chain is a chain that does not have a property, figure out the 4548 * size by making the product number of used blocks times the 4558 * this chain is a chain that does not have a property, figure out the 4559 * size by making the product number of used blocks times the 4549 4560 * size of them 4550 4561 */ … … 4552 4563 result.s.HighPart = 0; 4553 4564 4554 result.s.LowPart = 4555 BlockChainStream_GetCount(This) * 4565 result.s.LowPart = 4566 BlockChainStream_GetCount(This) * 4556 4567 This->parentStorage->bigBlockSize; 4557 4568 … … 4565 4576 4566 4577 SmallBlockChainStream* SmallBlockChainStream_Construct( 4567 StorageImpl* parentStorage, 4578 StorageImpl* parentStorage, 4568 4579 ULONG propertyIndex) 4569 4580 { … … 4616 4627 * 4617 4628 * Returns the index of the next small block in this chain. 4618 * 4629 * 4619 4630 * Return Values: 4620 4631 * - BLOCK_END_OF_CHAIN: end of this chain … … 4743 4754 else 4744 4755 { 4745 ULONG count = 4756 ULONG count = 4746 4757 BlockChainStream_GetCount(This->parentStorage->smallBlockDepotChain); 4747 4758 … … 4754 4765 { 4755 4766 sbdIndex = nextBlock; 4756 nextBlock = 4767 nextBlock = 4757 4768 StorageImpl_GetNextBlockInChain(This->parentStorage, sbdIndex); 4758 4769 } … … 4761 4772 if (sbdIndex != BLOCK_END_OF_CHAIN) 4762 4773 StorageImpl_SetNextBlockInChain( 4763 This->parentStorage, 4764 sbdIndex, 4774 This->parentStorage, 4775 sbdIndex, 4765 4776 newsbdIndex); 4766 4777 4767 4778 StorageImpl_SetNextBlockInChain( 4768 This->parentStorage, 4769 newsbdIndex, 4779 This->parentStorage, 4780 newsbdIndex, 4770 4781 BLOCK_END_OF_CHAIN); 4771 4782 … … 4773 4784 * Initialize all the small blocks to free 4774 4785 */ 4775 smallBlockDepot = 4786 smallBlockDepot = 4776 4787 StorageImpl_GetBigBlock(This->parentStorage, newsbdIndex); 4777 4788 … … 4785 4796 */ 4786 4797 StgProperty rootProp; 4787 ULONG sbStartIndex; 4798 ULONG sbStartIndex; 4788 4799 4789 4800 /* … … 4794 4805 4795 4806 /* 4796 * And allocate the first big block that will contain small blocks 4807 * And allocate the first big block that will contain small blocks 4797 4808 */ 4798 sbStartIndex = 4809 sbStartIndex = 4799 4810 StorageImpl_GetNextFreeBigBlock(This->parentStorage); 4800 4811 4801 4812 StorageImpl_SetNextBlockInChain( 4802 This->parentStorage, 4803 sbStartIndex, 4813 This->parentStorage, 4814 sbStartIndex, 4804 4815 BLOCK_END_OF_CHAIN); 4805 4816 4806 4817 StorageImpl_ReadProperty( 4807 This->parentStorage, 4808 This->parentStorage->rootPropertySetIndex, 4818 This->parentStorage, 4819 This->parentStorage->rootPropertySetIndex, 4809 4820 &rootProp); 4810 4821 … … 4814 4825 4815 4826 StorageImpl_WriteProperty( 4816 This->parentStorage, 4817 This->parentStorage->rootPropertySetIndex, 4827 This->parentStorage, 4828 This->parentStorage->rootPropertySetIndex, 4818 4829 &rootProp); 4819 4830 } … … 4821 4832 } 4822 4833 4823 smallBlocksPerBigBlock = 4834 smallBlocksPerBigBlock = 4824 4835 This->parentStorage->bigBlockSize / This->parentStorage->smallBlockSize; 4825 4836 … … 4833 4844 4834 4845 StorageImpl_ReadProperty( 4835 This->parentStorage, 4836 This->parentStorage->rootPropertySetIndex, 4846 This->parentStorage, 4847 This->parentStorage->rootPropertySetIndex, 4837 4848 &rootProp); 4838 4849 4839 if (rootProp.size.s.LowPart < 4850 if (rootProp.size.s.LowPart < 4840 4851 (blocksRequired * This->parentStorage->bigBlockSize)) 4841 4852 { … … 4843 4854 4844 4855 BlockChainStream_SetSize( 4845 This->parentStorage->smallBlockRootChain, 4856 This->parentStorage->smallBlockRootChain, 4846 4857 rootProp.size); 4847 4858 4848 4859 StorageImpl_WriteProperty( 4849 This->parentStorage, 4850 This->parentStorage->rootPropertySetIndex, 4860 This->parentStorage, 4861 This->parentStorage->rootPropertySetIndex, 4851 4862 &rootProp); 4852 4863 } … … 4861 4872 * Reads a specified number of bytes from this chain at the specified offset. 4862 4873 * bytesRead may be NULL. 4863 * Failure will be returned if the specified number of bytes has not been read. 4874 * Failure will be returned if the specified number of bytes has not been read. 4864 4875 */ 4865 4876 BOOL SmallBlockChainStream_ReadAt( … … 4871 4882 { 4872 4883 ULARGE_INTEGER offsetInBigBlockFile; 4873 ULONG blockNoInSequence = 4884 ULONG blockNoInSequence = 4874 4885 offset.s.LowPart / This->parentStorage->smallBlockSize; 4875 4886 … … 4908 4919 * Calculate how many bytes we can copy from this small block. 4909 4920 */ 4910 bytesToReadInBuffer = 4921 bytesToReadInBuffer = 4911 4922 min(This->parentStorage->smallBlockSize - offsetInBlock, size); 4912 4923 … … 4915 4926 */ 4916 4927 offsetInBigBlockFile.s.HighPart = 0; 4917 offsetInBigBlockFile.s.LowPart = 4928 offsetInBigBlockFile.s.LowPart = 4918 4929 blockIndex * This->parentStorage->smallBlockSize; 4919 4930 … … 4959 4970 { 4960 4971 ULARGE_INTEGER offsetInBigBlockFile; 4961 ULONG blockNoInSequence = 4972 ULONG blockNoInSequence = 4962 4973 offset.s.LowPart / This->parentStorage->smallBlockSize; 4963 4974 … … 4967 4978 ULONG bytesWrittenFromBigBlockFile; 4968 4979 BYTE* bufferWalker; 4969 4980 4970 4981 /* 4971 4982 * This should never happen on a small block file. 4972 4983 */ 4973 4984 assert(offset.s.HighPart==0); 4974 4985 4975 4986 /* 4976 4987 * Find the first block in the stream that contains part of the buffer. 4977 4988 */ 4978 4989 blockIndex = SmallBlockChainStream_GetHeadOfChain(This); 4979 4990 4980 4991 while ( (blockNoInSequence > 0) && (blockIndex != BLOCK_END_OF_CHAIN)) 4981 4992 { 4982 4993 blockIndex = SmallBlockChainStream_GetNextBlockInChain(This, blockIndex); 4983 4994 4984 4995 blockNoInSequence--; 4985 4996 } 4986 4997 4987 4998 /* 4988 4999 * Start writing the buffer. … … 4998 5009 * Calculate how many bytes we can copy to this small block. 4999 5010 */ 5000 bytesToWriteInBuffer = 5011 bytesToWriteInBuffer = 5001 5012 min(This->parentStorage->smallBlockSize - offsetInBlock, size); 5002 5013 5003 5014 /* 5004 5015 * Calculate the offset of the small block in the small block file. 5005 5016 */ 5006 5017 offsetInBigBlockFile.s.HighPart = 0; 5007 offsetInBigBlockFile.s.LowPart = 5018 offsetInBigBlockFile.s.LowPart = 5008 5019 blockIndex * This->parentStorage->smallBlockSize; 5009 5020 5010 5021 offsetInBigBlockFile.s.LowPart += offsetInBlock; 5011 5022 5012 5023 /* 5013 5024 * Write those bytes in the buffer to the small block file. … … 5018 5029 bufferWalker, 5019 5030 &bytesWrittenFromBigBlockFile); 5020 5031 5021 5032 assert(bytesWrittenFromBigBlockFile == bytesToWriteInBuffer); 5022 5033 5023 5034 /* 5024 5035 * Step to the next big block. … … 5030 5041 offsetInBlock = 0; /* There is no offset on the next block */ 5031 5042 } 5032 5043 5033 5044 return (size == 0); 5034 5045 } … … 5037 5048 * SmallBlockChainStream_Shrink 5038 5049 * 5039 * Shrinks this chain in the small block depot. 5050 * Shrinks this chain in the small block depot. 5040 5051 */ 5041 5052 BOOL SmallBlockChainStream_Shrink( … … 5065 5076 /* 5066 5077 * If the count is 0, we have a special case, the head of the chain was 5067 * just freed. 5078 * just freed. 5068 5079 */ 5069 5080 if (count == 0) … … 5071 5082 StgProperty chainProp; 5072 5083 5073 StorageImpl_ReadProperty(This->parentStorage, 5074 5075 5084 StorageImpl_ReadProperty(This->parentStorage, 5085 This->ownerPropertyIndex, 5086 &chainProp); 5076 5087 5077 5088 chainProp.startingBlock = BLOCK_END_OF_CHAIN; 5078 5089 5079 5090 StorageImpl_WriteProperty(This->parentStorage, 5080 5081 5091 This->ownerPropertyIndex, 5092 &chainProp); 5082 5093 5083 5094 /* … … 5093 5104 /* Mark the new end of chain */ 5094 5105 SmallBlockChainStream_SetNextBlockInChain( 5095 This, 5096 blockIndex, 5106 This, 5107 blockIndex, 5097 5108 BLOCK_END_OF_CHAIN); 5098 5109 } … … 5108 5119 } 5109 5120 5110 return TRUE; 5121 return TRUE; 5111 5122 } 5112 5123 … … 5144 5155 blockIndex = chainProp.startingBlock; 5145 5156 SmallBlockChainStream_SetNextBlockInChain( 5146 This, 5147 blockIndex, 5157 This, 5158 blockIndex, 5148 5159 BLOCK_END_OF_CHAIN); 5149 5160 } … … 5178 5189 5179 5190 SmallBlockChainStream_SetNextBlockInChain( 5180 This, 5181 blockIndex, 5191 This, 5192 blockIndex, 5182 5193 BLOCK_END_OF_CHAIN); 5183 5194 … … 5220 5231 * TODO: Free the actual blocks in the file when we shrink the chain. 5221 5232 * Currently, the blocks are still in the file. So the file size 5222 * doesn't shrink even if we shrink streams. 5233 * doesn't shrink even if we shrink streams. 5223 5234 */ 5224 5235 BOOL SmallBlockChainStream_SetSize( … … 5278 5289 WCHAR tempFileName[MAX_PATH]; 5279 5290 5280 TRACE("(%s, %lx, %ld, %p)\n", 5281 debugstr_w(pwcsName), grfMode, 5282 5291 TRACE("(%s, %lx, %ld, %p)\n", 5292 debugstr_w(pwcsName), grfMode, 5293 reserved, ppstgOpen); 5283 5294 5284 5295 /* … … 5326 5337 5327 5338 /* 5328 * Interpret the STGM value grfMode 5339 * Interpret the STGM value grfMode 5329 5340 */ 5330 5341 shareMode = GetShareModeFromSTGM(grfMode); … … 5351 5362 fileAttributes, 5352 5363 0); 5353 5364 5354 5365 if (hFile == INVALID_HANDLE_VALUE) 5355 5366 { … … 5361 5372 */ 5362 5373 newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); 5363 5374 5364 5375 if (newStorage == 0) 5365 5376 return STG_E_INSUFFICIENTMEMORY; … … 5372 5383 TRUE, 5373 5384 TRUE); 5374 5385 5375 5386 if (FAILED(hr)) 5376 5387 { … … 5398 5409 DWORD grfMode, 5399 5410 SNB snbExclude, 5400 DWORD reserved, 5411 DWORD reserved, 5401 5412 IStorage **ppstgOpen) 5402 5413 { … … 5407 5418 DWORD accessMode; 5408 5419 5409 TRACE("(%s, %p, %lx, %p, %ld, %p)\n", 5410 5411 5420 TRACE("(%s, %p, %lx, %p, %ld, %p)\n", 5421 debugstr_w(pwcsName), pstgPriority, grfMode, 5422 snbExclude, reserved, ppstgOpen); 5412 5423 5413 5424 /* … … 5433 5444 */ 5434 5445 *ppstgOpen = 0; 5435 5436 hFile = CreateFileW( pwcsName, 5446 5447 hFile = CreateFileW( pwcsName, 5437 5448 accessMode, 5438 5449 shareMode, … … 5441 5452 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 5442 5453 0); 5443 5444 5454 5455 5445 5456 if (hFile==INVALID_HANDLE_VALUE) 5446 5457 { … … 5478 5489 */ 5479 5490 newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); 5480 5491 5481 5492 if (newStorage == 0) 5482 5493 return STG_E_INSUFFICIENTMEMORY; … … 5489 5500 TRUE, 5490 5501 FALSE); 5491 5502 5492 5503 if (FAILED(hr)) 5493 5504 { … … 5497 5508 */ 5498 5509 if(hr == STG_E_INVALIDHEADER) 5499 5510 return STG_E_FILEALREADYEXISTS; 5500 5511 return hr; 5501 5512 } 5502 5513 5503 5514 /* 5504 5515 * Get an "out" pointer for the caller. … … 5508 5519 (REFIID)&IID_IStorage, 5509 5520 (void**)ppstgOpen); 5510 5521 5511 5522 return hr; 5512 5523 } … … 5560 5571 (void**)ppstgOpen); 5561 5572 5562 return hr; 5573 return hr; 5563 5574 } 5564 5575 … … 5598 5609 */ 5599 5610 newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageImpl)); 5600 5611 5601 5612 if (newStorage == 0) 5602 5613 return STG_E_INSUFFICIENTMEMORY; … … 5634 5645 HRESULT WINAPI StgSetTimes(WCHAR * str, FILETIME * a, FILETIME * b, FILETIME *c ) 5635 5646 { 5636 5647 5637 5648 FIXME("(%p, %p, %p, %p),stub!\n", str, a, b, c); 5638 5649 return FALSE; … … 5685 5696 STATSTG pstatstg; 5686 5697 HRESULT hRes; 5687 5698 5688 5699 TRACE("()\n"); 5689 5700 … … 5708 5719 HRESULT WINAPI OleLoadFromStream(IStream *pStm,REFIID iidInterface,void** ppvObj) 5709 5720 { 5710 CLSID 5711 HRESULT 5712 LPPERSISTSTREAM 5721 CLSID clsid; 5722 HRESULT res; 5723 LPPERSISTSTREAM xstm; 5713 5724 5714 5725 TRACE("(%p,%s,%p)\n",pStm,debugstr_guid(iidInterface),ppvObj); … … 5716 5727 res=ReadClassStm(pStm,&clsid); 5717 5728 if (!SUCCEEDED(res)) 5718 5729 return res; 5719 5730 res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj); 5720 5731 if (!SUCCEEDED(res)) 5721 5732 return res; 5722 5733 res=IUnknown_QueryInterface((IUnknown*)*ppvObj,&IID_IPersistStream,(LPVOID*)&xstm); 5723 5734 if (!SUCCEEDED(res)) { 5724 5725 5735 IUnknown_Release((IUnknown*)*ppvObj); 5736 return res; 5726 5737 } 5727 5738 res=IPersistStream_Load(xstm,pStm); 5728 5739 IPersistStream_Release(xstm); 5729 5740 /* FIXME: all refcounts ok at this point? I think they should be: 5730 * pStm: unchanged5731 * ppvObj: 15732 * xstm: 0 (released)5741 * pStm : unchanged 5742 * ppvObj : 1 5743 * xstm : 0 (released) 5733 5744 */ 5734 5745 return res; … … 5746 5757 CLSID clsid; 5747 5758 HRESULT res; 5748 5759 5749 5760 TRACE("(%p,%p)\n",pPStm,pStm); 5750 5761 … … 5752 5763 5753 5764 if (SUCCEEDED(res)){ 5754 5765 5755 5766 res=WriteClassStm(pStm,&clsid); 5756 5767 … … 5770 5781 * STGM_TRANSACTED 0x00010000 5771 5782 * STGM_SIMPLE 0x08000000 5772 * 5783 * 5773 5784 * STGM_READ 0x00000000 5774 5785 * STGM_WRITE 0x00000001 5775 5786 * STGM_READWRITE 0x00000002 5776 * 5787 * 5777 5788 * STGM_SHARE_DENY_NONE 0x00000040 5778 5789 * STGM_SHARE_DENY_READ 0x00000030 5779 5790 * STGM_SHARE_DENY_WRITE 0x00000020 5780 5791 * STGM_SHARE_EXCLUSIVE 0x00000010 5781 * 5792 * 5782 5793 * STGM_PRIORITY 0x00040000 5783 5794 * STGM_DELETEONRELEASE 0x04000000 … … 5795 5806 BOOL bSTGM_SIMPLE = ((stgm & STGM_SIMPLE) == STGM_SIMPLE); 5796 5807 BOOL bSTGM_DIRECT = ! (bSTGM_TRANSACTED || bSTGM_SIMPLE); 5797 5808 5798 5809 BOOL bSTGM_WRITE = ((stgm & STGM_WRITE) == STGM_WRITE); 5799 5810 BOOL bSTGM_READWRITE = ((stgm & STGM_READWRITE) == STGM_READWRITE); 5800 5811 BOOL bSTGM_READ = ! (bSTGM_WRITE || bSTGM_READWRITE); 5801 5812 5802 5813 BOOL bSTGM_SHARE_DENY_NONE = 5803 5814 ((stgm & STGM_SHARE_DENY_NONE) == STGM_SHARE_DENY_NONE); … … 5814 5825 BOOL bSTGM_CREATE = ((stgm & STGM_CREATE) == STGM_CREATE); 5815 5826 BOOL bSTGM_CONVERT = ((stgm & STGM_CONVERT) == STGM_CONVERT); 5816 5827 5817 5828 BOOL bSTGM_NOSCRATCH = ((stgm & STGM_NOSCRATCH) == STGM_NOSCRATCH); 5818 5829 BOOL bSTGM_NOSNAPSHOT = ((stgm & STGM_NOSNAPSHOT) == STGM_NOSNAPSHOT); 5819 5830 5820 /* 5831 /* 5821 5832 * STGM_DIRECT | STGM_TRANSACTED | STGM_SIMPLE 5822 5833 */ … … 5825 5836 return E_FAIL; 5826 5837 5827 /* 5838 /* 5828 5839 * STGM_WRITE | STGM_READWRITE | STGM_READ 5829 5840 */ … … 5833 5844 5834 5845 /* 5835 * STGM_SHARE_DENY_NONE | others 5846 * STGM_SHARE_DENY_NONE | others 5836 5847 * (I assume here that DENY_READ implies DENY_WRITE) 5837 5848 */ 5838 5849 if ( bSTGM_SHARE_DENY_NONE ) 5839 5850 if ( bSTGM_SHARE_DENY_READ || 5840 bSTGM_SHARE_DENY_WRITE || 5841 bSTGM_SHARE_EXCLUSIVE) 5851 bSTGM_SHARE_DENY_WRITE || 5852 bSTGM_SHARE_EXCLUSIVE) 5842 5853 return E_FAIL; 5843 5854 … … 5854 5865 if ( bSTGM_NOSCRATCH && ! bSTGM_TRANSACTED ) 5855 5866 return E_FAIL; 5856 5857 /* 5858 * STGM_NOSNAPSHOT requires STGM_TRANSACTED and 5867 5868 /* 5869 * STGM_NOSNAPSHOT requires STGM_TRANSACTED and 5859 5870 * not STGM_SHARE_EXCLUSIVE or STGM_SHARE_DENY_WRITE` 5860 5871 */ 5861 5872 if (bSTGM_NOSNAPSHOT) 5862 5873 { 5863 if ( ! ( bSTGM_TRANSACTED && 5874 if ( ! ( bSTGM_TRANSACTED && 5864 5875 !(bSTGM_SHARE_EXCLUSIVE || bSTGM_SHARE_DENY_WRITE)) ) 5865 5876 return E_FAIL; … … 5873 5884 * 5874 5885 * This method will return a share mode flag from a STGM value. 5875 * The STGM value is assumed valid. 5886 * The STGM value is assumed valid. 5876 5887 */ 5877 5888 static DWORD GetShareModeFromSTGM(DWORD stgm) … … 5943 5954 /* All other cases */ 5944 5955 if (stgm & ~ (STGM_CREATE|STGM_CONVERT)) 5945 5956 FIXME("unhandled storage mode : 0x%08lx\n",stgm & ~ (STGM_CREATE|STGM_CONVERT)); 5946 5957 return CREATE_NEW; 5947 5958 } … … 5949 5960 5950 5961 /************************************************************************* 5951 * OLECONVERT_LoadOLE10 [Internal] 5952 * 5953 * Loads the OLE10 STREAM to memory 5962 * OLECONVERT_LoadOLE10 [Internal] 5963 * 5964 * Loads the OLE10 STREAM to memory 5954 5965 * 5955 5966 * PARAMS … … 5964 5975 * NOTES 5965 5976 * This function is used by OleConvertOLESTREAMToIStorage only. 5966 * 5977 * 5967 5978 * Memory allocated for pData must be freed by the caller 5968 5979 */ 5969 5980 HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *pData, BOOL bStrem1) 5970 5981 { 5971 5972 5973 5974 5975 5976 5977 5978 5979 5980 5981 5982 5983 5984 5985 5986 5987 5988 5989 5990 5991 5992 5993 5994 5995 5996 5997 5998 5999 6000 6001 6002 6003 6004 6005 6006 6007 6008 6009 6010 6011 6012 6013 6014 6015 6016 6017 6018 6019 6020 6021 6022 6023 6024 6025 6026 6027 6028 6029 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 6043 6044 6045 6046 6047 6048 6049 6050 6051 6052 6053 6054 6055 6056 6057 6058 6059 6060 6061 6062 6063 6064 6065 6066 6067 6068 6069 6070 6071 6072 6073 6074 6075 6076 6077 6078 6079 6080 6081 6082 6083 6084 6085 6086 6087 6088 6089 6090 6091 6092 6093 6094 6095 6096 6097 6098 6099 6100 6101 6102 6103 6104 6105 6106 6107 6108 6109 6110 6111 6112 6113 6114 6115 6116 6117 5982 DWORD dwSize; 5983 HRESULT hRes = S_OK; 5984 int nTryCnt=0; 5985 int max_try = 6; 5986 5987 pData->pData = NULL; 5988 pData->pstrOleObjFileName = (CHAR *) NULL; 5989 5990 for( nTryCnt=0;nTryCnt < max_try; nTryCnt++) 5991 { 5992 /* Get the OleID */ 5993 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwOleID), sizeof(pData->dwOleID)); 5994 if(dwSize != sizeof(pData->dwOleID)) 5995 { 5996 hRes = CONVERT10_E_OLESTREAM_GET; 5997 } 5998 else if(pData->dwOleID != OLESTREAM_ID) 5999 { 6000 hRes = CONVERT10_E_OLESTREAM_FMT; 6001 } 6002 else 6003 { 6004 hRes = S_OK; 6005 break; 6006 } 6007 } 6008 6009 if(hRes == S_OK) 6010 { 6011 /* Get the TypeID...more info needed for this field */ 6012 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwTypeID), sizeof(pData->dwTypeID)); 6013 if(dwSize != sizeof(pData->dwTypeID)) 6014 { 6015 hRes = CONVERT10_E_OLESTREAM_GET; 6016 } 6017 } 6018 if(hRes == S_OK) 6019 { 6020 if(pData->dwTypeID != 0) 6021 { 6022 /* Get the lenght of the OleTypeName */ 6023 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *) &(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength)); 6024 if(dwSize != sizeof(pData->dwOleTypeNameLength)) 6025 { 6026 hRes = CONVERT10_E_OLESTREAM_GET; 6027 } 6028 6029 if(hRes == S_OK) 6030 { 6031 if(pData->dwOleTypeNameLength > 0) 6032 { 6033 /* Get the OleTypeName */ 6034 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)pData->strOleTypeName, pData->dwOleTypeNameLength); 6035 if(dwSize != pData->dwOleTypeNameLength) 6036 { 6037 hRes = CONVERT10_E_OLESTREAM_GET; 6038 } 6039 } 6040 } 6041 if(bStrem1) 6042 { 6043 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwOleObjFileNameLength), sizeof(pData->dwOleObjFileNameLength)); 6044 if(dwSize != sizeof(pData->dwOleObjFileNameLength)) 6045 { 6046 hRes = CONVERT10_E_OLESTREAM_GET; 6047 } 6048 if(hRes == S_OK) 6049 { 6050 if(pData->dwOleObjFileNameLength < 1) /* there is no file name exist */ 6051 pData->dwOleObjFileNameLength = sizeof(pData->dwOleObjFileNameLength); 6052 pData->pstrOleObjFileName = (CHAR *)malloc(pData->dwOleObjFileNameLength); 6053 if(pData->pstrOleObjFileName) 6054 { 6055 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)(pData->pstrOleObjFileName),pData->dwOleObjFileNameLength); 6056 if(dwSize != pData->dwOleObjFileNameLength) 6057 { 6058 hRes = CONVERT10_E_OLESTREAM_GET; 6059 } 6060 } 6061 else 6062 hRes = CONVERT10_E_OLESTREAM_GET; 6063 } 6064 } 6065 else 6066 { 6067 /* Get the Width of the Metafile */ 6068 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwMetaFileWidth), sizeof(pData->dwMetaFileWidth)); 6069 if(dwSize != sizeof(pData->dwMetaFileWidth)) 6070 { 6071 hRes = CONVERT10_E_OLESTREAM_GET; 6072 } 6073 if(hRes == S_OK) 6074 { 6075 /* Get the Height of the Metafile */ 6076 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwMetaFileHeight), sizeof(pData->dwMetaFileHeight)); 6077 if(dwSize != sizeof(pData->dwMetaFileHeight)) 6078 { 6079 hRes = CONVERT10_E_OLESTREAM_GET; 6080 } 6081 } 6082 } 6083 if(hRes == S_OK) 6084 { 6085 /* Get the Lenght of the Data */ 6086 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)&(pData->dwDataLength), sizeof(pData->dwDataLength)); 6087 if(dwSize != sizeof(pData->dwDataLength)) 6088 { 6089 hRes = CONVERT10_E_OLESTREAM_GET; 6090 } 6091 } 6092 6093 if(hRes == S_OK) /* I don't know what is this 8 byts information is we have to figure out */ 6094 { 6095 if(!bStrem1) /* if it is a second OLE stream data */ 6096 { 6097 pData->dwDataLength -= 8; 6098 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)(pData->strUnknown), sizeof(pData->strUnknown)); 6099 if(dwSize != sizeof(pData->strUnknown)) 6100 { 6101 hRes = CONVERT10_E_OLESTREAM_GET; 6102 } 6103 } 6104 } 6105 if(hRes == S_OK) 6106 { 6107 if(pData->dwDataLength > 0) 6108 { 6109 pData->pData = (BYTE *)HeapAlloc(GetProcessHeap(),0,pData->dwDataLength); 6110 6111 /* Get Data (ex. IStorage, Metafile, or BMP) */ 6112 if(pData->pData) 6113 { 6114 dwSize = pOleStream->lpstbl->Get(pOleStream, (void *)pData->pData, pData->dwDataLength); 6115 if(dwSize != pData->dwDataLength) 6116 { 6117 hRes = CONVERT10_E_OLESTREAM_GET; 6118 } 6119 } 6120 else 6121 { 6122 hRes = CONVERT10_E_OLESTREAM_GET; 6123 } 6124 } 6125 } 6126 } 6127 } 6128 return hRes; 6118 6129 } 6119 6130 6120 6131 /************************************************************************* 6121 * OLECONVERT_SaveOLE10 [Internal] 6122 * 6123 * Saves the OLE10 STREAM From memory 6132 * OLECONVERT_SaveOLE10 [Internal] 6133 * 6134 * Saves the OLE10 STREAM From memory 6124 6135 * 6125 6136 * PARAMS … … 6133 6144 * NOTES 6134 6145 * This function is used by OleConvertIStorageToOLESTREAM only. 6135 * 6146 * 6136 6147 */ 6137 6148 HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleStream) … … 6227 6238 6228 6239 /************************************************************************* 6229 * OLECONVERT_GetOLE20FromOLE10[Internal] 6240 * OLECONVERT_GetOLE20FromOLE10[Internal] 6230 6241 * 6231 6242 * This function copies OLE10 Data (the IStorage in the OLESTREAM) to disk, 6232 * opens it, and copies the content to the dest IStorage for 6243 * opens it, and copies the content to the dest IStorage for 6233 6244 * OleConvertOLESTREAMToIStorage 6234 * 6245 * 6235 6246 * 6236 6247 * PARAMS … … 6243 6254 * 6244 6255 * NOTES 6245 * 6246 * 6256 * 6257 * 6247 6258 */ 6248 6259 void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD nBufferLength) … … 6279 6290 6280 6291 /************************************************************************* 6281 * OLECONVERT_WriteOLE20ToBuffer [Internal] 6282 * 6283 * Saves the OLE10 STREAM From memory 6292 * OLECONVERT_WriteOLE20ToBuffer [Internal] 6293 * 6294 * Saves the OLE10 STREAM From memory 6284 6295 * 6285 6296 * PARAMS … … 6294 6305 * 6295 6306 * Used by OleConvertIStorageToOLESTREAM only. 6296 * 6307 * 6297 6308 */ 6298 6309 DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData) … … 6306 6317 6307 6318 *pData = NULL; 6308 6319 6309 6320 /* Create temp Storage */ 6310 6321 GetTempPathW(MAX_PATH, wstrTempDir); … … 6333 6344 6334 6345 /************************************************************************* 6335 * OLECONVERT_CreateOleStream [Internal] 6346 * OLECONVERT_CreateOleStream [Internal] 6336 6347 * 6337 6348 * Creates the "\001OLE" stream in the IStorage if neccessary. … … 6348 6359 * This stream is still unknown, MS Word seems to have extra data 6349 6360 * but since the data is stored in the OLESTREAM there should be 6350 * no need to recreate the stream. If the stream is manually 6361 * no need to recreate the stream. If the stream is manually 6351 6362 * deleted it will create it with this default data. 6352 * 6363 * 6353 6364 */ 6354 6365 void OLECONVERT_CreateOleStream(LPSTORAGE pStorage) … … 6357 6368 IStream *pStream; 6358 6369 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 6359 BYTE pOleStreamHeader [] = 6360 { 6361 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 6362 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6363 0x00, 0x00, 0x00, 0x00 6370 BYTE pOleStreamHeader [] = 6371 { 6372 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 6373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6374 0x00, 0x00, 0x00, 0x00 6364 6375 }; 6365 6376 6366 6377 /* Create stream if not present */ 6367 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6378 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6368 6379 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6369 6380 … … 6378 6389 6379 6390 /************************************************************************* 6380 * OLECONVERT_CreateCompObjStream [Internal] 6391 * OLECONVERT_CreateCompObjStream [Internal] 6381 6392 * 6382 6393 * Creates a "\001CompObj" is the destination IStorage if necessary. 6383 6394 * 6384 6395 * PARAMS 6385 * pStorage [I] The dest IStorage to create the CompObj Stream 6396 * pStorage [I] The dest IStorage to create the CompObj Stream 6386 6397 * if necessary. 6387 6398 * strOleTypeName [I] The ProgID … … 6395 6406 * 6396 6407 * The stream data is stored in the OLESTREAM and there should be 6397 * no need to recreate the stream. If the stream is manually 6408 * no need to recreate the stream. If the stream is manually 6398 6409 * deleted it will attempt to create it by querying the registry. 6399 6410 * 6400 * 6411 * 6401 6412 */ 6402 6413 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) … … 6417 6428 6418 6429 /* Create a CompObj stream if it doesn't exist */ 6419 hStorageRes = IStorage_CreateStream(pStorage, wstrStreamName, 6430 hStorageRes = IStorage_CreateStream(pStorage, wstrStreamName, 6420 6431 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6421 6432 if(hStorageRes == S_OK) … … 6438 6449 LONG hErr; 6439 6450 /* Get the CLSID Default Name from the Registry */ 6440 hErr = RegOpenKeyA(HKEY_CLASSES_ROOT, IStorageCompObj.strProgIDName, &hKey); 6451 hErr = RegOpenKeyA(HKEY_CLASSES_ROOT, IStorageCompObj.strProgIDName, &hKey); 6441 6452 if(hErr == ERROR_SUCCESS) 6442 6453 { … … 6480 6491 6481 6492 /************************************************************************* 6482 * OLECONVERT_CreateOlePresStream[Internal] 6493 * OLECONVERT_CreateOlePresStream[Internal] 6483 6494 * 6484 6495 * Creates the "\002OlePres000" Stream with the Metafile data … … 6487 6498 * pStorage [I] The dest IStorage to create \002OLEPres000 stream in. 6488 6499 * dwExtentX [I] Width of the Metafile 6489 * dwExtentY [I] Height of the Metafile 6500 * dwExtentY [I] Height of the Metafile 6490 6501 * pData [I] Metafile data 6491 6502 * dwDataLength [I] Size of the Metafile data … … 6497 6508 * NOTES 6498 6509 * This function is used by OleConvertOLESTREAMToIStorage only. 6499 * 6510 * 6500 6511 */ 6501 6512 void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX, DWORD dwExtentY , BYTE *pData, DWORD dwDataLength) … … 6504 6515 IStream *pStream; 6505 6516 WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; 6506 BYTE pOlePresStreamHeader [] = 6507 { 6508 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 6509 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6517 BYTE pOlePresStreamHeader [] = 6518 { 6519 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 6520 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6510 6521 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 6511 6522 0x00, 0x00, 0x00, 0x00 6512 6523 }; 6513 6524 6514 BYTE pOlePresStreamHeaderEmpty [] = 6515 { 6516 0x00, 0x00, 0x00, 0x00, 6517 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6525 BYTE pOlePresStreamHeaderEmpty [] = 6526 { 6527 0x00, 0x00, 0x00, 0x00, 6528 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6518 6529 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 6519 6530 0x00, 0x00, 0x00, 0x00 6520 6531 }; 6521 6532 6522 6533 /* Create the OlePres000 Stream */ 6523 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6534 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6524 6535 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6525 6536 … … 6565 6576 6566 6577 /************************************************************************* 6567 * OLECONVERT_CreateOle10NativeStream [Internal] 6578 * OLECONVERT_CreateOle10NativeStream [Internal] 6568 6579 * 6569 6580 * Creates the "\001Ole10Native" Stream (should contain a BMP) … … 6581 6592 * 6582 6593 * Might need to verify the data and return appropriate error message 6583 * 6594 * 6584 6595 */ 6585 6596 void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD dwDataLength) … … 6588 6599 IStream *pStream; 6589 6600 WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; 6590 6601 6591 6602 /* Create the Ole10Native Stream */ 6592 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6603 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6593 6604 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6594 6605 … … 6604 6615 6605 6616 /************************************************************************* 6606 * OLECONVERT_GetOLE10ProgID [Internal] 6617 * OLECONVERT_GetOLE10ProgID [Internal] 6607 6618 * 6608 6619 * Finds the ProgID (or OleTypeID) from the IStorage … … 6620 6631 * This function is used by OleConvertIStorageToOLESTREAM only. 6621 6632 * 6622 * 6633 * 6623 6634 */ 6624 6635 HRESULT OLECONVERT_GetOLE10ProgID(LPSTORAGE pStorage, char *strProgID, DWORD *dwSize) … … 6631 6642 6632 6643 /* Open the CompObj Stream */ 6633 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6644 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6634 6645 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6635 6646 if(hRes == S_OK) … … 6668 6679 *dwSize = WideCharToMultiByte(CP_ACP, 0, wstrProgID, -1, strProgID, *dwSize, NULL, FALSE); 6669 6680 } 6670 6681 6671 6682 } 6672 6683 return hRes; … … 6674 6685 6675 6686 /************************************************************************* 6676 * OLECONVERT_GetOle10PresData [Internal] 6687 * OLECONVERT_GetOle10PresData [Internal] 6677 6688 * 6678 6689 * Converts IStorage "/001Ole10Native" stream to a OLE10 Stream … … 6689 6700 * 6690 6701 * Memory allocated for pData must be freed by the caller 6691 * 6692 * 6702 * 6703 * 6693 6704 */ 6694 6705 void OLECONVERT_GetOle10PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) … … 6710 6721 6711 6722 /* Open Ole10Native Stream */ 6712 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6723 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6713 6724 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6714 6725 if(hRes == S_OK) … … 6729 6740 6730 6741 /************************************************************************* 6731 * OLECONVERT_GetOle20PresData[Internal] 6742 * OLECONVERT_GetOle20PresData[Internal] 6732 6743 * 6733 6744 * Converts IStorage "/002OlePres000" stream to a OLE10 Stream … … 6742 6753 * NOTES 6743 6754 * This function is used by OleConvertIStorageToOLESTREAM only. 6744 * 6755 * 6745 6756 * Memory allocated for pData must be freed by the caller 6746 6757 */ … … 6769 6780 6770 6781 /* Open OlePress000 stream */ 6771 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6782 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6772 6783 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6773 6784 if(hRes == S_OK) … … 6817 6828 6818 6829 /************************************************************************* 6819 * OleConvertOLESTREAMToIStorage [OLE32.87] 6830 * OleConvertOLESTREAMToIStorage [OLE32.87] 6820 6831 * 6821 6832 * Read info on MSDN … … 6826 6837 * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", 6827 6838 * and "\001OLE" streams 6828 * 6839 * 6829 6840 */ 6830 6841 HRESULT WINAPI OleConvertOLESTREAMToIStorage ( 6831 LPOLESTREAM pOleStream, 6832 LPSTORAGE pstg, 6842 LPOLESTREAM pOleStream, 6843 LPSTORAGE pstg, 6833 6844 const DVTARGETDEVICE* ptd) 6834 6845 { … … 6902 6913 } 6903 6914 if(pOleStreamData[i].pstrOleObjFileName != NULL) 6904 6905 6906 6907 6915 { 6916 HeapFree(GetProcessHeap(),0,pOleStreamData[i].pstrOleObjFileName); 6917 pOleStreamData[i].pstrOleObjFileName = NULL; 6918 } 6908 6919 } 6909 6920 return hRes; … … 6921 6932 * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", 6922 6933 * and "\001OLE" streams. 6923 * 6934 * 6924 6935 */ 6925 6936 HRESULT WINAPI OleConvertIStorageToOLESTREAM ( 6926 LPSTORAGE pstg, 6937 LPSTORAGE pstg, 6927 6938 LPOLESTREAM pOleStream) 6928 6939 { … … 6949 6960 { 6950 6961 /*Was it originaly Ole10 */ 6951 hRes = IStorage_OpenStream(pstg, wstrStreamName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream); 6962 hRes = IStorage_OpenStream(pstg, wstrStreamName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream); 6952 6963 if(hRes == S_OK) 6953 6964 { … … 6984 6995 6985 6996 /*********************************************************************** 6986 * 6997 * GetConvertStg (OLE32.68) 6987 6998 */ 6988 6999 HRESULT WINAPI GetConvertStg(LPGUID guid) { … … 6998 7009 */ 6999 7010 HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn) { 7000 HFILEhf;7001 OFSTRUCTofs;7002 BYTEmagic[24];7003 7004 7005 7006 7007 7008 7009 7010 7011 7012 7013 7014 7015 7016 7017 7018 7019 7020 7021 7022 7023 7024 7025 7026 7027 7028 7029 7030 7011 HFILE hf; 7012 OFSTRUCT ofs; 7013 BYTE magic[24]; 7014 7015 TRACE("(\'%s\')\n",fn); 7016 hf = OpenFile(fn,&ofs,OF_SHARE_DENY_NONE); 7017 if (hf==HFILE_ERROR) 7018 return STG_E_FILENOTFOUND; 7019 if (24!=_lread(hf,magic,24)) { 7020 WARN(" too short\n"); 7021 _lclose(hf); 7022 return S_FALSE; 7023 } 7024 if (!memcmp(magic,STORAGE_magic,8)) { 7025 WARN(" -> YES\n"); 7026 _lclose(hf); 7027 return S_OK; 7028 } 7029 if (!memcmp(magic,STORAGE_notmagic,8)) { 7030 WARN(" -> NO\n"); 7031 _lclose(hf); 7032 return S_FALSE; 7033 } 7034 if (!memcmp(magic,STORAGE_oldmagic,8)) { 7035 WARN(" -> old format\n"); 7036 _lclose(hf); 7037 return STG_E_OLDFORMAT; 7038 } 7039 WARN(" -> Invalid header.\n"); 7040 _lclose(hf); 7041 return STG_E_INVALIDHEADER; 7031 7042 } 7032 7043 … … 7034 7045 * StgIsStorageFile [OLE32.146] 7035 7046 */ 7036 HRESULT WINAPI 7037 StgIsStorageFile(LPCOLESTR fn) 7038 { 7039 LPOLESTR16xfn = HEAP_strdupWtoA(GetProcessHeap(),0,fn);7040 HRESULTret = StgIsStorageFile16(xfn);7041 7042 7043 7047 HRESULT WINAPI 7048 StgIsStorageFile(LPCOLESTR fn) 7049 { 7050 LPOLESTR16 xfn = HEAP_strdupWtoA(GetProcessHeap(),0,fn); 7051 HRESULT ret = StgIsStorageFile16(xfn); 7052 7053 HeapFree(GetProcessHeap(),0,xfn); 7054 return ret; 7044 7055 } 7045 7056 #endif
Note:
See TracChangeset
for help on using the changeset viewer.