| /* | |
| * 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 ); | |
| } |