tape.c 9.11 KB
Newer Older
1 2 3 4 5
/*
 * Tape handling functions
 *
 * Copyright 1999 Chris Morgan <cmorgan@wpi.edu>
 *                James Abbatiello <abbeyj@wpi.edu>
6
 * Copyright 2006 Hans Leidekker 
7
 *
8 9 10 11 12 13 14 15 16 17 18 19
 * 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
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 22
 */

23 24
#include <stdarg.h>

25 26
#include "ntstatus.h"
#define WIN32_NO_STATUS
27
#include "windef.h"
28
#include "winternl.h"
29 30
#include "winbase.h"
#include "winerror.h"
31 32 33
#include "winioctl.h"
#include "ddk/ntddtape.h"

34
#include "wine/debug.h"
35

36
WINE_DEFAULT_DEBUG_CHANNEL(tape);
37

38 39 40 41 42 43 44
static DWORD set_error_from_status( NTSTATUS status )
{
    DWORD error = RtlNtStatusToDosError( status );

    SetLastError( error );
    return error;
}
45 46

/************************************************************************
47
 *		BackupRead  (KERNEL32.@)
48 49
 *
 * Backup a file or directory.
50
 */
51 52
BOOL WINAPI BackupRead( HANDLE file, LPBYTE buffer, DWORD to_read,
    LPDWORD read, BOOL abort, BOOL security, LPVOID *context )
53
{
54
    FIXME( "(%p, %p, %d, %p, %d, %d, %p)\n", file, buffer,
55 56 57
           to_read, read, abort, security, context );
    SetLastError( ERROR_NOT_SUPPORTED );
    return FALSE;
58 59 60 61
}


/************************************************************************
62
 *		BackupSeek  (KERNEL32.@)
63 64
 *
 * Seek forward in a backup stream.
65
 */
66 67
BOOL WINAPI BackupSeek( HANDLE file, DWORD seek_low, DWORD seek_high,
    LPDWORD seeked_low, LPDWORD seeked_high, LPVOID *context )
68
{
69
    FIXME( "(%p, %d, %d, %p, %p, %p)\n", file, seek_low,
70 71 72
           seek_high, seeked_low, seeked_high, context );
    SetLastError( ERROR_NOT_SUPPORTED );
    return FALSE;
73
}
74 75 76


/************************************************************************
77
 *		BackupWrite  (KERNEL32.@)
78 79
 *
 * Restore a file or directory.
80
 */
81 82
BOOL WINAPI BackupWrite( HANDLE file, LPBYTE buffer, DWORD to_write,
    LPDWORD written, BOOL abort, BOOL security, LPVOID *context )
83
{
84
    FIXME( "(%p, %p, %d, %p, %d, %d, %p)\n", file, buffer,
85 86 87
           to_write, written, abort, security, context );
    SetLastError( ERROR_NOT_SUPPORTED );
    return FALSE;
88 89 90 91
}


/************************************************************************
92
 *		CreateTapePartition  (KERNEL32.@)
93 94
 *
 * Format a tape.
95
 */
96 97
DWORD WINAPI CreateTapePartition( HANDLE device, DWORD method,
    DWORD count, DWORD size )
98
{
99 100 101 102
    NTSTATUS status;
    TAPE_CREATE_PARTITION part;
    IO_STATUS_BLOCK io;

103
    TRACE( "(%p, %d, %d, %d)\n", device, method, count, size );
104

105 106 107
    part.Method = method;
    part.Count = count;
    part.Size = size;
108

109 110 111 112
    status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io,
        IOCTL_TAPE_CREATE_PARTITION, &part, sizeof(TAPE_CREATE_PARTITION), NULL, 0 );

    return set_error_from_status( status );
113 114 115 116
}


/************************************************************************
117
 *		EraseTape  (KERNEL32.@)
118 119
 *
 * Erase a tape.
120
 */
121
DWORD WINAPI EraseTape( HANDLE device, DWORD type, BOOL immediate )
122
{
123 124 125 126
    NTSTATUS status;
    TAPE_ERASE erase;
    IO_STATUS_BLOCK io;

127
    TRACE( "(%p, %d, %d)\n", device, type, immediate );
128

129 130 131 132 133
    erase.Type = type;
    erase.Immediate = immediate;
            
    status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io,
        IOCTL_TAPE_ERASE, &erase, sizeof(TAPE_ERASE), NULL, 0 );
134

135
    return set_error_from_status( status );
136 137 138 139
}


/************************************************************************
140
 *		GetTapeParameters  (KERNEL32.@)
141 142
 *
 * Retrieve information about a tape or tape drive.
143
 */
144 145
DWORD WINAPI GetTapeParameters( HANDLE device, DWORD operation,
    LPDWORD size, LPVOID info )
