| /* |
| * DOS interrupt 25h handler |
| * |
| * Copyright 1997 Andreas Mohr |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA |
| */ |
| |
| #include "config.h" |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <fcntl.h> |
| #ifdef HAVE_UNISTD_H |
| # include <unistd.h> |
| #endif |
| #include "dosexe.h" |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(int); |
| |
| |
| /*********************************************************************** |
| * DOSVM_RawRead |
| * |
| * Read raw sectors from a device. |
| */ |
| BOOL DOSVM_RawRead(BYTE drive, DWORD begin, DWORD nr_sect, BYTE *dataptr, BOOL fake_success) |
| { |
| WCHAR root[] = {'\\','\\','.','\\','A',':',0}; |
| HANDLE h; |
| |
| TRACE( "abs diskread, drive %d, sector %d, " |
| "count %d, buffer %p\n", |
| drive, begin, nr_sect, dataptr ); |
| |
| root[4] += drive; |
| h = CreateFileW(root, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, |
| FILE_FLAG_BACKUP_SEMANTICS, NULL); |
| if (h != INVALID_HANDLE_VALUE) |
| { |
| DWORD r; |
| SetFilePointer(h, begin * 512, NULL, SEEK_SET ); |
| /* FIXME: check errors */ |
| ReadFile(h, dataptr, nr_sect * 512, &r, NULL ); |
| CloseHandle(h); |
| } |
| else |
| { |
| memset( dataptr, 0, nr_sect * 512 ); |
| if (fake_success) |
| { |
| /* FIXME: explain what happens here */ |
| if (begin == 0 && nr_sect > 1) *(dataptr + 512) = 0xf8; |
| if (begin == 1) *dataptr = 0xf8; |
| } |
| else |
| return FALSE; |
| } |
| |
| return TRUE; |
| } |
| |
| |
| /********************************************************************** |
| * DOSVM_Int25Handler |
| * |
| * Handler for int 25h (absolute disk read). |
| */ |
| void WINAPI DOSVM_Int25Handler( CONTEXT *context ) |
| { |
| WCHAR drivespec[] = {'A', ':', '\\', 0}; |
| BYTE *dataptr = CTX_SEG_OFF_TO_LIN( context, context->SegDs, context->Ebx ); |
| DWORD begin; |
| DWORD length; |
| |
| drivespec[0] += AL_reg( context ); |
| |
| if (GetDriveTypeW( drivespec ) == DRIVE_NO_ROOT_DIR || |
| GetDriveTypeW( drivespec ) == DRIVE_UNKNOWN) |
| { |
| SET_CFLAG( context ); |
| SET_AX( context, 0x0201 ); /* unknown unit */ |
| return; |
| } |
| |
| if (CX_reg( context ) == 0xffff) |
| { |
| begin = *(DWORD *)dataptr; |
| length = *(WORD *)(dataptr + 4); |
| dataptr = (BYTE *)CTX_SEG_OFF_TO_LIN( context, |
| *(WORD *)(dataptr + 8), |
| *(DWORD *)(dataptr + 6) ); |
| } |
| else |
| { |
| begin = DX_reg( context ); |
| length = CX_reg( context ); |
| } |
| |
| DOSVM_RawRead( AL_reg( context ), begin, length, dataptr, TRUE ); |
| RESET_CFLAG( context ); |
| } |