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
7a73d01f
Commit
7a73d01f
authored
Aug 23, 2019
by
Zebediah Figura
Committed by
Alexandre Julliard
Aug 26, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
http.sys: Allow receiving parsed HTTP requests.
Signed-off-by:
Zebediah Figura
<
z.figura12@gmail.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
85f5338e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
208 additions
and
0 deletions
+208
-0
http.c
dlls/http.sys/http.c
+199
-0
http.h
include/wine/http.h
+9
-0
No files found.
dlls/http.sys/http.c
View file @
7a73d01f
...
@@ -18,6 +18,7 @@
...
@@ -18,6 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
*/
#include <assert.h>
#include "ntstatus.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
#define WIN32_NO_STATUS
#include "wine/http.h"
#include "wine/http.h"
...
@@ -32,6 +33,108 @@ static DEVICE_OBJECT *device_obj;
...
@@ -32,6 +33,108 @@ static DEVICE_OBJECT *device_obj;
WINE_DEFAULT_DEBUG_CHANNEL
(
http
);
WINE_DEFAULT_DEBUG_CHANNEL
(
http
);
/* We have to return the HTTP_REQUEST structure to userspace exactly as it will
* be consumed; httpapi has no opportunity to massage it. Since it contains
* pointers, this is somewhat nontrivial. */
struct
http_request_32
{
ULONG
Flags
;
HTTP_CONNECTION_ID
ConnectionId
;
HTTP_REQUEST_ID
RequestId
;
HTTP_URL_CONTEXT
UrlContext
;
HTTP_VERSION
Version
;
HTTP_VERB
Verb
;
USHORT
UnknownVerbLength
;
USHORT
RawUrlLength
;
ULONG
pUnknownVerb
;
/* char string */
ULONG
pRawUrl
;
/* char string */
struct
{
USHORT
FullUrlLength
;
USHORT
HostLength
;
USHORT
AbsPathLength
;
USHORT
QueryStringLength
;
ULONG
pFullUrl
;
/* WCHAR string */
ULONG
pHost
;
/* pointer to above */
ULONG
pAbsPath
;
/* pointer to above */
ULONG
pQueryString
;
/* pointer to above */
}
CookedUrl
;
struct
{
ULONG
pRemoteAddress
;
/* SOCKADDR */
ULONG
pLocalAddress
;
/* SOCKADDR */
}
Address
;
struct
{
USHORT
UnknownHeaderCount
;
ULONG
pUnknownHeaders
;
/* struct http_unknown_header_32 */
USHORT
TrailerCount
;
ULONG
pTrailers
;
/* NULL */
struct
{
USHORT
RawValueLength
;
ULONG
pRawValue
;
/* char string */
}
KnownHeaders
[
HttpHeaderRequestMaximum
];
}
Headers
;
ULONGLONG
BytesReceived
;
USHORT
EntityChunkCount
;
ULONG
pEntityChunks
;
/* struct http_data_chunk_32 */
HTTP_RAW_CONNECTION_ID
RawConnectionId
;
ULONG
pSslInfo
;
/* NULL (FIXME) */
USHORT
RequestInfoCount
;
ULONG
pRequestInfo
;
/* NULL (FIXME) */
};
struct
http_request_64
{
ULONG
Flags
;
HTTP_CONNECTION_ID
ConnectionId
;
HTTP_REQUEST_ID
RequestId
;
HTTP_URL_CONTEXT
UrlContext
;
HTTP_VERSION
Version
;
HTTP_VERB
Verb
;
USHORT
UnknownVerbLength
;
USHORT
RawUrlLength
;
ULONGLONG
pUnknownVerb
;
/* char string */
ULONGLONG
pRawUrl
;
/* char string */
struct
{
USHORT
FullUrlLength
;
USHORT
HostLength
;
USHORT
AbsPathLength
;
USHORT
QueryStringLength
;
ULONGLONG
pFullUrl
;
/* WCHAR string */
ULONGLONG
pHost
;
/* pointer to above */
ULONGLONG
pAbsPath
;
/* pointer to above */
ULONGLONG
pQueryString
;
/* pointer to above */
}
CookedUrl
;
struct
{
ULONGLONG
pRemoteAddress
;
/* SOCKADDR */
ULONGLONG
pLocalAddress
;
/* SOCKADDR */
}
Address
;
struct
{
USHORT
UnknownHeaderCount
;
ULONGLONG
pUnknownHeaders
;
/* struct http_unknown_header_32 */
USHORT
TrailerCount
;
ULONGLONG
pTrailers
;
/* NULL */
struct
{
USHORT
RawValueLength
;
ULONGLONG
pRawValue
;
/* char string */
}
KnownHeaders
[
HttpHeaderRequestMaximum
];
}
Headers
;
ULONGLONG
BytesReceived
;
USHORT
EntityChunkCount
;
ULONGLONG
pEntityChunks
;
/* struct http_data_chunk_32 */
HTTP_RAW_CONNECTION_ID
RawConnectionId
;
ULONGLONG
pSslInfo
;
/* NULL (FIXME) */
USHORT
RequestInfoCount
;
ULONGLONG
pRequestInfo
;
/* NULL (FIXME) */
};
#define DECLARE_CRITICAL_SECTION(cs) \
#define DECLARE_CRITICAL_SECTION(cs) \
static CRITICAL_SECTION cs; \
static CRITICAL_SECTION cs; \
static CRITICAL_SECTION_DEBUG cs##_debug = \
static CRITICAL_SECTION_DEBUG cs##_debug = \
...
@@ -161,6 +264,73 @@ static int parse_token(const char *str, const char *end)
...
@@ -161,6 +264,73 @@ static int parse_token(const char *str, const char *end)
return
p
-
str
;
return
p
-
str
;
}
}
static
NTSTATUS
complete_irp
(
struct
connection
*
conn
,
IRP
*
irp
)
{
const
struct
http_receive_request_params
params
=
*
(
struct
http_receive_request_params
*
)
irp
->
AssociatedIrp
.
SystemBuffer
;
DWORD
irp_size
=
(
params
.
bits
==
32
)
?
sizeof
(
struct
http_request_32
)
:
sizeof
(
struct
http_request_64
);
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
const
DWORD
output_len
=
stack
->
Parameters
.
DeviceIoControl
.
OutputBufferLength
;
ULONG
offset
;
TRACE
(
"Completing IRP %p.
\n
"
,
irp
);
/* First calculate the total buffer size needed for this IRP. */
TRACE
(
"Need %u bytes, have %u.
\n
"
,
irp_size
,
output_len
);
irp
->
IoStatus
.
Information
=
irp_size
;
memset
(
irp
->
AssociatedIrp
.
SystemBuffer
,
0
,
output_len
);
if
(
output_len
<
irp_size
)
{
if
(
params
.
bits
==
32
)
{
struct
http_request_32
*
req
=
irp
->
AssociatedIrp
.
SystemBuffer
;
req
->
ConnectionId
=
(
ULONG_PTR
)
conn
;
}
else
{
struct
http_request_64
*
req
=
irp
->
AssociatedIrp
.
SystemBuffer
;
req
->
ConnectionId
=
(
ULONG_PTR
)
conn
;
}
return
STATUS_BUFFER_OVERFLOW
;
}
if
(
params
.
bits
==
32
)
{
struct
http_request_32
*
req
=
irp
->
AssociatedIrp
.
SystemBuffer
;
offset
=
sizeof
(
*
req
);
req
->
ConnectionId
=
(
ULONG_PTR
)
conn
;
req
->
UrlContext
=
conn
->
queue
->
context
;
req
->
Version
=
conn
->
version
;
req
->
Verb
=
conn
->
verb
;
req
->
BytesReceived
=
conn
->
req_len
;
}
else
{
struct
http_request_64
*
req
=
irp
->
AssociatedIrp
.
SystemBuffer
;
offset
=
sizeof
(
*
req
);
req
->
ConnectionId
=
(
ULONG_PTR
)
conn
;
req
->
UrlContext
=
conn
->
queue
->
context
;
req
->
Version
=
conn
->
version
;
req
->
Verb
=
conn
->
verb
;
req
->
BytesReceived
=
conn
->
req_len
;
}
assert
(
offset
==
irp
->
IoStatus
.
Information
);
conn
->
available
=
FALSE
;
memmove
(
conn
->
buffer
,
conn
->
buffer
+
conn
->
req_len
,
conn
->
len
-
conn
->
req_len
);
conn
->
len
-=
conn
->
req_len
;
return
STATUS_SUCCESS
;
}
/* Return 1 if str matches expect, 0 if str is incomplete, -1 if they don't match. */
/* Return 1 if str matches expect, 0 if str is incomplete, -1 if they don't match. */
static
int
compare_exact
(
const
char
*
str
,
const
char
*
expect
,
const
char
*
end
)
static
int
compare_exact
(
const
char
*
str
,
const
char
*
expect
,
const
char
*
end
)
{
{
...
@@ -507,6 +677,32 @@ static NTSTATUS http_remove_url(struct request_queue *queue, IRP *irp)
...
@@ -507,6 +677,32 @@ static NTSTATUS http_remove_url(struct request_queue *queue, IRP *irp)
return
STATUS_SUCCESS
;
return
STATUS_SUCCESS
;
}
}
static
NTSTATUS
http_receive_request
(
struct
request_queue
*
queue
,
IRP
*
irp
)
{
const
struct
http_receive_request_params
*
params
=
irp
->
AssociatedIrp
.
SystemBuffer
;
struct
connection
*
conn
;
NTSTATUS
ret
;
TRACE
(
"addr %s, id %s, flags %#x, bits %u.
\n
"
,
wine_dbgstr_longlong
(
params
->
addr
),
wine_dbgstr_longlong
(
params
->
id
),
params
->
flags
,
params
->
bits
);
EnterCriticalSection
(
&
http_cs
);
LIST_FOR_EACH_ENTRY
(
conn
,
&
connections
,
struct
connection
,
entry
)
{
if
(
conn
->
available
&&
conn
->
queue
==
queue
)
{
ret
=
complete_irp
(
conn
,
irp
);
LeaveCriticalSection
(
&
http_cs
);
return
ret
;
}
}
LeaveCriticalSection
(
&
http_cs
);
return
STATUS_PENDING
;
}
static
NTSTATUS
WINAPI
dispatch_ioctl
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
static
NTSTATUS
WINAPI
dispatch_ioctl
(
DEVICE_OBJECT
*
device
,
IRP
*
irp
)
{
{
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
IO_STACK_LOCATION
*
stack
=
IoGetCurrentIrpStackLocation
(
irp
);
...
@@ -521,6 +717,9 @@ static NTSTATUS WINAPI dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp)
...
@@ -521,6 +717,9 @@ static NTSTATUS WINAPI dispatch_ioctl(DEVICE_OBJECT *device, IRP *irp)
case
IOCTL_HTTP_REMOVE_URL
:
case
IOCTL_HTTP_REMOVE_URL
:
ret
=
http_remove_url
(
queue
,
irp
);
ret
=
http_remove_url
(
queue
,
irp
);
break
;
break
;
case
IOCTL_HTTP_RECEIVE_REQUEST
:
ret
=
http_receive_request
(
queue
,
irp
);
break
;
default:
default:
FIXME
(
"Unhandled ioctl %#x.
\n
"
,
stack
->
Parameters
.
DeviceIoControl
.
IoControlCode
);
FIXME
(
"Unhandled ioctl %#x.
\n
"
,
stack
->
Parameters
.
DeviceIoControl
.
IoControlCode
);
ret
=
STATUS_NOT_IMPLEMENTED
;
ret
=
STATUS_NOT_IMPLEMENTED
;
...
...
include/wine/http.h
View file @
7a73d01f
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
#define IOCTL_HTTP_ADD_URL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, 0)
#define IOCTL_HTTP_ADD_URL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, 0)
#define IOCTL_HTTP_REMOVE_URL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, 0)
#define IOCTL_HTTP_REMOVE_URL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, 0)
#define IOCTL_HTTP_RECEIVE_REQUEST CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, 0)
struct
http_add_url_params
struct
http_add_url_params
{
{
...
@@ -32,4 +33,12 @@ struct http_add_url_params
...
@@ -32,4 +33,12 @@ struct http_add_url_params
char
url
[
1
];
char
url
[
1
];
};
};
struct
http_receive_request_params
{
ULONGLONG
addr
;
/* user-mode buffer address */
HTTP_REQUEST_ID
id
;
ULONG
flags
;
ULONG
bits
;
};
#endif
#endif
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