diff --git a/files/drive.c b/files/drive.c
index d1c190609a81f4560bbdd18d45a4f35494465b3e..2c69d0b9ee7806bc1919366b3d0bf6d7ec68f6f4 100644
--- a/files/drive.c
+++ b/files/drive.c
@@ -15,6 +15,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <unistd.h>
 
 #ifdef HAVE_SYS_PARAM_H
 # include <sys/param.h>
@@ -577,6 +578,61 @@ int DRIVE_OpenDevice( int drive, int flags )
 }
 
 
+/***********************************************************************
+ *           DRIVE_RawRead
+ *
+ * Read raw sectors from a device
+ */
+int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL32 fake_success)
+{
+    int fd;
+
+    if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1)
+    {
+        lseek( fd, begin * 512, SEEK_SET );
+        /* FIXME: check errors */
+        read( fd, dataptr, nr_sect * 512 );
+        close( fd );
+    }
+    else
+    {
+        memset(dataptr, 0, nr_sect * 512);
+		if (fake_success)
+        {
+			if (begin == 0 && nr_sect > 1) *(dataptr + 512) = 0xf8;
+			if (begin == 1) *dataptr = 0xf8;
+		}
+		else
+		return 0;
+    }
+	return 1;
+}
+
+
+/***********************************************************************
+ *           DRIVE_RawWrite
+ *
+ * Write raw sectors to a device
+ */
+int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL32 fake_success)
+{
+	int fd;
+
+    if ((fd = DRIVE_OpenDevice( drive, O_RDONLY )) != -1)
+    {
+        lseek( fd, begin * 512, SEEK_SET );
+        /* FIXME: check errors */
+        write( fd, dataptr, nr_sect * 512 );
+        close( fd );
+    }
+    else
+	if (!(fake_success))
+		return 0;
+
+	return 1;
+}
+
+
 /***********************************************************************
  *           DRIVE_GetFreeSpace
  */
diff --git a/include/drive.h b/include/drive.h
index 5849e3a6716b385413038a405647545706f951e0..f4aea646b90097e0754803afaeb4f4b9660c6656 100644
--- a/include/drive.h
+++ b/include/drive.h
@@ -45,5 +45,7 @@ extern int DRIVE_Disable( int drive  );
 extern int DRIVE_Enable( int drive  );
 extern int DRIVE_SetLogicalMapping ( int existing_drive, int new_drive );
 extern int DRIVE_OpenDevice( int drive, int flags );
+extern int DRIVE_RawRead(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL32 fake_success );
+extern int DRIVE_RawWrite(BYTE drive, DWORD begin, DWORD length, BYTE *dataptr, BOOL32 fake_success );
 
 #endif  /* __WINE_DRIVE_H */
diff --git a/msdos/int21.c b/msdos/int21.c
index 45a0c062e9982b18ed6b4e085f38ad321a23a747..6f7ca492f5615ec48a773741c1824899064710ad 100644
--- a/msdos/int21.c
+++ b/msdos/int21.c
@@ -291,6 +291,30 @@ static BOOL32 ioctlGenericBlkDevReq( CONTEXT *context )
 			RESET_CFLAG(context);
 			break;
 
