Commit 1ffc47b5 authored by Rémi Bernon's avatar Rémi Bernon Committed by Alexandre Julliard

dmloader: Use a simpler file stream implementation.

parent 9e0487c4
...@@ -59,26 +59,9 @@ typedef struct IDirectMusicLoaderGenericStream IDirectMusicLoaderGenericStream; ...@@ -59,26 +59,9 @@ typedef struct IDirectMusicLoaderGenericStream IDirectMusicLoaderGenericStream;
*/ */
extern HRESULT create_dmloader(REFIID riid, void **ret_iface); extern HRESULT create_dmloader(REFIID riid, void **ret_iface);
extern HRESULT create_dmcontainer(REFIID riid, void **ret_iface); extern HRESULT create_dmcontainer(REFIID riid, void **ret_iface);
extern HRESULT DMUSIC_CreateDirectMusicLoaderFileStream(void **ppobj);
extern HRESULT DMUSIC_CreateDirectMusicLoaderResourceStream(void **ppobj); extern HRESULT DMUSIC_CreateDirectMusicLoaderResourceStream(void **ppobj);
/***************************************************************************** /*****************************************************************************
* IDirectMusicLoaderFileStream implementation structure
*/
struct IDirectMusicLoaderFileStream {
/* VTABLEs */
const IStreamVtbl *StreamVtbl;
/* reference counter */
LONG dwRef;
/* file */
WCHAR wzFileName[MAX_PATH]; /* for clone */
HANDLE hFile;
};
/* Custom: */
extern HRESULT WINAPI IDirectMusicLoaderFileStream_Attach(LPSTREAM iface, LPCWSTR wzFile);
/*****************************************************************************
* IDirectMusicLoaderResourceStream implementation structure * IDirectMusicLoaderResourceStream implementation structure
*/ */
struct IDirectMusicLoaderResourceStream { struct IDirectMusicLoaderResourceStream {
...@@ -98,6 +81,7 @@ extern HRESULT WINAPI IDirectMusicLoaderResourceStream_Attach(LPSTREAM iface, LP ...@@ -98,6 +81,7 @@ extern HRESULT WINAPI IDirectMusicLoaderResourceStream_Attach(LPSTREAM iface, LP
LONGLONG llMemLength, LONGLONG llPos); LONGLONG llMemLength, LONGLONG llPos);
extern HRESULT loader_stream_create(IDirectMusicLoader *loader, IStream *stream, IStream **ret_iface); extern HRESULT loader_stream_create(IDirectMusicLoader *loader, IStream *stream, IStream **ret_iface);
extern HRESULT file_stream_create(const WCHAR *path, IStream **ret_iface);
#include "debug.h" #include "debug.h"
......
...@@ -305,40 +305,29 @@ static HRESULT WINAPI loader_GetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDE ...@@ -305,40 +305,29 @@ static HRESULT WINAPI loader_GetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDE
TRACE(": no cache/alias entry found for requested object\n"); TRACE(": no cache/alias entry found for requested object\n");
} }
if (pDesc->dwValidData & DMUS_OBJ_URL) { if (pDesc->dwValidData & DMUS_OBJ_URL)
TRACE(": loading from URLs not supported yet\n"); {
return DMUS_E_LOADER_FORMATNOTSUPPORTED; TRACE(": loading from URLs not supported yet\n");
} return DMUS_E_LOADER_FORMATNOTSUPPORTED;
else if (pDesc->dwValidData & DMUS_OBJ_FILENAME) { }
/* load object from file */ else if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
/* generate filename; if it's full path, don't add search {
directory path, otherwise do */ WCHAR file_name[MAX_PATH];
WCHAR wszFileName[MAX_PATH];
if (pDesc->dwValidData & DMUS_OBJ_FULLPATH)
if (pDesc->dwValidData & DMUS_OBJ_FULLPATH) { lstrcpyW(file_name, pDesc->wszFileName);
lstrcpyW(wszFileName, pDesc->wszFileName); else
} else { {
WCHAR *p; WCHAR *p;
get_search_path(This, &pDesc->guidClass, wszFileName); get_search_path(This, &pDesc->guidClass, file_name);
p = wszFileName + lstrlenW(wszFileName); p = file_name + lstrlenW(file_name);
if (p > wszFileName && p[-1] != '\\') *p++ = '\\'; if (p > file_name && p[-1] != '\\') *p++ = '\\';
lstrcpyW(p, pDesc->wszFileName); lstrcpyW(p, pDesc->wszFileName);
} }
TRACE(": loading from file (%s)\n", debugstr_w(wszFileName));
/* create stream and associate it with file */ TRACE(": loading from file (%s)\n", debugstr_w(file_name));
result = DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID*)&pStream); if (FAILED(hr = file_stream_create(file_name, &pStream))) return hr;
if (FAILED(result)) { }
ERR(": could not create file stream\n");
return result;
}
result = IDirectMusicLoaderFileStream_Attach(pStream, wszFileName);
if (FAILED(result))
{
ERR(": could not attach stream to file\n");
IStream_Release (pStream);
return result;
}
}
else if (pDesc->dwValidData & DMUS_OBJ_MEMORY) { else if (pDesc->dwValidData & DMUS_OBJ_MEMORY) {
/* load object from resource */ /* load object from resource */
TRACE(": loading from resource\n"); TRACE(": loading from resource\n");
...@@ -363,9 +352,8 @@ static HRESULT WINAPI loader_GetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDE ...@@ -363,9 +352,8 @@ static HRESULT WINAPI loader_GetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDE
} }
else else
{ {
/* nowhere to load from */
FIXME(": unknown/unsupported way of loading\n"); FIXME(": unknown/unsupported way of loading\n");
return DMUS_E_LOADER_NOFILENAME; /* test shows this is returned */ return DMUS_E_LOADER_NOFILENAME;
} }
if (FAILED(hr = loader_stream_create((IDirectMusicLoader *)iface, pStream, &loader_stream))) if (FAILED(hr = loader_stream_create((IDirectMusicLoader *)iface, pStream, &loader_stream)))
...@@ -459,36 +447,23 @@ static HRESULT WINAPI loader_SetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDE ...@@ -459,36 +447,23 @@ static HRESULT WINAPI loader_SetObject(IDirectMusicLoader8 *iface, DMUS_OBJECTDE
if (TRACE_ON(dmloader)) if (TRACE_ON(dmloader))
dump_DMUS_OBJECTDESC(pDesc); dump_DMUS_OBJECTDESC(pDesc);
/* create stream and load additional info from it */ if (pDesc->dwValidData & DMUS_OBJ_FILENAME)
if (pDesc->dwValidData & DMUS_OBJ_FILENAME) { {
/* generate filename; if it's full path, don't add search WCHAR file_name[MAX_PATH];
directory path, otherwise do */
WCHAR wszFileName[MAX_PATH];
if (pDesc->dwValidData & DMUS_OBJ_FULLPATH) { if (pDesc->dwValidData & DMUS_OBJ_FULLPATH)
lstrcpyW(wszFileName, pDesc->wszFileName); lstrcpyW(file_name, pDesc->wszFileName);
} else { else
WCHAR *p; {
get_search_path(This, &pDesc->guidClass, wszFileName); WCHAR *p;
p = wszFileName + lstrlenW(wszFileName); get_search_path(This, &pDesc->guidClass, file_name);
if (p > wszFileName && p[-1] != '\\') *p++ = '\\'; p = file_name + lstrlenW(file_name);
lstrcpyW(p, pDesc->wszFileName); if (p > file_name && p[-1] != '\\') *p++ = '\\';
} lstrcpyW(p, pDesc->wszFileName);
/* create stream */ }
hr = DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID*)&pStream);
if (FAILED(hr)) { if (FAILED(hr = file_stream_create(file_name, &pStream))) return hr;
ERR(": could not create file stream\n"); }
return DMUS_E_LOADER_FAILEDOPEN;
}
/* attach stream */
hr = IDirectMusicLoaderFileStream_Attach(pStream, wszFileName);
if (FAILED(hr))
{
ERR(": could not attach stream to file %s, make sure it exists\n", debugstr_w(wszFileName));
IStream_Release (pStream);
return DMUS_E_LOADER_FAILEDOPEN;
}
}
else if (pDesc->dwValidData & DMUS_OBJ_STREAM) else if (pDesc->dwValidData & DMUS_OBJ_STREAM)
{ {
pStream = pDesc->pStream; pStream = pDesc->pStream;
......
/* IDirectMusicLoaderFileStream /*
* IDirectMusicLoaderResourceStream
* IDirectMusicLoaderGenericStream
*
* Copyright (C) 2003-2004 Rok Mandeljc * Copyright (C) 2003-2004 Rok Mandeljc
* Copyright 2023 Rémi Bernon for CodeWeavers
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
...@@ -19,31 +17,6 @@ ...@@ -19,31 +17,6 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/ */
/* SIDE NOTES:
* After extensive testing and structure dumping I came to a conclusion that
* DirectMusic as in present state implements three types of streams:
* 1. IDirectMusicLoaderFileStream: stream that was most obvious, since
* it's used for loading from files; it is sort of wrapper around
* CreateFile, ReadFile, WriteFile and SetFilePointer and it supports
* both read and write
* 2. IDirectMusicLoaderResourceStream: a stream that had to exist, since
* according to MSDN, IDirectMusicLoader supports loading from resource
* as well; in this case, data is represented as a big chunk of bytes,
* from which we "read" (copy) data and keep the trace of our position;
* it supports read only
* 3. IDirectMusicLoaderGenericStream: this one was the most problematic,
* since I thought it was URL-related; besides, there's no obvious need
* for it, since input streams can simply be cloned, lest loading from
* stream is requested; but if one really thinks about it, input stream
* could be none of 1. or 2.; in this case, a wrapper that offers
* IDirectMusicGetLoader interface would be nice, and this is what this
* stream is; as such, all functions are supported, as long as underlying
* ("low-level") stream supports them
*
* - Rok Mandeljc; 24. April, 2004
*/
#include "dmloader_private.h" #include "dmloader_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(dmloader); WINE_DEFAULT_DEBUG_CHANNEL(dmloader);
...@@ -284,216 +257,204 @@ HRESULT loader_stream_create(IDirectMusicLoader *loader, IStream *stream, ...@@ -284,216 +257,204 @@ HRESULT loader_stream_create(IDirectMusicLoader *loader, IStream *stream,
return S_OK; return S_OK;
} }
static ULONG WINAPI IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface); struct file_stream
static ULONG WINAPI IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface); {
IStream IStream_iface;
LONG ref;
/***************************************************************************** WCHAR path[MAX_PATH];
* IDirectMusicLoaderFileStream implementation HANDLE file;
*/ };
/* Custom : */
static void IDirectMusicLoaderFileStream_Detach (LPSTREAM iface) { static struct file_stream *file_stream_from_IStream(IStream *iface)
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); {
TRACE("(%p)\n", This); return CONTAINING_RECORD(iface, struct file_stream, IStream_iface);
if (This->hFile != INVALID_HANDLE_VALUE) CloseHandle(This->hFile);
This->wzFileName[0] = '\0';
} }
HRESULT WINAPI IDirectMusicLoaderFileStream_Attach(LPSTREAM iface, LPCWSTR wzFile) static HRESULT WINAPI file_stream_QueryInterface(IStream *iface, REFIID riid, void **ret_iface)
{ {
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); struct file_stream *This = file_stream_from_IStream(iface);
TRACE("(%p, %s)\n", This, debugstr_w(wzFile));
IDirectMusicLoaderFileStream_Detach (iface);
This->hFile = CreateFileW (wzFile, (GENERIC_READ | GENERIC_WRITE), (FILE_SHARE_READ | FILE_SHARE_WRITE), NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (This->hFile == INVALID_HANDLE_VALUE) {
WARN(": failed\n");
return DMUS_E_LOADER_FAILEDOPEN;
}
/* create IDirectMusicGetLoader */
lstrcpynW (This->wzFileName, wzFile, MAX_PATH);
TRACE(": succeeded\n");
return S_OK;
}
TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ret_iface);
/* IUnknown/IStream part: */ if (IsEqualGUID(riid, &IID_IUnknown)
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_QueryInterface (LPSTREAM iface, REFIID riid, void** ppobj) { || IsEqualGUID(riid, &IID_IStream))
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); {
IStream_AddRef(&This->IStream_iface);
TRACE("(%p, %s, %p)\n", This, debugstr_dmguid(riid), ppobj); *ret_iface = &This->IStream_iface;
if (IsEqualIID (riid, &IID_IUnknown) || return S_OK;
IsEqualIID (riid, &IID_IStream)) { }
*ppobj = &This->StreamVtbl;
IDirectMusicLoaderFileStream_IStream_AddRef ((LPSTREAM)&This->StreamVtbl);
return S_OK;
}
WARN(": not found\n"); WARN("(%p, %s, %p): not found\n", iface, debugstr_dmguid(riid), ret_iface);
return E_NOINTERFACE; *ret_iface = NULL;
return E_NOINTERFACE;
} }
static ULONG WINAPI IDirectMusicLoaderFileStream_IStream_AddRef (LPSTREAM iface) { static ULONG WINAPI file_stream_AddRef(IStream *iface)
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); {
TRACE("(%p): AddRef from %ld\n", This, This->dwRef); struct file_stream *This = file_stream_from_IStream(iface);
return InterlockedIncrement (&This->dwRef); ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p): new ref = %lu\n", This, ref);
return ref;
} }
static ULONG WINAPI IDirectMusicLoaderFileStream_IStream_Release (LPSTREAM iface) { static ULONG WINAPI file_stream_Release(IStream *iface)
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); {
struct file_stream *This = file_stream_from_IStream(iface);
DWORD dwRef = InterlockedDecrement (&This->dwRef); ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p): ReleaseRef to %ld\n", This, dwRef);
if (dwRef == 0) {
if (This->hFile)
IDirectMusicLoaderFileStream_Detach (iface);
free(This);
}
return dwRef;
}
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Read (LPSTREAM iface, void* pv, ULONG cb, ULONG* pcbRead) { TRACE("(%p): new ref = %lu\n", This, ref);
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface);
ULONG cbRead; if (!ref)
{
TRACE_(dmfileraw)("(%p, %p, %#lx, %p)\n", This, pv, cb, pcbRead); CloseHandle(This->file);
if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL; free(This);
if (pcbRead == NULL) pcbRead = &cbRead; }
if (!ReadFile (This->hFile, pv, cb, pcbRead, NULL) || *pcbRead != cb) return E_FAIL;
return ref;
TRACE_(dmfileraw)(": data (size = %#lx): %s\n", *pcbRead, debugstr_an(pv, *pcbRead));
return S_OK;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Seek (LPSTREAM iface, LARGE_INTEGER dlibMove, DWORD dwOrigin, ULARGE_INTEGER* plibNewPosition) { static HRESULT WINAPI file_stream_Read(IStream *iface, void *data, ULONG size, ULONG *ret_size)
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); {
LARGE_INTEGER liNewPos; struct file_stream *This = file_stream_from_IStream(iface);
DWORD dummy;
TRACE_(dmfileraw)("(%p, %s, %s, %p)\n", This, wine_dbgstr_longlong(dlibMove.QuadPart), resolve_STREAM_SEEK(dwOrigin), plibNewPosition);
if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL; TRACE("(%p, %p, %#lx, %p)\n", This, data, size, ret_size);
liNewPos.HighPart = dlibMove.HighPart; if (!ret_size) ret_size = &dummy;
liNewPos.LowPart = SetFilePointer (This->hFile, dlibMove.LowPart, &liNewPos.HighPart, dwOrigin); if (!ReadFile(This->file, data, size, ret_size, NULL)) return HRESULT_FROM_WIN32(GetLastError());
return *ret_size == size ? S_OK : S_FALSE;
}
if (liNewPos.LowPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR) return E_FAIL; static HRESULT WINAPI file_stream_Write(IStream *iface, const void *data, ULONG size, ULONG *ret_size)
if (plibNewPosition) plibNewPosition->QuadPart = liNewPos.QuadPart; {
struct file_stream *This = file_stream_from_IStream(iface);
return S_OK; FIXME("(%p): stub\n", This);
return E_NOTIMPL;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Clone (LPSTREAM iface, IStream** ppstm) { static HRESULT WINAPI file_stream_Seek(IStream *iface, LARGE_INTEGER offset, DWORD method, ULARGE_INTEGER *ret_offset)
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); {
LPSTREAM pOther = NULL; struct file_stream *This = file_stream_from_IStream(iface);
HRESULT result; DWORD position;
TRACE("(%p, %p)\n", iface, ppstm); TRACE("(%p, %I64d, %#lx, %p)\n", This, offset.QuadPart, method, ret_offset);
result = DMUSIC_CreateDirectMusicLoaderFileStream ((LPVOID*)&pOther);
if (FAILED(result)) return result;
if (This->hFile != INVALID_HANDLE_VALUE) {
ULARGE_INTEGER ullCurrentPosition;
result = IDirectMusicLoaderFileStream_Attach(pOther, This->wzFileName);
if (SUCCEEDED(result))
{
LARGE_INTEGER liZero;
liZero.QuadPart = 0;
result = IDirectMusicLoaderFileStream_IStream_Seek (iface, liZero, STREAM_SEEK_CUR, &ullCurrentPosition); /* get current position in current stream */
}
if (SUCCEEDED(result)) {
LARGE_INTEGER liNewPosition;
liNewPosition.QuadPart = ullCurrentPosition.QuadPart;
result = IDirectMusicLoaderFileStream_IStream_Seek (pOther, liNewPosition, STREAM_SEEK_SET, &ullCurrentPosition);
}
if (FAILED(result)) {
TRACE(": failed\n");
IDirectMusicLoaderFileStream_IStream_Release (pOther);
return result;
}
}
TRACE(": succeeded\n");
*ppstm = pOther;
return S_OK;
}
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Write (LPSTREAM iface, const void* pv, ULONG cb, ULONG* pcbWritten) { position = SetFilePointer(This->file, offset.u.LowPart, NULL, method);
ICOM_THIS_MULTI(IDirectMusicLoaderFileStream, StreamVtbl, iface); if (position == INVALID_SET_FILE_POINTER) return HRESULT_FROM_WIN32(GetLastError());
ULONG cbWrite; if (ret_offset) ret_offset->QuadPart = position;
TRACE_(dmfileraw)("(%p, %p, %#lx, %p)\n", This, pv, cb, pcbWritten);
if (This->hFile == INVALID_HANDLE_VALUE) return E_FAIL;
if (pcbWritten == NULL) pcbWritten = &cbWrite;
if (!WriteFile (This->hFile, pv, cb, pcbWritten, NULL) || *pcbWritten != cb) return E_FAIL;
TRACE_(dmfileraw)(": data (size = %#lx): %s\n", *pcbWritten, debugstr_an(pv, *pcbWritten));
return S_OK; return S_OK;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_SetSize (LPSTREAM iface, ULARGE_INTEGER libNewSize) { static HRESULT WINAPI file_stream_SetSize(IStream *iface, ULARGE_INTEGER size)
ERR(": should not be needed\n"); {
struct file_stream *This = file_stream_from_IStream(iface);
FIXME("(%p): stub\n", This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_CopyTo (LPSTREAM iface, IStream* pstm, ULARGE_INTEGER cb, ULARGE_INTEGER* pcbRead, ULARGE_INTEGER* pcbWritten) { static HRESULT WINAPI file_stream_CopyTo(IStream *iface, IStream *dest, ULARGE_INTEGER size,
ERR(": should not be needed\n"); ULARGE_INTEGER *read_size, ULARGE_INTEGER *write_size)
{
struct file_stream *This = file_stream_from_IStream(iface);
FIXME("(%p): stub\n", This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Commit (LPSTREAM iface, DWORD grfCommitFlags) { static HRESULT WINAPI file_stream_Commit(IStream *iface, DWORD flags)
ERR(": should not be needed\n"); {
struct file_stream *This = file_stream_from_IStream(iface);
FIXME("(%p): stub\n", This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Revert (LPSTREAM iface) { static HRESULT WINAPI file_stream_Revert(IStream *iface)
ERR(": should not be needed\n"); {
struct file_stream *This = file_stream_from_IStream(iface);
FIXME("(%p): stub\n", This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_LockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { static HRESULT WINAPI file_stream_LockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER size, DWORD type)
ERR(": should not be needed\n"); {
struct file_stream *This = file_stream_from_IStream(iface);
FIXME("(%p): stub\n", This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_UnlockRegion (LPSTREAM iface, ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD dwLockType) { static HRESULT WINAPI file_stream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset,
ERR(": should not be needed\n"); ULARGE_INTEGER size, DWORD type)
{
struct file_stream *This = file_stream_from_IStream(iface);
FIXME("(%p): stub\n", This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static HRESULT WINAPI IDirectMusicLoaderFileStream_IStream_Stat (LPSTREAM iface, STATSTG* pstatstg, DWORD grfStatFlag) { static HRESULT WINAPI file_stream_Stat(IStream *iface, STATSTG *stat, DWORD flags)
ERR(": should not be needed\n"); {
struct file_stream *This = file_stream_from_IStream(iface);
FIXME("(%p): stub\n", This);
return E_NOTIMPL; return E_NOTIMPL;
} }
static const IStreamVtbl DirectMusicLoaderFileStream_Stream_Vtbl = { static HRESULT WINAPI file_stream_Clone(IStream *iface, IStream **ret_iface)
IDirectMusicLoaderFileStream_IStream_QueryInterface, {
IDirectMusicLoaderFileStream_IStream_AddRef, struct file_stream *This = file_stream_from_IStream(iface);
IDirectMusicLoaderFileStream_IStream_Release, HRESULT hr;
IDirectMusicLoaderFileStream_IStream_Read,
IDirectMusicLoaderFileStream_IStream_Write,
IDirectMusicLoaderFileStream_IStream_Seek,
IDirectMusicLoaderFileStream_IStream_SetSize,
IDirectMusicLoaderFileStream_IStream_CopyTo,
IDirectMusicLoaderFileStream_IStream_Commit,
IDirectMusicLoaderFileStream_IStream_Revert,
IDirectMusicLoaderFileStream_IStream_LockRegion,
IDirectMusicLoaderFileStream_IStream_UnlockRegion,
IDirectMusicLoaderFileStream_IStream_Stat,
IDirectMusicLoaderFileStream_IStream_Clone
};
HRESULT DMUSIC_CreateDirectMusicLoaderFileStream (void** ppobj) { TRACE("(%p, %p)\n", This, ret_iface);
IDirectMusicLoaderFileStream *obj;
TRACE("(%p)\n", ppobj); if (SUCCEEDED(hr = file_stream_create(This->path, ret_iface)))
{
LARGE_INTEGER position = {0};
position.LowPart = SetFilePointer(This->file, 0, NULL, SEEK_CUR);
hr = IStream_Seek(*ret_iface, position, SEEK_SET, NULL);
}
*ppobj = NULL; return hr;
if (!(obj = calloc(1, sizeof(*obj)))) return E_OUTOFMEMORY; }
obj->StreamVtbl = &DirectMusicLoaderFileStream_Stream_Vtbl;
obj->dwRef = 0; /* will be inited with QueryInterface */
return IDirectMusicLoaderFileStream_IStream_QueryInterface ((LPSTREAM)&obj->StreamVtbl, &IID_IStream, ppobj); static const IStreamVtbl file_stream_vtbl =
{
file_stream_QueryInterface,
file_stream_AddRef,
file_stream_Release,
file_stream_Read,
file_stream_Write,
file_stream_Seek,
file_stream_SetSize,
file_stream_CopyTo,
file_stream_Commit,
file_stream_Revert,
file_stream_LockRegion,
file_stream_UnlockRegion,
file_stream_Stat,
file_stream_Clone,
};
HRESULT file_stream_create(const WCHAR *path, IStream **ret_iface)
{
struct file_stream *stream;
*ret_iface = NULL;
if (!(stream = calloc(1, sizeof(*stream)))) return E_OUTOFMEMORY;
stream->IStream_iface.lpVtbl = &file_stream_vtbl;
stream->ref = 1;
wcscpy(stream->path, path);
stream->file = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (stream->file == INVALID_HANDLE_VALUE)
{
free(stream);
return DMUS_E_LOADER_FAILEDOPEN;
}
*ret_iface = &stream->IStream_iface;
return S_OK;
} }
static ULONG WINAPI IDirectMusicLoaderResourceStream_IStream_AddRef (LPSTREAM iface);
/***************************************************************************** /*****************************************************************************
* IDirectMusicLoaderResourceStream implementation * IDirectMusicLoaderResourceStream implementation
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment