diff options
Diffstat (limited to 'winsup/cygwin/fhandler_raw.cc')
-rw-r--r-- | winsup/cygwin/fhandler_raw.cc | 74 |
1 files changed, 57 insertions, 17 deletions
diff --git a/winsup/cygwin/fhandler_raw.cc b/winsup/cygwin/fhandler_raw.cc index a31e73904..3e73850e2 100644 --- a/winsup/cygwin/fhandler_raw.cc +++ b/winsup/cygwin/fhandler_raw.cc @@ -16,6 +16,7 @@ #include <cygwin/rdevio.h> #include <sys/mtio.h> +#include <ntdef.h> #include "cygerrno.h" #include "perprocess.h" #include "security.h" @@ -23,6 +24,7 @@ #include "path.h" #include "dtable.h" #include "cygheap.h" +#include "ntdll.h" /* static wrapper functions to hide the effect of media changes and bus resets which occurs after a new media is inserted. This is @@ -132,22 +134,69 @@ fhandler_dev_raw::~fhandler_dev_raw (void) } int -fhandler_dev_raw::open (path_conv *, int flags, mode_t) +fhandler_dev_raw::open (path_conv *real_path, int flags, mode_t) { - int ret; + if (!wincap.has_raw_devices ()) + { + set_errno (ENOENT); + debug_printf("%s is accessible under NT/W2K only",real_path->get_win32()); + return 0; + } + + /* Check for illegal flags. */ + if (flags & (O_APPEND | O_EXCL)) + { + set_errno (EINVAL); + return 0; + } /* Always open a raw device existing and binary. */ flags &= ~(O_CREAT | O_TRUNC); flags |= O_BINARY; - ret = fhandler_base::open (NULL, flags); - if (ret) + + if (get_device () == FH_FLOPPY && get_unit () >= 224) { - if (devbufsiz > 1L) - devbuf = new char [devbufsiz]; + /* Compatibility mode for old mount table device mapping. */ + if (!fhandler_base::open (real_path, flags)) + return 0; } else - devbufsiz = 0; - return ret; + { + DWORD access = GENERIC_READ | SYNCHRONIZE; + if (get_device () == FH_TAPE + || (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_WRONLY + || (flags & (O_RDONLY | O_WRONLY | O_RDWR)) == O_RDWR) + access |= GENERIC_WRITE; + + extern void str2buf2uni (UNICODE_STRING &, WCHAR *, const char *); + UNICODE_STRING dev; + WCHAR devname[MAX_PATH + 1]; + str2buf2uni (dev, devname, real_path->get_win32 ()); + OBJECT_ATTRIBUTES attr; + InitializeObjectAttributes(&attr, &dev, OBJ_CASE_INSENSITIVE, NULL, NULL); + + HANDLE h; + IO_STATUS_BLOCK io; + NTSTATUS status = NtOpenFile (&h, access, &attr, &io, wincap.shared (), + FILE_SYNCHRONOUS_IO_NONALERT); + if (!NT_SUCCESS (status)) + { + set_errno (RtlNtStatusToDosError (status)); + debug_printf ("NtOpenFile: NTSTATUS: %d, Win32: %E", status); + return 0; + } + + set_io_handle (h); + set_flags (flags); + } + + set_r_binary (O_BINARY); + set_w_binary (O_BINARY); + + if (devbufsiz > 1L) + devbuf = new char [devbufsiz]; + + return 1; } int @@ -157,15 +206,6 @@ fhandler_dev_raw::close (void) } int -fhandler_dev_raw::fstat (struct stat *buf, path_conv *pc) -{ - this->fhandler_base::fstat (buf, pc); - buf->st_blksize = devbuf ? devbufsiz : 1; - - return 0; -} - -int fhandler_dev_raw::raw_read (void *ptr, size_t ulen) { DWORD bytes_read = 0; |