Changeset 3167 for trunk/src/ole32/storage.cpp
- Timestamp:
- Mar 19, 2000, 4:35:32 PM (25 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/ole32/storage.cpp
r1033 r3167 1 /* $Id: storage.cpp,v 1. 1 1999-09-24 21:49:44davidr Exp $ */1 /* $Id: storage.cpp,v 1.2 2000-03-19 15:33:08 davidr Exp $ */ 2 2 /* 3 3 * Compound Storage functions. … … 26 26 #include "storage.h" 27 27 28 #include "winnls.h" 29 #include "winreg.h" 30 #include "wine/wingdi16.h" 31 28 32 DEFAULT_DEBUG_CHANNEL(storage) 29 33 30 34 #define FILE_BEGIN 0 31 35 36 37 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 38 #define OLESTREAM_ID 0x501 39 #define OLESTREAM_MAX_STR_LEN 255 40 41 #define OLECONVERT_NUM_OLE10STREAMS 2 42 43 #define OLECONVERT_LINK_TYPE 1L 44 #define OLECONVERT_EMBEDDED_TYPE 2L 45 #define OLECONVERT_PRESENTATION_DATA_TYPE 5L 46 32 47 static const char rootPropertyName[] = "Root Entry"; 48 49 50 /* OLESTREAM memory structure to use for Get and Put Routines */ 51 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 52 typedef struct 53 { 54 DWORD dwOleID; 55 DWORD dwObjectTypeID; 56 DWORD dwOleTypeNameLength; 57 CHAR strOleTypeName[OLESTREAM_MAX_STR_LEN]; 58 DWORD dwLinkFileNameLength; 59 BYTE *strLinkFileName; 60 DWORD dwLinkExtraInfoLength; 61 BYTE *pLinkExtraInfo; 62 DWORD dwMetaFileWidth; 63 DWORD dwMetaFileHeight; 64 DWORD dwDataLength; 65 BYTE *pData; 66 }OLECONVERT_OLESTREAM_DATA; 67 68 /* CompObj Stream structure */ 69 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 70 typedef struct 71 { 72 BYTE byUnknown1[12]; 73 CLSID clsid; 74 DWORD dwCLSIDNameLength; 75 CHAR strCLSIDName[OLESTREAM_MAX_STR_LEN]; 76 DWORD dwOleTypeNameLength; 77 CHAR strOleTypeName[OLESTREAM_MAX_STR_LEN]; 78 DWORD dwProgIDNameLength; 79 CHAR strProgIDName[OLESTREAM_MAX_STR_LEN]; 80 BYTE byUnknown2[16]; 81 }OLECONVERT_ISTORAGE_COMPOBJ; 82 83 84 /* Ole Presention Stream structure */ 85 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 86 typedef struct 87 { 88 BYTE byUnknown1[28]; 89 DWORD dwExtentX; 90 DWORD dwExtentY; 91 DWORD dwSize; 92 BYTE *pData; 93 }OLECONVERT_ISTORAGE_OLEPRES; 94 95 96 /* Ole Stream Structure */ 97 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 98 typedef struct 99 { 100 DWORD dwOLEHEADER_ID; 101 DWORD dwUnknown1; 102 DWORD dwUnknown2; 103 DWORD dwUnknown3; 104 DWORD dwUnknown4; /*Only used when using a Moniker is present in the /001Ole Stream*/ 105 DWORD dwUnknown5; /*Only used when using a Moniker is present in the /001Ole stream*/ 106 DWORD dwObjectCLSIDOffset; 107 CLSID clsidMonikerTypeID; 108 /*Save info for clsidMonikerTypeID (eg. FileMoniker, ItemMoniker, or CompositeMoniker) */ 109 DWORD dwUnknown6; 110 CLSID clsidObject; 111 BYTE dwUnknown7[32]; 112 }OLECONVERT_ISTORAGE_OLE; 113 114 115 33 116 34 117 /*********************************************************************** … … 37 120 static HRESULT deleteStorageProperty( 38 121 StorageImpl *parentStorage, 39 OLECHAR *propertyToDeleteName); 122 ULONG foundPropertyIndexToDelete, 123 StgProperty propertyToDelete); 40 124 41 125 static HRESULT deleteStreamProperty( … … 337 421 (currentProperty.propertyType==PROPTYPE_STREAM) ) 338 422 { 339 newStream = StgStreamImpl_Construct(This, foundPropertyIndex);423 newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex); 340 424 341 425 if (newStream!=0) … … 687 771 * non empty storage. 688 772 */ 773 StorageImpl_ReadProperty(This->ancestorStorage, 774 foundPropertyIndex, 775 ¤tProperty); 776 689 777 currentProperty.dirProperty = PROPERTY_NULL; 690 778 currentProperty.propertyType = PROPTYPE_STORAGE; … … 845 933 * Open the stream to return it. 846 934 */ 847 newStream = StgStreamImpl_Construct(This, newPropertyIndex);935 newStream = StgStreamImpl_Construct(This, grfMode, newPropertyIndex); 848 936 849 937 if (newStream != 0) … … 1593 1681 hr = deleteStorageProperty( 1594 1682 This, 1595 propertyToDelete.name); 1683 foundPropertyIndexToDelete, 1684 propertyToDelete); 1596 1685 } 1597 1686 else if ( propertyToDelete.propertyType == PROPTYPE_STREAM ) … … 1629 1718 static HRESULT deleteStorageProperty( 1630 1719 StorageImpl *parentStorage, 1631 OLECHAR *propertyToDeleteName) 1720 ULONG indexOfPropertyToDelete, 1721 StgProperty propertyToDelete) 1632 1722 { 1633 1723 IEnumSTATSTG *elements = 0; … … 1642 1732 hr = StorageBaseImpl_OpenStorage( 1643 1733 (IStorage*)parentStorage, 1644 propertyToDelete Name,1734 propertyToDelete.name, 1645 1735 0, 1646 1736 STGM_SHARE_EXCLUSIVE, … … 1682 1772 } while ((hr == S_OK) && (destroyHr == S_OK)); 1683 1773 1774 /* 1775 * Invalidate the property by zeroing it's name member. 1776 */ 1777 propertyToDelete.sizeOfNameString = 0; 1778 1779 StorageImpl_WriteProperty(parentStorage->ancestorStorage, 1780 indexOfPropertyToDelete, 1781 &propertyToDelete); 1782 1684 1783 IStorage_Release(childStorage); 1685 1784 IEnumSTATSTG_Release(elements); … … 1711 1810 (OLECHAR*)propertyToDelete.name, 1712 1811 NULL, 1713 STGM_ SHARE_EXCLUSIVE,1812 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 1714 1813 0, 1715 1814 &pis); … … 2027 2126 ILockBytes* pLkbyt, 2028 2127 DWORD openFlags, 2029 BOOL fileBased) 2128 BOOL fileBased, 2129 BOOL fileCreate) 2030 2130 { 2031 2131 HRESULT hr = S_OK; … … 2042 2142 * Initialize the virtual fgunction table. 2043 2143 */ 2044 This->lpvtbl= &Storage32Impl_Vtbl;2144 ICOM_VTBL(This) = &Storage32Impl_Vtbl; 2045 2145 This->v_destructor = &StorageImpl_Destroy; 2046 2146 … … 2070 2170 return E_FAIL; 2071 2171 2072 if ( openFlags & STGM_CREATE)2172 if (fileCreate) 2073 2173 { 2074 2174 ULARGE_INTEGER size; … … 2093 2193 This->extBigBlockDepotStart = BLOCK_END_OF_CHAIN; 2094 2194 This->extBigBlockDepotCount = 0; 2095 2096 2195 StorageImpl_SaveFileHeader(This); 2097 2196 … … 2151 2250 * Write the root property 2152 2251 */ 2153 if ( openFlags & STGM_CREATE)2252 if (fileCreate) 2154 2253 { 2155 2254 StgProperty rootProp; … … 2597 2696 if (depotBuffer!=0) 2598 2697 { 2599 int index; 2600 2601 for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++) 2602 { 2603 StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex); 2604 This->blockDepotCached[index] = nextBlockIndex; 2605 } 2698 StorageUtl_ReadDWords(depotBuffer, 0, This->blockDepotCached, 2699 NUM_BLOCKS_PER_DEPOT_BLOCK); 2606 2700 2607 2701 StorageImpl_ReleaseBigBlock(This, depotBuffer); … … 3034 3128 3035 3129 memcpy(currentProperty + OFFSET_PS_PROPERTYTYPE, &buffer->propertyType, 1); 3036 3037 /*3038 * Reassign the size in case of mistake....3039 */3040 buffer->sizeOfNameString = (lstrlenW(buffer->name)+1) * sizeof(WCHAR);3041 3130 3042 3131 StorageUtl_WriteWord( … … 3288 3377 * Initialize the virtual function table. 3289 3378 */ 3290 newStorage->lpvtbl= &Storage32InternalImpl_Vtbl;3379 ICOM_VTBL(newStorage) = &Storage32InternalImpl_Vtbl; 3291 3380 newStorage->v_destructor = &StorageInternalImpl_Destroy; 3292 3381 … … 3359 3448 * Set-up the virtual function table and reference count. 3360 3449 */ 3361 newEnumeration->lpvtbl= &IEnumSTATSTGImpl_Vtbl;3450 ICOM_VTBL(newEnumeration) = &IEnumSTATSTGImpl_Vtbl; 3362 3451 newEnumeration->ref = 0; 3363 3452 … … 3875 3964 { 3876 3965 memcpy(value, (BYTE*)buffer+offset, sizeof(DWORD)); 3966 } 3967 3968 void StorageUtl_ReadDWords(void *buffer, ULONG offset, DWORD *values, 3969 ULONG len) 3970 { 3971 memcpy(values, (BYTE*)buffer+offset, sizeof(DWORD)*len); 3877 3972 } 3878 3973 … … 3957 4052 { 3958 4053 BlockChainStream* newStream; 3959 ULONG blockIndex;3960 4054 3961 4055 newStream = (BlockChainStream *)HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream)); … … 3965 4059 newStream->ownerPropertyIndex = propertyIndex; 3966 4060 newStream->lastBlockNoInSequence = 0xFFFFFFFF; 4061 newStream->lazyInitComplete = FALSE; 3967 4062 newStream->tailIndex = BLOCK_END_OF_CHAIN; 3968 4063 newStream->numBlocks = 0; 3969 4064 3970 blockIndex = BlockChainStream_GetHeadOfChain(newStream);3971 3972 while (blockIndex != BLOCK_END_OF_CHAIN)3973 {3974 newStream->numBlocks++;3975 newStream->tailIndex = blockIndex;3976 3977 blockIndex = StorageImpl_GetNextBlockInChain(3978 parentStorage,3979 blockIndex);3980 }3981 3982 4065 return newStream; 4066 } 4067 4068 static void BlockChainStream_LazyInit(BlockChainStream *This) 4069 { 4070 ULONG numBlocks = 0; 4071 ULONG tailIndex = BLOCK_END_OF_CHAIN; 4072 StorageImpl *parentStorage = This->parentStorage; 4073 4074 ULONG blockIndex = BlockChainStream_GetHeadOfChain(This); 4075 4076 while (blockIndex != BLOCK_END_OF_CHAIN) 4077 { 4078 numBlocks++; 4079 tailIndex = blockIndex; 4080 4081 blockIndex = StorageImpl_GetNextBlockInChain(parentStorage, 4082 blockIndex); 4083 } 4084 4085 This->numBlocks = numBlocks; 4086 This->tailIndex = tailIndex; 4087 } 4088 4089 static inline ULONG BlockChainStream_TailIndex(BlockChainStream *This) 4090 { 4091 if (!This->lazyInitComplete) 4092 BlockChainStream_LazyInit(This); 4093 return This->tailIndex; 4094 } 4095 4096 static inline ULONG BlockChainStream_NumBlocks(BlockChainStream *This) 4097 { 4098 if (!This->lazyInitComplete) 4099 BlockChainStream_LazyInit(This); 4100 return This->numBlocks; 3983 4101 } 3984 4102 … … 4351 4469 * Go to the current end of chain 4352 4470 */ 4353 if (This->tailIndex == BLOCK_END_OF_CHAIN) 4354 { 4355 currentBlock = blockIndex; 4356 4357 while (blockIndex != BLOCK_END_OF_CHAIN) 4358 { 4359 This->numBlocks++; 4360 currentBlock = blockIndex; 4361 4362 blockIndex = 4363 StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock); 4364 } 4365 4366 This->tailIndex = currentBlock; 4367 } 4368 4369 currentBlock = This->tailIndex; 4370 oldNumBlocks = This->numBlocks; 4471 currentBlock = BlockChainStream_TailIndex(This); 4472 oldNumBlocks = BlockChainStream_NumBlocks(This); 4371 4473 4372 4474 /* … … 5205 5307 DWORD fileAttributes; 5206 5308 WCHAR tempFileName[MAX_PATH]; 5309 BOOL switchRemoteToLocalFile = TRUE; 5207 5310 5208 5311 TRACE("(%s, %lx, %ld, %p)\n", … … 5229 5332 WCHAR tempPath[MAX_PATH]; 5230 5333 WCHAR prefix[] = { 'S', 'T', 'O', 0 }; 5334 5335 switchRemoteToLocalFile = FALSE; 5231 5336 5232 5337 memset(tempPath, 0, sizeof(tempPath)); … … 5288 5393 NULL, 5289 5394 grfMode, 5395 TRUE, 5290 5396 TRUE); 5291 5397 … … 5352 5458 5353 5459 hFile = CreateFileW( pwcsName, 5354 5355 5356 NULL,5357 OPEN_EXISTING,5358 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,5359 0);5460 accessMode, 5461 shareMode, 5462 NULL, 5463 OPEN_EXISTING, 5464 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 5465 0); 5360 5466 5361 5467 5362 5468 if (hFile==INVALID_HANDLE_VALUE) 5363 5469 { 5364 return E_FAIL; 5470 HRESULT hr = E_FAIL; 5471 DWORD last_error = GetLastError(); 5472 5473 switch (last_error) 5474 { 5475 case ERROR_FILE_NOT_FOUND: 5476 hr = STG_E_FILENOTFOUND; 5477 break; 5478 5479 case ERROR_PATH_NOT_FOUND: 5480 hr = STG_E_PATHNOTFOUND; 5481 break; 5482 5483 case ERROR_ACCESS_DENIED: 5484 case ERROR_WRITE_PROTECT: 5485 hr = STG_E_ACCESSDENIED; 5486 break; 5487 5488 case ERROR_SHARING_VIOLATION: 5489 hr = STG_E_SHAREVIOLATION; 5490 break; 5491 5492 default: 5493 hr = E_FAIL; 5494 } 5495 5496 return hr; 5365 5497 } 5366 5498 … … 5378 5510 NULL, 5379 5511 grfMode, 5380 TRUE); 5512 TRUE, 5513 FALSE); 5381 5514 5382 5515 if (FAILED(hr)) … … 5428 5561 plkbyt, 5429 5562 grfMode, 5430 FALSE); 5563 FALSE, 5564 TRUE); 5431 5565 5432 5566 if (FAILED(hr)) … … 5491 5625 plkbyt, 5492 5626 grfMode, 5627 FALSE, 5493 5628 FALSE); 5494 5629 … … 5582 5717 HRESULT res; 5583 5718 5719 /* For this function to work. All registry keys related to Interface must be in */ 5720 /* Installed in the wine registry (eg. Search for IFileMoniker in the windows registry, */ 5721 /* copy the missing CLSID keys (and all contents) to wine registry). Implement */ 5722 /* the OLE32_DllGetClassObject (a big switch for all interface in OLE32.dll to allocate the */ 5723 /* actual interface ) */ 5584 5724 FIXME("(),stub!\n"); 5585 5725 … … 5587 5727 5588 5728 if (SUCCEEDED(res)){ 5589 5729 /* For this to work properly iidInterface should be IUnknown, need to Query */ 5730 /* for IPersitStream, if successful, query for iidInterface */ 5731 5590 5732 res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj); 5591 5733 … … 5619 5761 if (SUCCEEDED(res)) 5620 5762 5621 res=IPersistStream_Save(pPStm,pStm,FALSE); 5622 } 5623 5763 res=IPersistStream_Save(pPStm,pStm,TRUE); 5764 } 5765 5766 TRACE("Finished Save\n"); 5624 5767 return res; 5625 5768 } … … 5808 5951 } 5809 5952 5810 5953 BOOL OLECONVERT_IsStorageLink(LPSTORAGE pStorage) 5954 { 5955 STATSTG stat; 5956 5957 IStorage_Stat(pStorage, &stat, STATFLAG_NONAME); 5958 5959 return IsEqualCLSID(&IID_StdOleLink, &stat.clsid); 5960 } 5961 5962 /************************************************************************* 5963 * OLECONVERT_LoadOLE10 [Internal] 5964 * 5965 * Loads the OLE10 STREAM to memory 5966 * 5967 * PARAMS 5968 * pOleStream [I] The OLESTREAM 5969 * pData [I] Data Structure for the OLESTREAM Data 5970 * 5971 * RETURNS 5972 * Success: S_OK 5973 * Failure: CONVERT10_E_OLESTREAM_GET for invalid Get 5974 * CONVERT10_E_OLESTREAM_FMT if the OLEID is invalide 5975 * 5976 * NOTES 5977 * This function is used by OleConvertOLESTREAMToIStorage only. 5978 * 5979 * Memory allocated for pData must be freed by the caller 5980 */ 5981 HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *pData) 5982 { 5983 DWORD dwSize; 5984 pData->pData = NULL; 5985 pData->pLinkExtraInfo = NULL; 5986 pData->strLinkFileName = NULL; 5987 5988 /* Get the OleID */ 5989 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwOleID), sizeof(pData->dwOleID)); 5990 if(dwSize != sizeof(pData->dwOleID)) 5991 { 5992 return CONVERT10_E_OLESTREAM_GET; 5993 } 5994 else if(pData->dwOleID != OLESTREAM_ID) 5995 { 5996 return CONVERT10_E_OLESTREAM_FMT; 5997 } 5998 5999 /* Get the TypeID...more info needed for this field */ 6000 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwObjectTypeID), sizeof(pData->dwObjectTypeID)); 6001 6002 if(dwSize != sizeof(pData->dwObjectTypeID)) 6003 { 6004 return CONVERT10_E_OLESTREAM_GET; 6005 } 6006 if(pData->dwObjectTypeID != 0) 6007 { 6008 if(pData->dwObjectTypeID != OLECONVERT_LINK_TYPE 6009 && pData->dwObjectTypeID != OLECONVERT_EMBEDDED_TYPE 6010 && pData->dwObjectTypeID != OLECONVERT_PRESENTATION_DATA_TYPE) 6011 { 6012 FIXME("Unknown ObjectTypeID: %lx\n", pData->dwObjectTypeID); 6013 } 6014 6015 /* Get the lenght of the OleTypeName */ 6016 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) &(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength)); 6017 if(dwSize != sizeof(pData->dwOleTypeNameLength)) 6018 { 6019 return CONVERT10_E_OLESTREAM_GET; 6020 } 6021 if(pData->dwOleTypeNameLength > 0) 6022 { 6023 /* Get the OleTypeName */ 6024 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)pData->strOleTypeName, pData->dwOleTypeNameLength); 6025 if(dwSize != pData->dwOleTypeNameLength) 6026 { 6027 return CONVERT10_E_OLESTREAM_GET; 6028 } 6029 } 6030 if(pData->dwObjectTypeID == OLECONVERT_LINK_TYPE) 6031 { 6032 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) &(pData->dwLinkFileNameLength), sizeof(pData->dwLinkFileNameLength)); 6033 if(dwSize != sizeof(pData->dwLinkFileNameLength)) 6034 { 6035 return CONVERT10_E_OLESTREAM_GET; 6036 } 6037 6038 if(pData->dwLinkFileNameLength > 0) 6039 { 6040 pData->strLinkFileName = (BYTE *)malloc(pData->dwLinkFileNameLength); 6041 if(pData->strLinkFileName == NULL) 6042 { 6043 return E_OUTOFMEMORY; 6044 } 6045 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) pData->strLinkFileName, pData->dwLinkFileNameLength); 6046 if(dwSize != pData->dwLinkFileNameLength) 6047 { 6048 return CONVERT10_E_OLESTREAM_GET; 6049 } 6050 } 6051 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) &(pData->dwLinkExtraInfoLength), sizeof(pData->dwLinkExtraInfoLength)); 6052 if(dwSize != sizeof(pData->dwLinkExtraInfoLength)) 6053 { 6054 return CONVERT10_E_OLESTREAM_GET; 6055 } 6056 6057 if(pData->dwLinkExtraInfoLength > 0) 6058 { 6059 pData->pLinkExtraInfo = (BYTE *)malloc(pData->dwLinkExtraInfoLength); 6060 if(pData->pLinkExtraInfo == NULL) 6061 { 6062 return E_OUTOFMEMORY; 6063 } 6064 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) pData->pLinkExtraInfo, pData->dwLinkExtraInfoLength); 6065 if(dwSize != pData->dwLinkExtraInfoLength) 6066 { 6067 return CONVERT10_E_OLESTREAM_GET; 6068 } 6069 } 6070 } 6071 6072 /* Get the Width of the Metafile */ 6073 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwMetaFileWidth), sizeof(pData->dwMetaFileWidth)); 6074 if(dwSize != sizeof(pData->dwMetaFileWidth)) 6075 { 6076 return CONVERT10_E_OLESTREAM_GET; 6077 } 6078 6079 /* Get the Height of the Metafile */ 6080 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwMetaFileHeight), sizeof(pData->dwMetaFileHeight)); 6081 if(dwSize != sizeof(pData->dwMetaFileHeight)) 6082 { 6083 return CONVERT10_E_OLESTREAM_GET; 6084 } 6085 6086 /* Get the Length of the Data */ 6087 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwDataLength), sizeof(pData->dwDataLength)); 6088 if(dwSize != sizeof(pData->dwDataLength)) 6089 { 6090 return CONVERT10_E_OLESTREAM_GET; 6091 } 6092 if(pData->dwDataLength > 0) 6093 { 6094 pData->pData = (BYTE *)malloc(pData->dwDataLength); 6095 if(pData->pData == NULL) 6096 { 6097 return E_OUTOFMEMORY; 6098 } 6099 /* Get Data (ex. IStorage, Metafile, or BMP) */ 6100 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)pData->pData, pData->dwDataLength); 6101 if(dwSize != pData->dwDataLength) 6102 { 6103 return CONVERT10_E_OLESTREAM_GET; 6104 } 6105 } 6106 } 6107 return S_OK; 6108 } 6109 6110 6111 /************************************************************************* 6112 * OLECONVERT_SaveOLE10 [Internal] 6113 * 6114 * Saves the OLE10 STREAM From memory 6115 * 6116 * PARAMS 6117 * pData [I] Data Structure for the OLESTREAM Data 6118 * pOleStream [I] The OLESTREAM to save 6119 * 6120 * RETURNS 6121 * Success: S_OK 6122 * Failure: CONVERT10_E_OLESTREAM_PUT for invalid Put 6123 * 6124 * NOTES 6125 * This function is used by OleConvertIStorageToOLESTREAM only. 6126 * 6127 */ 6128 HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleStream) 6129 { 6130 DWORD dwSize; 6131 HRESULT hRes = S_OK; 6132 6133 6134 /* Set the OleID */ 6135 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwOleID), sizeof(pData->dwOleID)); 6136 if(dwSize != sizeof(pData->dwOleID)) 6137 { 6138 return CONVERT10_E_OLESTREAM_PUT; 6139 } 6140 6141 /* Set the TypeID */ 6142 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwObjectTypeID), sizeof(pData->dwObjectTypeID)); 6143 if(dwSize != sizeof(pData->dwObjectTypeID)) 6144 { 6145 return CONVERT10_E_OLESTREAM_PUT; 6146 } 6147 6148 if(pData->dwOleID == OLESTREAM_ID && pData->dwObjectTypeID != 0 && hRes == S_OK) 6149 { 6150 /* Set the Length of the OleTypeName */ 6151 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength)); 6152 if(dwSize != sizeof(pData->dwOleTypeNameLength)) 6153 { 6154 return CONVERT10_E_OLESTREAM_PUT; 6155 } 6156 6157 if(pData->dwOleTypeNameLength > 0) 6158 { 6159 /* Set the OleTypeName */ 6160 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->strOleTypeName, pData->dwOleTypeNameLength); 6161 if(dwSize != pData->dwOleTypeNameLength) 6162 { 6163 return CONVERT10_E_OLESTREAM_PUT; 6164 } 6165 } 6166 6167 if(pData->dwObjectTypeID == OLECONVERT_LINK_TYPE) 6168 { 6169 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) &(pData->dwLinkFileNameLength), sizeof(pData->dwLinkFileNameLength)); 6170 if(dwSize != sizeof(pData->dwLinkFileNameLength)) 6171 { 6172 return CONVERT10_E_OLESTREAM_GET; 6173 } 6174 6175 if(pData->dwLinkFileNameLength > 0) 6176 { 6177 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->strLinkFileName, pData->dwLinkFileNameLength); 6178 if(dwSize != pData->dwLinkFileNameLength) 6179 { 6180 return CONVERT10_E_OLESTREAM_GET; 6181 } 6182 } 6183 6184 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) &(pData->dwLinkExtraInfoLength), sizeof(pData->dwLinkExtraInfoLength)); 6185 if(dwSize != sizeof(pData->dwLinkExtraInfoLength)) 6186 { 6187 return CONVERT10_E_OLESTREAM_GET; 6188 } 6189 6190 if(pData->dwLinkExtraInfoLength > 0) 6191 { 6192 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->pLinkExtraInfo, pData->dwLinkExtraInfoLength); 6193 if(dwSize != pData->dwLinkExtraInfoLength) 6194 { 6195 return CONVERT10_E_OLESTREAM_GET; 6196 } 6197 } 6198 } 6199 6200 /* Set the width of the Metafile */ 6201 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwMetaFileWidth), sizeof(pData->dwMetaFileWidth)); 6202 if(dwSize != sizeof(pData->dwMetaFileWidth)) 6203 { 6204 return CONVERT10_E_OLESTREAM_PUT; 6205 } 6206 6207 /* Set the height of the Metafile */ 6208 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwMetaFileHeight), sizeof(pData->dwMetaFileHeight)); 6209 if(dwSize != sizeof(pData->dwMetaFileHeight)) 6210 { 6211 return CONVERT10_E_OLESTREAM_PUT; 6212 } 6213 6214 /* Set the lenght of the Data */ 6215 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwDataLength), sizeof(pData->dwDataLength)); 6216 if(dwSize != sizeof(pData->dwDataLength)) 6217 { 6218 return CONVERT10_E_OLESTREAM_PUT; 6219 } 6220 6221 if(pData->dwDataLength > 0) 6222 { 6223 /* Set the Data (eg. IStorage, Metafile, Bitmap) */ 6224 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->pData, pData->dwDataLength); 6225 if(dwSize != pData->dwDataLength) 6226 { 6227 return CONVERT10_E_OLESTREAM_PUT; 6228 } 6229 } 6230 } 6231 return S_OK; 6232 } 6233 6234 /************************************************************************* 6235 * OLECONVERT_GetOLE20FromOLE10[Internal] 6236 * 6237 * This function copies OLE10 Data (the IStorage in the OLESTREAM) to disk, 6238 * opens it, and copies the content to the dest IStorage for 6239 * OleConvertOLESTREAMToIStorage 6240 * 6241 * 6242 * PARAMS 6243 * pDestStorage [I] The IStorage to copy the data to 6244 * pBuffer [I] Buffer that contains the IStorage from the OLESTREAM 6245 * nBufferLength [I] The size of the buffer 6246 * 6247 * RETURNS 6248 * Nothing 6249 * 6250 * NOTES 6251 * 6252 * 6253 */ 6254 void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD nBufferLength) 6255 { 6256 HRESULT hRes; 6257 HANDLE hFile; 6258 IStorage *pTempStorage; 6259 DWORD dwNumOfBytesWritten; 6260 WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH]; 6261 WCHAR wstrPrefix[] = {'s', 'i', 's', 0}; 6262 6263 /* Create a temp File */ 6264 GetTempPathW(MAX_PATH, wstrTempDir); 6265 GetTempFileNameW(wstrTempDir, wstrPrefix, 0, wstrTempFile); 6266 hFile = CreateFileW(wstrTempFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 6267 6268 if(hFile != INVALID_HANDLE_VALUE) 6269 { 6270 /* Write IStorage Data to File */ 6271 WriteFile(hFile, pBuffer, nBufferLength, &dwNumOfBytesWritten, NULL); 6272 CloseHandle(hFile); 6273 6274 /* Open and copy temp storage to the Dest Storage */ 6275 hRes = StgOpenStorage(wstrTempFile, NULL, STGM_READ, NULL, 0, &pTempStorage); 6276 if(hRes == S_OK) 6277 { 6278 hRes = StorageImpl_CopyTo(pTempStorage, NULL,NULL,NULL, pDestStorage); 6279 StorageBaseImpl_Release(pTempStorage); 6280 } 6281 DeleteFileW(wstrTempFile); 6282 } 6283 } 6284 6285 6286 /************************************************************************* 6287 * OLECONVERT_WriteOLE20ToBuffer [Internal] 6288 * 6289 * Saves the OLE10 STREAM From memory 6290 * 6291 * PARAMS 6292 * pStorage [I] The Src IStorage to copy 6293 * pData [I] The Dest Memory to write to. 6294 * 6295 * RETURNS 6296 * The size in bytes allocated for pData 6297 * 6298 * NOTES 6299 * Memory allocated for pData must be freed by the caller 6300 * 6301 * Used by OleConvertIStorageToOLESTREAM only. 6302 * 6303 */ 6304 DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData) 6305 { 6306 HANDLE hFile; 6307 HRESULT hRes; 6308 DWORD nDataLength = 0; 6309 IStorage *pTempStorage; 6310 WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH]; 6311 WCHAR wstrPrefix[] = {'s', 'i', 's', 0}; 6312 6313 *pData = NULL; 6314 6315 /* Create temp Storage */ 6316 GetTempPathW(MAX_PATH, wstrTempDir); 6317 GetTempFileNameW(wstrTempDir, wstrPrefix, 0, wstrTempFile); 6318 hRes = StgCreateDocfile(wstrTempFile, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, &pTempStorage); 6319 6320 if(hRes == S_OK) 6321 { 6322 /* Copy Src Storage to the Temp Storage */ 6323 StorageImpl_CopyTo(pStorage, NULL,NULL,NULL, pTempStorage); 6324 StorageBaseImpl_Release(pTempStorage); 6325 6326 /* Open Temp Storage as a file and copy to memory */ 6327 hFile = CreateFileW(wstrTempFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 6328 if(hFile != INVALID_HANDLE_VALUE) 6329 { 6330 nDataLength = GetFileSize(hFile, NULL); 6331 *pData = (BYTE *) malloc(nDataLength); 6332 ReadFile(hFile, *pData, nDataLength, &nDataLength, 0); 6333 CloseHandle(hFile); 6334 } 6335 DeleteFileW(wstrTempFile); 6336 } 6337 return nDataLength; 6338 } 6339 6340 /************************************************************************* 6341 * OLECONVERT_CreateEmbeddedOleStream [Internal] 6342 * 6343 * Creates the "\001OLE" stream in the IStorage if neccessary. 6344 * 6345 * PARAMS 6346 * pStorage [I] Dest storage to create the stream in 6347 * 6348 * RETURNS 6349 * Nothing 6350 * 6351 * NOTES 6352 * This function is used by OleConvertOLESTREAMToIStorage only. 6353 * 6354 * This stream is still unknown, MS Word seems to have extra data 6355 * but since the data is stored in the OLESTREAM there should be 6356 * no need to recreate the stream. If the stream is manually 6357 * deleted it will create it with this default data. 6358 * 6359 */ 6360 void OLECONVERT_CreateEmbeddedOleStream(LPSTORAGE pStorage) 6361 { 6362 HRESULT hRes; 6363 IStream *pStream; 6364 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 6365 BYTE pOleStreamHeader [] = 6366 { 6367 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 6368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6369 0x00, 0x00, 0x00, 0x00 6370 }; 6371 6372 /* Create stream if not present */ 6373 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6374 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6375 6376 if(hRes == S_OK) 6377 { 6378 /* Write default Data */ 6379 hRes = IStream_Write(pStream, pOleStreamHeader, sizeof(pOleStreamHeader), NULL); 6380 IStream_Release(pStream); 6381 } 6382 } 6383 6384 /************************************************************************* 6385 * OLECONVERT_CreateLinkOleStream [Internal] 6386 * 6387 * Creates the "\001OLE" stream in the IStorage if neccessary. 6388 * 6389 * PARAMS 6390 * pStorage [I] Dest storage to create the stream in 6391 * 6392 * RETURNS 6393 * Nothing 6394 * 6395 * NOTES 6396 * This function is used by OleConvertOLESTREAMToIStorage only. 6397 * 6398 * This stream is still unknown, MS Word seems to have extra data 6399 * but since the data is stored in the OLESTREAM there should be 6400 * no need to recreate the stream. If the stream is manually 6401 * deleted it will create it with this default data. 6402 * 6403 */ 6404 HRESULT OLECONVERT_CreateLinkOleStream(LPSTORAGE pStorage, LPCSTR strProgID, LPCSTR strFileName, BYTE *pItemData, DWORD dwItemDataLength) 6405 { 6406 HRESULT hRes; 6407 IStream *pStream; 6408 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 6409 OLECONVERT_ISTORAGE_OLE OleStreamHeader; 6410 LPMONIKER pFileMoniker=NULL; 6411 LPMONIKER pItemMoniker=NULL; 6412 LPMONIKER pCompMoniker=NULL; 6413 LPMONIKER pDestMoniker=NULL; 6414 6415 6416 BYTE pUnknown7 [] = 6417 { 6418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6421 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 6422 }; 6423 6424 OleStreamHeader.dwOLEHEADER_ID = 0x02000001; 6425 OleStreamHeader.dwUnknown1 = 0x01; 6426 OleStreamHeader.dwUnknown2 = 0x01; 6427 OleStreamHeader.dwUnknown3 = 0x00; 6428 OleStreamHeader.dwUnknown4 = 0x00; 6429 OleStreamHeader.dwUnknown5 = 0x00; 6430 OleStreamHeader.dwUnknown6 = 0xFFFF; 6431 hRes = CLSIDFromProgID16(strProgID, &(OleStreamHeader.clsidObject)); 6432 memcpy(OleStreamHeader.dwUnknown7, pUnknown7, sizeof(pUnknown7)); 6433 6434 if(hRes != S_OK) 6435 { 6436 return REGDB_E_CLASSNOTREG; 6437 } 6438 6439 if(strFileName != NULL) 6440 { 6441 WCHAR wstrFileName[MAX_PATH]; 6442 MultiByteToWideChar(CP_ACP, 0, strFileName, -1, wstrFileName, MAX_PATH); 6443 hRes = CreateFileMoniker(wstrFileName, &pFileMoniker); 6444 } 6445 if(pItemData != NULL) 6446 { 6447 6448 WCHAR wstrDelim[] = {'!', 0}; 6449 WCHAR *wstrItem; 6450 6451 wstrItem = (LPWSTR) malloc(dwItemDataLength * sizeof(WCHAR)); 6452 6453 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pItemData, -1, wstrItem, dwItemDataLength); 6454 hRes = CreateItemMoniker(wstrDelim, wstrItem, &pItemMoniker); 6455 6456 free(wstrItem); 6457 } 6458 6459 if(pItemMoniker != NULL && pFileMoniker != NULL) 6460 { 6461 hRes = CreateGenericComposite(pFileMoniker, pItemMoniker, &pCompMoniker); 6462 } 6463 6464 if(hRes == S_OK) 6465 { 6466 6467 if(pCompMoniker != NULL) 6468 { 6469 pDestMoniker = pCompMoniker; 6470 } 6471 else if(pFileMoniker != NULL) 6472 { 6473 pDestMoniker = pFileMoniker; 6474 } 6475 else if(pItemMoniker != NULL) 6476 { 6477 pDestMoniker = pItemMoniker; 6478 } 6479 6480 6481 if(pDestMoniker != NULL) 6482 { 6483 ULARGE_INTEGER liFileMonikerSize; 6484 IMoniker_GetClassID(pDestMoniker, &(OleStreamHeader.clsidMonikerTypeID)); 6485 IMoniker_GetSizeMax(pDestMoniker, &liFileMonikerSize); 6486 OleStreamHeader.dwObjectCLSIDOffset = liFileMonikerSize.LowPart + sizeof(OleStreamHeader.dwUnknown6) + sizeof(OleStreamHeader.clsidMonikerTypeID); 6487 } 6488 6489 6490 /* Create stream (shouldn't be present)*/ 6491 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6492 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6493 6494 if(hRes == S_OK) 6495 { 6496 /* Write default Data */ 6497 IStream_Write(pStream, &(OleStreamHeader.dwOLEHEADER_ID), sizeof(OleStreamHeader.dwOLEHEADER_ID), NULL); 6498 IStream_Write(pStream, &(OleStreamHeader.dwUnknown1), sizeof(OleStreamHeader.dwUnknown1), NULL); 6499 IStream_Write(pStream, &(OleStreamHeader.dwUnknown2), sizeof(OleStreamHeader.dwUnknown2), NULL); 6500 IStream_Write(pStream, &(OleStreamHeader.dwUnknown3), sizeof(OleStreamHeader.dwUnknown3), NULL); 6501 IStream_Write(pStream, &(OleStreamHeader.dwUnknown4), sizeof(OleStreamHeader.dwUnknown4), NULL); 6502 IStream_Write(pStream, &(OleStreamHeader.dwUnknown5), sizeof(OleStreamHeader.dwUnknown5), NULL); 6503 IStream_Write(pStream, &(OleStreamHeader.dwObjectCLSIDOffset), sizeof(OleStreamHeader.dwObjectCLSIDOffset), NULL); 6504 /* Should call OleSaveToStream */ 6505 WriteClassStm(pStream, &(OleStreamHeader.clsidMonikerTypeID)); 6506 if(pDestMoniker != NULL) 6507 { 6508 IMoniker_Save(pDestMoniker, pStream, FALSE); 6509 } 6510 IStream_Write(pStream, &(OleStreamHeader.dwUnknown6), sizeof(OleStreamHeader.dwUnknown6), NULL); 6511 WriteClassStm(pStream, &(OleStreamHeader.clsidObject)); 6512 IStream_Write(pStream, OleStreamHeader.dwUnknown7, sizeof(OleStreamHeader.dwUnknown7), NULL); 6513 IStream_Release(pStream); 6514 } 6515 } 6516 if(pFileMoniker != NULL) 6517 { 6518 IMoniker_Release(pFileMoniker); 6519 } 6520 if(pItemMoniker != NULL) 6521 { 6522 IMoniker_Release(pItemMoniker); 6523 } 6524 if(pCompMoniker != NULL) 6525 { 6526 IMoniker_Release(pCompMoniker); 6527 } 6528 return S_OK; 6529 } 6530 6531 /************************************************************************* 6532 * OLECONVERT_CreateCompObjStream [Internal] 6533 * 6534 * Creates a "\001CompObj" is the destination IStorage if necessary. 6535 * 6536 * PARAMS 6537 * pStorage [I] The dest IStorage to create the CompObj Stream 6538 * if necessary. 6539 * strOleTypeName [I] The ProgID 6540 * 6541 * RETURNS 6542 * Success: S_OK 6543 * Failure: REGDB_E_CLASSNOTREG if cannot reconstruct the stream 6544 * 6545 * NOTES 6546 * This function is used by OleConvertOLESTREAMToIStorage only. 6547 * 6548 * The stream data is stored in the OLESTREAM and there should be 6549 * no need to recreate the stream. If the stream is manually 6550 * deleted it will attempt to create it by querying the registry. 6551 * 6552 * 6553 */ 6554 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) 6555 { 6556 IStream *pStream; 6557 HRESULT hStorageRes, hRes = S_OK; 6558 OLECONVERT_ISTORAGE_COMPOBJ IStorageCompObj; 6559 WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0}; 6560 6561 BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; 6562 BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71}; 6563 6564 /* Initialize the CompObj structure */ 6565 memset(&IStorageCompObj, 0, sizeof(IStorageCompObj)); 6566 memcpy(&(IStorageCompObj.byUnknown1), pCompObjUnknown1, sizeof(pCompObjUnknown1)); 6567 memcpy(&(IStorageCompObj.byUnknown2), pCompObjUnknown2, sizeof(pCompObjUnknown2)); 6568 6569 6570 /* Create a CompObj stream if it doesn't exist */ 6571 hStorageRes = IStorage_CreateStream(pStorage, wstrStreamName, 6572 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6573 if(hStorageRes == S_OK) 6574 { 6575 /* copy the OleTypeName to the compobj struct */ 6576 IStorageCompObj.dwOleTypeNameLength = strlen(strOleTypeName)+1; 6577 strcpy(IStorageCompObj.strOleTypeName, strOleTypeName); 6578 6579 /* copy the OleTypeName to the compobj struct */ 6580 /* Note: in the test made, these where Identical */ 6581 IStorageCompObj.dwProgIDNameLength = strlen(strOleTypeName)+1; 6582 strcpy(IStorageCompObj.strProgIDName, strOleTypeName); 6583 6584 /* Get the CLSID */ 6585 hRes = CLSIDFromProgID16(IStorageCompObj.strProgIDName, &(IStorageCompObj.clsid)); 6586 6587 if(hRes != S_OK) 6588 { 6589 hRes = REGDB_E_CLASSNOTREG; 6590 } 6591 else 6592 { 6593 HKEY hKey; 6594 LONG hErr; 6595 /* Get the CLSID Default Name from the Registry */ 6596 hErr = RegOpenKeyA(HKEY_CLASSES_ROOT, IStorageCompObj.strProgIDName, &hKey); 6597 if(hErr == ERROR_SUCCESS) 6598 { 6599 char strTemp[OLESTREAM_MAX_STR_LEN]; 6600 IStorageCompObj.dwCLSIDNameLength = OLESTREAM_MAX_STR_LEN; 6601 hErr = RegQueryValueA(hKey, NULL, strTemp, (LPLONG)&(IStorageCompObj.dwCLSIDNameLength)); 6602 if(hErr == ERROR_SUCCESS) 6603 { 6604 strcpy(IStorageCompObj.strCLSIDName, strTemp); 6605 } 6606 RegCloseKey(hKey); 6607 } 6608 if(hErr != ERROR_SUCCESS) 6609 { 6610 hRes = REGDB_E_CLASSNOTREG; 6611 } 6612 } 6613 6614 if(hRes == S_OK ) 6615 { 6616 /* Write CompObj Structure to stream */ 6617 hRes = IStream_Write(pStream, IStorageCompObj.byUnknown1, sizeof(IStorageCompObj.byUnknown1), NULL); 6618 WriteClassStm(pStream,&(IStorageCompObj.clsid)); 6619 hRes = IStream_Write(pStream, &(IStorageCompObj.dwCLSIDNameLength), sizeof(IStorageCompObj.dwCLSIDNameLength), NULL); 6620 if(IStorageCompObj.dwCLSIDNameLength > 0) 6621 { 6622 hRes = IStream_Write(pStream, IStorageCompObj.strCLSIDName, IStorageCompObj.dwCLSIDNameLength, NULL); 6623 } 6624 hRes = IStream_Write(pStream, &(IStorageCompObj.dwOleTypeNameLength) , sizeof(IStorageCompObj.dwOleTypeNameLength), NULL); 6625 if(IStorageCompObj.dwOleTypeNameLength > 0) 6626 { 6627 hRes = IStream_Write(pStream, IStorageCompObj.strOleTypeName , IStorageCompObj.dwOleTypeNameLength, NULL); 6628 } 6629 hRes = IStream_Write(pStream, &(IStorageCompObj.dwProgIDNameLength) , sizeof(IStorageCompObj.dwProgIDNameLength), NULL); 6630 if(IStorageCompObj.dwProgIDNameLength > 0) 6631 { 6632 hRes = IStream_Write(pStream, IStorageCompObj.strProgIDName , IStorageCompObj.dwProgIDNameLength, NULL); 6633 } 6634 hRes = IStream_Write(pStream, IStorageCompObj.byUnknown2 , sizeof(IStorageCompObj.byUnknown2), NULL); 6635 } 6636 IStream_Release(pStream); 6637 } 6638 return hRes; 6639 } 6640 6641 6642 /************************************************************************* 6643 * OLECONVERT_CreateOlePresStream[Internal] 6644 * 6645 * Creates the "\002OlePres000" Stream with the Metafile data 6646 * 6647 * PARAMS 6648 * pStorage [I] The dest IStorage to create \002OLEPres000 stream in. 6649 * dwExtentX [I] Width of the Metafile 6650 * dwExtentY [I] Height of the Metafile 6651 * pData [I] Metafile data 6652 * dwDataLength [I] Size of the Metafile data 6653 * 6654 * RETURNS 6655 * Success: S_OK 6656 * Failure: CONVERT10_E_OLESTREAM_PUT for invalid Put 6657 * 6658 * NOTES 6659 * This function is used by OleConvertOLESTREAMToIStorage only. 6660 * 6661 */ 6662 void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwObjectType, DWORD dwExtentX, DWORD dwExtentY , BYTE *pData, DWORD dwDataLength) 6663 { 6664 HRESULT hRes; 6665 IStream *pStream; 6666 WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; 6667 BYTE pOlePresStreamEmbeddedHeader [] = 6668 { 6669 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 6670 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6671 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 6672 0x00, 0x00, 0x00, 0x00 6673 }; 6674 6675 BYTE pOlePresStreamLinkHeader [] = 6676 { 6677 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 6678 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6679 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 6680 0x00, 0x00, 0x00, 0x00 6681 }; 6682 6683 BYTE pOlePresStreamHeaderEmpty [] = 6684 { 6685 0x00, 0x00, 0x00, 0x00, 6686 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6687 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 6688 0x00, 0x00, 0x00, 0x00 6689 }; 6690 6691 /* Create the OlePres000 Stream */ 6692 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6693 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6694 6695 if(hRes == S_OK) 6696 { 6697 DWORD nHeaderSize; 6698 OLECONVERT_ISTORAGE_OLEPRES OlePres; 6699 6700 memset(&OlePres, 0, sizeof(OlePres)); 6701 /* Do we have any metafile data to save */ 6702 if(dwDataLength > 0) 6703 { 6704 if(dwObjectType == OLECONVERT_LINK_TYPE) 6705 { 6706 memcpy(OlePres.byUnknown1, pOlePresStreamLinkHeader, sizeof(pOlePresStreamLinkHeader)); 6707 nHeaderSize = sizeof(pOlePresStreamLinkHeader); 6708 } 6709 else 6710 { 6711 memcpy(OlePres.byUnknown1, pOlePresStreamEmbeddedHeader, sizeof(pOlePresStreamEmbeddedHeader)); 6712 nHeaderSize = sizeof(pOlePresStreamEmbeddedHeader); 6713 } 6714 } 6715 else 6716 { 6717 memcpy(OlePres.byUnknown1, pOlePresStreamHeaderEmpty, sizeof(pOlePresStreamHeaderEmpty)); 6718 nHeaderSize = sizeof(pOlePresStreamHeaderEmpty); 6719 } 6720 /* Set width and height of the metafile */ 6721 OlePres.dwExtentX = dwExtentX; 6722 OlePres.dwExtentY = -dwExtentY; 6723 6724 /* Set Data and Length */ 6725 if(dwDataLength > sizeof(METAFILEPICT16)) 6726 { 6727 OlePres.dwSize = dwDataLength - sizeof(METAFILEPICT16); 6728 OlePres.pData = &(pData[8]); 6729 } 6730 /* Save OlePres000 Data to Stream */ 6731 hRes = IStream_Write(pStream, OlePres.byUnknown1, nHeaderSize, NULL); 6732 hRes = IStream_Write(pStream, &(OlePres.dwExtentX), sizeof(OlePres.dwExtentX), NULL); 6733 hRes = IStream_Write(pStream, &(OlePres.dwExtentY), sizeof(OlePres.dwExtentY), NULL); 6734 hRes = IStream_Write(pStream, &(OlePres.dwSize), sizeof(OlePres.dwSize), NULL); 6735 if(OlePres.dwSize > 0) 6736 { 6737 hRes = IStream_Write(pStream, OlePres.pData, OlePres.dwSize, NULL); 6738 } 6739 IStream_Release(pStream); 6740 } 6741 } 6742 6743 /************************************************************************* 6744 * OLECONVERT_CreateOle10NativeStream [Internal] 6745 * 6746 * Creates the "\001Ole10Native" Stream (should contain a BMP) 6747 * 6748 * PARAMS 6749 * pStorage [I] Dest storage to create the stream in 6750 * pData [I] Ole10 Native Data (ex. bmp) 6751 * dwDataLength [I] Size of the Ole10 Native Data 6752 * 6753 * RETURNS 6754 * Nothing 6755 * 6756 * NOTES 6757 * This function is used by OleConvertOLESTREAMToIStorage only. 6758 * 6759 * Might need to verify the data and return appropriate error message 6760 * 6761 */ 6762 void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD dwDataLength) 6763 { 6764 HRESULT hRes; 6765 IStream *pStream; 6766 WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; 6767 6768 /* Create the Ole10Native Stream */ 6769 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6770 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6771 6772 if(hRes == S_OK) 6773 { 6774 /* Write info to stream */ 6775 hRes = IStream_Write(pStream, &dwDataLength, sizeof(dwDataLength), NULL); 6776 hRes = IStream_Write(pStream, pData, dwDataLength, NULL); 6777 IStream_Release(pStream); 6778 } 6779 6780 } 6781 6782 /************************************************************************* 6783 * OLECONVERT_GetProgIDFromStorage [Internal] 6784 * 6785 * Finds the ProgID (or OleTypeID) from the IStorage 6786 * 6787 * PARAMS 6788 * pStorage [I] The Src IStorage to get the ProgID 6789 * strProgID [I] the ProgID string to get 6790 * dwSize [I] the size of the string 6791 * 6792 * RETURNS 6793 * Success: S_OK 6794 * Failure: REGDB_E_CLASSNOTREG if cannot reconstruct the stream 6795 * 6796 * NOTES 6797 * This function is used by OleConvertIStorageToOLESTREAM only. 6798 * 6799 * 6800 */ 6801 HRESULT OLECONVERT_GetProgIDFromStorage(LPSTORAGE pStorage, char *strProgID, DWORD *dwSize) 6802 { 6803 HRESULT hRes; 6804 IStream *pStream; 6805 LARGE_INTEGER iSeekPos; 6806 6807 strProgID[0] = NULL; 6808 6809 if(strProgID == NULL || dwSize == NULL) 6810 { 6811 return E_INVALIDARG; 6812 } 6813 6814 if(OLECONVERT_IsStorageLink(pStorage)) 6815 { 6816 LPOLESTR wstrProgID; 6817 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 6818 6819 /* Open the CompObj Stream */ 6820 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6821 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6822 if(hRes == S_OK) 6823 { 6824 OLECONVERT_ISTORAGE_OLE OleStreamHeader; 6825 6826 /* Get the CLSID Offset */ 6827 iSeekPos.LowPart = sizeof(OleStreamHeader.dwOLEHEADER_ID) + sizeof(OleStreamHeader.dwUnknown1) 6828 + sizeof(OleStreamHeader.dwUnknown2) + sizeof(OleStreamHeader.dwUnknown3) 6829 + sizeof(OleStreamHeader.dwUnknown4) + sizeof(OleStreamHeader.dwUnknown5); 6830 iSeekPos.HighPart = 0; 6831 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); 6832 if(hRes == S_OK) 6833 { 6834 hRes = IStream_Read(pStream, &OleStreamHeader.dwObjectCLSIDOffset, sizeof(OleStreamHeader.dwObjectCLSIDOffset), NULL); 6835 } 6836 if(hRes == S_OK) 6837 { 6838 iSeekPos.LowPart = OleStreamHeader.dwObjectCLSIDOffset; 6839 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR, NULL); 6840 } 6841 /* Read the CLSID */ 6842 hRes = ReadClassStm(pStream, &OleStreamHeader.clsidObject); 6843 if(hRes == S_OK) 6844 { 6845 hRes = ProgIDFromCLSID(&(OleStreamHeader.clsidObject), &wstrProgID); 6846 if(hRes == S_OK) 6847 { 6848 *dwSize = WideCharToMultiByte(CP_ACP, 0, wstrProgID, -1, strProgID, *dwSize, NULL, FALSE); 6849 } 6850 } 6851 IStream_Release(pStream); 6852 } 6853 } 6854 else 6855 { 6856 6857 STATSTG stat; 6858 OLECONVERT_ISTORAGE_COMPOBJ CompObj; 6859 WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0}; 6860 /* Open the CompObj Stream */ 6861 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6862 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6863 6864 if(hRes == S_OK) 6865 { 6866 6867 /*Get the OleType from the CompObj Stream */ 6868 iSeekPos.LowPart = sizeof(CompObj.byUnknown1) + sizeof(CompObj.clsid); 6869 iSeekPos.HighPart = 0; 6870 6871 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); 6872 if(hRes == S_OK) 6873 { 6874 hRes = IStream_Read(pStream, &CompObj.dwCLSIDNameLength, sizeof(CompObj.dwCLSIDNameLength), NULL); 6875 } 6876 6877 if(hRes == S_OK) 6878 { 6879 iSeekPos.LowPart = CompObj.dwCLSIDNameLength; 6880 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL); 6881 } 6882 if(hRes == S_OK) 6883 { 6884 hRes = IStream_Read(pStream, &CompObj.dwOleTypeNameLength, sizeof(CompObj.dwOleTypeNameLength), NULL); 6885 } 6886 if(hRes == S_OK) 6887 { 6888 iSeekPos.LowPart = CompObj.dwOleTypeNameLength; 6889 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL); 6890 } 6891 6892 if(hRes == S_OK) 6893 { 6894 hRes = IStream_Read(pStream, dwSize, sizeof(*dwSize), NULL); 6895 if(*dwSize > 0) 6896 { 6897 if(hRes == S_OK) 6898 { 6899 hRes = IStream_Read(pStream, strProgID, *dwSize, NULL); 6900 } 6901 } 6902 } 6903 IStream_Release(pStream); 6904 } 6905 6906 /* If the CompObject is not present, or there was an error reading the CompObject */ 6907 /* Get the CLSID from the storage stat */ 6908 if(hRes != S_OK) 6909 { 6910 LPOLESTR wstrProgID; 6911 6912 /* Get the OleType from the registry */ 6913 IStorage_Stat(pStorage, &stat, STATFLAG_NONAME); 6914 hRes = ProgIDFromCLSID(&(stat.clsid), &wstrProgID); 6915 if(hRes == S_OK) 6916 { 6917 *dwSize = WideCharToMultiByte(CP_ACP, 0, wstrProgID, -1, strProgID, *dwSize, NULL, FALSE); 6918 } 6919 } 6920 } 6921 if(strProgID[0] == NULL) 6922 { 6923 *dwSize = 0; 6924 } 6925 return hRes; 6926 } 6927 6928 /************************************************************************* 6929 * OLECONVERT_GetOle20PresData[Internal] 6930 * 6931 * Converts IStorage "/002OlePres000" stream to a OLE10 Stream 6932 * 6933 * PARAMS 6934 * pStorage [I] Src IStroage 6935 * pOleStreamData [I] Dest OleStream Mem Struct 6936 * 6937 * RETURNS 6938 * Nothing 6939 * 6940 * NOTES 6941 * This function is used by OleConvertIStorageToOLESTREAM only. 6942 * 6943 * Memory allocated for pData must be freed by the caller 6944 */ 6945 void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 6946 { 6947 HRESULT hRes; 6948 IStream *pStream; 6949 OLECONVERT_ISTORAGE_OLEPRES olePress; 6950 WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; 6951 6952 6953 6954 /* Open OlePress000 stream */ 6955 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6956 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6957 if(hRes == S_OK) 6958 { 6959 LARGE_INTEGER iSeekPos; 6960 METAFILEPICT16 MetaFilePict; 6961 char strMetafilePictName[] = "METAFILEPICT"; 6962 6963 /* Set the TypeID for a Metafile */ 6964 pOleStreamData[1].dwObjectTypeID = OLECONVERT_PRESENTATION_DATA_TYPE; 6965 6966 /* Set the OleTypeName to Metafile */ 6967 pOleStreamData[1].dwOleTypeNameLength = strlen(strMetafilePictName) +1; 6968 strcpy(pOleStreamData[1].strOleTypeName, strMetafilePictName); 6969 6970 iSeekPos.HighPart = 0; 6971 iSeekPos.LowPart = sizeof(olePress.byUnknown1); 6972 6973 /* Get Presentation Data */ 6974 IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); 6975 IStream_Read(pStream, &(olePress.dwExtentX), sizeof(olePress.dwExtentX), NULL); 6976 IStream_Read(pStream, &(olePress.dwExtentY), sizeof(olePress.dwExtentY), NULL); 6977 IStream_Read(pStream, &(olePress.dwSize), sizeof(olePress.dwSize), NULL); 6978 6979 /*Set width and Height */ 6980 pOleStreamData[1].dwMetaFileWidth = olePress.dwExtentX; 6981 pOleStreamData[1].dwMetaFileHeight = -olePress.dwExtentY; 6982 if(olePress.dwSize > 0) 6983 { 6984 /* Set Length */ 6985 pOleStreamData[1].dwDataLength = olePress.dwSize + sizeof(METAFILEPICT16); 6986 6987 /* Set MetaFilePict struct */ 6988 MetaFilePict.mm = 8; 6989 MetaFilePict.xExt = olePress.dwExtentX; 6990 MetaFilePict.yExt = olePress.dwExtentY; 6991 MetaFilePict.hMF = 0; 6992 6993 /* Get Metafile Data */ 6994 pOleStreamData[1].pData = (BYTE *) malloc(pOleStreamData[1].dwDataLength); 6995 memcpy(pOleStreamData[1].pData, &MetaFilePict, sizeof(MetaFilePict)); 6996 IStream_Read(pStream, &(pOleStreamData[1].pData[sizeof(MetaFilePict)]), pOleStreamData[1].dwDataLength-sizeof(METAFILEPICT16), NULL); 6997 } 6998 IStream_Release(pStream); 6999 } 7000 } 7001 7002 LPMONIKER OLECONVERT_LoadMonikers(CLSID *pclsid, IStream *pStream ) 7003 { 7004 7005 LPMONIKER pDestMoniker=NULL; 7006 HRESULT hRes; 7007 if(IsEqualCLSID(&CLSID_FileMoniker, pclsid)) 7008 { 7009 WCHAR temp=0; 7010 hRes = CreateFileMoniker(&temp, &pDestMoniker); 7011 IMoniker_Load(pDestMoniker, pStream); 7012 } 7013 else if(IsEqualCLSID(&CLSID_ItemMoniker, pclsid)) 7014 { 7015 WCHAR temp1=0; 7016 WCHAR temp2=0; 7017 hRes = CreateItemMoniker(&temp1, &temp2, &pDestMoniker); 7018 IMoniker_Load(pDestMoniker, pStream); 7019 } 7020 else if(IsEqualCLSID(&CLSID_CompositeMoniker, pclsid)) 7021 { 7022 /* Problem with Saving CompositeMoniker */ 7023 /* TODO: Rechange remove code, create an empty CompositeMoniker */ 7024 WCHAR temp1=0; 7025 WCHAR temp2=0; 7026 LPMONIKER pItemMoniker, pFileMoniker; 7027 hRes = CreateItemMoniker(&temp1, &temp2, &pItemMoniker); 7028 hRes = CreateFileMoniker(&temp1, &pFileMoniker); 7029 hRes = CreateGenericComposite(pFileMoniker, pItemMoniker, &pDestMoniker); 7030 IMoniker_Load(pDestMoniker, pStream); 7031 } 7032 else 7033 { 7034 FIXME("Unsupported moniker in IStorage, /001Ole stream\n"); 7035 } 7036 return pDestMoniker; 7037 } 7038 7039 HRESULT OLECONVERT_GetMonikerFromStorage(LPSTORAGE pStorage, 7040 BYTE **pLinkFileName, DWORD* dwLinkFileNameLength, 7041 BYTE **pLinkExtraInfo, DWORD* dwLinkExtraInfoLength) 7042 { 7043 HRESULT hRes; 7044 IStream *pStream; 7045 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 7046 OLECONVERT_ISTORAGE_OLE OleStreamHeader; 7047 LPMONIKER pDestMoniker=NULL; 7048 7049 *pLinkFileName = NULL; 7050 *pLinkExtraInfo = NULL; 7051 *dwLinkFileNameLength = 0; 7052 *dwLinkExtraInfoLength = 0; 7053 7054 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 7055 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 7056 7057 if(hRes == S_OK) 7058 { 7059 /* Write default Data */ 7060 IStream_Read(pStream, &(OleStreamHeader.dwOLEHEADER_ID), sizeof(OleStreamHeader.dwOLEHEADER_ID), NULL); 7061 IStream_Read(pStream, &(OleStreamHeader.dwUnknown1), sizeof(OleStreamHeader.dwUnknown1), NULL); 7062 IStream_Read(pStream, &(OleStreamHeader.dwUnknown2), sizeof(OleStreamHeader.dwUnknown2), NULL); 7063 IStream_Read(pStream, &(OleStreamHeader.dwUnknown3), sizeof(OleStreamHeader.dwUnknown3), NULL); 7064 IStream_Read(pStream, &(OleStreamHeader.dwUnknown4), sizeof(OleStreamHeader.dwUnknown4), NULL); 7065 IStream_Read(pStream, &(OleStreamHeader.dwUnknown5), sizeof(OleStreamHeader.dwUnknown5), NULL); 7066 IStream_Read(pStream, &(OleStreamHeader.dwObjectCLSIDOffset), sizeof(OleStreamHeader.dwObjectCLSIDOffset), NULL); 7067 7068 /* Should call OleLoadFromStream, but implementeation incomplete */ 7069 ReadClassStm(pStream, &(OleStreamHeader.clsidMonikerTypeID)); 7070 /* Load the moniker */ 7071 pDestMoniker = OLECONVERT_LoadMonikers(&(OleStreamHeader.clsidMonikerTypeID), pStream); 7072 7073 /* Retreive the neccesary data */ 7074 if(IsEqualCLSID(&CLSID_FileMoniker, &(OleStreamHeader.clsidMonikerTypeID))) 7075 { 7076 7077 LPOLESTR ppszDisplayName; 7078 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7079 *dwLinkFileNameLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7080 NULL, 0, NULL, FALSE); 7081 *pLinkFileName = (BYTE *) malloc(*dwLinkFileNameLength); 7082 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7083 (LPSTR)*pLinkFileName, *dwLinkFileNameLength, NULL, FALSE); 7084 CoTaskMemFree(ppszDisplayName); 7085 } 7086 else if(IsEqualCLSID(&CLSID_ItemMoniker, &(OleStreamHeader.clsidMonikerTypeID))) 7087 { 7088 LPOLESTR ppszDisplayName; 7089 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7090 *dwLinkExtraInfoLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7091 NULL, 0, NULL, FALSE); 7092 *pLinkExtraInfo = (BYTE *) malloc(*dwLinkExtraInfoLength); 7093 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7094 (LPSTR)*pLinkExtraInfo, *dwLinkExtraInfoLength, NULL, FALSE); 7095 CoTaskMemFree(ppszDisplayName); 7096 7097 } 7098 else if(IsEqualCLSID(&CLSID_CompositeMoniker, &(OleStreamHeader.clsidMonikerTypeID))) 7099 { 7100 LPOLESTR ppszDisplayName; 7101 IMoniker *pmk; 7102 IEnumMoniker *enumMk; 7103 7104 IMoniker_Enum(pDestMoniker,TRUE,&enumMk); 7105 IEnumMoniker_Next(enumMk,1,&pmk,NULL); 7106 7107 7108 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7109 *dwLinkFileNameLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7110 NULL, 0, NULL, FALSE); 7111 *pLinkFileName = (BYTE *) malloc(*dwLinkFileNameLength); 7112 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7113 (LPSTR)*pLinkFileName, *dwLinkFileNameLength, NULL, FALSE); 7114 CoTaskMemFree(ppszDisplayName); 7115 IMoniker_Release(pmk); 7116 7117 IEnumMoniker_Next(enumMk,1,&pmk,NULL); 7118 7119 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7120 *dwLinkExtraInfoLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7121 NULL, 0, NULL, FALSE); 7122 *pLinkExtraInfo = (BYTE *) malloc(*dwLinkExtraInfoLength); 7123 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7124 (LPSTR)*pLinkExtraInfo, *dwLinkExtraInfoLength, NULL, FALSE); 7125 CoTaskMemFree(ppszDisplayName); 7126 IMoniker_Release(pmk); 7127 IEnumMoniker_Release(enumMk); 7128 } 7129 IStream_Read(pStream, &(OleStreamHeader.dwUnknown6), sizeof(OleStreamHeader.dwUnknown6), NULL); 7130 7131 ReadClassStm(pStream, &(OleStreamHeader.clsidObject)); 7132 IStream_Read(pStream, OleStreamHeader.dwUnknown7, sizeof(OleStreamHeader.dwUnknown7), NULL); 7133 IStream_Release(pStream); 7134 } 7135 if(pDestMoniker != NULL) 7136 { 7137 IMoniker_Release(pDestMoniker); 7138 } 7139 return S_OK; 7140 7141 7142 } 7143 /************************************************************************* 7144 * OLECONVERT_SetEmbeddedOle10OLESTREAMData [Internal] 7145 * 7146 * Converts IStorage "/001Ole10Native" stream to a OLE10 Stream 7147 * 7148 * PARAMS 7149 * pStorage [I] Src IStroage 7150 * pOleStream [I] Dest OleStream Mem Struct 7151 * 7152 * RETURNS 7153 * Nothing 7154 * 7155 * NOTES 7156 * This function is used by OleConvertIStorageToOLESTREAM only. 7157 * 7158 * Memory allocated for pData must be freed by the caller 7159 * 7160 * 7161 */ 7162 HRESULT OLECONVERT_SetEmbeddedOle10OLESTREAMData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7163 { 7164 7165 HRESULT hRes; 7166 IStream *pStream; 7167 WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; 7168 7169 /* Initialize Default data for OLESTREAM */ 7170 memset(pOleStreamData,0, sizeof(OLECONVERT_OLESTREAM_DATA) * OLECONVERT_NUM_OLE10STREAMS); 7171 /* Get the ProgID */ 7172 pOleStreamData[0].dwOleTypeNameLength = OLESTREAM_MAX_STR_LEN; 7173 hRes = OLECONVERT_GetProgIDFromStorage(pStorage, pOleStreamData[0].strOleTypeName, &(pOleStreamData[0].dwOleTypeNameLength)); 7174 7175 if(hRes != S_OK) 7176 { 7177 /* Cannot find the CLSID in the registry. Abort! */ 7178 return hRes; 7179 } 7180 7181 pOleStreamData[0].dwOleID = OLESTREAM_ID; 7182 pOleStreamData[0].dwObjectTypeID = OLECONVERT_EMBEDDED_TYPE; 7183 7184 /* Open Ole10Native Stream */ 7185 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 7186 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 7187 if(hRes == S_OK) 7188 { 7189 7190 /* Read Size and Data */ 7191 IStream_Read(pStream, &(pOleStreamData->dwDataLength), sizeof(pOleStreamData->dwDataLength), NULL); 7192 if(pOleStreamData->dwDataLength > 0) 7193 { 7194 pOleStreamData->pData = (BYTE *) malloc(pOleStreamData->dwDataLength); 7195 IStream_Read(pStream, pOleStreamData->pData, pOleStreamData->dwDataLength, NULL); 7196 } 7197 IStream_Release(pStream); 7198 } 7199 7200 if(hRes == S_OK) 7201 { 7202 /* Stream doens't exist for all cases: no stream for pbrush but package does! */ 7203 /* Cannot check for return value because the stream might not exist (normal behavior)*/ 7204 pOleStreamData[1].dwOleID = OLESTREAM_ID; 7205 OLECONVERT_GetOle20PresData(pStorage, pOleStreamData); 7206 } 7207 7208 return hRes; 7209 7210 } 7211 7212 HRESULT OLECONVERT_SetEmbeddedOle20OLESTREAMData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7213 { 7214 7215 HRESULT hRes=S_OK; 7216 /* Initialize Default data for OLESTREAM */ 7217 memset(pOleStreamData,0, sizeof(OLECONVERT_OLESTREAM_DATA) * OLECONVERT_NUM_OLE10STREAMS); 7218 7219 /* Get the ProgID */ 7220 pOleStreamData[0].dwOleTypeNameLength = OLESTREAM_MAX_STR_LEN; 7221 hRes = OLECONVERT_GetProgIDFromStorage(pStorage, pOleStreamData[0].strOleTypeName, &(pOleStreamData[0].dwOleTypeNameLength)); 7222 7223 if(hRes != S_OK) 7224 { 7225 /* Cannot find the CLSID in the registry. Abort! */ 7226 return hRes; 7227 } 7228 7229 pOleStreamData[0].dwOleID = OLESTREAM_ID; 7230 pOleStreamData[0].dwObjectTypeID = OLECONVERT_EMBEDDED_TYPE; 7231 pOleStreamData[0].dwDataLength = OLECONVERT_WriteOLE20ToBuffer(pStorage, 7232 &(pOleStreamData[0].pData)); 7233 pOleStreamData[1].dwOleID = OLESTREAM_ID; 7234 OLECONVERT_GetOle20PresData(pStorage, pOleStreamData); 7235 7236 return hRes; 7237 } 7238 7239 7240 HRESULT OLECONVERT_SetLinkOLESTREAMData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7241 { 7242 7243 HRESULT hRes = S_OK; 7244 /* Initialize Default data for OLESTREAM */ 7245 memset(pOleStreamData,0, sizeof(OLECONVERT_OLESTREAM_DATA) * OLECONVERT_NUM_OLE10STREAMS); 7246 7247 /* Get the ProgID */ 7248 pOleStreamData[0].dwOleTypeNameLength = OLESTREAM_MAX_STR_LEN; 7249 hRes = OLECONVERT_GetProgIDFromStorage(pStorage, pOleStreamData[0].strOleTypeName, &(pOleStreamData[0].dwOleTypeNameLength)); 7250 7251 if(hRes != S_OK) 7252 { 7253 /* Cannot find the CLSID in the registry. Abort! */ 7254 return hRes; 7255 } 7256 pOleStreamData[0].dwOleID = OLESTREAM_ID; 7257 pOleStreamData[0].dwObjectTypeID = OLECONVERT_LINK_TYPE; 7258 /* TODO: Write the Link data */ 7259 OLECONVERT_GetMonikerFromStorage(pStorage, 7260 &(pOleStreamData[0].strLinkFileName), &(pOleStreamData[0].dwLinkFileNameLength), 7261 &(pOleStreamData[0].pLinkExtraInfo), &(pOleStreamData[0].dwLinkExtraInfoLength)); 7262 7263 /* pOleStreamData[0].dwDataLength = OLECONVERT_WriteOLE20ToBuffer(pStorage, &(pOleStreamData[0].pData)); */ 7264 pOleStreamData[1].dwOleID = OLESTREAM_ID; 7265 OLECONVERT_GetOle20PresData(pStorage, pOleStreamData); 7266 return hRes; 7267 } 7268 7269 7270 HRESULT OLECONVERT_CreateEmbeddedIStorage(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7271 { 7272 HRESULT hRes = S_OK; 7273 BOOL bCreateOle10Native = TRUE; 7274 if(pOleStreamData[0].dwDataLength > sizeof(STORAGE_magic)) 7275 { 7276 /* Do we have the IStorage Data in the OLESTREAM */ 7277 if(memcmp(pOleStreamData[0].pData, STORAGE_magic, sizeof(STORAGE_magic)) ==0) 7278 { 7279 OLECONVERT_GetOLE20FromOLE10(pStorage, pOleStreamData[0].pData, pOleStreamData[0].dwDataLength); 7280 7281 OLECONVERT_CreateOlePresStream(pStorage, OLECONVERT_EMBEDDED_TYPE, 7282 pOleStreamData[1].dwMetaFileWidth, pOleStreamData[1].dwMetaFileHeight, 7283 pOleStreamData[1].pData, pOleStreamData[1].dwDataLength); 7284 bCreateOle10Native = FALSE; 7285 } 7286 } 7287 7288 if(bCreateOle10Native) 7289 { 7290 /* It must be an original OLE 1.0 source */ 7291 OLECONVERT_CreateOle10NativeStream(pStorage, pOleStreamData[0].pData, pOleStreamData[0].dwDataLength); 7292 7293 if(pOleStreamData[1].dwObjectTypeID == OLECONVERT_PRESENTATION_DATA_TYPE) 7294 { 7295 OLECONVERT_CreateOlePresStream(pStorage, OLECONVERT_EMBEDDED_TYPE, 7296 pOleStreamData[1].dwMetaFileWidth, pOleStreamData[1].dwMetaFileHeight, 7297 pOleStreamData[1].pData, pOleStreamData[1].dwDataLength); 7298 } 7299 } 7300 7301 /*Create the Ole Stream if necessary */ 7302 OLECONVERT_CreateEmbeddedOleStream(pStorage); 7303 /* Create CompObj Stream if necessary */ 7304 hRes = OLECONVERT_CreateCompObjStream(pStorage, pOleStreamData[0].strOleTypeName); 7305 if(hRes == S_OK) 7306 { 7307 CLSID clsid; 7308 7309 CLSIDFromProgID16(pOleStreamData[0].strOleTypeName, &clsid); 7310 IStorage_SetClass(pStorage, &clsid); 7311 } 7312 return hRes; 7313 } 7314 7315 HRESULT OLECONVERT_CreateLinkIStorage(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7316 { 7317 HRESULT hRes; 7318 hRes = OLECONVERT_CreateLinkOleStream(pStorage, 7319 pOleStreamData[0].strOleTypeName, (LPCSTR)pOleStreamData[0].strLinkFileName, 7320 pOleStreamData[0].pLinkExtraInfo, pOleStreamData[0].dwLinkExtraInfoLength); 7321 if(hRes == S_OK) 7322 { 7323 OLECONVERT_CreateOlePresStream(pStorage, OLECONVERT_LINK_TYPE, 7324 pOleStreamData[1].dwMetaFileWidth, pOleStreamData[1].dwMetaFileHeight, 7325 pOleStreamData[1].pData, pOleStreamData[1].dwDataLength); 7326 } 7327 if(hRes == S_OK) 7328 { 7329 IStorage_SetClass(pStorage, &IID_StdOleLink); 7330 } 7331 return hRes; 7332 } 7333 7334 7335 7336 /************************************************************************* 7337 * OleConvertOLESTREAMToIStorage [OLE32.87] 7338 * 7339 * Read info on MSDN 7340 * 7341 * TODO 7342 * DVTARGETDEVICE paramenter is not handled 7343 * Still unsure of some mem fields for OLE 10 Stream 7344 * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", 7345 * and "\001OLE" streams 7346 * 7347 */ 7348 HRESULT WINAPI OleConvertOLESTREAMToIStorage ( 7349 LPOLESTREAM pOleStream, 7350 LPSTORAGE pstg, 7351 const DVTARGETDEVICE* ptd) 7352 { 7353 int i; 7354 HRESULT hRes=S_OK; 7355 OLECONVERT_OLESTREAM_DATA pOleStreamData[OLECONVERT_NUM_OLE10STREAMS]; 7356 7357 memset(pOleStreamData, 0, sizeof(pOleStreamData)); 7358 7359 if(ptd != NULL) 7360 { 7361 FIXME("DVTARGETDEVICE is not NULL, unhandled parameter\n"); 7362 } 7363 7364 if(pstg == NULL || pOleStream == NULL) 7365 { 7366 hRes = E_INVALIDARG; 7367 } 7368 7369 if(hRes == S_OK) 7370 { 7371 /* Load the OLESTREAM to Memory */ 7372 hRes = OLECONVERT_LoadOLE10(pOleStream, &pOleStreamData[0]); 7373 } 7374 7375 if(hRes == S_OK) 7376 { 7377 /* Load the OLESTREAM to Memory (part 2)*/ 7378 hRes = OLECONVERT_LoadOLE10(pOleStream, &pOleStreamData[1]); 7379 } 7380 7381 if(hRes == S_OK) 7382 { 7383 /* Is olestream an embedded object */ 7384 if(pOleStreamData[0].dwObjectTypeID != OLECONVERT_LINK_TYPE) 7385 { 7386 hRes = OLECONVERT_CreateEmbeddedIStorage(pstg, pOleStreamData); 7387 } 7388 else 7389 { 7390 hRes = OLECONVERT_CreateLinkIStorage(pstg, pOleStreamData); 7391 } 7392 } 7393 /* Free allocated memory */ 7394 for(i=0; i < OLECONVERT_NUM_OLE10STREAMS; i++) 7395 { 7396 if(pOleStreamData[i].pData != NULL) 7397 { 7398 free(pOleStreamData[i].pData); 7399 } 7400 7401 if(pOleStreamData[i].pLinkExtraInfo != NULL) 7402 { 7403 free(pOleStreamData[i].pLinkExtraInfo); 7404 } 7405 if(pOleStreamData[i].strLinkFileName != NULL) 7406 { 7407 free(pOleStreamData[i].strLinkFileName); 7408 } 7409 } 7410 return hRes; 7411 } 7412 7413 /************************************************************************* 7414 * OleConvertIStorageToOLESTREAM [OLE32.85] 7415 * 7416 * Read info on MSDN 7417 * 7418 * Read info on MSDN 7419 * 7420 * TODO 7421 * Still unsure of some mem fields for OLE 10 Stream 7422 * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", 7423 * and "\001OLE" streams. 7424 * 7425 */ 7426 HRESULT WINAPI OleConvertIStorageToOLESTREAM ( 7427 LPSTORAGE pstg, 7428 LPOLESTREAM pOleStream) 7429 { 7430 int i; 7431 HRESULT hRes = S_OK; 7432 IStream *pStream; 7433 OLECONVERT_OLESTREAM_DATA pOleStreamData[OLECONVERT_NUM_OLE10STREAMS]; 7434 WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; 7435 7436 7437 memset(pOleStreamData, 0, sizeof(pOleStreamData)); 7438 7439 if(pstg == NULL || pOleStream == NULL) 7440 { 7441 hRes = E_INVALIDARG; 7442 } 7443 if(hRes == S_OK) 7444 { 7445 if(!OLECONVERT_IsStorageLink(pstg)) 7446 { 7447 /*Was it originaly Ole10 */ 7448 hRes = IStorage_OpenStream(pstg, wstrStreamName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream); 7449 if(hRes == S_OK) 7450 { 7451 IStream_Release(pStream); 7452 /*Get Presentation Data for Ole10Native */ 7453 hRes = OLECONVERT_SetEmbeddedOle10OLESTREAMData(pstg, pOleStreamData); 7454 } 7455 else 7456 { 7457 /*Get Presentation Data (OLE20)*/ 7458 hRes = OLECONVERT_SetEmbeddedOle20OLESTREAMData(pstg, pOleStreamData); 7459 } 7460 } 7461 else 7462 { 7463 hRes = OLECONVERT_SetLinkOLESTREAMData(pstg, pOleStreamData); 7464 } 7465 7466 if(hRes == S_OK) 7467 { 7468 /* Save OLESTREAM */ 7469 hRes = OLECONVERT_SaveOLE10(&(pOleStreamData[0]), pOleStream); 7470 if(hRes == S_OK) 7471 { 7472 hRes = OLECONVERT_SaveOLE10(&(pOleStreamData[1]), pOleStream); 7473 } 7474 } 7475 } 7476 7477 /* Free allocated memory */ 7478 for(i=0; i < OLECONVERT_NUM_OLE10STREAMS; i++) 7479 { 7480 if(pOleStreamData[i].pData != NULL) 7481 { 7482 free(pOleStreamData[i].pData); 7483 } 7484 7485 if(pOleStreamData[i].pLinkExtraInfo != NULL) 7486 { 7487 free(pOleStreamData[i].pLinkExtraInfo); 7488 } 7489 7490 if(pOleStreamData[i].strLinkFileName != NULL) 7491 { 7492 free(pOleStreamData[i].strLinkFileName); 7493 } 7494 } 7495 7496 return hRes; 7497 } 5811 7498 5812 7499 /****************************************************************************** … … 5814 7501 */ 5815 7502 HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn) { 7503 static const BYTE STORAGE_notmagic[8]={0x0e,0x11,0xfc,0x0d,0xd0,0xcf,0x11,0xe0}; 5816 7504 HFILE hf; 5817 7505 OFSTRUCT ofs;
Note:
See TracChangeset
for help on using the changeset viewer.