From f3960c32f18f97a7bf444c145089536135f7004e Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 9 Sep 2019 21:05:07 +0200 Subject: [PATCH] kernel32: Move ioctl functions to kernelbase. Signed-off-by: Alexandre Julliard --- dlls/kernel32/comm.c | 702 -------------------------------- dlls/kernel32/kernel32.spec | 36 +- dlls/kernelbase/file.c | 416 +++++++++++++++++++ dlls/kernelbase/kernelbase.spec | 38 +- 4 files changed, 453 insertions(+), 739 deletions(-) diff --git a/dlls/kernel32/comm.c b/dlls/kernel32/comm.c index b5de654cc09..48939c02875 100644 --- a/dlls/kernel32/comm.c +++ b/dlls/kernel32/comm.c @@ -530,648 +530,6 @@ BOOL WINAPI BuildCommDCBW( return BuildCommDCBAndTimeoutsW(devid,lpdcb,NULL); } -/***************************************************************************** - * SetCommBreak (KERNEL32.@) - * - * Halts the transmission of characters to a communications device. - * - * PARAMS - * handle [in] The communications device to suspend - * - * RETURNS - * - * True on success, and false if the communications device could not be found, - * the control is not supported. - * - * BUGS - * - * Only TIOCSBRK and TIOCCBRK are supported. - */ -BOOL WINAPI SetCommBreak(HANDLE handle) -{ - DWORD dwBytesReturned; - return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_ON, NULL, 0, NULL, 0, &dwBytesReturned, NULL); -} - -/***************************************************************************** - * ClearCommBreak (KERNEL32.@) - * - * Resumes character transmission from a communication device. - * - * PARAMS - * - * handle [in] The halted communication device whose character transmission is to be resumed - * - * RETURNS - * - * True on success and false if the communications device could not be found. - * - * BUGS - * - * Only TIOCSBRK and TIOCCBRK are supported. - */ -BOOL WINAPI ClearCommBreak(HANDLE handle) -{ - DWORD dwBytesReturned; - return DeviceIoControl(handle, IOCTL_SERIAL_SET_BREAK_OFF, NULL, 0, NULL, 0, &dwBytesReturned, NULL); -} - -/***************************************************************************** - * EscapeCommFunction (KERNEL32.@) - * - * Directs a communication device to perform an extended function. - * - * PARAMS - * - * handle [in] The communication device to perform the extended function - * nFunction [in] The extended function to be performed - * - * RETURNS - * - * True or requested data on successful completion of the command, - * false if the device is not present cannot execute the command - * or the command failed. - */ -BOOL WINAPI EscapeCommFunction(HANDLE handle, DWORD func) -{ - DWORD ioc; - DWORD dwBytesReturned; - - switch (func) - { - case CLRDTR: ioc = IOCTL_SERIAL_CLR_DTR; break; - case CLRRTS: ioc = IOCTL_SERIAL_CLR_RTS; break; - case SETDTR: ioc = IOCTL_SERIAL_SET_DTR; break; - case SETRTS: ioc = IOCTL_SERIAL_SET_RTS; break; - case SETXOFF: ioc = IOCTL_SERIAL_SET_XOFF; break; - case SETXON: ioc = IOCTL_SERIAL_SET_XON; break; - case SETBREAK: ioc = IOCTL_SERIAL_SET_BREAK_ON; break; - case CLRBREAK: ioc = IOCTL_SERIAL_SET_BREAK_OFF; break; - case RESETDEV: ioc = IOCTL_SERIAL_RESET_DEVICE; break; - default: - ERR("Unknown function code (%u)\n", func); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - return DeviceIoControl(handle, ioc, NULL, 0, NULL, 0, &dwBytesReturned, NULL); -} - -/******************************************************************** - * PurgeComm (KERNEL32.@) - * - * Terminates pending operations and/or discards buffers on a - * communication resource. - * - * PARAMS - * - * handle [in] The communication resource to be purged - * flags [in] Flags for clear pending/buffer on input/output - * - * RETURNS - * - * True on success and false if the communications handle is bad. - */ -BOOL WINAPI PurgeComm(HANDLE handle, DWORD flags) -{ - DWORD dwBytesReturned; - return DeviceIoControl(handle, IOCTL_SERIAL_PURGE, &flags, sizeof(flags), - NULL, 0, &dwBytesReturned, NULL); -} - -/***************************************************************************** - * ClearCommError (KERNEL32.@) - * - * Enables further I/O operations on a communications resource after - * supplying error and current status information. - * - * PARAMS - * - * handle [in] The communication resource with the error - * errors [out] Flags indicating error the resource experienced - * lpStat [out] The status of the communication resource - * RETURNS - * - * True on success, false if the communication resource handle is bad. - */ -BOOL WINAPI ClearCommError(HANDLE handle, LPDWORD errors, LPCOMSTAT lpStat) -{ - SERIAL_STATUS ss; - DWORD dwBytesReturned; - - if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0, - &ss, sizeof(ss), &dwBytesReturned, NULL)) - return FALSE; - - TRACE("=> status %#x,%#x, in %u, out %u, eof %d, wait %d\n", ss.Errors, ss.HoldReasons, - ss.AmountInInQueue, ss.AmountInOutQueue, ss.EofReceived, ss.WaitForImmediate); - - if (errors) - { - *errors = 0; - if (ss.Errors & SERIAL_ERROR_BREAK) *errors |= CE_BREAK; - if (ss.Errors & SERIAL_ERROR_FRAMING) *errors |= CE_FRAME; - if (ss.Errors & SERIAL_ERROR_OVERRUN) *errors |= CE_OVERRUN; - if (ss.Errors & SERIAL_ERROR_QUEUEOVERRUN) *errors |= CE_RXOVER; - if (ss.Errors & SERIAL_ERROR_PARITY) *errors |= CE_RXPARITY; - } - - if (lpStat) - { - memset(lpStat, 0, sizeof(*lpStat)); - - if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_CTS) lpStat->fCtsHold = TRUE; - if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DSR) lpStat->fDsrHold = TRUE; - if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_DCD) lpStat->fRlsdHold = TRUE; - if (ss.HoldReasons & SERIAL_TX_WAITING_FOR_XON) lpStat->fXoffHold = TRUE; - if (ss.HoldReasons & SERIAL_TX_WAITING_XOFF_SENT) lpStat->fXoffSent = TRUE; - if (ss.EofReceived) lpStat->fEof = TRUE; - if (ss.WaitForImmediate) lpStat->fTxim = TRUE; - lpStat->cbInQue = ss.AmountInInQueue; - lpStat->cbOutQue = ss.AmountInOutQueue; - } - return TRUE; -} - -/***************************************************************************** - * SetupComm (KERNEL32.@) - * - * Called after CreateFile to hint to the communication resource to use - * specified sizes for input and output buffers rather than the default values. - * - * PARAMS - * handle [in] The just created communication resource handle - * insize [in] The suggested size of the communication resources input buffer in bytes - * outsize [in] The suggested size of the communication resources output buffer in bytes - * - * RETURNS - * - * True if successful, false if the communications resource handle is bad. - * - * BUGS - * - * Stub. - */ -BOOL WINAPI SetupComm(HANDLE handle, DWORD insize, DWORD outsize) -{ - SERIAL_QUEUE_SIZE sqs; - DWORD dwBytesReturned; - - sqs.InSize = insize; - sqs.OutSize = outsize; - return DeviceIoControl(handle, IOCTL_SERIAL_SET_QUEUE_SIZE, - &sqs, sizeof(sqs), NULL, 0, &dwBytesReturned, NULL); -} - -/***************************************************************************** - * GetCommMask (KERNEL32.@) - * - * Obtain the events associated with a communication device that will cause - * a call WaitCommEvent to return. - * - * PARAMS - * - * handle [in] The communications device - * evtmask [out] The events which cause WaitCommEvent to return - * - * RETURNS - * - * True on success, fail on bad device handle etc. - */ -BOOL WINAPI GetCommMask(HANDLE handle, LPDWORD evtmask) -{ - DWORD dwBytesReturned; - TRACE("handle %p, mask %p\n", handle, evtmask); - return DeviceIoControl(handle, IOCTL_SERIAL_GET_WAIT_MASK, - NULL, 0, evtmask, sizeof(*evtmask), &dwBytesReturned, NULL); -} - -/***************************************************************************** - * SetCommMask (KERNEL32.@) - * - * There be some things we need to hear about yon there communications device. - * (Set which events associated with a communication device should cause - * a call WaitCommEvent to return.) - * - * PARAMS - * - * handle [in] The communications device - * evtmask [in] The events that are to be monitored - * - * RETURNS - * - * True on success, false on bad handle etc. - */ -BOOL WINAPI SetCommMask(HANDLE handle, DWORD evtmask) -{ - DWORD dwBytesReturned; - TRACE("handle %p, mask %x\n", handle, evtmask); - return DeviceIoControl(handle, IOCTL_SERIAL_SET_WAIT_MASK, - &evtmask, sizeof(evtmask), NULL, 0, &dwBytesReturned, NULL); -} - -static void dump_dcb(const DCB* lpdcb) -{ - TRACE("bytesize=%d baudrate=%d fParity=%d Parity=%d stopbits=%d\n", - lpdcb->ByteSize, lpdcb->BaudRate, lpdcb->fParity, lpdcb->Parity, - (lpdcb->StopBits == ONESTOPBIT) ? 1 : - (lpdcb->StopBits == TWOSTOPBITS) ? 2 : 0); - TRACE("%sIXON %sIXOFF\n", (lpdcb->fOutX) ? "" : "~", (lpdcb->fInX) ? "" : "~"); - TRACE("fOutxCtsFlow=%d fRtsControl=%d\n", lpdcb->fOutxCtsFlow, lpdcb->fRtsControl); - TRACE("fOutxDsrFlow=%d fDtrControl=%d\n", lpdcb->fOutxDsrFlow, lpdcb->fDtrControl); - if (lpdcb->fOutxCtsFlow || lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE) - TRACE("CRTSCTS\n"); - else - TRACE("~CRTSCTS\n"); -} - -/***************************************************************************** - * SetCommState (KERNEL32.@) - * - * Re-initializes all hardware and control settings of a communications device, - * with values from a device control block without affecting the input and output - * queues. - * - * PARAMS - * - * handle [in] The communications device - * lpdcb [out] The device control block - * - * RETURNS - * - * True on success, false on failure, e.g., if the XonChar is equal to the XoffChar. - */ -BOOL WINAPI SetCommState( HANDLE handle, LPDCB lpdcb) -{ - SERIAL_BAUD_RATE sbr; - SERIAL_LINE_CONTROL slc; - SERIAL_HANDFLOW shf; - SERIAL_CHARS sc; - DWORD dwBytesReturned; - - TRACE("handle %p, ptr %p\n", handle, lpdcb); - - if (lpdcb == NULL) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - dump_dcb(lpdcb); - - sbr.BaudRate = lpdcb->BaudRate; - - slc.StopBits = lpdcb->StopBits; - slc.Parity = lpdcb->Parity; - slc.WordLength = lpdcb->ByteSize; - - shf.ControlHandShake = 0; - shf.FlowReplace = 0; - if (lpdcb->fOutxCtsFlow) shf.ControlHandShake |= SERIAL_CTS_HANDSHAKE; - if (lpdcb->fOutxDsrFlow) shf.ControlHandShake |= SERIAL_DSR_HANDSHAKE; - switch (lpdcb->fDtrControl) - { - case DTR_CONTROL_DISABLE: break; - case DTR_CONTROL_ENABLE: shf.ControlHandShake |= SERIAL_DTR_CONTROL; break; - case DTR_CONTROL_HANDSHAKE: shf.ControlHandShake |= SERIAL_DTR_HANDSHAKE;break; - default: - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - switch (lpdcb->fRtsControl) - { - case RTS_CONTROL_DISABLE: break; - case RTS_CONTROL_ENABLE: shf.FlowReplace |= SERIAL_RTS_CONTROL; break; - case RTS_CONTROL_HANDSHAKE: shf.FlowReplace |= SERIAL_RTS_HANDSHAKE; break; - case RTS_CONTROL_TOGGLE: shf.FlowReplace |= SERIAL_RTS_CONTROL | - SERIAL_RTS_HANDSHAKE; break; - default: - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (lpdcb->fDsrSensitivity) shf.ControlHandShake |= SERIAL_DSR_SENSITIVITY; - if (lpdcb->fAbortOnError) shf.ControlHandShake |= SERIAL_ERROR_ABORT; - - if (lpdcb->fErrorChar) shf.FlowReplace |= SERIAL_ERROR_CHAR; - if (lpdcb->fNull) shf.FlowReplace |= SERIAL_NULL_STRIPPING; - if (lpdcb->fTXContinueOnXoff) shf.FlowReplace |= SERIAL_XOFF_CONTINUE; - if (lpdcb->fOutX) shf.FlowReplace |= SERIAL_AUTO_TRANSMIT; - if (lpdcb->fInX) shf.FlowReplace |= SERIAL_AUTO_RECEIVE; - - shf.XonLimit = lpdcb->XonLim; - shf.XoffLimit = lpdcb->XoffLim; - - sc.EofChar = lpdcb->EofChar; - sc.ErrorChar = lpdcb->ErrorChar; - sc.BreakChar = 0; - sc.EventChar = lpdcb->EvtChar; - sc.XonChar = lpdcb->XonChar; - sc.XoffChar = lpdcb->XoffChar; - - /* note: change DTR/RTS lines after setting the comm attributes, - * so flow control does not interfere. - */ - return (DeviceIoControl(handle, IOCTL_SERIAL_SET_BAUD_RATE, - &sbr, sizeof(sbr), NULL, 0, &dwBytesReturned, NULL) && - DeviceIoControl(handle, IOCTL_SERIAL_SET_LINE_CONTROL, - &slc, sizeof(slc), NULL, 0, &dwBytesReturned, NULL) && - DeviceIoControl(handle, IOCTL_SERIAL_SET_HANDFLOW, - &shf, sizeof(shf), NULL, 0, &dwBytesReturned, NULL) && - DeviceIoControl(handle, IOCTL_SERIAL_SET_CHARS, - &sc, sizeof(sc), NULL, 0, &dwBytesReturned, NULL)); -} - - -/***************************************************************************** - * GetCommState (KERNEL32.@) - * - * Fills in a device control block with information from a communications device. - * - * PARAMS - * handle [in] The communications device - * lpdcb [out] The device control block - * - * RETURNS - * - * True on success, false if the communication device handle is bad etc - * - * BUGS - * - * XonChar and XoffChar are not set. - */ -BOOL WINAPI GetCommState(HANDLE handle, LPDCB lpdcb) -{ - SERIAL_BAUD_RATE sbr; - SERIAL_LINE_CONTROL slc; - SERIAL_HANDFLOW shf; - SERIAL_CHARS sc; - DWORD dwBytesReturned; - - TRACE("handle %p, ptr %p\n", handle, lpdcb); - - if (!lpdcb) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_BAUD_RATE, - NULL, 0, &sbr, sizeof(sbr), &dwBytesReturned, NULL) || - !DeviceIoControl(handle, IOCTL_SERIAL_GET_LINE_CONTROL, - NULL, 0, &slc, sizeof(slc), &dwBytesReturned, NULL) || - !DeviceIoControl(handle, IOCTL_SERIAL_GET_HANDFLOW, - NULL, 0, &shf, sizeof(shf), &dwBytesReturned, NULL) || - !DeviceIoControl(handle, IOCTL_SERIAL_GET_CHARS, - NULL, 0, &sc, sizeof(sc), &dwBytesReturned, NULL)) - return FALSE; - - memset(lpdcb, 0, sizeof(*lpdcb)); - lpdcb->DCBlength = sizeof(*lpdcb); - - /* yes, they seem no never be (re)set on NT */ - lpdcb->fBinary = 1; - lpdcb->fParity = 0; - - lpdcb->BaudRate = sbr.BaudRate; - - lpdcb->StopBits = slc.StopBits; - lpdcb->Parity = slc.Parity; - lpdcb->ByteSize = slc.WordLength; - - if (shf.ControlHandShake & SERIAL_CTS_HANDSHAKE) lpdcb->fOutxCtsFlow = 1; - if (shf.ControlHandShake & SERIAL_DSR_HANDSHAKE) lpdcb->fOutxDsrFlow = 1; - switch (shf.ControlHandShake & (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE)) - { - case 0: lpdcb->fDtrControl = DTR_CONTROL_DISABLE; break; - case SERIAL_DTR_CONTROL: lpdcb->fDtrControl = DTR_CONTROL_ENABLE; break; - case SERIAL_DTR_HANDSHAKE: lpdcb->fDtrControl = DTR_CONTROL_HANDSHAKE; break; - } - switch (shf.FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE)) - { - case 0: lpdcb->fRtsControl = RTS_CONTROL_DISABLE; break; - case SERIAL_RTS_CONTROL: lpdcb->fRtsControl = RTS_CONTROL_ENABLE; break; - case SERIAL_RTS_HANDSHAKE: lpdcb->fRtsControl = RTS_CONTROL_HANDSHAKE; break; - case SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE: - lpdcb->fRtsControl = RTS_CONTROL_TOGGLE; break; - } - if (shf.ControlHandShake & SERIAL_DSR_SENSITIVITY) lpdcb->fDsrSensitivity = 1; - if (shf.ControlHandShake & SERIAL_ERROR_ABORT) lpdcb->fAbortOnError = 1; - if (shf.FlowReplace & SERIAL_ERROR_CHAR) lpdcb->fErrorChar = 1; - if (shf.FlowReplace & SERIAL_NULL_STRIPPING) lpdcb->fNull = 1; - if (shf.FlowReplace & SERIAL_XOFF_CONTINUE) lpdcb->fTXContinueOnXoff = 1; - lpdcb->XonLim = shf.XonLimit; - lpdcb->XoffLim = shf.XoffLimit; - - if (shf.FlowReplace & SERIAL_AUTO_TRANSMIT) lpdcb->fOutX = 1; - if (shf.FlowReplace & SERIAL_AUTO_RECEIVE) lpdcb->fInX = 1; - - lpdcb->EofChar = sc.EofChar; - lpdcb->ErrorChar = sc.ErrorChar; - lpdcb->EvtChar = sc.EventChar; - lpdcb->XonChar = sc.XonChar; - lpdcb->XoffChar = sc.XoffChar; - - TRACE("OK\n"); - dump_dcb(lpdcb); - - return TRUE; -} - -/***************************************************************************** - * TransmitCommChar (KERNEL32.@) - * - * Transmits a single character in front of any pending characters in the - * output buffer. Usually used to send an interrupt character to a host. - * - * PARAMS - * hComm [in] The communication device in need of a command character - * chTransmit [in] The character to transmit - * - * RETURNS - * - * True if the call succeeded, false if the previous command character to the - * same device has not been sent yet the handle is bad etc. - * - */ -BOOL WINAPI TransmitCommChar(HANDLE hComm, CHAR chTransmit) -{ - DWORD dwBytesReturned; - return DeviceIoControl(hComm, IOCTL_SERIAL_IMMEDIATE_CHAR, - &chTransmit, sizeof(chTransmit), NULL, 0, &dwBytesReturned, NULL); -} - - -/***************************************************************************** - * GetCommTimeouts (KERNEL32.@) - * - * Obtains the request timeout values for the communications device. - * - * PARAMS - * hComm [in] The communications device - * lptimeouts [out] The struct of request timeouts - * - * RETURNS - * - * True on success, false if communications device handle is bad - * or the target structure is null. - */ -BOOL WINAPI GetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts) -{ - SERIAL_TIMEOUTS st; - DWORD dwBytesReturned; - - TRACE("(%p, %p)\n", hComm, lptimeouts); - if (!lptimeouts) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - if (!DeviceIoControl(hComm, IOCTL_SERIAL_GET_TIMEOUTS, - NULL, 0, &st, sizeof(st), &dwBytesReturned, NULL)) - return FALSE; - lptimeouts->ReadIntervalTimeout = st.ReadIntervalTimeout; - lptimeouts->ReadTotalTimeoutMultiplier = st.ReadTotalTimeoutMultiplier; - lptimeouts->ReadTotalTimeoutConstant = st.ReadTotalTimeoutConstant; - lptimeouts->WriteTotalTimeoutMultiplier = st.WriteTotalTimeoutMultiplier; - lptimeouts->WriteTotalTimeoutConstant = st.WriteTotalTimeoutConstant; - return TRUE; -} - -/***************************************************************************** - * SetCommTimeouts (KERNEL32.@) - * - * Sets the timeouts used when reading and writing data to/from COMM ports. - * - * PARAMS - * hComm [in] handle of COMM device - * lptimeouts [in] pointer to COMMTIMEOUTS structure - * - * ReadIntervalTimeout - * - converted and passes to linux kernel as c_cc[VTIME] - * ReadTotalTimeoutMultiplier, ReadTotalTimeoutConstant - * - used in ReadFile to calculate GetOverlappedResult's timeout - * WriteTotalTimeoutMultiplier, WriteTotalTimeoutConstant - * - used in WriteFile to calculate GetOverlappedResult's timeout - * - * RETURNS - * - * True if the timeouts were set, false otherwise. - */ -BOOL WINAPI SetCommTimeouts(HANDLE hComm, LPCOMMTIMEOUTS lptimeouts) -{ - SERIAL_TIMEOUTS st; - DWORD dwBytesReturned; - - TRACE("(%p, %p)\n", hComm, lptimeouts); - - if (lptimeouts == NULL) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - st.ReadIntervalTimeout = lptimeouts->ReadIntervalTimeout; - st.ReadTotalTimeoutMultiplier = lptimeouts->ReadTotalTimeoutMultiplier; - st.ReadTotalTimeoutConstant = lptimeouts->ReadTotalTimeoutConstant; - st.WriteTotalTimeoutMultiplier = lptimeouts->WriteTotalTimeoutMultiplier; - st.WriteTotalTimeoutConstant = lptimeouts->WriteTotalTimeoutConstant; - - return DeviceIoControl(hComm, IOCTL_SERIAL_SET_TIMEOUTS, - &st, sizeof(st), NULL, 0, &dwBytesReturned, NULL); -} - -/*********************************************************************** - * GetCommModemStatus (KERNEL32.@) - * - * Obtains the four control register bits if supported by the hardware. - * - * PARAMS - * - * hFile [in] The communications device - * lpModemStat [out] The control register bits - * - * RETURNS - * - * True if the communications handle was good and for hardware that - * control register access, false otherwise. - */ -BOOL WINAPI GetCommModemStatus(HANDLE hFile, LPDWORD lpModemStat) -{ - DWORD dwBytesReturned; - return DeviceIoControl(hFile, IOCTL_SERIAL_GET_MODEMSTATUS, - NULL, 0, lpModemStat, sizeof(DWORD), &dwBytesReturned, NULL); -} - -/*********************************************************************** - * WaitCommEvent (KERNEL32.@) - * - * Wait until something interesting happens on a COMM port. - * Interesting things (events) are set by calling SetCommMask before - * this function is called. - * - * RETURNS - * TRUE if successful - * FALSE if failure - * - * The set of detected events will be written to *lpdwEventMask - * ERROR_IO_PENDING will be returned the overlapped structure was passed - * - * BUGS: - * Only supports EV_RXCHAR and EV_TXEMPTY - */ -BOOL WINAPI WaitCommEvent( - HANDLE hFile, /* [in] handle of comm port to wait for */ - LPDWORD lpdwEvents, /* [out] event(s) that were detected */ - LPOVERLAPPED lpOverlapped) /* [in/out] for Asynchronous waiting */ -{ - return DeviceIoControl(hFile, IOCTL_SERIAL_WAIT_ON_MASK, NULL, 0, - lpdwEvents, sizeof(DWORD), NULL, lpOverlapped); -} - -/*********************************************************************** - * GetCommProperties (KERNEL32.@) - * - * This function fills in a structure with the capabilities of the - * communications port driver. - * - * RETURNS - * - * TRUE on success, FALSE on failure - * If successful, the lpCommProp structure be filled in with - * properties of the comm port. - */ -BOOL WINAPI GetCommProperties( - HANDLE hFile, /* [in] handle of the comm port */ - LPCOMMPROP lpCommProp) /* [out] pointer to struct to be filled */ -{ - TRACE("(%p %p)\n",hFile,lpCommProp); - if(!lpCommProp) - return FALSE; - - /* - * These values should be valid for LINUX's serial driver - * FIXME: Perhaps they deserve an #ifdef LINUX - */ - memset(lpCommProp,0,sizeof(COMMPROP)); - lpCommProp->wPacketLength = 1; - lpCommProp->wPacketVersion = 1; - lpCommProp->dwServiceMask = SP_SERIALCOMM; - lpCommProp->dwMaxTxQueue = 4096; - lpCommProp->dwMaxRxQueue = 4096; - lpCommProp->dwMaxBaud = BAUD_115200; - lpCommProp->dwProvSubType = PST_RS232; - lpCommProp->dwProvCapabilities = PCF_DTRDSR | PCF_PARITY_CHECK | PCF_RTSCTS | PCF_TOTALTIMEOUTS | PCF_INTTIMEOUTS; - lpCommProp->dwSettableParams = SP_BAUD | SP_DATABITS | SP_HANDSHAKING | - SP_PARITY | SP_PARITY_CHECK | SP_STOPBITS ; - lpCommProp->dwSettableBaud = BAUD_075 | BAUD_110 | BAUD_134_5 | BAUD_150 | - BAUD_300 | BAUD_600 | BAUD_1200 | BAUD_1800 | BAUD_2400 | BAUD_4800 | - BAUD_9600 | BAUD_19200 | BAUD_38400 | BAUD_57600 | BAUD_115200 ; - lpCommProp->wSettableData = DATABITS_5 | DATABITS_6 | DATABITS_7 | DATABITS_8 ; - lpCommProp->wSettableStopParity = STOPBITS_10 | STOPBITS_15 | STOPBITS_20 | - PARITY_NONE | PARITY_ODD |PARITY_EVEN | PARITY_MARK | PARITY_SPACE; - lpCommProp->dwCurrentTxQueue = lpCommProp->dwMaxTxQueue; - lpCommProp->dwCurrentRxQueue = lpCommProp->dwMaxRxQueue; - - return TRUE; -} - /*********************************************************************** * FIXME: * The functionality of CommConfigDialogA, GetDefaultCommConfig and @@ -1258,66 +616,6 @@ BOOL WINAPI CommConfigDialogW( return (res == ERROR_SUCCESS); } -/*********************************************************************** - * GetCommConfig (KERNEL32.@) - * - * Fill in the COMMCONFIG structure for the comm port hFile - * - * RETURNS - * - * TRUE on success, FALSE on failure - * If successful, lpCommConfig contains the comm port configuration. - * - * BUGS - * - */ -BOOL WINAPI GetCommConfig( - HANDLE hFile, /* [in] The communications device. */ - LPCOMMCONFIG lpCommConfig, /* [out] The communications configuration of the device (if it fits). */ - LPDWORD lpdwSize) /* [in/out] Initially the size of the configuration buffer/structure, - afterwards the number of bytes copied to the buffer or - the needed size of the buffer. */ -{ - BOOL r; - - TRACE("(%p, %p, %p) *lpdwSize: %u\n", hFile, lpCommConfig, lpdwSize, lpdwSize ? *lpdwSize : 0 ); - - if(lpCommConfig == NULL) - return FALSE; - r = *lpdwSize < sizeof(COMMCONFIG); /* TRUE if not enough space */ - *lpdwSize = sizeof(COMMCONFIG); - if(r) - return FALSE; - - lpCommConfig->dwSize = sizeof(COMMCONFIG); - lpCommConfig->wVersion = 1; - lpCommConfig->wReserved = 0; - r = GetCommState(hFile,&lpCommConfig->dcb); - lpCommConfig->dwProviderSubType = PST_RS232; - lpCommConfig->dwProviderOffset = 0; - lpCommConfig->dwProviderSize = 0; - - return r; -} - -/*********************************************************************** - * SetCommConfig (KERNEL32.@) - * - * Sets the configuration of the communications device. - * - * RETURNS - * - * True on success, false if the handle was bad is not a communications device. - */ -BOOL WINAPI SetCommConfig( - HANDLE hFile, /* [in] The communications device. */ - LPCOMMCONFIG lpCommConfig, /* [in] The desired configuration. */ - DWORD dwSize) /* [in] size of the lpCommConfig struct */ -{ - TRACE("(%p, %p, %u)\n", hFile, lpCommConfig, dwSize); - return SetCommState(hFile,&lpCommConfig->dcb); -} - /*********************************************************************** * SetDefaultCommConfigW (KERNEL32.@) * diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index 0bb80ae57b8..7fb34e2918c 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -220,8 +220,8 @@ @ stdcall CheckNameLegalDOS8Dot3A(str ptr long ptr ptr) @ stdcall CheckNameLegalDOS8Dot3W(wstr ptr long ptr ptr) @ stdcall -import CheckRemoteDebuggerPresent(long ptr) -@ stdcall ClearCommBreak(long) -@ stdcall ClearCommError(long ptr ptr) +@ stdcall -import ClearCommBreak(long) +@ stdcall -import ClearCommError(long ptr ptr) @ stdcall CloseConsoleHandle(long) @ stdcall CloseHandle(long) # @ stub ClosePrivateNamespace @@ -434,7 +434,7 @@ # @ stub EnumerateLocalComputerNamesW @ stdcall -arch=x86_64 EnterUmsSchedulingMode(ptr) @ stdcall EraseTape(ptr long long) -@ stdcall EscapeCommFunction(long long) +@ stdcall -import EscapeCommFunction(long long) @ stdcall -arch=x86_64 ExecuteUmsThread(ptr) @ stdcall ExitProcess(long) @ stdcall ExitThread(long) ntdll.RtlExitUserThread @@ -562,12 +562,12 @@ # @ stub GetCalendarSupportedDateRange # @ stub GetCalendarWeekNumber # @ stub GetComPlusPackageInstallStatus -@ stdcall GetCommConfig(long ptr ptr) -@ stdcall GetCommMask(long ptr) -@ stdcall GetCommModemStatus(long ptr) -@ stdcall GetCommProperties(long ptr) -@ stdcall GetCommState(long ptr) -@ stdcall GetCommTimeouts(long ptr) +@ stdcall -import GetCommConfig(long ptr ptr) +@ stdcall -import GetCommMask(long ptr) +@ stdcall -import GetCommModemStatus(long ptr) +@ stdcall -import GetCommProperties(long ptr) +@ stdcall -import GetCommState(long ptr) +@ stdcall -import GetCommTimeouts(long ptr) @ stdcall -import GetCommandLineA() @ stdcall -import GetCommandLineW() @ stdcall -import GetCompressedFileSizeA(long ptr) @@ -1154,7 +1154,7 @@ @ stdcall Process32NextW (ptr ptr) @ stdcall ProcessIdToSessionId(long ptr) @ stdcall -import PulseEvent(long) -@ stdcall PurgeComm(long long) +@ stdcall -import PurgeComm(long long) @ stdcall -i386 -private -norelay QT_Thunk() krnl386.exe16.QT_Thunk @ stdcall -import QueryActCtxSettingsW(long ptr wstr wstr ptr long ptr) @ stdcall -import QueryActCtxW(long ptr ptr long ptr long ptr) @@ -1331,11 +1331,11 @@ @ stdcall SetCalendarInfoW(long long long wstr) # @ stub SetClientTimeZoneInformation # @ stub SetComPlusPackageInstallStatus -@ stdcall SetCommBreak(long) -@ stdcall SetCommConfig(long ptr long) -@ stdcall SetCommMask(long long) -@ stdcall SetCommState(long ptr) -@ stdcall SetCommTimeouts(long ptr) +@ stdcall -import SetCommBreak(long) +@ stdcall -import SetCommConfig(long ptr long) +@ stdcall -import SetCommMask(long long) +@ stdcall -import SetCommState(long ptr) +@ stdcall -import SetCommTimeouts(long ptr) @ stdcall SetComputerNameA(str) @ stdcall SetComputerNameExA(long str) @ stdcall SetComputerNameExW(long wstr) @@ -1477,7 +1477,7 @@ @ stdcall -import SetWaitableTimer(long ptr long ptr ptr long) @ stdcall -import SetWaitableTimerEx(long ptr long ptr ptr ptr long) # @ stub SetXStateFeaturesMask -@ stdcall SetupComm(long long long) +@ stdcall -import SetupComm(long long long) @ stub ShowConsoleCursor @ stdcall -import SignalObjectAndWait(long long long long) @ stdcall -import SizeofResource(long long) @@ -1510,7 +1510,7 @@ @ stdcall -import TlsSetValue(long ptr) @ stdcall Toolhelp32ReadProcessMemory(long ptr ptr long ptr) @ stdcall -import TransactNamedPipe(long ptr long ptr long ptr ptr) -@ stdcall TransmitCommChar(long long) +@ stdcall -import TransmitCommChar(long long) @ stub TrimVirtualBuffer @ stdcall TryAcquireSRWLockExclusive(ptr) ntdll.RtlTryAcquireSRWLockExclusive @ stdcall TryAcquireSRWLockShared(ptr) ntdll.RtlTryAcquireSRWLockShared @@ -1570,7 +1570,7 @@ @ stdcall -import VirtualQueryEx(long ptr ptr long) @ stdcall -import VirtualUnlock(ptr long) @ stdcall WTSGetActiveConsoleSessionId() -@ stdcall WaitCommEvent(long ptr ptr) +@ stdcall -import WaitCommEvent(long ptr ptr) @ stdcall -import WaitForDebugEvent(ptr long) @ stdcall -import WaitForMultipleObjects(long ptr long long) @ stdcall -import WaitForMultipleObjectsEx(long ptr long long long) diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 2ae0f81f3f0..8705b8856bc 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -35,6 +35,7 @@ #include "wincon.h" #include "fileapi.h" #include "ddk/ntddk.h" +#include "ddk/ntddser.h" #include "kernelbase.h" #include "wine/exception.h" @@ -1766,3 +1767,418 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteFileGather( HANDLE file, FILE_SEGMENT_ELEMENT return set_ntstatus( NtWriteFileGather( file, overlapped->hEvent, NULL, cvalue, io, segments, count, &offset, NULL )); } + + +/*********************************************************************** + * I/O controls + ***********************************************************************/ + + +static void dump_dcb( const DCB *dcb ) +{ + TRACE( "size=%d rate=%d fParity=%d Parity=%d stopbits=%d %sIXON %sIXOFF CTS=%d RTS=%d DSR=%d DTR=%d %sCRTSCTS\n", + dcb->ByteSize, dcb->BaudRate, dcb->fParity, dcb->Parity, + (dcb->StopBits == ONESTOPBIT) ? 1 : (dcb->StopBits == TWOSTOPBITS) ? 2 : 0, + dcb->fOutX ? "" : "~", dcb->fInX ? "" : "~", + dcb->fOutxCtsFlow, dcb->fRtsControl, dcb->fOutxDsrFlow, dcb->fDtrControl, + (dcb->fOutxCtsFlow || dcb->fRtsControl == RTS_CONTROL_HANDSHAKE) ? "" : "~" ); +} + +/***************************************************************************** + * ClearCommBreak (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH ClearCommBreak( HANDLE handle ) +{ + return EscapeCommFunction( handle, CLRBREAK ); +} + + +/***************************************************************************** + * ClearCommError (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH ClearCommError( HANDLE handle, DWORD *errors, COMSTAT *stat ) +{ + SERIAL_STATUS ss; + + if (!DeviceIoControl( handle, IOCTL_SERIAL_GET_COMMSTATUS, NULL, 0, &ss, sizeof(ss), NULL, NULL )) + return FALSE; + + TRACE( "status %#x,%#x, in %u, out %u, eof %d, wait %d\n", ss.Errors, ss.HoldReasons, + ss.AmountInInQueue, ss.AmountInOutQueue, ss.EofReceived, ss.WaitForImmediate ); + + if (errors) + { + *errors = 0; + if (ss.Errors & SERIAL_ERROR_BREAK) *errors |= CE_BREAK; + if (ss.Errors & SERIAL_ERROR_FRAMING) *errors |= CE_FRAME; + if (ss.Errors & SERIAL_ERROR_OVERRUN) *errors |= CE_OVERRUN; + if (ss.Errors & SERIAL_ERROR_QUEUEOVERRUN) *errors |= CE_RXOVER; + if (ss.Errors & SERIAL_ERROR_PARITY) *errors |= CE_RXPARITY; + } + if (stat) + { + stat->fCtsHold = !!(ss.HoldReasons & SERIAL_TX_WAITING_FOR_CTS); + stat->fDsrHold = !!(ss.HoldReasons & SERIAL_TX_WAITING_FOR_DSR); + stat->fRlsdHold = !!(ss.HoldReasons & SERIAL_TX_WAITING_FOR_DCD); + stat->fXoffHold = !!(ss.HoldReasons & SERIAL_TX_WAITING_FOR_XON); + stat->fXoffSent = !!(ss.HoldReasons & SERIAL_TX_WAITING_XOFF_SENT); + stat->fEof = !!ss.EofReceived; + stat->fTxim = !!ss.WaitForImmediate; + stat->cbInQue = ss.AmountInInQueue; + stat->cbOutQue = ss.AmountInOutQueue; + } + return TRUE; +} + + +/**************************************************************************** + * DeviceIoControl (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH DeviceIoControl( HANDLE handle, DWORD code, void *in_buff, DWORD in_count, + void *out_buff, DWORD out_count, DWORD *returned, + OVERLAPPED *overlapped ) +{ + IO_STATUS_BLOCK iosb, *piosb = &iosb; + void *cvalue = NULL; + HANDLE event = 0; + NTSTATUS status; + + TRACE( "(%p,%x,%p,%d,%p,%d,%p,%p)\n", + handle, code, in_buff, in_count, out_buff, out_count, returned, overlapped ); + + if (overlapped) + { + piosb = (IO_STATUS_BLOCK *)overlapped; + if (!((ULONG_PTR)overlapped->hEvent & 1)) cvalue = overlapped; + event = overlapped->hEvent; + overlapped->Internal = STATUS_PENDING; + overlapped->InternalHigh = 0; + } + + if (HIWORD(code) == FILE_DEVICE_FILE_SYSTEM) + status = NtFsControlFile( handle, event, NULL, cvalue, piosb, code, + in_buff, in_count, out_buff, out_count ); + else + status = NtDeviceIoControlFile( handle, event, NULL, cvalue, piosb, code, + in_buff, in_count, out_buff, out_count ); + + if (returned) *returned = piosb->Information; + return set_ntstatus( status ); +} + + +/***************************************************************************** + * EscapeCommFunction (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH EscapeCommFunction( HANDLE handle, DWORD func ) +{ + static const DWORD ioctls[] = + { + 0, + IOCTL_SERIAL_SET_XOFF, /* SETXOFF */ + IOCTL_SERIAL_SET_XON, /* SETXON */ + IOCTL_SERIAL_SET_RTS, /* SETRTS */ + IOCTL_SERIAL_CLR_RTS, /* CLRRTS */ + IOCTL_SERIAL_SET_DTR, /* SETDTR */ + IOCTL_SERIAL_CLR_DTR, /* CLRDTR */ + IOCTL_SERIAL_RESET_DEVICE, /* RESETDEV */ + IOCTL_SERIAL_SET_BREAK_ON, /* SETBREAK */ + IOCTL_SERIAL_SET_BREAK_OFF /* CLRBREAK */ + }; + + if (func >= ARRAY_SIZE(ioctls) || !ioctls[func]) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + return DeviceIoControl( handle, ioctls[func], NULL, 0, NULL, 0, NULL, NULL ); +} + + +/*********************************************************************** + * GetCommConfig (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH GetCommConfig( HANDLE handle, COMMCONFIG *config, DWORD *size ) +{ + if (!config) return FALSE; + + TRACE( "(%p, %p, %p %u)\n", handle, config, size, *size ); + + if (*size < sizeof(COMMCONFIG)) + { + *size = sizeof(COMMCONFIG); + return FALSE; + } + *size = sizeof(COMMCONFIG); + config->dwSize = sizeof(COMMCONFIG); + config->wVersion = 1; + config->wReserved = 0; + config->dwProviderSubType = PST_RS232; + config->dwProviderOffset = 0; + config->dwProviderSize = 0; + return GetCommState( handle, &config->dcb ); +} + + +/***************************************************************************** + * GetCommMask (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH GetCommMask( HANDLE handle, DWORD *mask ) +{ + return DeviceIoControl( handle, IOCTL_SERIAL_GET_WAIT_MASK, NULL, 0, mask, sizeof(*mask), + NULL, NULL ); +} + + +/*********************************************************************** + * GetCommModemStatus (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH GetCommModemStatus( HANDLE handle, DWORD *status ) +{ + return DeviceIoControl( handle, IOCTL_SERIAL_GET_MODEMSTATUS, NULL, 0, status, sizeof(*status), + NULL, NULL ); +} + + +/*********************************************************************** + * GetCommProperties (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH GetCommProperties( HANDLE handle, COMMPROP *prop ) +{ + return DeviceIoControl( handle, IOCTL_SERIAL_GET_PROPERTIES, NULL, 0, prop, sizeof(*prop), NULL, NULL ); +} + + +/***************************************************************************** + * GetCommState (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH GetCommState( HANDLE handle, DCB *dcb ) +{ + SERIAL_BAUD_RATE sbr; + SERIAL_LINE_CONTROL slc; + SERIAL_HANDFLOW shf; + SERIAL_CHARS sc; + + if (!dcb) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (!DeviceIoControl(handle, IOCTL_SERIAL_GET_BAUD_RATE, NULL, 0, &sbr, sizeof(sbr), NULL, NULL) || + !DeviceIoControl(handle, IOCTL_SERIAL_GET_LINE_CONTROL, NULL, 0, &slc, sizeof(slc), NULL, NULL) || + !DeviceIoControl(handle, IOCTL_SERIAL_GET_HANDFLOW, NULL, 0, &shf, sizeof(shf), NULL, NULL) || + !DeviceIoControl(handle, IOCTL_SERIAL_GET_CHARS, NULL, 0, &sc, sizeof(sc), NULL, NULL)) + return FALSE; + + dcb->DCBlength = sizeof(*dcb); + dcb->BaudRate = sbr.BaudRate; + /* yes, they seem no never be (re)set on NT */ + dcb->fBinary = 1; + dcb->fParity = 0; + dcb->fOutxCtsFlow = !!(shf.ControlHandShake & SERIAL_CTS_HANDSHAKE); + dcb->fOutxDsrFlow = !!(shf.ControlHandShake & SERIAL_DSR_HANDSHAKE); + dcb->fDsrSensitivity = !!(shf.ControlHandShake & SERIAL_DSR_SENSITIVITY); + dcb->fTXContinueOnXoff = !!(shf.FlowReplace & SERIAL_XOFF_CONTINUE); + dcb->fOutX = !!(shf.FlowReplace & SERIAL_AUTO_TRANSMIT); + dcb->fInX = !!(shf.FlowReplace & SERIAL_AUTO_RECEIVE); + dcb->fErrorChar = !!(shf.FlowReplace & SERIAL_ERROR_CHAR); + dcb->fNull = !!(shf.FlowReplace & SERIAL_NULL_STRIPPING); + dcb->fAbortOnError = !!(shf.ControlHandShake & SERIAL_ERROR_ABORT); + dcb->XonLim = shf.XonLimit; + dcb->XoffLim = shf.XoffLimit; + dcb->ByteSize = slc.WordLength; + dcb->Parity = slc.Parity; + dcb->StopBits = slc.StopBits; + dcb->XonChar = sc.XonChar; + dcb->XoffChar = sc.XoffChar; + dcb->ErrorChar = sc.ErrorChar; + dcb->EofChar = sc.EofChar; + dcb->EvtChar = sc.EventChar; + + switch (shf.ControlHandShake & (SERIAL_DTR_CONTROL | SERIAL_DTR_HANDSHAKE)) + { + case SERIAL_DTR_CONTROL: dcb->fDtrControl = DTR_CONTROL_ENABLE; break; + case SERIAL_DTR_HANDSHAKE: dcb->fDtrControl = DTR_CONTROL_HANDSHAKE; break; + default: dcb->fDtrControl = DTR_CONTROL_DISABLE; break; + } + switch (shf.FlowReplace & (SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE)) + { + case SERIAL_RTS_CONTROL: dcb->fRtsControl = RTS_CONTROL_ENABLE; break; + case SERIAL_RTS_HANDSHAKE: dcb->fRtsControl = RTS_CONTROL_HANDSHAKE; break; + case SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE: + dcb->fRtsControl = RTS_CONTROL_TOGGLE; break; + default: dcb->fRtsControl = RTS_CONTROL_DISABLE; break; + } + dump_dcb( dcb ); + return TRUE; +} + + +/***************************************************************************** + * GetCommTimeouts (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH GetCommTimeouts( HANDLE handle, COMMTIMEOUTS *timeouts ) +{ + if (!timeouts) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + return DeviceIoControl( handle, IOCTL_SERIAL_GET_TIMEOUTS, NULL, 0, timeouts, sizeof(*timeouts), + NULL, NULL ); +} + +/******************************************************************** + * PurgeComm (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH PurgeComm(HANDLE handle, DWORD flags) +{ + return DeviceIoControl( handle, IOCTL_SERIAL_PURGE, &flags, sizeof(flags), + NULL, 0, NULL, NULL ); +} + + +/***************************************************************************** + * SetCommBreak (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetCommBreak( HANDLE handle ) +{ + return EscapeCommFunction( handle, SETBREAK ); +} + + +/*********************************************************************** + * SetCommConfig (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetCommConfig( HANDLE handle, COMMCONFIG *config, DWORD size ) +{ + TRACE( "(%p, %p, %u)\n", handle, config, size ); + return SetCommState( handle, &config->dcb ); +} + + +/***************************************************************************** + * SetCommMask (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetCommMask( HANDLE handle, DWORD mask ) +{ + return DeviceIoControl( handle, IOCTL_SERIAL_SET_WAIT_MASK, &mask, sizeof(mask), + NULL, 0, NULL, NULL ); +} + + +/***************************************************************************** + * SetCommState (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetCommState( HANDLE handle, DCB *dcb ) +{ + SERIAL_BAUD_RATE sbr; + SERIAL_LINE_CONTROL slc; + SERIAL_HANDFLOW shf; + SERIAL_CHARS sc; + + if (!dcb) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + dump_dcb( dcb ); + + sbr.BaudRate = dcb->BaudRate; + slc.StopBits = dcb->StopBits; + slc.Parity = dcb->Parity; + slc.WordLength = dcb->ByteSize; + shf.ControlHandShake = 0; + shf.FlowReplace = 0; + if (dcb->fOutxCtsFlow) shf.ControlHandShake |= SERIAL_CTS_HANDSHAKE; + if (dcb->fOutxDsrFlow) shf.ControlHandShake |= SERIAL_DSR_HANDSHAKE; + switch (dcb->fDtrControl) + { + case DTR_CONTROL_DISABLE: break; + case DTR_CONTROL_ENABLE: shf.ControlHandShake |= SERIAL_DTR_CONTROL; break; + case DTR_CONTROL_HANDSHAKE: shf.ControlHandShake |= SERIAL_DTR_HANDSHAKE; break; + default: + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + switch (dcb->fRtsControl) + { + case RTS_CONTROL_DISABLE: break; + case RTS_CONTROL_ENABLE: shf.FlowReplace |= SERIAL_RTS_CONTROL; break; + case RTS_CONTROL_HANDSHAKE: shf.FlowReplace |= SERIAL_RTS_HANDSHAKE; break; + case RTS_CONTROL_TOGGLE: shf.FlowReplace |= SERIAL_RTS_CONTROL | SERIAL_RTS_HANDSHAKE; break; + default: + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + if (dcb->fDsrSensitivity) shf.ControlHandShake |= SERIAL_DSR_SENSITIVITY; + if (dcb->fAbortOnError) shf.ControlHandShake |= SERIAL_ERROR_ABORT; + if (dcb->fErrorChar) shf.FlowReplace |= SERIAL_ERROR_CHAR; + if (dcb->fNull) shf.FlowReplace |= SERIAL_NULL_STRIPPING; + if (dcb->fTXContinueOnXoff) shf.FlowReplace |= SERIAL_XOFF_CONTINUE; + if (dcb->fOutX) shf.FlowReplace |= SERIAL_AUTO_TRANSMIT; + if (dcb->fInX) shf.FlowReplace |= SERIAL_AUTO_RECEIVE; + shf.XonLimit = dcb->XonLim; + shf.XoffLimit = dcb->XoffLim; + sc.EofChar = dcb->EofChar; + sc.ErrorChar = dcb->ErrorChar; + sc.BreakChar = 0; + sc.EventChar = dcb->EvtChar; + sc.XonChar = dcb->XonChar; + sc.XoffChar = dcb->XoffChar; + + /* note: change DTR/RTS lines after setting the comm attributes, + * so flow control does not interfere. + */ + return (DeviceIoControl( handle, IOCTL_SERIAL_SET_BAUD_RATE, &sbr, sizeof(sbr), NULL, 0, NULL, NULL ) && + DeviceIoControl( handle, IOCTL_SERIAL_SET_LINE_CONTROL, &slc, sizeof(slc), NULL, 0, NULL, NULL ) && + DeviceIoControl( handle, IOCTL_SERIAL_SET_HANDFLOW, &shf, sizeof(shf), NULL, 0, NULL, NULL ) && + DeviceIoControl( handle, IOCTL_SERIAL_SET_CHARS, &sc, sizeof(sc), NULL, 0, NULL, NULL )); +} + + +/***************************************************************************** + * SetCommTimeouts (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetCommTimeouts( HANDLE handle, COMMTIMEOUTS *timeouts ) +{ + if (!timeouts) + { + SetLastError( ERROR_INVALID_PARAMETER ); + return FALSE; + } + return DeviceIoControl( handle, IOCTL_SERIAL_SET_TIMEOUTS, timeouts, sizeof(*timeouts), + NULL, 0, NULL, NULL ); +} + + +/***************************************************************************** + * SetupComm (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH SetupComm( HANDLE handle, DWORD in_size, DWORD out_size ) +{ + SERIAL_QUEUE_SIZE sqs; + + sqs.InSize = in_size; + sqs.OutSize = out_size; + return DeviceIoControl( handle, IOCTL_SERIAL_SET_QUEUE_SIZE, &sqs, sizeof(sqs), NULL, 0, NULL, NULL ); +} + + +/***************************************************************************** + * TransmitCommChar (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH TransmitCommChar( HANDLE handle, CHAR ch ) +{ + return DeviceIoControl( handle, IOCTL_SERIAL_IMMEDIATE_CHAR, &ch, sizeof(ch), NULL, 0, NULL, NULL ); +} + + +/*********************************************************************** + * WaitCommEvent (kernelbase.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH WaitCommEvent( HANDLE handle, DWORD *events, OVERLAPPED *overlapped ) +{ + return DeviceIoControl( handle, IOCTL_SERIAL_WAIT_ON_MASK, NULL, 0, events, sizeof(*events), + NULL, overlapped ); +} diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 083a15348d5..f97f6ce945c 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -132,8 +132,8 @@ # @ stub CheckTokenMembershipEx @ stdcall ChrCmpIA(long long) @ stdcall ChrCmpIW(long long) -@ stdcall ClearCommBreak(long) kernel32.ClearCommBreak -@ stdcall ClearCommError(long ptr ptr) kernel32.ClearCommError +@ stdcall ClearCommBreak(long) +@ stdcall ClearCommError(long ptr ptr) # @ stub CloseGlobalizationUserSettingsKey @ stdcall CloseHandle(long) kernel32.CloseHandle # @ stub ClosePackageInfo @@ -261,7 +261,7 @@ @ stdcall DeleteTimerQueueTimer(long long long) @ stdcall DeleteVolumeMountPointW(wstr) kernel32.DeleteVolumeMountPointW @ stdcall DestroyPrivateObjectSecurity(ptr) -@ stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) kernel32.DeviceIoControl +@ stdcall DeviceIoControl(long long ptr long ptr long ptr ptr) @ stdcall DisablePredefinedHandleTableInternal(long) @ stdcall DisableThreadLibraryCalls(long) @ stdcall DisassociateCurrentThreadFromCallback(ptr) ntdll.TpDisassociateCallback @@ -326,7 +326,7 @@ @ stub EqualDomainSid @ stdcall EqualPrefixSid(ptr ptr) @ stdcall EqualSid(ptr ptr) -@ stdcall EscapeCommFunction(long long) kernel32.EscapeCommFunction +@ stdcall EscapeCommFunction(long long) @ stdcall EventActivityIdControl(long ptr) ntdll.EtwEventActivityIdControl @ stdcall EventEnabled(int64 ptr) ntdll.EtwEventEnabled @ stdcall EventProviderEnabled(int64 long int64) ntdll.EtwEventProviderEnabled @@ -427,12 +427,12 @@ @ stub GetCalendar @ stdcall GetCalendarInfoEx(wstr long ptr long ptr long ptr) kernel32.GetCalendarInfoEx @ stdcall GetCalendarInfoW(long long long ptr long ptr) kernel32.GetCalendarInfoW -@ stdcall GetCommConfig(long ptr ptr) kernel32.GetCommConfig -@ stdcall GetCommMask(long ptr) kernel32.GetCommMask -@ stdcall GetCommModemStatus(long ptr) kernel32.GetCommModemStatus -@ stdcall GetCommProperties(long ptr) kernel32.GetCommProperties -@ stdcall GetCommState(long ptr) kernel32.GetCommState -@ stdcall GetCommTimeouts(long ptr) kernel32.GetCommTimeouts +@ stdcall GetCommConfig(long ptr ptr) +@ stdcall GetCommMask(long ptr) +@ stdcall GetCommModemStatus(long ptr) +@ stdcall GetCommProperties(long ptr) +@ stdcall GetCommState(long ptr) +@ stdcall GetCommTimeouts(long ptr) @ stdcall GetCommandLineA() @ stdcall GetCommandLineW() @ stdcall GetCompressedFileSizeA(long ptr) @@ -1190,7 +1190,7 @@ # @ stub PssWalkSnapshot # @ stub PublishStateChangeNotification @ stdcall PulseEvent(long) -@ stdcall PurgeComm(long long) kernel32.PurgeComm +@ stdcall PurgeComm(long long) @ stdcall QISearch(ptr ptr ptr ptr) @ stdcall QueryActCtxSettingsW(long ptr wstr wstr ptr long ptr) @ stdcall QueryActCtxW(long ptr ptr long ptr long ptr) @@ -1393,11 +1393,11 @@ @ stdcall SetCalendarInfoW(long long long wstr) kernel32.SetCalendarInfoW # @ stub SetClientDynamicTimeZoneInformation # @ stub SetClientTimeZoneInformation -@ stdcall SetCommBreak(long) kernel32.SetCommBreak -@ stdcall SetCommConfig(long ptr long) kernel32.SetCommConfig -@ stdcall SetCommMask(long long) kernel32.SetCommMask -@ stdcall SetCommState(long ptr) kernel32.SetCommState -@ stdcall SetCommTimeouts(long ptr) kernel32.SetCommTimeouts +@ stdcall SetCommBreak(long) +@ stdcall SetCommConfig(long ptr long) +@ stdcall SetCommMask(long long) +@ stdcall SetCommState(long ptr) +@ stdcall SetCommTimeouts(long ptr) @ stdcall SetComputerNameA(str) kernel32.SetComputerNameA # @ stub SetComputerNameEx2W @ stdcall SetComputerNameExA(long str) kernel32.SetComputerNameExA @@ -1507,7 +1507,7 @@ @ stdcall SetWaitableTimer(long ptr long ptr ptr long) @ stdcall SetWaitableTimerEx(long ptr long ptr ptr ptr long) # @ stub SetXStateFeaturesMask -@ stdcall SetupComm(long long long) kernel32.SetupComm +@ stdcall SetupComm(long long long) # @ stub SharedLocalIsEnabled @ stdcall SignalObjectAndWait(long long long long) @ stdcall SizeofResource(long long) @@ -1605,7 +1605,7 @@ @ varargs TraceMessage(int64 long ptr long) ntdll.EtwTraceMessage @ stdcall TraceMessageVa(int64 long ptr long ptr) ntdll.EtwTraceMessageVa @ stdcall TransactNamedPipe(long ptr long ptr long ptr ptr) -@ stdcall TransmitCommChar(long long) kernel32.TransmitCommChar +@ stdcall TransmitCommChar(long long) @ stdcall TryAcquireSRWLockExclusive(ptr) ntdll.RtlTryAcquireSRWLockExclusive @ stdcall TryAcquireSRWLockShared(ptr) ntdll.RtlTryAcquireSRWLockShared @ stdcall TryEnterCriticalSection(ptr) ntdll.RtlTryEnterCriticalSection @@ -1683,7 +1683,7 @@ @ stdcall VirtualUnlock(ptr long) # @ stub WTSGetServiceSessionId # @ stub WTSIsServerContainer -@ stdcall WaitCommEvent(long ptr ptr) kernel32.WaitCommEvent +@ stdcall WaitCommEvent(long ptr ptr) @ stdcall WaitForDebugEvent(ptr long) # @ stub WaitForDebugEventEx # @ stub WaitForMachinePolicyForegroundProcessingInternal