The FD_TYPE_XXX macros are used in the ReadFile() and WriteFile()
routines to invoke special read/write procedures for file descriptors of
certain types. I feel that for future improvements of Wine IO, it
might be important to distinguish between FD type (regular file, serial
port, pipe, ...) and FD attributes (can do overlapped IO, uses timeout,
...).
That is the rationale for the following small patch.
Please comment.
--
Martin Wilck Phone: +49 5251 8 15113
Fujitsu Siemens Computers Fax: +49 5251 8 20409
Heinz-Nixdorf-Ring 1 mailto:Martin.Wilck@Fujitsu-Siemens.com
D-33106 Paderborn
http://www.fujitsu-siemens.com/primergy
diff -ruw -X diffignore CVS/wine/files/file.c MW/wine/files/file.c
--- CVS/wine/files/file.c Wed Jan 2 12:50:02 2002
+++ MW/wine/files/file.c Thu Jan 3 14:55:13 2002
@@ -1436,9 +1436,8 @@
unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_READ, &type );
- switch (type)
+ if ( FD_TYPE_IS_OVERLAPPED (type) )
{
- case FD_TYPE_OVERLAPPED:
if (unix_handle == -1) return FALSE;
if ( (overlapped==NULL) || NtResetEvent( overlapped->hEvent, NULL ) )
{
@@ -1481,15 +1480,21 @@
/* fail on return, with ERROR_IO_PENDING */
SetLastError(ERROR_IO_PENDING);
return FALSE;
+ }
- case FD_TYPE_CONSOLE:
+ else if ( FD_TYPE (type) == FD_TYPE_CONSOLE )
+ {
return ReadConsoleA(hFile, buffer, bytesToRead, bytesRead, NULL);
+ }
- case FD_TYPE_TIMEOUT:
+ else if ( FD_TYPE_HAS_TIMEOUT (type) )
+ {
close(unix_handle);
return FILE_TimeoutRead(hFile, buffer, bytesToRead, bytesRead);
+ }
- default:
+ else
+ {
/* normal unix files */
if (unix_handle == -1)
return FALSE;
@@ -1499,7 +1504,6 @@
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- break;
}
/* code for synchronous reads */
@@ -1639,9 +1643,8 @@
unix_handle = FILE_GetUnixHandleType( hFile, GENERIC_WRITE, &type );
- switch (type)
+ if ( FD_TYPE_IS_OVERLAPPED (type) )
{
- case FD_TYPE_OVERLAPPED:
if (unix_handle == -1) return FALSE;
if ( (overlapped==NULL) || NtResetEvent( overlapped->hEvent, NULL ) )
{
@@ -1652,12 +1655,17 @@
}
/* FIXME: try write immediately before starting overlapped operation */
return WriteFileEx(hFile, buffer, bytesToWrite, overlapped, FILE_OverlappedComplete);
+ }
- case FD_TYPE_CONSOLE:
+ else if ( FD_TYPE (type) == FD_TYPE_CONSOLE )
+ {
TRACE("%d %s %ld %p %p\n", hFile, debugstr_an(buffer, bytesToWrite), bytesToWrite,
bytesWritten, overlapped );
return WriteConsoleA(hFile, buffer, bytesToWrite, bytesWritten, NULL);
- default:
+ }
+
+ else
+ {
if (unix_handle == -1)
return FALSE;
}
diff -ruw -X diffignore CVS/wine/server/device.c MW/wine/server/device.c
--- CVS/wine/server/device.c Wed Jan 2 12:50:05 2002
+++ MW/wine/server/device.c Thu Jan 3 14:46:50 2002
@@ -83,7 +83,7 @@
reply->index_low = 0;
reply->serial = 0;
}
- return FD_TYPE_DEFAULT;
+ return FD_TYPE_DEVICE;
}
/* create a device */
diff -ruw -X diffignore CVS/wine/server/file.c MW/wine/server/file.c
--- CVS/wine/server/file.c Wed Jan 2 12:50:05 2002
+++ MW/wine/server/file.c Thu Jan 3 14:53:56 2002
@@ -276,6 +276,7 @@
{
struct stat st;
struct file *file = (struct file *)obj;
+ int fd_type = FD_TYPE_DEFAULT;
assert( obj->ops == &file_ops );
if (reply)
@@ -308,7 +309,10 @@
reply->index_low = st.st_ino;
reply->serial = 0; /* FIXME */
}
- return FD_TYPE_DEFAULT;
+
+ if ( file->flags & FILE_FLAG_OVERLAPPED )
+ fd_type |= FD_TYPE_FLAG_OVERLAPPED;
+ return fd_type;
}
static void file_destroy( struct object *obj )
diff -ruw -X diffignore CVS/wine/server/named_pipe.c MW/wine/server/named_pipe.c
--- CVS/wine/server/named_pipe.c Wed Jan 2 12:50:05 2002
+++ MW/wine/server/named_pipe.c Thu Jan 3 14:50:17 2002
@@ -197,7 +197,7 @@
reply->index_low = 0;
reply->serial = 0;
}
- return FD_TYPE_DEFAULT;
+ return FD_TYPE_NAMED_PIPE;
}
static struct named_pipe *create_named_pipe( const WCHAR *name, size_t len )
diff -ruw -X diffignore CVS/wine/server/pipe.c MW/wine/server/pipe.c
--- CVS/wine/server/pipe.c Wed Jan 2 12:50:05 2002
+++ MW/wine/server/pipe.c Thu Jan 3 14:50:29 2002
@@ -140,7 +140,7 @@
reply->index_low = 0;
reply->serial = 0;
}
- return FD_TYPE_DEFAULT;
+ return FD_TYPE_PIPE;
}
static void pipe_destroy( struct object *obj )
diff -ruw -X diffignore CVS/wine/server/protocol.def MW/wine/server/protocol.def
--- CVS/wine/server/protocol.def Wed Jan 2 12:50:05 2002
+++ MW/wine/server/protocol.def Thu Jan 3 14:53:27 2002
@@ -544,12 +544,22 @@
int fd; /* file descriptor */
int type; /* the type of file */
@END
+#define FD_TYPE(x) ((x) & 0xff)
+
#define FD_TYPE_INVALID 0
#define FD_TYPE_DEFAULT 1
#define FD_TYPE_CONSOLE 2
-#define FD_TYPE_OVERLAPPED 3
-#define FD_TYPE_TIMEOUT 4
+#define FD_TYPE_DEVICE 3
+#define FD_TYPE_NAMED_PIPE 4
+#define FD_TYPE_PIPE 5
+#define FD_TYPE_SERIAL 6
+#define FD_TYPE_SOCKET 7
+
+#define FD_TYPE_FLAG_OVERLAPPED 0x100
+#define FD_TYPE_FLAG_TIMEOUT 0x200
+#define FD_TYPE_IS_OVERLAPPED(x) ((x) & FD_TYPE_FLAG_OVERLAPPED)
+#define FD_TYPE_HAS_TIMEOUT(x) ((x) & FD_TYPE_FLAG_TIMEOUT)
/* Set a file current position */
@REQ(set_file_pointer)
diff -ruw -X diffignore CVS/wine/server/serial.c MW/wine/server/serial.c
--- CVS/wine/server/serial.c Wed Jan 2 12:50:05 2002
+++ MW/wine/server/serial.c Thu Jan 3 14:54:09 2002
@@ -192,6 +192,7 @@
static int serial_get_info( struct object *obj, struct get_file_info_reply *reply )
{
struct serial *serial = (struct serial *) obj;
+ int fd_type = FD_TYPE_SERIAL;
assert( obj->ops == &serial_ops );
if (reply)
@@ -209,13 +210,13 @@
}
if(serial->attrib & FILE_FLAG_OVERLAPPED)
- return FD_TYPE_OVERLAPPED;
+ fd_type |= FD_TYPE_FLAG_OVERLAPPED;
- if( (serial->readinterval == MAXDWORD) &&
- (serial->readmult == 0) && (serial->readconst == 0) )
- return FD_TYPE_DEFAULT;
+ else if( !((serial->readinterval == MAXDWORD) &&
+ (serial->readmult == 0) && (serial->readconst == 0)) )
+ fd_type |= FD_TYPE_FLAG_TIMEOUT;
- return FD_TYPE_TIMEOUT;
+ return fd_type;
}
static void serial_poll_event(struct object *obj, int event)
diff -ruw -X diffignore CVS/wine/server/sock.c MW/wine/server/sock.c
--- CVS/wine/server/sock.c Wed Jan 2 12:50:05 2002
+++ MW/wine/server/sock.c Thu Jan 3 14:53:11 2002
@@ -288,7 +288,7 @@
reply->index_low = 0;
reply->serial = 0;
}
- return FD_TYPE_DEFAULT;
+ return FD_TYPE_SOCKET;
}
static void sock_destroy( struct object *obj )