Changeset 3167 for trunk/src


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

Ported changes from wine/corel sources

Location:
trunk/src/ole32
Files:
1 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/ole32/clsid.cpp

    r1822 r3167  
    1 /* $Id: clsid.cpp,v 1.9 1999-11-23 20:37:42 davidr Exp $ */
     1/* $Id: clsid.cpp,v 1.10 2000-03-19 15:33:05 davidr Exp $ */
    22/*
    33 *
     
    2424
    2525// ----------------------------------------------------------------------
     26// CLSIDFromProgID16()
     27// ----------------------------------------------------------------------
     28HRESULT WIN32API CLSIDFromProgID16(
     29    LPCOLESTR16         lpszProgID,     // [in] - UNICODE program id as found in registry
     30    LPCLSID             pclsid)         // [out] - CLSID
     31{
     32    dprintf(("OLE32: CLSIDFromProgID16"));
     33
     34    LONG                lDataLen = 80;
     35    oStringA            szKey(lpszProgID);
     36    oStringA            szCLSID(lDataLen, 1);
     37    HKEY                hKey;
     38    HRESULT             rc;
     39
     40    // Create the registry lookup string...
     41    szKey += "\\CLSID";
     42
     43    // Try to open the key in the registry...
     44    rc = RegOpenKeyA(HKEY_CLASSES_ROOT, szKey, &hKey);
     45    if (rc != 0)
     46        return OLE_ERROR_GENERIC;
     47
     48    // Now get the data from the _default_ entry on this key...
     49    rc = RegQueryValueA(hKey, NULL, szCLSID, &lDataLen);
     50    RegCloseKey(hKey);
     51    if (rc != 0)
     52        return OLE_ERROR_GENERIC;
     53
     54    // Now convert from a string to a UUID
     55    return CLSIDFromString16(szCLSID, pclsid);
     56}
     57
     58// ----------------------------------------------------------------------
    2659// CLSIDFromProgID()
    2760// ----------------------------------------------------------------------
     
    72105// ----------------------------------------------------------------------
    73106
    74 // missing prototype
    75 LPWSTR WIN32API HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str );
    76 
    77107HRESULT WIN32API CLSIDFromStringA(
    78108    LPCSTR              lpsz,           // [in] - ASCII string CLSID
    79109    LPCLSID             pclsid)         // [out] - Binary CLSID
    80110{
    81   LPWSTR  lpszOle = HEAP_strdupAtoW(GetProcessHeap(),
    82                                     0,
    83                                     lpsz);
    84   HRESULT hRes;
    85 
    86   dprintf(("OLE32: CLSIDFromStringA"));
    87 
    88   hRes = CLSIDFromString(lpszOle, pclsid);
    89   HeapFree(GetProcessHeap(), 0, lpszOle);
    90   return hRes;
    91 }
    92 
     111    return CLSIDFromString16(lpsz, pclsid);
     112}
     113
     114
     115// ----------------------------------------------------------------------
     116// CLSIDFromString16()
     117// ----------------------------------------------------------------------
     118HRESULT WIN32API CLSIDFromString16(
     119    LPCOLESTR16         lpsz,           // [in] - Unicode string CLSID
     120    LPCLSID             pclsid)         // [out] - Binary CLSID
     121{
     122    dprintf(("OLE32: CLSIDFromString16"));
     123
     124    // Convert to binary CLSID
     125    char *s = (char *) lpsz;
     126    char *p;
     127    int   i;
     128    char table[256];
     129
     130    /* quick lookup table */
     131    memset(table, 0, 256);
     132
     133    for (i = 0; i < 10; i++)
     134    {
     135        table['0' + i] = i;
     136    }
     137    for (i = 0; i < 6; i++)
     138    {
     139        table['A' + i] = i+10;
     140        table['a' + i] = i+10;
     141    }
     142
     143    /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
     144
     145    if (lstrlenA(lpsz) != 38)
     146        return OLE_ERROR_OBJECT;
     147
     148    p = (char *) pclsid;
     149
     150    s++;  /* skip leading brace  */
     151    for (i = 0; i < 4; i++)
     152    {
     153        p[3 - i] = table[*s]<<4 | table[*(s+1)];
     154        s += 2;
     155    }
     156    p += 4;
     157    s++;  /* skip - */
     158
     159    for (i = 0; i < 2; i++)
     160    {
     161        p[1-i] = table[*s]<<4 | table[*(s+1)];
     162        s += 2;
     163    }
     164    p += 2;
     165    s++;  /* skip - */
     166
     167    for (i = 0; i < 2; i++)
     168    {
     169        p[1-i] = table[*s]<<4 | table[*(s+1)];
     170        s += 2;
     171    }
     172    p += 2;
     173    s++;  /* skip - */
     174
     175    /* these are just sequential bytes */
     176    for (i = 0; i < 2; i++)
     177    {
     178        *p++ = table[*s]<<4 | table[*(s+1)];
     179        s += 2;
     180    }
     181    s++;  /* skip - */
     182
     183    for (i = 0; i < 6; i++)
     184    {
     185        *p++ = table[*s]<<4 | table[*(s+1)];
     186        s += 2;
     187    }
     188
     189    return S_OK;
     190}
    93191
    94192// ----------------------------------------------------------------------
     
    103201    oStringA            tClsId(lpsz);
    104202
    105     HRESULT             ret = OLE_ERROR_GENERIC;
    106 
    107     // Convert to binary CLSID
    108     char *s = (char *) tClsId;
    109     char *p;
    110     int   i;
    111     char table[256];
    112 
    113     /* quick lookup table */
    114     memset(table, 0, 256);
    115 
    116     for (i = 0; i < 10; i++)
    117     {
    118         table['0' + i] = i;
    119     }
    120     for (i = 0; i < 6; i++)
    121     {
    122         table['A' + i] = i+10;
    123         table['a' + i] = i+10;
    124     }
    125 
    126     /* in form {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX} */
    127 
    128     if (lstrlenW(lpsz) != 38)
    129         return OLE_ERROR_OBJECT;
    130 
    131     p = (char *) pclsid;
    132 
    133     s++;  /* skip leading brace  */
    134     for (i = 0; i < 4; i++)
    135     {
    136         p[3 - i] = table[*s]<<4 | table[*(s+1)];
    137         s += 2;
    138     }
    139     p += 4;
    140     s++;  /* skip - */
    141 
    142     for (i = 0; i < 2; i++)
    143     {
    144         p[1-i] = table[*s]<<4 | table[*(s+1)];
    145         s += 2;
    146     }
    147     p += 2;
    148     s++;  /* skip - */
    149 
    150     for (i = 0; i < 2; i++)
    151     {
    152         p[1-i] = table[*s]<<4 | table[*(s+1)];
    153         s += 2;
    154     }
    155     p += 2;
    156     s++;  /* skip - */
    157 
    158     /* these are just sequential bytes */
    159     for (i = 0; i < 2; i++)
    160     {
    161         *p++ = table[*s]<<4 | table[*(s+1)];
    162         s += 2;
    163     }
    164     s++;  /* skip - */
    165 
    166     for (i = 0; i < 6; i++)
    167     {
    168         *p++ = table[*s]<<4 | table[*(s+1)];
    169         s += 2;
    170     }
    171 
    172     return S_OK;
     203    return CLSIDFromString16(tClsId, pclsid);
    173204}
    174205
  • trunk/src/ole32/datacache.cpp

    r1033 r3167  
    1 /* $Id: datacache.cpp,v 1.1 1999-09-24 21:49:42 davidr Exp $ */
     1/* $Id: datacache.cpp,v 1.2 2000-03-19 15:33:05 davidr Exp $ */
    22/*
    33 *  OLE 2 Data cache
     
    13151315  TRACE("(%p, %p)\n", iface, pStgNew);
    13161316
    1317   /*
    1318    * First, make sure we get our hands off any storage we have.
    1319    */
    1320   DataCache_HandsOffStorage(iface);
    1321 
    1322   /*
    1323    * Then, attach to the new storage.
    1324    */
    1325   DataCache_Load(iface, pStgNew);
     1317  if (pStgNew)
     1318  {
     1319      /*
     1320       * First, make sure we get our hands off any storage we have.
     1321       */
     1322      DataCache_HandsOffStorage(iface);
     1323
     1324      /*
     1325       * Then, attach to the new storage.
     1326       */
     1327      DataCache_Load(iface, pStgNew);
     1328  }
    13261329
    13271330  return S_OK;
     
    14431446    return E_INVALIDARG;
    14441447
     1448/** Hack for WPO2000 release. */
     1449  if (dwDrawAspect != DVASPECT_CONTENT)
     1450  {
     1451      FIXME("only CONTENT aspect implemented\n");
     1452      dwDrawAspect = DVASPECT_CONTENT;
     1453  }
     1454/***/
     1455
    14451456  /*
    14461457   * First, we need to retrieve the dimensions of the
  • trunk/src/ole32/filemoniker.cpp

    r1033 r3167  
    1 /* $Id: filemoniker.cpp,v 1.1 1999-09-24 21:49:43 davidr Exp $ */
     1/* $Id: filemoniker.cpp,v 1.2 2000-03-19 15:33:06 davidr Exp $ */
    22/*
    33 *  FileMonikers functions.
     
    1515#include "debugtools.h"
    1616#include "filemoniker.h"
     17#include "winnls.h"
    1718
    1819DEFAULT_DEBUG_CHANNEL(ole)
     
    212213{
    213214    HRESULT res;
    214     CHAR* filePathA;
    215     WCHAR* filePathW;
     215    CHAR* filePathA=NULL;
     216    WCHAR* filePathW=NULL;
    216217    ULONG bread;
    217218    WORD  wbuffer;
    218     DWORD dwbuffer,length,i,doubleLenHex,doubleLenDec;
    219 
     219    DWORD i;
     220    DWORD dwAnsiLength, dwUnicodeLength;
     221    DWORD dwOffsetToEndUnicodeStr;
     222    WCHAR tempUnicodePath[MAX_PATH];
    220223    ICOM_THIS(FileMonikerImpl,iface);
    221224
     
    230233   
    231234    /* read filePath string length (plus one) */
    232     res=IStream_Read(pStm,&length,sizeof(DWORD),&bread);
     235    res=IStream_Read(pStm,&dwAnsiLength,sizeof(DWORD),&bread);
    233236    if (bread != sizeof(DWORD))
    234237        return E_FAIL;
    235238
    236     /* read filePath string */
    237     filePathA=(CHAR*)HeapAlloc(GetProcessHeap(),0,length);
    238     res=IStream_Read(pStm,filePathA,length,&bread);
    239     if (bread != length)
     239    if(dwAnsiLength > 0)
     240    {
     241        /* read filePath string */
     242        filePathA=(CHAR *)HeapAlloc(GetProcessHeap(),0,dwAnsiLength);
     243        res=IStream_Read(pStm,filePathA,dwAnsiLength,&bread);
     244        if (bread != dwAnsiLength)
     245            return E_FAIL;
     246    }
     247    tempUnicodePath[0] = 0;
     248    if(filePathA != NULL)
     249    {
     250        MultiByteToWideChar(CP_ACP, 0, filePathA, -1, tempUnicodePath, MAX_PATH);
     251    }
     252    FileMonikerImpl_CheckFileFormat(This, tempUnicodePath);
     253
     254    IStream_Read(pStm, &(This->wNetworkDomainLenght), sizeof(WORD), &bread);
     255    if(bread != sizeof(WORD))
     256    {
    240257        return E_FAIL;
    241 
     258    }
    242259    /* read the first constant */
    243     IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
    244     if (bread != sizeof(DWORD) || dwbuffer != 0xDEADFFFF)
     260    IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
     261    if (bread != sizeof(WORD) || wbuffer != 0xDEAD)
    245262        return E_FAIL;
    246        
    247     length--;
    248263       
    249264    for(i=0;i<10;i++){
     
    253268    }
    254269   
    255     if (length>8)
    256         length=0;
    257        
    258     doubleLenHex=doubleLenDec=2*length;
    259     if (length > 5)
    260         doubleLenDec+=6;
    261 
    262     res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
    263     if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenDec)
     270    res=IStream_Read(pStm,&dwOffsetToEndUnicodeStr,sizeof(DWORD),&bread);
     271    if (bread != sizeof(DWORD))
    264272        return E_FAIL;
    265 
    266     if (length==0)
    267         return res;
    268        
    269     res=IStream_Read(pStm,&dwbuffer,sizeof(DWORD),&bread);
    270     if (bread!=sizeof(DWORD) || dwbuffer!=doubleLenHex)
    271         return E_FAIL;
    272 
    273     res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
    274     if (bread!=sizeof(WORD) || wbuffer!=0x3)
    275         return E_FAIL;
    276 
    277     filePathW=(WCHAR*)HeapAlloc(GetProcessHeap(),0,(length+1)*sizeof(WCHAR));
    278     filePathW[length]=0;
    279     res=IStream_Read(pStm,filePathW,doubleLenHex,&bread);
    280     if (bread!=doubleLenHex)
    281         return E_FAIL;
     273    if(dwOffsetToEndUnicodeStr != 0)
     274    {
     275        res=IStream_Read(pStm,&dwUnicodeLength,sizeof(DWORD),&bread);
     276        if (bread!=sizeof(DWORD))
     277            return E_FAIL;
     278
     279
     280        res=IStream_Read(pStm,&wbuffer,sizeof(WORD),&bread);
     281        if (bread!=sizeof(WORD) || wbuffer!=0x3)
     282            return E_FAIL;
     283
     284        if(dwUnicodeLength > 0)
     285        {
     286            filePathW=(WCHAR *)HeapAlloc(GetProcessHeap(),0,dwUnicodeLength + sizeof(WCHAR));
     287            res=IStream_Read(pStm, filePathW, dwUnicodeLength,&bread);
     288            filePathW[dwAnsiLength-1]=0;
     289            if (bread!=dwUnicodeLength)
     290                return E_FAIL;
     291        }
     292    }
     293    else
     294    {
     295        if(filePathA != NULL)
     296        {
     297            filePathW=(WCHAR *)HeapAlloc(GetProcessHeap(),0,dwAnsiLength*sizeof(WCHAR));
     298            MultiByteToWideChar(CP_ACP, 0, filePathA, -1, filePathW, dwAnsiLength);
     299            filePathW[dwAnsiLength-1]=0;
     300        }
     301    }
    282302
    283303    if (This->filePathName!=NULL)
     
    286306    This->filePathName=filePathW;
    287307
    288     HeapFree(GetProcessHeap(),0,filePathA);
     308    if(filePathA != NULL)
     309    {
     310        HeapFree(GetProcessHeap(),0,filePathA);
     311    }
    289312   
    290313    return res;
     
    313336    HRESULT res;
    314337    LPOLESTR filePathW=This->filePathName;
    315     CHAR*     filePathA;
    316     DWORD  len=1+lstrlenW(filePathW);
    317 
    318     DWORD  constant1 = 0xDEADFFFF; /* these constants are detected after analysing the data structure writen by */
     338    CHAR*     filePathA=NULL;
     339    DWORD  len=0;
     340
     341    WORD  constant1 = 0xDEAD; /* these constants are detected after analysing the data structure writen by */
    319342    WORD   constant2 = 0x3;        /* FileMoniker_Save function in a windows program system */
     343    WORD wUnicodeLen=0xFFFF; 
     344    DWORD dwOffsetToEndUnicodeStr=0;
    320345
    321346    WORD   zero=0;
    322347    DWORD doubleLenHex;
    323     DWORD doubleLenDec;
    324348    int i=0;
     349    WCHAR temp = 0;
     350
    325351
    326352    TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty);
     
    328354    if (pStm==NULL)
    329355        return E_POINTER;
     356    if(filePathW == NULL)
     357    {
     358        return S_FALSE;  /* TODO: Check what windows returns */
     359    }
     360
     361    doubleLenHex=lstrlenW(filePathW) * sizeof(WCHAR); /* Doesn't include the "\0" */
     362    len = lstrlenW(filePathW)+1;
     363    filePathA=(CHAR *)HeapAlloc(GetProcessHeap(), 0,len);
     364    lstrcpyWtoA(filePathA,filePathW);
     365   
     366    if(!This->bIsLongFileName && len > 1)
     367    {
     368       
     369        dwOffsetToEndUnicodeStr = sizeof(DWORD) + sizeof(WORD) + doubleLenHex;
     370    }
    330371
    331372    /* write a DWORD seted to 0 : constant */
     373    /* TODO: Not Sure, but I believe that this is a constant for  char types */
     374    /* eg. 0000 for Ansi, 0003 for Unicode, will need to verify this  */
    332375    res=IStream_Write(pStm,&zero,sizeof(WORD),NULL);
    333376
     
    336379
    337380    /* write filePath string type A */
    338     filePathA=(CHAR *)HeapAlloc(GetProcessHeap(),0,len);
    339     lstrcpyWtoA(filePathA,filePathW);
    340381    res=IStream_Write(pStm,filePathA,len,NULL);
    341     HeapFree(GetProcessHeap(),0,filePathA);
    342 
    343     /* write a DWORD seted to 0xDEADFFFF: constant */
    344     res=IStream_Write(pStm,&constant1,sizeof(DWORD),NULL);
     382
     383    /*When the file path is a network path, it fills this value with */
     384    /*Lenght in of the domain/share drive name */
     385    res=IStream_Write(pStm, &(This->wNetworkDomainLenght), sizeof(wUnicodeLen), NULL);
     386    /* write a WORD seted to 0xDEAD: constant */
     387    res=IStream_Write(pStm,&constant1,sizeof(constant1),NULL);
    345388       
    346389    len--;
    347     /* write 10 times a DWORD seted to 0 : constants */
     390    /* write 10 times a WORD seted to 0 : constants */
    348391    for(i=0;i<10;i++)
    349392        res=IStream_Write(pStm,&zero,sizeof(WORD),NULL);
    350        
    351     if (len>8)
    352         len=0;
    353        
    354     doubleLenHex=doubleLenDec=2*len;
    355     if (len > 5)
    356         doubleLenDec+=6;
    357 
    358     /* write double-length of the path string ( "\0" included )*/
    359     res=IStream_Write(pStm,&doubleLenDec,sizeof(DWORD),NULL);
    360 
    361     if (len==0)
    362         return res;
    363 
    364     /* write double-length (hexa representation) of the path string ( "\0" included ) */
    365     res=IStream_Write(pStm,&doubleLenHex,sizeof(DWORD),NULL);
    366 
    367     /* write a WORD seted to 0x3: constant */
    368     res=IStream_Write(pStm,&constant2,sizeof(WORD),NULL);
    369 
    370     /* write path unicode string */
    371     res=IStream_Write(pStm,filePathW,doubleLenHex,NULL);
    372 
     393
     394    /* when a file path is a file or network path that doesn't fallow the dos 8.3 format  */
     395    /* it creates the unicode data.  This value is offset */
     396    /* where the Unicode string ends.  If the file is a long dos filename (or network containing a long filename)*/
     397    /* it doesn't create it's unicode counterpart */   
     398    res=IStream_Write(pStm, &dwOffsetToEndUnicodeStr, sizeof(DWORD), NULL);
     399    if(dwOffsetToEndUnicodeStr != 0)
     400    {
     401        /* write double-length (hexa representation) of the path string*/
     402        res=IStream_Write(pStm, &doubleLenHex, sizeof(DWORD),NULL);
     403        /* write a WORD seted to 0x3: constant */
     404        /* TODO: (same as above) Not Sure, but I believe that this is a constant for  char types */
     405        /* eg. 0000 for Ansi, 0003 for Unicode, will need to verify this  */
     406        res=IStream_Write(pStm, &constant2, sizeof(WORD),NULL);
     407        /* write path unicode string */
     408        if(doubleLenHex > 0)
     409        {
     410            res=IStream_Write(pStm, filePathW, doubleLenHex,NULL);
     411        }
     412    }
     413    if(filePathA != NULL)
     414    {
     415        HeapFree(GetProcessHeap(),0,filePathA);
     416    }
    373417    return res;
    374418}
     
    386430    TRACE("(%p,%p)\n",iface,pcbSize);
    387431
    388     if (pcbSize!=NULL)
     432    if (pcbSize==NULL)
    389433        return E_POINTER;
    390434
     
    398442               sizeof(DWORD);           /* size of the unicode filePath: "\0" not included */
    399443
    400     if (len==0 || len > 8)
    401         return S_OK;
    402    
    403     sizeMAx += sizeof(DWORD)+           /* size of the unicode filePath: "\0" not included */
    404                sizeof(WORD)+            /* constant : 0x3 */
    405                len*sizeof(WCHAR);       /* unicde filePath string */
     444    if(!This->bIsLongFileName)
     445    {
     446       
     447        sizeMAx += sizeof(DWORD)+           /* size of the unicode filePath: "\0" not included */
     448                   sizeof(WORD)+            /* constant : 0x3 */
     449                   len*sizeof(WCHAR);       /* unicde filePath string */
     450    }
    406451   
    407452    pcbSize->LowPart=sizeMAx;
     
    411456}
    412457
     458void WINAPI FileMonikerImpl_CheckFileFormat(FileMonikerImpl* This, LPCOLESTR lpszPathName)
     459{
     460    int len;
     461    WCHAR tempShortPath[MAX_PATH];
     462
     463    This->bIsNetworkPath = FALSE;
     464    This->bIsLongFileName = FALSE;
     465    This->wNetworkDomainLenght = 0xFFFF;
     466
     467    /* TODO: Not handling invalid filesname  and invalid UNC Filenames */
     468    /* Filenames that doesn't conform to dos 8.3, are handled diffently when saving and loading */
     469    /* Same applies to network path, but only after the \\Domain\Share path */
     470
     471    if(lpszPathName == NULL)
     472    {
     473        return;
     474    }
     475    len = lstrlenW(lpszPathName);
     476    if(len == 0)
     477    {
     478        return;
     479    }
     480
     481    if( len >= 2)
     482    {
     483        /* Is this a network path */
     484        if(lpszPathName[0] == '\\' && lpszPathName[1] == '\\')
     485        {
     486            int i=2; /* Skip the \\ */
     487            int j=0;
     488            This->bIsNetworkPath = TRUE;
     489            /* Skip Domain name \ share drive name */
     490            for(j =0; j < 2; j++)
     491            {
     492                for(; i < len && lpszPathName[i] != '\\'; i++)
     493                {
     494                }
     495                i++;
     496            }
     497            This->wNetworkDomainLenght = i-1;
     498            if( i < len)
     499            {
     500                /* Check to see if the file fallows the dos file format (8.3)*/
     501                GetShortPathNameW(&(lpszPathName[i]), tempShortPath, MAX_PATH);
     502                if(lstrcmpiW(&(lpszPathName[i]), tempShortPath) != 0)
     503                {
     504                    This->bIsLongFileName = TRUE;
     505                }
     506            }
     507        }
     508       
     509        else
     510        {
     511            GetShortPathNameW(lpszPathName, tempShortPath, MAX_PATH);
     512            if(lstrcmpiW(lpszPathName, tempShortPath) != 0)
     513            {
     514                This->bIsLongFileName = TRUE;
     515            }
     516        }
     517    }
     518}
    413519/******************************************************************************
    414520 *         FileMoniker_Construct (local function)
     
    475581    }
    476582
     583    FileMonikerImpl_CheckFileFormat(This, This->filePathName);
    477584    for(i=0; tabStr[i]!=NULL;i++)
    478585        CoTaskMemFree(tabStr[i]);
     
    10481155{
    10491156    WCHAR bSlash[] = {'\\',0};
    1050     WCHAR word[100];
     1157    WCHAR word[MAX_PATH];
    10511158    int i=0,j,tabIndex=0;
    10521159    LPOLESTR *strgtable ;
  • trunk/src/ole32/filemoniker.h

    r1033 r3167  
    1 /* $Id: filemoniker.h,v 1.1 1999-09-24 21:49:43 davidr Exp $ */
     1/* $Id: filemoniker.h,v 1.2 2000-03-19 15:35:14 davidr Exp $ */
    22/*
    33 *
     
    2222
    2323    LPOLESTR filePathName; /* path string identified by this filemoniker */
     24    BOOL bIsLongFileName;  /* Is the path a valid dos 8.3 file */
     25    BOOL bIsNetworkPath;   /* Is the path a network path */
     26    WORD wNetworkDomainLenght;  /*Lenght of the \\Domain\share network name, otherwise 0xFFFF for regular file*/
    2427
    2528} FileMonikerImpl;
     
    2932HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface);
    3033int     WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** tabStr);
     34void WINAPI FileMonikerImpl_CheckFileFormat(FileMonikerImpl* iface, LPCOLESTR lpszPathName);
    3135
    3236#endif /* FILEMONIKER_INCLUDED */
  • trunk/src/ole32/hglobalstream.cpp

    r1033 r3167  
    1 /* $Id: hglobalstream.cpp,v 1.1 1999-09-24 21:49:43 davidr Exp $ */
     1/* $Id: hglobalstream.cpp,v 1.2 2000-03-19 15:33:06 davidr Exp $ */
    22/*
    33 *  HGLOBAL Stream implementation functions.
     
    2626struct HGLOBALStreamImpl
    2727{
    28   ICOM_VTABLE(IStream) *lpvtbl;  /* Needs to be the first item in the stuct
     28  ICOM_VFIELD(IStream);  /* Needs to be the first item in the stuct
    2929                                  * since we want to cast this in a IStream pointer */
    3030 
     
    200200   * Verify that the stream object was created with CreateStreamOnHGlobal.
    201201   */
    202   if (pStream->lpvtbl == &HGLOBALStreamImpl_Vtbl)
     202  if (ICOM_VTBL(pStream) == &HGLOBALStreamImpl_Vtbl)
    203203    *phglobal = pStream->supportHandle;
    204204  else
     
    236236     * Set-up the virtual function table and reference count.
    237237     */
    238     newStream->lpvtbl = &HGLOBALStreamImpl_Vtbl;
     238    ICOM_VTBL(newStream) = &HGLOBALStreamImpl_Vtbl;
    239239    newStream->ref    = 0;
    240240   
  • trunk/src/ole32/moniker.cpp

    r2764 r3167  
    1 /* $Id: moniker.cpp,v 1.4 2000-02-12 11:51:03 davidr Exp $ */
     1/* $Id: moniker.cpp,v 1.5 2000-03-19 15:33:06 davidr Exp $ */
    22/*
    33 *
     
    279279   
    280280    return res;
    281     return S_OK;
    282281}
    283282
  • trunk/src/ole32/ole32.def

    r2000 r3167  
    168168    WriteOleStg                = _WriteOleStg@0              @161
    169169    WriteStringStream          = _WriteStringStream@0        @162
    170     CoImpersonateClient        = _CoImpersonateClient@0
    171     CoInitializeSecurity       = _CoInitializeSecurity@36
    172     CoRegisterSurrogate        = _CoRegisterSurrogate@4
     170
     171    CoImpersonateClient        = _CoImpersonateClient@0      @997       ; suppress warning
     172    CoInitializeSecurity       = _CoInitializeSecurity@36    @998       ; suppress warning
     173    CoRegisterSurrogate        = _CoRegisterSurrogate@4      @999       ; suppress warning
    173174
    174175;
     
    177178    WINE_StringFromCLSID       = _WINE_StringFromCLSID@8     @1000
    178179    CLSIDFromStringA           = _CLSIDFromStringA@8         @1001
     180    CLSIDFromString16          = _CLSIDFromString16@8        @1002      ; COMPOBJ.19
    179181
  • trunk/src/ole32/ole32.h

    r1033 r3167  
    1 /* $Id: ole32.h,v 1.9 1999-09-24 21:49:44 davidr Exp $ */
     1/* $Id: ole32.h,v 1.10 2000-03-19 15:35:14 davidr Exp $ */
    22/*
    33 *
     
    3939
    4040#include "objbase.h"
     41#include "docobj.h"    /* for the IID_StdOleLink */
    4142
    4243#include "wine/obj_inplace.h"
  • trunk/src/ole32/oleobj.cpp

    r1033 r3167  
    1 /* $Id: oleobj.cpp,v 1.1 1999-09-24 21:49:44 davidr Exp $ */
     1/* $Id: oleobj.cpp,v 1.2 2000-03-19 15:33:06 davidr Exp $ */
    22/*
    33 * OLE2 COM objects
     
    2424typedef struct OleAdviseHolderImpl
    2525{
    26   ICOM_VTABLE(IOleAdviseHolder)* lpvtbl;
     26  ICOM_VFIELD(IOleAdviseHolder);
    2727
    2828  DWORD ref;
     
    7575                                         sizeof(OleAdviseHolderImpl));
    7676 
    77   lpoah->lpvtbl = &oahvt;
     77  ICOM_VTBL(lpoah) = &oahvt;
    7878  lpoah->ref = 1;
    7979  lpoah->maxSinks = 10;
    80   lpoah->arrayOfSinks = (IAdviseSink **)HeapAlloc(GetProcessHeap(),
     80  lpoah->arrayOfSinks = (IAdviseSink**)HeapAlloc(GetProcessHeap(),
    8181                                  0,
    8282                                  lpoah->maxSinks * sizeof(IAdviseSink*));
     
    226226    This->maxSinks+=10;
    227227
    228     This->arrayOfSinks = (IAdviseSink **)HeapReAlloc(GetProcessHeap(),
     228    This->arrayOfSinks = (IAdviseSink**)HeapReAlloc(GetProcessHeap(),
    229229                                     0,
    230230                                     This->arrayOfSinks,
     
    348348typedef struct DataAdviseHolder
    349349{
    350   ICOM_VTABLE(IDataAdviseHolder)* lpvtbl;
     350  ICOM_VFIELD(IDataAdviseHolder);
    351351
    352352  DWORD ref;
     
    411411                                           sizeof(DataAdviseHolder));
    412412 
    413   newHolder->lpvtbl = &DataAdviseHolderImpl_VTable;
     413  ICOM_VTBL(newHolder) = &DataAdviseHolderImpl_VTable;
    414414  newHolder->ref = 1;
    415415
  • trunk/src/ole32/stg_bigblockfile.cpp

    r1033 r3167  
    1 /* $Id: stg_bigblockfile.cpp,v 1.1 1999-09-24 21:49:44 davidr Exp $ */
     1/* $Id: stg_bigblockfile.cpp,v 1.2 2000-03-19 15:33:07 davidr Exp $ */
    22/*
    33 * BigBlockFile
    44 *
    5  * 20/9/99
    6  *
    7  * Copyright 1999 David J. Raison
     5 * 12/03/00
    86 *
    97 * Direct port of Wine Implementation
     
    3129#include <assert.h>
    3230
    33 DEFAULT_DEBUG_CHANNEL(storage)
     31#define CHAR_BIT 8      // (From EMX limits.h)
    3432
    3533/***********************************************************
     
    3836 */
    3937
    40 /***
    41  * Itdentifies a single big block and the related
    42  * information
    43  */
    44 struct BigBlock
    45 {
    46   BigBlock * next;
    47   DWORD index;
    48   DWORD access_mode;
    49   LPVOID lpBlock;
    50 };
     38/* We map in PAGE_SIZE-sized chunks. Must be a multiple of 4096. */
     39#define PAGE_SIZE       131072
     40
     41#define BLOCKS_PER_PAGE (PAGE_SIZE / BIG_BLOCK_SIZE)
     42
     43/* We keep a list of recently-discarded pages. This controls the
     44 * size of that list. */
     45#define MAX_VICTIM_PAGES 16
     46
     47/* This structure provides one bit for each block in a page.
     48 * Use BIGBLOCKFILE_{Test,Set,Clear}Bit to manipulate it. */
     49typedef struct
     50{
     51    unsigned int bits[BLOCKS_PER_PAGE / (CHAR_BIT * sizeof(unsigned int))];
     52} BlockBits;
    5153
    5254/***
     
    5456 * from the file and their position in memory. It is
    5557 * also used to hold a reference count to those pages.
     58 *
     59 * page_index identifies which PAGE_SIZE chunk from the
     60 * file this mapping represents. (The mappings are always
     61 * PAGE_SIZE-aligned.)
    5662 */
    5763struct MappedPage
    5864{
    59   MappedPage * next;
    60   DWORD number;
    61   int ref;
    62   LPVOID lpBytes;
     65    MappedPage *next;
     66    MappedPage *prev;
     67
     68    DWORD  page_index;
     69    LPVOID lpBytes;
     70    LONG   refcnt;
     71
     72    BlockBits readable_blocks;
     73    BlockBits writable_blocks;
    6374};
    64 
    65 #define PAGE_SIZE       131072
    66 #define BLOCKS_PER_PAGE 256
    67 
    68 #define NUMBER_OF_MAPPED_PAGES 100
    6975
    7076/***********************************************************
     
    7278 */
    7379static void*     BIGBLOCKFILE_GetMappedView(LPBIGBLOCKFILE This,
    74                                             DWORD          pagenum,
    75                                             DWORD          desired_access);
     80                                            DWORD          page_index);
    7681static void      BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This,
    77                                                 DWORD          pagenum,
    78                                                 DWORD          access);
     82                                                MappedPage *page);
    7983static void      BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This);
     84static void      BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This);
     85static void      BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This);
    8086static void*     BIGBLOCKFILE_GetBigBlockPointer(LPBIGBLOCKFILE This,
    8187                                                 ULONG          index,
    8288                                                 DWORD          desired_access);
    83 static BigBlock* BIGBLOCKFILE_GetBigBlockFromPointer(LPBIGBLOCKFILE This,
    84                                                      void*          pBlock);
    85 static void      BIGBLOCKFILE_RemoveBlock(LPBIGBLOCKFILE This,
    86                                           ULONG          index);
    87 static BigBlock* BIGBLOCKFILE_AddBigBlock(LPBIGBLOCKFILE This,
    88                                           ULONG          index);
    89 static BigBlock* BIGBLOCKFILE_CreateBlock(ULONG index);
     89static MappedPage* BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
     90                                                   void*         pBlock);
     91static MappedPage* BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
     92                                           ULONG page_index);
    9093static DWORD     BIGBLOCKFILE_GetProtectMode(DWORD openFlags);
    9194static BOOL      BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile);
    9295static BOOL      BIGBLOCKFILE_MemInit(LPBIGBLOCKFILE This, ILockBytes* plkbyt);
    93 static void      BIGBLOCKFILE_RemoveAllBlocks(LPBIGBLOCKFILE This);
     96
     97/* Note that this evaluates a and b multiple times, so don't
     98 * pass expressions with side effects. */
     99#define ROUND_UP(a, b) (!(a) ? 0 : ((a) + (b) - (((a)-1) % (b)) - 1))
     100
     101/***********************************************************
     102 * Blockbits functions.
     103 */
     104static inline BOOL BIGBLOCKFILE_TestBit(const BlockBits *bb,
     105                                        unsigned int index)
     106{
     107    unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
     108    unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
     109
     110    return bb->bits[array_index] & (1 << bit_index);
     111}
     112
     113static inline void BIGBLOCKFILE_SetBit(BlockBits *bb, unsigned int index)
     114{
     115    unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
     116    unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
     117
     118    bb->bits[array_index] |= (1 << bit_index);
     119}
     120
     121static inline void BIGBLOCKFILE_ClearBit(BlockBits *bb, unsigned int index)
     122{
     123    unsigned int array_index = index / (CHAR_BIT * sizeof(unsigned int));
     124    unsigned int bit_index = index % (CHAR_BIT * sizeof(unsigned int));
     125
     126    bb->bits[array_index] &= ~(1 << bit_index);
     127}
     128
     129static inline void BIGBLOCKFILE_Zero(BlockBits *bb)
     130{
     131    memset(bb->bits, 0, sizeof(bb->bits));
     132}
    94133
    95134/******************************************************************************
     
    97136 *
    98137 * Construct a big block file. Create the file mapping object.
    99  * Create the read only mapped pages list, the writeable mapped page list
     138 * Create the read only mapped pages list, the writable mapped page list
    100139 * and the blocks in use list.
    101140 */
     
    120159  This->blocksize = blocksize;
    121160
    122   /* initialize the block list
    123    */
    124   This->headblock = NULL;
     161  This->maplist = NULL;
     162  This->victimhead = NULL;
     163  This->victimtail = NULL;
     164  This->num_victim_pages = 0;
    125165
    126166  if (This->fileBased)
     
    174214  }
    175215
    176   This->filesize.LowPart = GetFileSize(This->hfile, NULL);
    177 
    178   /* create the mapped pages list
    179    */
    180   This->maplisthead = (MappedPage *)HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
    181 
    182   if (This->maplisthead == NULL)
    183   {
    184     CloseHandle(This->hfilemap);
    185     CloseHandle(This->hfile);
    186     return FALSE;
    187   }
    188 
    189   This->maplisthead->next = NULL;
     216  This->filesize.LowPart = GetFileSize(This->hfile,
     217                                         (LPDWORD)&This->filesize.HighPart);
     218
     219  This->maplist = NULL;
     220
     221  TRACE("file len %lu\n", This->filesize.LowPart);
    190222
    191223  return TRUE;
     
    201233  This->hfile       = 0;
    202234  This->hfilemap    = NULL;
    203   This->maplisthead = NULL;
    204235
    205236  /*
     
    225256  This->pbytearray = GlobalLock(This->hbytearray);
    226257
     258  TRACE("mem on %p len %lu\n", This->pbytearray, This->filesize.LowPart);
     259
    227260  return TRUE;
    228261}
     
    236269  LPBIGBLOCKFILE This)
    237270{
     271  BIGBLOCKFILE_FreeAllMappedPages(This);
     272
    238273  if (This->fileBased)
    239274  {
    240     /* unmap all views and destroy the mapped page list
    241      */
    242     BIGBLOCKFILE_FreeAllMappedPages(This);
    243     HeapFree(GetProcessHeap(), 0, This->maplisthead);
    244  
    245     /* close all open handles
    246      */
    247275    CloseHandle(This->hfilemap);
    248276    CloseHandle(This->hfile);
     
    253281    ILockBytes_Release(This->pLkbyt);
    254282  }
    255 
    256   /*
    257    * Destroy the blocks list.
    258    */
    259   BIGBLOCKFILE_RemoveAllBlocks(This);
    260283
    261284  /* destroy this
     
    287310   *
    288311   */
    289   if ((This->blocksize * (index + 1)) >
    290       (This->filesize.LowPart +
    291        (This->blocksize - (This->filesize.LowPart % This->blocksize))))
    292     return 0;
     312  if (This->blocksize * (index + 1)
     313      > ROUND_UP(This->filesize.LowPart, This->blocksize))
     314  {
     315    TRACE("out of range %lu vs %lu\n", This->blocksize * (index + 1),
     316          This->filesize.LowPart);
     317    return NULL;
     318  }
    293319
    294320  return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_READ);
     
    335361void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock)
    336362{
    337   DWORD page_num;
    338   BigBlock* theBigBlock;
    339 
    340   if (pBlock == NULL)
    341     return;
    342 
    343   /*
    344    * get the block from the block list
    345    */
    346   theBigBlock = BIGBLOCKFILE_GetBigBlockFromPointer(This, pBlock);
    347 
    348   if (theBigBlock == NULL)
    349     return;
    350 
    351   if (This->fileBased)
    352   {
    353     /*
    354      * find out which page this block is in
    355      */
    356     page_num = theBigBlock->index / BLOCKS_PER_PAGE;
    357  
    358     /*
    359      * release this page
    360      */
    361     BIGBLOCKFILE_ReleaseMappedPage(This, page_num, theBigBlock->access_mode);
    362   }
    363 
    364   /*
    365    * remove block from list
    366    */
    367   BIGBLOCKFILE_RemoveBlock(This, theBigBlock->index);
     363    MappedPage *page;
     364
     365    if (pBlock == NULL)
     366        return;
     367
     368    page = BIGBLOCKFILE_GetPageFromPointer(This, pBlock);
     369
     370    if (page == NULL)
     371        return;
     372
     373    BIGBLOCKFILE_ReleaseMappedPage(This, page);
    368374}
    369375
     
    379385    return;
    380386
     387  TRACE("from %lu to %lu\n", This->filesize.LowPart, newSize.LowPart);
     388  /*
     389   * unmap all views, must be done before call to SetEndFile
     390   */
     391  BIGBLOCKFILE_UnmapAllMappedPages(This);
     392 
    381393  if (This->fileBased)
    382394  {
    383     /*
    384      * unmap all views, must be done before call to SetEndFile
    385      */
    386     BIGBLOCKFILE_FreeAllMappedPages(This);
    387  
     395    char buf[10];
     396
    388397    /*
    389398     * close file-mapping object, must be done before call to SetEndFile
     
    391400    CloseHandle(This->hfilemap);
    392401    This->hfilemap = NULL;
     402
     403    /*
     404     * BEGIN HACK
     405     * This fixes a bug when saving through smbfs.
     406     * smbmount a Windows shared directory, save a structured storage file
     407     * to that dir: crash.
     408     *
     409     * The problem is that the SetFilePointer-SetEndOfFile combo below
     410     * doesn't always succeed. The file is not grown. It seems like the
     411     * operation is cached. By doing the WriteFile, the file is actually
     412     * grown on disk.
     413     * This hack is only needed when saving to smbfs.
     414     */
     415    memset(buf, '0', 10);
     416    SetFilePointer(This->hfile, newSize.LowPart, NULL, FILE_BEGIN);
     417    WriteFile(This->hfile, buf, 10, NULL, NULL);
     418    /*
     419     * END HACK
     420     */
    393421 
    394422    /*
     
    423451  }
    424452
    425   /*
    426    * empty the blocks list.
    427    */
    428   BIGBLOCKFILE_RemoveAllBlocks(This);
    429 
    430453  This->filesize.LowPart = newSize.LowPart;
    431454  This->filesize.HighPart = newSize.HighPart;
     455
     456  BIGBLOCKFILE_RemapAllMappedPages(This);
    432457}
    433458
     
    444469
    445470/******************************************************************************
     471 *      BIGBLOCKFILE_AccessCheck     [PRIVATE]
     472 *
     473 * block_index is the index within the page.
     474 */
     475static BOOL BIGBLOCKFILE_AccessCheck(MappedPage *page, ULONG block_index,
     476                                     DWORD desired_access)
     477{
     478    assert(block_index < BLOCKS_PER_PAGE);
     479
     480    if (desired_access == FILE_MAP_READ)
     481    {
     482        if (BIGBLOCKFILE_TestBit(&page->writable_blocks, block_index))
     483            return FALSE;
     484
     485        BIGBLOCKFILE_SetBit(&page->readable_blocks, block_index);
     486    }
     487    else
     488    {
     489        assert(desired_access == FILE_MAP_WRITE);
     490
     491        if (BIGBLOCKFILE_TestBit(&page->readable_blocks, block_index))
     492            return FALSE;
     493
     494        BIGBLOCKFILE_SetBit(&page->writable_blocks, block_index);
     495    }
     496
     497    return TRUE;
     498}
     499
     500/******************************************************************************
    446501 *      BIGBLOCKFILE_GetBigBlockPointer     [PRIVATE]
    447502 *
     
    450505static void* BIGBLOCKFILE_GetBigBlockPointer(
    451506  LPBIGBLOCKFILE This,
    452   ULONG          index,
     507  ULONG          block_index,
    453508  DWORD          desired_access)
    454509{
    455   DWORD block_num;
    456   void * pBytes;
    457   BigBlock *aBigBlock;
    458 
    459   /* get the big block from the list or add it to the list
    460    */
    461   aBigBlock = BIGBLOCKFILE_AddBigBlock(This, index);
    462 
    463   if (aBigBlock == NULL)
    464     return NULL;
    465 
    466   /* we already have an address for this block
    467    */
    468   if (aBigBlock->lpBlock != NULL)
    469   {
    470     /* make sure the desired access matches what we already have
    471      */
    472     if (aBigBlock->access_mode == desired_access)
    473       return aBigBlock->lpBlock;
    474     else
    475       return NULL;
    476   }
    477 
    478   /*
    479    * else aBigBlock->lpBigBlock == NULL, it's a new block
    480    */
    481 
    482   if (This->fileBased)
    483   {
    484     DWORD page_num;
    485 
    486     /* find out which page this block is in
    487      */
    488     page_num = index / BLOCKS_PER_PAGE;
    489  
    490     /* offset of the block in the page
    491      */
    492     block_num = index % BLOCKS_PER_PAGE;
    493  
    494     /* get a pointer to the first byte in the page
    495      */
    496     pBytes = BIGBLOCKFILE_GetMappedView(This, page_num, desired_access);
    497   }
    498   else
    499   {
    500     pBytes = This->pbytearray;
    501     block_num = index;
    502   }
    503 
    504   if (pBytes == NULL)
    505     return NULL;
    506 
    507   /* initialize block
    508    */
    509   aBigBlock->lpBlock = ((BYTE*)pBytes + (block_num*This->blocksize));
    510   aBigBlock->access_mode = desired_access;
    511 
    512   return aBigBlock->lpBlock;
    513 }
    514 
    515 /******************************************************************************
    516  *      BIGBLOCKFILE_CreateBlock      [PRIVATE]
    517  *
    518  * Creates a node of the blocks list.
    519  */
    520 static BigBlock* BIGBLOCKFILE_CreateBlock(
    521   ULONG index)
    522 {
    523   BigBlock *newBigBlock;
    524 
    525   /* create new list node
    526    */
    527   newBigBlock = (BigBlock *)HeapAlloc(GetProcessHeap(), 0, sizeof(BigBlock));
    528 
    529   if (newBigBlock == NULL)
    530     return NULL;
    531 
    532   /* initialize node
    533    */
    534   newBigBlock->index = index;
    535   newBigBlock->lpBlock = NULL;
    536 
    537   return newBigBlock;
    538 }
    539 
    540 /******************************************************************************
    541  *      BIGBLOCKFILE_AddBigBlock      [PRIVATE]
    542  *
    543  * Returns the specified block from the blocks list.
    544  * If the block is not found in the list, we will create it and add it to the
    545  * list.
    546  */
    547 static BigBlock* BIGBLOCKFILE_AddBigBlock(
    548   LPBIGBLOCKFILE This,
    549   ULONG          index)
    550 {
    551   BigBlock *current = This->headblock;
    552   BigBlock *newBigBlock;
    553 
    554   if (current == NULL) /* empty list */
    555   {
    556     newBigBlock = BIGBLOCKFILE_CreateBlock(index);
    557    
    558     if (newBigBlock != NULL)
    559     {
    560       newBigBlock->next = NULL;
    561       This->headblock = newBigBlock;
    562     }
    563 
    564     return newBigBlock;
    565   }
    566   else
    567   {
    568     /*
    569      * special handling for head of the list
    570      */
    571 
    572     if (current->index == index) /* it's already here */
    573       return current;
    574     else if (current->index > index) /* insertion at head of the list */
    575     {
    576       newBigBlock = BIGBLOCKFILE_CreateBlock(index);
    577 
    578       if (newBigBlock != NULL)
    579       {
    580         newBigBlock->next = current;
    581         This->headblock = newBigBlock;
    582       }
    583 
    584       return newBigBlock;
    585     }
    586   }
    587 
    588   /* iterate through rest the list
    589    */
    590   while (current->next != NULL)
    591   {
    592     if (current->next->index == index) /* found it */
    593     {
    594       return current->next;
    595     }
    596     else if (current->next->index > index) /* it's not in the list */
    597     {
    598       newBigBlock = BIGBLOCKFILE_CreateBlock(index);
    599 
    600       if (newBigBlock != NULL)
    601       {
    602         newBigBlock->next = current->next;
    603         current->next = newBigBlock;
    604       }
    605 
    606       return newBigBlock;
    607     }
    608     else
    609       current = current->next;
    610   }
    611 
    612   /*
    613    * insertion at end of the list
    614    */
    615   if (current->next == NULL)
    616   {
    617     newBigBlock = BIGBLOCKFILE_CreateBlock(index);
    618 
    619     if (newBigBlock != NULL)
    620     {
    621       newBigBlock->next = NULL;
    622       current->next = newBigBlock;
    623     }
    624 
    625     return newBigBlock;
    626   }
    627 
    628   return NULL;
    629 }
    630 
    631 /******************************************************************************
    632  *      BIGBLOCKFILE_RemoveAllBlocks      [PRIVATE]
    633  *
    634  * Removes all blocks from the blocks list.
    635  */
    636 static void BIGBLOCKFILE_RemoveAllBlocks(
    637   LPBIGBLOCKFILE This)
    638 {
    639   BigBlock *current;
    640 
    641   while (This->headblock != NULL)
    642   {
    643     current = This->headblock;
    644     This->headblock = current->next;
    645     HeapFree(GetProcessHeap(), 0, current);
    646   }
    647 }
    648 
    649 /******************************************************************************
    650  *      BIGBLOCKFILE_RemoveBlock      [PRIVATE]
    651  *
    652  * Removes the specified block from the blocks list.
    653  */
    654 static void BIGBLOCKFILE_RemoveBlock(
    655   LPBIGBLOCKFILE This,
    656   ULONG          index)
    657 {
    658   BigBlock *current = This->headblock;
    659 
    660   /*
    661    * empty list
    662    */
    663   if (current == NULL)
    664     return;
    665 
    666   /*
    667    *special case: removing head of list
    668    */
    669   if (current->index == index)
    670   {
    671     /*
    672      * set new head free the old one
    673      */
    674     This->headblock = current->next;
    675     HeapFree(GetProcessHeap(), 0, current);
    676    
    677     return;
    678   }
    679 
    680   /*
    681    * iterate through rest of the list
    682    */
    683   while (current->next != NULL)
    684   {
    685     if (current->next->index == index) /* found it */
    686     {
    687       /*
    688        * unlink the block and free the block
    689        */
    690       current->next = current->next->next;
    691       HeapFree(GetProcessHeap(), 0, current->next);
    692 
    693       return;
    694     }
    695     else
    696     {
    697       /* next node
    698        */
    699       current = current->next;
    700     }
    701   }
    702 }
    703 
    704 /******************************************************************************
    705  *      BIGBLOCKFILE_GetBigBlockFromPointer     [PRIVATE]
    706  *
    707  * Given a block pointer, this will return the corresponding block
    708  * from the blocks list.
    709  */
    710 static BigBlock* BIGBLOCKFILE_GetBigBlockFromPointer(
    711   LPBIGBLOCKFILE This,
    712   void*          pBlock)
    713 {
    714   BigBlock *current = This->headblock;
    715 
    716   while (current != NULL)
    717   {
    718     if (current->lpBlock == pBlock)
    719     {
    720       break;
    721     }
    722     else
    723       current = current->next;
    724   }
    725 
    726   return current;
     510    DWORD page_index = block_index / BLOCKS_PER_PAGE;
     511    DWORD block_on_page = block_index % BLOCKS_PER_PAGE;
     512
     513    MappedPage *page = (MappedPage *)BIGBLOCKFILE_GetMappedView(This, page_index);
     514    if (!page || !page->lpBytes) return NULL;
     515
     516    if (!BIGBLOCKFILE_AccessCheck(page, block_on_page, desired_access))
     517    {
     518        BIGBLOCKFILE_ReleaseMappedPage(This, page);
     519        return NULL;
     520    }
     521
     522    return (LPBYTE)page->lpBytes + (block_on_page * This->blocksize);
     523}
     524
     525/******************************************************************************
     526 *      BIGBLOCKFILE_GetMappedPageFromPointer     [PRIVATE]
     527 *
     528 * pBlock is a pointer to a block on a page.
     529 * The page has to be on the in-use list. (As oppsed to the victim list.)
     530 *
     531 * Does not increment the usage count.
     532 */
     533static MappedPage *BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This,
     534                                                   void *pBlock)
     535{
     536    MappedPage *page;
     537
     538    for (page = This->maplist; page != NULL; page = page->next)
     539    {
     540        if ((LPBYTE)pBlock >= (LPBYTE)page->lpBytes
     541            && (LPBYTE)pBlock <= (LPBYTE)page->lpBytes + PAGE_SIZE)
     542            break;
     543
     544    }
     545
     546    return page;
     547}
     548
     549/******************************************************************************
     550 *      BIGBLOCKFILE_FindPageInList      [PRIVATE]
     551 *
     552 */
     553static MappedPage *BIGBLOCKFILE_FindPageInList(MappedPage *head,
     554                                               ULONG page_index)
     555{
     556    for (; head != NULL; head = head->next)
     557    {
     558        if (head->page_index == page_index)
     559        {
     560            InterlockedIncrement(&head->refcnt);
     561            break;
     562        }
     563    }
     564
     565    return head;
     566
     567}
     568
     569static void BIGBLOCKFILE_UnlinkPage(MappedPage *page)
     570{
     571    if (page->next) page->next->prev = page->prev;
     572    if (page->prev) page->prev->next = page->next;
     573}
     574
     575static void BIGBLOCKFILE_LinkHeadPage(MappedPage **head, MappedPage *page)
     576{
     577    if (*head) (*head)->prev = page;
     578    page->next = *head;
     579    page->prev = NULL;
     580    *head = page;
    727581}
    728582
     
    735589static void * BIGBLOCKFILE_GetMappedView(
    736590  LPBIGBLOCKFILE This,
    737   DWORD          pagenum,
    738   DWORD          desired_access)
    739 {
    740   MappedPage* current = This->maplisthead;
    741   ULONG       count   = 1;
    742   BOOL        found   = FALSE;
    743 
    744   assert(This->maplisthead != NULL);
    745 
    746   /*
    747    * Search for the page in the list.
    748    */
    749   while ((found == FALSE) && (current->next != NULL))
    750   {
    751     if (current->next->number == pagenum)
    752     {
    753       found = TRUE;
    754 
    755       /*
    756        * If it's not already at the head of the list
    757        * move it there.
    758        */
    759       if (current != This->maplisthead)
    760       {
    761         MappedPage* temp = current->next;
    762 
    763         current->next = current->next->next;
    764 
    765         temp->next = This->maplisthead->next;
    766         This->maplisthead->next = temp;
    767       }
    768     }
    769 
    770     /*
    771      * The list is full and we haven't found it.
    772      * Free the last element of the list because we'll add a new
    773      * one at the head.
    774      */
    775     if ((found == FALSE) &&
    776         (count >= NUMBER_OF_MAPPED_PAGES) &&
    777         (current->next != NULL))
    778     {
    779       UnmapViewOfFile(current->next->lpBytes);
    780 
    781       HeapFree(GetProcessHeap(), 0, current->next);
    782       current->next = NULL;
    783     }
    784 
    785     if (current->next != NULL)
    786       current = current->next;
    787 
    788     count++;
    789   }
    790 
    791   /*
    792    * Add the page at the head of the list.
    793    */
    794   if (found == FALSE)
    795   {
    796     MappedPage* newMappedPage;
    797     DWORD       numBytesToMap;
    798     DWORD       hioffset  = 0;
    799     DWORD       lowoffset = PAGE_SIZE * pagenum;
    800 
    801     newMappedPage = (MappedPage *)HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
    802 
    803     if (newMappedPage == NULL)
     591  DWORD          page_index)
     592{
     593    MappedPage *page;
     594
     595    page = BIGBLOCKFILE_FindPageInList(This->maplist, page_index);
     596    if (!page)
     597    {
     598        page = BIGBLOCKFILE_FindPageInList(This->victimhead, page_index);
     599        if (page)
     600        {
     601            This->num_victim_pages--;
     602
     603            BIGBLOCKFILE_Zero(&page->readable_blocks);
     604            BIGBLOCKFILE_Zero(&page->writable_blocks);
     605        }
     606    }
     607
     608    if (page)
     609    {
     610        /* If the page is not already at the head of the list, move
     611         * it there. (Also moves pages from victim to main list.) */
     612        if (This->maplist != page)
     613        {
     614            if (This->victimhead == page) This->victimhead = page->next;
     615            if (This->victimtail == page) This->victimtail = page->prev;
     616
     617            BIGBLOCKFILE_UnlinkPage(page);
     618
     619            BIGBLOCKFILE_LinkHeadPage(&This->maplist, page);
     620        }
     621
     622        return page;
     623    }
     624
     625    page = BIGBLOCKFILE_CreatePage(This, page_index);
     626    if (!page) return NULL;
     627
     628    BIGBLOCKFILE_LinkHeadPage(&This->maplist, page);
     629
     630    return page;
     631}
     632
     633static BOOL BIGBLOCKFILE_MapPage(LPBIGBLOCKFILE This, MappedPage *page)
     634{
     635    DWORD lowoffset = PAGE_SIZE * page->page_index;
     636
     637    if (This->fileBased)
     638    {
     639        DWORD numBytesToMap;
     640        DWORD desired_access;
     641
     642        if (lowoffset + PAGE_SIZE > This->filesize.LowPart)
     643            numBytesToMap = This->filesize.LowPart - lowoffset;
     644        else
     645            numBytesToMap = PAGE_SIZE;
     646
     647        if (This->flProtect == PAGE_READONLY)
     648            desired_access = FILE_MAP_READ;
     649        else
     650            desired_access = FILE_MAP_WRITE;
     651
     652        page->lpBytes = MapViewOfFile(This->hfilemap, desired_access, 0,
     653                                      lowoffset, numBytesToMap);
     654    }
     655    else
     656    {
     657        page->lpBytes = (LPBYTE)This->pbytearray + lowoffset;
     658    }
     659
     660    TRACE("mapped page %lu to %p\n", page->page_index, page->lpBytes);
     661
     662    return page->lpBytes != NULL;
     663}
     664
     665static MappedPage *BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This,
     666                                           ULONG page_index)
     667{
     668    MappedPage *page;
     669
     670    page = (MappedPage *)HeapAlloc(GetProcessHeap(), 0, sizeof(MappedPage));
     671    if (page == NULL)
    804672      return NULL;
    805673
    806     newMappedPage->number = pagenum;
    807     newMappedPage->ref = 0;
    808 
    809     newMappedPage->next = This->maplisthead->next;
    810     This->maplisthead->next = newMappedPage;
    811 
    812     if (((pagenum + 1) * PAGE_SIZE) > This->filesize.LowPart)
    813       numBytesToMap = This->filesize.LowPart - (pagenum * PAGE_SIZE);
    814     else
    815       numBytesToMap = PAGE_SIZE;
    816 
    817     if (This->flProtect == PAGE_READONLY)
    818       desired_access = FILE_MAP_READ;
    819     else
    820       desired_access = FILE_MAP_WRITE;
    821 
    822     newMappedPage->lpBytes = MapViewOfFile(This->hfilemap,
    823                                            desired_access,
    824                                            hioffset,
    825                                            lowoffset,
    826                                            numBytesToMap);
    827   }
    828 
    829   /*
    830    * The page we want should now be at the head of the list.
    831    */
    832   assert(This->maplisthead->next != NULL);
    833 
    834   current = This->maplisthead->next;
    835   current->ref++;
    836 
    837   return current->lpBytes;
     674    page->page_index = page_index;
     675    page->refcnt = 1;
     676
     677    page->next = NULL;
     678    page->prev = NULL;
     679
     680    BIGBLOCKFILE_MapPage(This, page);
     681
     682    BIGBLOCKFILE_Zero(&page->readable_blocks);
     683    BIGBLOCKFILE_Zero(&page->writable_blocks);
     684
     685    return page;
     686}
     687
     688static void BIGBLOCKFILE_UnmapPage(LPBIGBLOCKFILE This, MappedPage *page)
     689{
     690    TRACE("%ld at %p\n", page->page_index, page->lpBytes);
     691    if (page->refcnt > 0)
     692        ERR("unmapping inuse page %p\n", page->lpBytes);
     693
     694    if (This->fileBased && page->lpBytes)
     695        UnmapViewOfFile(page->lpBytes);
     696
     697    page->lpBytes = NULL;
     698}
     699
     700static void BIGBLOCKFILE_DeletePage(LPBIGBLOCKFILE This, MappedPage *page)
     701{
     702    BIGBLOCKFILE_UnmapPage(This, page);
     703
     704    HeapFree(GetProcessHeap(), 0, page);
    838705}
    839706
     
    845712static void BIGBLOCKFILE_ReleaseMappedPage(
    846713  LPBIGBLOCKFILE This,
    847   DWORD          pagenum,
    848   DWORD          access)
    849 {
    850   MappedPage* previous = This->maplisthead;
    851   MappedPage* current;
    852 
    853   assert(This->maplisthead->next != NULL);
    854 
    855   current = previous->next;
    856 
    857   /* search for the page in the list
    858    */
    859   while (current != NULL)
    860   {
    861     if (current->number == pagenum)
    862     {
    863       /* decrement the reference count
    864        */
    865       current->ref--;
    866       return;
    867     }
    868     else
    869     {
    870       previous = current;
    871       current = current->next;
    872     }
    873   }
     714  MappedPage    *page)
     715{
     716    assert(This != NULL);
     717    assert(page != NULL);
     718
     719    /* If the page is no longer refenced, move it to the victim list.
     720     * If the victim list is too long, kick somebody off. */
     721    if (!InterlockedDecrement(&page->refcnt))
     722    {
     723        if (This->maplist == page) This->maplist = page->next;
     724
     725        BIGBLOCKFILE_UnlinkPage(page);
     726
     727        if (MAX_VICTIM_PAGES > 0)
     728        {
     729            if (This->num_victim_pages >= MAX_VICTIM_PAGES)
     730            {
     731                MappedPage *victim = This->victimtail;
     732                if (victim)
     733                {
     734                    This->victimtail = victim->prev;
     735                    if (This->victimhead == victim)
     736                        This->victimhead = victim->next;
     737
     738                    BIGBLOCKFILE_UnlinkPage(victim);
     739                    BIGBLOCKFILE_DeletePage(This, victim);
     740                }
     741            }
     742            else This->num_victim_pages++;
     743
     744            BIGBLOCKFILE_LinkHeadPage(&This->victimhead, page);
     745            if (This->victimtail == NULL) This->victimtail = page;
     746        }
     747        else
     748            BIGBLOCKFILE_DeletePage(This, page);
     749    }
     750}
     751
     752static void BIGBLOCKFILE_DeleteList(LPBIGBLOCKFILE This, MappedPage *list)
     753{
     754    while (list != NULL)
     755    {
     756        MappedPage *next = list->next;
     757
     758        BIGBLOCKFILE_DeletePage(This, list);
     759
     760        list = next;
     761    }
    874762}
    875763
     
    883771  LPBIGBLOCKFILE This)
    884772{
    885   MappedPage * current = This->maplisthead->next;
    886 
    887   while (current != NULL)
    888   {
    889     /* Unmap views.
    890      */
    891     UnmapViewOfFile(current->lpBytes);
    892 
    893     /* Free the nodes.
    894      */
    895     This->maplisthead->next = current->next;
    896     HeapFree(GetProcessHeap(), 0, current);
    897 
    898     current = This->maplisthead->next;
    899   }
     773    BIGBLOCKFILE_DeleteList(This, This->maplist);
     774    BIGBLOCKFILE_DeleteList(This, This->victimhead);
     775
     776    This->maplist = NULL;
     777    This->victimhead = NULL;
     778    This->victimtail = NULL;
     779    This->num_victim_pages = 0;
     780}
     781
     782static void BIGBLOCKFILE_UnmapList(LPBIGBLOCKFILE This, MappedPage *list)
     783{
     784    for (; list != NULL; list = list->next)
     785    {
     786        BIGBLOCKFILE_UnmapPage(This, list);
     787    }
     788}
     789
     790static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This)
     791{
     792    BIGBLOCKFILE_UnmapList(This, This->maplist);
     793    BIGBLOCKFILE_UnmapList(This, This->victimhead);
     794}
     795
     796static void BIGBLOCKFILE_RemapList(LPBIGBLOCKFILE This, MappedPage *list)
     797{
     798    while (list != NULL)
     799    {
     800        MappedPage *next = list->next;
     801
     802        if (list->page_index * PAGE_SIZE > This->filesize.LowPart)
     803        {
     804            TRACE("discarding %lu\n", list->page_index);
     805
     806            /* page is entirely outside of the file, delete it */
     807            BIGBLOCKFILE_UnlinkPage(list);
     808            BIGBLOCKFILE_DeletePage(This, list);
     809        }
     810        else
     811        {
     812            /* otherwise, remap it */
     813            BIGBLOCKFILE_MapPage(This, list);
     814        }
     815
     816        list = next;
     817    }
     818}
     819
     820static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This)
     821{
     822    BIGBLOCKFILE_RemapList(This, This->maplist);
     823    BIGBLOCKFILE_RemapList(This, This->victimhead);
    900824}
    901825
     
    908832static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags)
    909833{
    910   DWORD flProtect        = PAGE_READONLY;
    911   BOOL bSTGM_WRITE     = ((openFlags & STGM_WRITE) == STGM_WRITE);
    912   BOOL bSTGM_READWRITE = ((openFlags & STGM_READWRITE) == STGM_READWRITE);
    913   BOOL bSTGM_READ      = ! (bSTGM_WRITE || bSTGM_READWRITE);
    914 
    915   if (bSTGM_READ)
    916     flProtect = PAGE_READONLY;
    917 
    918   if ((bSTGM_WRITE) || (bSTGM_READWRITE))
    919     flProtect = PAGE_READWRITE;
    920 
    921   return flProtect;
    922 }
    923 
    924  
     834    if (openFlags & (STGM_WRITE | STGM_READWRITE))
     835        return PAGE_READWRITE;
     836    else
     837        return PAGE_READONLY;
     838}
  • trunk/src/ole32/stg_stream.cpp

    r1033 r3167  
    1 /* $Id: stg_stream.cpp,v 1.1 1999-09-24 21:49:44 davidr Exp $ */
     1/* $Id: stg_stream.cpp,v 1.2 2000-03-19 15:33:07 davidr Exp $ */
    22/*
    33 * Compound Storage (32 bit version)
     
    6565StgStreamImpl* StgStreamImpl_Construct(
    6666                StorageBaseImpl* parentStorage,
     67                DWORD            grfMode,
    6768                ULONG              ownerProperty)
    6869{
     
    7677     * Set-up the virtual function table and reference count.
    7778     */
    78     newStream->lpvtbl = &StgStreamImpl_Vtbl;
     79    ICOM_VTBL(newStream) = &StgStreamImpl_Vtbl;
    7980    newStream->ref    = 0;
    8081   
     
    8687    IStorage_AddRef((IStorage*)newStream->parentStorage);
    8788   
     89    newStream->grfMode = grfMode;   
    8890    newStream->ownerProperty = ownerProperty;
    8991   
     
    431433  *pcbWritten = 0;
    432434
     435  /*
     436   * Do we have permission to write to this stream?
     437   */
     438  if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
     439    return STG_E_ACCESSDENIED;
     440
    433441  if (cb == 0)
    434442  {
     
    533541  }
    534542
    535   /*
    536    * We don't support files with offsets of 64 bits.
    537    */
    538   assert(dlibMove.HighPart == 0);
    539 
    540   /*
    541    * Check if we end-up before the beginning of the file. That should trigger an
    542    * error.
    543    */
    544   if ( (dlibMove.LowPart<0) && (plibNewPosition->LowPart < (ULONG)(-dlibMove.LowPart)) )
    545   {
     543#if SIZEOF_LONG_LONG >= 8
     544  plibNewPosition->QuadPart += dlibMove.QuadPart;
     545#else
     546  /*
     547   * do some multiword arithmetic:
     548   *    treat HighPart as a signed value
     549   *    treat LowPart as unsigned
     550   *  NOTE: this stuff is two's complement specific!
     551   */
     552  if (dlibMove.HighPart < 0) { /* dlibMove is < 0 */
     553      /* calculate the absolute value of dlibMove ... */
     554      dlibMove.HighPart = -dlibMove.HighPart;
     555      dlibMove.LowPart ^= -1;
     556      /* ... and subtract with carry */
     557      if (dlibMove.LowPart > plibNewPosition->LowPart) {
     558          /* carry needed, This accounts for any underflows at [1]*/
     559          plibNewPosition->HighPart -= 1;
     560      }
     561      plibNewPosition->LowPart -= dlibMove.LowPart; /* [1] */
     562      plibNewPosition->HighPart -= dlibMove.HighPart;
     563  } else {
     564      /* add directly */
     565      int initialLowPart = plibNewPosition->LowPart;
     566      plibNewPosition->LowPart += dlibMove.LowPart;
     567      if((plibNewPosition->LowPart < initialLowPart) ||
     568         (plibNewPosition->LowPart < dlibMove.LowPart)) {
     569          /* LowPart has rolled over => add the carry digit to HighPart */
     570          plibNewPosition->HighPart++;
     571      }
     572      plibNewPosition->HighPart += dlibMove.HighPart;
     573  }
     574  /*
     575   * Check if we end-up before the beginning of the file. That should
     576   * trigger an error.
     577   */
     578  if (plibNewPosition->HighPart < 0) {
     579      return STG_E_INVALIDPOINTER;
     580  }
     581
    546582    /*
    547      * I don't know what error to send there.
     583   * We currently don't support files with offsets of >32 bits. 
     584   * Note that we have checked for a negative offset already
    548585     */
    549     return E_FAIL;
    550   }
    551 
    552   /*
    553    * Move the actual file pointer
    554    * If the file pointer ends-up after the end of the stream, the next Write operation will
    555    * make the file larger. This is how it is documented.
    556    */
    557   plibNewPosition->LowPart += dlibMove.LowPart;
     586  assert(plibNewPosition->HighPart <= 0);
     587
     588#endif
     589
     590  /*
     591   * tell the caller what we calculated
     592   */
    558593  This->currentPosition = *plibNewPosition;
    559594 
     
    587622    return STG_E_INVALIDFUNCTION;
    588623 
     624  /*
     625   * Do we have permission?
     626   */
     627  if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE)))
     628    return STG_E_ACCESSDENIED;
     629
    589630  if (This->streamSize.LowPart == libNewSize.LowPart)
    590631    return S_OK;
     
    828869                                     grfStatFlag);
    829870   
     871    pstatstg->grfMode = This->grfMode;
     872
    830873    return S_OK;
    831874  }
  • 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;
  • trunk/src/ole32/storage.h

    r1033 r3167  
    1 /* $Id: storage.h,v 1.1 1999-09-24 21:49:45 davidr Exp $ */
     1/* $Id: storage.h,v 1.2 2000-03-19 15:35:15 davidr Exp $ */
    22/*
    33 * Compound Storage (32 bit version)
     
    8989static const BYTE STORAGE_magic[8]    ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1};
    9090static const BYTE STORAGE_oldmagic[8] ={0xd0,0xcf,0x11,0xe0,0x0e,0x11,0xfc,0x0d};
    91 static const BYTE STORAGE_notmagic[8]={0x0e,0x11,0xfc,0x0d,0xd0,0xcf,0x11,0xe0};
    9291
    9392/*
     
    138137typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE;
    139138typedef struct MappedPage   MappedPage,*LPMAPPEDPAGE;
    140 typedef struct BigBlock     BigBlock,*LPBIGBLOCK;
    141139
    142140struct BigBlockFile
     
    148146  HANDLE hfilemap;
    149147  DWORD flProtect;
    150   MappedPage *maplisthead;
     148  MappedPage *maplist;
     149  MappedPage *victimhead, *victimtail;
     150  ULONG num_victim_pages;
    151151  ILockBytes *pLkbyt;
    152152  HGLOBAL hbytearray;
    153153  LPVOID pbytearray;
    154   BigBlock *headblock;
    155154};
    156155
     
    182181struct StorageBaseImpl
    183182{
    184   ICOM_VTABLE(IStorage)*  lpvtbl;   /* Needs to be the first item in the stuct
    185                                        * since we want to cast this in a Storage32 pointer */
     183  ICOM_VFIELD(IStorage);   /* Needs to be the first item in the stuct
     184                            * since we want to cast this in a Storage32 pointer */
    186185
    187186  /*
     
    276275struct StorageImpl
    277276{
    278   ICOM_VTABLE(IStorage) *lpvtbl;   /* Needs to be the first item in the stuct
     277  ICOM_VFIELD(IStorage);   /* Needs to be the first item in the stuct
    279278                                      * since we want to cast this in a Storage32 pointer */
    280279
     
    323322   */
    324323  BigBlockFile* bigBlockFile;
     324
     325  /*****************************************************************************************/
     326  /* warning: this is a temp fix for bugs related to save file to mounted network drive    */
     327  /* TBD: these lines should be removed when we will get the final fix                     */
     328  /*****************************************************************************************/
     329  WCHAR* srcDestFiles[2];
     330  /*****************************************************************************************/
    325331};
    326332
     
    378384
    379385HRESULT StorageImpl_Construct(
    380             StorageImpl* This,
    381             HANDLE       hFile,
    382       ILockBytes*  pLkbyt,
    383             DWORD        openFlags,
    384       BOOL         fileBased);
     386            StorageImpl* This,
     387            HANDLE       hFile,
     388            ILockBytes*  pLkbyt,
     389            DWORD        openFlags,
     390            BOOL         fileBased,
     391            BOOL         fileCreate);
    385392
    386393BOOL StorageImpl_ReadBigBlock(
     
    465472struct StorageInternalImpl
    466473{
    467   ICOM_VTABLE(IStorage) *lpvtbl;        /* Needs to be the first item in the stuct
    468                                         * since we want to cast this in a Storage32 pointer */
     474  ICOM_VFIELD(IStorage);        /* Needs to be the first item in the stuct
     475                                * since we want to cast this in a Storage32 pointer */
    469476
    470477  /*
     
    509516struct IEnumSTATSTGImpl
    510517{
    511   ICOM_VTABLE(IEnumSTATSTG) *lpvtbl;    /* Needs to be the first item in the stuct
     518  ICOM_VFIELD(IEnumSTATSTG);    /* Needs to be the first item in the stuct
    512519                                         * since we want to cast this in a IEnumSTATSTG pointer */
    513520 
     
    594601struct StgStreamImpl
    595602{
    596   ICOM_VTABLE(IStream) *lpvtbl;  /* Needs to be the first item in the stuct
     603  ICOM_VFIELD(IStream);  /* Needs to be the first item in the stuct
    597604                                    * since we want to cast this in a IStream pointer */
    598605 
     
    606613   */
    607614  StorageBaseImpl* parentStorage;
     615
     616  /*
     617   * Access mode of this stream.
     618   */
     619  DWORD grfMode;
    608620
    609621  /*
     
    637649StgStreamImpl* StgStreamImpl_Construct(
    638650                StorageBaseImpl* parentStorage,
    639                 ULONG              ownerProperty);
     651    DWORD            grfMode,
     652    ULONG            ownerProperty);
    640653
    641654void StgStreamImpl_Destroy(
     
    723736void StorageUtl_ReadDWord(void* buffer, ULONG offset, DWORD* value);
    724737void StorageUtl_WriteDWord(void* buffer, ULONG offset, DWORD value);
     738void StorageUtl_ReadDWords(void *buffer, ULONG offset, DWORD *values,
     739                           ULONG len);
    725740void StorageUtl_ReadGUID(void* buffer, ULONG offset, GUID* value);
    726741void StorageUtl_WriteGUID(void* buffer, ULONG offset, GUID* value);
     
    744759  ULONG        tailIndex;
    745760  ULONG        numBlocks;
     761  BOOL         lazyInitComplete;
    746762};
    747763
  • trunk/src/ole32/stubs.cpp

    r1957 r3167  
    1 /* $Id: stubs.cpp,v 1.10 1999-12-03 11:57:20 sandervl Exp $ */
     1/* $Id: stubs.cpp,v 1.11 2000-03-19 15:33:09 davidr Exp $ */
    22/*
    33 * Win32 COM/OLE stubs for OS/2
     
    323323//*******************************************************************************
    324324//*******************************************************************************
    325 HRESULT WIN32API OleConvertIStorageToOLESTREAM(IStorage *pStg, LPOLESTREAM lpolestream)
    326 {
    327     dprintf(("OLE32: OleConvertIStorageToOLESTREAM - stub"));
    328     return E_INVALIDARG;
    329 }
    330 //*******************************************************************************
    331 //*******************************************************************************
    332325HRESULT WIN32API OleConvertIStorageToOLESTREAMEx(LPSTORAGE      pStg,
    333326                                                 CLIPFORMAT     ctFormat,
     
    339332{
    340333    dprintf(("OLE32: OleConvertIStorageToOLESTREAMEx - stub"));
    341     return(E_INVALIDARG);
    342 }
    343 //*******************************************************************************
    344 //*******************************************************************************
    345 HRESULT WIN32API OleConvertOLESTREAMToIStorage(LPOLESTREAM lpolestream,
    346                                                   IStorage *pstg,
    347                                                   const DVTARGETDEVICE *ptd)
    348 {
    349     dprintf(("OLE32: OleConvertOLESTREAMToIStorage - stub"));
    350334    return(E_INVALIDARG);
    351335}
Note: See TracChangeset for help on using the changeset viewer.