http.sys: Support cancelling IRPs.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0959d189c8
commit
fb35743f84
|
@ -1178,6 +1178,20 @@ static struct connection *get_connection(HTTP_REQUEST_ID req_id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WINAPI http_receive_request_cancel(DEVICE_OBJECT *device, IRP *irp)
|
||||||
|
{
|
||||||
|
TRACE("device %p, irp %p.\n", device, irp);
|
||||||
|
|
||||||
|
IoReleaseCancelSpinLock(irp->CancelIrql);
|
||||||
|
|
||||||
|
EnterCriticalSection(&http_cs);
|
||||||
|
RemoveEntryList(&irp->Tail.Overlay.ListEntry);
|
||||||
|
LeaveCriticalSection(&http_cs);
|
||||||
|
|
||||||
|
irp->IoStatus.Status = STATUS_CANCELLED;
|
||||||
|
IoCompleteRequest(irp, IO_NO_INCREMENT);
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS http_receive_request(struct request_queue *queue, IRP *irp)
|
static NTSTATUS http_receive_request(struct request_queue *queue, IRP *irp)
|
||||||
{
|
{
|
||||||
const struct http_receive_request_params *params = irp->AssociatedIrp.SystemBuffer;
|
const struct http_receive_request_params *params = irp->AssociatedIrp.SystemBuffer;
|
||||||
|
@ -1199,9 +1213,19 @@ static NTSTATUS http_receive_request(struct request_queue *queue, IRP *irp)
|
||||||
if (params->id == HTTP_NULL_ID)
|
if (params->id == HTTP_NULL_ID)
|
||||||
{
|
{
|
||||||
TRACE("Queuing IRP %p.\n", irp);
|
TRACE("Queuing IRP %p.\n", irp);
|
||||||
|
|
||||||
|
IoSetCancelRoutine(irp, http_receive_request_cancel);
|
||||||
|
if (irp->Cancel && !IoSetCancelRoutine(irp, NULL))
|
||||||
|
{
|
||||||
|
/* The IRP was canceled before we set the cancel routine. */
|
||||||
|
ret = STATUS_CANCELLED;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
InsertTailList(&queue->irp_queue, &irp->Tail.Overlay.ListEntry);
|
InsertTailList(&queue->irp_queue, &irp->Tail.Overlay.ListEntry);
|
||||||
ret = STATUS_PENDING;
|
ret = STATUS_PENDING;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ret = STATUS_CONNECTION_INVALID;
|
ret = STATUS_CONNECTION_INVALID;
|
||||||
|
|
||||||
|
|
|
@ -348,6 +348,18 @@ static void test_v1_server(void)
|
||||||
ret = remove_url_v1(queue, port);
|
ret = remove_url_v1(queue, port);
|
||||||
ok(ret == ERROR_FILE_NOT_FOUND, "Got error %u.\n", ret);
|
ok(ret == ERROR_FILE_NOT_FOUND, "Got error %u.\n", ret);
|
||||||
|
|
||||||
|
ret = HttpReceiveHttpRequest(queue, HTTP_NULL_ID, 0, (HTTP_REQUEST *)req, sizeof(req_buffer), NULL, &ovl);
|
||||||
|
ok(ret == ERROR_IO_PENDING, "Got error %u.\n", ret);
|
||||||
|
|
||||||
|
ret = CancelIo(queue);
|
||||||
|
ok(ret, "Failed to close queue handle, error %u.\n", GetLastError());
|
||||||
|
|
||||||
|
ret_size = 0xdeadbeef;
|
||||||
|
ret = GetOverlappedResult(queue, &ovl, &ret_size, FALSE);
|
||||||
|
ok(!ret, "Expected failure.\n");
|
||||||
|
ok(GetLastError() == ERROR_OPERATION_ABORTED, "Got error %u.\n", GetLastError());
|
||||||
|
ok(!ret_size, "Got size %u.\n", ret_size);
|
||||||
|
|
||||||
closesocket(s);
|
closesocket(s);
|
||||||
CloseHandle(ovl.hEvent);
|
CloseHandle(ovl.hEvent);
|
||||||
ret = CloseHandle(queue);
|
ret = CloseHandle(queue);
|
||||||
|
|
Loading…
Reference in New Issue