Sync to Wine-0_9_5:

Jacek Caban <jacek@codeweavers.com>
- urlmon: URL with two slashes is valid.
- urlmon: Added GetSecurityId implementation.
- urlmon: Removed not used code.
- urlmon: Use pluggable protocol for file protocol.
Rolf Kalbermatter <rolf.kalbermatter@citeng.com>
- urlmon: Implement BindAsyncMoniker function.

svn path=/trunk/; revision=20627
This commit is contained in:
Gé van Geldorp 2006-01-06 20:42:46 +00:00
parent d587904c0c
commit 5d44b0636a
5 changed files with 144 additions and 126 deletions

View file

@ -225,6 +225,16 @@ static HRESULT WINAPI InternetProtocolSink_ReportProgress(IInternetProtocolSink
memcpy(This->mime, szStatusText, len*sizeof(WCHAR));
break;
}
case BINDSTATUS_SENDINGREQUEST:
IBindStatusCallback_OnProgress(This->callback, 0, 0, BINDSTATUS_SENDINGREQUEST,
szStatusText);
break;
case BINDSTATUS_VERIFIEDMIMETYPEAVAILABLE:
IBindStatusCallback_OnProgress(This->callback, 0, 0,
BINDSTATUS_MIMETYPEAVAILABLE, szStatusText);
break;
case BINDSTATUS_CACHEFILENAMEAVAILABLE:
break;
default:
FIXME("Unhandled status code %ld\n", ulStatusCode);
return E_NOTIMPL;
@ -438,6 +448,8 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding *
int len;
HRESULT hres;
static const WCHAR wszFile[] = {'f','i','l','e',':'};
if(!IsEqualGUID(&IID_IStream, riid)) {
FIXME("Unsupported riid %s\n", debugstr_guid(riid));
return E_NOTIMPL;
@ -483,9 +495,13 @@ static HRESULT Binding_Create(LPCWSTR url, IBindCtx *pbc, REFIID riid, Binding *
return hres;
}
ret->bindf |= (BINDF_FROMURLMON|BINDF_NEEDFILE);
ret->bindf |= BINDF_FROMURLMON;
len = strlenW(url)+1;
if(len < sizeof(wszFile)/sizeof(WCHAR) || memcmp(wszFile, url, sizeof(wszFile)))
ret->bindf |= BINDF_NEEDFILE;
ret->url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR));
memcpy(ret->url, url, len*sizeof(WCHAR));

View file

