mirror of
https://github.com/reactos/reactos.git
synced 2024-12-30 19:14:31 +00:00
Alexandre Julliard <julliard@winehq.org>
- Added rules for building import libraries in the individual dll makefiles, and added support for building a .def.a static import library too. Troy Rollo <wine@troy.rollo.name> - Implement URLMonikerImpl_BindToStorage. - Correct bug truncating downloaded files to 4096 bytes. Jacek Caban <jack@itma.pwr.wroc.pl> - Separated IBinding and IMoniker interfaces. Mike McCormack <mike@codeweavers.com> - Add the missing interface method PromptAction to IInternetZoneManager. - Stub implementation for GetSoftwareUpdateInfo. Francois Gouget <fgouget@free.fr> - Update win32.api to match the current sources. - Declare CoGetClassObjectFromURL() in urlmon.h. Christian Costa <titan.costa@wanadoo.fr> - Added stub implementation for CoGetClassObjectFromURL. svn path=/trunk/; revision=15625
This commit is contained in:
parent
d07eefd752
commit
9259eba707
8 changed files with 926 additions and 203 deletions
|
@ -3,6 +3,7 @@ TOPOBJDIR = ../..
|
||||||
SRCDIR = @srcdir@
|
SRCDIR = @srcdir@
|
||||||
VPATH = @srcdir@
|
VPATH = @srcdir@
|
||||||
MODULE = urlmon.dll
|
MODULE = urlmon.dll
|
||||||
|
IMPORTLIB = liburlmon.$(IMPLIBEXT)
|
||||||
IMPORTS = cabinet ole32 shlwapi wininet user32 advapi32 kernel32 ntdll
|
IMPORTS = cabinet ole32 shlwapi wininet user32 advapi32 kernel32 ntdll
|
||||||
EXTRALIBS = -luuid
|
EXTRALIBS = -luuid
|
||||||
|
|
||||||
|
@ -10,6 +11,7 @@ C_SRCS = \
|
||||||
regsvr.c \
|
regsvr.c \
|
||||||
sec_mgr.c \
|
sec_mgr.c \
|
||||||
umon.c \
|
umon.c \
|
||||||
|
umstream.c \
|
||||||
urlmon_main.c
|
urlmon_main.c
|
||||||
|
|
||||||
SUBDIRS = tests
|
SUBDIRS = tests
|
||||||
|
|
|
@ -352,6 +352,21 @@ static HRESULT WINAPI ZoneMgrImpl_SetZoneActionPolicy(IInternetZoneManager* ifac
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/********************************************************************
|
||||||
|
* IInternetZoneManager_PromptAction
|
||||||
|
*/
|
||||||
|
static HRESULT WINAPI ZoneMgrImpl_PromptAction(IInternetZoneManager* iface,
|
||||||
|
DWORD dwAction,
|
||||||
|
HWND hwndParent,
|
||||||
|
LPCWSTR pwszUrl,
|
||||||
|
LPCWSTR pwszText,
|
||||||
|
DWORD dwPromptFlags)
|
||||||
|
{
|
||||||
|
FIXME("%p %08lx %p %s %s %08lx\n", iface, dwAction, hwndParent,
|
||||||
|
debugstr_w(pwszUrl), debugstr_w(pwszText), dwPromptFlags );
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* IInternetZoneManager_LogAction
|
* IInternetZoneManager_LogAction
|
||||||
*/
|
*/
|
||||||
|
@ -425,12 +440,14 @@ static IInternetZoneManagerVtbl ZoneMgrImplVtbl = {
|
||||||
ZoneMgrImpl_SetZoneCustomPolicy,
|
ZoneMgrImpl_SetZoneCustomPolicy,
|
||||||
ZoneMgrImpl_GetZoneActionPolicy,
|
ZoneMgrImpl_GetZoneActionPolicy,
|
||||||
ZoneMgrImpl_SetZoneActionPolicy,
|
ZoneMgrImpl_SetZoneActionPolicy,
|
||||||
|
ZoneMgrImpl_PromptAction,
|
||||||
ZoneMgrImpl_LogAction,
|
ZoneMgrImpl_LogAction,
|
||||||
ZoneMgrImpl_CreateZoneEnumerator,
|
ZoneMgrImpl_CreateZoneEnumerator,
|
||||||
ZoneMgrImpl_GetZoneAt,
|
ZoneMgrImpl_GetZoneAt,
|
||||||
ZoneMgrImpl_DestroyZoneEnumerator,
|
ZoneMgrImpl_DestroyZoneEnumerator,
|
||||||
ZoneMgrImpl_CopyTemplatePoliciesToZone,
|
ZoneMgrImpl_CopyTemplatePoliciesToZone,
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
|
HRESULT ZoneMgrImpl_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
|
||||||
{
|
{
|
||||||
ZoneMgrImpl* ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ZoneMgrImpl));
|
ZoneMgrImpl* ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ZoneMgrImpl));
|
||||||
|
|
|
@ -48,19 +48,252 @@ static const WCHAR BSCBHolder[] = { '_','B','S','C','B','_','H','o','l','d','e',
|
||||||
|
|
||||||
/*static BOOL registered_wndclass = FALSE;*/
|
/*static BOOL registered_wndclass = FALSE;*/
|
||||||
|
|
||||||
/* filemoniker data structure */
|
typedef struct {
|
||||||
typedef struct URLMonikerImpl{
|
IBindingVtbl *lpVtbl;
|
||||||
|
|
||||||
IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/
|
ULONG ref;
|
||||||
IBindingVtbl* lpvtbl2; /* VTable to IBinding interface */
|
|
||||||
|
|
||||||
ULONG ref; /* reference counter for this object */
|
LPWSTR URLName;
|
||||||
|
|
||||||
LPOLESTR URLName; /* URL string identified by this URLmoniker */
|
|
||||||
|
|
||||||
HWND hwndCallback;
|
HWND hwndCallback;
|
||||||
IBindCtx *pBC;
|
IBindCtx *pBC;
|
||||||
HINTERNET hinternet, hconnect, hrequest;
|
HINTERNET hinternet, hconnect, hrequest;
|
||||||
|
HANDLE hCacheFile;
|
||||||
|
IUMCacheStream *pstrCache;
|
||||||
|
IBindStatusCallback *pbscb;
|
||||||
|
DWORD total_read, expected_size;
|
||||||
|
} Binding;
|
||||||
|
|
||||||
|
static HRESULT WINAPI Binding_QueryInterface(IBinding* iface, REFIID riid, void **ppvObject)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%s,%p)\n", This, debugstr_guid(riid), ppvObject);
|
||||||
|
|
||||||
|
if((This == NULL) || (ppvObject == NULL))
|
||||||
|
return E_INVALIDARG;
|
||||||
|
|
||||||
|
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IBinding, riid)) {
|
||||||
|
*ppvObject = iface;
|
||||||
|
IBinding_AddRef(iface);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
*ppvObject = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Binding_AddRef(IBinding* iface)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
ULONG ref = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%ld\n", This, ref);
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI Binding_Release(IBinding* iface)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p) ref=%ld\n",This, ref);
|
||||||
|
|
||||||
|
if(!ref) {
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->URLName);
|
||||||
|
if (This->hCacheFile)
|
||||||
|
CloseHandle(This->hCacheFile);
|
||||||
|
if (This->pstrCache)
|
||||||
|
{
|
||||||
|
UMCloseCacheFileStream(This->pstrCache);
|
||||||
|
IStream_Release((IStream *)This->pstrCache);
|
||||||
|
}
|
||||||
|
if (This->pbscb)
|
||||||
|
IBindStatusCallback_Release(This->pbscb);
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, This);
|
||||||
|
|
||||||
|
URLMON_UnlockModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Binding_Abort(IBinding* iface)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
|
||||||
|
FIXME("(%p): stub\n", This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Binding_GetBindResult(IBinding* iface, CLSID* pclsidProtocol, DWORD* pdwResult, LPOLESTR* pszResult, DWORD* pdwReserved)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
|
||||||
|
FIXME("(%p)->(%p, %p, %p, %p): stub\n", This, pclsidProtocol, pdwResult, pszResult, pdwReserved);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Binding_GetPriority(IBinding* iface, LONG* pnPriority)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
|
||||||
|
FIXME("(%p)->(%p): stub\n", This, pnPriority);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Binding_Resume(IBinding* iface)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
|
||||||
|
FIXME("(%p): stub\n", This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Binding_SetPriority(IBinding* iface, LONG nPriority)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
|
||||||
|
FIXME("(%p)->(%ld): stub\n", This, nPriority);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI Binding_Suspend(IBinding* iface)
|
||||||
|
{
|
||||||
|
Binding *This = (Binding*)iface;
|
||||||
|
|
||||||
|
FIXME("(%p): stub\n", This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Binding_CloseCacheDownload(Binding *This)
|
||||||
|
{
|
||||||
|
CloseHandle(This->hCacheFile);
|
||||||
|
This->hCacheFile = 0;
|
||||||
|
UMCloseCacheFileStream(This->pstrCache);
|
||||||
|
IStream_Release((IStream *)This->pstrCache);
|
||||||
|
This->pstrCache = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT Binding_MoreCacheData(Binding *This, char *buf, DWORD dwBytes)
|
||||||
|
{
|
||||||
|
DWORD written;
|
||||||
|
|
||||||
|
if (WriteFile(This->hCacheFile, buf, dwBytes, &written, NULL) && written == dwBytes)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
This->total_read += written;
|
||||||
|
hr = IBindStatusCallback_OnProgress(This->pbscb,
|
||||||
|
This->total_read + written,
|
||||||
|
This->expected_size,
|
||||||
|
(This->total_read == written) ?
|
||||||
|
BINDSTATUS_BEGINDOWNLOADDATA :
|
||||||
|
BINDSTATUS_DOWNLOADINGDATA,
|
||||||
|
NULL);
|
||||||
|
if (!hr)
|
||||||
|
{
|
||||||
|
STGMEDIUM stg;
|
||||||
|
FORMATETC fmt;
|
||||||
|
|
||||||
|
fmt.cfFormat = 0;
|
||||||
|
fmt.ptd = NULL;
|
||||||
|
fmt.dwAspect = 0;
|
||||||
|
fmt.lindex = -1;
|
||||||
|
fmt.tymed = TYMED_ISTREAM;
|
||||||
|
|
||||||
|
stg.tymed = TYMED_ISTREAM;
|
||||||
|
stg.u.pstm = (IStream *)This->pstrCache;
|
||||||
|
stg.pUnkForRelease = NULL;
|
||||||
|
|
||||||
|
hr = IBindStatusCallback_OnDataAvailable(This->pbscb,
|
||||||
|
(This->total_read == written) ?
|
||||||
|
BSCF_FIRSTDATANOTIFICATION :
|
||||||
|
BSCF_INTERMEDIATEDATANOTIFICATION,
|
||||||
|
This->total_read + written,
|
||||||
|
&fmt,
|
||||||
|
&stg);
|
||||||
|
}
|
||||||
|
if (written < dwBytes)
|
||||||
|
return STG_E_MEDIUMFULL;
|
||||||
|
else
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Binding_FinishedDownload(Binding *This, HRESULT hr)
|
||||||
|
{
|
||||||
|
STGMEDIUM stg;
|
||||||
|
FORMATETC fmt;
|
||||||
|
|
||||||
|
fmt.ptd = NULL;
|
||||||
|
fmt.dwAspect = 0;
|
||||||
|
fmt.lindex = -1;
|
||||||
|
fmt.tymed = TYMED_ISTREAM;
|
||||||
|
|
||||||
|
stg.tymed = TYMED_ISTREAM;
|
||||||
|
stg.u.pstm = (IStream *)This->pstrCache;
|
||||||
|
stg.pUnkForRelease = NULL;
|
||||||
|
|
||||||
|
IBindStatusCallback_OnProgress(This->pbscb, This->total_read, This->expected_size, BINDSTATUS_ENDDOWNLOADDATA, NULL);
|
||||||
|
IBindStatusCallback_OnDataAvailable(This->pbscb, BSCF_LASTDATANOTIFICATION, This->total_read, &fmt, &stg);
|
||||||
|
if (hr)
|
||||||
|
{
|
||||||
|
WCHAR *pwchError = 0;
|
||||||
|
|
||||||
|
FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER,
|
||||||
|
NULL, (DWORD) hr,
|
||||||
|
0, (LPWSTR) &pwchError,
|
||||||
|
0, NULL);
|
||||||
|
if (!pwchError)
|
||||||
|
{
|
||||||
|
static WCHAR achFormat[] = { '%', '0', '8', 'x', 0 };
|
||||||
|
|
||||||
|
pwchError =(WCHAR *) LocalAlloc(LMEM_FIXED, sizeof(WCHAR) * 9);
|
||||||
|
wsprintfW(pwchError, achFormat, hr);
|
||||||
|
}
|
||||||
|
IBindStatusCallback_OnStopBinding(This->pbscb, hr, pwchError);
|
||||||
|
LocalFree(pwchError);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
IBindStatusCallback_OnStopBinding(This->pbscb, hr, NULL);
|
||||||
|
}
|
||||||
|
IBindStatusCallback_Release(This->pbscb);
|
||||||
|
This->pbscb = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IBindingVtbl BindingVtbl =
|
||||||
|
{
|
||||||
|
Binding_QueryInterface,
|
||||||
|
Binding_AddRef,
|
||||||
|
Binding_Release,
|
||||||
|
Binding_Abort,
|
||||||
|
Binding_Suspend,
|
||||||
|
Binding_Resume,
|
||||||
|
Binding_SetPriority,
|
||||||
|
Binding_GetPriority,
|
||||||
|
Binding_GetBindResult
|
||||||
|
};
|
||||||
|
|
||||||
|
/* filemoniker data structure */
|
||||||
|
typedef struct {
|
||||||
|
|
||||||
|
IMonikerVtbl* lpvtbl; /* VTable relative to the IMoniker interface.*/
|
||||||
|
|
||||||
|
ULONG ref; /* reference counter for this object */
|
||||||
|
|
||||||
|
LPOLESTR URLName; /* URL string identified by this URLmoniker */
|
||||||
} URLMonikerImpl;
|
} URLMonikerImpl;
|
||||||
|
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
|
@ -133,6 +366,7 @@ static ULONG WINAPI URLMonikerImpl_Release(IMoniker* iface)
|
||||||
return refCount;
|
return refCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* URLMoniker_GetClassID
|
* URLMoniker_GetClassID
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -310,6 +544,8 @@ static void CALLBACK URLMON_InternetCallback(HINTERNET hinet, /*DWORD_PTR*/ DWOR
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* URLMoniker_BindToStorage
|
* URLMoniker_BindToStorage
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
@ -321,12 +557,12 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface,
|
||||||
{
|
{
|
||||||
URLMonikerImpl *This = (URLMonikerImpl *)iface;
|
URLMonikerImpl *This = (URLMonikerImpl *)iface;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
IBindStatusCallback *pbscb;
|
|
||||||
BINDINFO bi;
|
BINDINFO bi;
|
||||||
DWORD bindf;
|
DWORD bindf;
|
||||||
IStream *pstr;
|
WCHAR szFileName[MAX_PATH + 1];
|
||||||
|
Binding *bind;
|
||||||
|
int len;
|
||||||
|
|
||||||
FIXME("(%p)->(%p,%p,%s,%p): stub\n",This,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);
|
|
||||||
if(pmkToLeft) {
|
if(pmkToLeft) {
|
||||||
FIXME("pmkToLeft != NULL\n");
|
FIXME("pmkToLeft != NULL\n");
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
|
@ -336,36 +572,55 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface,
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME This is a bad hack (tm). We should clearly download to a temporary file.
|
bind = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Binding));
|
||||||
We also need to implement IStream ourselves so that IStream_Read can return
|
bind->lpVtbl = &BindingVtbl;
|
||||||
E_PENDING */
|
bind->ref = 1;
|
||||||
|
URLMON_LockModule();
|
||||||
|
|
||||||
hres = CreateStreamOnHGlobal(0, TRUE, &pstr);
|
len = lstrlenW(This->URLName)+1;
|
||||||
|
bind->URLName = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
|
||||||
|
memcpy(bind->URLName, This->URLName, len*sizeof(WCHAR));
|
||||||
|
|
||||||
|
hres = UMCreateStreamOnCacheFile(bind->URLName, 0, szFileName, &bind->hCacheFile, &bind->pstrCache);
|
||||||
|
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
TRACE("Created dummy stream...\n");
|
TRACE("Created stream...\n");
|
||||||
|
|
||||||
hres = IBindCtx_GetObjectParam(pbc, (LPOLESTR)BSCBHolder, (IUnknown**)&pbscb);
|
*ppvObject = (void *) bind->pstrCache;
|
||||||
|
IStream_AddRef((IStream *) bind->pstrCache);
|
||||||
|
|
||||||
|
hres = IBindCtx_GetObjectParam(pbc, (LPOLESTR)BSCBHolder, (IUnknown**)&bind->pbscb);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
TRACE("Got IBindStatusCallback...\n");
|
TRACE("Got IBindStatusCallback...\n");
|
||||||
|
|
||||||
memset(&bi, 0, sizeof(bi));
|
memset(&bi, 0, sizeof(bi));
|
||||||
bi.cbSize = sizeof(bi);
|
bi.cbSize = sizeof(bi);
|
||||||
bindf = 0;
|
bindf = 0;
|
||||||
hres = IBindStatusCallback_GetBindInfo(pbscb, &bindf, &bi);
|
hres = IBindStatusCallback_GetBindInfo(bind->pbscb, &bindf, &bi);
|
||||||
if(SUCCEEDED(hres)) {
|
if(SUCCEEDED(hres)) {
|
||||||
|
WCHAR *urlcopy, *tmpwc;
|
||||||
URL_COMPONENTSW url;
|
URL_COMPONENTSW url;
|
||||||
WCHAR *host, *path;
|
WCHAR *host, *path, *user, *pass;
|
||||||
DWORD len, lensz = sizeof(len), total_read = 0;
|
DWORD lensz = sizeof(bind->expected_size);
|
||||||
LARGE_INTEGER last_read_pos;
|
DWORD dwService = 0;
|
||||||
FORMATETC fmt;
|
BOOL bSuccess;
|
||||||
STGMEDIUM stg;
|
|
||||||
|
|
||||||
TRACE("got bindinfo. bindf = %08lx extrainfo = %s bindinfof = %08lx bindverb = %08lx iid %s\n",
|
TRACE("got bindinfo. bindf = %08lx extrainfo = %s bindinfof = %08lx bindverb = %08lx iid %s\n",
|
||||||
bindf, debugstr_w(bi.szExtraInfo), bi.grfBindInfoF, bi.dwBindVerb, debugstr_guid(&bi.iid));
|
bindf, debugstr_w(bi.szExtraInfo), bi.grfBindInfoF, bi.dwBindVerb, debugstr_guid(&bi.iid));
|
||||||
hres = IBindStatusCallback_OnStartBinding(pbscb, 0, (IBinding*)&This->lpvtbl2);
|
hres = IBindStatusCallback_OnStartBinding(bind->pbscb, 0, (IBinding*)bind);
|
||||||
TRACE("OnStartBinding rets %08lx\n", hres);
|
TRACE("OnStartBinding rets %08lx\n", hres);
|
||||||
|
|
||||||
|
/* This class will accept URLs with the backslash in them. But InternetCrackURL will not - it
|
||||||
|
* requires forward slashes (this is the behaviour of Microsoft's INETAPI). So we need to make
|
||||||
|
* a copy of the URL here and change the backslash to a forward slash everywhere it appears -
|
||||||
|
* but only before any '#' or '?', after which backslash should be left alone.
|
||||||
|
*/
|
||||||
|
urlcopy = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (lstrlenW(bind->URLName) + 1));
|
||||||
|
lstrcpyW(urlcopy, bind->URLName);
|
||||||
|
for (tmpwc = urlcopy; *tmpwc && *tmpwc != '#' && *tmpwc != '?'; ++tmpwc)
|
||||||
|
if (*tmpwc == '\\')
|
||||||
|
*tmpwc = '/';
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if(!registered_wndclass) {
|
if(!registered_wndclass) {
|
||||||
WNDCLASSA urlmon_wndclass = {0, URLMON_WndProc,0, 0, URLMON_hInstance, 0, 0, 0, NULL, "URLMON_Callback_Window_Class"};
|
WNDCLASSA urlmon_wndclass = {0, URLMON_WndProc,0, 0, URLMON_hInstance, 0, 0, 0, NULL, "URLMON_Callback_Window_Class"};
|
||||||
|
@ -377,81 +632,228 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface,
|
||||||
URLMON_hInstance, NULL);
|
URLMON_hInstance, NULL);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
bind->expected_size = 0;
|
||||||
|
bind->total_read = 0;
|
||||||
|
|
||||||
memset(&url, 0, sizeof(url));
|
memset(&url, 0, sizeof(url));
|
||||||
url.dwStructSize = sizeof(url);
|
url.dwStructSize = sizeof(url);
|
||||||
url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = 1;
|
url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1;
|
||||||
InternetCrackUrlW(This->URLName, 0, 0, &url);
|
InternetCrackUrlW(urlcopy, 0, 0, &url);
|
||||||
host = HeapAlloc(GetProcessHeap(), 0, (url.dwHostNameLength + 1) * sizeof(WCHAR));
|
host = HeapAlloc(GetProcessHeap(), 0, (url.dwHostNameLength + 1) * sizeof(WCHAR));
|
||||||
memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
|
memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
|
||||||
host[url.dwHostNameLength] = '\0';
|
host[url.dwHostNameLength] = '\0';
|
||||||
path = HeapAlloc(GetProcessHeap(), 0, (url.dwUrlPathLength + 1) * sizeof(WCHAR));
|
path = HeapAlloc(GetProcessHeap(), 0, (url.dwUrlPathLength + 1) * sizeof(WCHAR));
|
||||||
memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR));
|
memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR));
|
||||||
path[url.dwUrlPathLength] = '\0';
|
path[url.dwUrlPathLength] = '\0';
|
||||||
|
if (url.dwUserNameLength)
|
||||||
|
{
|
||||||
|
user = HeapAlloc(GetProcessHeap(), 0, ((url.dwUserNameLength + 1) * sizeof(WCHAR)));
|
||||||
|
memcpy(user, url.lpszUserName, url.dwUserNameLength * sizeof(WCHAR));
|
||||||
|
user[url.dwUserNameLength] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
user = 0;
|
||||||
|
}
|
||||||
|
if (url.dwPasswordLength)
|
||||||
|
{
|
||||||
|
pass = HeapAlloc(GetProcessHeap(), 0, ((url.dwPasswordLength + 1) * sizeof(WCHAR)));
|
||||||
|
memcpy(pass, url.lpszPassword, url.dwPasswordLength * sizeof(WCHAR));
|
||||||
|
pass[url.dwPasswordLength] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pass = 0;
|
||||||
|
}
|
||||||
|
|
||||||
This->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0 /*INTERNET_FLAG_ASYNC*/);
|
switch ((DWORD) url.nScheme)
|
||||||
/* InternetSetStatusCallback(This->hinternet, URLMON_InternetCallback);*/
|
{
|
||||||
|
case INTERNET_SCHEME_FTP:
|
||||||
|
case INTERNET_SCHEME_GOPHER:
|
||||||
|
case INTERNET_SCHEME_HTTP:
|
||||||
|
case INTERNET_SCHEME_HTTPS:
|
||||||
|
|
||||||
This->hconnect = InternetConnectW(This->hinternet, host, INTERNET_DEFAULT_HTTP_PORT, NULL, NULL,
|
bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0 /*INTERNET_FLAG_ASYNC*/);
|
||||||
INTERNET_SERVICE_HTTP, 0, (DWORD)This);
|
/* InternetSetStatusCallback(bind->hinternet, URLMON_InternetCallback);*/
|
||||||
This->hrequest = HttpOpenRequestW(This->hconnect, NULL, path, NULL, NULL, NULL, 0, (DWORD)This);
|
if (!bind->hinternet)
|
||||||
|
{
|
||||||
|
hres = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, 0x22, NULL);
|
switch ((DWORD) url.nScheme)
|
||||||
hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
|
{
|
||||||
hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, BINDSTATUS_CONNECTING, NULL);
|
case INTERNET_SCHEME_FTP:
|
||||||
hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL);
|
if (!url.nPort)
|
||||||
hres = E_OUTOFMEMORY; /* FIXME */
|
url.nPort = INTERNET_DEFAULT_FTP_PORT;
|
||||||
if(HttpSendRequestW(This->hrequest, NULL, 0, NULL, 0)) {
|
dwService = INTERNET_SERVICE_FTP;
|
||||||
len = 0;
|
break;
|
||||||
HttpQueryInfoW(This->hrequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &len, &lensz, NULL);
|
|
||||||
|
|
||||||
TRACE("res = %ld gle = %08lx url len = %ld\n", hres, GetLastError(), len);
|
case INTERNET_SCHEME_GOPHER:
|
||||||
|
if (!url.nPort)
|
||||||
|
url.nPort = INTERNET_DEFAULT_GOPHER_PORT;
|
||||||
|
dwService = INTERNET_SERVICE_GOPHER;
|
||||||
|
break;
|
||||||
|
|
||||||
last_read_pos.u.LowPart = last_read_pos.u.HighPart = 0;
|
case INTERNET_SCHEME_HTTP:
|
||||||
fmt.cfFormat = 0;
|
if (!url.nPort)
|
||||||
fmt.ptd = NULL;
|
url.nPort = INTERNET_DEFAULT_HTTP_PORT;
|
||||||
fmt.dwAspect = 0;
|
dwService = INTERNET_SERVICE_HTTP;
|
||||||
fmt.lindex = -1;
|
break;
|
||||||
fmt.tymed = TYMED_ISTREAM;
|
|
||||||
stg.tymed = TYMED_ISTREAM;
|
case INTERNET_SCHEME_HTTPS:
|
||||||
stg.u.pstm = pstr;
|
if (!url.nPort)
|
||||||
stg.pUnkForRelease = NULL;
|
url.nPort = INTERNET_DEFAULT_HTTPS_PORT;
|
||||||
|
dwService = INTERNET_SERVICE_HTTP;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bind->hconnect = InternetConnectW(bind->hinternet, host, url.nPort, user, pass,
|
||||||
|
dwService, 0, (DWORD)bind);
|
||||||
|
if (!bind->hconnect)
|
||||||
|
{
|
||||||
|
hres = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
CloseHandle(bind->hinternet);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, 0x22, NULL);
|
||||||
|
hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
|
||||||
|
hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CONNECTING, NULL);
|
||||||
|
hres = IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL);
|
||||||
|
|
||||||
|
bSuccess = FALSE;
|
||||||
|
|
||||||
|
switch (dwService)
|
||||||
|
{
|
||||||
|
case INTERNET_SERVICE_GOPHER:
|
||||||
|
bind->hrequest = GopherOpenFileW(bind->hconnect,
|
||||||
|
path,
|
||||||
|
0,
|
||||||
|
INTERNET_FLAG_RELOAD,
|
||||||
|
0);
|
||||||
|
if (bind->hrequest)
|
||||||
|
bSuccess = TRUE;
|
||||||
|
else
|
||||||
|
hres = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INTERNET_SERVICE_FTP:
|
||||||
|
bind->hrequest = FtpOpenFileW(bind->hconnect,
|
||||||
|
path,
|
||||||
|
GENERIC_READ,
|
||||||
|
FTP_TRANSFER_TYPE_BINARY |
|
||||||
|
INTERNET_FLAG_TRANSFER_BINARY |
|
||||||
|
INTERNET_FLAG_RELOAD,
|
||||||
|
0);
|
||||||
|
if (bind->hrequest)
|
||||||
|
bSuccess = TRUE;
|
||||||
|
else
|
||||||
|
hres = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case INTERNET_SERVICE_HTTP:
|
||||||
|
bind->hrequest = HttpOpenRequestW(bind->hconnect, NULL, path, NULL, NULL, NULL, 0, (DWORD)bind);
|
||||||
|
if (!bind->hrequest)
|
||||||
|
{
|
||||||
|
hres = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
else if (!HttpSendRequestW(bind->hrequest, NULL, 0, NULL, 0))
|
||||||
|
{
|
||||||
|
hres = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
InternetCloseHandle(bind->hrequest);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HttpQueryInfoW(bind->hrequest,
|
||||||
|
HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER,
|
||||||
|
&bind->expected_size,
|
||||||
|
&lensz,
|
||||||
|
NULL);
|
||||||
|
bSuccess = TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(bSuccess)
|
||||||
|
{
|
||||||
|
TRACE("res = %ld gle = %08lx url len = %ld\n", hres, GetLastError(), bind->expected_size);
|
||||||
|
|
||||||
|
IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CACHEFILENAMEAVAILABLE, szFileName);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
char buf[4096];
|
char buf[4096];
|
||||||
DWORD bufread;
|
DWORD bufread;
|
||||||
DWORD written;
|
if(InternetReadFile(bind->hrequest, buf, sizeof(buf), &bufread)) {
|
||||||
if(InternetReadFile(This->hrequest, buf, sizeof(buf), &bufread)) {
|
|
||||||
TRACE("read %ld bytes %s...\n", bufread, debugstr_an(buf, 10));
|
TRACE("read %ld bytes %s...\n", bufread, debugstr_an(buf, 10));
|
||||||
if(bufread == 0) break;
|
if(bufread == 0) break;
|
||||||
IStream_Write(pstr, buf, bufread, &written);
|
hres = Binding_MoreCacheData(bind, buf, bufread);
|
||||||
total_read += bufread;
|
|
||||||
IStream_Seek(pstr, last_read_pos, STREAM_SEEK_SET, NULL);
|
|
||||||
hres = IBindStatusCallback_OnProgress(pbscb, total_read, len, (total_read == bufread) ?
|
|
||||||
BINDSTATUS_BEGINDOWNLOADDATA :
|
|
||||||
BINDSTATUS_DOWNLOADINGDATA, NULL);
|
|
||||||
hres = IBindStatusCallback_OnDataAvailable(pbscb,
|
|
||||||
(total_read == bufread) ? BSCF_FIRSTDATANOTIFICATION :
|
|
||||||
BSCF_INTERMEDIATEDATANOTIFICATION,
|
|
||||||
total_read, &fmt, &stg);
|
|
||||||
last_read_pos.u.LowPart += bufread; /* FIXME */
|
|
||||||
} else
|
} else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
hres = IBindStatusCallback_OnProgress(pbscb, total_read, len, BINDSTATUS_ENDDOWNLOADDATA, NULL);
|
InternetCloseHandle(bind->hrequest);
|
||||||
hres = IBindStatusCallback_OnDataAvailable(pbscb, BSCF_LASTDATANOTIFICATION, total_read, &fmt, &stg);
|
|
||||||
TRACE("OnDataAvail rets %08lx\n", hres);
|
|
||||||
hres = IBindStatusCallback_OnStopBinding(pbscb, S_OK, NULL);
|
|
||||||
TRACE("OnStop rets %08lx\n", hres);
|
|
||||||
hres = S_OK;
|
hres = S_OK;
|
||||||
}
|
}
|
||||||
InternetCloseHandle(This->hrequest);
|
|
||||||
InternetCloseHandle(This->hconnect);
|
InternetCloseHandle(bind->hconnect);
|
||||||
InternetCloseHandle(This->hinternet);
|
InternetCloseHandle(bind->hinternet);
|
||||||
IBindStatusCallback_Release(pbscb);
|
break;
|
||||||
|
|
||||||
|
case INTERNET_SCHEME_FILE:
|
||||||
|
path = bind->URLName + 5; /* Skip the "file:" part */
|
||||||
|
if ((path[0] != '/' && path[0] != '\\') ||
|
||||||
|
(path[1] != '/' && path[1] != '\\'))
|
||||||
|
{
|
||||||
|
hres = E_FAIL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HANDLE h;
|
||||||
|
|
||||||
|
path += 2;
|
||||||
|
if (path[0] == '/' || path[0] == '\\')
|
||||||
|
++path;
|
||||||
|
h = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0 );
|
||||||
|
if (h == (HANDLE) HFILE_ERROR)
|
||||||
|
{
|
||||||
|
hres = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char buf[4096];
|
||||||
|
DWORD bufread;
|
||||||
|
|
||||||
|
IBindStatusCallback_OnProgress(bind->pbscb, 0, 0, BINDSTATUS_CACHEFILENAMEAVAILABLE, szFileName);
|
||||||
|
|
||||||
|
while (ReadFile(h, buf, sizeof(buf), &bufread, NULL) && bufread > 0)
|
||||||
|
hres = Binding_MoreCacheData(bind, buf, bufread);
|
||||||
|
|
||||||
|
CloseHandle(h);
|
||||||
|
hres = S_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FIXME("Unsupported URI scheme");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Binding_CloseCacheDownload(bind);
|
||||||
|
Binding_FinishedDownload(bind, hres);
|
||||||
|
|
||||||
|
if (user)
|
||||||
|
HeapFree(GetProcessHeap(), 0, user);
|
||||||
|
if (pass)
|
||||||
|
HeapFree(GetProcessHeap(), 0, pass);
|
||||||
|
HeapFree(GetProcessHeap(), 0, path);
|
||||||
|
HeapFree(GetProcessHeap(), 0, host);
|
||||||
|
HeapFree(GetProcessHeap(), 0, urlcopy);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*ppvObject = (VOID*)pstr;
|
|
||||||
|
IBinding_Release((IBinding*)bind);
|
||||||
|
|
||||||
return hres;
|
return hres;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,98 +1100,6 @@ static HRESULT WINAPI URLMonikerImpl_IsSystemMoniker(IMoniker* iface,DWORD* pwdM
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI URLMonikerImpl_IBinding_QueryInterface(IBinding* iface,REFIID riid,void** ppvObject)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
|
|
||||||
TRACE("(%p)->(%s,%p)\n",This,debugstr_guid(riid),ppvObject);
|
|
||||||
|
|
||||||
/* Perform a sanity check on the parameters.*/
|
|
||||||
if ( (This==0) || (ppvObject==0) )
|
|
||||||
return E_INVALIDARG;
|
|
||||||
|
|
||||||
/* Initialize the return parameter */
|
|
||||||
*ppvObject = 0;
|
|
||||||
|
|
||||||
/* Compare the riid with the interface IDs implemented by this object.*/
|
|
||||||
if (IsEqualIID(&IID_IUnknown, riid) || IsEqualIID(&IID_IBinding, riid))
|
|
||||||
*ppvObject = iface;
|
|
||||||
|
|
||||||
/* Check that we obtained an interface.*/
|
|
||||||
if ((*ppvObject)==0)
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
|
|
||||||
/* Query Interface always increases the reference count by one when it is successful */
|
|
||||||
IBinding_AddRef(iface);
|
|
||||||
|
|
||||||
return S_OK;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI URLMonikerImpl_IBinding_AddRef(IBinding* iface)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
TRACE("(%p)\n",This);
|
|
||||||
|
|
||||||
return URLMonikerImpl_AddRef((IMoniker*)This);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI URLMonikerImpl_IBinding_Release(IBinding* iface)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
TRACE("(%p)\n",This);
|
|
||||||
|
|
||||||
return URLMonikerImpl_Release((IMoniker*)This);
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI URLMonikerImpl_IBinding_Abort(IBinding* iface)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
FIXME("(%p): stub\n", This);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI URLMonikerImpl_IBinding_GetBindResult(IBinding* iface, CLSID* pclsidProtocol, DWORD* pdwResult, LPOLESTR* pszResult, DWORD* pdwReserved)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
FIXME("(%p)->(%p, %p, %p, %p): stub\n", This, pclsidProtocol, pdwResult, pszResult, pdwReserved);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI URLMonikerImpl_IBinding_GetPriority(IBinding* iface, LONG* pnPriority)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
FIXME("(%p)->(%p): stub\n", This, pnPriority);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI URLMonikerImpl_IBinding_Resume(IBinding* iface)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
FIXME("(%p): stub\n", This);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI URLMonikerImpl_IBinding_SetPriority(IBinding* iface, LONG nPriority)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
FIXME("(%p)->(%ld): stub\n", This, nPriority);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI URLMonikerImpl_IBinding_Suspend(IBinding* iface)
|
|
||||||
{
|
|
||||||
ICOM_THIS_MULTI(URLMonikerImpl, lpvtbl2, iface);
|
|
||||||
FIXME("(%p): stub\n", This);
|
|
||||||
|
|
||||||
return E_NOTIMPL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************************************************************/
|
/********************************************************************************/
|
||||||
/* Virtual function table for the URLMonikerImpl class which include IPersist,*/
|
/* Virtual function table for the URLMonikerImpl class which include IPersist,*/
|
||||||
/* IPersistStream and IMoniker functions. */
|
/* IPersistStream and IMoniker functions. */
|
||||||
|
@ -820,19 +1130,6 @@ static IMonikerVtbl VT_URLMonikerImpl =
|
||||||
URLMonikerImpl_IsSystemMoniker
|
URLMonikerImpl_IsSystemMoniker
|
||||||
};
|
};
|
||||||
|
|
||||||
static IBindingVtbl VTBinding_URLMonikerImpl =
|
|
||||||
{
|
|
||||||
URLMonikerImpl_IBinding_QueryInterface,
|
|
||||||
URLMonikerImpl_IBinding_AddRef,
|
|
||||||
URLMonikerImpl_IBinding_Release,
|
|
||||||
URLMonikerImpl_IBinding_Abort,
|
|
||||||
URLMonikerImpl_IBinding_Suspend,
|
|
||||||
URLMonikerImpl_IBinding_Resume,
|
|
||||||
URLMonikerImpl_IBinding_SetPriority,
|
|
||||||
URLMonikerImpl_IBinding_GetPriority,
|
|
||||||
URLMonikerImpl_IBinding_GetBindResult
|
|
||||||
};
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* URLMoniker_Construct (local function)
|
* URLMoniker_Construct (local function)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
@ -845,8 +1142,7 @@ static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeft
|
||||||
memset(This, 0, sizeof(*This));
|
memset(This, 0, sizeof(*This));
|
||||||
|
|
||||||
/* Initialize the virtual function table. */
|
/* Initialize the virtual function table. */
|
||||||
This->lpvtbl1 = &VT_URLMonikerImpl;
|
This->lpvtbl = &VT_URLMonikerImpl;
|
||||||
This->lpvtbl2 = &VTBinding_URLMonikerImpl;
|
|
||||||
This->ref = 0;
|
This->ref = 0;
|
||||||
|
|
||||||
if(lpszLeftURLName) {
|
if(lpszLeftURLName) {
|
||||||
|
|
380
reactos/lib/urlmon/umstream.c
Normal file
380
reactos/lib/urlmon/umstream.c
Normal file
|
@ -0,0 +1,380 @@
|
||||||
|
/*
|
||||||
|
* Based on ../shell32/memorystream.c
|
||||||
|
*
|
||||||
|
* Copyright 1999 Juergen Schmied
|
||||||
|
* Copyright 2003 Mike McCormack for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define COBJMACROS
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winreg.h"
|
||||||
|
#include "winternl.h"
|
||||||
|
#include "winuser.h"
|
||||||
|
#include "objbase.h"
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
#include "ole2.h"
|
||||||
|
#include "urlmon.h"
|
||||||
|
#include "wininet.h"
|
||||||
|
#include "shlwapi.h"
|
||||||
|
#include "urlmon_main.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
|
||||||
|
|
||||||
|
static const IStreamVtbl stvt;
|
||||||
|
|
||||||
|
HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL,
|
||||||
|
DWORD dwSize,
|
||||||
|
LPWSTR pszFileName,
|
||||||
|
HANDLE *phfile,
|
||||||
|
IUMCacheStream **ppstr)
|
||||||
|
{
|
||||||
|
IUMCacheStream* ucstr;
|
||||||
|
HANDLE handle;
|
||||||
|
LPWSTR ext;
|
||||||
|
LPCWSTR c;
|
||||||
|
LPCWSTR eloc = 0;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
for (c = pszURL; *c && *c != '#' && *c != '?'; ++c)
|
||||||
|
{
|
||||||
|
if (*c == '.')
|
||||||
|
eloc = c + 1;
|
||||||
|
else if (*c == '/' || *c == '\\')
|
||||||
|
eloc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!eloc)
|
||||||
|
eloc = c;
|
||||||
|
|
||||||
|
ext = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (c - eloc + 1));
|
||||||
|
memcpy(ext, eloc, sizeof(WCHAR) * (c - eloc));
|
||||||
|
ext[c - eloc] = 0;
|
||||||
|
|
||||||
|
if(!CreateUrlCacheEntryW(pszURL, dwSize, ext, pszFileName, 0))
|
||||||
|
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
else
|
||||||
|
hr = 0;
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, ext);
|
||||||
|
|
||||||
|
if (hr)
|
||||||
|
return hr;
|
||||||
|
|
||||||
|
TRACE("Opening %s\n", debugstr_w(pszFileName) );
|
||||||
|
|
||||||
|
handle = CreateFileW( pszFileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL );
|
||||||
|
if( handle == INVALID_HANDLE_VALUE )
|
||||||
|
return HRESULT_FROM_WIN32(GetLastError());
|
||||||
|
|
||||||
|
if (phfile)
|
||||||
|
{
|
||||||
|
/* Call CreateFileW again because we need a handle with its own file pointer, and DuplicateHandle will return
|
||||||
|
* a handle that shares its file pointer with the original.
|
||||||
|
*/
|
||||||
|
*phfile = CreateFileW( pszFileName, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL );
|
||||||
|
|
||||||
|
if (*phfile == (HANDLE) HFILE_ERROR)
|
||||||
|
{
|
||||||
|
DWORD dwError = GetLastError();
|
||||||
|
|
||||||
|
CloseHandle(handle);
|
||||||
|
return HRESULT_FROM_WIN32(dwError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ucstr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,sizeof(IUMCacheStream));
|
||||||
|
if(ucstr )
|
||||||
|
{
|
||||||
|
ucstr->pszURL = HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
sizeof(WCHAR) * (lstrlenW(pszURL) + 1));
|
||||||
|
if (ucstr->pszURL)
|
||||||
|
{
|
||||||
|
ucstr->pszFileName = HeapAlloc(GetProcessHeap(),
|
||||||
|
HEAP_ZERO_MEMORY,
|
||||||
|
sizeof(WCHAR) * (lstrlenW(pszFileName) + 1));
|
||||||
|
if (ucstr->pszFileName)
|
||||||
|
{
|
||||||
|
ucstr->lpVtbl=&stvt;
|
||||||
|
ucstr->ref = 1;
|
||||||
|
ucstr->handle = handle;
|
||||||
|
ucstr->closed = 0;
|
||||||
|
lstrcpyW(ucstr->pszURL, pszURL);
|
||||||
|
lstrcpyW(ucstr->pszFileName, pszFileName);
|
||||||
|
|
||||||
|
*ppstr = ucstr;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, ucstr->pszURL);
|
||||||
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, ucstr);
|
||||||
|
}
|
||||||
|
CloseHandle(handle);
|
||||||
|
if (phfile)
|
||||||
|
CloseHandle(*phfile);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UMCloseCacheFileStream(IUMCacheStream *This)
|
||||||
|
{
|
||||||
|
if (!This->closed)
|
||||||
|
{
|
||||||
|
FILETIME ftZero;
|
||||||
|
|
||||||
|
ftZero.dwLowDateTime = ftZero.dwHighDateTime = 0;
|
||||||
|
|
||||||
|
This->closed = 1;
|
||||||
|
CommitUrlCacheEntryW(This->pszURL,
|
||||||
|
This->pszFileName,
|
||||||
|
ftZero,
|
||||||
|
ftZero,
|
||||||
|
NORMAL_CACHE_ENTRY,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* IStream_fnQueryInterface
|
||||||
|
*/
|
||||||
|
static HRESULT WINAPI IStream_fnQueryInterface(IStream *iface,
|
||||||
|
REFIID riid,
|
||||||
|
LPVOID *ppvObj)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)->(\n\tIID:\t%s,%p)\n",This,debugstr_guid(riid),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)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
ULONG refCount = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p)->(count=%lu)\n", This, refCount - 1);
|
||||||
|
|
||||||
|
return refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* IStream_fnRelease
|
||||||
|
*/
|
||||||
|
static ULONG WINAPI IStream_fnRelease(IStream *iface)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
ULONG refCount = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
|
TRACE("(%p)->(count=%lu)\n", This, refCount + 1);
|
||||||
|
|
||||||
|
if (!refCount)
|
||||||
|
{
|
||||||
|
TRACE(" destroying UMCacheStream (%p)\n",This);
|
||||||
|
UMCloseCacheFileStream(This);
|
||||||
|
CloseHandle(This->handle);
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->pszFileName);
|
||||||
|
HeapFree(GetProcessHeap(), 0, This->pszURL);
|
||||||
|
HeapFree(GetProcessHeap(),0,This);
|
||||||
|
}
|
||||||
|
return refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IStream_fnRead (IStream * iface,
|
||||||
|
void* pv,
|
||||||
|
ULONG cb,
|
||||||
|
ULONG* pcbRead)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)->(%p,0x%08lx,%p)\n",This, pv, cb, pcbRead);
|
||||||
|
|
||||||
|
if ( !pv )
|
||||||
|
return STG_E_INVALIDPOINTER;
|
||||||
|
|
||||||
|
if ( ! ReadFile( This->handle, pv, cb, pcbRead, NULL ) )
|
||||||
|
return S_FALSE;
|
||||||
|
|
||||||
|
if (!*pcbRead)
|
||||||
|
return This->closed ? S_FALSE : E_PENDING;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IStream_fnWrite (IStream * iface,
|
||||||
|
const void* pv,
|
||||||
|
ULONG cb,
|
||||||
|
ULONG* pcbWritten)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IStream_fnSeek ( IStream * iface,
|
||||||
|
LARGE_INTEGER dlibMove,
|
||||||
|
DWORD dwOrigin,
|
||||||
|
ULARGE_INTEGER* plibNewPosition)
|
||||||
|
{
|
||||||
|
DWORD pos, newposlo, newposhi;
|
||||||
|
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
pos = dlibMove.QuadPart; /* FIXME: truncates */
|
||||||
|
newposhi = 0;
|
||||||
|
newposlo = SetFilePointer( This->handle, pos, &newposhi, dwOrigin );
|
||||||
|
if( newposlo == INVALID_SET_FILE_POINTER )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if (plibNewPosition)
|
||||||
|
plibNewPosition->QuadPart = newposlo | ( (LONGLONG)newposhi<<32);
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IStream_fnSetSize (IStream * iface,
|
||||||
|
ULARGE_INTEGER libNewSize)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
if( ! SetFilePointer( This->handle, libNewSize.QuadPart, NULL, FILE_BEGIN ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
if( ! SetEndOfFile( This->handle ) )
|
||||||
|
return E_FAIL;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IStream_fnCopyTo (IStream * iface,
|
||||||
|
IStream* pstm,
|
||||||
|
ULARGE_INTEGER cb,
|
||||||
|
ULARGE_INTEGER* pcbRead,
|
||||||
|
ULARGE_INTEGER* pcbWritten)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IStream_fnCommit (IStream * iface,
|
||||||
|
DWORD grfCommitFlags)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IStream_fnRevert (IStream * iface)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
static HRESULT WINAPI IStream_fnLockRegion (IStream * iface,
|
||||||
|
ULARGE_INTEGER libOffset,
|
||||||
|
ULARGE_INTEGER cb,
|
||||||
|
DWORD dwLockType)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
static HRESULT WINAPI IStream_fnUnlockRegion (IStream * iface,
|
||||||
|
ULARGE_INTEGER libOffset,
|
||||||
|
ULARGE_INTEGER cb,
|
||||||
|
DWORD dwLockType)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
static HRESULT WINAPI IStream_fnStat (IStream * iface,
|
||||||
|
STATSTG* pstatstg,
|
||||||
|
DWORD grfStatFlag)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
static HRESULT WINAPI IStream_fnClone (IStream * iface,
|
||||||
|
IStream** ppstm)
|
||||||
|
{
|
||||||
|
IUMCacheStream *This = (IUMCacheStream *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n",This);
|
||||||
|
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IStreamVtbl stvt =
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|
||||||
|
};
|
|
@ -8,7 +8,7 @@
|
||||||
@ stub AsyncGetClassBits
|
@ stub AsyncGetClassBits
|
||||||
@ stub AsyncInstallDistributionUnit
|
@ stub AsyncInstallDistributionUnit
|
||||||
@ stub BindAsyncMoniker
|
@ stub BindAsyncMoniker
|
||||||
@ stub CoGetClassObjectFromURL
|
@ stdcall CoGetClassObjectFromURL(ptr wstr long long wstr ptr long ptr ptr ptr)
|
||||||
@ stub CoInstall
|
@ stub CoInstall
|
||||||
@ stdcall CoInternetCombineUrl(wstr wstr long wstr long ptr long)
|
@ stdcall CoInternetCombineUrl(wstr wstr long wstr long ptr long)
|
||||||
@ stdcall CoInternetCompareUrl(wstr wstr long)
|
@ stdcall CoInternetCompareUrl(wstr wstr long)
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
<file>regsvr.c</file>
|
<file>regsvr.c</file>
|
||||||
<file>sec_mgr.c</file>
|
<file>sec_mgr.c</file>
|
||||||
<file>umon.c</file>
|
<file>umon.c</file>
|
||||||
|
<file>umstream.c</file>
|
||||||
<file>urlmon_main.c</file>
|
<file>urlmon_main.c</file>
|
||||||
<file>urlmon.spec</file>
|
<file>urlmon.spec</file>
|
||||||
</module>
|
</module>
|
||||||
|
|
|
@ -341,3 +341,17 @@ HRESULT WINAPI FaultInIEFeature( HWND hwnd, uCLSSPEC * pClassSpec,
|
||||||
FIXME("%p %p %p %08lx\n", hwnd, pClassSpec, pQuery, flags);
|
FIXME("%p %p %p %08lx\n", hwnd, pClassSpec, pQuery, flags);
|
||||||
return E_NOTIMPL;
|
return E_NOTIMPL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* CoGetClassObjectFromURL (URLMON.@)
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI CoGetClassObjectFromURL( REFCLSID rclsid, LPCWSTR szCodeURL, DWORD dwFileVersionMS,
|
||||||
|
DWORD dwFileVersionLS, LPCWSTR szContentType,
|
||||||
|
LPBINDCTX pBindCtx, DWORD dwClsContext, LPVOID pvReserved,
|
||||||
|
REFIID riid, LPVOID *ppv )
|
||||||
|
{
|
||||||
|
FIXME("(%s %s %ld %ld %s %p %ld %p %s %p) Stub!\n", debugstr_guid(rclsid), debugstr_w(szCodeURL),
|
||||||
|
dwFileVersionMS, dwFileVersionLS, debugstr_w(szContentType), pBindCtx, dwClsContext, pvReserved,
|
||||||
|
debugstr_guid(riid), ppv);
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
|
@ -37,4 +37,17 @@ static inline void URLMON_UnlockModule() { InterlockedDecrement( &URLMON_refCoun
|
||||||
|
|
||||||
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const IStreamVtbl *lpVtbl;
|
||||||
|
DWORD ref;
|
||||||
|
HANDLE handle;
|
||||||
|
BOOL closed;
|
||||||
|
WCHAR *pszFileName;
|
||||||
|
WCHAR *pszURL;
|
||||||
|
} IUMCacheStream;
|
||||||
|
|
||||||
|
HRESULT UMCreateStreamOnCacheFile(LPCWSTR pszURL, DWORD dwSize, LPWSTR pszFileName, HANDLE *phfile, IUMCacheStream **ppstr);
|
||||||
|
void UMCloseCacheFileStream(IUMCacheStream *pstr);
|
||||||
|
|
||||||
#endif /* __WINE_URLMON_MAIN_H */
|
#endif /* __WINE_URLMON_MAIN_H */
|
||||||
|
|
Loading…
Reference in a new issue