- Timestamp:
- Mar 19, 2000, 4:35:32 PM (25 years ago)
- 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:42davidr Exp $ */1 /* $Id: clsid.cpp,v 1.10 2000-03-19 15:33:05 davidr Exp $ */ 2 2 /* 3 3 * … … 24 24 25 25 // ---------------------------------------------------------------------- 26 // CLSIDFromProgID16() 27 // ---------------------------------------------------------------------- 28 HRESULT 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 // ---------------------------------------------------------------------- 26 59 // CLSIDFromProgID() 27 60 // ---------------------------------------------------------------------- … … 72 105 // ---------------------------------------------------------------------- 73 106 74 // missing prototype75 LPWSTR WIN32API HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str );76 77 107 HRESULT WIN32API CLSIDFromStringA( 78 108 LPCSTR lpsz, // [in] - ASCII string CLSID 79 109 LPCLSID pclsid) // [out] - Binary CLSID 80 110 { 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 // ---------------------------------------------------------------------- 118 HRESULT 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 } 93 191 94 192 // ---------------------------------------------------------------------- … … 103 201 oStringA tClsId(lpsz); 104 202 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); 173 204 } 174 205 -
trunk/src/ole32/datacache.cpp
r1033 r3167 1 /* $Id: datacache.cpp,v 1. 1 1999-09-24 21:49:42davidr Exp $ */1 /* $Id: datacache.cpp,v 1.2 2000-03-19 15:33:05 davidr Exp $ */ 2 2 /* 3 3 * OLE 2 Data cache … … 1315 1315 TRACE("(%p, %p)\n", iface, pStgNew); 1316 1316 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 } 1326 1329 1327 1330 return S_OK; … … 1443 1446 return E_INVALIDARG; 1444 1447 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 1445 1456 /* 1446 1457 * 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:43davidr Exp $ */1 /* $Id: filemoniker.cpp,v 1.2 2000-03-19 15:33:06 davidr Exp $ */ 2 2 /* 3 3 * FileMonikers functions. … … 15 15 #include "debugtools.h" 16 16 #include "filemoniker.h" 17 #include "winnls.h" 17 18 18 19 DEFAULT_DEBUG_CHANNEL(ole) … … 212 213 { 213 214 HRESULT res; 214 CHAR* filePathA ;215 WCHAR* filePathW ;215 CHAR* filePathA=NULL; 216 WCHAR* filePathW=NULL; 216 217 ULONG bread; 217 218 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]; 220 223 ICOM_THIS(FileMonikerImpl,iface); 221 224 … … 230 233 231 234 /* read filePath string length (plus one) */ 232 res=IStream_Read(pStm,& length,sizeof(DWORD),&bread);235 res=IStream_Read(pStm,&dwAnsiLength,sizeof(DWORD),&bread); 233 236 if (bread != sizeof(DWORD)) 234 237 return E_FAIL; 235 238 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 { 240 257 return E_FAIL; 241 258 } 242 259 /* 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) 245 262 return E_FAIL; 246 247 length--;248 263 249 264 for(i=0;i<10;i++){ … … 253 268 } 254 269 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)) 264 272 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 } 282 302 283 303 if (This->filePathName!=NULL) … … 286 306 This->filePathName=filePathW; 287 307 288 HeapFree(GetProcessHeap(),0,filePathA); 308 if(filePathA != NULL) 309 { 310 HeapFree(GetProcessHeap(),0,filePathA); 311 } 289 312 290 313 return res; … … 313 336 HRESULT res; 314 337 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 */ 319 342 WORD constant2 = 0x3; /* FileMoniker_Save function in a windows program system */ 343 WORD wUnicodeLen=0xFFFF; 344 DWORD dwOffsetToEndUnicodeStr=0; 320 345 321 346 WORD zero=0; 322 347 DWORD doubleLenHex; 323 DWORD doubleLenDec;324 348 int i=0; 349 WCHAR temp = 0; 350 325 351 326 352 TRACE("(%p,%p,%d)\n",iface,pStm,fClearDirty); … … 328 354 if (pStm==NULL) 329 355 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 } 330 371 331 372 /* 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 */ 332 375 res=IStream_Write(pStm,&zero,sizeof(WORD),NULL); 333 376 … … 336 379 337 380 /* write filePath string type A */ 338 filePathA=(CHAR *)HeapAlloc(GetProcessHeap(),0,len);339 lstrcpyWtoA(filePathA,filePathW);340 381 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); 345 388 346 389 len--; 347 /* write 10 times a DWORD seted to 0 : constants */390 /* write 10 times a WORD seted to 0 : constants */ 348 391 for(i=0;i<10;i++) 349 392 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 } 373 417 return res; 374 418 } … … 386 430 TRACE("(%p,%p)\n",iface,pcbSize); 387 431 388 if (pcbSize !=NULL)432 if (pcbSize==NULL) 389 433 return E_POINTER; 390 434 … … 398 442 sizeof(DWORD); /* size of the unicode filePath: "\0" not included */ 399 443 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 } 406 451 407 452 pcbSize->LowPart=sizeMAx; … … 411 456 } 412 457 458 void 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 } 413 519 /****************************************************************************** 414 520 * FileMoniker_Construct (local function) … … 475 581 } 476 582 583 FileMonikerImpl_CheckFileFormat(This, This->filePathName); 477 584 for(i=0; tabStr[i]!=NULL;i++) 478 585 CoTaskMemFree(tabStr[i]); … … 1048 1155 { 1049 1156 WCHAR bSlash[] = {'\\',0}; 1050 WCHAR word[ 100];1157 WCHAR word[MAX_PATH]; 1051 1158 int i=0,j,tabIndex=0; 1052 1159 LPOLESTR *strgtable ; -
trunk/src/ole32/filemoniker.h
r1033 r3167 1 /* $Id: filemoniker.h,v 1. 1 1999-09-24 21:49:43davidr Exp $ */1 /* $Id: filemoniker.h,v 1.2 2000-03-19 15:35:14 davidr Exp $ */ 2 2 /* 3 3 * … … 22 22 23 23 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*/ 24 27 25 28 } FileMonikerImpl; … … 29 32 HRESULT WINAPI FileMonikerImpl_Destroy(FileMonikerImpl* iface); 30 33 int WINAPI FileMonikerImpl_DecomposePath(LPOLESTR str, LPOLESTR** tabStr); 34 void WINAPI FileMonikerImpl_CheckFileFormat(FileMonikerImpl* iface, LPCOLESTR lpszPathName); 31 35 32 36 #endif /* FILEMONIKER_INCLUDED */ -
trunk/src/ole32/hglobalstream.cpp
r1033 r3167 1 /* $Id: hglobalstream.cpp,v 1. 1 1999-09-24 21:49:43davidr Exp $ */1 /* $Id: hglobalstream.cpp,v 1.2 2000-03-19 15:33:06 davidr Exp $ */ 2 2 /* 3 3 * HGLOBAL Stream implementation functions. … … 26 26 struct HGLOBALStreamImpl 27 27 { 28 ICOM_V TABLE(IStream) *lpvtbl; /* Needs to be the first item in the stuct28 ICOM_VFIELD(IStream); /* Needs to be the first item in the stuct 29 29 * since we want to cast this in a IStream pointer */ 30 30 … … 200 200 * Verify that the stream object was created with CreateStreamOnHGlobal. 201 201 */ 202 if ( pStream->lpvtbl== &HGLOBALStreamImpl_Vtbl)202 if (ICOM_VTBL(pStream) == &HGLOBALStreamImpl_Vtbl) 203 203 *phglobal = pStream->supportHandle; 204 204 else … … 236 236 * Set-up the virtual function table and reference count. 237 237 */ 238 newStream->lpvtbl= &HGLOBALStreamImpl_Vtbl;238 ICOM_VTBL(newStream) = &HGLOBALStreamImpl_Vtbl; 239 239 newStream->ref = 0; 240 240 -
trunk/src/ole32/moniker.cpp
r2764 r3167 1 /* $Id: moniker.cpp,v 1. 4 2000-02-12 11:51:03davidr Exp $ */1 /* $Id: moniker.cpp,v 1.5 2000-03-19 15:33:06 davidr Exp $ */ 2 2 /* 3 3 * … … 279 279 280 280 return res; 281 return S_OK;282 281 } 283 282 -
trunk/src/ole32/ole32.def
r2000 r3167 168 168 WriteOleStg = _WriteOleStg@0 @161 169 169 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 173 174 174 175 ; … … 177 178 WINE_StringFromCLSID = _WINE_StringFromCLSID@8 @1000 178 179 CLSIDFromStringA = _CLSIDFromStringA@8 @1001 180 CLSIDFromString16 = _CLSIDFromString16@8 @1002 ; COMPOBJ.19 179 181 -
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 $ */ 2 2 /* 3 3 * … … 39 39 40 40 #include "objbase.h" 41 #include "docobj.h" /* for the IID_StdOleLink */ 41 42 42 43 #include "wine/obj_inplace.h" -
trunk/src/ole32/oleobj.cpp
r1033 r3167 1 /* $Id: oleobj.cpp,v 1. 1 1999-09-24 21:49:44davidr Exp $ */1 /* $Id: oleobj.cpp,v 1.2 2000-03-19 15:33:06 davidr Exp $ */ 2 2 /* 3 3 * OLE2 COM objects … … 24 24 typedef struct OleAdviseHolderImpl 25 25 { 26 ICOM_V TABLE(IOleAdviseHolder)* lpvtbl;26 ICOM_VFIELD(IOleAdviseHolder); 27 27 28 28 DWORD ref; … … 75 75 sizeof(OleAdviseHolderImpl)); 76 76 77 lpoah->lpvtbl= &oahvt;77 ICOM_VTBL(lpoah) = &oahvt; 78 78 lpoah->ref = 1; 79 79 lpoah->maxSinks = 10; 80 lpoah->arrayOfSinks = (IAdviseSink 80 lpoah->arrayOfSinks = (IAdviseSink**)HeapAlloc(GetProcessHeap(), 81 81 0, 82 82 lpoah->maxSinks * sizeof(IAdviseSink*)); … … 226 226 This->maxSinks+=10; 227 227 228 This->arrayOfSinks = (IAdviseSink 228 This->arrayOfSinks = (IAdviseSink**)HeapReAlloc(GetProcessHeap(), 229 229 0, 230 230 This->arrayOfSinks, … … 348 348 typedef struct DataAdviseHolder 349 349 { 350 ICOM_V TABLE(IDataAdviseHolder)* lpvtbl;350 ICOM_VFIELD(IDataAdviseHolder); 351 351 352 352 DWORD ref; … … 411 411 sizeof(DataAdviseHolder)); 412 412 413 newHolder->lpvtbl= &DataAdviseHolderImpl_VTable;413 ICOM_VTBL(newHolder) = &DataAdviseHolderImpl_VTable; 414 414 newHolder->ref = 1; 415 415 -
trunk/src/ole32/stg_bigblockfile.cpp
r1033 r3167 1 /* $Id: stg_bigblockfile.cpp,v 1. 1 1999-09-24 21:49:44davidr Exp $ */1 /* $Id: stg_bigblockfile.cpp,v 1.2 2000-03-19 15:33:07 davidr Exp $ */ 2 2 /* 3 3 * BigBlockFile 4 4 * 5 * 20/9/99 6 * 7 * Copyright 1999 David J. Raison 5 * 12/03/00 8 6 * 9 7 * Direct port of Wine Implementation … … 31 29 #include <assert.h> 32 30 33 DEFAULT_DEBUG_CHANNEL(storage)31 #define CHAR_BIT 8 // (From EMX limits.h) 34 32 35 33 /*********************************************************** … … 38 36 */ 39 37 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. */ 49 typedef struct 50 { 51 unsigned int bits[BLOCKS_PER_PAGE / (CHAR_BIT * sizeof(unsigned int))]; 52 } BlockBits; 51 53 52 54 /*** … … 54 56 * from the file and their position in memory. It is 55 57 * 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.) 56 62 */ 57 63 struct MappedPage 58 64 { 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; 63 74 }; 64 65 #define PAGE_SIZE 13107266 #define BLOCKS_PER_PAGE 25667 68 #define NUMBER_OF_MAPPED_PAGES 10069 75 70 76 /*********************************************************** … … 72 78 */ 73 79 static void* BIGBLOCKFILE_GetMappedView(LPBIGBLOCKFILE This, 74 DWORD pagenum, 75 DWORD desired_access); 80 DWORD page_index); 76 81 static void BIGBLOCKFILE_ReleaseMappedPage(LPBIGBLOCKFILE This, 77 DWORD pagenum, 78 DWORD access); 82 MappedPage *page); 79 83 static void BIGBLOCKFILE_FreeAllMappedPages(LPBIGBLOCKFILE This); 84 static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This); 85 static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This); 80 86 static void* BIGBLOCKFILE_GetBigBlockPointer(LPBIGBLOCKFILE This, 81 87 ULONG index, 82 88 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); 89 static MappedPage* BIGBLOCKFILE_GetPageFromPointer(LPBIGBLOCKFILE This, 90 void* pBlock); 91 static MappedPage* BIGBLOCKFILE_CreatePage(LPBIGBLOCKFILE This, 92 ULONG page_index); 90 93 static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags); 91 94 static BOOL BIGBLOCKFILE_FileInit(LPBIGBLOCKFILE This, HANDLE hFile); 92 95 static 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 */ 104 static 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 113 static 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 121 static 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 129 static inline void BIGBLOCKFILE_Zero(BlockBits *bb) 130 { 131 memset(bb->bits, 0, sizeof(bb->bits)); 132 } 94 133 95 134 /****************************************************************************** … … 97 136 * 98 137 * Construct a big block file. Create the file mapping object. 99 * Create the read only mapped pages list, the writ eable mapped page list138 * Create the read only mapped pages list, the writable mapped page list 100 139 * and the blocks in use list. 101 140 */ … … 120 159 This->blocksize = blocksize; 121 160 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; 125 165 126 166 if (This->fileBased) … … 174 214 } 175 215 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); 190 222 191 223 return TRUE; … … 201 233 This->hfile = 0; 202 234 This->hfilemap = NULL; 203 This->maplisthead = NULL;204 235 205 236 /* … … 225 256 This->pbytearray = GlobalLock(This->hbytearray); 226 257 258 TRACE("mem on %p len %lu\n", This->pbytearray, This->filesize.LowPart); 259 227 260 return TRUE; 228 261 } … … 236 269 LPBIGBLOCKFILE This) 237 270 { 271 BIGBLOCKFILE_FreeAllMappedPages(This); 272 238 273 if (This->fileBased) 239 274 { 240 /* unmap all views and destroy the mapped page list241 */242 BIGBLOCKFILE_FreeAllMappedPages(This);243 HeapFree(GetProcessHeap(), 0, This->maplisthead);244 245 /* close all open handles246 */247 275 CloseHandle(This->hfilemap); 248 276 CloseHandle(This->hfile); … … 253 281 ILockBytes_Release(This->pLkbyt); 254 282 } 255 256 /*257 * Destroy the blocks list.258 */259 BIGBLOCKFILE_RemoveAllBlocks(This);260 283 261 284 /* destroy this … … 287 310 * 288 311 */ 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 } 293 319 294 320 return BIGBLOCKFILE_GetBigBlockPointer(This, index, FILE_MAP_READ); … … 335 361 void BIGBLOCKFILE_ReleaseBigBlock(LPBIGBLOCKFILE This, void *pBlock) 336 362 { 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); 368 374 } 369 375 … … 379 385 return; 380 386 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 381 393 if (This->fileBased) 382 394 { 383 /* 384 * unmap all views, must be done before call to SetEndFile 385 */ 386 BIGBLOCKFILE_FreeAllMappedPages(This); 387 395 char buf[10]; 396 388 397 /* 389 398 * close file-mapping object, must be done before call to SetEndFile … … 391 400 CloseHandle(This->hfilemap); 392 401 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 */ 393 421 394 422 /* … … 423 451 } 424 452 425 /*426 * empty the blocks list.427 */428 BIGBLOCKFILE_RemoveAllBlocks(This);429 430 453 This->filesize.LowPart = newSize.LowPart; 431 454 This->filesize.HighPart = newSize.HighPart; 455 456 BIGBLOCKFILE_RemapAllMappedPages(This); 432 457 } 433 458 … … 444 469 445 470 /****************************************************************************** 471 * BIGBLOCKFILE_AccessCheck [PRIVATE] 472 * 473 * block_index is the index within the page. 474 */ 475 static 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 /****************************************************************************** 446 501 * BIGBLOCKFILE_GetBigBlockPointer [PRIVATE] 447 502 * … … 450 505 static void* BIGBLOCKFILE_GetBigBlockPointer( 451 506 LPBIGBLOCKFILE This, 452 ULONG index,507 ULONG block_index, 453 508 DWORD desired_access) 454 509 { 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 */ 533 static 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 */ 553 static 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 569 static 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 575 static 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; 727 581 } 728 582 … … 735 589 static void * BIGBLOCKFILE_GetMappedView( 736 590 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 633 static 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 665 static 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) 804 672 return NULL; 805 673 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 688 static 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 700 static void BIGBLOCKFILE_DeletePage(LPBIGBLOCKFILE This, MappedPage *page) 701 { 702 BIGBLOCKFILE_UnmapPage(This, page); 703 704 HeapFree(GetProcessHeap(), 0, page); 838 705 } 839 706 … … 845 712 static void BIGBLOCKFILE_ReleaseMappedPage( 846 713 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 752 static 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 } 874 762 } 875 763 … … 883 771 LPBIGBLOCKFILE This) 884 772 { 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 782 static void BIGBLOCKFILE_UnmapList(LPBIGBLOCKFILE This, MappedPage *list) 783 { 784 for (; list != NULL; list = list->next) 785 { 786 BIGBLOCKFILE_UnmapPage(This, list); 787 } 788 } 789 790 static void BIGBLOCKFILE_UnmapAllMappedPages(LPBIGBLOCKFILE This) 791 { 792 BIGBLOCKFILE_UnmapList(This, This->maplist); 793 BIGBLOCKFILE_UnmapList(This, This->victimhead); 794 } 795 796 static 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 820 static void BIGBLOCKFILE_RemapAllMappedPages(LPBIGBLOCKFILE This) 821 { 822 BIGBLOCKFILE_RemapList(This, This->maplist); 823 BIGBLOCKFILE_RemapList(This, This->victimhead); 900 824 } 901 825 … … 908 832 static DWORD BIGBLOCKFILE_GetProtectMode(DWORD openFlags) 909 833 { 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:44davidr Exp $ */1 /* $Id: stg_stream.cpp,v 1.2 2000-03-19 15:33:07 davidr Exp $ */ 2 2 /* 3 3 * Compound Storage (32 bit version) … … 65 65 StgStreamImpl* StgStreamImpl_Construct( 66 66 StorageBaseImpl* parentStorage, 67 DWORD grfMode, 67 68 ULONG ownerProperty) 68 69 { … … 76 77 * Set-up the virtual function table and reference count. 77 78 */ 78 newStream->lpvtbl= &StgStreamImpl_Vtbl;79 ICOM_VTBL(newStream) = &StgStreamImpl_Vtbl; 79 80 newStream->ref = 0; 80 81 … … 86 87 IStorage_AddRef((IStorage*)newStream->parentStorage); 87 88 89 newStream->grfMode = grfMode; 88 90 newStream->ownerProperty = ownerProperty; 89 91 … … 431 433 *pcbWritten = 0; 432 434 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 433 441 if (cb == 0) 434 442 { … … 533 541 } 534 542 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 546 582 /* 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 548 585 */ 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 */ 558 593 This->currentPosition = *plibNewPosition; 559 594 … … 587 622 return STG_E_INVALIDFUNCTION; 588 623 624 /* 625 * Do we have permission? 626 */ 627 if (!(This->grfMode & (STGM_WRITE | STGM_READWRITE))) 628 return STG_E_ACCESSDENIED; 629 589 630 if (This->streamSize.LowPart == libNewSize.LowPart) 590 631 return S_OK; … … 828 869 grfStatFlag); 829 870 871 pstatstg->grfMode = This->grfMode; 872 830 873 return S_OK; 831 874 } -
trunk/src/ole32/storage.cpp
r1033 r3167 1 /* $Id: storage.cpp,v 1. 1 1999-09-24 21:49:44davidr Exp $ */1 /* $Id: storage.cpp,v 1.2 2000-03-19 15:33:08 davidr Exp $ */ 2 2 /* 3 3 * Compound Storage functions. … … 26 26 #include "storage.h" 27 27 28 #include "winnls.h" 29 #include "winreg.h" 30 #include "wine/wingdi16.h" 31 28 32 DEFAULT_DEBUG_CHANNEL(storage) 29 33 30 34 #define FILE_BEGIN 0 31 35 36 37 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 38 #define OLESTREAM_ID 0x501 39 #define OLESTREAM_MAX_STR_LEN 255 40 41 #define OLECONVERT_NUM_OLE10STREAMS 2 42 43 #define OLECONVERT_LINK_TYPE 1L 44 #define OLECONVERT_EMBEDDED_TYPE 2L 45 #define OLECONVERT_PRESENTATION_DATA_TYPE 5L 46 32 47 static const char rootPropertyName[] = "Root Entry"; 48 49 50 /* OLESTREAM memory structure to use for Get and Put Routines */ 51 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 52 typedef struct 53 { 54 DWORD dwOleID; 55 DWORD dwObjectTypeID; 56 DWORD dwOleTypeNameLength; 57 CHAR strOleTypeName[OLESTREAM_MAX_STR_LEN]; 58 DWORD dwLinkFileNameLength; 59 BYTE *strLinkFileName; 60 DWORD dwLinkExtraInfoLength; 61 BYTE *pLinkExtraInfo; 62 DWORD dwMetaFileWidth; 63 DWORD dwMetaFileHeight; 64 DWORD dwDataLength; 65 BYTE *pData; 66 }OLECONVERT_OLESTREAM_DATA; 67 68 /* CompObj Stream structure */ 69 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 70 typedef struct 71 { 72 BYTE byUnknown1[12]; 73 CLSID clsid; 74 DWORD dwCLSIDNameLength; 75 CHAR strCLSIDName[OLESTREAM_MAX_STR_LEN]; 76 DWORD dwOleTypeNameLength; 77 CHAR strOleTypeName[OLESTREAM_MAX_STR_LEN]; 78 DWORD dwProgIDNameLength; 79 CHAR strProgIDName[OLESTREAM_MAX_STR_LEN]; 80 BYTE byUnknown2[16]; 81 }OLECONVERT_ISTORAGE_COMPOBJ; 82 83 84 /* Ole Presention Stream structure */ 85 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 86 typedef struct 87 { 88 BYTE byUnknown1[28]; 89 DWORD dwExtentX; 90 DWORD dwExtentY; 91 DWORD dwSize; 92 BYTE *pData; 93 }OLECONVERT_ISTORAGE_OLEPRES; 94 95 96 /* Ole Stream Structure */ 97 /* Used for OleConvertIStorageToOLESTREAM and OleConvertOLESTREAMToIStorage */ 98 typedef struct 99 { 100 DWORD dwOLEHEADER_ID; 101 DWORD dwUnknown1; 102 DWORD dwUnknown2; 103 DWORD dwUnknown3; 104 DWORD dwUnknown4; /*Only used when using a Moniker is present in the /001Ole Stream*/ 105 DWORD dwUnknown5; /*Only used when using a Moniker is present in the /001Ole stream*/ 106 DWORD dwObjectCLSIDOffset; 107 CLSID clsidMonikerTypeID; 108 /*Save info for clsidMonikerTypeID (eg. FileMoniker, ItemMoniker, or CompositeMoniker) */ 109 DWORD dwUnknown6; 110 CLSID clsidObject; 111 BYTE dwUnknown7[32]; 112 }OLECONVERT_ISTORAGE_OLE; 113 114 115 33 116 34 117 /*********************************************************************** … … 37 120 static HRESULT deleteStorageProperty( 38 121 StorageImpl *parentStorage, 39 OLECHAR *propertyToDeleteName); 122 ULONG foundPropertyIndexToDelete, 123 StgProperty propertyToDelete); 40 124 41 125 static HRESULT deleteStreamProperty( … … 337 421 (currentProperty.propertyType==PROPTYPE_STREAM) ) 338 422 { 339 newStream = StgStreamImpl_Construct(This, foundPropertyIndex);423 newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex); 340 424 341 425 if (newStream!=0) … … 687 771 * non empty storage. 688 772 */ 773 StorageImpl_ReadProperty(This->ancestorStorage, 774 foundPropertyIndex, 775 ¤tProperty); 776 689 777 currentProperty.dirProperty = PROPERTY_NULL; 690 778 currentProperty.propertyType = PROPTYPE_STORAGE; … … 845 933 * Open the stream to return it. 846 934 */ 847 newStream = StgStreamImpl_Construct(This, newPropertyIndex);935 newStream = StgStreamImpl_Construct(This, grfMode, newPropertyIndex); 848 936 849 937 if (newStream != 0) … … 1593 1681 hr = deleteStorageProperty( 1594 1682 This, 1595 propertyToDelete.name); 1683 foundPropertyIndexToDelete, 1684 propertyToDelete); 1596 1685 } 1597 1686 else if ( propertyToDelete.propertyType == PROPTYPE_STREAM ) … … 1629 1718 static HRESULT deleteStorageProperty( 1630 1719 StorageImpl *parentStorage, 1631 OLECHAR *propertyToDeleteName) 1720 ULONG indexOfPropertyToDelete, 1721 StgProperty propertyToDelete) 1632 1722 { 1633 1723 IEnumSTATSTG *elements = 0; … … 1642 1732 hr = StorageBaseImpl_OpenStorage( 1643 1733 (IStorage*)parentStorage, 1644 propertyToDelete Name,1734 propertyToDelete.name, 1645 1735 0, 1646 1736 STGM_SHARE_EXCLUSIVE, … … 1682 1772 } while ((hr == S_OK) && (destroyHr == S_OK)); 1683 1773 1774 /* 1775 * Invalidate the property by zeroing it's name member. 1776 */ 1777 propertyToDelete.sizeOfNameString = 0; 1778 1779 StorageImpl_WriteProperty(parentStorage->ancestorStorage, 1780 indexOfPropertyToDelete, 1781 &propertyToDelete); 1782 1684 1783 IStorage_Release(childStorage); 1685 1784 IEnumSTATSTG_Release(elements); … … 1711 1810 (OLECHAR*)propertyToDelete.name, 1712 1811 NULL, 1713 STGM_ SHARE_EXCLUSIVE,1812 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 1714 1813 0, 1715 1814 &pis); … … 2027 2126 ILockBytes* pLkbyt, 2028 2127 DWORD openFlags, 2029 BOOL fileBased) 2128 BOOL fileBased, 2129 BOOL fileCreate) 2030 2130 { 2031 2131 HRESULT hr = S_OK; … … 2042 2142 * Initialize the virtual fgunction table. 2043 2143 */ 2044 This->lpvtbl= &Storage32Impl_Vtbl;2144 ICOM_VTBL(This) = &Storage32Impl_Vtbl; 2045 2145 This->v_destructor = &StorageImpl_Destroy; 2046 2146 … … 2070 2170 return E_FAIL; 2071 2171 2072 if ( openFlags & STGM_CREATE)2172 if (fileCreate) 2073 2173 { 2074 2174 ULARGE_INTEGER size; … … 2093 2193 This->extBigBlockDepotStart = BLOCK_END_OF_CHAIN; 2094 2194 This->extBigBlockDepotCount = 0; 2095 2096 2195 StorageImpl_SaveFileHeader(This); 2097 2196 … … 2151 2250 * Write the root property 2152 2251 */ 2153 if ( openFlags & STGM_CREATE)2252 if (fileCreate) 2154 2253 { 2155 2254 StgProperty rootProp; … … 2597 2696 if (depotBuffer!=0) 2598 2697 { 2599 int index; 2600 2601 for (index = 0; index < NUM_BLOCKS_PER_DEPOT_BLOCK; index++) 2602 { 2603 StorageUtl_ReadDWord(depotBuffer, index*sizeof(ULONG), &nextBlockIndex); 2604 This->blockDepotCached[index] = nextBlockIndex; 2605 } 2698 StorageUtl_ReadDWords(depotBuffer, 0, This->blockDepotCached, 2699 NUM_BLOCKS_PER_DEPOT_BLOCK); 2606 2700 2607 2701 StorageImpl_ReleaseBigBlock(This, depotBuffer); … … 3034 3128 3035 3129 memcpy(currentProperty + OFFSET_PS_PROPERTYTYPE, &buffer->propertyType, 1); 3036 3037 /*3038 * Reassign the size in case of mistake....3039 */3040 buffer->sizeOfNameString = (lstrlenW(buffer->name)+1) * sizeof(WCHAR);3041 3130 3042 3131 StorageUtl_WriteWord( … … 3288 3377 * Initialize the virtual function table. 3289 3378 */ 3290 newStorage->lpvtbl= &Storage32InternalImpl_Vtbl;3379 ICOM_VTBL(newStorage) = &Storage32InternalImpl_Vtbl; 3291 3380 newStorage->v_destructor = &StorageInternalImpl_Destroy; 3292 3381 … … 3359 3448 * Set-up the virtual function table and reference count. 3360 3449 */ 3361 newEnumeration->lpvtbl= &IEnumSTATSTGImpl_Vtbl;3450 ICOM_VTBL(newEnumeration) = &IEnumSTATSTGImpl_Vtbl; 3362 3451 newEnumeration->ref = 0; 3363 3452 … … 3875 3964 { 3876 3965 memcpy(value, (BYTE*)buffer+offset, sizeof(DWORD)); 3966 } 3967 3968 void StorageUtl_ReadDWords(void *buffer, ULONG offset, DWORD *values, 3969 ULONG len) 3970 { 3971 memcpy(values, (BYTE*)buffer+offset, sizeof(DWORD)*len); 3877 3972 } 3878 3973 … … 3957 4052 { 3958 4053 BlockChainStream* newStream; 3959 ULONG blockIndex;3960 4054 3961 4055 newStream = (BlockChainStream *)HeapAlloc(GetProcessHeap(), 0, sizeof(BlockChainStream)); … … 3965 4059 newStream->ownerPropertyIndex = propertyIndex; 3966 4060 newStream->lastBlockNoInSequence = 0xFFFFFFFF; 4061 newStream->lazyInitComplete = FALSE; 3967 4062 newStream->tailIndex = BLOCK_END_OF_CHAIN; 3968 4063 newStream->numBlocks = 0; 3969 4064 3970 blockIndex = BlockChainStream_GetHeadOfChain(newStream);3971 3972 while (blockIndex != BLOCK_END_OF_CHAIN)3973 {3974 newStream->numBlocks++;3975 newStream->tailIndex = blockIndex;3976 3977 blockIndex = StorageImpl_GetNextBlockInChain(3978 parentStorage,3979 blockIndex);3980 }3981 3982 4065 return newStream; 4066 } 4067 4068 static void BlockChainStream_LazyInit(BlockChainStream *This) 4069 { 4070 ULONG numBlocks = 0; 4071 ULONG tailIndex = BLOCK_END_OF_CHAIN; 4072 StorageImpl *parentStorage = This->parentStorage; 4073 4074 ULONG blockIndex = BlockChainStream_GetHeadOfChain(This); 4075 4076 while (blockIndex != BLOCK_END_OF_CHAIN) 4077 { 4078 numBlocks++; 4079 tailIndex = blockIndex; 4080 4081 blockIndex = StorageImpl_GetNextBlockInChain(parentStorage, 4082 blockIndex); 4083 } 4084 4085 This->numBlocks = numBlocks; 4086 This->tailIndex = tailIndex; 4087 } 4088 4089 static inline ULONG BlockChainStream_TailIndex(BlockChainStream *This) 4090 { 4091 if (!This->lazyInitComplete) 4092 BlockChainStream_LazyInit(This); 4093 return This->tailIndex; 4094 } 4095 4096 static inline ULONG BlockChainStream_NumBlocks(BlockChainStream *This) 4097 { 4098 if (!This->lazyInitComplete) 4099 BlockChainStream_LazyInit(This); 4100 return This->numBlocks; 3983 4101 } 3984 4102 … … 4351 4469 * Go to the current end of chain 4352 4470 */ 4353 if (This->tailIndex == BLOCK_END_OF_CHAIN) 4354 { 4355 currentBlock = blockIndex; 4356 4357 while (blockIndex != BLOCK_END_OF_CHAIN) 4358 { 4359 This->numBlocks++; 4360 currentBlock = blockIndex; 4361 4362 blockIndex = 4363 StorageImpl_GetNextBlockInChain(This->parentStorage, currentBlock); 4364 } 4365 4366 This->tailIndex = currentBlock; 4367 } 4368 4369 currentBlock = This->tailIndex; 4370 oldNumBlocks = This->numBlocks; 4471 currentBlock = BlockChainStream_TailIndex(This); 4472 oldNumBlocks = BlockChainStream_NumBlocks(This); 4371 4473 4372 4474 /* … … 5205 5307 DWORD fileAttributes; 5206 5308 WCHAR tempFileName[MAX_PATH]; 5309 BOOL switchRemoteToLocalFile = TRUE; 5207 5310 5208 5311 TRACE("(%s, %lx, %ld, %p)\n", … … 5229 5332 WCHAR tempPath[MAX_PATH]; 5230 5333 WCHAR prefix[] = { 'S', 'T', 'O', 0 }; 5334 5335 switchRemoteToLocalFile = FALSE; 5231 5336 5232 5337 memset(tempPath, 0, sizeof(tempPath)); … … 5288 5393 NULL, 5289 5394 grfMode, 5395 TRUE, 5290 5396 TRUE); 5291 5397 … … 5352 5458 5353 5459 hFile = CreateFileW( pwcsName, 5354 5355 5356 NULL,5357 OPEN_EXISTING,5358 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS,5359 0);5460 accessMode, 5461 shareMode, 5462 NULL, 5463 OPEN_EXISTING, 5464 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, 5465 0); 5360 5466 5361 5467 5362 5468 if (hFile==INVALID_HANDLE_VALUE) 5363 5469 { 5364 return E_FAIL; 5470 HRESULT hr = E_FAIL; 5471 DWORD last_error = GetLastError(); 5472 5473 switch (last_error) 5474 { 5475 case ERROR_FILE_NOT_FOUND: 5476 hr = STG_E_FILENOTFOUND; 5477 break; 5478 5479 case ERROR_PATH_NOT_FOUND: 5480 hr = STG_E_PATHNOTFOUND; 5481 break; 5482 5483 case ERROR_ACCESS_DENIED: 5484 case ERROR_WRITE_PROTECT: 5485 hr = STG_E_ACCESSDENIED; 5486 break; 5487 5488 case ERROR_SHARING_VIOLATION: 5489 hr = STG_E_SHAREVIOLATION; 5490 break; 5491 5492 default: 5493 hr = E_FAIL; 5494 } 5495 5496 return hr; 5365 5497 } 5366 5498 … … 5378 5510 NULL, 5379 5511 grfMode, 5380 TRUE); 5512 TRUE, 5513 FALSE); 5381 5514 5382 5515 if (FAILED(hr)) … … 5428 5561 plkbyt, 5429 5562 grfMode, 5430 FALSE); 5563 FALSE, 5564 TRUE); 5431 5565 5432 5566 if (FAILED(hr)) … … 5491 5625 plkbyt, 5492 5626 grfMode, 5627 FALSE, 5493 5628 FALSE); 5494 5629 … … 5582 5717 HRESULT res; 5583 5718 5719 /* For this function to work. All registry keys related to Interface must be in */ 5720 /* Installed in the wine registry (eg. Search for IFileMoniker in the windows registry, */ 5721 /* copy the missing CLSID keys (and all contents) to wine registry). Implement */ 5722 /* the OLE32_DllGetClassObject (a big switch for all interface in OLE32.dll to allocate the */ 5723 /* actual interface ) */ 5584 5724 FIXME("(),stub!\n"); 5585 5725 … … 5587 5727 5588 5728 if (SUCCEEDED(res)){ 5589 5729 /* For this to work properly iidInterface should be IUnknown, need to Query */ 5730 /* for IPersitStream, if successful, query for iidInterface */ 5731 5590 5732 res=CoCreateInstance(&clsid,NULL,CLSCTX_INPROC_SERVER,iidInterface,ppvObj); 5591 5733 … … 5619 5761 if (SUCCEEDED(res)) 5620 5762 5621 res=IPersistStream_Save(pPStm,pStm,FALSE); 5622 } 5623 5763 res=IPersistStream_Save(pPStm,pStm,TRUE); 5764 } 5765 5766 TRACE("Finished Save\n"); 5624 5767 return res; 5625 5768 } … … 5808 5951 } 5809 5952 5810 5953 BOOL OLECONVERT_IsStorageLink(LPSTORAGE pStorage) 5954 { 5955 STATSTG stat; 5956 5957 IStorage_Stat(pStorage, &stat, STATFLAG_NONAME); 5958 5959 return IsEqualCLSID(&IID_StdOleLink, &stat.clsid); 5960 } 5961 5962 /************************************************************************* 5963 * OLECONVERT_LoadOLE10 [Internal] 5964 * 5965 * Loads the OLE10 STREAM to memory 5966 * 5967 * PARAMS 5968 * pOleStream [I] The OLESTREAM 5969 * pData [I] Data Structure for the OLESTREAM Data 5970 * 5971 * RETURNS 5972 * Success: S_OK 5973 * Failure: CONVERT10_E_OLESTREAM_GET for invalid Get 5974 * CONVERT10_E_OLESTREAM_FMT if the OLEID is invalide 5975 * 5976 * NOTES 5977 * This function is used by OleConvertOLESTREAMToIStorage only. 5978 * 5979 * Memory allocated for pData must be freed by the caller 5980 */ 5981 HRESULT OLECONVERT_LoadOLE10(LPOLESTREAM pOleStream, OLECONVERT_OLESTREAM_DATA *pData) 5982 { 5983 DWORD dwSize; 5984 pData->pData = NULL; 5985 pData->pLinkExtraInfo = NULL; 5986 pData->strLinkFileName = NULL; 5987 5988 /* Get the OleID */ 5989 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwOleID), sizeof(pData->dwOleID)); 5990 if(dwSize != sizeof(pData->dwOleID)) 5991 { 5992 return CONVERT10_E_OLESTREAM_GET; 5993 } 5994 else if(pData->dwOleID != OLESTREAM_ID) 5995 { 5996 return CONVERT10_E_OLESTREAM_FMT; 5997 } 5998 5999 /* Get the TypeID...more info needed for this field */ 6000 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwObjectTypeID), sizeof(pData->dwObjectTypeID)); 6001 6002 if(dwSize != sizeof(pData->dwObjectTypeID)) 6003 { 6004 return CONVERT10_E_OLESTREAM_GET; 6005 } 6006 if(pData->dwObjectTypeID != 0) 6007 { 6008 if(pData->dwObjectTypeID != OLECONVERT_LINK_TYPE 6009 && pData->dwObjectTypeID != OLECONVERT_EMBEDDED_TYPE 6010 && pData->dwObjectTypeID != OLECONVERT_PRESENTATION_DATA_TYPE) 6011 { 6012 FIXME("Unknown ObjectTypeID: %lx\n", pData->dwObjectTypeID); 6013 } 6014 6015 /* Get the lenght of the OleTypeName */ 6016 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) &(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength)); 6017 if(dwSize != sizeof(pData->dwOleTypeNameLength)) 6018 { 6019 return CONVERT10_E_OLESTREAM_GET; 6020 } 6021 if(pData->dwOleTypeNameLength > 0) 6022 { 6023 /* Get the OleTypeName */ 6024 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)pData->strOleTypeName, pData->dwOleTypeNameLength); 6025 if(dwSize != pData->dwOleTypeNameLength) 6026 { 6027 return CONVERT10_E_OLESTREAM_GET; 6028 } 6029 } 6030 if(pData->dwObjectTypeID == OLECONVERT_LINK_TYPE) 6031 { 6032 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) &(pData->dwLinkFileNameLength), sizeof(pData->dwLinkFileNameLength)); 6033 if(dwSize != sizeof(pData->dwLinkFileNameLength)) 6034 { 6035 return CONVERT10_E_OLESTREAM_GET; 6036 } 6037 6038 if(pData->dwLinkFileNameLength > 0) 6039 { 6040 pData->strLinkFileName = (BYTE *)malloc(pData->dwLinkFileNameLength); 6041 if(pData->strLinkFileName == NULL) 6042 { 6043 return E_OUTOFMEMORY; 6044 } 6045 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) pData->strLinkFileName, pData->dwLinkFileNameLength); 6046 if(dwSize != pData->dwLinkFileNameLength) 6047 { 6048 return CONVERT10_E_OLESTREAM_GET; 6049 } 6050 } 6051 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) &(pData->dwLinkExtraInfoLength), sizeof(pData->dwLinkExtraInfoLength)); 6052 if(dwSize != sizeof(pData->dwLinkExtraInfoLength)) 6053 { 6054 return CONVERT10_E_OLESTREAM_GET; 6055 } 6056 6057 if(pData->dwLinkExtraInfoLength > 0) 6058 { 6059 pData->pLinkExtraInfo = (BYTE *)malloc(pData->dwLinkExtraInfoLength); 6060 if(pData->pLinkExtraInfo == NULL) 6061 { 6062 return E_OUTOFMEMORY; 6063 } 6064 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR) pData->pLinkExtraInfo, pData->dwLinkExtraInfoLength); 6065 if(dwSize != pData->dwLinkExtraInfoLength) 6066 { 6067 return CONVERT10_E_OLESTREAM_GET; 6068 } 6069 } 6070 } 6071 6072 /* Get the Width of the Metafile */ 6073 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwMetaFileWidth), sizeof(pData->dwMetaFileWidth)); 6074 if(dwSize != sizeof(pData->dwMetaFileWidth)) 6075 { 6076 return CONVERT10_E_OLESTREAM_GET; 6077 } 6078 6079 /* Get the Height of the Metafile */ 6080 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwMetaFileHeight), sizeof(pData->dwMetaFileHeight)); 6081 if(dwSize != sizeof(pData->dwMetaFileHeight)) 6082 { 6083 return CONVERT10_E_OLESTREAM_GET; 6084 } 6085 6086 /* Get the Length of the Data */ 6087 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)&(pData->dwDataLength), sizeof(pData->dwDataLength)); 6088 if(dwSize != sizeof(pData->dwDataLength)) 6089 { 6090 return CONVERT10_E_OLESTREAM_GET; 6091 } 6092 if(pData->dwDataLength > 0) 6093 { 6094 pData->pData = (BYTE *)malloc(pData->dwDataLength); 6095 if(pData->pData == NULL) 6096 { 6097 return E_OUTOFMEMORY; 6098 } 6099 /* Get Data (ex. IStorage, Metafile, or BMP) */ 6100 dwSize = pOleStream->lpstbl->Get(pOleStream, (LPSTR)pData->pData, pData->dwDataLength); 6101 if(dwSize != pData->dwDataLength) 6102 { 6103 return CONVERT10_E_OLESTREAM_GET; 6104 } 6105 } 6106 } 6107 return S_OK; 6108 } 6109 6110 6111 /************************************************************************* 6112 * OLECONVERT_SaveOLE10 [Internal] 6113 * 6114 * Saves the OLE10 STREAM From memory 6115 * 6116 * PARAMS 6117 * pData [I] Data Structure for the OLESTREAM Data 6118 * pOleStream [I] The OLESTREAM to save 6119 * 6120 * RETURNS 6121 * Success: S_OK 6122 * Failure: CONVERT10_E_OLESTREAM_PUT for invalid Put 6123 * 6124 * NOTES 6125 * This function is used by OleConvertIStorageToOLESTREAM only. 6126 * 6127 */ 6128 HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREAM pOleStream) 6129 { 6130 DWORD dwSize; 6131 HRESULT hRes = S_OK; 6132 6133 6134 /* Set the OleID */ 6135 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwOleID), sizeof(pData->dwOleID)); 6136 if(dwSize != sizeof(pData->dwOleID)) 6137 { 6138 return CONVERT10_E_OLESTREAM_PUT; 6139 } 6140 6141 /* Set the TypeID */ 6142 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwObjectTypeID), sizeof(pData->dwObjectTypeID)); 6143 if(dwSize != sizeof(pData->dwObjectTypeID)) 6144 { 6145 return CONVERT10_E_OLESTREAM_PUT; 6146 } 6147 6148 if(pData->dwOleID == OLESTREAM_ID && pData->dwObjectTypeID != 0 && hRes == S_OK) 6149 { 6150 /* Set the Length of the OleTypeName */ 6151 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwOleTypeNameLength), sizeof(pData->dwOleTypeNameLength)); 6152 if(dwSize != sizeof(pData->dwOleTypeNameLength)) 6153 { 6154 return CONVERT10_E_OLESTREAM_PUT; 6155 } 6156 6157 if(pData->dwOleTypeNameLength > 0) 6158 { 6159 /* Set the OleTypeName */ 6160 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->strOleTypeName, pData->dwOleTypeNameLength); 6161 if(dwSize != pData->dwOleTypeNameLength) 6162 { 6163 return CONVERT10_E_OLESTREAM_PUT; 6164 } 6165 } 6166 6167 if(pData->dwObjectTypeID == OLECONVERT_LINK_TYPE) 6168 { 6169 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) &(pData->dwLinkFileNameLength), sizeof(pData->dwLinkFileNameLength)); 6170 if(dwSize != sizeof(pData->dwLinkFileNameLength)) 6171 { 6172 return CONVERT10_E_OLESTREAM_GET; 6173 } 6174 6175 if(pData->dwLinkFileNameLength > 0) 6176 { 6177 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->strLinkFileName, pData->dwLinkFileNameLength); 6178 if(dwSize != pData->dwLinkFileNameLength) 6179 { 6180 return CONVERT10_E_OLESTREAM_GET; 6181 } 6182 } 6183 6184 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) &(pData->dwLinkExtraInfoLength), sizeof(pData->dwLinkExtraInfoLength)); 6185 if(dwSize != sizeof(pData->dwLinkExtraInfoLength)) 6186 { 6187 return CONVERT10_E_OLESTREAM_GET; 6188 } 6189 6190 if(pData->dwLinkExtraInfoLength > 0) 6191 { 6192 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->pLinkExtraInfo, pData->dwLinkExtraInfoLength); 6193 if(dwSize != pData->dwLinkExtraInfoLength) 6194 { 6195 return CONVERT10_E_OLESTREAM_GET; 6196 } 6197 } 6198 } 6199 6200 /* Set the width of the Metafile */ 6201 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwMetaFileWidth), sizeof(pData->dwMetaFileWidth)); 6202 if(dwSize != sizeof(pData->dwMetaFileWidth)) 6203 { 6204 return CONVERT10_E_OLESTREAM_PUT; 6205 } 6206 6207 /* Set the height of the Metafile */ 6208 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwMetaFileHeight), sizeof(pData->dwMetaFileHeight)); 6209 if(dwSize != sizeof(pData->dwMetaFileHeight)) 6210 { 6211 return CONVERT10_E_OLESTREAM_PUT; 6212 } 6213 6214 /* Set the lenght of the Data */ 6215 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR)&(pData->dwDataLength), sizeof(pData->dwDataLength)); 6216 if(dwSize != sizeof(pData->dwDataLength)) 6217 { 6218 return CONVERT10_E_OLESTREAM_PUT; 6219 } 6220 6221 if(pData->dwDataLength > 0) 6222 { 6223 /* Set the Data (eg. IStorage, Metafile, Bitmap) */ 6224 dwSize = pOleStream->lpstbl->Put(pOleStream, (LPSTR) pData->pData, pData->dwDataLength); 6225 if(dwSize != pData->dwDataLength) 6226 { 6227 return CONVERT10_E_OLESTREAM_PUT; 6228 } 6229 } 6230 } 6231 return S_OK; 6232 } 6233 6234 /************************************************************************* 6235 * OLECONVERT_GetOLE20FromOLE10[Internal] 6236 * 6237 * This function copies OLE10 Data (the IStorage in the OLESTREAM) to disk, 6238 * opens it, and copies the content to the dest IStorage for 6239 * OleConvertOLESTREAMToIStorage 6240 * 6241 * 6242 * PARAMS 6243 * pDestStorage [I] The IStorage to copy the data to 6244 * pBuffer [I] Buffer that contains the IStorage from the OLESTREAM 6245 * nBufferLength [I] The size of the buffer 6246 * 6247 * RETURNS 6248 * Nothing 6249 * 6250 * NOTES 6251 * 6252 * 6253 */ 6254 void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD nBufferLength) 6255 { 6256 HRESULT hRes; 6257 HANDLE hFile; 6258 IStorage *pTempStorage; 6259 DWORD dwNumOfBytesWritten; 6260 WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH]; 6261 WCHAR wstrPrefix[] = {'s', 'i', 's', 0}; 6262 6263 /* Create a temp File */ 6264 GetTempPathW(MAX_PATH, wstrTempDir); 6265 GetTempFileNameW(wstrTempDir, wstrPrefix, 0, wstrTempFile); 6266 hFile = CreateFileW(wstrTempFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 6267 6268 if(hFile != INVALID_HANDLE_VALUE) 6269 { 6270 /* Write IStorage Data to File */ 6271 WriteFile(hFile, pBuffer, nBufferLength, &dwNumOfBytesWritten, NULL); 6272 CloseHandle(hFile); 6273 6274 /* Open and copy temp storage to the Dest Storage */ 6275 hRes = StgOpenStorage(wstrTempFile, NULL, STGM_READ, NULL, 0, &pTempStorage); 6276 if(hRes == S_OK) 6277 { 6278 hRes = StorageImpl_CopyTo(pTempStorage, NULL,NULL,NULL, pDestStorage); 6279 StorageBaseImpl_Release(pTempStorage); 6280 } 6281 DeleteFileW(wstrTempFile); 6282 } 6283 } 6284 6285 6286 /************************************************************************* 6287 * OLECONVERT_WriteOLE20ToBuffer [Internal] 6288 * 6289 * Saves the OLE10 STREAM From memory 6290 * 6291 * PARAMS 6292 * pStorage [I] The Src IStorage to copy 6293 * pData [I] The Dest Memory to write to. 6294 * 6295 * RETURNS 6296 * The size in bytes allocated for pData 6297 * 6298 * NOTES 6299 * Memory allocated for pData must be freed by the caller 6300 * 6301 * Used by OleConvertIStorageToOLESTREAM only. 6302 * 6303 */ 6304 DWORD OLECONVERT_WriteOLE20ToBuffer(LPSTORAGE pStorage, BYTE **pData) 6305 { 6306 HANDLE hFile; 6307 HRESULT hRes; 6308 DWORD nDataLength = 0; 6309 IStorage *pTempStorage; 6310 WCHAR wstrTempDir[MAX_PATH], wstrTempFile[MAX_PATH]; 6311 WCHAR wstrPrefix[] = {'s', 'i', 's', 0}; 6312 6313 *pData = NULL; 6314 6315 /* Create temp Storage */ 6316 GetTempPathW(MAX_PATH, wstrTempDir); 6317 GetTempFileNameW(wstrTempDir, wstrPrefix, 0, wstrTempFile); 6318 hRes = StgCreateDocfile(wstrTempFile, STGM_CREATE | STGM_READWRITE | STGM_SHARE_EXCLUSIVE, NULL, &pTempStorage); 6319 6320 if(hRes == S_OK) 6321 { 6322 /* Copy Src Storage to the Temp Storage */ 6323 StorageImpl_CopyTo(pStorage, NULL,NULL,NULL, pTempStorage); 6324 StorageBaseImpl_Release(pTempStorage); 6325 6326 /* Open Temp Storage as a file and copy to memory */ 6327 hFile = CreateFileW(wstrTempFile, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 6328 if(hFile != INVALID_HANDLE_VALUE) 6329 { 6330 nDataLength = GetFileSize(hFile, NULL); 6331 *pData = (BYTE *) malloc(nDataLength); 6332 ReadFile(hFile, *pData, nDataLength, &nDataLength, 0); 6333 CloseHandle(hFile); 6334 } 6335 DeleteFileW(wstrTempFile); 6336 } 6337 return nDataLength; 6338 } 6339 6340 /************************************************************************* 6341 * OLECONVERT_CreateEmbeddedOleStream [Internal] 6342 * 6343 * Creates the "\001OLE" stream in the IStorage if neccessary. 6344 * 6345 * PARAMS 6346 * pStorage [I] Dest storage to create the stream in 6347 * 6348 * RETURNS 6349 * Nothing 6350 * 6351 * NOTES 6352 * This function is used by OleConvertOLESTREAMToIStorage only. 6353 * 6354 * This stream is still unknown, MS Word seems to have extra data 6355 * but since the data is stored in the OLESTREAM there should be 6356 * no need to recreate the stream. If the stream is manually 6357 * deleted it will create it with this default data. 6358 * 6359 */ 6360 void OLECONVERT_CreateEmbeddedOleStream(LPSTORAGE pStorage) 6361 { 6362 HRESULT hRes; 6363 IStream *pStream; 6364 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 6365 BYTE pOleStreamHeader [] = 6366 { 6367 0x01, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 6368 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6369 0x00, 0x00, 0x00, 0x00 6370 }; 6371 6372 /* Create stream if not present */ 6373 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6374 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6375 6376 if(hRes == S_OK) 6377 { 6378 /* Write default Data */ 6379 hRes = IStream_Write(pStream, pOleStreamHeader, sizeof(pOleStreamHeader), NULL); 6380 IStream_Release(pStream); 6381 } 6382 } 6383 6384 /************************************************************************* 6385 * OLECONVERT_CreateLinkOleStream [Internal] 6386 * 6387 * Creates the "\001OLE" stream in the IStorage if neccessary. 6388 * 6389 * PARAMS 6390 * pStorage [I] Dest storage to create the stream in 6391 * 6392 * RETURNS 6393 * Nothing 6394 * 6395 * NOTES 6396 * This function is used by OleConvertOLESTREAMToIStorage only. 6397 * 6398 * This stream is still unknown, MS Word seems to have extra data 6399 * but since the data is stored in the OLESTREAM there should be 6400 * no need to recreate the stream. If the stream is manually 6401 * deleted it will create it with this default data. 6402 * 6403 */ 6404 HRESULT OLECONVERT_CreateLinkOleStream(LPSTORAGE pStorage, LPCSTR strProgID, LPCSTR strFileName, BYTE *pItemData, DWORD dwItemDataLength) 6405 { 6406 HRESULT hRes; 6407 IStream *pStream; 6408 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 6409 OLECONVERT_ISTORAGE_OLE OleStreamHeader; 6410 LPMONIKER pFileMoniker=NULL; 6411 LPMONIKER pItemMoniker=NULL; 6412 LPMONIKER pCompMoniker=NULL; 6413 LPMONIKER pDestMoniker=NULL; 6414 6415 6416 BYTE pUnknown7 [] = 6417 { 6418 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6420 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 6421 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 6422 }; 6423 6424 OleStreamHeader.dwOLEHEADER_ID = 0x02000001; 6425 OleStreamHeader.dwUnknown1 = 0x01; 6426 OleStreamHeader.dwUnknown2 = 0x01; 6427 OleStreamHeader.dwUnknown3 = 0x00; 6428 OleStreamHeader.dwUnknown4 = 0x00; 6429 OleStreamHeader.dwUnknown5 = 0x00; 6430 OleStreamHeader.dwUnknown6 = 0xFFFF; 6431 hRes = CLSIDFromProgID16(strProgID, &(OleStreamHeader.clsidObject)); 6432 memcpy(OleStreamHeader.dwUnknown7, pUnknown7, sizeof(pUnknown7)); 6433 6434 if(hRes != S_OK) 6435 { 6436 return REGDB_E_CLASSNOTREG; 6437 } 6438 6439 if(strFileName != NULL) 6440 { 6441 WCHAR wstrFileName[MAX_PATH]; 6442 MultiByteToWideChar(CP_ACP, 0, strFileName, -1, wstrFileName, MAX_PATH); 6443 hRes = CreateFileMoniker(wstrFileName, &pFileMoniker); 6444 } 6445 if(pItemData != NULL) 6446 { 6447 6448 WCHAR wstrDelim[] = {'!', 0}; 6449 WCHAR *wstrItem; 6450 6451 wstrItem = (LPWSTR) malloc(dwItemDataLength * sizeof(WCHAR)); 6452 6453 MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pItemData, -1, wstrItem, dwItemDataLength); 6454 hRes = CreateItemMoniker(wstrDelim, wstrItem, &pItemMoniker); 6455 6456 free(wstrItem); 6457 } 6458 6459 if(pItemMoniker != NULL && pFileMoniker != NULL) 6460 { 6461 hRes = CreateGenericComposite(pFileMoniker, pItemMoniker, &pCompMoniker); 6462 } 6463 6464 if(hRes == S_OK) 6465 { 6466 6467 if(pCompMoniker != NULL) 6468 { 6469 pDestMoniker = pCompMoniker; 6470 } 6471 else if(pFileMoniker != NULL) 6472 { 6473 pDestMoniker = pFileMoniker; 6474 } 6475 else if(pItemMoniker != NULL) 6476 { 6477 pDestMoniker = pItemMoniker; 6478 } 6479 6480 6481 if(pDestMoniker != NULL) 6482 { 6483 ULARGE_INTEGER liFileMonikerSize; 6484 IMoniker_GetClassID(pDestMoniker, &(OleStreamHeader.clsidMonikerTypeID)); 6485 IMoniker_GetSizeMax(pDestMoniker, &liFileMonikerSize); 6486 OleStreamHeader.dwObjectCLSIDOffset = liFileMonikerSize.LowPart + sizeof(OleStreamHeader.dwUnknown6) + sizeof(OleStreamHeader.clsidMonikerTypeID); 6487 } 6488 6489 6490 /* Create stream (shouldn't be present)*/ 6491 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6492 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6493 6494 if(hRes == S_OK) 6495 { 6496 /* Write default Data */ 6497 IStream_Write(pStream, &(OleStreamHeader.dwOLEHEADER_ID), sizeof(OleStreamHeader.dwOLEHEADER_ID), NULL); 6498 IStream_Write(pStream, &(OleStreamHeader.dwUnknown1), sizeof(OleStreamHeader.dwUnknown1), NULL); 6499 IStream_Write(pStream, &(OleStreamHeader.dwUnknown2), sizeof(OleStreamHeader.dwUnknown2), NULL); 6500 IStream_Write(pStream, &(OleStreamHeader.dwUnknown3), sizeof(OleStreamHeader.dwUnknown3), NULL); 6501 IStream_Write(pStream, &(OleStreamHeader.dwUnknown4), sizeof(OleStreamHeader.dwUnknown4), NULL); 6502 IStream_Write(pStream, &(OleStreamHeader.dwUnknown5), sizeof(OleStreamHeader.dwUnknown5), NULL); 6503 IStream_Write(pStream, &(OleStreamHeader.dwObjectCLSIDOffset), sizeof(OleStreamHeader.dwObjectCLSIDOffset), NULL); 6504 /* Should call OleSaveToStream */ 6505 WriteClassStm(pStream, &(OleStreamHeader.clsidMonikerTypeID)); 6506 if(pDestMoniker != NULL) 6507 { 6508 IMoniker_Save(pDestMoniker, pStream, FALSE); 6509 } 6510 IStream_Write(pStream, &(OleStreamHeader.dwUnknown6), sizeof(OleStreamHeader.dwUnknown6), NULL); 6511 WriteClassStm(pStream, &(OleStreamHeader.clsidObject)); 6512 IStream_Write(pStream, OleStreamHeader.dwUnknown7, sizeof(OleStreamHeader.dwUnknown7), NULL); 6513 IStream_Release(pStream); 6514 } 6515 } 6516 if(pFileMoniker != NULL) 6517 { 6518 IMoniker_Release(pFileMoniker); 6519 } 6520 if(pItemMoniker != NULL) 6521 { 6522 IMoniker_Release(pItemMoniker); 6523 } 6524 if(pCompMoniker != NULL) 6525 { 6526 IMoniker_Release(pCompMoniker); 6527 } 6528 return S_OK; 6529 } 6530 6531 /************************************************************************* 6532 * OLECONVERT_CreateCompObjStream [Internal] 6533 * 6534 * Creates a "\001CompObj" is the destination IStorage if necessary. 6535 * 6536 * PARAMS 6537 * pStorage [I] The dest IStorage to create the CompObj Stream 6538 * if necessary. 6539 * strOleTypeName [I] The ProgID 6540 * 6541 * RETURNS 6542 * Success: S_OK 6543 * Failure: REGDB_E_CLASSNOTREG if cannot reconstruct the stream 6544 * 6545 * NOTES 6546 * This function is used by OleConvertOLESTREAMToIStorage only. 6547 * 6548 * The stream data is stored in the OLESTREAM and there should be 6549 * no need to recreate the stream. If the stream is manually 6550 * deleted it will attempt to create it by querying the registry. 6551 * 6552 * 6553 */ 6554 HRESULT OLECONVERT_CreateCompObjStream(LPSTORAGE pStorage, LPCSTR strOleTypeName) 6555 { 6556 IStream *pStream; 6557 HRESULT hStorageRes, hRes = S_OK; 6558 OLECONVERT_ISTORAGE_COMPOBJ IStorageCompObj; 6559 WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0}; 6560 6561 BYTE pCompObjUnknown1[] = {0x01, 0x00, 0xFE, 0xFF, 0x03, 0x0A, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF}; 6562 BYTE pCompObjUnknown2[] = {0xF4, 0x39, 0xB2, 0x71}; 6563 6564 /* Initialize the CompObj structure */ 6565 memset(&IStorageCompObj, 0, sizeof(IStorageCompObj)); 6566 memcpy(&(IStorageCompObj.byUnknown1), pCompObjUnknown1, sizeof(pCompObjUnknown1)); 6567 memcpy(&(IStorageCompObj.byUnknown2), pCompObjUnknown2, sizeof(pCompObjUnknown2)); 6568 6569 6570 /* Create a CompObj stream if it doesn't exist */ 6571 hStorageRes = IStorage_CreateStream(pStorage, wstrStreamName, 6572 STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6573 if(hStorageRes == S_OK) 6574 { 6575 /* copy the OleTypeName to the compobj struct */ 6576 IStorageCompObj.dwOleTypeNameLength = strlen(strOleTypeName)+1; 6577 strcpy(IStorageCompObj.strOleTypeName, strOleTypeName); 6578 6579 /* copy the OleTypeName to the compobj struct */ 6580 /* Note: in the test made, these where Identical */ 6581 IStorageCompObj.dwProgIDNameLength = strlen(strOleTypeName)+1; 6582 strcpy(IStorageCompObj.strProgIDName, strOleTypeName); 6583 6584 /* Get the CLSID */ 6585 hRes = CLSIDFromProgID16(IStorageCompObj.strProgIDName, &(IStorageCompObj.clsid)); 6586 6587 if(hRes != S_OK) 6588 { 6589 hRes = REGDB_E_CLASSNOTREG; 6590 } 6591 else 6592 { 6593 HKEY hKey; 6594 LONG hErr; 6595 /* Get the CLSID Default Name from the Registry */ 6596 hErr = RegOpenKeyA(HKEY_CLASSES_ROOT, IStorageCompObj.strProgIDName, &hKey); 6597 if(hErr == ERROR_SUCCESS) 6598 { 6599 char strTemp[OLESTREAM_MAX_STR_LEN]; 6600 IStorageCompObj.dwCLSIDNameLength = OLESTREAM_MAX_STR_LEN; 6601 hErr = RegQueryValueA(hKey, NULL, strTemp, (LPLONG)&(IStorageCompObj.dwCLSIDNameLength)); 6602 if(hErr == ERROR_SUCCESS) 6603 { 6604 strcpy(IStorageCompObj.strCLSIDName, strTemp); 6605 } 6606 RegCloseKey(hKey); 6607 } 6608 if(hErr != ERROR_SUCCESS) 6609 { 6610 hRes = REGDB_E_CLASSNOTREG; 6611 } 6612 } 6613 6614 if(hRes == S_OK ) 6615 { 6616 /* Write CompObj Structure to stream */ 6617 hRes = IStream_Write(pStream, IStorageCompObj.byUnknown1, sizeof(IStorageCompObj.byUnknown1), NULL); 6618 WriteClassStm(pStream,&(IStorageCompObj.clsid)); 6619 hRes = IStream_Write(pStream, &(IStorageCompObj.dwCLSIDNameLength), sizeof(IStorageCompObj.dwCLSIDNameLength), NULL); 6620 if(IStorageCompObj.dwCLSIDNameLength > 0) 6621 { 6622 hRes = IStream_Write(pStream, IStorageCompObj.strCLSIDName, IStorageCompObj.dwCLSIDNameLength, NULL); 6623 } 6624 hRes = IStream_Write(pStream, &(IStorageCompObj.dwOleTypeNameLength) , sizeof(IStorageCompObj.dwOleTypeNameLength), NULL); 6625 if(IStorageCompObj.dwOleTypeNameLength > 0) 6626 { 6627 hRes = IStream_Write(pStream, IStorageCompObj.strOleTypeName , IStorageCompObj.dwOleTypeNameLength, NULL); 6628 } 6629 hRes = IStream_Write(pStream, &(IStorageCompObj.dwProgIDNameLength) , sizeof(IStorageCompObj.dwProgIDNameLength), NULL); 6630 if(IStorageCompObj.dwProgIDNameLength > 0) 6631 { 6632 hRes = IStream_Write(pStream, IStorageCompObj.strProgIDName , IStorageCompObj.dwProgIDNameLength, NULL); 6633 } 6634 hRes = IStream_Write(pStream, IStorageCompObj.byUnknown2 , sizeof(IStorageCompObj.byUnknown2), NULL); 6635 } 6636 IStream_Release(pStream); 6637 } 6638 return hRes; 6639 } 6640 6641 6642 /************************************************************************* 6643 * OLECONVERT_CreateOlePresStream[Internal] 6644 * 6645 * Creates the "\002OlePres000" Stream with the Metafile data 6646 * 6647 * PARAMS 6648 * pStorage [I] The dest IStorage to create \002OLEPres000 stream in. 6649 * dwExtentX [I] Width of the Metafile 6650 * dwExtentY [I] Height of the Metafile 6651 * pData [I] Metafile data 6652 * dwDataLength [I] Size of the Metafile data 6653 * 6654 * RETURNS 6655 * Success: S_OK 6656 * Failure: CONVERT10_E_OLESTREAM_PUT for invalid Put 6657 * 6658 * NOTES 6659 * This function is used by OleConvertOLESTREAMToIStorage only. 6660 * 6661 */ 6662 void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwObjectType, DWORD dwExtentX, DWORD dwExtentY , BYTE *pData, DWORD dwDataLength) 6663 { 6664 HRESULT hRes; 6665 IStream *pStream; 6666 WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; 6667 BYTE pOlePresStreamEmbeddedHeader [] = 6668 { 6669 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 6670 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6671 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 6672 0x00, 0x00, 0x00, 0x00 6673 }; 6674 6675 BYTE pOlePresStreamLinkHeader [] = 6676 { 6677 0xFF, 0xFF, 0xFF, 0xFF, 0x03, 0x00, 0x00, 0x00, 6678 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6679 0xFF, 0xFF, 0xFF, 0xFF, 0x02, 0x00, 0x00, 0x00, 6680 0x00, 0x00, 0x00, 0x00 6681 }; 6682 6683 BYTE pOlePresStreamHeaderEmpty [] = 6684 { 6685 0x00, 0x00, 0x00, 0x00, 6686 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 6687 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 6688 0x00, 0x00, 0x00, 0x00 6689 }; 6690 6691 /* Create the OlePres000 Stream */ 6692 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6693 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6694 6695 if(hRes == S_OK) 6696 { 6697 DWORD nHeaderSize; 6698 OLECONVERT_ISTORAGE_OLEPRES OlePres; 6699 6700 memset(&OlePres, 0, sizeof(OlePres)); 6701 /* Do we have any metafile data to save */ 6702 if(dwDataLength > 0) 6703 { 6704 if(dwObjectType == OLECONVERT_LINK_TYPE) 6705 { 6706 memcpy(OlePres.byUnknown1, pOlePresStreamLinkHeader, sizeof(pOlePresStreamLinkHeader)); 6707 nHeaderSize = sizeof(pOlePresStreamLinkHeader); 6708 } 6709 else 6710 { 6711 memcpy(OlePres.byUnknown1, pOlePresStreamEmbeddedHeader, sizeof(pOlePresStreamEmbeddedHeader)); 6712 nHeaderSize = sizeof(pOlePresStreamEmbeddedHeader); 6713 } 6714 } 6715 else 6716 { 6717 memcpy(OlePres.byUnknown1, pOlePresStreamHeaderEmpty, sizeof(pOlePresStreamHeaderEmpty)); 6718 nHeaderSize = sizeof(pOlePresStreamHeaderEmpty); 6719 } 6720 /* Set width and height of the metafile */ 6721 OlePres.dwExtentX = dwExtentX; 6722 OlePres.dwExtentY = -dwExtentY; 6723 6724 /* Set Data and Length */ 6725 if(dwDataLength > sizeof(METAFILEPICT16)) 6726 { 6727 OlePres.dwSize = dwDataLength - sizeof(METAFILEPICT16); 6728 OlePres.pData = &(pData[8]); 6729 } 6730 /* Save OlePres000 Data to Stream */ 6731 hRes = IStream_Write(pStream, OlePres.byUnknown1, nHeaderSize, NULL); 6732 hRes = IStream_Write(pStream, &(OlePres.dwExtentX), sizeof(OlePres.dwExtentX), NULL); 6733 hRes = IStream_Write(pStream, &(OlePres.dwExtentY), sizeof(OlePres.dwExtentY), NULL); 6734 hRes = IStream_Write(pStream, &(OlePres.dwSize), sizeof(OlePres.dwSize), NULL); 6735 if(OlePres.dwSize > 0) 6736 { 6737 hRes = IStream_Write(pStream, OlePres.pData, OlePres.dwSize, NULL); 6738 } 6739 IStream_Release(pStream); 6740 } 6741 } 6742 6743 /************************************************************************* 6744 * OLECONVERT_CreateOle10NativeStream [Internal] 6745 * 6746 * Creates the "\001Ole10Native" Stream (should contain a BMP) 6747 * 6748 * PARAMS 6749 * pStorage [I] Dest storage to create the stream in 6750 * pData [I] Ole10 Native Data (ex. bmp) 6751 * dwDataLength [I] Size of the Ole10 Native Data 6752 * 6753 * RETURNS 6754 * Nothing 6755 * 6756 * NOTES 6757 * This function is used by OleConvertOLESTREAMToIStorage only. 6758 * 6759 * Might need to verify the data and return appropriate error message 6760 * 6761 */ 6762 void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD dwDataLength) 6763 { 6764 HRESULT hRes; 6765 IStream *pStream; 6766 WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; 6767 6768 /* Create the Ole10Native Stream */ 6769 hRes = IStorage_CreateStream(pStorage, wstrStreamName, 6770 STGM_CREATE | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pStream ); 6771 6772 if(hRes == S_OK) 6773 { 6774 /* Write info to stream */ 6775 hRes = IStream_Write(pStream, &dwDataLength, sizeof(dwDataLength), NULL); 6776 hRes = IStream_Write(pStream, pData, dwDataLength, NULL); 6777 IStream_Release(pStream); 6778 } 6779 6780 } 6781 6782 /************************************************************************* 6783 * OLECONVERT_GetProgIDFromStorage [Internal] 6784 * 6785 * Finds the ProgID (or OleTypeID) from the IStorage 6786 * 6787 * PARAMS 6788 * pStorage [I] The Src IStorage to get the ProgID 6789 * strProgID [I] the ProgID string to get 6790 * dwSize [I] the size of the string 6791 * 6792 * RETURNS 6793 * Success: S_OK 6794 * Failure: REGDB_E_CLASSNOTREG if cannot reconstruct the stream 6795 * 6796 * NOTES 6797 * This function is used by OleConvertIStorageToOLESTREAM only. 6798 * 6799 * 6800 */ 6801 HRESULT OLECONVERT_GetProgIDFromStorage(LPSTORAGE pStorage, char *strProgID, DWORD *dwSize) 6802 { 6803 HRESULT hRes; 6804 IStream *pStream; 6805 LARGE_INTEGER iSeekPos; 6806 6807 strProgID[0] = NULL; 6808 6809 if(strProgID == NULL || dwSize == NULL) 6810 { 6811 return E_INVALIDARG; 6812 } 6813 6814 if(OLECONVERT_IsStorageLink(pStorage)) 6815 { 6816 LPOLESTR wstrProgID; 6817 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 6818 6819 /* Open the CompObj Stream */ 6820 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6821 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6822 if(hRes == S_OK) 6823 { 6824 OLECONVERT_ISTORAGE_OLE OleStreamHeader; 6825 6826 /* Get the CLSID Offset */ 6827 iSeekPos.LowPart = sizeof(OleStreamHeader.dwOLEHEADER_ID) + sizeof(OleStreamHeader.dwUnknown1) 6828 + sizeof(OleStreamHeader.dwUnknown2) + sizeof(OleStreamHeader.dwUnknown3) 6829 + sizeof(OleStreamHeader.dwUnknown4) + sizeof(OleStreamHeader.dwUnknown5); 6830 iSeekPos.HighPart = 0; 6831 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); 6832 if(hRes == S_OK) 6833 { 6834 hRes = IStream_Read(pStream, &OleStreamHeader.dwObjectCLSIDOffset, sizeof(OleStreamHeader.dwObjectCLSIDOffset), NULL); 6835 } 6836 if(hRes == S_OK) 6837 { 6838 iSeekPos.LowPart = OleStreamHeader.dwObjectCLSIDOffset; 6839 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR, NULL); 6840 } 6841 /* Read the CLSID */ 6842 hRes = ReadClassStm(pStream, &OleStreamHeader.clsidObject); 6843 if(hRes == S_OK) 6844 { 6845 hRes = ProgIDFromCLSID(&(OleStreamHeader.clsidObject), &wstrProgID); 6846 if(hRes == S_OK) 6847 { 6848 *dwSize = WideCharToMultiByte(CP_ACP, 0, wstrProgID, -1, strProgID, *dwSize, NULL, FALSE); 6849 } 6850 } 6851 IStream_Release(pStream); 6852 } 6853 } 6854 else 6855 { 6856 6857 STATSTG stat; 6858 OLECONVERT_ISTORAGE_COMPOBJ CompObj; 6859 WCHAR wstrStreamName[] = {1,'C', 'o', 'm', 'p', 'O', 'b', 'j', 0}; 6860 /* Open the CompObj Stream */ 6861 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6862 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6863 6864 if(hRes == S_OK) 6865 { 6866 6867 /*Get the OleType from the CompObj Stream */ 6868 iSeekPos.LowPart = sizeof(CompObj.byUnknown1) + sizeof(CompObj.clsid); 6869 iSeekPos.HighPart = 0; 6870 6871 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); 6872 if(hRes == S_OK) 6873 { 6874 hRes = IStream_Read(pStream, &CompObj.dwCLSIDNameLength, sizeof(CompObj.dwCLSIDNameLength), NULL); 6875 } 6876 6877 if(hRes == S_OK) 6878 { 6879 iSeekPos.LowPart = CompObj.dwCLSIDNameLength; 6880 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL); 6881 } 6882 if(hRes == S_OK) 6883 { 6884 hRes = IStream_Read(pStream, &CompObj.dwOleTypeNameLength, sizeof(CompObj.dwOleTypeNameLength), NULL); 6885 } 6886 if(hRes == S_OK) 6887 { 6888 iSeekPos.LowPart = CompObj.dwOleTypeNameLength; 6889 hRes = IStream_Seek(pStream, iSeekPos, STREAM_SEEK_CUR , NULL); 6890 } 6891 6892 if(hRes == S_OK) 6893 { 6894 hRes = IStream_Read(pStream, dwSize, sizeof(*dwSize), NULL); 6895 if(*dwSize > 0) 6896 { 6897 if(hRes == S_OK) 6898 { 6899 hRes = IStream_Read(pStream, strProgID, *dwSize, NULL); 6900 } 6901 } 6902 } 6903 IStream_Release(pStream); 6904 } 6905 6906 /* If the CompObject is not present, or there was an error reading the CompObject */ 6907 /* Get the CLSID from the storage stat */ 6908 if(hRes != S_OK) 6909 { 6910 LPOLESTR wstrProgID; 6911 6912 /* Get the OleType from the registry */ 6913 IStorage_Stat(pStorage, &stat, STATFLAG_NONAME); 6914 hRes = ProgIDFromCLSID(&(stat.clsid), &wstrProgID); 6915 if(hRes == S_OK) 6916 { 6917 *dwSize = WideCharToMultiByte(CP_ACP, 0, wstrProgID, -1, strProgID, *dwSize, NULL, FALSE); 6918 } 6919 } 6920 } 6921 if(strProgID[0] == NULL) 6922 { 6923 *dwSize = 0; 6924 } 6925 return hRes; 6926 } 6927 6928 /************************************************************************* 6929 * OLECONVERT_GetOle20PresData[Internal] 6930 * 6931 * Converts IStorage "/002OlePres000" stream to a OLE10 Stream 6932 * 6933 * PARAMS 6934 * pStorage [I] Src IStroage 6935 * pOleStreamData [I] Dest OleStream Mem Struct 6936 * 6937 * RETURNS 6938 * Nothing 6939 * 6940 * NOTES 6941 * This function is used by OleConvertIStorageToOLESTREAM only. 6942 * 6943 * Memory allocated for pData must be freed by the caller 6944 */ 6945 void OLECONVERT_GetOle20PresData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 6946 { 6947 HRESULT hRes; 6948 IStream *pStream; 6949 OLECONVERT_ISTORAGE_OLEPRES olePress; 6950 WCHAR wstrStreamName[] = {2, 'O', 'l', 'e', 'P', 'r', 'e', 's', '0', '0', '0', 0}; 6951 6952 6953 6954 /* Open OlePress000 stream */ 6955 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 6956 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 6957 if(hRes == S_OK) 6958 { 6959 LARGE_INTEGER iSeekPos; 6960 METAFILEPICT16 MetaFilePict; 6961 char strMetafilePictName[] = "METAFILEPICT"; 6962 6963 /* Set the TypeID for a Metafile */ 6964 pOleStreamData[1].dwObjectTypeID = OLECONVERT_PRESENTATION_DATA_TYPE; 6965 6966 /* Set the OleTypeName to Metafile */ 6967 pOleStreamData[1].dwOleTypeNameLength = strlen(strMetafilePictName) +1; 6968 strcpy(pOleStreamData[1].strOleTypeName, strMetafilePictName); 6969 6970 iSeekPos.HighPart = 0; 6971 iSeekPos.LowPart = sizeof(olePress.byUnknown1); 6972 6973 /* Get Presentation Data */ 6974 IStream_Seek(pStream, iSeekPos, STREAM_SEEK_SET, NULL); 6975 IStream_Read(pStream, &(olePress.dwExtentX), sizeof(olePress.dwExtentX), NULL); 6976 IStream_Read(pStream, &(olePress.dwExtentY), sizeof(olePress.dwExtentY), NULL); 6977 IStream_Read(pStream, &(olePress.dwSize), sizeof(olePress.dwSize), NULL); 6978 6979 /*Set width and Height */ 6980 pOleStreamData[1].dwMetaFileWidth = olePress.dwExtentX; 6981 pOleStreamData[1].dwMetaFileHeight = -olePress.dwExtentY; 6982 if(olePress.dwSize > 0) 6983 { 6984 /* Set Length */ 6985 pOleStreamData[1].dwDataLength = olePress.dwSize + sizeof(METAFILEPICT16); 6986 6987 /* Set MetaFilePict struct */ 6988 MetaFilePict.mm = 8; 6989 MetaFilePict.xExt = olePress.dwExtentX; 6990 MetaFilePict.yExt = olePress.dwExtentY; 6991 MetaFilePict.hMF = 0; 6992 6993 /* Get Metafile Data */ 6994 pOleStreamData[1].pData = (BYTE *) malloc(pOleStreamData[1].dwDataLength); 6995 memcpy(pOleStreamData[1].pData, &MetaFilePict, sizeof(MetaFilePict)); 6996 IStream_Read(pStream, &(pOleStreamData[1].pData[sizeof(MetaFilePict)]), pOleStreamData[1].dwDataLength-sizeof(METAFILEPICT16), NULL); 6997 } 6998 IStream_Release(pStream); 6999 } 7000 } 7001 7002 LPMONIKER OLECONVERT_LoadMonikers(CLSID *pclsid, IStream *pStream ) 7003 { 7004 7005 LPMONIKER pDestMoniker=NULL; 7006 HRESULT hRes; 7007 if(IsEqualCLSID(&CLSID_FileMoniker, pclsid)) 7008 { 7009 WCHAR temp=0; 7010 hRes = CreateFileMoniker(&temp, &pDestMoniker); 7011 IMoniker_Load(pDestMoniker, pStream); 7012 } 7013 else if(IsEqualCLSID(&CLSID_ItemMoniker, pclsid)) 7014 { 7015 WCHAR temp1=0; 7016 WCHAR temp2=0; 7017 hRes = CreateItemMoniker(&temp1, &temp2, &pDestMoniker); 7018 IMoniker_Load(pDestMoniker, pStream); 7019 } 7020 else if(IsEqualCLSID(&CLSID_CompositeMoniker, pclsid)) 7021 { 7022 /* Problem with Saving CompositeMoniker */ 7023 /* TODO: Rechange remove code, create an empty CompositeMoniker */ 7024 WCHAR temp1=0; 7025 WCHAR temp2=0; 7026 LPMONIKER pItemMoniker, pFileMoniker; 7027 hRes = CreateItemMoniker(&temp1, &temp2, &pItemMoniker); 7028 hRes = CreateFileMoniker(&temp1, &pFileMoniker); 7029 hRes = CreateGenericComposite(pFileMoniker, pItemMoniker, &pDestMoniker); 7030 IMoniker_Load(pDestMoniker, pStream); 7031 } 7032 else 7033 { 7034 FIXME("Unsupported moniker in IStorage, /001Ole stream\n"); 7035 } 7036 return pDestMoniker; 7037 } 7038 7039 HRESULT OLECONVERT_GetMonikerFromStorage(LPSTORAGE pStorage, 7040 BYTE **pLinkFileName, DWORD* dwLinkFileNameLength, 7041 BYTE **pLinkExtraInfo, DWORD* dwLinkExtraInfoLength) 7042 { 7043 HRESULT hRes; 7044 IStream *pStream; 7045 WCHAR wstrStreamName[] = {1,'O', 'l', 'e', 0}; 7046 OLECONVERT_ISTORAGE_OLE OleStreamHeader; 7047 LPMONIKER pDestMoniker=NULL; 7048 7049 *pLinkFileName = NULL; 7050 *pLinkExtraInfo = NULL; 7051 *dwLinkFileNameLength = 0; 7052 *dwLinkExtraInfoLength = 0; 7053 7054 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 7055 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 7056 7057 if(hRes == S_OK) 7058 { 7059 /* Write default Data */ 7060 IStream_Read(pStream, &(OleStreamHeader.dwOLEHEADER_ID), sizeof(OleStreamHeader.dwOLEHEADER_ID), NULL); 7061 IStream_Read(pStream, &(OleStreamHeader.dwUnknown1), sizeof(OleStreamHeader.dwUnknown1), NULL); 7062 IStream_Read(pStream, &(OleStreamHeader.dwUnknown2), sizeof(OleStreamHeader.dwUnknown2), NULL); 7063 IStream_Read(pStream, &(OleStreamHeader.dwUnknown3), sizeof(OleStreamHeader.dwUnknown3), NULL); 7064 IStream_Read(pStream, &(OleStreamHeader.dwUnknown4), sizeof(OleStreamHeader.dwUnknown4), NULL); 7065 IStream_Read(pStream, &(OleStreamHeader.dwUnknown5), sizeof(OleStreamHeader.dwUnknown5), NULL); 7066 IStream_Read(pStream, &(OleStreamHeader.dwObjectCLSIDOffset), sizeof(OleStreamHeader.dwObjectCLSIDOffset), NULL); 7067 7068 /* Should call OleLoadFromStream, but implementeation incomplete */ 7069 ReadClassStm(pStream, &(OleStreamHeader.clsidMonikerTypeID)); 7070 /* Load the moniker */ 7071 pDestMoniker = OLECONVERT_LoadMonikers(&(OleStreamHeader.clsidMonikerTypeID), pStream); 7072 7073 /* Retreive the neccesary data */ 7074 if(IsEqualCLSID(&CLSID_FileMoniker, &(OleStreamHeader.clsidMonikerTypeID))) 7075 { 7076 7077 LPOLESTR ppszDisplayName; 7078 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7079 *dwLinkFileNameLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7080 NULL, 0, NULL, FALSE); 7081 *pLinkFileName = (BYTE *) malloc(*dwLinkFileNameLength); 7082 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7083 (LPSTR)*pLinkFileName, *dwLinkFileNameLength, NULL, FALSE); 7084 CoTaskMemFree(ppszDisplayName); 7085 } 7086 else if(IsEqualCLSID(&CLSID_ItemMoniker, &(OleStreamHeader.clsidMonikerTypeID))) 7087 { 7088 LPOLESTR ppszDisplayName; 7089 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7090 *dwLinkExtraInfoLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7091 NULL, 0, NULL, FALSE); 7092 *pLinkExtraInfo = (BYTE *) malloc(*dwLinkExtraInfoLength); 7093 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7094 (LPSTR)*pLinkExtraInfo, *dwLinkExtraInfoLength, NULL, FALSE); 7095 CoTaskMemFree(ppszDisplayName); 7096 7097 } 7098 else if(IsEqualCLSID(&CLSID_CompositeMoniker, &(OleStreamHeader.clsidMonikerTypeID))) 7099 { 7100 LPOLESTR ppszDisplayName; 7101 IMoniker *pmk; 7102 IEnumMoniker *enumMk; 7103 7104 IMoniker_Enum(pDestMoniker,TRUE,&enumMk); 7105 IEnumMoniker_Next(enumMk,1,&pmk,NULL); 7106 7107 7108 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7109 *dwLinkFileNameLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7110 NULL, 0, NULL, FALSE); 7111 *pLinkFileName = (BYTE *) malloc(*dwLinkFileNameLength); 7112 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7113 (LPSTR)*pLinkFileName, *dwLinkFileNameLength, NULL, FALSE); 7114 CoTaskMemFree(ppszDisplayName); 7115 IMoniker_Release(pmk); 7116 7117 IEnumMoniker_Next(enumMk,1,&pmk,NULL); 7118 7119 IMoniker_GetDisplayName(pDestMoniker, NULL, NULL, &ppszDisplayName); 7120 *dwLinkExtraInfoLength = WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7121 NULL, 0, NULL, FALSE); 7122 *pLinkExtraInfo = (BYTE *) malloc(*dwLinkExtraInfoLength); 7123 WideCharToMultiByte(CP_ACP, 0, ppszDisplayName, -1, 7124 (LPSTR)*pLinkExtraInfo, *dwLinkExtraInfoLength, NULL, FALSE); 7125 CoTaskMemFree(ppszDisplayName); 7126 IMoniker_Release(pmk); 7127 IEnumMoniker_Release(enumMk); 7128 } 7129 IStream_Read(pStream, &(OleStreamHeader.dwUnknown6), sizeof(OleStreamHeader.dwUnknown6), NULL); 7130 7131 ReadClassStm(pStream, &(OleStreamHeader.clsidObject)); 7132 IStream_Read(pStream, OleStreamHeader.dwUnknown7, sizeof(OleStreamHeader.dwUnknown7), NULL); 7133 IStream_Release(pStream); 7134 } 7135 if(pDestMoniker != NULL) 7136 { 7137 IMoniker_Release(pDestMoniker); 7138 } 7139 return S_OK; 7140 7141 7142 } 7143 /************************************************************************* 7144 * OLECONVERT_SetEmbeddedOle10OLESTREAMData [Internal] 7145 * 7146 * Converts IStorage "/001Ole10Native" stream to a OLE10 Stream 7147 * 7148 * PARAMS 7149 * pStorage [I] Src IStroage 7150 * pOleStream [I] Dest OleStream Mem Struct 7151 * 7152 * RETURNS 7153 * Nothing 7154 * 7155 * NOTES 7156 * This function is used by OleConvertIStorageToOLESTREAM only. 7157 * 7158 * Memory allocated for pData must be freed by the caller 7159 * 7160 * 7161 */ 7162 HRESULT OLECONVERT_SetEmbeddedOle10OLESTREAMData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7163 { 7164 7165 HRESULT hRes; 7166 IStream *pStream; 7167 WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; 7168 7169 /* Initialize Default data for OLESTREAM */ 7170 memset(pOleStreamData,0, sizeof(OLECONVERT_OLESTREAM_DATA) * OLECONVERT_NUM_OLE10STREAMS); 7171 /* Get the ProgID */ 7172 pOleStreamData[0].dwOleTypeNameLength = OLESTREAM_MAX_STR_LEN; 7173 hRes = OLECONVERT_GetProgIDFromStorage(pStorage, pOleStreamData[0].strOleTypeName, &(pOleStreamData[0].dwOleTypeNameLength)); 7174 7175 if(hRes != S_OK) 7176 { 7177 /* Cannot find the CLSID in the registry. Abort! */ 7178 return hRes; 7179 } 7180 7181 pOleStreamData[0].dwOleID = OLESTREAM_ID; 7182 pOleStreamData[0].dwObjectTypeID = OLECONVERT_EMBEDDED_TYPE; 7183 7184 /* Open Ole10Native Stream */ 7185 hRes = IStorage_OpenStream(pStorage, wstrStreamName, NULL, 7186 STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream ); 7187 if(hRes == S_OK) 7188 { 7189 7190 /* Read Size and Data */ 7191 IStream_Read(pStream, &(pOleStreamData->dwDataLength), sizeof(pOleStreamData->dwDataLength), NULL); 7192 if(pOleStreamData->dwDataLength > 0) 7193 { 7194 pOleStreamData->pData = (BYTE *) malloc(pOleStreamData->dwDataLength); 7195 IStream_Read(pStream, pOleStreamData->pData, pOleStreamData->dwDataLength, NULL); 7196 } 7197 IStream_Release(pStream); 7198 } 7199 7200 if(hRes == S_OK) 7201 { 7202 /* Stream doens't exist for all cases: no stream for pbrush but package does! */ 7203 /* Cannot check for return value because the stream might not exist (normal behavior)*/ 7204 pOleStreamData[1].dwOleID = OLESTREAM_ID; 7205 OLECONVERT_GetOle20PresData(pStorage, pOleStreamData); 7206 } 7207 7208 return hRes; 7209 7210 } 7211 7212 HRESULT OLECONVERT_SetEmbeddedOle20OLESTREAMData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7213 { 7214 7215 HRESULT hRes=S_OK; 7216 /* Initialize Default data for OLESTREAM */ 7217 memset(pOleStreamData,0, sizeof(OLECONVERT_OLESTREAM_DATA) * OLECONVERT_NUM_OLE10STREAMS); 7218 7219 /* Get the ProgID */ 7220 pOleStreamData[0].dwOleTypeNameLength = OLESTREAM_MAX_STR_LEN; 7221 hRes = OLECONVERT_GetProgIDFromStorage(pStorage, pOleStreamData[0].strOleTypeName, &(pOleStreamData[0].dwOleTypeNameLength)); 7222 7223 if(hRes != S_OK) 7224 { 7225 /* Cannot find the CLSID in the registry. Abort! */ 7226 return hRes; 7227 } 7228 7229 pOleStreamData[0].dwOleID = OLESTREAM_ID; 7230 pOleStreamData[0].dwObjectTypeID = OLECONVERT_EMBEDDED_TYPE; 7231 pOleStreamData[0].dwDataLength = OLECONVERT_WriteOLE20ToBuffer(pStorage, 7232 &(pOleStreamData[0].pData)); 7233 pOleStreamData[1].dwOleID = OLESTREAM_ID; 7234 OLECONVERT_GetOle20PresData(pStorage, pOleStreamData); 7235 7236 return hRes; 7237 } 7238 7239 7240 HRESULT OLECONVERT_SetLinkOLESTREAMData(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7241 { 7242 7243 HRESULT hRes = S_OK; 7244 /* Initialize Default data for OLESTREAM */ 7245 memset(pOleStreamData,0, sizeof(OLECONVERT_OLESTREAM_DATA) * OLECONVERT_NUM_OLE10STREAMS); 7246 7247 /* Get the ProgID */ 7248 pOleStreamData[0].dwOleTypeNameLength = OLESTREAM_MAX_STR_LEN; 7249 hRes = OLECONVERT_GetProgIDFromStorage(pStorage, pOleStreamData[0].strOleTypeName, &(pOleStreamData[0].dwOleTypeNameLength)); 7250 7251 if(hRes != S_OK) 7252 { 7253 /* Cannot find the CLSID in the registry. Abort! */ 7254 return hRes; 7255 } 7256 pOleStreamData[0].dwOleID = OLESTREAM_ID; 7257 pOleStreamData[0].dwObjectTypeID = OLECONVERT_LINK_TYPE; 7258 /* TODO: Write the Link data */ 7259 OLECONVERT_GetMonikerFromStorage(pStorage, 7260 &(pOleStreamData[0].strLinkFileName), &(pOleStreamData[0].dwLinkFileNameLength), 7261 &(pOleStreamData[0].pLinkExtraInfo), &(pOleStreamData[0].dwLinkExtraInfoLength)); 7262 7263 /* pOleStreamData[0].dwDataLength = OLECONVERT_WriteOLE20ToBuffer(pStorage, &(pOleStreamData[0].pData)); */ 7264 pOleStreamData[1].dwOleID = OLESTREAM_ID; 7265 OLECONVERT_GetOle20PresData(pStorage, pOleStreamData); 7266 return hRes; 7267 } 7268 7269 7270 HRESULT OLECONVERT_CreateEmbeddedIStorage(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7271 { 7272 HRESULT hRes = S_OK; 7273 BOOL bCreateOle10Native = TRUE; 7274 if(pOleStreamData[0].dwDataLength > sizeof(STORAGE_magic)) 7275 { 7276 /* Do we have the IStorage Data in the OLESTREAM */ 7277 if(memcmp(pOleStreamData[0].pData, STORAGE_magic, sizeof(STORAGE_magic)) ==0) 7278 { 7279 OLECONVERT_GetOLE20FromOLE10(pStorage, pOleStreamData[0].pData, pOleStreamData[0].dwDataLength); 7280 7281 OLECONVERT_CreateOlePresStream(pStorage, OLECONVERT_EMBEDDED_TYPE, 7282 pOleStreamData[1].dwMetaFileWidth, pOleStreamData[1].dwMetaFileHeight, 7283 pOleStreamData[1].pData, pOleStreamData[1].dwDataLength); 7284 bCreateOle10Native = FALSE; 7285 } 7286 } 7287 7288 if(bCreateOle10Native) 7289 { 7290 /* It must be an original OLE 1.0 source */ 7291 OLECONVERT_CreateOle10NativeStream(pStorage, pOleStreamData[0].pData, pOleStreamData[0].dwDataLength); 7292 7293 if(pOleStreamData[1].dwObjectTypeID == OLECONVERT_PRESENTATION_DATA_TYPE) 7294 { 7295 OLECONVERT_CreateOlePresStream(pStorage, OLECONVERT_EMBEDDED_TYPE, 7296 pOleStreamData[1].dwMetaFileWidth, pOleStreamData[1].dwMetaFileHeight, 7297 pOleStreamData[1].pData, pOleStreamData[1].dwDataLength); 7298 } 7299 } 7300 7301 /*Create the Ole Stream if necessary */ 7302 OLECONVERT_CreateEmbeddedOleStream(pStorage); 7303 /* Create CompObj Stream if necessary */ 7304 hRes = OLECONVERT_CreateCompObjStream(pStorage, pOleStreamData[0].strOleTypeName); 7305 if(hRes == S_OK) 7306 { 7307 CLSID clsid; 7308 7309 CLSIDFromProgID16(pOleStreamData[0].strOleTypeName, &clsid); 7310 IStorage_SetClass(pStorage, &clsid); 7311 } 7312 return hRes; 7313 } 7314 7315 HRESULT OLECONVERT_CreateLinkIStorage(LPSTORAGE pStorage, OLECONVERT_OLESTREAM_DATA *pOleStreamData) 7316 { 7317 HRESULT hRes; 7318 hRes = OLECONVERT_CreateLinkOleStream(pStorage, 7319 pOleStreamData[0].strOleTypeName, (LPCSTR)pOleStreamData[0].strLinkFileName, 7320 pOleStreamData[0].pLinkExtraInfo, pOleStreamData[0].dwLinkExtraInfoLength); 7321 if(hRes == S_OK) 7322 { 7323 OLECONVERT_CreateOlePresStream(pStorage, OLECONVERT_LINK_TYPE, 7324 pOleStreamData[1].dwMetaFileWidth, pOleStreamData[1].dwMetaFileHeight, 7325 pOleStreamData[1].pData, pOleStreamData[1].dwDataLength); 7326 } 7327 if(hRes == S_OK) 7328 { 7329 IStorage_SetClass(pStorage, &IID_StdOleLink); 7330 } 7331 return hRes; 7332 } 7333 7334 7335 7336 /************************************************************************* 7337 * OleConvertOLESTREAMToIStorage [OLE32.87] 7338 * 7339 * Read info on MSDN 7340 * 7341 * TODO 7342 * DVTARGETDEVICE paramenter is not handled 7343 * Still unsure of some mem fields for OLE 10 Stream 7344 * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", 7345 * and "\001OLE" streams 7346 * 7347 */ 7348 HRESULT WINAPI OleConvertOLESTREAMToIStorage ( 7349 LPOLESTREAM pOleStream, 7350 LPSTORAGE pstg, 7351 const DVTARGETDEVICE* ptd) 7352 { 7353 int i; 7354 HRESULT hRes=S_OK; 7355 OLECONVERT_OLESTREAM_DATA pOleStreamData[OLECONVERT_NUM_OLE10STREAMS]; 7356 7357 memset(pOleStreamData, 0, sizeof(pOleStreamData)); 7358 7359 if(ptd != NULL) 7360 { 7361 FIXME("DVTARGETDEVICE is not NULL, unhandled parameter\n"); 7362 } 7363 7364 if(pstg == NULL || pOleStream == NULL) 7365 { 7366 hRes = E_INVALIDARG; 7367 } 7368 7369 if(hRes == S_OK) 7370 { 7371 /* Load the OLESTREAM to Memory */ 7372 hRes = OLECONVERT_LoadOLE10(pOleStream, &pOleStreamData[0]); 7373 } 7374 7375 if(hRes == S_OK) 7376 { 7377 /* Load the OLESTREAM to Memory (part 2)*/ 7378 hRes = OLECONVERT_LoadOLE10(pOleStream, &pOleStreamData[1]); 7379 } 7380 7381 if(hRes == S_OK) 7382 { 7383 /* Is olestream an embedded object */ 7384 if(pOleStreamData[0].dwObjectTypeID != OLECONVERT_LINK_TYPE) 7385 { 7386 hRes = OLECONVERT_CreateEmbeddedIStorage(pstg, pOleStreamData); 7387 } 7388 else 7389 { 7390 hRes = OLECONVERT_CreateLinkIStorage(pstg, pOleStreamData); 7391 } 7392 } 7393 /* Free allocated memory */ 7394 for(i=0; i < OLECONVERT_NUM_OLE10STREAMS; i++) 7395 { 7396 if(pOleStreamData[i].pData != NULL) 7397 { 7398 free(pOleStreamData[i].pData); 7399 } 7400 7401 if(pOleStreamData[i].pLinkExtraInfo != NULL) 7402 { 7403 free(pOleStreamData[i].pLinkExtraInfo); 7404 } 7405 if(pOleStreamData[i].strLinkFileName != NULL) 7406 { 7407 free(pOleStreamData[i].strLinkFileName); 7408 } 7409 } 7410 return hRes; 7411 } 7412 7413 /************************************************************************* 7414 * OleConvertIStorageToOLESTREAM [OLE32.85] 7415 * 7416 * Read info on MSDN 7417 * 7418 * Read info on MSDN 7419 * 7420 * TODO 7421 * Still unsure of some mem fields for OLE 10 Stream 7422 * Still some unknowns for the IStorage: "\002OlePres000", "\001CompObj", 7423 * and "\001OLE" streams. 7424 * 7425 */ 7426 HRESULT WINAPI OleConvertIStorageToOLESTREAM ( 7427 LPSTORAGE pstg, 7428 LPOLESTREAM pOleStream) 7429 { 7430 int i; 7431 HRESULT hRes = S_OK; 7432 IStream *pStream; 7433 OLECONVERT_OLESTREAM_DATA pOleStreamData[OLECONVERT_NUM_OLE10STREAMS]; 7434 WCHAR wstrStreamName[] = {1, 'O', 'l', 'e', '1', '0', 'N', 'a', 't', 'i', 'v', 'e', 0}; 7435 7436 7437 memset(pOleStreamData, 0, sizeof(pOleStreamData)); 7438 7439 if(pstg == NULL || pOleStream == NULL) 7440 { 7441 hRes = E_INVALIDARG; 7442 } 7443 if(hRes == S_OK) 7444 { 7445 if(!OLECONVERT_IsStorageLink(pstg)) 7446 { 7447 /*Was it originaly Ole10 */ 7448 hRes = IStorage_OpenStream(pstg, wstrStreamName, 0, STGM_READ | STGM_SHARE_EXCLUSIVE, 0, &pStream); 7449 if(hRes == S_OK) 7450 { 7451 IStream_Release(pStream); 7452 /*Get Presentation Data for Ole10Native */ 7453 hRes = OLECONVERT_SetEmbeddedOle10OLESTREAMData(pstg, pOleStreamData); 7454 } 7455 else 7456 { 7457 /*Get Presentation Data (OLE20)*/ 7458 hRes = OLECONVERT_SetEmbeddedOle20OLESTREAMData(pstg, pOleStreamData); 7459 } 7460 } 7461 else 7462 { 7463 hRes = OLECONVERT_SetLinkOLESTREAMData(pstg, pOleStreamData); 7464 } 7465 7466 if(hRes == S_OK) 7467 { 7468 /* Save OLESTREAM */ 7469 hRes = OLECONVERT_SaveOLE10(&(pOleStreamData[0]), pOleStream); 7470 if(hRes == S_OK) 7471 { 7472 hRes = OLECONVERT_SaveOLE10(&(pOleStreamData[1]), pOleStream); 7473 } 7474 } 7475 } 7476 7477 /* Free allocated memory */ 7478 for(i=0; i < OLECONVERT_NUM_OLE10STREAMS; i++) 7479 { 7480 if(pOleStreamData[i].pData != NULL) 7481 { 7482 free(pOleStreamData[i].pData); 7483 } 7484 7485 if(pOleStreamData[i].pLinkExtraInfo != NULL) 7486 { 7487 free(pOleStreamData[i].pLinkExtraInfo); 7488 } 7489 7490 if(pOleStreamData[i].strLinkFileName != NULL) 7491 { 7492 free(pOleStreamData[i].strLinkFileName); 7493 } 7494 } 7495 7496 return hRes; 7497 } 5811 7498 5812 7499 /****************************************************************************** … … 5814 7501 */ 5815 7502 HRESULT WINAPI StgIsStorageFile16(LPCOLESTR16 fn) { 7503 static const BYTE STORAGE_notmagic[8]={0x0e,0x11,0xfc,0x0d,0xd0,0xcf,0x11,0xe0}; 5816 7504 HFILE hf; 5817 7505 OFSTRUCT ofs; -
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 $ */ 2 2 /* 3 3 * Compound Storage (32 bit version) … … 89 89 static const BYTE STORAGE_magic[8] ={0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1}; 90 90 static 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};92 91 93 92 /* … … 138 137 typedef struct BigBlockFile BigBlockFile,*LPBIGBLOCKFILE; 139 138 typedef struct MappedPage MappedPage,*LPMAPPEDPAGE; 140 typedef struct BigBlock BigBlock,*LPBIGBLOCK;141 139 142 140 struct BigBlockFile … … 148 146 HANDLE hfilemap; 149 147 DWORD flProtect; 150 MappedPage *maplisthead; 148 MappedPage *maplist; 149 MappedPage *victimhead, *victimtail; 150 ULONG num_victim_pages; 151 151 ILockBytes *pLkbyt; 152 152 HGLOBAL hbytearray; 153 153 LPVOID pbytearray; 154 BigBlock *headblock;155 154 }; 156 155 … … 182 181 struct StorageBaseImpl 183 182 { 184 ICOM_V TABLE(IStorage)* lpvtbl; /* Needs to be the first item in the stuct185 183 ICOM_VFIELD(IStorage); /* Needs to be the first item in the stuct 184 * since we want to cast this in a Storage32 pointer */ 186 185 187 186 /* … … 276 275 struct StorageImpl 277 276 { 278 ICOM_V TABLE(IStorage) *lpvtbl; /* Needs to be the first item in the stuct277 ICOM_VFIELD(IStorage); /* Needs to be the first item in the stuct 279 278 * since we want to cast this in a Storage32 pointer */ 280 279 … … 323 322 */ 324 323 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 /*****************************************************************************************/ 325 331 }; 326 332 … … 378 384 379 385 HRESULT 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); 385 392 386 393 BOOL StorageImpl_ReadBigBlock( … … 465 472 struct StorageInternalImpl 466 473 { 467 ICOM_V TABLE(IStorage) *lpvtbl; /* Needs to be the first item in the stuct468 474 ICOM_VFIELD(IStorage); /* Needs to be the first item in the stuct 475 * since we want to cast this in a Storage32 pointer */ 469 476 470 477 /* … … 509 516 struct IEnumSTATSTGImpl 510 517 { 511 ICOM_V TABLE(IEnumSTATSTG) *lpvtbl; /* Needs to be the first item in the stuct518 ICOM_VFIELD(IEnumSTATSTG); /* Needs to be the first item in the stuct 512 519 * since we want to cast this in a IEnumSTATSTG pointer */ 513 520 … … 594 601 struct StgStreamImpl 595 602 { 596 ICOM_V TABLE(IStream) *lpvtbl; /* Needs to be the first item in the stuct603 ICOM_VFIELD(IStream); /* Needs to be the first item in the stuct 597 604 * since we want to cast this in a IStream pointer */ 598 605 … … 606 613 */ 607 614 StorageBaseImpl* parentStorage; 615 616 /* 617 * Access mode of this stream. 618 */ 619 DWORD grfMode; 608 620 609 621 /* … … 637 649 StgStreamImpl* StgStreamImpl_Construct( 638 650 StorageBaseImpl* parentStorage, 639 ULONG ownerProperty); 651 DWORD grfMode, 652 ULONG ownerProperty); 640 653 641 654 void StgStreamImpl_Destroy( … … 723 736 void StorageUtl_ReadDWord(void* buffer, ULONG offset, DWORD* value); 724 737 void StorageUtl_WriteDWord(void* buffer, ULONG offset, DWORD value); 738 void StorageUtl_ReadDWords(void *buffer, ULONG offset, DWORD *values, 739 ULONG len); 725 740 void StorageUtl_ReadGUID(void* buffer, ULONG offset, GUID* value); 726 741 void StorageUtl_WriteGUID(void* buffer, ULONG offset, GUID* value); … … 744 759 ULONG tailIndex; 745 760 ULONG numBlocks; 761 BOOL lazyInitComplete; 746 762 }; 747 763 -
trunk/src/ole32/stubs.cpp
r1957 r3167 1 /* $Id: stubs.cpp,v 1.1 0 1999-12-03 11:57:20 sandervlExp $ */1 /* $Id: stubs.cpp,v 1.11 2000-03-19 15:33:09 davidr Exp $ */ 2 2 /* 3 3 * Win32 COM/OLE stubs for OS/2 … … 323 323 //******************************************************************************* 324 324 //******************************************************************************* 325 HRESULT WIN32API OleConvertIStorageToOLESTREAM(IStorage *pStg, LPOLESTREAM lpolestream)326 {327 dprintf(("OLE32: OleConvertIStorageToOLESTREAM - stub"));328 return E_INVALIDARG;329 }330 //*******************************************************************************331 //*******************************************************************************332 325 HRESULT WIN32API OleConvertIStorageToOLESTREAMEx(LPSTORAGE pStg, 333 326 CLIPFORMAT ctFormat, … … 339 332 { 340 333 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"));350 334 return(E_INVALIDARG); 351 335 }
Note:
See TracChangeset
for help on using the changeset viewer.