Ignore:
Timestamp:
Mar 19, 2000, 4:35:32 PM (25 years ago)
Author:
davidr
Message:

Ported changes from wine/corel sources

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:44 davidr Exp $ */
     1/* $Id: storage.cpp,v 1.2 2000-03-19 15:33:08 davidr Exp $ */
    22/*
    33 * Compound Storage functions.
     
    2626#include "storage.h"
    2727
     28#include "winnls.h"
     29#include "winreg.h"
     30#include "wine/wingdi16.h"
     31
    2832DEFAULT_DEBUG_CHANNEL(storage)
    2933
    3034#define FILE_BEGIN 0
    3135
     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
    3247static const char rootPropertyName[] = "Root Entry";
     48
     49
     50/* OLESTREAM memory structure to use for Get and Put Routines */
     51/* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */
     52typedef 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 */
     70typedef 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 */
     86typedef 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 */
     98typedef 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
    33116
    34117/***********************************************************************
     
    37120static HRESULT deleteStorageProperty(
    38121  StorageImpl *parentStorage,
    39   OLECHAR     *propertyToDeleteName);
     122  ULONG        foundPropertyIndexToDelete,
     123  StgProperty  propertyToDelete);
    40124
    41125static HRESULT deleteStreamProperty(
     
    337421       (currentProperty.propertyType==PROPTYPE_STREAM) )
    338422  {
    339     newStream = StgStreamImpl_Construct(This, foundPropertyIndex);
     423    newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex);
    340424   
    341425    if (newStream!=0)
     
    687771     * non empty storage.
    688772     */
     773    StorageImpl_ReadProperty(This->ancestorStorage,
     774                             foundPropertyIndex,
     775                             &currentProperty);
     776
    689777    currentProperty.dirProperty  = PROPERTY_NULL;
    690778    currentProperty.propertyType = PROPTYPE_STORAGE;
     
    845933   * Open the stream to return it.
    846934   */
    847   newStream = StgStreamImpl_Construct(This, newPropertyIndex);
     935  newStream = StgStreamImpl_Construct(This, grfMode, newPropertyIndex);
    848936
    849937  if (newStream != 0)
     
    15931681    hr = deleteStorageProperty(
    15941682           This,
    1595            propertyToDelete.name);
     1683           foundPropertyIndexToDelete,
     1684           propertyToDelete);
    15961685  }
    15971686  else if ( propertyToDelete.propertyType == PROPTYPE_STREAM )
     
    16291718static HRESULT deleteStorageProperty(
    16301719  StorageImpl *parentStorage,
    1631   OLECHAR     *propertyToDeleteName)
     1720  ULONG        indexOfPropertyToDelete,
     1721  StgProperty  propertyToDelete)
    16321722{
    16331723  IEnumSTATSTG *elements     = 0;
     
    16421732  hr = StorageBaseImpl_OpenStorage(
    16431733        (IStorage*)parentStorage,
    1644         propertyToDeleteName,
     1734        propertyToDelete.name,
    16451735        0,
    16461736        STGM_SHARE_EXCLUSIVE,
     
    16821772  } while ((hr == S_OK) && (destroyHr == S_OK));
    16831773
     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
    16841783  IStorage_Release(childStorage);
    16851784  IEnumSTATSTG_Release(elements);
     
    17111810         (OLECHAR*)propertyToDelete.name,
    17121811         NULL,
    1713          STGM_SHARE_EXCLUSIVE,
     1812         STGM_WRITE | STGM_SHARE_EXCLUSIVE,
    17141813         0,
    17151814         &pis);
     
    20272126  ILockBytes*  pLkbyt,
    20282127  DWORD        openFlags,
    2029   BOOL         fileBased)
     2128  BOOL         fileBased,
     2129  BOOL         fileCreate)
    20302130{
    20312131  HRESULT     hr = S_OK;
     
    20422142   * Initialize the virtual fgunction table.
    20432143   */
    2044   This->lpvtbl       = &Storage32Impl_Vtbl;
     2144  ICOM_VTBL(This)    = &Storage32Impl_Vtbl;
    20452145  This->v_destructor = &StorageImpl_Destroy;
    20462146 
     
    20702170    return E_FAIL;
    20712171 
    2072   if (openFlags & STGM_CREATE)
     2172  if (fileCreate)
    20732173  {
    20742174    ULARGE_INTEGER size;
     
    20932193    This->extBigBlockDepotStart = BLOCK_END_OF_CHAIN;
    20942194    This->extBigBlockDepotCount = 0;
    2095 
    20962195    StorageImpl_SaveFileHeader(This);
    20972196
     
    21512250   * Write the root property
    21522251   */
    2153   if (openFlags & STGM_CREATE)
     2252  if (fileCreate)
    21542253  {
    21552254    StgProperty rootProp;
     
    25972696    if (depotBuffer!=0)
    25982697    {
    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);
    26062700
    26072701      StorageImpl_ReleaseBigBlock(This, depotBuffer);
     
    30343128
    30353129  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);
    30413130
    30423131  StorageUtl_WriteWord(
     
    32883377     * Initialize the virtual function table.
    32893378     */
    3290     newStorage->lpvtbl       = &Storage32InternalImpl_Vtbl;
     3379    ICOM_VTBL(newStorage)    = &Storage32InternalImpl_Vtbl;
    32913380    newStorage->v_destructor = &StorageInternalImpl_Destroy;
    32923381
     
    33593448     * Set-up the virtual function table and reference count.
    33603449     */
    3361     newEnumeration->lpvtbl = &IEnumSTATSTGImpl_Vtbl;
     3450    ICOM_VTBL(newEnumeration) = &IEnumSTATSTGImpl_Vtbl;
    33623451    newEnumeration->ref    = 0;
    33633452   
     
    38753964{
    38763965  memcpy(value, (BYTE*)buffer+offset, sizeof(DWORD));
     3966}
     3967
     3968void StorageUtl_ReadDWords(void *buffer, ULONG offset, DWORD *values,
     3969                           ULONG len)
     3970{
     3971  memcpy(values, (BYTE*)buffer+offset, sizeof(DWORD)*len);
    38773972}
    38783973
     
    39574052{
    39584053  BlockChainStream* newStream;
    3959   ULONG blockIndex;
    39604054
    39614055  newStream = (BlockChainStream *)HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream));
     
    39654059  newStream->ownerPropertyIndex      = propertyIndex;
    39664060  newStream->lastBlockNoInSequence   = 0xFFFFFFFF;
     4061  newStream->lazyInitComplete        = FALSE;
    39674062  newStream->tailIndex               = BLOCK_END_OF_CHAIN;
    39684063  newStream->numBlocks               = 0;
    39694064
    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 
    39824065  return newStream;
     4066}
     4067
     4068static 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
     4089static inline ULONG BlockChainStream_TailIndex(BlockChainStream *This)
     4090{
     4091    if (!This->lazyInitComplete)
     4092        BlockChainStream_LazyInit(This);
     4093    return This->tailIndex;
     4094}
     4095
     4096static inline ULONG BlockChainStream_NumBlocks(BlockChainStream *This)
     4097{
     4098    if (!This->lazyInitComplete)
     4099        BlockChainStream_LazyInit(This);
     4100    return This->numBlocks;
    39834101}
    39844102
     
    43514469   * Go to the current end of chain
    43524470   */
    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);
    43714473
    43724474  /*
     
    52055307  DWORD          fileAttributes;
    52065308  WCHAR          tempFileName[MAX_PATH];
     5309  BOOL           switchRemoteToLocalFile = TRUE;
    52075310
    52085311  TRACE("(%s, %lx, %ld, %p)\n",
     
    52295332    WCHAR tempPath[MAX_PATH];
    52305333    WCHAR prefix[] = { 'S', 'T', 'O', 0 };
     5334
     5335    switchRemoteToLocalFile = FALSE;
    52315336
    52325337    memset(tempPath, 0, sizeof(tempPath));
     
    52885393         NULL,
    52895394         grfMode,
     5395         TRUE,
    52905396         TRUE);
    52915397 
     
    53525458 
    53535459  hFile = CreateFileW( pwcsName,
    5354                         accessMode,
    5355                         shareMode,
    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);
    53605466 
    53615467 
    53625468  if (hFile==INVALID_HANDLE_VALUE)
    53635469  {
    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;
    53655497  }
    53665498
     
    53785510         NULL,
    53795511         grfMode,
    5380          TRUE);
     5512         TRUE,
     5513         FALSE);
    53815514 
    53825515  if (FAILED(hr))
     
    54285561         plkbyt,
    54295562         grfMode,
    5430          FALSE);
     5563         FALSE,
     5564         TRUE);
    54315565
    54325566  if (FAILED(hr))
     
    54915625         plkbyt,
    54925626         grfMode,
     5627         FALSE,
    54935628         FALSE);
    54945629
     
    55825717    HRESULT res;
    55835718
     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 )                                                                       */
    55845724    FIXME("(),stub!\n");
    55855725
     
    55875727
    55885728    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
    55905732        res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj);
    55915733
     
    56195761        if (SUCCEEDED(res))
    56205762
    5621             res=IPersistStream_Save(pPStm,pStm,FALSE);
    5622     }
    5623 
     5763            res=IPersistStream_Save(pPStm,pStm,TRUE);
     5764    }
     5765
     5766    TRACE("Finished Save\n");
    56245767    return res;
    56255768}
     
    58085951}
    58095952
    5810 
     5953BOOL 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 */
     5981HRESULT 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 */
     6128HRESULT 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 */
     6254void 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 */
     6304DWORD 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 */
     6360void 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 */
     6404HRESULT 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 */
     6554HRESULT 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 */
     6662void 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 */
     6762void 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 */
     6801HRESULT 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 */
     6945void 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
     7002LPMONIKER 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
     7039HRESULT 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 */
     7162HRESULT 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
     7212HRESULT 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
     7240HRESULT 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
     7270HRESULT 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
     7315HRESULT 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 */
     7348HRESULT 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 */
     7426HRESULT 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}
    58117498
    58127499/******************************************************************************
     
    58147501 */
    58157502HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn) {
     7503static const BYTE STORAGE_notmagic[8]={0x0e,0x11,0xfc,0x0d,0xd0,0xcf,0x11,0xe0};
    58167504        HFILE           hf;
    58177505        OFSTRUCT        ofs;
Note: See TracChangeset for help on using the changeset viewer.