146
{
147 148 149
    NTSTATUS status = STATUS_INVALID_PARAMETER;
    IO_STATUS_BLOCK io;

150
    TRACE( "(%p, %d, %p, %p)\n", device, operation, size, info );
151 152 153 154 155 156 157 158 159 160 161 162

    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:
163
        ERR( "Unhandled operation: 0x%08x\n", operation );
164 165 166
    }

    return set_error_from_status( status );
167 168 169 170
}


/************************************************************************
171
 *		GetTapePosition  (KERNEL32.@)
172 173
 *
 *	Retrieve the current tape position.
174
 */
175 176
DWORD WINAPI GetTapePosition( HANDLE device, DWORD type, LPDWORD partition,
    LPDWORD offset_low, LPDWORD offset_high )
177
{
178 179 180 181
    NTSTATUS status;
    TAPE_GET_POSITION in, out;
    IO_STATUS_BLOCK io;

182
    TRACE( "(%p, %d, %p, %p, %p)\n", device, type, partition, offset_low,
183 184 185 186 187 188 189 190
           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) );
191

192 193
    if (status != STATUS_SUCCESS)
        return set_error_from_status( status );
194

195 196 197 198 199
    *partition = out.Partition;
    *offset_low = out.OffsetLow;
    *offset_high = out.OffsetHigh;

    return set_error_from_status( status );
200 201 202 203
}


/************************************************************************
204
 *		GetTapeStatus  (KERNEL32.@)
205 206
 *
 * Determine if the tape device is ready for operation.
207
 */
208
DWORD WINAPI GetTapeStatus( HANDLE device )
209
{
210 211 212 213
    NTSTATUS status;
    IO_STATUS_BLOCK io;

    TRACE( "(%p)\n", device );
214

215 216
    status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io,
        IOCTL_TAPE_GET_STATUS, NULL, 0, NULL, 0 );
217

218
    return set_error_from_status( status );
219 220 221 222
}


/************************************************************************
223
 *		PrepareTape  (KERNEL32.@)
224 225
 *
 * Prepare a tape for operation.
226
 */
227
DWORD WINAPI PrepareTape( HANDLE device, DWORD operation, BOOL immediate )
228
{
229 230 231 232
    NTSTATUS status;
    TAPE_PREPARE prep;
    IO_STATUS_BLOCK io;

233
    TRACE( "(%p, %d, %d)\n", device, operation, immediate );
234

235 236
    prep.Operation = operation;
    prep.Immediate = immediate;
237

238 239 240 241
    status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io,
        IOCTL_TAPE_PREPARE, &prep, sizeof(TAPE_PREPARE), NULL, 0 );

    return set_error_from_status( status );
242 243 244 245
}


/************************************************************************
246
 *		SetTapeParameters  (KERNEL32.@)
247 248
 *
 * Configure a tape or tape device.
249
 */
250
DWORD WINAPI SetTapeParameters( HANDLE device, DWORD operation, LPVOID info )
251
{
252 253 254
    NTSTATUS status = STATUS_INVALID_PARAMETER;
    IO_STATUS_BLOCK io;

255
    TRACE( "(%p, %d, %p)\n", device, operation, info );
256 257 258 259 260 261 262 263 264 265 266 267 268 269

    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:
270
        ERR( "Unhandled operation: 0x%08x\n", operation );
271 272 273
    }

    return set_error_from_status( status );
274 275 276 277
}


/************************************************************************
278
 *		SetTapePosition  (KERNEL32.@)
279 280
 *
 * Set the tape position on a given device.
281
 */
282 283
DWORD WINAPI SetTapePosition( HANDLE device, DWORD method, DWORD partition,
    DWORD offset_low, DWORD offset_high, BOOL immediate )
284
{
285 286 287
    NTSTATUS status;
    TAPE_SET_POSITION pos;
    IO_STATUS_BLOCK io;
288

289
    TRACE( "(%p, %d, %d, %d, %d, %d)\n", device, method, partition,
290
           offset_low, offset_high, immediate );
291

292 293 294 295 296 297 298 299 300 301
    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 );
302 303 304 305
}


/************************************************************************
306
 *		WriteTapemark  (KERNEL32.@)
307 308
 *
 * Write tapemarks on a tape.
309
 */
310 311
DWORD WINAPI WriteTapemark( HANDLE device, DWORD type, DWORD count,
    BOOL immediate )
312
{
313 314 315 316
    NTSTATUS status;
    TAPE_WRITE_MARKS marks;
    IO_STATUS_BLOCK io;

317
    TRACE( "(%p, %d, %d, %d)\n", device, type, count, immediate );
318 319 320 321

    marks.Type = type;
    marks.Count = count;
    marks.Immediate = immediate;
322

323 324
    status = NtDeviceIoControlFile( device, NULL, NULL, NULL, &io,
        IOCTL_TAPE_WRITE_MARKS, &marks, sizeof(TAPE_WRITE_MARKS), NULL, 0 );
325

326
    return set_error_from_status( status );
327
}