windows: Use architecture-specific size limit for WriteFile calls.

This commit is contained in:
Martin Ling 2019-12-28 19:47:06 +01:00 committed by Uwe Hermann
parent 39df7833f7
commit b457865b8f
5 changed files with 63 additions and 1 deletions

View File

@ -32,7 +32,7 @@ if LINUX
libserialport_la_SOURCES += linux.c linux_termios.c linux_termios.h
endif
if WIN32
libserialport_la_SOURCES += windows.c
libserialport_la_SOURCES += windows.c windows_ddk.c windows_ddk.h
endif
if MACOSX
libserialport_la_SOURCES += macosx.c

View File

@ -47,6 +47,7 @@
static const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }
#include <usbioctl.h>
#include <usbiodef.h>
#include "windows_ddk.h"
#else
#include <limits.h>
#include <termios.h>

View File

@ -793,6 +793,10 @@ SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf,
RETURN_FAIL("SetCommTimeouts() failed");
}
/* Reduce count if it exceeds the WriteFile limit. */
if (count > WRITEFILE_MAX_SIZE)
count = WRITEFILE_MAX_SIZE;
/* Start write. */
if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl)) {
DEBUG("Write completed immediately");
@ -921,6 +925,10 @@ SP_API enum sp_return sp_nonblocking_write(struct sp_port *port,
RETURN_FAIL("SetCommTimeouts() failed");
}
/* Reduce count if it exceeds the WriteFile limit. */
if (count > WRITEFILE_MAX_SIZE)
count = WRITEFILE_MAX_SIZE;
/* Copy data to our write buffer. */
buf_bytes = min(port->write_buf_size, count);
memcpy(port->write_buf, buf, buf_bytes);

28
windows_ddk.c Normal file
View File

@ -0,0 +1,28 @@
/*
* This file is part of the libserialport project.
*
* Copyright (C) 2019 Martin Ling <martin-libserialport@earth.li>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
* We can't include DDK headers in serialport.c because they conflict with
* user space headers. So this file exists to isolate the definitions which
* use the kernel declarations.
*/
#include <ddk/wdm.h>
const size_t WRITEFILE_MAX_SIZE = ((65535 - sizeof(MDL)) / sizeof(ULONG_PTR)) * PAGE_SIZE;

25
windows_ddk.h Normal file
View File

@ -0,0 +1,25 @@
/*
* This file is part of the libserialport project.
*
* Copyright (C) 2019 Martin Ling <martin-libserialport@earth.li>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LIBSERIALPORT_WINDOWS_DDK_H
#define LIBSERIALPORT_WINDOWS_DDK_H
SP_PRIV extern const size_t WRITEFILE_MAX_SIZE;
#endif