IStream interface for file access.
diff --git a/dlls/shell32/Makefile.in b/dlls/shell32/Makefile.in
index 82288a3..397a6ee 100644
--- a/dlls/shell32/Makefile.in
+++ b/dlls/shell32/Makefile.in
@@ -14,6 +14,7 @@
enumidlist.c \
folders.c \
iconcache.c \
+ memorystream.c \
pidl.c \
regstream.c \
shell32_main.c \
diff --git a/dlls/shell32/memorystream.c b/dlls/shell32/memorystream.c
new file mode 100644
index 0000000..443a2af
--- /dev/null
+++ b/dlls/shell32/memorystream.c
@@ -0,0 +1,268 @@
+/*
+ * this class implements a pure IStream object
+ * and can be used for many purposes
+ *
+ * the main reason for implementing this was
+ * a cleaner implementation of IShellLink which
+ * needs to be able to load lnk's from a IStream
+ * interface so it was obvious to capsule the file
+ * access in a IStream to.
+ */
+
+#include <string.h>
+
+#include "wine/obj_storage.h"
+#include "heap.h"
+#include "winerror.h"
+#include "debugtools.h"
+#include "shell32_main.h"
+
+DEFAULT_DEBUG_CHANNEL(shell)
+
+typedef struct
+{ ICOM_VTABLE(IStream) *lpvtst;
+ DWORD ref;
+ LPBYTE pImage;
+ HANDLE hMapping;
+ DWORD dwLength;
+ DWORD dwPos;
+} ISHFileStream;
+
+static ICOM_VTABLE(IStream) stvt;
+
+/**************************************************************************
+ * CreateStreamOnFile()
+ *
+ * similar to CreateStreamOnHGlobal
+ */
+HRESULT CreateStreamOnFile (LPCSTR pszFilename, IStream ** ppstm)
+{
+ ISHFileStream* fstr;
+ OFSTRUCT ofs;
+ HFILE hFile = OpenFile( pszFilename, &ofs, OF_READ );
+ HRESULT ret = E_FAIL;
+
+ fstr = (ISHFileStream*)HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(ISHFileStream));
+ fstr->lpvtst=&stvt;
+ fstr->ref = 1;
+ fstr->dwLength = GetFileSize (hFile, NULL);
+
+ shell32_ObjCount++;
+
+ if (!(fstr->hMapping = CreateFileMappingA(hFile,NULL,PAGE_READONLY|SEC_COMMIT,0,0,NULL)))
+ {
+ WARN("failed to create filemap.\n");
+ goto end_2;
+ }
+
+ if (!(fstr->pImage = MapViewOfFile(fstr->hMapping,FILE_MAP_READ,0,0,0)))
+ {
+ WARN("failed to mmap filemap.\n");
+ goto end_3;
+ }
+
+ ret = S_OK;
+ goto end_1;
+
+end_3: CloseHandle(fstr->hMapping);
+end_2: HeapFree(GetProcessHeap(), 0, fstr);
+ fstr = NULL;
+
+end_1: _lclose(hFile);
+ (*ppstm) = (IStream*)fstr;
+ return ret;
+}
+
+/**************************************************************************
+* IStream_fnQueryInterface
+*/
+static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface, REFIID riid, LPVOID *ppvObj)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ char xriid[50];
+ WINE_StringFromCLSID((LPCLSID)riid,xriid);
+
+ TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,xriid,ppvObj);
+
+ *ppvObj = NULL;
+
+ if(IsEqualIID(riid, &IID_IUnknown) ||
+ IsEqualIID(riid, &IID_IStream))
+ {
+ *ppvObj = This;
+ }
+
+ if(*ppvObj)
+ {
+ IStream_AddRef((IStream*)*ppvObj);
+ TRACE("-- Interface: (%p)->(%p)\n",ppvObj,*ppvObj);
+ return S_OK;
+ }
+ TRACE("-- Interface: E_NOINTERFACE\n");
+ return E_NOINTERFACE;
+}
+
+/**************************************************************************
+* IStream_fnAddRef
+*/
+static ULONG WINAPI IStream_fnAddRef(IStream *iface)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)->(count=%lu)\n",This, This->ref);
+
+ shell32_ObjCount++;
+ return ++(This->ref);
+}
+
+/**************************************************************************
+* IStream_fnRelease
+*/
+static ULONG WINAPI IStream_fnRelease(IStream *iface)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)->()\n",This);
+
+ shell32_ObjCount--;
+
+ if (!--(This->ref))
+ { TRACE(" destroying SHFileStream (%p)\n",This);
+
+ UnmapViewOfFile(This->pImage);
+ CloseHandle(This->hMapping);
+
+ HeapFree(GetProcessHeap(),0,This);
+ return 0;
+ }
+ return This->ref;
+}
+
+static HRESULT WINAPI IStream_fnRead (IStream * iface, void* pv, ULONG cb, ULONG* pcbRead)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ DWORD dwBytesToRead, dwBytesLeft;
+
+ TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
+
+ if ( !pv )
+ return STG_E_INVALIDPOINTER;
+
+ dwBytesLeft = This->dwLength - This->dwPos;
+
+ if ( 0 >= dwBytesLeft ) /* end of buffer */
+ return S_FALSE;
+
+ dwBytesToRead = ( cb > dwBytesLeft) ? dwBytesLeft : cb;
+
+ memmove ( pv, (This->pImage) + (This->dwPos), dwBytesToRead);
+
+ This->dwPos += dwBytesToRead; /* adjust pointer */
+
+ if (pcbRead)
+ *pcbRead = dwBytesToRead;
+
+ return S_OK;
+}
+static HRESULT WINAPI IStream_fnWrite (IStream * iface, const void* pv, ULONG cb, ULONG* pcbWritten)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnSeek (IStream * iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnSetSize (IStream * iface, ULARGE_INTEGER libNewSize)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnCopyTo (IStream * iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnCommit (IStream * iface, DWORD grfCommitFlags)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnRevert (IStream * iface)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnLockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnStat (IStream * iface, STATSTG* pstatstg, DWORD grfStatFlag)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+static HRESULT WINAPI IStream_fnClone (IStream * iface, IStream** ppstm)
+{
+ ICOM_THIS(ISHFileStream, iface);
+
+ TRACE("(%p)\n",This);
+
+ return E_NOTIMPL;
+}
+
+static struct ICOM_VTABLE(IStream) stvt =
+{
+ ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
+ IStream_fnQueryInterface,
+ IStream_fnAddRef,
+ IStream_fnRelease,
+ IStream_fnRead,
+ IStream_fnWrite,
+ IStream_fnSeek,
+ IStream_fnSetSize,
+ IStream_fnCopyTo,
+ IStream_fnCommit,
+ IStream_fnRevert,
+ IStream_fnLockRegion,
+ IStream_fnUnlockRegion,
+ IStream_fnStat,
+ IStream_fnClone
+
+};