ws2_32: Add support for TransmitFile headers and footers.
Signed-off-by: Erich E. Hoover <erich.e.hoover@wine-staging.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4d081f36ef
commit
f1ebc93603
|
@ -522,6 +522,7 @@ struct ws2_transmitfile_async
|
||||||
DWORD file_read;
|
DWORD file_read;
|
||||||
DWORD file_bytes;
|
DWORD file_bytes;
|
||||||
DWORD bytes_per_send;
|
DWORD bytes_per_send;
|
||||||
|
TRANSMIT_FILE_BUFFERS buffers;
|
||||||
DWORD flags;
|
DWORD flags;
|
||||||
struct ws2_async write;
|
struct ws2_async write;
|
||||||
};
|
};
|
||||||
|
@ -2789,6 +2790,17 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn
|
||||||
if (wsa->write.first_iovec < wsa->write.n_iovecs)
|
if (wsa->write.first_iovec < wsa->write.n_iovecs)
|
||||||
return STATUS_PENDING;
|
return STATUS_PENDING;
|
||||||
|
|
||||||
|
/* process the header (if applicable) */
|
||||||
|
if (wsa->buffers.Head)
|
||||||
|
{
|
||||||
|
wsa->write.first_iovec = 0;
|
||||||
|
wsa->write.n_iovecs = 1;
|
||||||
|
wsa->write.iovec[0].iov_base = wsa->buffers.Head;
|
||||||
|
wsa->write.iovec[0].iov_len = wsa->buffers.HeadLength;
|
||||||
|
wsa->buffers.Head = NULL;
|
||||||
|
return STATUS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
/* process the main file */
|
/* process the main file */
|
||||||
if (wsa->file)
|
if (wsa->file)
|
||||||
{
|
{
|
||||||
|
@ -2801,7 +2813,7 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn
|
||||||
bytes_per_send = min(bytes_per_send, wsa->file_bytes - wsa->file_read);
|
bytes_per_send = min(bytes_per_send, wsa->file_bytes - wsa->file_read);
|
||||||
status = WS2_ReadFile( wsa->file, &iosb, wsa->buffer, bytes_per_send );
|
status = WS2_ReadFile( wsa->file, &iosb, wsa->buffer, bytes_per_send );
|
||||||
if (status == STATUS_END_OF_FILE)
|
if (status == STATUS_END_OF_FILE)
|
||||||
return STATUS_SUCCESS;
|
wsa->file = NULL; /* continue on to the footer */
|
||||||
else if (status != STATUS_SUCCESS)
|
else if (status != STATUS_SUCCESS)
|
||||||
return status;
|
return status;
|
||||||
else
|
else
|
||||||
|
@ -2822,6 +2834,17 @@ static NTSTATUS WS2_transmitfile_getbuffer( int fd, struct ws2_transmitfile_asyn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* send the footer (if applicable) */
|
||||||
|
if (wsa->buffers.Tail)
|
||||||
|
{
|
||||||
|
wsa->write.first_iovec = 0;
|
||||||
|
wsa->write.n_iovecs = 1;
|
||||||
|
wsa->write.iovec[0].iov_base = wsa->buffers.Tail;
|
||||||
|
wsa->write.iovec[0].iov_len = wsa->buffers.TailLength;
|
||||||
|
wsa->buffers.Tail = NULL;
|
||||||
|
return STATUS_PENDING;
|
||||||
|
}
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2860,7 +2883,7 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if (overlapped || buffers)
|
if (overlapped)
|
||||||
{
|
{
|
||||||
FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send,
|
FIXME("(%lx, %p, %d, %d, %p, %p, %d): stub !\n", s, h, file_bytes, bytes_per_send,
|
||||||
overlapped, buffers, flags);
|
overlapped, buffers, flags);
|
||||||
|
@ -2904,6 +2927,10 @@ static BOOL WINAPI WS2_TransmitFile( SOCKET s, HANDLE h, DWORD file_bytes, DWORD
|
||||||
WSASetLastError( WSAEFAULT );
|
WSASetLastError( WSAEFAULT );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
if (buffers)
|
||||||
|
wsa->buffers = *buffers;
|
||||||
|
else
|
||||||
|
memset(&wsa->buffers, 0x0, sizeof(wsa->buffers));
|
||||||
wsa->buffer = (char *)(wsa + 1);
|
wsa->buffer = (char *)(wsa + 1);
|
||||||
wsa->file = h;
|
wsa->file = h;
|
||||||
wsa->file_read = 0;
|
wsa->file_read = 0;
|
||||||
|
|
|
@ -7460,8 +7460,11 @@ static void test_TransmitFile(void)
|
||||||
GUID transmitFileGuid = WSAID_TRANSMITFILE;
|
GUID transmitFileGuid = WSAID_TRANSMITFILE;
|
||||||
LPFN_TRANSMITFILE pTransmitFile = NULL;
|
LPFN_TRANSMITFILE pTransmitFile = NULL;
|
||||||
HANDLE file = INVALID_HANDLE_VALUE;
|
HANDLE file = INVALID_HANDLE_VALUE;
|
||||||
|
char header_msg[] = "hello world";
|
||||||
|
char footer_msg[] = "goodbye!!!";
|
||||||
char system_ini_path[MAX_PATH];
|
char system_ini_path[MAX_PATH];
|
||||||
struct sockaddr_in bindAddress;
|
struct sockaddr_in bindAddress;
|
||||||
|
TRANSMIT_FILE_BUFFERS buffers;
|
||||||
SOCKET client, server, dest;
|
SOCKET client, server, dest;
|
||||||
DWORD num_bytes, err;
|
DWORD num_bytes, err;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
@ -7546,11 +7549,42 @@ static void test_TransmitFile(void)
|
||||||
iret = recv(dest, buf, sizeof(buf), 0);
|
iret = recv(dest, buf, sizeof(buf), 0);
|
||||||
ok(iret == -1, "Returned an unexpected buffer from TransmitFile (%d != -1).\n", iret);
|
ok(iret == -1, "Returned an unexpected buffer from TransmitFile (%d != -1).\n", iret);
|
||||||
|
|
||||||
|
/* Test TransmitFile with only buffer data */
|
||||||
|
buffers.Head = &header_msg[0];
|
||||||
|
buffers.HeadLength = sizeof(header_msg)+1;
|
||||||
|
buffers.Tail = &footer_msg[0];
|
||||||
|
buffers.TailLength = sizeof(footer_msg)+1;
|
||||||
|
bret = pTransmitFile(client, NULL, 0, 0, NULL, &buffers, 0);
|
||||||
|
ok(bret, "TransmitFile failed unexpectedly.\n");
|
||||||
|
iret = recv(dest, buf, sizeof(buf), 0);
|
||||||
|
ok(iret == sizeof(header_msg)+sizeof(footer_msg)+2,
|
||||||
|
"Returned an unexpected buffer from TransmitFile: %d\n", iret );
|
||||||
|
ok(memcmp(&buf[0], &header_msg[0], sizeof(header_msg)+1) == 0,
|
||||||
|
"TransmitFile header buffer did not match!\n");
|
||||||
|
ok(memcmp(&buf[sizeof(header_msg)+1], &footer_msg[0], sizeof(footer_msg)+1) == 0,
|
||||||
|
"TransmitFile footer buffer did not match!\n");
|
||||||
|
|
||||||
/* Test TransmitFile with only file data */
|
/* Test TransmitFile with only file data */
|
||||||
bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0);
|
bret = pTransmitFile(client, file, 0, 0, NULL, NULL, 0);
|
||||||
ok(bret, "TransmitFile failed unexpectedly.\n");
|
ok(bret, "TransmitFile failed unexpectedly.\n");
|
||||||
compare_file(file, dest);
|
compare_file(file, dest);
|
||||||
|
|
||||||
|
/* Test TransmitFile with both file and buffer data */
|
||||||
|
buffers.Head = &header_msg[0];
|
||||||
|
buffers.HeadLength = sizeof(header_msg)+1;
|
||||||
|
buffers.Tail = &footer_msg[0];
|
||||||
|
buffers.TailLength = sizeof(footer_msg)+1;
|
||||||
|
SetFilePointer(file, 0, NULL, FILE_BEGIN);
|
||||||
|
bret = pTransmitFile(client, file, 0, 0, NULL, &buffers, 0);
|
||||||
|
ok(bret, "TransmitFile failed unexpectedly.\n");
|
||||||
|
iret = recv(dest, buf, sizeof(header_msg)+1, 0);
|
||||||
|
ok(memcmp(buf, &header_msg[0], sizeof(header_msg)+1) == 0,
|
||||||
|
"TransmitFile header buffer did not match!\n");
|
||||||
|
compare_file(file, dest);
|
||||||
|
iret = recv(dest, buf, sizeof(footer_msg)+1, 0);
|
||||||
|
ok(memcmp(buf, &footer_msg[0], sizeof(footer_msg)+1) == 0,
|
||||||
|
"TransmitFile footer buffer did not match!\n");
|
||||||
|
|
||||||
/* Test TransmitFile with a UDP datagram socket */
|
/* Test TransmitFile with a UDP datagram socket */
|
||||||
closesocket(client);
|
closesocket(client);
|
||||||
client = socket(AF_INET, SOCK_DGRAM, 0);
|
client = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
Loading…
Reference in New Issue