+		case 0x41: /* write logical device track */
+		case 0x61: /* read logical device track */
+			{
+				BYTE drive = BL_reg(context) ?
+						BL_reg(context) : DRIVE_GetCurrentDrive(); 
+				WORD head   = *(WORD *)dataptr+1;
+				WORD cyl    = *(WORD *)dataptr+3;
+				WORD sect   = *(WORD *)dataptr+5;
+				WORD nrsect = *(WORD *)dataptr+7;
+				BYTE *data  = (BYTE **)dataptr+9;
+				int (*raw_func)(BYTE, DWORD, DWORD, BYTE *, BOOL32);
+
+				raw_func = (CL_reg(context) == 0x41) ?
+								DRIVE_RawWrite : DRIVE_RawRead;
+
+				if (raw_func(drive, head*cyl*sect, nrsect, data, FALSE))
+					RESET_CFLAG(context);
+				else
+				{
+					AX_reg(context) = 0x1e; /* read fault */
+					SET_CFLAG(context);
+				}
+			}
+			break;
 		case 0x66:/*  get disk serial number */
 			{	
 				char	label[12],fsname[9],path[4];
@@ -327,16 +351,16 @@ static BOOL32 ioctlGenericBlkDevReq( CONTEXT *context )
 static void INT21_ParseFileNameIntoFCB( CONTEXT *context )
 {
     char *filename =
-        CTX_SEG_OFF_TO_LIN(context, DS_reg(context), SI_reg(context) );
+        CTX_SEG_OFF_TO_LIN(context, DS_reg(context), ESI_reg(context) );
     char *fcb =
-        CTX_SEG_OFF_TO_LIN(context, ES_reg(context), DI_reg(context) );
+        CTX_SEG_OFF_TO_LIN(context, ES_reg(context), EDI_reg(context) );
     char *buffer, *s, *d;
 
     AL_reg(context) = 0xff; /* failed */
 
     TRACE(int21, "filename: '%s'\n", filename);
 
-    buffer = HeapAlloc( GetProcessHeap(), 0, strlen(filename) );
+    buffer = HeapAlloc( GetProcessHeap(), 0, strlen(filename) + 1);
 
     s = filename;
     d = buffer;
@@ -1082,6 +1106,9 @@ void WINAPI DOS3Call( CONTEXT *context )
         break;
 
     case 0x01: /* READ CHARACTER FROM STANDARD INPUT, WITH ECHO */
+		_lread16(1, (BYTE *)&context->Eax, 1);
+		break;
+
     case 0x03: /* READ CHARACTER FROM STDAUX  */
     case 0x04: /* WRITE CHARACTER TO STDAUX */
     case 0x05: /* WRITE CHARACTER TO PRINTER */
diff --git a/msdos/int25.c b/msdos/int25.c
index b2635e7569a207df7a75c3f5252e79a1cf3b476d..19d4598b80a9e4782db58529f1ffab300c84389c 100644
--- a/msdos/int25.c
+++ b/msdos/int25.c
@@ -12,6 +12,7 @@
 #include "drive.h"
 #include "debug.h"
 
+
 /**********************************************************************
  *	    INT_Int25Handler
  *
@@ -21,7 +22,6 @@ void WINAPI INT_Int25Handler( CONTEXT *context )
 {
     BYTE *dataptr = CTX_SEG_OFF_TO_LIN( context, DS_reg(context), EBX_reg(context) );
     DWORD begin, length;
-    int fd;
 
     if (!DRIVE_IsValid(AL_reg(context)))
     {
@@ -43,22 +43,10 @@ void WINAPI INT_Int25Handler( CONTEXT *context )
         length = CX_reg(context);
     }
     TRACE(int, "int25: abs diskread, drive %d, sector %ld, "
-                 "count %ld, buffer %d\n",
-                 AL_reg(context), begin, length, (int) dataptr);
+                 "count %ld, buffer %p\n",
+                 AL_reg(context), begin, length, dataptr);
 
-    if ((fd = DRIVE_OpenDevice( AL_reg(context), O_RDONLY )) != -1)
-    {
-        lseek( fd, begin * 512, SEEK_SET );
-        /* FIXME: check errors */
-        read( fd, dataptr, length * 512 );
-        close( fd );
-    }
-    else
-    {
-        memset(dataptr, 0, length * 512);
-        if (begin == 0 && length > 1) *(dataptr + 512) = 0xf8;
-        if (begin == 1) *dataptr = 0xf8;
-    }
+	DRIVE_RawRead(AL_reg(context), begin, length, dataptr, TRUE);
     RESET_CFLAG(context);
 }
 
diff --git a/msdos/int26.c b/msdos/int26.c
index ba3e11b8418c7e847d663d6e2aa4907171f68327..5ed49957b2798d8d645fff9fb0510d4449834256 100644
--- a/msdos/int26.c
+++ b/msdos/int26.c
@@ -20,7 +20,6 @@ void WINAPI INT_Int26Handler( CONTEXT *context )
 {
     BYTE *dataptr = CTX_SEG_OFF_TO_LIN( context, DS_reg(context), EBX_reg(context) );
     DWORD begin, length;
-    int fd;
 
     if (!DRIVE_IsValid(AL_reg(context)))
     {
@@ -43,16 +42,9 @@ void WINAPI INT_Int26Handler( CONTEXT *context )
     }
 		
     TRACE(int,"int26: abs diskwrite, drive %d, sector %ld, "
-                 "count %ld, buffer %d\n",
-                 AL_reg(context), begin, length, (int) dataptr );
-
-    if ((fd = DRIVE_OpenDevice( AL_reg(context), O_WRONLY )) != -1)
-    {
-        lseek( fd, begin * 512, SEEK_SET );
-        /* FIXME: check errors */
-        write( fd, dataptr, length * 512 );
-        close( fd );
-    }
+                 "count %ld, buffer %p\n",
+                 AL_reg(context), begin, length, dataptr );
 
+	DRIVE_RawWrite(AL_reg(context), begin, length, dataptr, TRUE);
     RESET_CFLAG(context);
 }