--- trunk/reactos/lib/urlmon/umon.c 2005-05-28 21:40:01 UTC (rev 15624)
+++ trunk/reactos/lib/urlmon/umon.c 2005-05-28 21:44:21 UTC (rev 15625)
@@ -48,19 +48,252 @@
/*static BOOL registered_wndclass = FALSE;*/
+typedef struct {
+ IBindingVtbl *lpVtbl;
+
+ ULONG ref;
+
+ LPWSTR URLName;
+
+ HWND hwndCallback;
+ IBindCtx *pBC;
+ 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 URLMonikerImpl{
+typedef struct {
- IMonikerVtbl* lpvtbl1; /* VTable relative to the IMoniker interface.*/
- IBindingVtbl* lpvtbl2; /* VTable to IBinding interface */
+ IMonikerVtbl* lpvtbl; /* VTable relative to the IMoniker interface.*/
ULONG ref; /* reference counter for this object */
LPOLESTR URLName; /* URL string identified by this URLmoniker */
-
- HWND hwndCallback;
- IBindCtx *pBC;
- HINTERNET hinternet, hconnect, hrequest;
} URLMonikerImpl;
/*******************************************************************************
@@ -133,6 +366,7 @@
return refCount;
}
+
/******************************************************************************
* URLMoniker_GetClassID
******************************************************************************/
@@ -310,6 +544,8 @@
return;
}
#endif
+
+
/******************************************************************************
* URLMoniker_BindToStorage
******************************************************************************/
@@ -321,12 +557,12 @@
{
URLMonikerImpl *This = (URLMonikerImpl *)iface;
HRESULT hres;
- IBindStatusCallback *pbscb;
BINDINFO bi;
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) {
FIXME("pmkToLeft != NULL\n");
return E_NOTIMPL;
@@ -336,122 +572,288 @@
return E_NOTIMPL;
}
- /* FIXME This is a bad hack (tm). We should clearly download to a temporary file.
- We also need to implement IStream ourselves so that IStream_Read can return
- E_PENDING */
+ bind = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Binding));
+ bind->lpVtbl = &BindingVtbl;
+ 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)) {
- 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)) {
TRACE("Got IBindStatusCallback...\n");
memset(&bi, 0, sizeof(bi));
bi.cbSize = sizeof(bi);
bindf = 0;
- hres = IBindStatusCallback_GetBindInfo(pbscb, &bindf, &bi);
+ hres = IBindStatusCallback_GetBindInfo(bind->pbscb, &bindf, &bi);
if(SUCCEEDED(hres)) {
+ WCHAR *urlcopy, *tmpwc;
URL_COMPONENTSW url;
- WCHAR *host, *path;
- DWORD len, lensz = sizeof(len), total_read = 0;
- LARGE_INTEGER last_read_pos;
- FORMATETC fmt;
- STGMEDIUM stg;
+ WCHAR *host, *path, *user, *pass;
+ DWORD lensz = sizeof(bind->expected_size);
+ DWORD dwService = 0;
+ BOOL bSuccess;
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));
- hres = IBindStatusCallback_OnStartBinding(pbscb, 0, (IBinding*)&This->lpvtbl2);
+ hres = IBindStatusCallback_OnStartBinding(bind->pbscb, 0, (IBinding*)bind);
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(!registered_wndclass) {
+ if(!registered_wndclass) {
WNDCLASSA urlmon_wndclass = {0, URLMON_WndProc,0, 0, URLMON_hInstance, 0, 0, 0, NULL, "URLMON_Callback_Window_Class"};
- RegisterClassA(&urlmon_wndclass);
- registered_wndclass = TRUE;
- }
+ RegisterClassA(&urlmon_wndclass);
+ registered_wndclass = TRUE;
+ }
- This->hwndCallback = CreateWindowA("URLMON_Callback_Window_Class", NULL, 0, 0, 0, 0, 0, 0, 0,
- URLMON_hInstance, NULL);
+ This->hwndCallback = CreateWindowA("URLMON_Callback_Window_Class", NULL, 0, 0, 0, 0, 0, 0, 0,
+ URLMON_hInstance, NULL);
#endif
+ bind->expected_size = 0;
+ bind->total_read = 0;
+
memset(&url, 0, sizeof(url));
url.dwStructSize = sizeof(url);
- url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = 1;
- InternetCrackUrlW(This->URLName, 0, 0, &url);
+ url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength = url.dwUserNameLength = url.dwPasswordLength = 1;
+ InternetCrackUrlW(urlcopy, 0, 0, &url);
host = HeapAlloc(GetProcessHeap(), 0, (url.dwHostNameLength + 1) * sizeof(WCHAR));
memcpy(host, url.lpszHostName, url.dwHostNameLength * sizeof(WCHAR));
host[url.dwHostNameLength] = '\0';
path = HeapAlloc(GetProcessHeap(), 0, (url.dwUrlPathLength + 1) * sizeof(WCHAR));
memcpy(path, url.lpszUrlPath, url.dwUrlPathLength * sizeof(WCHAR));
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*/);
-/* InternetSetStatusCallback(This->hinternet, URLMON_InternetCallback);*/
+ switch ((DWORD) url.nScheme)
+ {
+ 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,
- INTERNET_SERVICE_HTTP, 0, (DWORD)This);
- This->hrequest = HttpOpenRequestW(This->hconnect, NULL, path, NULL, NULL, NULL, 0, (DWORD)This);
+ bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0 /*INTERNET_FLAG_ASYNC*/);
+/* InternetSetStatusCallback(bind->hinternet, URLMON_InternetCallback);*/
+ if (!bind->hinternet)
+ {
+ hres = HRESULT_FROM_WIN32(GetLastError());
+ break;
+ }
- hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, 0x22, NULL);
- hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, BINDSTATUS_FINDINGRESOURCE, NULL);
- hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, BINDSTATUS_CONNECTING, NULL);
- hres = IBindStatusCallback_OnProgress(pbscb, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL);
- hres = E_OUTOFMEMORY; /* FIXME */
- if(HttpSendRequestW(This->hrequest, NULL, 0, NULL, 0)) {
- len = 0;
- HttpQueryInfoW(This->hrequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &len, &lensz, NULL);
+ switch ((DWORD) url.nScheme)
+ {
+ case INTERNET_SCHEME_FTP:
+ if (!url.nPort)
+ url.nPort = INTERNET_DEFAULT_FTP_PORT;
+ dwService = INTERNET_SERVICE_FTP;
+ break;
+
+ case INTERNET_SCHEME_GOPHER:
+ if (!url.nPort)
+ url.nPort = INTERNET_DEFAULT_GOPHER_PORT;
+ dwService = INTERNET_SERVICE_GOPHER;
+ break;
- TRACE("res = %ld gle = %08lx url len = %ld\n", hres, GetLastError(), len);
+ case INTERNET_SCHEME_HTTP:
+ if (!url.nPort)
+ url.nPort = INTERNET_DEFAULT_HTTP_PORT;
+ dwService = INTERNET_SERVICE_HTTP;
+ break;
- last_read_pos.u.LowPart = last_read_pos.u.HighPart = 0;
- fmt.cfFormat = 0;
- fmt.ptd = NULL;
- fmt.dwAspect = 0;
- fmt.lindex = -1;
- fmt.tymed = TYMED_ISTREAM;
- stg.tymed = TYMED_ISTREAM;
- stg.u.pstm = pstr;
- stg.pUnkForRelease = NULL;
+ case INTERNET_SCHEME_HTTPS:
+ if (!url.nPort)
+ url.nPort = INTERNET_DEFAULT_HTTPS_PORT;
+ dwService = INTERNET_SERVICE_HTTP;
+ break;
+ }
- while(1) {
- char buf[4096];
- DWORD bufread;
- DWORD written;
- if(InternetReadFile(This->hrequest, buf, sizeof(buf), &bufread)) {
- TRACE("read %ld bytes %s...\n", bufread, debugstr_an(buf, 10));
- if(bufread == 0) break;
- IStream_Write(pstr, buf, bufread, &written);
- 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
+ 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(pbscb, total_read, len, BINDSTATUS_ENDDOWNLOADDATA, NULL);
- 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 = 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) {
+ char buf[4096];
+ DWORD bufread;
+ if(InternetReadFile(bind->hrequest, buf, sizeof(buf), &bufread)) {
+ TRACE("read %ld bytes %s...\n", bufread, debugstr_an(buf, 10));
+ if(bufread == 0) break;
+ hres = Binding_MoreCacheData(bind, buf, bufread);
+ } else
+ break;
+ }
+ InternetCloseHandle(bind->hrequest);
+ hres = S_OK;
+ }
+
+ InternetCloseHandle(bind->hconnect);
+ InternetCloseHandle(bind->hinternet);
+ 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;
}
- InternetCloseHandle(This->hrequest);
- InternetCloseHandle(This->hconnect);
- InternetCloseHandle(This->hinternet);
- IBindStatusCallback_Release(pbscb);
+ 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;
}
@@ -698,98 +1100,6 @@
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,*/
/* IPersistStream and IMoniker functions. */
@@ -820,19 +1130,6 @@
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)
*******************************************************************************/
@@ -845,9 +1142,8 @@
memset(This, 0, sizeof(*This));
/* Initialize the virtual function table. */
- This->lpvtbl1 = &VT_URLMonikerImpl;
- This->lpvtbl2 = &VTBinding_URLMonikerImpl;
- This->ref = 0;
+ This->lpvtbl = &VT_URLMonikerImpl;
+ This->ref = 0;
if(lpszLeftURLName) {
hres = UrlCombineW(lpszLeftURLName, lpszURLName, NULL, &sizeStr, 0);