Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
4c129514
Commit
4c129514
authored
Mar 02, 2009
by
Jacek Caban
Committed by
Alexandre Julliard
Mar 02, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
urlmon: Move HttpProtocol::Read implementation to generic Protocol object.
parent
a30ffca1
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
145 additions
and
79 deletions
+145
-79
http.c
dlls/urlmon/http.c
+1
-79
protocol.c
dlls/urlmon/protocol.c
+143
-0
urlmon_main.h
dlls/urlmon/urlmon_main.h
+1
-0
No files found.
dlls/urlmon/http.c
View file @
4c129514
...
...
@@ -144,14 +144,6 @@ static void HTTPPROTOCOL_ReportData(HttpProtocol *This)
}
}
static
void
HTTPPROTOCOL_AllDataRead
(
HttpProtocol
*
This
)
{
if
(
!
(
This
->
base
.
flags
&
FLAG_ALL_DATA_READ
))
This
->
base
.
flags
|=
FLAG_ALL_DATA_READ
;
HTTPPROTOCOL_ReportData
(
This
);
HTTPPROTOCOL_ReportResult
(
This
,
S_OK
);
}
static
void
CALLBACK
HTTPPROTOCOL_InternetStatusCallback
(
HINTERNET
hInternet
,
DWORD_PTR
dwContext
,
DWORD
dwInternetStatus
,
LPVOID
lpvStatusInformation
,
DWORD
dwStatusInformationLength
)
...
...
@@ -735,80 +727,10 @@ static HRESULT WINAPI HttpProtocol_Read(IInternetProtocol *iface, void *pv,
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
->
base
.
flags
&
FLAG_REQUEST_COMPLETE
))
{
hres
=
E_PENDING
;
}
else
while
(
!
(
This
->
base
.
flags
&
FLAG_ALL_DATA_READ
)
&&
read
<
cb
)
{
if
(
This
->
base
.
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
->
base
.
flags
&=
~
FLAG_REQUEST_COMPLETE
;
if
(
!
InternetQueryDataAvailable
(
This
->
base
.
request
,
&
This
->
base
.
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
->
base
.
available_bytes
==
0
)
{
HTTPPROTOCOL_AllDataRead
(
This
);
}
}
else
{
if
(
!
InternetReadFile
(
This
->
base
.
request
,
((
BYTE
*
)
pv
)
+
read
,
This
->
base
.
available_bytes
>
cb
-
read
?
cb
-
read
:
This
->
base
.
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
->
base
.
current_position
+=
len
;
This
->
base
.
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
->
base
.
flags
|=
FLAG_REQUEST_COMPLETE
;
return
hres
;
return
protocol_read
(
&
This
->
base
,
pv
,
cb
,
pcbRead
);
}
static
HRESULT
WINAPI
HttpProtocol_Seek
(
IInternetProtocol
*
iface
,
LARGE_INTEGER
dlibMove
,
...
...
dlls/urlmon/protocol.c
View file @
4c129514
...
...
@@ -23,6 +23,149 @@
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_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
);
}
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
))
...
...
dlls/urlmon/urlmon_main.h
View file @
4c129514
...
...
@@ -106,6 +106,7 @@ struct ProtocolVtbl {
void
(
*
close_connection
)(
Protocol
*
);
};
HRESULT
protocol_read
(
Protocol
*
,
void
*
,
ULONG
,
ULONG
*
);
HRESULT
protocol_lock_request
(
Protocol
*
);
HRESULT
protocol_unlock_request
(
Protocol
*
);
void
protocol_close_connection
(
Protocol
*
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment