Commit 298a1b29 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

server: Move the STATUS_ALERTED logic from async_request_complete() to async_terminate().

In particular, don't mark asyncs with output data as "alerted", i.e. restartable. Signed-off-by: 's avatarZebediah Figura <zfigura@codeweavers.com> Signed-off-by: 's avatarAlexandre Julliard <julliard@winehq.org>
parent 19d39239
...@@ -663,11 +663,12 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -663,11 +663,12 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
size = 0xdeadf00d; size = 0xdeadf00d;
SetLastError(0xdeadf00d); SetLastError(0xdeadf00d);
ret = DeviceIoControl(device, ioctl, params, sizeof(*params), buffer, sizeof(buffer), &size, NULL); ret = DeviceIoControl(device, ioctl, params, sizeof(*params), buffer, sizeof(buffer), &size, NULL);
todo_wine_if (NT_SUCCESS(expect_status) != NT_SUCCESS(params->iosb_status)) todo_wine_if ((params->iosb_status != STATUS_PENDING && NT_SUCCESS(expect_status) != NT_SUCCESS(params->iosb_status))
|| (params->iosb_status == STATUS_PENDING && NT_SUCCESS(expect_status)))
ok(ret == NT_SUCCESS(expect_status), "got %d\n", ret); ok(ret == NT_SUCCESS(expect_status), "got %d\n", ret);
if (NT_SUCCESS(expect_status)) if (NT_SUCCESS(expect_status))
{ {
todo_wine_if (!NT_SUCCESS(params->iosb_status)) todo_wine_if (!NT_SUCCESS(params->iosb_status) || params->iosb_status == STATUS_PENDING)
ok(GetLastError() == 0xdeadf00d, "got error %u\n", GetLastError()); ok(GetLastError() == 0xdeadf00d, "got error %u\n", GetLastError());
} }
else else
...@@ -679,7 +680,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -679,7 +680,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
if (NT_ERROR(expect_status)) if (NT_ERROR(expect_status))
todo_wine ok(size == 0xdeadf00d, "got size %u\n", size); todo_wine ok(size == 0xdeadf00d, "got size %u\n", size);
else if (!NT_ERROR(params->iosb_status)) else if (!NT_ERROR(params->iosb_status))
ok(size == 3, "got size %u\n", size); todo_wine_if (params->iosb_status == STATUS_PENDING) ok(size == 3, "got size %u\n", size);
/* size is garbage if !NT_ERROR(expect_status) && NT_ERROR(iosb_status) */ /* size is garbage if !NT_ERROR(expect_status) && NT_ERROR(iosb_status) */
todo_wine_if (ioctl != IOCTL_WINETEST_RETURN_STATUS_BUFFERED) todo_wine_if (ioctl != IOCTL_WINETEST_RETURN_STATUS_BUFFERED)
ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer); ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer);
...@@ -689,8 +690,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -689,8 +690,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
io.Information = 0xdeadf00d; io.Information = 0xdeadf00d;
ret = NtDeviceIoControlFile(device, NULL, NULL, NULL, &io, ret = NtDeviceIoControlFile(device, NULL, NULL, NULL, &io,
ioctl, params, sizeof(*params), buffer, sizeof(buffer)); ioctl, params, sizeof(*params), buffer, sizeof(buffer));
todo_wine_if ((params->ret_status != params->iosb_status && params->ret_status != STATUS_PENDING) todo_wine_if (params->ret_status != params->iosb_status && params->ret_status != STATUS_PENDING)
|| params->iosb_status == STATUS_PENDING)
ok(ret == expect_status, "got %#x\n", ret); ok(ret == expect_status, "got %#x\n", ret);
if (NT_ERROR(params->iosb_status)) if (NT_ERROR(params->iosb_status))
{ {
...@@ -700,9 +700,11 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -700,9 +700,11 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
else else
{ {
todo_wine_if (params->iosb_status == STATUS_PENDING) todo_wine_if (params->iosb_status == STATUS_PENDING)
{
ok(io.Status == params->iosb_status, "got %#x\n", io.Status); ok(io.Status == params->iosb_status, "got %#x\n", io.Status);
ok(io.Information == 3, "got size %Iu\n", io.Information); ok(io.Information == 3, "got size %Iu\n", io.Information);
} }
}
todo_wine_if (ioctl != IOCTL_WINETEST_RETURN_STATUS_BUFFERED) todo_wine_if (ioctl != IOCTL_WINETEST_RETURN_STATUS_BUFFERED)
ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer); ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer);
...@@ -723,7 +725,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -723,7 +725,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
io.Information = 0xdeadf00d; io.Information = 0xdeadf00d;
ret = NtDeviceIoControlFile(file, event, NULL, (void *)456, &io, ret = NtDeviceIoControlFile(file, event, NULL, (void *)456, &io,
ioctl, params, sizeof(*params), buffer, sizeof(buffer)); ioctl, params, sizeof(*params), buffer, sizeof(buffer));
todo_wine_if (params->ret_status != params->iosb_status || params->ret_status == STATUS_PENDING) todo_wine_if (params->ret_status != params->iosb_status)
ok(ret == params->ret_status ok(ret == params->ret_status
|| broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */ || broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */
"got %#x\n", ret); "got %#x\n", ret);
...@@ -737,8 +739,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -737,8 +739,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
else else
{ {
todo_wine_if (params->iosb_status == STATUS_PENDING) todo_wine_if (params->iosb_status == STATUS_PENDING)
{
ok(io.Status == params->iosb_status, "got %#x\n", io.Status); ok(io.Status == params->iosb_status, "got %#x\n", io.Status);
ok(io.Information == 3, "got size %Iu\n", io.Information); ok(io.Information == 3, "got size %Iu\n", io.Information);
}
ret = WaitForSingleObject(event, 0); ret = WaitForSingleObject(event, 0);
ok(!ret, "got %d\n", ret); ok(!ret, "got %d\n", ret);
} }
...@@ -761,8 +765,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -761,8 +765,8 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
ok(!ret, "got %#x\n", ret); ok(!ret, "got %#x\n", ret);
ok(key == 123, "got key %Iu\n", key); ok(key == 123, "got key %Iu\n", key);
ok(value == 456, "got value %Iu\n", value); ok(value == 456, "got value %Iu\n", value);
todo_wine_if (params->iosb_status == STATUS_PENDING)
ok(io.Status == params->iosb_status, "got iosb status %#x\n", io.Status); ok(io.Status == params->iosb_status, "got iosb status %#x\n", io.Status);
todo_wine_if (params->iosb_status == STATUS_PENDING)
ok(io.Information == 3, "got information %Iu\n", io.Information); ok(io.Information == 3, "got information %Iu\n", io.Information);
} }
...@@ -774,7 +778,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -774,7 +778,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
io.Information = 0xdeadf00d; io.Information = 0xdeadf00d;
ret = NtDeviceIoControlFile(file, event, NULL, NULL, &io, ret = NtDeviceIoControlFile(file, event, NULL, NULL, &io,
ioctl, params, sizeof(*params), buffer, sizeof(buffer)); ioctl, params, sizeof(*params), buffer, sizeof(buffer));
todo_wine_if (params->ret_status != params->iosb_status || params->ret_status == STATUS_PENDING) todo_wine_if (params->ret_status != params->iosb_status)
ok(ret == params->ret_status ok(ret == params->ret_status
|| broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */ || broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */
"got %#x\n", ret); "got %#x\n", ret);
...@@ -788,8 +792,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -788,8 +792,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
else else
{ {
todo_wine_if (params->iosb_status == STATUS_PENDING) todo_wine_if (params->iosb_status == STATUS_PENDING)
{
ok(io.Status == params->iosb_status, "got %#x\n", io.Status); ok(io.Status == params->iosb_status, "got %#x\n", io.Status);
ok(io.Information == 3, "got size %Iu\n", io.Information); ok(io.Information == 3, "got size %Iu\n", io.Information);
}
ret = WaitForSingleObject(event, 0); ret = WaitForSingleObject(event, 0);
ok(!ret, "got %d\n", ret); ok(!ret, "got %d\n", ret);
} }
...@@ -805,7 +811,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -805,7 +811,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
io.Information = 0xdeadf00d; io.Information = 0xdeadf00d;
ret = NtDeviceIoControlFile(file, NULL, NULL, NULL, &io, ret = NtDeviceIoControlFile(file, NULL, NULL, NULL, &io,
ioctl, params, sizeof(*params), buffer, sizeof(buffer)); ioctl, params, sizeof(*params), buffer, sizeof(buffer));
todo_wine_if (params->ret_status != params->iosb_status || params->ret_status == STATUS_PENDING) todo_wine_if (params->ret_status != params->iosb_status)
ok(ret == params->ret_status ok(ret == params->ret_status
|| broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */ || broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */
"got %#x\n", ret); "got %#x\n", ret);
...@@ -819,8 +825,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -819,8 +825,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
else else
{ {
todo_wine_if (params->iosb_status == STATUS_PENDING) todo_wine_if (params->iosb_status == STATUS_PENDING)
{
ok(io.Status == params->iosb_status, "got %#x\n", io.Status); ok(io.Status == params->iosb_status, "got %#x\n", io.Status);
ok(io.Information == 3, "got size %Iu\n", io.Information); ok(io.Information == 3, "got size %Iu\n", io.Information);
}
ret = WaitForSingleObject(file, 0); ret = WaitForSingleObject(file, 0);
ok(!ret, "got %d\n", ret); ok(!ret, "got %d\n", ret);
} }
...@@ -840,7 +848,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -840,7 +848,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
io.Information = 0xdeadf00d; io.Information = 0xdeadf00d;
ret = NtDeviceIoControlFile(file, event, NULL, (void *)456, &io, ret = NtDeviceIoControlFile(file, event, NULL, (void *)456, &io,
ioctl, params, sizeof(*params), buffer, sizeof(buffer)); ioctl, params, sizeof(*params), buffer, sizeof(buffer));
todo_wine_if (params->ret_status != params->iosb_status || params->ret_status == STATUS_PENDING) todo_wine_if (params->ret_status != params->iosb_status)
ok(ret == params->ret_status ok(ret == params->ret_status
|| broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */ || broken(NT_WARNING(params->ret_status) && ret == STATUS_PENDING), /* win10 */
"got %#x\n", ret); "got %#x\n", ret);
...@@ -854,8 +862,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -854,8 +862,10 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
else else
{ {
todo_wine_if (params->iosb_status == STATUS_PENDING) todo_wine_if (params->iosb_status == STATUS_PENDING)
{
ok(io.Status == params->iosb_status, "got %#x\n", io.Status); ok(io.Status == params->iosb_status, "got %#x\n", io.Status);
ok(io.Information == 3, "got size %Iu\n", io.Information); ok(io.Information == 3, "got size %Iu\n", io.Information);
}
ret = WaitForSingleObject(event, 0); ret = WaitForSingleObject(event, 0);
ok(!ret, "got %d\n", ret); ok(!ret, "got %d\n", ret);
} }
...@@ -909,7 +919,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -909,7 +919,7 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
io.Information = 0xdeadf00d; io.Information = 0xdeadf00d;
ret = NtDeviceIoControlFile(file, NULL, return_status_apc, (void *)456, &io, ret = NtDeviceIoControlFile(file, NULL, return_status_apc, (void *)456, &io,
ioctl, params, sizeof(*params), buffer, sizeof(buffer)); ioctl, params, sizeof(*params), buffer, sizeof(buffer));
todo_wine_if (params->ret_status != params->iosb_status || params->ret_status == STATUS_PENDING) todo_wine_if (params->ret_status != params->iosb_status)
ok(ret == params->ret_status, "got %#x\n", ret); ok(ret == params->ret_status, "got %#x\n", ret);
if (!params->pending && NT_ERROR(params->iosb_status)) if (!params->pending && NT_ERROR(params->iosb_status))
{ {
...@@ -919,9 +929,11 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params) ...@@ -919,9 +929,11 @@ static void do_return_status(ULONG ioctl, struct return_status_params *params)
else else
{ {
todo_wine_if (params->iosb_status == STATUS_PENDING) todo_wine_if (params->iosb_status == STATUS_PENDING)
{
ok(io.Status == params->iosb_status, "got %#x\n", io.Status); ok(io.Status == params->iosb_status, "got %#x\n", io.Status);
ok(io.Information == 3, "got size %Iu\n", io.Information); ok(io.Information == 3, "got size %Iu\n", io.Information);
} }
}
todo_wine_if (ioctl != IOCTL_WINETEST_RETURN_STATUS_BUFFERED) todo_wine_if (ioctl != IOCTL_WINETEST_RETURN_STATUS_BUFFERED)
ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer); ok(!strcmp(buffer, expect_buffer), "got buffer %s\n", buffer);
......
...@@ -156,6 +156,8 @@ static void async_destroy( struct object *obj ) ...@@ -156,6 +156,8 @@ static void async_destroy( struct object *obj )
/* notifies client thread of new status of its async request */ /* notifies client thread of new status of its async request */
void async_terminate( struct async *async, unsigned int status ) void async_terminate( struct async *async, unsigned int status )
{ {
struct iosb *iosb = async->iosb;
if (async->terminated) return; if (async->terminated) return;
async->terminated = 1; async->terminated = 1;
...@@ -176,7 +178,15 @@ void async_terminate( struct async *async, unsigned int status ) ...@@ -176,7 +178,15 @@ void async_terminate( struct async *async, unsigned int status )
data.type = APC_ASYNC_IO; data.type = APC_ASYNC_IO;
data.async_io.user = async->data.user; data.async_io.user = async->data.user;
data.async_io.sb = async->data.iosb; data.async_io.sb = async->data.iosb;
/* if the result is nonzero or there is output data, the client needs to
* make an extra request to retrieve them; use STATUS_ALERTED to signal
* this case */
if (iosb && (iosb->result || iosb->out_data))
data.async_io.status = STATUS_ALERTED;
else
data.async_io.status = status; data.async_io.status = status;
thread_queue_apc( async->thread->process, async->thread, &async->obj, &data ); thread_queue_apc( async->thread->process, async->thread, &async->obj, &data );
} }
...@@ -353,11 +363,6 @@ void async_request_complete( struct async *async, unsigned int status, data_size ...@@ -353,11 +363,6 @@ void async_request_complete( struct async *async, unsigned int status, data_size
release_object( iosb ); release_object( iosb );
/* if the result is nonzero or there is output data, the client needs to
* make an extra request to retrieve them; use STATUS_ALERTED to signal
* this case */
if (result || out_data)
status = STATUS_ALERTED;
async_terminate( async, status ); async_terminate( async, status );
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment