Skip to content
Snippets Groups Projects
Commit 9c894d1f authored by Juergen Schmied's avatar Juergen Schmied Committed by Alexandre Julliard
Browse files

IStream interface for file access.

parent cb782195
No related branches found
No related tags found
No related merge requests found
......@@ -14,6 +14,7 @@ C_SRCS = \
enumidlist.c \
folders.c \
iconcache.c \
memorystream.c \
pidl.c \
regstream.c \
shell32_main.c \
......
/*
* 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
};
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment