Author: dchapyshev
Date: Wed Mar 4 18:29:32 2009
New Revision: 39867
URL:
http://svn.reactos.org/svn/reactos?rev=39867&view=rev
Log:
- Sync crypt32, jscript, mapi32, mlang, msctf, msvcrt20, msvcrt40, msxml3, snmpapi, urlmon
with Wine head
Added:
trunk/reactos/dll/win32/mapi32/version.rc (with props)
trunk/reactos/dll/win32/urlmon/protocol.c (with props)
Modified:
trunk/reactos/dll/win32/crypt32/chain.c
trunk/reactos/dll/win32/crypt32/decode.c
trunk/reactos/dll/win32/jscript/jsutils.c
trunk/reactos/dll/win32/mapi32/mapi32.rbuild
trunk/reactos/dll/win32/mlang/mlang.c
trunk/reactos/dll/win32/msctf/categorymgr.c
trunk/reactos/dll/win32/msctf/inputprocessor.c
trunk/reactos/dll/win32/msvcrt20/msvcrt20.spec
trunk/reactos/dll/win32/msvcrt40/msvcrt40.c
trunk/reactos/dll/win32/msvcrt40/msvcrt40.spec
trunk/reactos/dll/win32/msxml3/node.c
trunk/reactos/dll/win32/snmpapi/main.c
trunk/reactos/dll/win32/urlmon/binding.c
trunk/reactos/dll/win32/urlmon/ftp.c
trunk/reactos/dll/win32/urlmon/http.c
trunk/reactos/dll/win32/urlmon/umon.c
trunk/reactos/dll/win32/urlmon/urlmon.rbuild
trunk/reactos/dll/win32/urlmon/urlmon_main.h
Modified: trunk/reactos/dll/win32/crypt32/chain.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/crypt32/chain.c?…
==============================================================================
--- trunk/reactos/dll/win32/crypt32/chain.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/crypt32/chain.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -306,7 +306,13 @@
= subjectInfoStatus;
/* FIXME: initialize the rest of element */
if (!(chain->cElement % engine->CycleDetectionModulus))
+ {
CRYPT_CheckSimpleChainForCycles(chain);
+ /* Reinitialize the element pointer in case the chain is
+ * cyclic, in which case the chain is truncated.
+ */
+ element = chain->rgpElement[chain->cElement - 1];
+ }
CRYPT_CombineTrustStatus(&chain->TrustStatus,
&element->TrustStatus);
ret = TRUE;
Modified: trunk/reactos/dll/win32/crypt32/decode.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/crypt32/decode.c…
==============================================================================
--- trunk/reactos/dll/win32/crypt32/decode.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/crypt32/decode.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -1724,9 +1724,8 @@
case ASN_UTF8STRING:
value->Value.cbData = MultiByteToWideChar(CP_UTF8, 0,
(LPCSTR)pbEncoded + 1 + lenBytes, dataLen,
- str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * 2;
- value->Value.pbData[value->Value.cbData / sizeof(WCHAR)]
- = 0;
+ str, bytesNeeded - sizeof(CERT_NAME_VALUE)) * sizeof(WCHAR);
+ *(WCHAR *)(value->Value.pbData + value->Value.cbData) = 0;
value->Value.cbData += sizeof(WCHAR);
break;
}
Modified: trunk/reactos/dll/win32/jscript/jsutils.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/jscript/jsutils.…
==============================================================================
--- trunk/reactos/dll/win32/jscript/jsutils.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/jscript/jsutils.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -27,6 +27,7 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+WINE_DECLARE_DEBUG_CHANNEL(heap);
const char *debugstr_variant(const VARIANT *v)
{
@@ -51,6 +52,7 @@
}
#define MIN_BLOCK_SIZE 128
+#define ARENA_FREE_FILLER 0xaa
static inline DWORD block_size(DWORD block)
{
@@ -83,25 +85,25 @@
heap->block_cnt = 1;
}
- if(heap->offset + size < block_size(heap->last_block)) {
+ if(heap->offset + size <= block_size(heap->last_block)) {
tmp = ((BYTE*)heap->blocks[heap->last_block])+heap->offset;
heap->offset += size;
return tmp;
}
- if(size < block_size(heap->last_block+1)) {
+ if(size <= block_size(heap->last_block+1)) {
if(heap->last_block+1 == heap->block_cnt) {
tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
if(!tmp)
return NULL;
+
heap->blocks = tmp;
+ heap->blocks[heap->block_cnt] =
heap_alloc(block_size(heap->block_cnt));
+ if(!heap->blocks[heap->block_cnt])
+ return NULL;
+
+ heap->block_cnt++;
}
-
- tmp = heap_alloc(block_size(heap->block_cnt+1));
- if(!tmp)
- return NULL;
-
- heap->blocks[heap->block_cnt++] = tmp;
heap->last_block++;
heap->offset = size;
@@ -139,7 +141,15 @@
heap_free(tmp);
}
+ if(WARN_ON(heap)) {
+ DWORD i;
+
+ for(i=0; i < heap->block_cnt; i++)
+ memset(heap->blocks[i], ARENA_FREE_FILLER, block_size(i));
+ }
+
heap->last_block = heap->offset = 0;
+ heap->mark = FALSE;
}
void jsheap_free(jsheap_t *heap)
Modified: trunk/reactos/dll/win32/mapi32/mapi32.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mapi32/mapi32.rb…
==============================================================================
--- trunk/reactos/dll/win32/mapi32/mapi32.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mapi32/mapi32.rbuild [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -11,6 +11,7 @@
<file>prop.c</file>
<file>sendmail.c</file>
<file>util.c</file>
+ <file>version.rc</file>
<library>wine</library>
<library>shlwapi</library>
<library>shell32</library>
Added: trunk/reactos/dll/win32/mapi32/version.rc
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mapi32/version.r…
==============================================================================
--- trunk/reactos/dll/win32/mapi32/version.rc (added)
+++ trunk/reactos/dll/win32/mapi32/version.rc [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -1,0 +1,22 @@
+/*
+ * Copyright 2009 Vincent Povirk 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine Messaging API"
+#define WINE_FILENAME_STR "mapi32.dll"
+
+#include "wine/wine_common_ver.rc"
Propchange: trunk/reactos/dll/win32/mapi32/version.rc
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/win32/mlang/mlang.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/mlang/mlang.c?re…
==============================================================================
--- trunk/reactos/dll/win32/mlang/mlang.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/mlang/mlang.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -1912,9 +1912,34 @@
DWORD* pdwCodePages,
long* pcchCodePages)
{
- FIXME("(pszSrc=%s, cchSrc=%ld, dwPriorityCodePages=%d) stub\n",
debugstr_w(pszSrc), cchSrc, dwPriorityCodePages);
- *pdwCodePages = 0;
- *pcchCodePages = 1;
+ long i;
+ DWORD cps = 0;
+
+ TRACE("(%p)->%s %ld %x %p %p\n", iface,
debugstr_wn(pszSrc,cchSrc),cchSrc,dwPriorityCodePages,pdwCodePages,pcchCodePages);
+
+ if (pdwCodePages) *pdwCodePages = 0;
+ if (pcchCodePages) *pcchCodePages = 0;
+
+ if (!pszSrc || !cchSrc || cchSrc < 0)
+ return E_INVALIDARG;
+
+ for (i = 0; i < cchSrc; i++)
+ {
+ DWORD cp;
+ HRESULT ret;
+
+ ret = fnIMLangFontLink_GetCharCodePages(iface, pszSrc[i], &cp);
+ if (ret != S_OK) return E_FAIL;
+
+ if (!cps) cps = cp;
+ else cps &= cp;
+
+ /* FIXME: not tested */
+ if (dwPriorityCodePages & cps) break;
+ }
+
+ if (pdwCodePages) *pdwCodePages = cps;
+ if (pcchCodePages) *pcchCodePages = i;
return S_OK;
}
@@ -3179,10 +3204,8 @@
const WCHAR *pszSrc, long cchSrc, DWORD dwPriorityCodePages,
DWORD *pdwCodePages, long *pcchCodePages)
{
- FIXME("(%p)->%s %li %x %p %p\n",This,
debugstr_wn(pszSrc,cchSrc),cchSrc,dwPriorityCodePages,pdwCodePages,pcchCodePages);
- *pdwCodePages = 0;
- *pcchCodePages = 1;
- return S_OK;
+ return fnIMLangFontLink_GetStrCodePages((IMLangFontLink *)This,
+ pszSrc, cchSrc, dwPriorityCodePages, pdwCodePages, pcchCodePages);
}
static HRESULT WINAPI fnIMLangFontLink2_CodePageToCodePages(IMLangFontLink2* This,
Modified: trunk/reactos/dll/win32/msctf/categorymgr.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/categorymg…
==============================================================================
--- trunk/reactos/dll/win32/msctf/categorymgr.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/categorymgr.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -168,9 +168,67 @@
static HRESULT WINAPI CategoryMgr_FindClosestCategory ( ITfCategoryMgr *iface,
REFGUID rguid, GUID *pcatid, const GUID **ppcatidList, ULONG ulCount)
{
- CategoryMgr *This = (CategoryMgr*)iface;
- FIXME("STUB:(%p)\n",This);
- return E_NOTIMPL;
+ static const WCHAR fmt[] = {
'%','s','\\','%','s','\\','C','a','t','e','g','o','r','y','\\','I','t','e','m','\\','%','s',0};
+
+ WCHAR fullkey[110];
+ WCHAR buf[39];
+ HKEY key;
+ HRESULT hr = S_FALSE;
+ INT index = 0;
+ CategoryMgr *This = (CategoryMgr*)iface;
+
+ TRACE("(%p)\n",This);
+
+ if (!pcatid || (ulCount && ppcatidList == NULL))
+ return E_INVALIDARG;
+
+ StringFromGUID2(rguid, buf, 39);
+ sprintfW(fullkey,fmt,szwSystemTIPKey,buf,buf);
+ *pcatid = GUID_NULL;
+
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE,fullkey, 0, KEY_READ, &key ) !=
+ ERROR_SUCCESS)
+ return S_FALSE;
+
+ while (1)
+ {
+ HRESULT hr2;
+ ULONG res;
+ GUID guid;
+ WCHAR catid[39];
+ DWORD cName;
+
+ cName = 39;
+ res = RegEnumKeyExW(key, index, catid, &cName, NULL, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) break;
+ index ++;
+
+ hr2 = CLSIDFromString(catid, &guid);
+ if (FAILED(hr2)) continue;
+
+ if (ulCount)
+ {
+ int j;
+ BOOL found = FALSE;
+ for (j = 0; j < ulCount; j++)
+ if (IsEqualGUID(&guid, ppcatidList[j]))
+ {
+ found = TRUE;
+ *pcatid = guid;
+ hr = S_OK;
+ break;
+ }
+ if (found) break;
+ }
+ else
+ {
+ *pcatid = guid;
+ hr = S_OK;
+ break;
+ }
+ }
+
+ return hr;
}
static HRESULT WINAPI CategoryMgr_RegisterGUIDDescription (
Modified: trunk/reactos/dll/win32/msctf/inputprocessor.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msctf/inputproce…
==============================================================================
--- trunk/reactos/dll/win32/msctf/inputprocessor.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msctf/inputprocessor.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -72,6 +72,7 @@
DWORD lang_index;
LANGID langid;
+ ITfCategoryMgr *catmgr;
} EnumTfLanguageProfiles;
static HRESULT ProfilesEnumGuid_Constructor(IEnumGUID **ppOut);
@@ -670,6 +671,7 @@
RegCloseKey(This->tipkey);
if (This->langkey)
RegCloseKey(This->langkey);
+ ITfCategoryMgr_Release(This->catmgr);
HeapFree(GetProcessHeap(),0,This);
}
@@ -746,6 +748,9 @@
if (tflp)
{
+ static const GUID * tipcats[3] = { &GUID_TFCAT_TIP_KEYBOARD,
+ &GUID_TFCAT_TIP_SPEECH,
+ &GUID_TFCAT_TIP_HANDWRITING };
res = CLSIDFromString(profileid, &profile);
if (FAILED(res)) return 0;
@@ -754,7 +759,10 @@
/* FIXME */
tflp->fActive = FALSE;
tflp->guidProfile = profile;
- /* FIXME set catid */
+ if (ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
+ &tflp->catid, tipcats, 3) != S_OK)
+ ITfCategoryMgr_FindClosestCategory(This->catmgr, &clsid,
+ &tflp->catid, NULL, 0);
}
return 1;
@@ -865,6 +873,7 @@
static HRESULT EnumTfLanguageProfiles_Constructor(LANGID langid, IEnumTfLanguageProfiles
**ppOut)
{
+ HRESULT hr;
EnumTfLanguageProfiles *This;
This = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(EnumTfLanguageProfiles));
@@ -875,6 +884,13 @@
This->refCount = 1;
This->langid = langid;
+ hr = CategoryMgr_Constructor(NULL,(IUnknown**)&This->catmgr);
+ if (FAILED(hr))
+ {
+ HeapFree(GetProcessHeap(),0,This);
+ return hr;
+ }
+
if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, szwSystemTIPKey, 0, NULL, 0,
KEY_READ | KEY_WRITE, NULL, &This->tipkey, NULL) !=
ERROR_SUCCESS)
return E_FAIL;
Modified: trunk/reactos/dll/win32/msvcrt20/msvcrt20.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msvcrt20/msvcrt2…
==============================================================================
--- trunk/reactos/dll/win32/msvcrt20/msvcrt20.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msvcrt20/msvcrt20.spec [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -437,22 +437,22 @@
@ stub ?xsgetn@streambuf@@UAEHPADH@Z #
@ stub ?xsputn@streambuf@@UAEHPBDH@Z #
@ stub $I10_OUTPUT #
-@ cdecl _CIacos() msvcrt._CIacos
-@ cdecl _CIasin() msvcrt._CIasin
-@ cdecl _CIatan() msvcrt._CIatan
-@ cdecl _CIatan2() msvcrt._CIatan2
-@ cdecl _CIcos() msvcrt._CIcos
-@ cdecl _CIcosh() msvcrt._CIcosh
-@ cdecl _CIexp() msvcrt._CIexp
-@ cdecl _CIfmod() msvcrt._CIfmod
-@ cdecl _CIlog() msvcrt._CIlog
-@ cdecl _CIlog10() msvcrt._CIlog10
-@ cdecl _CIpow() msvcrt._CIpow
-@ cdecl _CIsin() msvcrt._CIsin
-@ cdecl _CIsinh() msvcrt._CIsinh
-@ cdecl _CIsqrt() msvcrt._CIsqrt
-@ cdecl _CItan() msvcrt._CItan
-@ cdecl _CItanh() msvcrt._CItanh
+@ cdecl -arch=i386 _CIacos() msvcrt._CIacos
+@ cdecl -arch=i386 _CIasin() msvcrt._CIasin
+@ cdecl -arch=i386 _CIatan() msvcrt._CIatan
+@ cdecl -arch=i386 _CIatan2() msvcrt._CIatan2
+@ cdecl -arch=i386 _CIcos() msvcrt._CIcos
+@ cdecl -arch=i386 _CIcosh() msvcrt._CIcosh
+@ cdecl -arch=i386 _CIexp() msvcrt._CIexp
+@ cdecl -arch=i386 _CIfmod() msvcrt._CIfmod
+@ cdecl -arch=i386 _CIlog() msvcrt._CIlog
+@ cdecl -arch=i386 _CIlog10() msvcrt._CIlog10
+@ cdecl -arch=i386 _CIpow() msvcrt._CIpow
+@ cdecl -arch=i386 _CIsin() msvcrt._CIsin
+@ cdecl -arch=i386 _CIsinh() msvcrt._CIsinh
+@ cdecl -arch=i386 _CIsqrt() msvcrt._CIsqrt
+@ cdecl -arch=i386 _CItan() msvcrt._CItan
+@ cdecl -arch=i386 _CItanh() msvcrt._CItanh
@ cdecl _CxxThrowException(long long) msvcrt._CxxThrowException
@ extern _HUGE msvcrt._HUGE
@ cdecl _XcptFilter(long ptr) msvcrt._XcptFilter
@@ -471,32 +471,32 @@
@ cdecl __iscsymf(long) msvcrt.__iscsymf
@ cdecl __lconv_init() msvcrt.__lconv_init
@ extern __mb_cur_max msvcrt.__mb_cur_max
-@ cdecl __p___argc() msvcrt.__p___argc
-@ cdecl __p___argv() msvcrt.__p___argv
-@ cdecl __p___initenv() msvcrt.__p___initenv
-@ cdecl __p___mb_cur_max() msvcrt.__p___mb_cur_max
-@ cdecl __p___wargv() msvcrt.__p___wargv
-@ cdecl __p___winitenv() msvcrt.__p___winitenv
-@ cdecl __p__acmdln() msvcrt.__p__acmdln
-@ cdecl __p__amblksiz() msvcrt.__p__amblksiz
-@ cdecl __p__commode() msvcrt.__p__commode
-@ cdecl __p__daylight() msvcrt.__p__daylight
-@ cdecl __p__environ() msvcrt.__p__environ
-@ cdecl __p__fmode() msvcrt.__p__fmode
-@ cdecl __p__iob() msvcrt.__p__iob
-@ cdecl __p__mbctype() msvcrt.__p__mbctype
-@ cdecl __p__osver() msvcrt.__p__osver
-@ cdecl __p__pctype() msvcrt.__p__pctype
-@ cdecl __p__pgmptr() msvcrt.__p__pgmptr
-@ cdecl __p__pwctype() msvcrt.__p__pwctype
-@ cdecl __p__timezone() msvcrt.__p__timezone
-@ cdecl __p__tzname() msvcrt.__p__tzname
-@ cdecl __p__wcmdln() msvcrt.__p__wcmdln
-@ cdecl __p__wenviron() msvcrt.__p__wenviron
-@ cdecl __p__winmajor() msvcrt.__p__winmajor
-@ cdecl __p__winminor() msvcrt.__p__winminor
-@ cdecl __p__winver() msvcrt.__p__winver
-@ cdecl __p__wpgmptr() msvcrt.__p__wpgmptr
+@ cdecl -arch=i386 __p___argc() msvcrt.__p___argc
+@ cdecl -arch=i386 __p___argv() msvcrt.__p___argv
+@ cdecl -arch=i386 __p___initenv() msvcrt.__p___initenv
+@ cdecl -arch=i386 __p___mb_cur_max() msvcrt.__p___mb_cur_max
+@ cdecl -arch=i386 __p___wargv() msvcrt.__p___wargv
+@ cdecl -arch=i386 __p___winitenv() msvcrt.__p___winitenv
+@ cdecl -arch=i386 __p__acmdln() msvcrt.__p__acmdln
+@ cdecl -arch=i386 __p__amblksiz() msvcrt.__p__amblksiz
+@ cdecl -arch=i386 __p__commode() msvcrt.__p__commode
+@ cdecl -arch=i386 __p__daylight() msvcrt.__p__daylight
+@ cdecl -arch=i386 __p__environ() msvcrt.__p__environ
+@ cdecl -arch=i386 __p__fmode() msvcrt.__p__fmode
+@ cdecl -arch=i386 __p__iob() msvcrt.__p__iob
+@ cdecl -arch=i386 __p__mbctype() msvcrt.__p__mbctype
+@ cdecl -arch=i386 __p__osver() msvcrt.__p__osver
+@ cdecl -arch=i386 __p__pctype() msvcrt.__p__pctype
+@ cdecl -arch=i386 __p__pgmptr() msvcrt.__p__pgmptr
+@ cdecl -arch=i386 __p__pwctype() msvcrt.__p__pwctype
+@ cdecl -arch=i386 __p__timezone() msvcrt.__p__timezone
+@ cdecl -arch=i386 __p__tzname() msvcrt.__p__tzname
+@ cdecl -arch=i386 __p__wcmdln() msvcrt.__p__wcmdln
+@ cdecl -arch=i386 __p__wenviron() msvcrt.__p__wenviron
+@ cdecl -arch=i386 __p__winmajor() msvcrt.__p__winmajor
+@ cdecl -arch=i386 __p__winminor() msvcrt.__p__winminor
+@ cdecl -arch=i386 __p__winver() msvcrt.__p__winver
+@ cdecl -arch=i386 __p__wpgmptr() msvcrt.__p__wpgmptr
@ cdecl __pxcptinfoptrs() msvcrt.__pxcptinfoptrs
@ cdecl __threadhandle() msvcrt.__threadhandle
@ cdecl __threadid() msvcrt.__threadid
Modified: trunk/reactos/dll/win32/msvcrt40/msvcrt40.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msvcrt40/msvcrt4…
==============================================================================
--- trunk/reactos/dll/win32/msvcrt40/msvcrt40.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msvcrt40/msvcrt40.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -22,9 +22,6 @@
#include "windef.h"
#include "winbase.h"
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(msvcrt40);
BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserved )
{
Modified: trunk/reactos/dll/win32/msvcrt40/msvcrt40.spec
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msvcrt40/msvcrt4…
==============================================================================
--- trunk/reactos/dll/win32/msvcrt40/msvcrt40.spec [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msvcrt40/msvcrt40.spec [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -481,22 +481,22 @@
@ stub ?xsgetn@streambuf@@UAEHPADH@Z
@ stub ?xsputn@streambuf@@UAEHPBDH@Z
@ cdecl $I10_OUTPUT() msvcrt.$I10_OUTPUT
-@ cdecl _CIacos() msvcrt._CIacos
-@ cdecl _CIasin() msvcrt._CIasin
-@ cdecl _CIatan() msvcrt._CIatan
-@ cdecl _CIatan2() msvcrt._CIatan2
-@ cdecl _CIcos() msvcrt._CIcos
-@ cdecl _CIcosh() msvcrt._CIcosh
-@ cdecl _CIexp() msvcrt._CIexp
-@ cdecl _CIfmod() msvcrt._CIfmod
-@ cdecl _CIlog() msvcrt._CIlog
-@ cdecl _CIlog10() msvcrt._CIlog10
-@ cdecl _CIpow() msvcrt._CIpow
-@ cdecl _CIsin() msvcrt._CIsin
-@ cdecl _CIsinh() msvcrt._CIsinh
-@ cdecl _CIsqrt() msvcrt._CIsqrt
-@ cdecl _CItan() msvcrt._CItan
-@ cdecl _CItanh() msvcrt._CItanh
+@ cdecl -arch=i386 _CIacos() msvcrt._CIacos
+@ cdecl -arch=i386 _CIasin() msvcrt._CIasin
+@ cdecl -arch=i386 _CIatan() msvcrt._CIatan
+@ cdecl -arch=i386 _CIatan2() msvcrt._CIatan2
+@ cdecl -arch=i386 _CIcos() msvcrt._CIcos
+@ cdecl -arch=i386 _CIcosh() msvcrt._CIcosh
+@ cdecl -arch=i386 _CIexp() msvcrt._CIexp
+@ cdecl -arch=i386 _CIfmod() msvcrt._CIfmod
+@ cdecl -arch=i386 _CIlog() msvcrt._CIlog
+@ cdecl -arch=i386 _CIlog10() msvcrt._CIlog10
+@ cdecl -arch=i386 _CIpow() msvcrt._CIpow
+@ cdecl -arch=i386 _CIsin() msvcrt._CIsin
+@ cdecl -arch=i386 _CIsinh() msvcrt._CIsinh
+@ cdecl -arch=i386 _CIsqrt() msvcrt._CIsqrt
+@ cdecl -arch=i386 _CItan() msvcrt._CItan
+@ cdecl -arch=i386 _CItanh() msvcrt._CItanh
@ cdecl _CxxThrowException(long long) msvcrt._CxxThrowException
@ cdecl -i386 _EH_prolog() msvcrt._EH_prolog
@ extern _HUGE msvcrt._HUGE
@@ -519,33 +519,33 @@
@ cdecl __iscsymf(long) msvcrt.__iscsymf
@ cdecl __lconv_init() msvcrt.__lconv_init
@ extern __mb_cur_max msvcrt.__mb_cur_max
-@ cdecl __p___argc() msvcrt.__p___argc
-@ cdecl __p___argv() msvcrt.__p___argv
-@ cdecl __p___initenv() msvcrt.__p___initenv
-@ cdecl __p___mb_cur_max() msvcrt.__p___mb_cur_max
-@ cdecl __p___wargv() msvcrt.__p___wargv
-@ cdecl __p___winitenv() msvcrt.__p___winitenv
-@ cdecl __p__acmdln() msvcrt.__p__acmdln
-@ cdecl __p__amblksiz() msvcrt.__p__amblksiz
-@ cdecl __p__commode() msvcrt.__p__commode
-@ cdecl __p__daylight() msvcrt.__p__daylight
-@ cdecl __p__dstbias() msvcrt.__p__dstbias
-@ cdecl __p__environ() msvcrt.__p__environ
-@ cdecl __p__fmode() msvcrt.__p__fmode
-@ cdecl __p__iob() msvcrt.__p__iob
-@ cdecl __p__mbctype() msvcrt.__p__mbctype
-@ cdecl __p__osver() msvcrt.__p__osver
-@ cdecl __p__pctype() msvcrt.__p__pctype
-@ cdecl __p__pgmptr() msvcrt.__p__pgmptr
-@ cdecl __p__pwctype() msvcrt.__p__pwctype
-@ cdecl __p__timezone() msvcrt.__p__timezone
-@ cdecl __p__tzname() msvcrt.__p__tzname
-@ cdecl __p__wcmdln() msvcrt.__p__wcmdln
-@ cdecl __p__wenviron() msvcrt.__p__wenviron
-@ cdecl __p__winmajor() msvcrt.__p__winmajor
-@ cdecl __p__winminor() msvcrt.__p__winminor
-@ cdecl __p__winver() msvcrt.__p__winver
-@ cdecl __p__wpgmptr() msvcrt.__p__wpgmptr
+@ cdecl -arch=i386 __p___argc() msvcrt.__p___argc
+@ cdecl -arch=i386 __p___argv() msvcrt.__p___argv
+@ cdecl -arch=i386 __p___initenv() msvcrt.__p___initenv
+@ cdecl -arch=i386 __p___mb_cur_max() msvcrt.__p___mb_cur_max
+@ cdecl -arch=i386 __p___wargv() msvcrt.__p___wargv
+@ cdecl -arch=i386 __p___winitenv() msvcrt.__p___winitenv
+@ cdecl -arch=i386 __p__acmdln() msvcrt.__p__acmdln
+@ cdecl -arch=i386 __p__amblksiz() msvcrt.__p__amblksiz
+@ cdecl -arch=i386 __p__commode() msvcrt.__p__commode
+@ cdecl -arch=i386 __p__daylight() msvcrt.__p__daylight
+@ cdecl -arch=i386 __p__dstbias() msvcrt.__p__dstbias
+@ cdecl -arch=i386 __p__environ() msvcrt.__p__environ
+@ cdecl -arch=i386 __p__fmode() msvcrt.__p__fmode
+@ cdecl -arch=i386 __p__iob() msvcrt.__p__iob
+@ cdecl -arch=i386 __p__mbctype() msvcrt.__p__mbctype
+@ cdecl -arch=i386 __p__osver() msvcrt.__p__osver
+@ cdecl -arch=i386 __p__pctype() msvcrt.__p__pctype
+@ cdecl -arch=i386 __p__pgmptr() msvcrt.__p__pgmptr
+@ cdecl -arch=i386 __p__pwctype() msvcrt.__p__pwctype
+@ cdecl -arch=i386 __p__timezone() msvcrt.__p__timezone
+@ cdecl -arch=i386 __p__tzname() msvcrt.__p__tzname
+@ cdecl -arch=i386 __p__wcmdln() msvcrt.__p__wcmdln
+@ cdecl -arch=i386 __p__wenviron() msvcrt.__p__wenviron
+@ cdecl -arch=i386 __p__winmajor() msvcrt.__p__winmajor
+@ cdecl -arch=i386 __p__winminor() msvcrt.__p__winminor
+@ cdecl -arch=i386 __p__winver() msvcrt.__p__winver
+@ cdecl -arch=i386 __p__wpgmptr() msvcrt.__p__wpgmptr
@ cdecl __pxcptinfoptrs() msvcrt.__pxcptinfoptrs
@ cdecl __set_app_type(long) msvcrt.__set_app_type
@ cdecl __setusermatherr(ptr) msvcrt.__setusermatherr
Modified: trunk/reactos/dll/win32/msxml3/node.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/msxml3/node.c?re…
==============================================================================
--- trunk/reactos/dll/win32/msxml3/node.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/msxml3/node.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -387,6 +387,11 @@
if ( !out )
return E_INVALIDARG;
+
+ /* if we dont have a doc, use our parent. */
+ if(node && !node->doc && node->parent)
+ node->doc = node->parent->doc;
+
*out = create_node( node );
if (!*out)
return S_FALSE;
Modified: trunk/reactos/dll/win32/snmpapi/main.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/snmpapi/main.c?r…
==============================================================================
--- trunk/reactos/dll/win32/snmpapi/main.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/snmpapi/main.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -19,6 +19,8 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#include "config.h"
+
#include <stdio.h>
#include <stdarg.h>
Modified: trunk/reactos/dll/win32/urlmon/binding.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/binding.c…
==============================================================================
--- trunk/reactos/dll/win32/urlmon/binding.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/urlmon/binding.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -1200,7 +1200,7 @@
TRACE("(%p)->(%d %u %u)\n", This, bscf, progress, progress_max);
- if(This->download_state == END_DOWNLOAD)
+ if(This->download_state == END_DOWNLOAD || (This->state &
BINDING_STOPPED))
return;
if(GetCurrentThreadId() != This->apartment_thread)
Modified: trunk/reactos/dll/win32/urlmon/ftp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/ftp.c?rev…
==============================================================================
--- trunk/reactos/dll/win32/urlmon/ftp.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/urlmon/ftp.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -1,5 +1,5 @@
/*
- * Copyright 2005 Jacek Caban
+ * Copyright 2005-2009 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
@@ -22,13 +22,63 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
typedef struct {
+ Protocol base;
+
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
+ const IInternetPriorityVtbl *lpInternetPriorityVtbl;
+
LONG ref;
} FtpProtocol;
+#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
+#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
+
+#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(FtpProtocol, base, iface)
+
+static HRESULT FtpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD
request_flags,
+ IInternetBindInfo *bind_info)
+{
+ FtpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+
+ This->base.request = InternetOpenUrlW(This->base.internet, url, NULL, 0,
+ request_flags|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_PASSIVE,
+ (DWORD_PTR)&This->base);
+ if (!This->base.request && GetLastError() != ERROR_IO_PENDING) {
+ WARN("InternetOpenUrl failed: %d\n", GetLastError());
+ return INET_E_RESOURCE_NOT_FOUND;
+ }
+
+ return S_OK;
+}
+
+static HRESULT FtpProtocol_start_downloading(Protocol *prot)
+{
+ FtpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ DWORD size;
+ BOOL res;
+
+ res = FtpGetFileSize(This->base.request, &size);
+ if(res)
+ This->base.content_length = size;
+ else
+ WARN("FtpGetFileSize failed: %d\n", GetLastError());
+
+ return S_OK;
+}
+
+static void FtpProtocol_close_connection(Protocol *prot)
+{
+}
+
+#undef ASYNCPROTOCOL_THIS
+
+static const ProtocolVtbl AsyncProtocolVtbl = {
+ FtpProtocol_open_request,
+ FtpProtocol_start_downloading,
+ FtpProtocol_close_connection
+};
+
#define PROTOCOL_THIS(iface) DEFINE_THIS(FtpProtocol, InternetProtocol, iface)
-
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
static HRESULT WINAPI FtpProtocol_QueryInterface(IInternetProtocol *iface, REFIID riid,
void **ppv)
{
@@ -44,6 +94,9 @@
}else if(IsEqualGUID(&IID_IInternetProtocol, riid)) {
TRACE("(%p)->(IID_IInternetProtocol %p)\n", This, ppv);
*ppv = PROTOCOL(This);
+ }else if(IsEqualGUID(&IID_IInternetPriority, riid)) {
+ TRACE("(%p)->(IID_IInternetPriority %p)\n", This, ppv);
+ *ppv = PRIORITY(This);
}
if(*ppv) {
@@ -71,6 +124,7 @@
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
+ protocol_close_connection(&This->base);
heap_free(This);
URLMON_UnlockModule();
@@ -84,16 +138,25 @@
DWORD grfPI, DWORD dwReserved)
{
FtpProtocol *This = PROTOCOL_THIS(iface);
- FIXME("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl),
pOIProtSink,
- pOIBindInfo, grfPI, dwReserved);
- return E_NOTIMPL;
+
+ static const WCHAR ftpW[] = {'f','t','p',':'};
+
+ TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl),
pOIProtSink,
+ pOIBindInfo, grfPI, dwReserved);
+
+ if(strncmpW(szUrl, ftpW, sizeof(ftpW)/sizeof(WCHAR)))
+ return MK_E_SYNTAX;
+
+ return protocol_start(&This->base, PROTOCOL(This), szUrl, pOIProtSink,
pOIBindInfo);
}
static HRESULT WINAPI FtpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA
*pProtocolData)
{
FtpProtocol *This = PROTOCOL_THIS(iface);
- FIXME("(%p)->(%p)\n", This, pProtocolData);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%p)\n", This, pProtocolData);
+
+ return protocol_continue(&This->base, pProtocolData);
}
static HRESULT WINAPI FtpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
@@ -107,8 +170,11 @@
static HRESULT WINAPI FtpProtocol_Terminate(IInternetProtocol *iface, DWORD dwOptions)
{
FtpProtocol *This = PROTOCOL_THIS(iface);
- FIXME("(%p)->(%08x)\n", This, dwOptions);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%08x)\n", This, dwOptions);
+
+ protocol_close_connection(&This->base);
+ return S_OK;
}
static HRESULT WINAPI FtpProtocol_Suspend(IInternetProtocol *iface)
@@ -129,8 +195,10 @@
ULONG cb, ULONG *pcbRead)
{
FtpProtocol *This = PROTOCOL_THIS(iface);
- FIXME("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
+
+ return protocol_read(&This->base, pv, cb, pcbRead);
}
static HRESULT WINAPI FtpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER dlibMove,
@@ -144,15 +212,19 @@
static HRESULT WINAPI FtpProtocol_LockRequest(IInternetProtocol *iface, DWORD dwOptions)
{
FtpProtocol *This = PROTOCOL_THIS(iface);
- FIXME("(%p)->(%08x)\n", This, dwOptions);
- return E_NOTIMPL;
+
+ TRACE("(%p)->(%08x)\n", This, dwOptions);
+
+ return protocol_lock_request(&This->base);
}
static HRESULT WINAPI FtpProtocol_UnlockRequest(IInternetProtocol *iface)
{
FtpProtocol *This = PROTOCOL_THIS(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
+
+ TRACE("(%p)\n", This);
+
+ return protocol_unlock_request(&This->base);
}
#undef PROTOCOL_THIS
@@ -173,6 +245,56 @@
FtpProtocol_UnlockRequest
};
+#define PRIORITY_THIS(iface) DEFINE_THIS(FtpProtocol, InternetPriority, iface)
+
+static HRESULT WINAPI FtpPriority_QueryInterface(IInternetPriority *iface, REFIID riid,
void **ppv)
+{
+ FtpProtocol *This = PRIORITY_THIS(iface);
+ return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
+}
+
+static ULONG WINAPI FtpPriority_AddRef(IInternetPriority *iface)
+{
+ FtpProtocol *This = PRIORITY_THIS(iface);
+ return IInternetProtocol_AddRef(PROTOCOL(This));
+}
+
+static ULONG WINAPI FtpPriority_Release(IInternetPriority *iface)
+{
+ FtpProtocol *This = PRIORITY_THIS(iface);
+ return IInternetProtocol_Release(PROTOCOL(This));
+}
+
+static HRESULT WINAPI FtpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
+{
+ FtpProtocol *This = PRIORITY_THIS(iface);
+
+ TRACE("(%p)->(%d)\n", This, nPriority);
+
+ This->base.priority = nPriority;
+ return S_OK;
+}
+
+static HRESULT WINAPI FtpPriority_GetPriority(IInternetPriority *iface, LONG
*pnPriority)
+{
+ FtpProtocol *This = PRIORITY_THIS(iface);
+
+ TRACE("(%p)->(%p)\n", This, pnPriority);
+
+ *pnPriority = This->base.priority;
+ return S_OK;
+}
+
+#undef PRIORITY_THIS
+
+static const IInternetPriorityVtbl FtpPriorityVtbl = {
+ FtpPriority_QueryInterface,
+ FtpPriority_AddRef,
+ FtpPriority_Release,
+ FtpPriority_SetPriority,
+ FtpPriority_GetPriority
+};
+
HRESULT FtpProtocol_Construct(IUnknown *pUnkOuter, LPVOID *ppobj)
{
FtpProtocol *ret;
@@ -181,9 +303,11 @@
URLMON_LockModule();
- ret = heap_alloc(sizeof(FtpProtocol));
-
+ ret = heap_alloc_zero(sizeof(FtpProtocol));
+
+ ret->base.vtbl = &AsyncProtocolVtbl;
ret->lpInternetProtocolVtbl = &FtpProtocolVtbl;
+ ret->lpInternetPriorityVtbl = &FtpPriorityVtbl;
ret->ref = 1;
*ppobj = PROTOCOL(ret);
Modified: trunk/reactos/dll/win32/urlmon/http.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/http.c?re…
==============================================================================
--- trunk/reactos/dll/win32/urlmon/http.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/urlmon/http.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -29,215 +29,283 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-/* Flags are needed for, among other things, return HRESULTs from the Read function
- * to conform to native. For example, Read returns:
- *
- * 1. E_PENDING if called before the request has completed,
- * (flags = 0)
- * 2. S_FALSE after all data has been read and S_OK has been reported,
- * (flags = FLAG_REQUEST_COMPLETE | FLAG_ALL_DATA_READ | FLAG_RESULT_REPORTED)
- * 3. INET_E_DATA_NOT_AVAILABLE if InternetQueryDataAvailable fails. The first time
- * this occurs, INET_E_DATA_NOT_AVAILABLE will also be reported to the sink,
- * (flags = FLAG_REQUEST_COMPLETE)
- * but upon subsequent calls to Read no reporting will take place, yet
- * InternetQueryDataAvailable will still be called, and, on failure,
- * INET_E_DATA_NOT_AVAILABLE will still be returned.
- * (flags = FLAG_REQUEST_COMPLETE | FLAG_RESULT_REPORTED)
- *
- * FLAG_FIRST_DATA_REPORTED and FLAG_LAST_DATA_REPORTED are needed for proper
- * ReportData reporting. For example, if OnResponse returns S_OK, Continue will
- * report BSCF_FIRSTDATANOTIFICATION, and when all data has been read Read will
- * report BSCF_INTERMEDIATEDATANOTIFICATION|BSCF_LASTDATANOTIFICATION. However,
- * if OnResponse does not return S_OK, Continue will not report data, and Read
- * will report BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION when all
- * data has been read.
- */
-#define FLAG_REQUEST_COMPLETE 0x1
-#define FLAG_FIRST_CONTINUE_COMPLETE 0x2
-#define FLAG_FIRST_DATA_REPORTED 0x4
-#define FLAG_ALL_DATA_READ 0x8
-#define FLAG_LAST_DATA_REPORTED 0x10
-#define FLAG_RESULT_REPORTED 0x20
-
typedef struct {
+ Protocol base;
+
const IInternetProtocolVtbl *lpInternetProtocolVtbl;
const IInternetPriorityVtbl *lpInternetPriorityVtbl;
BOOL https;
- DWORD flags, grfBINDF;
- BINDINFO bind_info;
- IInternetProtocolSink *protocol_sink;
IHttpNegotiate *http_negotiate;
- HINTERNET internet, connect, request;
LPWSTR full_header;
- HANDLE lock;
- ULONG current_position, content_length, available_bytes;
- LONG priority;
LONG ref;
} HttpProtocol;
+
+#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
+#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
/* Default headers from native */
static const WCHAR wszHeaders[] =
{'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',
':','
','g','z','i','p',',','
','d','e','f','l','a','t','e',0};
-/*
- * Helpers
- */
-
-static void HTTPPROTOCOL_ReportResult(HttpProtocol *This, HRESULT hres)
-{
- if (!(This->flags & FLAG_RESULT_REPORTED) &&
- This->protocol_sink)
- {
- This->flags |= FLAG_RESULT_REPORTED;
- IInternetProtocolSink_ReportResult(This->protocol_sink, hres, 0, NULL);
- }
-}
-
-static void HTTPPROTOCOL_ReportData(HttpProtocol *This)
-{
- DWORD bscf;
- if (!(This->flags & FLAG_LAST_DATA_REPORTED) &&
- This->protocol_sink)
- {
- if (This->flags & FLAG_FIRST_DATA_REPORTED)
- {
- bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
+static LPWSTR query_http_info(HttpProtocol *This, DWORD option)
+{
+ LPWSTR ret = NULL;
+ DWORD len = 0;
+ BOOL res;
+
+ res = HttpQueryInfoW(This->base.request, option, NULL, &len, NULL);
+ if (!res && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
+ ret = heap_alloc(len);
+ res = HttpQueryInfoW(This->base.request, option, ret, &len, NULL);
+ }
+ if(!res) {
+ TRACE("HttpQueryInfoW(%d) failed: %08x\n", option, GetLastError());
+ heap_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(HttpProtocol, base, iface)
+
+static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD
request_flags,
+ IInternetBindInfo *bind_info)
+{
+ HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ LPWSTR addl_header = NULL, post_cookie = NULL, optional = NULL;
+ IServiceProvider *service_provider = NULL;
+ IHttpNegotiate2 *http_negotiate2 = NULL;
+ LPWSTR host, user, pass, path;
+ LPOLESTR accept_mimes[257];
+ URL_COMPONENTSW url_comp;
+ BYTE security_id[512];
+ DWORD len = 0;
+ ULONG num = 0;
+ BOOL res;
+ HRESULT hres;
+
+ static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
+ {{'G','E','T',0},
+ {'P','O','S','T',0},
+ {'P','U','T',0}};
+
+ memset(&url_comp, 0, sizeof(url_comp));
+ url_comp.dwStructSize = sizeof(url_comp);
+ url_comp.dwSchemeLength = url_comp.dwHostNameLength = url_comp.dwUrlPathLength =
+ url_comp.dwUserNameLength = url_comp.dwPasswordLength = 1;
+ if (!InternetCrackUrlW(url, 0, 0, &url_comp))
+ return MK_E_SYNTAX;
+
+ if(!url_comp.nPort)
+ url_comp.nPort = This->https ? INTERNET_DEFAULT_HTTPS_PORT :
INTERNET_DEFAULT_HTTP_PORT;
+
+ host = heap_strndupW(url_comp.lpszHostName, url_comp.dwHostNameLength);
+ user = heap_strndupW(url_comp.lpszUserName, url_comp.dwUserNameLength);
+ pass = heap_strndupW(url_comp.lpszPassword, url_comp.dwPasswordLength);
+ This->base.connection = InternetConnectW(This->base.internet, host,
url_comp.nPort, user, pass,
+ INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0,
(DWORD_PTR)&This->base);
+ heap_free(pass);
+ heap_free(user);
+ heap_free(host);
+ if(!This->base.connection) {
+ WARN("InternetConnect failed: %d\n", GetLastError());
+ return INET_E_CANNOT_CONNECT;
+ }
+
+ num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
+ hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_ACCEPT_MIMES,
accept_mimes, num, &num);
+ if(hres != S_OK) {
+ WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
+ return INET_E_NO_VALID_MEDIA;
+ }
+ accept_mimes[num] = 0;
+
+ path = heap_strndupW(url_comp.lpszUrlPath, url_comp.dwUrlPathLength);
+ if(This->https)
+ request_flags |= INTERNET_FLAG_SECURE;
+ This->base.request = HttpOpenRequestW(This->base.connection,
+ This->base.bind_info.dwBindVerb < BINDVERB_CUSTOM
+ ? wszBindVerb[This->base.bind_info.dwBindVerb] :
This->base.bind_info.szCustomVerb,
+ path, NULL, NULL, (LPCWSTR *)accept_mimes, request_flags,
(DWORD_PTR)&This->base);
+ heap_free(path);
+ while (num<sizeof(accept_mimes)/sizeof(accept_mimes[0]) &&
accept_mimes[num])
+ CoTaskMemFree(accept_mimes[num++]);
+ if (!This->base.request) {
+ WARN("HttpOpenRequest failed: %d\n", GetLastError());
+ return INET_E_RESOURCE_NOT_FOUND;
+ }
+
+ hres = IInternetProtocolSink_QueryInterface(This->base.protocol_sink,
&IID_IServiceProvider,
+ (void **)&service_provider);
+ if (hres != S_OK) {
+ WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed:
%08x\n", hres);
+ return hres;
+ }
+
+ hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
+ &IID_IHttpNegotiate, (void **)&This->http_negotiate);
+ if (hres != S_OK) {
+ WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n",
hres);
+ return hres;
+ }
+
+ hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, url, wszHeaders,
+ 0, &addl_header);
+ if(hres != S_OK) {
+ WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
+ IServiceProvider_Release(service_provider);
+ return hres;
+ }
+
+ if(addl_header) {
+ int len_addl_header = strlenW(addl_header);
+
+ This->full_header =
heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));
+
+ lstrcpyW(This->full_header, addl_header);
+ lstrcpyW(&This->full_header[len_addl_header], wszHeaders);
+ CoTaskMemFree(addl_header);
+ }else {
+ This->full_header = (LPWSTR)wszHeaders;
+ }
+
+ hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
+ &IID_IHttpNegotiate2, (void **)&http_negotiate2);
+ IServiceProvider_Release(service_provider);
+ if(hres != S_OK) {
+ WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed:
%08x\n", hres);
+ /* No goto done as per native */
+ }else {
+ len = sizeof(security_id)/sizeof(security_id[0]);
+ hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len,
0);
+ IHttpNegotiate2_Release(http_negotiate2);
+ if (hres != S_OK)
+ WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
+ }
+
+ /* FIXME: Handle security_id. Native calls undocumented function
IsHostInProxyBypassList. */
+
+ if(This->base.bind_info.dwBindVerb == BINDVERB_POST) {
+ num = 0;
+ hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_POST_COOKIE,
&post_cookie, 1, &num);
+ if(hres == S_OK && num) {
+ if(!InternetSetOptionW(This->base.request,
INTERNET_OPTION_SECONDARY_CACHE_KEY,
+ post_cookie, lstrlenW(post_cookie)))
+ WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed:
%d\n", GetLastError());
+ CoTaskMemFree(post_cookie);
}
+ }
+
+ if(This->base.bind_info.dwBindVerb != BINDVERB_GET) {
+ /* Native does not use GlobalLock/GlobalUnlock, so we won't either */
+ if (This->base.bind_info.stgmedData.tymed != TYMED_HGLOBAL)
+ WARN("Expected This->base.bind_info.stgmedData.tymed to be
TYMED_HGLOBAL, not %d\n",
+ This->base.bind_info.stgmedData.tymed);
else
- {
- This->flags |= FLAG_FIRST_DATA_REPORTED;
- bscf = BSCF_FIRSTDATANOTIFICATION;
+ optional = (LPWSTR)This->base.bind_info.stgmedData.u.hGlobal;
+ }
+
+ res = HttpSendRequestW(This->base.request, This->full_header,
lstrlenW(This->full_header),
+ optional, optional ? This->base.bind_info.cbstgmedData : 0);
+ if(!res && GetLastError() != ERROR_IO_PENDING) {
+ WARN("HttpSendRequest failed: %d\n", GetLastError());
+ return INET_E_DOWNLOAD_FAILURE;
+ }
+
+ return S_OK;
+}
+
+static HRESULT HttpProtocol_start_downloading(Protocol *prot)
+{
+ HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+ LPWSTR content_type = 0, content_length = 0;
+ DWORD len = sizeof(DWORD);
+ DWORD status_code;
+ BOOL res;
+ HRESULT hres;
+
+ static const WCHAR wszDefaultContentType[] =
+
{'t','e','x','t','/','h','t','m','l',0};
+
+ if(!This->http_negotiate) {
+ WARN("Expected IHttpNegotiate pointer to be non-NULL\n");
+ return S_OK;
+ }
+
+ res = HttpQueryInfoW(This->base.request, HTTP_QUERY_STATUS_CODE |
HTTP_QUERY_FLAG_NUMBER,
+ &status_code, &len, NULL);
+ if(res) {
+ LPWSTR response_headers = query_http_info(This, HTTP_QUERY_RAW_HEADERS_CRLF);
+ if(response_headers) {
+ hres = IHttpNegotiate_OnResponse(This->http_negotiate, status_code,
response_headers,
+ NULL, NULL);
+ heap_free(response_headers);
+ if (hres != S_OK) {
+ WARN("IHttpNegotiate_OnResponse failed: %08x\n", hres);
+ return S_OK;
+ }
}
- if (This->flags & FLAG_ALL_DATA_READ &&
- !(This->flags & FLAG_LAST_DATA_REPORTED))
- {
- This->flags |= FLAG_LAST_DATA_REPORTED;
- bscf |= BSCF_LASTDATANOTIFICATION;
- }
- IInternetProtocolSink_ReportData(This->protocol_sink, bscf,
-
This->current_position+This->available_bytes,
- This->content_length);
- }
-}
-
-static void HTTPPROTOCOL_AllDataRead(HttpProtocol *This)
-{
- if (!(This->flags & FLAG_ALL_DATA_READ))
- This->flags |= FLAG_ALL_DATA_READ;
- HTTPPROTOCOL_ReportData(This);
- HTTPPROTOCOL_ReportResult(This, S_OK);
-}
-
-static void HTTPPROTOCOL_Close(HttpProtocol *This)
-{
- if (This->http_negotiate)
- {
+ }else {
+ WARN("HttpQueryInfo failed: %d\n", GetLastError());
+ }
+
+ if(This->https)
+ IInternetProtocolSink_ReportProgress(This->base.protocol_sink,
BINDSTATUS_ACCEPTRANGES, NULL);
+
+ content_type = query_http_info(This, HTTP_QUERY_CONTENT_TYPE);
+ if(content_type) {
+ /* remove the charset, if present */
+ LPWSTR p = strchrW(content_type, ';');
+ if (p) *p = '\0';
+
+ IInternetProtocolSink_ReportProgress(This->base.protocol_sink,
+ (This->base.bindf & BINDF_FROMURLMON)
+ ? BINDSTATUS_MIMETYPEAVAILABLE : BINDSTATUS_RAWMIMETYPE,
+ content_type);
+ heap_free(content_type);
+ }else {
+ WARN("HttpQueryInfo failed: %d\n", GetLastError());
+ IInternetProtocolSink_ReportProgress(This->base.protocol_sink,
+ (This->base.bindf & BINDF_FROMURLMON)
+ ? BINDSTATUS_MIMETYPEAVAILABLE : BINDSTATUS_RAWMIMETYPE,
+ wszDefaultContentType);
+ }
+
+ content_length = query_http_info(This, HTTP_QUERY_CONTENT_LENGTH);
+ if(content_length) {
+ This->base.content_length = atoiW(content_length);
+ heap_free(content_length);
+ }
+
+ return S_OK;
+}
+
+static void HttpProtocol_close_connection(Protocol *prot)
+{
+ HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
+
+ if(This->http_negotiate) {
IHttpNegotiate_Release(This->http_negotiate);
This->http_negotiate = 0;
}
- if (This->request)
- InternetCloseHandle(This->request);
- if (This->connect)
- InternetCloseHandle(This->connect);
- if (This->internet)
- {
- InternetCloseHandle(This->internet);
- This->internet = 0;
- }
- if (This->full_header)
- {
- if (This->full_header != wszHeaders)
+
+ if(This->full_header) {
+ if(This->full_header != wszHeaders)
heap_free(This->full_header);
This->full_header = 0;
}
- This->flags = 0;
-}
-
-static void CALLBACK HTTPPROTOCOL_InternetStatusCallback(
- HINTERNET hInternet, DWORD_PTR dwContext, DWORD dwInternetStatus,
- LPVOID lpvStatusInformation, DWORD dwStatusInformationLength)
-{
- HttpProtocol *This = (HttpProtocol *)dwContext;
- PROTOCOLDATA data;
- ULONG ulStatusCode;
-
- switch (dwInternetStatus)
- {
- case INTERNET_STATUS_RESOLVING_NAME:
- ulStatusCode = BINDSTATUS_FINDINGRESOURCE;
- break;
- case INTERNET_STATUS_CONNECTING_TO_SERVER:
- ulStatusCode = BINDSTATUS_CONNECTING;
- break;
- case INTERNET_STATUS_SENDING_REQUEST:
- ulStatusCode = BINDSTATUS_SENDINGREQUEST;
- break;
- case INTERNET_STATUS_REQUEST_COMPLETE:
- This->flags |= FLAG_REQUEST_COMPLETE;
- /* PROTOCOLDATA same as native */
- memset(&data, 0, sizeof(data));
- data.dwState = 0xf1000000;
- if (This->flags & FLAG_FIRST_CONTINUE_COMPLETE)
- data.pData = (LPVOID)BINDSTATUS_ENDDOWNLOADCOMPONENTS;
- else
- data.pData = (LPVOID)BINDSTATUS_DOWNLOADINGDATA;
- if (This->grfBINDF & BINDF_FROMURLMON)
- IInternetProtocolSink_Switch(This->protocol_sink, &data);
- else
- IInternetProtocol_Continue((IInternetProtocol *)This, &data);
- return;
- case INTERNET_STATUS_HANDLE_CREATED:
- IInternetProtocol_AddRef((IInternetProtocol *)This);
- return;
- case INTERNET_STATUS_HANDLE_CLOSING:
- if (*(HINTERNET *)lpvStatusInformation == This->connect)
- {
- This->connect = 0;
- }
- else if (*(HINTERNET *)lpvStatusInformation == This->request)
- {
- This->request = 0;
- if (This->protocol_sink)
- {
- IInternetProtocolSink_Release(This->protocol_sink);
- This->protocol_sink = 0;
- }
- if (This->bind_info.cbSize)
- {
- ReleaseBindInfo(&This->bind_info);
- memset(&This->bind_info, 0, sizeof(This->bind_info));
- }
- }
- IInternetProtocol_Release((IInternetProtocol *)This);
- return;
- default:
- WARN("Unhandled Internet status callback %d\n", dwInternetStatus);
- return;
- }
-
- IInternetProtocolSink_ReportProgress(This->protocol_sink, ulStatusCode,
(LPWSTR)lpvStatusInformation);
-}
-
-static inline LPWSTR strndupW(LPCWSTR string, int len)
-{
- LPWSTR ret = NULL;
- if (string &&
- (ret = heap_alloc((len+1)*sizeof(WCHAR))) != NULL)
- {
- memcpy(ret, string, len*sizeof(WCHAR));
- ret[len] = 0;
- }
- return ret;
-}
-
-/*
- * Interface implementations
- */
-
-#define PROTOCOL(x) ((IInternetProtocol*) &(x)->lpInternetProtocolVtbl)
-#define PRIORITY(x) ((IInternetPriority*) &(x)->lpInternetPriorityVtbl)
+}
+
+#undef ASYNCPROTOCOL_THIS
+
+static const ProtocolVtbl AsyncProtocolVtbl = {
+ HttpProtocol_open_request,
+ HttpProtocol_start_downloading,
+ HttpProtocol_close_connection
+};
#define PROTOCOL_THIS(iface) DEFINE_THIS(HttpProtocol, InternetProtocol, iface)
@@ -285,7 +353,7 @@
TRACE("(%p) ref=%d\n", This, ref);
if(!ref) {
- HTTPPROTOCOL_Close(This);
+ protocol_close_connection(&This->base);
heap_free(This);
URLMON_UnlockModule();
@@ -299,422 +367,28 @@
DWORD grfPI, DWORD dwReserved)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
- URL_COMPONENTSW url;
- DWORD len = 0, request_flags = INTERNET_FLAG_KEEP_CONNECTION;
- ULONG num = 0;
- IServiceProvider *service_provider = 0;
- IHttpNegotiate2 *http_negotiate2 = 0;
- LPWSTR host = 0, path = 0, user = 0, pass = 0, addl_header = 0,
- post_cookie = 0, optional = 0;
- BYTE security_id[512];
- LPOLESTR user_agent = NULL, accept_mimes[257];
- HRESULT hres;
static const WCHAR httpW[] =
{'h','t','t','p',':'};
static const WCHAR httpsW[] =
{'h','t','t','p','s',':'};
- static const WCHAR wszBindVerb[BINDVERB_CUSTOM][5] =
- {{'G','E','T',0},
- {'P','O','S','T',0},
- {'P','U','T',0}};
TRACE("(%p)->(%s %p %p %08x %d)\n", This, debugstr_w(szUrl),
pOIProtSink,
pOIBindInfo, grfPI, dwReserved);
-
- IInternetProtocolSink_AddRef(pOIProtSink);
- This->protocol_sink = pOIProtSink;
-
- memset(&This->bind_info, 0, sizeof(This->bind_info));
- This->bind_info.cbSize = sizeof(BINDINFO);
- hres = IInternetBindInfo_GetBindInfo(pOIBindInfo, &This->grfBINDF,
&This->bind_info);
- if (hres != S_OK)
- {
- WARN("GetBindInfo failed: %08x\n", hres);
- goto done;
- }
if(This->https
? strncmpW(szUrl, httpsW, sizeof(httpsW)/sizeof(WCHAR))
: strncmpW(szUrl, httpW, sizeof(httpW)/sizeof(WCHAR)))
- {
- hres = MK_E_SYNTAX;
- goto done;
- }
-
- memset(&url, 0, sizeof(url));
- url.dwStructSize = sizeof(url);
- url.dwSchemeLength = url.dwHostNameLength = url.dwUrlPathLength =
url.dwUserNameLength =
- url.dwPasswordLength = 1;
- if (!InternetCrackUrlW(szUrl, 0, 0, &url))
- {
- hres = MK_E_SYNTAX;
- goto done;
- }
- host = strndupW(url.lpszHostName, url.dwHostNameLength);
- path = strndupW(url.lpszUrlPath, url.dwUrlPathLength);
- user = strndupW(url.lpszUserName, url.dwUserNameLength);
- pass = strndupW(url.lpszPassword, url.dwPasswordLength);
- if (!url.nPort)
- url.nPort = This->https ? INTERNET_DEFAULT_HTTPS_PORT :
INTERNET_DEFAULT_HTTP_PORT;
-
- if(!(This->grfBINDF & BINDF_FROMURLMON))
- IInternetProtocolSink_ReportProgress(This->protocol_sink,
BINDSTATUS_DIRECTBIND, NULL);
-
- hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_USER_AGENT,
&user_agent,
- 1, &num);
- if (hres != S_OK || !num)
- {
- CHAR null_char = 0;
- LPSTR user_agenta = NULL;
- len = 0;
- if ((hres = ObtainUserAgentString(0, &null_char, &len)) !=
E_OUTOFMEMORY)
- {
- WARN("ObtainUserAgentString failed: %08x\n", hres);
- }
- else if (!(user_agenta = heap_alloc(len*sizeof(CHAR))))
- {
- WARN("Out of memory\n");
- }
- else if ((hres = ObtainUserAgentString(0, user_agenta, &len)) != S_OK)
- {
- WARN("ObtainUserAgentString failed: %08x\n", hres);
- }
- else
- {
- if (!(user_agent = CoTaskMemAlloc((len)*sizeof(WCHAR))))
- WARN("Out of memory\n");
- else
- MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len);
- }
- heap_free(user_agenta);
- }
-
- This->internet = InternetOpenW(user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
- if (!This->internet)
- {
- WARN("InternetOpen failed: %d\n", GetLastError());
- hres = INET_E_NO_SESSION;
- goto done;
- }
-
- /* Native does not check for success of next call, so we won't either */
- InternetSetStatusCallbackW(This->internet, HTTPPROTOCOL_InternetStatusCallback);
-
- This->connect = InternetConnectW(This->internet, host, url.nPort, user,
- pass, INTERNET_SERVICE_HTTP,
- This->https ? INTERNET_FLAG_SECURE : 0,
- (DWORD_PTR)This);
- if (!This->connect)
- {
- WARN("InternetConnect failed: %d\n", GetLastError());
- hres = INET_E_CANNOT_CONNECT;
- goto done;
- }
-
- num = sizeof(accept_mimes)/sizeof(accept_mimes[0])-1;
- hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_ACCEPT_MIMES,
- accept_mimes,
- num, &num);
- if (hres != S_OK)
- {
- WARN("GetBindString BINDSTRING_ACCEPT_MIMES failed: %08x\n", hres);
- hres = INET_E_NO_VALID_MEDIA;
- goto done;
- }
- accept_mimes[num] = 0;
-
- if (This->grfBINDF & BINDF_NOWRITECACHE)
- request_flags |= INTERNET_FLAG_NO_CACHE_WRITE;
- if (This->grfBINDF & BINDF_NEEDFILE)
- request_flags |= INTERNET_FLAG_NEED_FILE;
- if (This->https)
- request_flags |= INTERNET_FLAG_SECURE;
- This->request = HttpOpenRequestW(This->connect, This->bind_info.dwBindVerb
< BINDVERB_CUSTOM ?
- wszBindVerb[This->bind_info.dwBindVerb] :
- This->bind_info.szCustomVerb,
- path, NULL, NULL, (LPCWSTR *)accept_mimes,
- request_flags, (DWORD_PTR)This);
- if (!This->request)
- {
- WARN("HttpOpenRequest failed: %d\n", GetLastError());
- hres = INET_E_RESOURCE_NOT_FOUND;
- goto done;
- }
-
- hres = IInternetProtocolSink_QueryInterface(This->protocol_sink,
&IID_IServiceProvider,
- (void **)&service_provider);
- if (hres != S_OK)
- {
- WARN("IInternetProtocolSink_QueryInterface IID_IServiceProvider failed:
%08x\n", hres);
- goto done;
- }
-
- hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate,
- &IID_IHttpNegotiate, (void
**)&This->http_negotiate);
- if (hres != S_OK)
- {
- WARN("IServiceProvider_QueryService IID_IHttpNegotiate failed: %08x\n",
hres);
- goto done;
- }
-
- hres = IHttpNegotiate_BeginningTransaction(This->http_negotiate, szUrl,
wszHeaders,
- 0, &addl_header);
- if (hres != S_OK)
- {
- WARN("IHttpNegotiate_BeginningTransaction failed: %08x\n", hres);
- goto done;
- }
- else if (addl_header == NULL)
- {
- This->full_header = (LPWSTR)wszHeaders;
- }
- else
- {
- int len_addl_header = lstrlenW(addl_header);
- This->full_header =
heap_alloc(len_addl_header*sizeof(WCHAR)+sizeof(wszHeaders));
- if (!This->full_header)
- {
- WARN("Out of memory\n");
- hres = E_OUTOFMEMORY;
- goto done;
- }
- lstrcpyW(This->full_header, addl_header);
- lstrcpyW(&This->full_header[len_addl_header], wszHeaders);
- }
-
- hres = IServiceProvider_QueryService(service_provider, &IID_IHttpNegotiate2,
- &IID_IHttpNegotiate2, (void
**)&http_negotiate2);
- if (hres != S_OK)
- {
- WARN("IServiceProvider_QueryService IID_IHttpNegotiate2 failed:
%08x\n", hres);
- /* No goto done as per native */
- }
- else
- {
- len = sizeof(security_id)/sizeof(security_id[0]);
- hres = IHttpNegotiate2_GetRootSecurityId(http_negotiate2, security_id, &len,
0);
- if (hres != S_OK)
- {
- WARN("IHttpNegotiate2_GetRootSecurityId failed: %08x\n", hres);
- /* No goto done as per native */
- }
- }
-
- /* FIXME: Handle security_id. Native calls undocumented function
IsHostInProxyBypassList. */
-
- if (This->bind_info.dwBindVerb == BINDVERB_POST)
- {
- num = 0;
- hres = IInternetBindInfo_GetBindString(pOIBindInfo, BINDSTRING_POST_COOKIE,
&post_cookie,
- 1, &num);
- if (hres == S_OK && num &&
- !InternetSetOptionW(This->request, INTERNET_OPTION_SECONDARY_CACHE_KEY,
- post_cookie, lstrlenW(post_cookie)))
- {
- WARN("InternetSetOption INTERNET_OPTION_SECONDARY_CACHE_KEY failed:
%d\n",
- GetLastError());
- }
- }
-
- if (This->bind_info.dwBindVerb != BINDVERB_GET)
- {
- /* Native does not use GlobalLock/GlobalUnlock, so we won't either */
- if (This->bind_info.stgmedData.tymed != TYMED_HGLOBAL)
- WARN("Expected This->bind_info.stgmedData.tymed to be TYMED_HGLOBAL,
not %d\n",
- This->bind_info.stgmedData.tymed);
- else
- optional = (LPWSTR)This->bind_info.stgmedData.u.hGlobal;
- }
- if (!HttpSendRequestW(This->request, This->full_header,
lstrlenW(This->full_header),
- optional,
- optional ? This->bind_info.cbstgmedData : 0) &&
- GetLastError() != ERROR_IO_PENDING)
- {
- WARN("HttpSendRequest failed: %d\n", GetLastError());
- hres = INET_E_DOWNLOAD_FAILURE;
- goto done;
- }
-
- hres = S_OK;
-done:
- if (hres != S_OK)
- {
- IInternetProtocolSink_ReportResult(This->protocol_sink, hres, 0, NULL);
- HTTPPROTOCOL_Close(This);
- }
-
- CoTaskMemFree(post_cookie);
- CoTaskMemFree(addl_header);
- if (http_negotiate2)
- IHttpNegotiate2_Release(http_negotiate2);
- if (service_provider)
- IServiceProvider_Release(service_provider);
-
- while (num<sizeof(accept_mimes)/sizeof(accept_mimes[0]) &&
- accept_mimes[num])
- CoTaskMemFree(accept_mimes[num++]);
- CoTaskMemFree(user_agent);
-
- heap_free(pass);
- heap_free(user);
- heap_free(path);
- heap_free(host);
-
- return hres;
+ return MK_E_SYNTAX;
+
+ return protocol_start(&This->base, PROTOCOL(This), szUrl, pOIProtSink,
pOIBindInfo);
}
static HRESULT WINAPI HttpProtocol_Continue(IInternetProtocol *iface, PROTOCOLDATA
*pProtocolData)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
- DWORD len = sizeof(DWORD), status_code;
- LPWSTR response_headers = 0, content_type = 0, content_length = 0;
-
- static const WCHAR wszDefaultContentType[] =
-
{'t','e','x','t','/','h','t','m','l',0};
TRACE("(%p)->(%p)\n", This, pProtocolData);
- if (!pProtocolData)
- {
- WARN("Expected pProtocolData to be non-NULL\n");
- return S_OK;
- }
- else if (!This->request)
- {
- WARN("Expected request to be non-NULL\n");
- return S_OK;
- }
- else if (!This->http_negotiate)
- {
- WARN("Expected IHttpNegotiate pointer to be non-NULL\n");
- return S_OK;
- }
- else if (!This->protocol_sink)
- {
- WARN("Expected IInternetProtocolSink pointer to be non-NULL\n");
- return S_OK;
- }
-
- if (pProtocolData->pData == (LPVOID)BINDSTATUS_DOWNLOADINGDATA)
- {
- if (!HttpQueryInfoW(This->request, HTTP_QUERY_STATUS_CODE |
HTTP_QUERY_FLAG_NUMBER,
- &status_code, &len, NULL))
- {
- WARN("HttpQueryInfo failed: %d\n", GetLastError());
- }
- else
- {
- len = 0;
- if ((!HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF,
response_headers, &len,
- NULL) &&
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
- !(response_headers = heap_alloc(len)) ||
- !HttpQueryInfoW(This->request, HTTP_QUERY_RAW_HEADERS_CRLF,
response_headers, &len,
- NULL))
- {
- WARN("HttpQueryInfo failed: %d\n", GetLastError());
- }
- else
- {
- HRESULT hres = IHttpNegotiate_OnResponse(This->http_negotiate,
status_code,
- response_headers, NULL, NULL);
- if (hres != S_OK)
- {
- WARN("IHttpNegotiate_OnResponse failed: %08x\n", hres);
- goto done;
- }
- }
- }
-
- if(This->https)
- IInternetProtocolSink_ReportProgress(This->protocol_sink,
BINDSTATUS_ACCEPTRANGES, NULL);
-
- len = 0;
- if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type,
&len, NULL) &&
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
- !(content_type = heap_alloc(len)) ||
- !HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_TYPE, content_type,
&len, NULL))
- {
- WARN("HttpQueryInfo failed: %d\n", GetLastError());
- IInternetProtocolSink_ReportProgress(This->protocol_sink,
- (This->grfBINDF &
BINDF_FROMURLMON) ?
- BINDSTATUS_MIMETYPEAVAILABLE :
- BINDSTATUS_RAWMIMETYPE,
- wszDefaultContentType);
- }
- else
- {
- /* remove the charset, if present */
- LPWSTR p = strchrW(content_type, ';');
- if (p) *p = '\0';
-
- IInternetProtocolSink_ReportProgress(This->protocol_sink,
- (This->grfBINDF &
BINDF_FROMURLMON) ?
- BINDSTATUS_MIMETYPEAVAILABLE :
- BINDSTATUS_RAWMIMETYPE,
- content_type);
- }
-
- len = 0;
- if ((!HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length,
&len, NULL) &&
- GetLastError() != ERROR_INSUFFICIENT_BUFFER) ||
- !(content_length = heap_alloc(len)) ||
- !HttpQueryInfoW(This->request, HTTP_QUERY_CONTENT_LENGTH, content_length,
&len, NULL))
- {
- WARN("HttpQueryInfo failed: %d\n", GetLastError());
- This->content_length = 0;
- }
- else
- {
- This->content_length = atoiW(content_length);
- }
-
- if(This->grfBINDF & BINDF_NEEDFILE) {
- WCHAR cache_file[MAX_PATH];
- DWORD buflen = sizeof(cache_file);
-
- if(InternetQueryOptionW(This->request, INTERNET_OPTION_DATAFILE_NAME,
- cache_file, &buflen))
- {
- IInternetProtocolSink_ReportProgress(This->protocol_sink,
- BINDSTATUS_CACHEFILENAMEAVAILABLE,
- cache_file);
- }else {
- FIXME("Could not get cache file\n");
- }
- }
-
- This->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
- }
-
- if (pProtocolData->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA)
- {
- /* InternetQueryDataAvailable may immediately fork and perform its asynchronous
- * read, so clear the flag _before_ calling so it does not incorrectly get
cleared
- * after the status callback is called */
- This->flags &= ~FLAG_REQUEST_COMPLETE;
- if (!InternetQueryDataAvailable(This->request, &This->available_bytes,
0, 0))
- {
- if (GetLastError() != ERROR_IO_PENDING)
- {
- This->flags |= FLAG_REQUEST_COMPLETE;
- WARN("InternetQueryDataAvailable failed: %d\n",
GetLastError());
- HTTPPROTOCOL_ReportResult(This, INET_E_DATA_NOT_AVAILABLE);
- }
- }
- else
- {
- This->flags |= FLAG_REQUEST_COMPLETE;
- HTTPPROTOCOL_ReportData(This);
- }
- }
-
-done:
- heap_free(response_headers);
- heap_free(content_type);
- heap_free(content_length);
-
- /* Returns S_OK on native */
- return S_OK;
+ return protocol_continue(&This->base, pProtocolData);
}
static HRESULT WINAPI HttpProtocol_Abort(IInternetProtocol *iface, HRESULT hrReason,
@@ -730,8 +404,8 @@
HttpProtocol *This = PROTOCOL_THIS(iface);
TRACE("(%p)->(%08x)\n", This, dwOptions);
- HTTPPROTOCOL_Close(This);
-
+
+ protocol_close_connection(&This->base);
return S_OK;
}
@@ -753,80 +427,10 @@
ULONG cb, ULONG *pcbRead)
{
HttpProtocol *This = PROTOCOL_THIS(iface);
- ULONG read = 0, len = 0;
- HRESULT hres = S_FALSE;
TRACE("(%p)->(%p %u %p)\n", This, pv, cb, pcbRead);
- if (!(This->flags & FLAG_REQUEST_COMPLETE))
- {
- hres = E_PENDING;
- }
- else while (!(This->flags & FLAG_ALL_DATA_READ) &&
- read < cb)
- {
- if (This->available_bytes == 0)
- {
- /* InternetQueryDataAvailable may immediately fork and perform its
asynchronous
- * read, so clear the flag _before_ calling so it does not incorrectly get
cleared
- * after the status callback is called */
- This->flags &= ~FLAG_REQUEST_COMPLETE;
- if (!InternetQueryDataAvailable(This->request,
&This->available_bytes, 0, 0))
- {
- if (GetLastError() == ERROR_IO_PENDING)
- {
- hres = E_PENDING;
- }
- else
- {
- WARN("InternetQueryDataAvailable failed: %d\n",
GetLastError());
- hres = INET_E_DATA_NOT_AVAILABLE;
- HTTPPROTOCOL_ReportResult(This, hres);
- }
- goto done;
- }
- else if (This->available_bytes == 0)
- {
- HTTPPROTOCOL_AllDataRead(This);
- }
- }
- else
- {
- if (!InternetReadFile(This->request, ((BYTE *)pv)+read,
- This->available_bytes > cb-read ?
- cb-read : This->available_bytes, &len))
- {
- WARN("InternetReadFile failed: %d\n", GetLastError());
- hres = INET_E_DOWNLOAD_FAILURE;
- HTTPPROTOCOL_ReportResult(This, hres);
- goto done;
- }
- else if (len == 0)
- {
- HTTPPROTOCOL_AllDataRead(This);
- }
- else
- {
- read += len;
- This->current_position += len;
- This->available_bytes -= len;
- }
- }
- }
-
- /* Per MSDN this should be if (read == cb), but native returns S_OK
- * if any bytes were read, so we will too */
- if (read)
- hres = S_OK;
-
-done:
- if (pcbRead)
- *pcbRead = read;
-
- if (hres != E_PENDING)
- This->flags |= FLAG_REQUEST_COMPLETE;
-
- return hres;
+ return protocol_read(&This->base, pv, cb, pcbRead);
}
static HRESULT WINAPI HttpProtocol_Seek(IInternetProtocol *iface, LARGE_INTEGER
dlibMove,
@@ -843,10 +447,7 @@
TRACE("(%p)->(%08x)\n", This, dwOptions);
- if (!InternetLockRequestFile(This->request, &This->lock))
- WARN("InternetLockRequest failed: %d\n", GetLastError());
-
- return S_OK;
+ return protocol_lock_request(&This->base);
}
static HRESULT WINAPI HttpProtocol_UnlockRequest(IInternetProtocol *iface)
@@ -855,67 +456,10 @@
TRACE("(%p)\n", This);
- if (This->lock)
- {
- if (!InternetUnlockRequestFile(This->lock))
- WARN("InternetUnlockRequest failed: %d\n", GetLastError());
- This->lock = 0;
- }
-
- return S_OK;
+ return protocol_unlock_request(&This->base);
}
#undef PROTOCOL_THIS
-
-#define PRIORITY_THIS(iface) DEFINE_THIS(HttpProtocol, InternetPriority, iface)
-
-static HRESULT WINAPI HttpPriority_QueryInterface(IInternetPriority *iface, REFIID riid,
void **ppv)
-{
- HttpProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
-}
-
-static ULONG WINAPI HttpPriority_AddRef(IInternetPriority *iface)
-{
- HttpProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocol_AddRef(PROTOCOL(This));
-}
-
-static ULONG WINAPI HttpPriority_Release(IInternetPriority *iface)
-{
- HttpProtocol *This = PRIORITY_THIS(iface);
- return IInternetProtocol_Release(PROTOCOL(This));
-}
-
-static HRESULT WINAPI HttpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
-{
- HttpProtocol *This = PRIORITY_THIS(iface);
-
- TRACE("(%p)->(%d)\n", This, nPriority);
-
- This->priority = nPriority;
- return S_OK;
-}
-
-static HRESULT WINAPI HttpPriority_GetPriority(IInternetPriority *iface, LONG
*pnPriority)
-{
- HttpProtocol *This = PRIORITY_THIS(iface);
-
- TRACE("(%p)->(%p)\n", This, pnPriority);
-
- *pnPriority = This->priority;
- return S_OK;
-}
-
-#undef PRIORITY_THIS
-
-static const IInternetPriorityVtbl HttpPriorityVtbl = {
- HttpPriority_QueryInterface,
- HttpPriority_AddRef,
- HttpPriority_Release,
- HttpPriority_SetPriority,
- HttpPriority_GetPriority
-};
static const IInternetProtocolVtbl HttpProtocolVtbl = {
HttpProtocol_QueryInterface,
@@ -933,6 +477,56 @@
HttpProtocol_UnlockRequest
};
+#define PRIORITY_THIS(iface) DEFINE_THIS(HttpProtocol, InternetPriority, iface)
+
+static HRESULT WINAPI HttpPriority_QueryInterface(IInternetPriority *iface, REFIID riid,
void **ppv)
+{
+ HttpProtocol *This = PRIORITY_THIS(iface);
+ return IInternetProtocol_QueryInterface(PROTOCOL(This), riid, ppv);
+}
+
+static ULONG WINAPI HttpPriority_AddRef(IInternetPriority *iface)
+{
+ HttpProtocol *This = PRIORITY_THIS(iface);
+ return IInternetProtocol_AddRef(PROTOCOL(This));
+}
+
+static ULONG WINAPI HttpPriority_Release(IInternetPriority *iface)
+{
+ HttpProtocol *This = PRIORITY_THIS(iface);
+ return IInternetProtocol_Release(PROTOCOL(This));
+}
+
+static HRESULT WINAPI HttpPriority_SetPriority(IInternetPriority *iface, LONG nPriority)
+{
+ HttpProtocol *This = PRIORITY_THIS(iface);
+
+ TRACE("(%p)->(%d)\n", This, nPriority);
+
+ This->base.priority = nPriority;
+ return S_OK;
+}
+
+static HRESULT WINAPI HttpPriority_GetPriority(IInternetPriority *iface, LONG
*pnPriority)
+{
+ HttpProtocol *This = PRIORITY_THIS(iface);
+
+ TRACE("(%p)->(%p)\n", This, pnPriority);
+
+ *pnPriority = This->base.priority;
+ return S_OK;
+}
+
+#undef PRIORITY_THIS
+
+static const IInternetPriorityVtbl HttpPriorityVtbl = {
+ HttpPriority_QueryInterface,
+ HttpPriority_AddRef,
+ HttpPriority_Release,
+ HttpPriority_SetPriority,
+ HttpPriority_GetPriority
+};
+
static HRESULT create_http_protocol(BOOL https, void **ppobj)
{
HttpProtocol *ret;
@@ -941,6 +535,7 @@
if(!ret)
return E_OUTOFMEMORY;
+ ret->base.vtbl = &AsyncProtocolVtbl;
ret->lpInternetProtocolVtbl = &HttpProtocolVtbl;
ret->lpInternetPriorityVtbl = &HttpPriorityVtbl;
Added: trunk/reactos/dll/win32/urlmon/protocol.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/protocol.…
==============================================================================
--- trunk/reactos/dll/win32/urlmon/protocol.c (added)
+++ trunk/reactos/dll/win32/urlmon/protocol.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -1,0 +1,430 @@
+/*
+ * Copyright 2007 Misha Koshelev
+ * Copyright 2009 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
+ * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "urlmon_main.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
+
+/* Flags are needed for, among other things, return HRESULTs from the Read function
+ * to conform to native. For example, Read returns:
+ *
+ * 1. E_PENDING if called before the request has completed,
+ * (flags = 0)
+ * 2. S_FALSE after all data has been read and S_OK has been reported,
+ * (flags = FLAG_REQUEST_COMPLETE | FLAG_ALL_DATA_READ | FLAG_RESULT_REPORTED)
+ * 3. INET_E_DATA_NOT_AVAILABLE if InternetQueryDataAvailable fails. The first time
+ * this occurs, INET_E_DATA_NOT_AVAILABLE will also be reported to the sink,
+ * (flags = FLAG_REQUEST_COMPLETE)
+ * but upon subsequent calls to Read no reporting will take place, yet
+ * InternetQueryDataAvailable will still be called, and, on failure,
+ * INET_E_DATA_NOT_AVAILABLE will still be returned.
+ * (flags = FLAG_REQUEST_COMPLETE | FLAG_RESULT_REPORTED)
+ *
+ * FLAG_FIRST_DATA_REPORTED and FLAG_LAST_DATA_REPORTED are needed for proper
+ * ReportData reporting. For example, if OnResponse returns S_OK, Continue will
+ * report BSCF_FIRSTDATANOTIFICATION, and when all data has been read Read will
+ * report BSCF_INTERMEDIATEDATANOTIFICATION|BSCF_LASTDATANOTIFICATION. However,
+ * if OnResponse does not return S_OK, Continue will not report data, and Read
+ * will report BSCF_FIRSTDATANOTIFICATION|BSCF_LASTDATANOTIFICATION when all
+ * data has been read.
+ */
+#define FLAG_REQUEST_COMPLETE 0x0001
+#define FLAG_FIRST_CONTINUE_COMPLETE 0x0002
+#define FLAG_FIRST_DATA_REPORTED 0x0004
+#define FLAG_ALL_DATA_READ 0x0008
+#define FLAG_LAST_DATA_REPORTED 0x0010
+#define FLAG_RESULT_REPORTED 0x0020
+
+static inline HRESULT report_progress(Protocol *protocol, ULONG status_code, LPCWSTR
status_text)
+{
+ return IInternetProtocolSink_ReportProgress(protocol->protocol_sink, status_code,
status_text);
+}
+
+static inline HRESULT report_result(Protocol *protocol, HRESULT hres)
+{
+ if (!(protocol->flags & FLAG_RESULT_REPORTED) &&
protocol->protocol_sink) {
+ protocol->flags |= FLAG_RESULT_REPORTED;
+ IInternetProtocolSink_ReportResult(protocol->protocol_sink, hres, 0, NULL);
+ }
+
+ return hres;
+}
+
+static void report_data(Protocol *protocol)
+{
+ DWORD bscf;
+
+ if((protocol->flags & FLAG_LAST_DATA_REPORTED) ||
!protocol->protocol_sink)
+ return;
+
+ if(protocol->flags & FLAG_FIRST_DATA_REPORTED) {
+ bscf = BSCF_INTERMEDIATEDATANOTIFICATION;
+ }else {
+ protocol->flags |= FLAG_FIRST_DATA_REPORTED;
+ bscf = BSCF_FIRSTDATANOTIFICATION;
+ }
+
+ if(protocol->flags & FLAG_ALL_DATA_READ && !(protocol->flags &
FLAG_LAST_DATA_REPORTED)) {
+ protocol->flags |= FLAG_LAST_DATA_REPORTED;
+ bscf |= BSCF_LASTDATANOTIFICATION;
+ }
+
+ IInternetProtocolSink_ReportData(protocol->protocol_sink, bscf,
+ protocol->current_position+protocol->available_bytes,
+ protocol->content_length);
+}
+
+static void all_data_read(Protocol *protocol)
+{
+ protocol->flags |= FLAG_ALL_DATA_READ;
+
+ report_data(protocol);
+ report_result(protocol, S_OK);
+}
+
+static void request_complete(Protocol *protocol, INTERNET_ASYNC_RESULT *ar)
+{
+ PROTOCOLDATA data;
+
+ if(!ar->dwResult) {
+ WARN("request failed: %d\n", ar->dwError);
+ return;
+ }
+
+ protocol->flags |= FLAG_REQUEST_COMPLETE;
+
+ if(!protocol->request) {
+ TRACE("setting request handle %p\n", (HINTERNET)ar->dwResult);
+ protocol->request = (HINTERNET)ar->dwResult;
+ }
+
+ /* PROTOCOLDATA same as native */
+ memset(&data, 0, sizeof(data));
+ data.dwState = 0xf1000000;
+ if(protocol->flags & FLAG_FIRST_CONTINUE_COMPLETE)
+ data.pData = (LPVOID)BINDSTATUS_ENDDOWNLOADCOMPONENTS;
+ else
+ data.pData = (LPVOID)BINDSTATUS_DOWNLOADINGDATA;
+
+ if (protocol->bindf & BINDF_FROMURLMON)
+ IInternetProtocolSink_Switch(protocol->protocol_sink, &data);
+ else
+ protocol_continue(protocol, &data);
+}
+
+static void WINAPI internet_status_callback(HINTERNET internet, DWORD_PTR context,
+ DWORD internet_status, LPVOID status_info, DWORD status_info_len)
+{
+ Protocol *protocol = (Protocol*)context;
+
+ switch(internet_status) {
+ case INTERNET_STATUS_RESOLVING_NAME:
+ TRACE("%p INTERNET_STATUS_RESOLVING_NAME\n", protocol);
+ report_progress(protocol, BINDSTATUS_FINDINGRESOURCE, (LPWSTR)status_info);
+ break;
+
+ case INTERNET_STATUS_CONNECTING_TO_SERVER:
+ TRACE("%p INTERNET_STATUS_CONNECTING_TO_SERVER\n", protocol);
+ report_progress(protocol, BINDSTATUS_CONNECTING, (LPWSTR)status_info);
+ break;
+
+ case INTERNET_STATUS_SENDING_REQUEST:
+ TRACE("%p INTERNET_STATUS_SENDING_REQUEST\n", protocol);
+ report_progress(protocol, BINDSTATUS_SENDINGREQUEST, (LPWSTR)status_info);
+ break;
+
+ case INTERNET_STATUS_REQUEST_COMPLETE:
+ request_complete(protocol, status_info);
+ break;
+
+ case INTERNET_STATUS_HANDLE_CREATED:
+ TRACE("%p INTERNET_STATUS_HANDLE_CREATED\n", protocol);
+ IInternetProtocol_AddRef(protocol->protocol);
+ break;
+
+ case INTERNET_STATUS_HANDLE_CLOSING:
+ TRACE("%p INTERNET_STATUS_HANDLE_CLOSING\n", protocol);
+
+ if(*(HINTERNET *)status_info == protocol->request) {
+ protocol->request = NULL;
+ if(protocol->protocol_sink) {
+ IInternetProtocolSink_Release(protocol->protocol_sink);
+ protocol->protocol_sink = NULL;
+ }
+
+ if(protocol->bind_info.cbSize) {
+ ReleaseBindInfo(&protocol->bind_info);
+ memset(&protocol->bind_info, 0, sizeof(protocol->bind_info));
+ }
+ }else if(*(HINTERNET *)status_info == protocol->connection) {
+ protocol->connection = NULL;
+ }
+
+ IInternetProtocol_Release(protocol->protocol);
+ break;
+
+ default:
+ WARN("Unhandled Internet status callback %d\n", internet_status);
+ }
+}
+
+HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, LPCWSTR url,
+ IInternetProtocolSink *protocol_sink, IInternetBindInfo *bind_info)
+{
+ LPOLESTR user_agent = NULL;
+ DWORD request_flags;
+ ULONG size = 0;
+ HRESULT hres;
+
+ protocol->protocol = prot;
+
+ IInternetProtocolSink_AddRef(protocol_sink);
+ protocol->protocol_sink = protocol_sink;
+
+ memset(&protocol->bind_info, 0, sizeof(protocol->bind_info));
+ protocol->bind_info.cbSize = sizeof(BINDINFO);
+ hres = IInternetBindInfo_GetBindInfo(bind_info, &protocol->bindf,
&protocol->bind_info);
+ if(hres != S_OK) {
+ WARN("GetBindInfo failed: %08x\n", hres);
+ return report_result(protocol, hres);
+ }
+
+ if(!(protocol->bindf & BINDF_FROMURLMON))
+ report_progress(protocol, BINDSTATUS_DIRECTBIND, NULL);
+
+ hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_USER_AGENT,
&user_agent, 1, &size);
+ if (hres != S_OK || !size) {
+ DWORD len;
+ CHAR null_char = 0;
+ LPSTR user_agenta = NULL;
+
+ len = 0;
+ if ((hres = ObtainUserAgentString(0, &null_char, &len)) != E_OUTOFMEMORY)
{
+ WARN("ObtainUserAgentString failed: %08x\n", hres);
+ }else if (!(user_agenta = heap_alloc(len*sizeof(CHAR)))) {
+ WARN("Out of memory\n");
+ }else if ((hres = ObtainUserAgentString(0, user_agenta, &len)) != S_OK) {
+ WARN("ObtainUserAgentString failed: %08x\n", hres);
+ }else {
+ if(!(user_agent = CoTaskMemAlloc((len)*sizeof(WCHAR))))
+ WARN("Out of memory\n");
+ else
+ MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len);
+ }
+ heap_free(user_agenta);
+ }
+
+ protocol->internet = InternetOpenW(user_agent, 0, NULL, NULL,
INTERNET_FLAG_ASYNC);
+ CoTaskMemFree(user_agent);
+ if(!protocol->internet) {
+ WARN("InternetOpen failed: %d\n", GetLastError());
+ return report_result(protocol, INET_E_NO_SESSION);
+ }
+
+ /* Native does not check for success of next call, so we won't either */
+ InternetSetStatusCallbackW(protocol->internet, internet_status_callback);
+
+ request_flags = INTERNET_FLAG_KEEP_CONNECTION;
+ if(protocol->bindf & BINDF_NOWRITECACHE)
+ request_flags |= INTERNET_FLAG_NO_CACHE_WRITE;
+ if(protocol->bindf & BINDF_NEEDFILE)
+ request_flags |= INTERNET_FLAG_NEED_FILE;
+
+ hres = protocol->vtbl->open_request(protocol, url, request_flags, bind_info);
+ if(FAILED(hres)) {
+ protocol_close_connection(protocol);
+ return report_result(protocol, hres);
+ }
+
+ return S_OK;
+}
+
+HRESULT protocol_continue(Protocol *protocol, PROTOCOLDATA *data)
+{
+ HRESULT hres;
+
+ if (!data) {
+ WARN("Expected pProtocolData to be non-NULL\n");
+ return S_OK;
+ }
+
+ if(!protocol->request) {
+ WARN("Expected request to be non-NULL\n");
+ return S_OK;
+ }
+
+ if(!protocol->protocol_sink) {
+ WARN("Expected IInternetProtocolSink pointer to be non-NULL\n");
+ return S_OK;
+ }
+
+ if(data->pData == (LPVOID)BINDSTATUS_DOWNLOADINGDATA) {
+ hres = protocol->vtbl->start_downloading(protocol);
+ if(FAILED(hres)) {
+ protocol_close_connection(protocol);
+ report_result(protocol, hres);
+ return S_OK;
+ }
+
+ if(protocol->bindf & BINDF_NEEDFILE) {
+ WCHAR cache_file[MAX_PATH];
+ DWORD buflen = sizeof(cache_file);
+
+ if(InternetQueryOptionW(protocol->request, INTERNET_OPTION_DATAFILE_NAME,
+ cache_file, &buflen)) {
+ report_progress(protocol, BINDSTATUS_CACHEFILENAMEAVAILABLE,
cache_file);
+ }else {
+ FIXME("Could not get cache file\n");
+ }
+ }
+
+ protocol->flags |= FLAG_FIRST_CONTINUE_COMPLETE;
+ }
+
+ if(data->pData >= (LPVOID)BINDSTATUS_DOWNLOADINGDATA) {
+ BOOL res;
+
+ /* InternetQueryDataAvailable may immediately fork and perform its asynchronous
+ * read, so clear the flag _before_ calling so it does not incorrectly get
cleared
+ * after the status callback is called */
+ protocol->flags &= ~FLAG_REQUEST_COMPLETE;
+ res = InternetQueryDataAvailable(protocol->request,
&protocol->available_bytes, 0, 0);
+ if(res) {
+ protocol->flags |= FLAG_REQUEST_COMPLETE;
+ report_data(protocol);
+ }else if(GetLastError() != ERROR_IO_PENDING) {
+ protocol->flags |= FLAG_REQUEST_COMPLETE;
+ WARN("InternetQueryDataAvailable failed: %d\n", GetLastError());
+ report_result(protocol, INET_E_DATA_NOT_AVAILABLE);
+ }
+ }
+
+ return S_OK;
+}
+
+HRESULT protocol_read(Protocol *protocol, void *buf, ULONG size, ULONG *read_ret)
+{
+ ULONG read = 0;
+ BOOL res;
+ HRESULT hres = S_FALSE;
+
+ if(!(protocol->flags & FLAG_REQUEST_COMPLETE)) {
+ *read_ret = 0;
+ return E_PENDING;
+ }
+
+ if(protocol->flags & FLAG_ALL_DATA_READ) {
+ *read_ret = 0;
+ return S_FALSE;
+ }
+
+ while(read < size) {
+ if(protocol->available_bytes) {
+ ULONG len;
+
+ res = InternetReadFile(protocol->request, ((BYTE *)buf)+read,
+ protocol->available_bytes > size-read ? size-read :
protocol->available_bytes, &len);
+ if(!res) {
+ WARN("InternetReadFile failed: %d\n", GetLastError());
+ hres = INET_E_DOWNLOAD_FAILURE;
+ report_result(protocol, hres);
+ break;
+ }
+
+ if(!len) {
+ all_data_read(protocol);
+ break;
+ }
+
+ read += len;
+ protocol->current_position += len;
+ protocol->available_bytes -= len;
+ }else {
+ /* InternetQueryDataAvailable may immediately fork and perform its
asynchronous
+ * read, so clear the flag _before_ calling so it does not incorrectly get
cleared
+ * after the status callback is called */
+ protocol->flags &= ~FLAG_REQUEST_COMPLETE;
+ res = InternetQueryDataAvailable(protocol->request,
&protocol->available_bytes, 0, 0);
+ if(!res) {
+ if (GetLastError() == ERROR_IO_PENDING) {
+ hres = E_PENDING;
+ }else {
+ WARN("InternetQueryDataAvailable failed: %d\n",
GetLastError());
+ hres = INET_E_DATA_NOT_AVAILABLE;
+ report_result(protocol, hres);
+ }
+ break;
+ }
+
+ if(!protocol->available_bytes) {
+ all_data_read(protocol);
+ break;
+ }
+ }
+ }
+
+ *read_ret = read;
+
+ if (hres != E_PENDING)
+ protocol->flags |= FLAG_REQUEST_COMPLETE;
+ if(FAILED(hres))
+ return hres;
+
+ return read ? S_OK : S_FALSE;
+}
+
+HRESULT protocol_lock_request(Protocol *protocol)
+{
+ if (!InternetLockRequestFile(protocol->request, &protocol->lock))
+ WARN("InternetLockRequest failed: %d\n", GetLastError());
+
+ return S_OK;
+}
+
+HRESULT protocol_unlock_request(Protocol *protocol)
+{
+ if(!protocol->lock)
+ return S_OK;
+
+ if(!InternetUnlockRequestFile(protocol->lock))
+ WARN("InternetUnlockRequest failed: %d\n", GetLastError());
+ protocol->lock = 0;
+
+ return S_OK;
+}
+
+void protocol_close_connection(Protocol *protocol)
+{
+ protocol->vtbl->close_connection(protocol);
+
+ if(protocol->request)
+ InternetCloseHandle(protocol->request);
+
+ if(protocol->connection)
+ InternetCloseHandle(protocol->connection);
+
+ if(protocol->internet) {
+ InternetCloseHandle(protocol->internet);
+ protocol->internet = 0;
+ }
+
+ protocol->flags = 0;
+}
Propchange: trunk/reactos/dll/win32/urlmon/protocol.c
------------------------------------------------------------------------------
svn:eol-style = native
Modified: trunk/reactos/dll/win32/urlmon/umon.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/umon.c?re…
==============================================================================
--- trunk/reactos/dll/win32/urlmon/umon.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/urlmon/umon.c [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -532,8 +532,6 @@
if(SUCCEEDED(hres)) {
URL_COMPONENTSW url;
WCHAR *host, *path, *user, *pass;
- DWORD dwService = 0;
- BOOL bSuccess;
TRACE("got bindinfo. bindf = %08x extrainfo = %s bindinfof = %08x
bindverb = %08x iid %s\n",
bindf, debugstr_w(bi.szExtraInfo), bi.grfBindInfoF, bi.dwBindVerb,
debugstr_guid(&bi.iid));
@@ -583,23 +581,10 @@
break;
}
- 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;
- }
-
+ if (!url.nPort)
+ url.nPort = INTERNET_DEFAULT_GOPHER_PORT;
bind->hconnect = InternetConnectW(bind->hinternet, host,
url.nPort, user, pass,
- dwService, 0, (DWORD_PTR)bind);
+ INTERNET_SERVICE_GOPHER, 0,
(DWORD_PTR)bind);
if (!bind->hconnect)
{
hres = HRESULT_FROM_WIN32(GetLastError());
@@ -612,37 +597,12 @@
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;
- }
- if(bSuccess)
+ bind->hrequest = GopherOpenFileW(bind->hconnect,
+ path,
+ 0,
+ INTERNET_FLAG_RELOAD,
+ 0);
+ if (bind->hrequest)
{
TRACE("res = %d gle = %u url len = %d\n", hres,
GetLastError(), bind->expected_size);
@@ -660,7 +620,10 @@
}
InternetCloseHandle(bind->hrequest);
hres = S_OK;
+ }else {
+ hres = HRESULT_FROM_WIN32(GetLastError());
}
+
InternetCloseHandle(bind->hconnect);
InternetCloseHandle(bind->hinternet);
@@ -704,9 +667,7 @@
return E_FAIL;
}
- if(IsEqualGUID(&IID_IStream, riid) &&
- ( url.nScheme == INTERNET_SCHEME_FTP
- || url.nScheme == INTERNET_SCHEME_GOPHER))
+ if(IsEqualGUID(&IID_IStream, riid) && url.nScheme ==
INTERNET_SCHEME_GOPHER)
return URLMonikerImpl_BindToStorage_hack(This->URLName, pbc, ppvObject);
TRACE("(%p)->(%p %p %s %p)\n", This, pbc, pmkToLeft,
debugstr_guid(riid), ppvObject);
Modified: trunk/reactos/dll/win32/urlmon/urlmon.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon.rb…
==============================================================================
--- trunk/reactos/dll/win32/urlmon/urlmon.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/urlmon/urlmon.rbuild [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -18,6 +18,7 @@
<file>http.c</file>
<file>internet.c</file>
<file>mk.c</file>
+ <file>protocol.c</file>
<file>regsvr.c</file>
<file>sec_mgr.c</file>
<file>session.c</file>
Modified: trunk/reactos/dll/win32/urlmon/urlmon_main.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/urlmon/urlmon_ma…
==============================================================================
--- trunk/reactos/dll/win32/urlmon/urlmon_main.h [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/urlmon/urlmon_main.h [iso-8859-1] Wed Mar 4 18:29:32 2009
@@ -1,5 +1,6 @@
/*
* Copyright 2002 Huw D M Davies for CodeWeavers
+ * Copyright 2009 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
@@ -30,6 +31,7 @@
#include "winuser.h"
#include "ole2.h"
#include "urlmon.h"
+#include "wininet.h"
#include "wine/unicode.h"
@@ -50,7 +52,8 @@
static inline void URLMON_UnlockModule(void) { InterlockedDecrement( &URLMON_refCount
); }
#define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) -
offsetof(impl,field))
-#define DEFINE_THIS(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,lp ## ifc ##
Vtbl)))
+#define DEFINE_THIS2(cls,ifc,iface) ((cls*)((BYTE*)(iface)-offsetof(cls,ifc)))
+#define DEFINE_THIS(cls,ifc,iface) DEFINE_THIS2(cls,lp ## ifc ## Vtbl,iface)
typedef struct
{
@@ -75,6 +78,43 @@
HRESULT create_binding_protocol(LPCWSTR url, BOOL from_urlmon, IInternetProtocol
**protocol);
void set_binding_sink(IInternetProtocol *bind_protocol, IInternetProtocolSink *sink);
+
+typedef struct ProtocolVtbl ProtocolVtbl;
+
+typedef struct {
+ const ProtocolVtbl *vtbl;
+
+ IInternetProtocol *protocol;
+ IInternetProtocolSink *protocol_sink;
+
+ DWORD bindf;
+ BINDINFO bind_info;
+
+ HINTERNET internet;
+ HINTERNET request;
+ HINTERNET connection;
+ DWORD flags;
+ HANDLE lock;
+
+ ULONG current_position;
+ ULONG content_length;
+ ULONG available_bytes;
+
+ LONG priority;
+} Protocol;
+
+struct ProtocolVtbl {
+ HRESULT (*open_request)(Protocol*,LPCWSTR,DWORD,IInternetBindInfo*);
+ HRESULT (*start_downloading)(Protocol*);
+ void (*close_connection)(Protocol*);
+};
+
+HRESULT
protocol_start(Protocol*,IInternetProtocol*,LPCWSTR,IInternetProtocolSink*,IInternetBindInfo*);
+HRESULT protocol_continue(Protocol*,PROTOCOLDATA*);
+HRESULT protocol_read(Protocol*,void*,ULONG,ULONG*);
+HRESULT protocol_lock_request(Protocol*);
+HRESULT protocol_unlock_request(Protocol*);
+void protocol_close_connection(Protocol*);
static inline void *heap_alloc(size_t len)
{
@@ -111,6 +151,21 @@
return ret;
}
+static inline LPWSTR heap_strndupW(LPCWSTR str, int len)
+{
+ LPWSTR ret = NULL;
+
+ if(str) {
+ ret = heap_alloc((len+1)*sizeof(WCHAR));
+ if(ret) {
+ memcpy(ret, str, len*sizeof(WCHAR));
+ ret[len] = 0;
+ }
+ }
+
+ return ret;
+}
+
static inline LPWSTR heap_strdupAtoW(const char *str)
{
LPWSTR ret = NULL;