| /* |
| * Tape handling functions |
| * |
| * Copyright 1999 Chris Morgan <cmorgan@wpi.edu> |
| * James Abbatiello <abbeyj@wpi.edu> |
| * Copyright 2006 Hans Leidekker |
| * |
| * 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 <stdarg.h> |
| |
| #include "ntstatus.h" |
| #define WIN32_NO_STATUS |
| #include "windef.h" |
| #include "winternl.h" |
| #include "winbase.h" |
| #include "winerror.h" |
| #include "winioctl.h" |
| #include "ddk/ntddtape.h" |
| |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(tape); |
| |
| static DWORD set_error_from_status( NTSTATUS status ) |
| { |
| DWORD error = RtlNtStatusToDosError( status ); |
| |
| SetLastError( error ); |
| return error; |
| } |
| |
| /************************************************************************ |
| * BackupRead (KERNEL32.@) |
| * |
| * Backup a file or directory. |
| */ |
| BOOL WINAPI BackupRead( HANDLE file, LPBYTE buffer, DWORD to_read, |
| LPDWORD read, BOOL abort, BOOL security, LPVOID *context ) |
| { |
| FIXME( "(%p, %p, %d, %p, %d, %d, %p)\n", file, buffer, |
| to_read, read, abort, security, context ); |
| SetLastError( ERROR_NOT_SUPPORTED ); |
| return FALSE; |
| } |
| |
| |
| /************************************************************************ |
| * BackupSeek (KERNEL32.@) |
| * |
| * Seek forward in a backup stream. |
| */ |
| BOOL WINAPI BackupSeek( HANDLE file, DWORD seek_low, DWORD seek_high, |
| LPDWORD seeked_low, LPDWORD seeked_high, LPVOID *context ) |
| { |
| FIXME( "(%p, %d, %d, %p, %p, %p)\n", file, seek_low, |
| seek_high, seeked_low, seeked_high, context ); |
| SetLastError( ERROR_NOT_SUPPORTED ); |
| return FALSE; |
| } |
| |
| |
| /************************************************************************ |
| * BackupWrite (KERNEL32.@) |
| * |
| * Restore a file or directory. |
| */ |
| BOOL WINAPI BackupWrite( HANDLE file, LPBYTE buffer, DWORD to_write, |
| LPDWORD written, BOOL abort, BOOL security, LPVOID *context ) |
| { |
| FIXME( "(%p, %p, %d, %p, %d, %d, %p)\n", file, buffer, |
| to_write, written, abort, security, context ); |
| SetLastError( ERROR_NOT_SUPPORTED ); |
| return FALSE; |
| } |
| |
| |
| /************************************************************************ |
| * CreateTapePartition (KERNEL32.@) |
| * |
| * Format a tape. |
| */ |
| DWORD WINAPI CreateTapePartition( HANDLE device, DWORD method, |
| DWORD count, DWORD size ) |
| { |
| NTSTATUS status; |
| TAPE_CREATE_PARTITION part; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %d, %d)\n", device, method, count, size ); |
| |
| part.Method = method; |
| part.Count = count; |
| part.Size = size; |
| |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_CREATE_PARTITION, &part, sizeof(TAPE_CREATE_PARTITION), NULL, 0 ); |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * EraseTape (KERNEL32.@) |
| * |
| * Erase a tape. |
| */ |
| DWORD WINAPI EraseTape( HANDLE device, DWORD type, BOOL immediate ) |
| { |
| NTSTATUS status; |
| TAPE_ERASE erase; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %d)\n", device, type, immediate ); |
| |
| erase.Type = type; |
| erase.Immediate = immediate; |
| |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_ERASE, &erase, sizeof(TAPE_ERASE), NULL, 0 ); |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * GetTapeParameters (KERNEL32.@) |
| * |
| * Retrieve information about a tape or tape drive. |
| */ |
| DWORD WINAPI GetTapeParameters( HANDLE device, DWORD operation, |
| LPDWORD size, LPVOID info ) |
| { |
| NTSTATUS status = STATUS_INVALID_PARAMETER; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %p, %p)\n", device, operation, size, info ); |
| |
| switch (operation) |
| { |
| case GET_TAPE_DRIVE_INFORMATION: |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_GET_DRIVE_PARAMS, NULL, 0, info, *size ); |
| break; |
| case GET_TAPE_MEDIA_INFORMATION: |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_GET_MEDIA_PARAMS, NULL, 0, info, *size ); |
| break; |
| default: |
| ERR( "Unhandled operation: 0x%08x\n", operation ); |
| } |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * GetTapePosition (KERNEL32.@) |
| * |
| * Retrieve the current tape position. |
| */ |
| DWORD WINAPI GetTapePosition( HANDLE device, DWORD type, LPDWORD partition, |
| LPDWORD offset_low, LPDWORD offset_high ) |
| { |
| NTSTATUS status; |
| TAPE_GET_POSITION in, out; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %p, %p, %p)\n", device, type, partition, offset_low, |
| offset_high ); |
| |
| memset( &in, 0, sizeof(TAPE_GET_POSITION) ); |
| in.Type = type; |
| |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_GET_POSITION, &in, sizeof(TAPE_GET_POSITION), |
| &out, sizeof(TAPE_GET_POSITION) ); |
| |
| if (status != STATUS_SUCCESS) |
| return set_error_from_status( status ); |
| |
| *partition = out.Partition; |
| *offset_low = out.OffsetLow; |
| *offset_high = out.OffsetHigh; |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * GetTapeStatus (KERNEL32.@) |
| * |
| * Determine if the tape device is ready for operation. |
| */ |
| DWORD WINAPI GetTapeStatus( HANDLE device ) |
| { |
| NTSTATUS status; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p)\n", device ); |
| |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_GET_STATUS, NULL, 0, NULL, 0 ); |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * PrepareTape (KERNEL32.@) |
| * |
| * Prepare a tape for operation. |
| */ |
| DWORD WINAPI PrepareTape( HANDLE device, DWORD operation, BOOL immediate ) |
| { |
| NTSTATUS status; |
| TAPE_PREPARE prep; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %d)\n", device, operation, immediate ); |
| |
| prep.Operation = operation; |
| prep.Immediate = immediate; |
| |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_PREPARE, &prep, sizeof(TAPE_PREPARE), NULL, 0 ); |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * SetTapeParameters (KERNEL32.@) |
| * |
| * Configure a tape or tape device. |
| */ |
| DWORD WINAPI SetTapeParameters( HANDLE device, DWORD operation, LPVOID info ) |
| { |
| NTSTATUS status = STATUS_INVALID_PARAMETER; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %p)\n", device, operation, info ); |
| |
| switch (operation) |
| { |
| case SET_TAPE_DRIVE_INFORMATION: |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_SET_DRIVE_PARAMS, info, sizeof(TAPE_SET_DRIVE_PARAMETERS), |
| NULL, 0 ); |
| break; |
| case SET_TAPE_MEDIA_INFORMATION: |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_SET_MEDIA_PARAMS, info, sizeof(TAPE_SET_MEDIA_PARAMETERS), |
| NULL, 0 ); |
| break; |
| default: |
| ERR( "Unhandled operation: 0x%08x\n", operation ); |
| } |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * SetTapePosition (KERNEL32.@) |
| * |
| * Set the tape position on a given device. |
| */ |
| DWORD WINAPI SetTapePosition( HANDLE device, DWORD method, DWORD partition, |
| DWORD offset_low, DWORD offset_high, BOOL immediate ) |
| { |
| NTSTATUS status; |
| TAPE_SET_POSITION pos; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %d, %d, %d, %d)\n", device, method, partition, |
| offset_low, offset_high, immediate ); |
| |
| pos.Method = method; |
| pos.Partition = partition; |
| pos.Offset.u.LowPart = offset_low; |
| pos.Offset.u.HighPart = offset_high; |
| pos.Immediate = immediate; |
| |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_SET_POSITION, &pos, sizeof(TAPE_SET_POSITION), NULL, 0 ); |
| |
| return set_error_from_status( status ); |
| } |
| |
| |
| /************************************************************************ |
| * WriteTapemark (KERNEL32.@) |
| * |
| * Write tapemarks on a tape. |
| */ |
| DWORD WINAPI WriteTapemark( HANDLE device, DWORD type, DWORD count, |
| BOOL immediate ) |
| { |
| NTSTATUS status; |
| TAPE_WRITE_MARKS marks; |
| IO_STATUS_BLOCK io; |
| |
| TRACE( "(%p, %d, %d, %d)\n", device, type, count, immediate ); |
| |
| marks.Type = type; |
| marks.Count = count; |
| marks.Immediate = immediate; |
| |
| status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io, |
| IOCTL_TAPE_WRITE_MARKS, &marks, sizeof(TAPE_WRITE_MARKS), NULL, 0 ); |
| |
| return set_error_from_status( status ); |
| } |