@ -145,8 +145,10 @@ static HRESULT WINAPI FileProtocol_Start(IInternetProtocol *iface, LPCWSTR szUrl
IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
file_name = url+sizeof(wszFile)/sizeof(WCHAR);
if(file_name[0] == '/' && file_name[1] == '/' && file_name[2] == '/')
file_name += 3;
if(file_name[0] == '/' && file_name[1] == '/')
file_name += 2;
if(*file_name == '/')
file_name++;
This->file = CreateFileW(file_name, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

View file

@ -109,7 +109,7 @@ static HRESULT map_url_to_zone(LPCWSTR url, DWORD *zone)
size = sizeof(DWORD);
res = RegQueryValueExW(hkey, schema, NULL, NULL, (PBYTE)zone, &size);
if(res == ERROR_SUCCESS)
return S_OK;
return S_OK;
*zone = 3;
return S_OK;
@ -268,15 +268,17 @@ static HRESULT WINAPI SecManagerImpl_MapUrlToZone(IInternetSecurityManager *ifac
}
static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *iface,
LPCWSTR pwszUrl,
BYTE *pbSecurityId, DWORD *pcbSecurityId,
DWORD_PTR dwReserved)
LPCWSTR pwszUrl, BYTE *pbSecurityId, DWORD *pcbSecurityId, DWORD_PTR dwReserved)
{
SecManagerImpl *This = SECMGR_THIS(iface);
LPWSTR buf, ptr, ptr2;
DWORD size, zone, len;
HRESULT hres;
TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId, pcbSecurityId,
dwReserved);
static const WCHAR wszFile[] = {'f','i','l','e',':'};
TRACE("(%p)->(%s %p %p %08lx)\n", iface, debugstr_w(pwszUrl), pbSecurityId,
pcbSecurityId, dwReserved);
if(This->custom_manager) {
hres = IInternetSecurityManager_GetSecurityId(This->custom_manager,
@ -285,8 +287,65 @@ static HRESULT WINAPI SecManagerImpl_GetSecurityId(IInternetSecurityManager *ifa
return hres;
}
FIXME("Default action is not implemented\n");
return E_NOTIMPL;
if(!pwszUrl || !pbSecurityId || !pcbSecurityId)
return E_INVALIDARG;
if(dwReserved)
FIXME("dwReserved is not supported\n");
len = strlenW(pwszUrl)+1;
buf = HeapAlloc(GetProcessHeap(), 0, (len+16)*sizeof(WCHAR));
hres = CoInternetParseUrl(pwszUrl, PARSE_SECURITY_URL, 0, buf, len, &size, 0);
if(FAILED(hres))
memcpy(buf, pwszUrl, len*sizeof(WCHAR));
hres = map_url_to_zone(buf, &zone);
if(FAILED(hres)) {
HeapFree(GetProcessHeap(), 0, buf);
return hres == 0x80041001 ? E_INVALIDARG : hres;
}
/* file protocol is a special case */
if(strlenW(pwszUrl) >= sizeof(wszFile)/sizeof(WCHAR)
&& !memcmp(buf, wszFile, sizeof(wszFile))) {
static const BYTE secidFile[] = {'f','i','l','e',':'};
if(*pcbSecurityId < sizeof(secidFile)+sizeof(zone))
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
memcpy(pbSecurityId, secidFile, sizeof(secidFile));
*(DWORD*)(pbSecurityId+sizeof(secidFile)) = zone;
*pcbSecurityId = sizeof(secidFile)+sizeof(zone);
return S_OK;
}
ptr = strchrW(buf, ':');
ptr2 = ++ptr;
while(*ptr2 == '/')
ptr2++;
if(ptr2 != ptr)
memmove(ptr, ptr2, (strlenW(ptr2)+1)*sizeof(WCHAR));
ptr = strchrW(ptr, '/');
if(ptr)
*ptr = 0;
len = WideCharToMultiByte(CP_ACP, 0, buf, -1, NULL, 0, NULL, NULL)-1;
if(len+sizeof(DWORD) > *pcbSecurityId)
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
WideCharToMultiByte(CP_ACP, 0, buf, -1, (LPSTR)pbSecurityId, -1, NULL, NULL);
HeapFree(GetProcessHeap(), 0, buf);
*(DWORD*)(pbSecurityId+len) = zone;
*pcbSecurityId = len+sizeof(DWORD);
return S_OK;
}

View file

@ -3,6 +3,7 @@
*
* Copyright 1999 Ulrich Czekalla for Corel Corporation
* Copyright 2002 Huw D M Davies for CodeWeavers
* Copyright 2005 Jacek Caban for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -496,55 +497,6 @@ static HRESULT WINAPI URLMonikerImpl_BindToObject(IMoniker* iface,
return E_NOTIMPL;
}
typedef struct {
enum {OnProgress, OnDataAvailable} callback;
} URLMON_CallbackData;
#if 0
static LRESULT CALLBACK URLMON_WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
static void PostOnProgress(URLMonikerImpl *This, UINT progress, UINT maxprogress, DWORD status, LPCWSTR *str)
{
}
static void CALLBACK URLMON_InternetCallback(HINTERNET hinet, /*DWORD_PTR*/ DWORD context, DWORD status,
void *status_info, DWORD status_info_len)
{
URLMonikerImpl *This = (URLMonikerImpl *)context;
TRACE("handle %p this %p status %08lx\n", hinet, This, status);
if(This->filesize == -1) {
switch(status) {
case INTERNET_STATUS_RESOLVING_NAME:
PostOnProgess(This, 0, 0, BINDSTATUS_FINDINGRESOURCE, status_info);
break;
case INTERNET_STATUS_CONNECTING_TO_SERVER:
PostOnProgress(This, 0, 0, BINDSTATUS_CONNECTING, NULL);
break;
case INTERNET_STATUS_SENDING_REQUEST:
PostOnProgress(This, 0, 0, BINDSTATUS_SENDINGREQUEST, NULL);
break;
case INTERNET_REQUEST_COMPLETE:
{
DWORD len, lensz = sizeof(len);
HttpQueryInfoW(hrequest, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &len, &lensz, NULL);
TRACE("res = %ld gle = %08lx url len = %ld\n", hres, GetLastError(), len);
This->filesize = len;
break;
}
}
}
return;
}
#endif
/******************************************************************************
* URLMoniker_BindToStorage
******************************************************************************/
@ -601,7 +553,7 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
if(SUCCEEDED(hres)) {
WCHAR *urlcopy, *tmpwc;
URL_COMPONENTSW url;
WCHAR *host, *path, *partial_path, *user, *pass;
WCHAR *host, *path, *user, *pass;
DWORD lensz = sizeof(bind->expected_size);
DWORD dwService = 0;
BOOL bSuccess;
@ -622,17 +574,6 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
if (*tmpwc == '\\')
*tmpwc = '/';
#if 0
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;
}
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;
@ -667,15 +608,9 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
pass = 0;
}
switch ((DWORD) url.nScheme)
{
case INTERNET_SCHEME_FTP:
case INTERNET_SCHEME_GOPHER:
case INTERNET_SCHEME_HTTP:
case INTERNET_SCHEME_HTTPS:
bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0 /*INTERNET_FLAG_ASYNC*/);
/* InternetSetStatusCallback(bind->hinternet, URLMON_InternetCallback);*/
do {
bind->hinternet = InternetOpenA("User Agent", 0, NULL, NULL, 0);
if (!bind->hinternet)
{
hres = HRESULT_FROM_WIN32(GetLastError());
@ -797,48 +732,8 @@ static HRESULT URLMonikerImpl_BindToStorage_hack(LPCWSTR URLName,
InternetCloseHandle(bind->hconnect);
InternetCloseHandle(bind->hinternet);
break;
} while(0);
case INTERNET_SCHEME_FILE:
partial_path = bind->URLName + 5; /* Skip the "file:" part */
if ((partial_path[0] != '/' && partial_path[0] != '\\') ||
(partial_path[1] != '/' && partial_path[1] != '\\'))
{
hres = E_FAIL;
}
else
{
HANDLE h;
partial_path += 2;
if (partial_path[0] == '/' || partial_path[0] == '\\')
++partial_path;
h = CreateFileW(partial_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);
@ -880,8 +775,7 @@ static HRESULT WINAPI URLMonikerImpl_BindToStorage(IMoniker* iface,
if(url.nScheme == INTERNET_SCHEME_HTTP
|| url.nScheme== INTERNET_SCHEME_HTTPS
|| url.nScheme== INTERNET_SCHEME_FTP
|| url.nScheme == INTERNET_SCHEME_GOPHER
|| url.nScheme == INTERNET_SCHEME_FILE)
|| url.nScheme == INTERNET_SCHEME_GOPHER)
return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, pmkToLeft, riid, ppvObject);
TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft, debugstr_guid(riid), ppvObject);
@ -1198,9 +1092,20 @@ static HRESULT URLMonikerImpl_Construct(URLMonikerImpl* This, LPCOLESTR lpszLeft
HeapFree(GetProcessHeap(), 0, This->URLName);
return hres;
}
}else {
/* FIXME:
* We probably should use CoInternetParseUrl or something similar here.
*/
static const WCHAR wszFile[] = {'f','i','l','e',':','/','/',};
/* file protocol is a special case */
if(sizeStr > sizeof(wszFile)/sizeof(WCHAR)
&& !memcmp(lpszURLName, wszFile, sizeof(wszFile)))
UrlCanonicalizeW(lpszURLName, This->URLName, &sizeStr, URL_FILE_USE_PATHURL);
else
strcpyW(This->URLName,lpszURLName);
}
else
strcpyW(This->URLName,lpszURLName);
URLMON_LockModule();
@ -1349,6 +1254,42 @@ HRESULT WINAPI IsAsyncMoniker(IMoniker *pmk)
return S_FALSE;
}
/***********************************************************************
* BindAsyncMoniker (URLMON.@)
*
* Bind a bind status callback to an asynchronous URL Moniker.
*
* PARAMS
* pmk [I] Moniker object to bind status callback to
* grfOpt [I] Options, seems not used
* pbsc [I] Status callback to bind
* iidResult [I] Interface to return
* ppvResult [O] Resulting asynchronous moniker object
*
* RETURNS
* Success: S_OK.
* Failure: E_INVALIDARG, if any argument is invalid, or
* E_OUTOFMEMORY if memory allocation fails.
*/
HRESULT WINAPI BindAsyncMoniker(IMoniker *pmk, DWORD grfOpt, IBindStatusCallback *pbsc, REFIID iidResult, LPVOID *ppvResult)
{
LPBC pbc = NULL;
HRESULT hr = E_INVALIDARG;
if (pmk && ppvResult)
{
*ppvResult = NULL;
hr = CreateAsyncBindCtx(0, pbsc, NULL, &pbc);
if (hr == NOERROR)
{
hr = IMoniker_BindToObject(pmk, pbc, NULL, iidResult, ppvResult);
IBindCtx_Release(pbc);
}
}
return hr;
}
/***********************************************************************
* RegisterBindStatusCallback (URLMON.@)
*

View file

@ -7,7 +7,7 @@
@ stub AsyncGetClassBits
@ stub AsyncInstallDistributionUnit
@ stub BindAsyncMoniker
@ stdcall BindAsyncMoniker(ptr long ptr ptr ptr)
@ stdcall CoGetClassObjectFromURL(ptr wstr long long wstr ptr long ptr ptr ptr)
@ stub CoInstall
@ stdcall CoInternetCombineUrl(wstr wstr long wstr long ptr long)