Implements OleLoadPicturePath

Maxime Bellengé maxime.bellenge at wanadoo.fr
Mon Feb 28 15:41:58 CST 2005


Thanks for your reply, I will fix the places you mentioned to clean
things up correctly. But other places in olepicture should also be fixed
in this case. I will check that.

Max

On Mon, 2005-02-28 at 15:22 -0600, Robert Shearman wrote:
> Maxime Bellengé wrote:
> 
> >Hello, here is an implementation of OleLoadPicturePath.
> >The filename can be either a local file or an url.
> >In case of a url, I needed a user-agent for wininet. I put a dummy value
> >as I didn't find a default wine value. Is there a default value
> >somewhere for the whole project ?
> >
> >a+
> >
> >Max
> >
> >ChangeLog:
> >    * Implements OleLoadPicturePath
> >
> >  
> >
> >------------------------------------------------------------------------
> >
> >Index: wine/dlls/oleaut32/olepicture.c
> >===================================================================
> >RCS file: /home/wine/wine/dlls/oleaut32/olepicture.c,v
> >retrieving revision 1.55
> >diff -u -r1.55 olepicture.c
> >--- wine/dlls/oleaut32/olepicture.c	25 Feb 2005 14:07:57 -0000	1.55
> >+++ wine/dlls/oleaut32/olepicture.c	27 Feb 2005 10:51:43 -0000
> >@@ -71,7 +71,9 @@
> > #include "olectl.h"
> > #include "oleauto.h"
> > #include "connpt.h"
> >+#include "wininet.h"
> > #include "wine/debug.h"
> >+#include "wine/unicode.h"
> > 
> > #include "wine/wingdi16.h"
> > #include "cursoricon.h"
> >@@ -1998,11 +2000,122 @@
> > 		DWORD dwReserved, OLE_COLOR clrReserved, REFIID riid,
> > 		LPVOID *ppvRet )
> > {
> >-  FIXME("(%s,%p,%ld,%08lx,%s,%p): stub\n",
> >+  static const WCHAR file[] = { 'f','i','l','e',':','/','/',0 };
> >+  static const WCHAR name[] = { 'w','i','n','e','-','a','g','e','n','t',0};
> >+  IPicture *ipicture;
> >+  HANDLE hFile;
> >+  DWORD dwFileSize;
> >+  HGLOBAL hGlobal = NULL;
> >+  DWORD dwBytesRead = 0;
> >+  IStream *stream;
> >+  BOOL bRead;
> >+  IPersistStream *pStream;
> >+  HRESULT hRes;
> >+
> >+  TRACE("(%s,%p,%ld,%08lx,%s,%p): stub\n",
> >         debugstr_w(szURLorPath), punkCaller, dwReserved, clrReserved,
> >         debugstr_guid(riid), ppvRet);
> > 
> >-  return E_NOTIMPL;
> >+  if (!ppvRet) return E_POINTER;
> >+
> >+  if (strncmpW(szURLorPath, file, 7) == 0) {	    
> >+      szURLorPath += 7;
> >+  
> >+      hFile = CreateFileW(szURLorPath, GENERIC_READ, 0, NULL, OPEN_EXISTING,
> >+				   0, NULL);
> >+      if (hFile == INVALID_HANDLE_VALUE)
> >+	  return E_UNEXPECTED;
> >+
> >+      dwFileSize = GetFileSize(hFile, NULL);
> >+      if (dwFileSize != INVALID_FILE_SIZE )
> >+      {
> >+	  hGlobal = GlobalAlloc(GMEM_FIXED,dwFileSize);
> >+	  if ( hGlobal)
> >+	  {
> >+	      bRead = ReadFile(hFile, hGlobal, dwFileSize, &dwBytesRead, NULL);
> >+	      if (!bRead)
> >+	      {
> >+		  GlobalFree(hGlobal);
> >+		  hGlobal = 0;
> >+	      }
> >+	  }
> >+      }
> >+      CloseHandle(hFile);      
> >+  } else {
> >+      HINTERNET hInternet;
> >+      BOOL res = FALSE;
> >+
> >+      hInternet = InternetOpenW(name, INTERNET_OPEN_TYPE_PRECONFIG, NULL,
> >+				NULL, 0);
> >+      if (hInternet) 
> >+      {
> >+	  HINTERNET hFile;
> >+	  hFile = InternetOpenUrlW(hInternet, szURLorPath, NULL, -1L, 
> >+			  INTERNET_FLAG_RESYNCHRONIZE, (DWORD_PTR)NULL);
> >+	  if (hFile)
> >+	  {	      
> >+	      DWORD total = 4096;
> >+	      DWORD nbRead;	      
> >+
> >+	      hGlobal = GlobalAlloc(GMEM_FIXED, 4096);
> >+	      if (hGlobal)
> >+	      {
> >+		  do {
> >+		      res = InternetReadFile(hFile, hGlobal, 4096, &nbRead);
> >+		      if (res && (nbRead>0))
> >+		      {
> >+			  HGLOBAL hNewGlobal;
> >+			  hNewGlobal = GlobalReAlloc(hGlobal, total+4096, 0);
> >+			  if (!hNewGlobal)
> >+			  {
> >+			      res = FALSE;
> >+			      break;
> >+			  }		      
> >+		      }
> >+		  } while (res && (nbRead>0));
> >+	      }
> >+	  }
> >+	  
> >+	  InternetCloseHandle(hInternet);
> >+      }
> >+      if (!res) 
> >+      {
> >+	  GlobalFree(hGlobal);	  
> >+      }
> >+  }
> >+
> >+  if (!hGlobal)
> >+      return E_UNEXPECTED;
> >+
> >+  hRes = CreateStreamOnHGlobal(hGlobal, TRUE, &stream);
> >+  if (FAILED(hRes)) 
> >+  {
> >+      if (stream != NULL) IStream_Release(stream);
> >  
> >
> 
> A valid stream will not be returned on failure, so no need for the extra 
> check here.
> 
> >+      GlobalFree(hGlobal);
> >+      return hRes;
> >+  }
> >+
> >+  hRes = CoCreateInstance(&CLSID_StdPicture, punkCaller, CLSCTX_INPROC_SERVER, 
> >+		   &IID_IPicture, (LPVOID*)&ipicture);
> >+  if (hRes != S_OK) {
> >  
> >
> 
> Lack of cleanup code here.
> 
> >+       return hRes;
> >+  }
> >+  
> >+  hRes = IPicture_QueryInterface(ipicture, &IID_IPersistStream, (LPVOID*)&pStream);
> >+  if (hRes) {
> >+      IPicture_Release(ipicture);
> >  
> >
> 
> And here.
> 
> >+      return hRes;
> >+  }
> >+
> >+  IPersistStream_Load(pStream, stream);
> >  
> >
> 
> You should probably check the return value from this function as it is 
> kinda vital to the function you are implementing.
> 
> >+  IPersistStream_Release(pStream);
> >+  IStream_Release(stream);
> >+  hRes = IPicture_QueryInterface(ipicture,riid,ppvRet);
> >+  if (hRes)
> >+      FIXME("Failed to get interface %s from IPicture.\n",debugstr_guid(riid));
> >+  
> >+  IPicture_Release(ipicture);
> >+  return hRes;
> > }
> > 
> > /*******************************************************************************
> >  
> >
> 
> >Index: wine/dlls/oleaut32/Makefile.in
> >===================================================================
> >RCS file: /home/wine/wine/dlls/oleaut32/Makefile.in,v
> >retrieving revision 1.57
> >diff -u -r1.57 Makefile.in
> >--- wine/dlls/oleaut32/Makefile.in	27 Oct 2004 00:47:53 -0000	1.57
> >+++ wine/dlls/oleaut32/Makefile.in	27 Feb 2005 10:52:08 -0000
> >@@ -4,7 +4,7 @@
> > SRCDIR    = @srcdir@
> > VPATH     = @srcdir@
> > MODULE    = oleaut32.dll
> >-IMPORTS   = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll
> >+IMPORTS   = ole32 rpcrt4 user32 gdi32 advapi32 kernel32 ntdll wininet
> > DELAYIMPORTS = comctl32
> > EXTRALIBS = $(LIBUNICODE) -luuid 
> >  
> >
> 
> I don't think oleaut32 should be importing from wininet for just the 
> implementation of OleLoadPicturePath. It surprises me that there is not 
> already an implementation of IStream for URLs that can be re-used. If 
> there is no alternative, I think we should just make wininet a delayed 
> import.
> 
> Rob
> 





More information about the wine-devel mailing list