Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
e12d8ae0
Commit
e12d8ae0
authored
Jul 20, 2001
by
Mike McCormack
Committed by
Alexandre Julliard
Jul 20, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Replace service thread with ReadFileEx/WriteFileEx.
parent
f89722db
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
107 additions
and
68 deletions
+107
-68
comm.c
dlls/kernel/comm.c
+107
-68
No files found.
dlls/kernel/comm.c
View file @
e12d8ae0
...
...
@@ -67,7 +67,6 @@
#include "wine/port.h"
#include "wine/server.h"
#include "winerror.h"
#include "services.h"
#include "callback.h"
#include "file.h"
...
...
@@ -110,7 +109,7 @@ struct DosDeviceStruct {
unsigned
obuf_size
,
obuf_head
,
obuf_tail
;
/* notifications */
int
wnd
,
n_read
,
n_write
;
HANDLE
s_read
,
s_write
;
OVERLAPPED
read_ov
,
write_ov
;
/* save terminal states */
DCB16
dcb
;
/* pointer to unknown(==undocumented) comm structure */
...
...
@@ -216,12 +215,12 @@ static struct DosDeviceStruct *GetDeviceStruct(int index)
return
NULL
;
}
static
int
GetCommPort_
fd
(
HANDLE
handl
e
)
static
int
GetCommPort_
ov
(
LPOVERLAPPED
ov
,
int
writ
e
)
{
int
x
;
for
(
x
=
0
;
x
<
MAX_PORTS
;
x
++
)
{
if
(
COM
[
x
].
handle
==
handle
)
if
(
ov
==
(
write
?&
COM
[
x
].
write_ov
:&
COM
[
x
].
read_ov
)
)
return
x
;
}
...
...
@@ -269,26 +268,32 @@ static int COMM_WhackModem(int fd, unsigned int andy, unsigned int orrie)
return
ioctl
(
fd
,
TIOCMSET
,
&
mstat
);
}
static
void
CALLBACK
comm_notification
(
ULONG_PTR
private
)
static
void
comm_waitread
(
struct
DosDeviceStruct
*
ptr
);
static
void
comm_waitwrite
(
struct
DosDeviceStruct
*
ptr
);
static
VOID
WINAPI
COMM16_ReadComplete
(
DWORD
status
,
DWORD
len
,
LPOVERLAPPED
ov
)
{
struct
DosDeviceStruct
*
ptr
=
(
struct
DosDeviceStruct
*
)
private
;
int
prev
,
bleft
;
DWORD
len
;
int
prev
;
WORD
mask
=
0
;
int
cid
=
GetCommPort_fd
(
ptr
->
handle
);
int
cid
=
GetCommPort_ov
(
ov
,
0
);
struct
DosDeviceStruct
*
ptr
;
if
(
cid
<
0
)
{
ERR
(
"async write with bad overlapped pointer
\n
"
);
return
;
}
ptr
=
&
COM
[
cid
];
TRACE
(
"async notification
\n
"
);
/* read data from comm port */
if
(
status
!=
STATUS_SUCCESS
)
{
ERR
(
"async read failed
\n
"
);
COM
[
cid
].
commerror
=
CE_RXOVER
;
return
;
}
TRACE
(
"async read completed %ld bytes
\n
"
,
len
);
prev
=
comm_inbuf
(
ptr
);
do
{
bleft
=
((
ptr
->
ibuf_tail
>
ptr
->
ibuf_head
)
?
(
ptr
->
ibuf_tail
-
1
)
:
ptr
->
ibuf_size
)
-
ptr
->
ibuf_head
;
if
(
!
ReadFile
(
ptr
->
handle
,
ptr
->
inbuf
+
ptr
->
ibuf_head
,
bleft
?
bleft
:
1
,
&
len
,
NULL
))
len
=
-
1
;
if
(
len
>
0
)
{
if
(
!
bleft
)
{
ptr
->
commerror
=
CE_RXOVER
;
}
else
{
/* check for events */
if
((
ptr
->
eventmask
&
EV_RXFLAG
)
&&
memchr
(
ptr
->
inbuf
+
ptr
->
ibuf_head
,
ptr
->
evtchar
,
len
))
{
...
...
@@ -299,13 +304,12 @@ static void CALLBACK comm_notification( ULONG_PTR private )
*
(
WORD
*
)(
COM
[
cid
].
unknown
)
|=
EV_RXCHAR
;
mask
|=
CN_EVENT
;
}
/* advance buffer position */
ptr
->
ibuf_head
+=
len
;
if
(
ptr
->
ibuf_head
>=
ptr
->
ibuf_size
)
ptr
->
ibuf_head
=
0
;
}
}
}
while
(
len
>
0
);
/* check for notification */
if
(
ptr
->
wnd
&&
(
ptr
->
n_read
>
0
)
&&
(
prev
<
ptr
->
n_read
)
&&
(
comm_inbuf
(
ptr
)
>=
ptr
->
n_read
))
{
...
...
@@ -313,39 +317,55 @@ static void CALLBACK comm_notification( ULONG_PTR private )
mask
|=
CN_RECEIVE
;
}
/* send notifications, if any */
if
(
ptr
->
wnd
&&
mask
)
{
TRACE
(
"notifying %04x: cid=%d, mask=%02x
\n
"
,
ptr
->
wnd
,
cid
,
mask
);
if
(
Callout
.
PostMessageA
)
Callout
.
PostMessageA
(
ptr
->
wnd
,
WM_COMMNOTIFY
,
cid
,
mask
);
}
/* on real windows, this could cause problems, since it is recursive */
/* restart the receive */
comm_waitread
(
ptr
);
}
static
VOID
WINAPI
COMM16_WriteComplete
(
DWORD
status
,
DWORD
len
,
LPOVERLAPPED
ov
)
{
int
prev
,
bleft
;
WORD
mask
=
0
;
int
cid
=
GetCommPort_ov
(
ov
,
1
);
struct
DosDeviceStruct
*
ptr
;
if
(
cid
<
0
)
{
ERR
(
"async write with bad overlapped pointer
\n
"
);
return
;
}
ptr
=
&
COM
[
cid
];
/* read data from comm port */
if
(
status
!=
STATUS_SUCCESS
)
{
ERR
(
"async write failed
\n
"
);
COM
[
cid
].
commerror
=
CE_RXOVER
;
return
;
}
TRACE
(
"async write completed %ld bytes
\n
"
,
len
);
/* update the buffer pointers */
prev
=
comm_outbuf
(
&
COM
[
cid
]);
ptr
->
obuf_tail
+=
len
;
if
(
ptr
->
obuf_tail
>=
ptr
->
obuf_size
)
ptr
->
obuf_tail
=
0
;
/* write any TransmitCommChar character */
if
(
ptr
->
xmit
>=
0
)
{
if
(
!
WriteFile
(
ptr
->
handle
,
&
(
ptr
->
xmit
),
1
,
&
len
,
NULL
))
len
=
-
1
;
if
(
len
>
0
)
ptr
->
xmit
=
-
1
;
}
/* write from output queue */
prev
=
comm_outbuf
(
ptr
);
do
{
bleft
=
((
ptr
->
obuf_tail
<=
ptr
->
obuf_head
)
?
ptr
->
obuf_head
:
ptr
->
obuf_size
)
-
ptr
->
obuf_tail
;
if
(
bleft
)
{
if
(
!
WriteFile
(
ptr
->
handle
,
ptr
->
outbuf
+
ptr
->
obuf_tail
,
bleft
,
&
len
,
NULL
))
len
=
-
1
;
}
else
len
=
bleft
;
if
(
len
>
0
)
{
ptr
->
obuf_tail
+=
len
;
if
(
ptr
->
obuf_tail
>=
ptr
->
obuf_size
)
ptr
->
obuf_tail
=
0
;
/* flag event */
if
(
ptr
->
obuf_tail
==
ptr
->
obuf_head
)
{
if
(
ptr
->
s_write
)
{
SERVICE_Delete
(
ptr
->
s_write
);
ptr
->
s_write
=
INVALID_HANDLE_VALUE
;
}
if
(
ptr
->
eventmask
&
EV_TXEMPTY
)
{
*
(
WORD
*
)(
COM
[
cid
].
unknown
)
|=
EV_TXEMPTY
;
mask
|=
CN_EVENT
;
}
}
}
}
while
(
len
>
0
);
bleft
=
((
ptr
->
obuf_tail
<=
ptr
->
obuf_head
)
?
ptr
->
obuf_head
:
ptr
->
obuf_size
)
-
ptr
->
obuf_tail
;
/* check for notification */
if
(
ptr
->
wnd
&&
(
ptr
->
n_write
>
0
)
&&
(
prev
>=
ptr
->
n_write
)
&&
(
comm_outbuf
(
ptr
)
<
ptr
->
n_write
))
{
...
...
@@ -358,30 +378,37 @@ static void CALLBACK comm_notification( ULONG_PTR private )
TRACE
(
"notifying %04x: cid=%d, mask=%02x
\n
"
,
ptr
->
wnd
,
cid
,
mask
);
if
(
Callout
.
PostMessageA
)
Callout
.
PostMessageA
(
ptr
->
wnd
,
WM_COMMNOTIFY
,
cid
,
mask
);
}
/* start again if necessary */
if
(
bleft
)
comm_waitwrite
(
ptr
);
}
static
void
comm_waitread
(
struct
DosDeviceStruct
*
ptr
)
{
HANDLE
dup
=
INVALID_HANDLE_VALUE
;
if
(
ptr
->
s_read
!=
INVALID_HANDLE_VALUE
)
return
;
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
ptr
->
handle
,
GetCurrentProcess
(),
&
dup
,
GENERIC_READ
|
SYNCHRONIZE
,
FALSE
,
0
))
return
;
ptr
->
s_read
=
SERVICE_AddObject
(
dup
,
comm_notification
,
(
ULONG_PTR
)
ptr
);
int
bleft
;
bleft
=
((
ptr
->
ibuf_tail
>
ptr
->
ibuf_head
)
?
(
ptr
->
ibuf_tail
-
1
)
:
ptr
->
ibuf_size
)
-
ptr
->
ibuf_head
;
/* FIXME: get timeouts working properly so we can read bleft bytes */
ReadFileEx
(
ptr
->
handle
,
ptr
->
inbuf
+
ptr
->
ibuf_head
,
1
,
&
ptr
->
read_ov
,
COMM16_ReadComplete
);
}
static
void
comm_waitwrite
(
struct
DosDeviceStruct
*
ptr
)
{
HANDLE
dup
=
INVALID_HANDLE_VALUE
;
if
(
ptr
->
s_write
!=
INVALID_HANDLE_VALUE
)
return
;
if
(
!
DuplicateHandle
(
GetCurrentProcess
(),
ptr
->
handle
,
GetCurrentProcess
(),
&
dup
,
GENERIC_WRITE
|
SYNCHRONIZE
,
FALSE
,
0
))
return
;
ptr
->
s_write
=
SERVICE_AddObject
(
dup
,
comm_notification
,
(
ULONG_PTR
)
ptr
);
int
bleft
;
bleft
=
((
ptr
->
obuf_tail
<=
ptr
->
obuf_head
)
?
ptr
->
obuf_head
:
ptr
->
obuf_size
)
-
ptr
->
obuf_tail
;
WriteFileEx
(
ptr
->
handle
,
ptr
->
outbuf
+
ptr
->
obuf_tail
,
bleft
,
&
ptr
->
write_ov
,
COMM16_WriteComplete
);
}
/**************************************************************************
...
...
@@ -590,9 +617,13 @@ INT16 WINAPI OpenComm16(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
return
IE_MEMORY
;
}
COM
[
port
].
s_read
=
INVALID_HANDLE_VALUE
;
COM
[
port
].
s_write
=
INVALID_HANDLE_VALUE
;
ZeroMemory
(
&
COM
[
port
].
read_ov
,
sizeof
(
OVERLAPPED
));
ZeroMemory
(
&
COM
[
port
].
write_ov
,
sizeof
(
OVERLAPPED
));
COM
[
port
].
read_ov
.
hEvent
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
);
COM
[
port
].
write_ov
.
hEvent
=
CreateEventA
(
NULL
,
0
,
0
,
NULL
);
comm_waitread
(
&
COM
[
port
]
);
return
port
;
}
}
...
...
@@ -635,8 +666,9 @@ INT16 WINAPI CloseComm16(INT16 cid)
/* COM port */
SEGPTR_FREE
(
COM
[
cid
].
unknown
);
/* [LW] */
SERVICE_Delete
(
COM
[
cid
].
s_write
);
SERVICE_Delete
(
COM
[
cid
].
s_read
);
CloseHandle
(
COM
[
cid
].
read_ov
.
hEvent
);
CloseHandle
(
COM
[
cid
].
write_ov
.
hEvent
);
/* free buffers */
free
(
ptr
->
outbuf
);
free
(
ptr
->
inbuf
);
...
...
@@ -815,8 +847,15 @@ INT16 WINAPI GetCommError16(INT16 cid,LPCOMSTAT16 lpStat)
COMM_MSRUpdate
(
ptr
->
handle
,
stol
);
if
(
lpStat
)
{
HANDLE
rw_events
[
2
];
lpStat
->
status
=
0
;
rw_events
[
0
]
=
COM
[
cid
].
read_ov
.
hEvent
;
rw_events
[
1
]
=
COM
[
cid
].
write_ov
.
hEvent
;
WaitForMultipleObjectsEx
(
2
,
&
rw_events
[
0
],
FALSE
,
1
,
TRUE
);
lpStat
->
cbOutQue
=
comm_outbuf
(
ptr
);
lpStat
->
cbInQue
=
comm_inbuf
(
ptr
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment