kernel: Remove bogus breaks in tape.c
[wine/wine64.git] / dlls / ntdll / tape.c
blob99258325c922c1813949d6e92c5e884db6da4dfd
1 /*
2 * TAPE support
4 * Copyright 2006 Hans Leidekker
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
25 #include <stdio.h>
26 #ifdef HAVE_SYS_IOCTL_H
27 #include <sys/ioctl.h>
28 #endif
29 #ifdef HAVE_SYS_MTIO_H
30 #include <sys/mtio.h>
31 #endif
33 #define NONAMELESSUNION
34 #define NONAMELESSSTRUCT
35 #include "ntstatus.h"
36 #define WIN32_NO_STATUS
37 #include "windef.h"
38 #include "winternl.h"
39 #include "winioctl.h"
40 #include "ddk/ntddtape.h"
41 #include "ntdll_misc.h"
42 #include "wine/server.h"
43 #include "wine/debug.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(tape);
47 static const char *io2str( DWORD io )
49 switch (io)
51 #define X(x) case (x): return #x;
52 X(IOCTL_TAPE_CHECK_VERIFY);
53 X(IOCTL_TAPE_CREATE_PARTITION);
54 X(IOCTL_TAPE_ERASE);
55 X(IOCTL_TAPE_FIND_NEW_DEVICES);
56 X(IOCTL_TAPE_GET_DRIVE_PARAMS);
57 X(IOCTL_TAPE_GET_MEDIA_PARAMS);
58 X(IOCTL_TAPE_GET_POSITION);
59 X(IOCTL_TAPE_GET_STATUS);
60 X(IOCTL_TAPE_PREPARE);
61 X(IOCTL_TAPE_SET_DRIVE_PARAMS);
62 X(IOCTL_TAPE_SET_MEDIA_PARAMS);
63 X(IOCTL_TAPE_SET_POSITION);
64 X(IOCTL_TAPE_WRITE_MARKS);
65 #undef X
66 default: { static char tmp[32]; sprintf(tmp, "IOCTL_TAPE_%ld\n", io); return tmp; }
70 /******************************************************************
71 * TAPE_GetStatus
73 static NTSTATUS TAPE_GetStatus( int error )
75 if (!error) return STATUS_SUCCESS;
76 return FILE_GetNtStatus();
79 /******************************************************************
80 * TAPE_CreatePartition
82 static NTSTATUS TAPE_CreatePartition( int fd, TAPE_CREATE_PARTITION *data )
84 #ifdef HAVE_SYS_MTIO_H
85 struct mtop cmd;
87 TRACE( "fd: %d method: 0x%08lx count: 0x%08lx size: 0x%08lx\n",
88 fd, data->Method, data->Count, data->Size );
90 if (data->Count > 1)
92 WARN( "Creating more than 1 partition is not supported\n" );
93 return STATUS_INVALID_PARAMETER;
96 switch (data->Method)
98 case TAPE_FIXED_PARTITIONS:
99 case TAPE_SELECT_PARTITIONS:
100 cmd.mt_op = MTMKPART;
101 cmd.mt_count = 0;
102 break;
103 case TAPE_INITIATOR_PARTITIONS:
104 cmd.mt_op = MTMKPART;
105 cmd.mt_count = data->Size;
106 break;
107 default:
108 ERR( "Unhandled method: 0x%08lx\n", data->Method );
109 return STATUS_INVALID_PARAMETER;
112 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
113 #else
114 FIXME( "Not implemented.\n" );
115 return STATUS_NOT_SUPPORTED;
116 #endif
119 /******************************************************************
120 * TAPE_Erase
122 static NTSTATUS TAPE_Erase( int fd, TAPE_ERASE *data )
124 #ifdef HAVE_SYS_MTIO_H
125 struct mtop cmd;
127 TRACE( "fd: %d type: 0x%08lx immediate: 0x%02x\n",
128 fd, data->Type, data->Immediate );
130 switch (data->Type)
132 case TAPE_ERASE_LONG:
133 cmd.mt_op = MTERASE;
134 cmd.mt_count = 1;
135 break;
136 case TAPE_ERASE_SHORT:
137 cmd.mt_op = MTERASE;
138 cmd.mt_count = 0;
139 break;
140 default:
141 ERR( "Unhandled type: 0x%08lx\n", data->Type );
142 return STATUS_INVALID_PARAMETER;
145 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
146 #else
147 FIXME( "Not implemented.\n" );
148 return STATUS_NOT_SUPPORTED;
149 #endif
152 /******************************************************************
153 * TAPE_GetDriveParams
155 static NTSTATUS TAPE_GetDriveParams( int fd, TAPE_GET_DRIVE_PARAMETERS *data )
157 #ifdef HAVE_SYS_MTIO_H
158 struct mtget get;
159 NTSTATUS status;
161 TRACE( "fd: %d\n", fd );
163 memset( data, 0, sizeof(TAPE_GET_DRIVE_PARAMETERS) );
165 status = TAPE_GetStatus( ioctl( fd, MTIOCGET, &get ) );
166 if (status != STATUS_SUCCESS)
167 return status;
169 data->ECC = FALSE;
170 data->Compression = FALSE;
171 data->DataPadding = FALSE;
172 data->ReportSetmarks = FALSE;
173 data->DefaultBlockSize = get.mt_dsreg & MT_ST_BLKSIZE_MASK;
174 data->MaximumBlockSize = data->DefaultBlockSize;
175 data->MinimumBlockSize = data->DefaultBlockSize;
176 data->MaximumPartitionCount = 1;
178 return status;
179 #else
180 FIXME( "Not implemented.\n" );
181 return STATUS_NOT_SUPPORTED;
182 #endif
185 /******************************************************************
186 * TAPE_GetMediaParams
188 static NTSTATUS TAPE_GetMediaParams( int fd, TAPE_GET_MEDIA_PARAMETERS *data )
190 #ifdef HAVE_SYS_MTIO_H
191 struct mtget get;
192 NTSTATUS status;
194 TRACE( "fd: %d\n", fd );
196 memset( data, 0, sizeof(TAPE_GET_MEDIA_PARAMETERS) );
198 status = TAPE_GetStatus( ioctl( fd, MTIOCGET, &get ) );
199 if (status != STATUS_SUCCESS)
200 return status;
202 data->Capacity.u.LowPart = 1024 * 1024 * 1024;
203 data->Remaining.u.LowPart = 1024 * 1024 * 1024;
204 data->BlockSize = get.mt_dsreg & MT_ST_BLKSIZE_MASK;
205 data->PartitionCount = 1;
206 data->WriteProtected = GMT_WR_PROT(get.mt_gstat);
208 return status;
209 #else
210 FIXME( "Not implemented.\n" );
211 return STATUS_NOT_SUPPORTED;
212 #endif
215 /******************************************************************
216 * TAPE_GetPosition
218 static NTSTATUS TAPE_GetPosition( int fd, ULONG type, TAPE_GET_POSITION *data )
220 #ifdef HAVE_SYS_MTIO_H
221 struct mtget get;
222 struct mtpos pos;
223 NTSTATUS status;
225 TRACE( "fd: %d type: 0x%08lx\n", fd, type );
227 memset( data, 0, sizeof(TAPE_GET_POSITION) );
229 status = TAPE_GetStatus( ioctl( fd, MTIOCGET, &get ) );
230 if (status != STATUS_SUCCESS)
231 return status;
233 status = TAPE_GetStatus( ioctl( fd, MTIOCPOS, &pos ) );
234 if (status != STATUS_SUCCESS)
235 return status;
237 switch (type)
239 case TAPE_ABSOLUTE_BLOCK:
240 data->Type = type;
241 data->Partition = get.mt_resid;
242 data->OffsetLow = pos.mt_blkno;
243 case TAPE_LOGICAL_BLOCK:
244 case TAPE_PSEUDO_LOGICAL_BLOCK:
245 WARN( "Positioning type not supported\n" );
246 break;
247 default:
248 ERR( "Unhandled type: 0x%08lx\n", type );
249 return STATUS_INVALID_PARAMETER;
252 return status;
253 #else
254 FIXME( "Not implemented.\n" );
255 return STATUS_NOT_SUPPORTED;
256 #endif
259 /******************************************************************
260 * TAPE_Prepare
262 static NTSTATUS TAPE_Prepare( int fd, TAPE_PREPARE *data )
264 #ifdef HAVE_SYS_MTIO_H
265 struct mtop cmd;
267 TRACE( "fd: %d type: 0x%08lx immediate: 0x%02x\n",
268 fd, data->Operation, data->Immediate );
270 switch (data->Operation)
272 case TAPE_LOAD:
273 cmd.mt_op = MTLOAD;
274 break;
275 case TAPE_UNLOAD:
276 cmd.mt_op = MTUNLOAD;
277 break;
278 case TAPE_TENSION:
279 cmd.mt_op = MTRETEN;
280 break;
281 case TAPE_LOCK:
282 cmd.mt_op = MTLOCK;
283 break;
284 case TAPE_UNLOCK:
285 cmd.mt_op = MTUNLOCK;
286 break;
287 case TAPE_FORMAT:
288 /* Native ignores this if the drive doesn't support it */
289 return STATUS_SUCCESS;
290 default:
291 ERR( "Unhandled operation: 0x%08lx\n", data->Operation );
292 return STATUS_INVALID_PARAMETER;
295 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
296 #else
297 FIXME( "Not implemented.\n" );
298 return STATUS_NOT_SUPPORTED;
299 #endif
302 /******************************************************************
303 * TAPE_SetDriveParams
305 static NTSTATUS TAPE_SetDriveParams( int fd, TAPE_SET_DRIVE_PARAMETERS *data )
307 #ifdef HAVE_SYS_MTIO_H
308 struct mtop cmd;
310 TRACE( "fd: %d ECC: 0x%02x, compression: 0x%02x padding: 0x%02x\n",
311 fd, data->ECC, data->Compression, data->DataPadding );
312 TRACE( "setmarks: 0x%02x zonesize: 0x%08lx\n",
313 data->ReportSetmarks, data->EOTWarningZoneSize );
315 if (data->ECC || data->DataPadding || data->ReportSetmarks ||
316 data->EOTWarningZoneSize ) WARN( "Setting not supported\n" );
318 cmd.mt_op = MTCOMPRESSION;
319 cmd.mt_count = data->Compression;
321 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
322 #else
323 FIXME( "Not implemented.\n" );
324 return STATUS_NOT_SUPPORTED;
325 #endif
328 /******************************************************************
329 * TAPE_SetMediaParams
331 static NTSTATUS TAPE_SetMediaParams( int fd, TAPE_SET_MEDIA_PARAMETERS *data )
333 #ifdef HAVE_SYS_MTIO_H
334 struct mtop cmd;
336 TRACE( "fd: %d blocksize: 0x%08lx\n", fd, data->BlockSize );
338 cmd.mt_op = MTSETBLK;
339 cmd.mt_count = data->BlockSize;
341 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
342 #else
343 FIXME( "Not implemented.\n" );
344 return STATUS_NOT_SUPPORTED;
345 #endif
348 /******************************************************************
349 * TAPE_SetPosition
351 static NTSTATUS TAPE_SetPosition( int fd, TAPE_SET_POSITION *data )
353 #ifdef HAVE_SYS_MTIO_H
354 struct mtop cmd;
356 TRACE( "fd: %d method: 0x%08lx partition: 0x%08lx offset: 0x%08lx immediate: 0x%02x\n",
357 fd, data->Method, data->Partition, data->Offset.u.LowPart, data->Immediate );
359 if (data->Offset.u.HighPart > 0)
360 return STATUS_INVALID_PARAMETER;
362 switch (data->Method)
364 case TAPE_REWIND:
365 cmd.mt_op = MTREW;
366 break;
367 case TAPE_ABSOLUTE_BLOCK:
368 cmd.mt_op = MTSEEK;
369 cmd.mt_count = data->Offset.u.LowPart;
370 break;
371 case TAPE_SPACE_END_OF_DATA:
372 cmd.mt_op = MTEOM;
373 break;
374 case TAPE_SPACE_FILEMARKS:
375 if (data->Offset.u.LowPart >= 0) {
376 cmd.mt_op = MTFSF;
377 cmd.mt_count = data->Offset.u.LowPart;
379 else {
380 cmd.mt_op = MTBSF;
381 cmd.mt_count = -data->Offset.u.LowPart;
383 case TAPE_SPACE_SETMARKS:
384 if (data->Offset.u.LowPart >= 0) {
385 cmd.mt_op = MTFSS;
386 cmd.mt_count = data->Offset.u.LowPart;
388 else {
389 cmd.mt_op = MTBSS;
390 cmd.mt_count = -data->Offset.u.LowPart;
392 case TAPE_LOGICAL_BLOCK:
393 case TAPE_PSEUDO_LOGICAL_BLOCK:
394 case TAPE_SPACE_RELATIVE_BLOCKS:
395 case TAPE_SPACE_SEQUENTIAL_FMKS:
396 case TAPE_SPACE_SEQUENTIAL_SMKS:
397 WARN( "Positioning method not supported\n" );
398 return STATUS_INVALID_PARAMETER;
399 default:
400 ERR( "Unhandled method: 0x%08lx\n", data->Method );
401 return STATUS_INVALID_PARAMETER;
404 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
405 #else
406 FIXME( "Not implemented.\n" );
407 return STATUS_NOT_SUPPORTED;
408 #endif
411 /******************************************************************
412 * TAPE_WriteMarks
414 static NTSTATUS TAPE_WriteMarks( int fd, TAPE_WRITE_MARKS *data )
416 #ifdef HAVE_SYS_MTIO_H
417 struct mtop cmd;
419 TRACE( "fd: %d type: 0x%08lx count: 0x%08lx immediate: 0x%02x\n",
420 fd, data->Type, data->Count, data->Immediate );
422 switch (data->Type)
424 case TAPE_SETMARKS:
425 cmd.mt_op = MTWSM;
426 cmd.mt_count = data->Count;
427 break;
428 case TAPE_FILEMARKS:
429 case TAPE_SHORT_FILEMARKS:
430 case TAPE_LONG_FILEMARKS:
431 cmd.mt_op = MTWEOF;
432 cmd.mt_count = data->Count;
433 break;
434 default:
435 ERR( "Unhandled type: 0x%08lx\n", data->Type );
436 return STATUS_INVALID_PARAMETER;
439 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
440 #else
441 FIXME( "Not implemented.\n" );
442 return STATUS_NOT_SUPPORTED;
443 #endif
446 /******************************************************************
447 * TAPE_DeviceIoControl
449 * SEE ALSO
450 * NtDeviceIoControl.
452 NTSTATUS TAPE_DeviceIoControl( HANDLE device, HANDLE event,
453 PIO_APC_ROUTINE apc, PVOID apc_user, PIO_STATUS_BLOCK io_status,
454 ULONG io_control, LPVOID in_buffer, DWORD in_size,
455 LPVOID out_buffer, DWORD out_size )
457 DWORD sz = 0;
458 NTSTATUS status = STATUS_INVALID_PARAMETER;
459 int fd;
461 TRACE( "%p %s %p %ld %p %ld %p\n", device, io2str(io_control),
462 in_buffer, in_size, out_buffer, out_size, io_status );
464 io_status->Information = 0;
466 if ((status = wine_server_handle_to_fd( device, 0, &fd, NULL )))
467 goto error;
469 switch (io_control)
471 case IOCTL_TAPE_CREATE_PARTITION:
472 status = TAPE_CreatePartition( fd, (TAPE_CREATE_PARTITION *)in_buffer );
473 break;
474 case IOCTL_TAPE_ERASE:
475 status = TAPE_Erase( fd, (TAPE_ERASE *)in_buffer );
476 break;
477 case IOCTL_TAPE_GET_DRIVE_PARAMS:
478 status = TAPE_GetDriveParams( fd, (TAPE_GET_DRIVE_PARAMETERS *)out_buffer );
479 break;
480 case IOCTL_TAPE_GET_MEDIA_PARAMS:
481 status = TAPE_GetMediaParams( fd, (TAPE_GET_MEDIA_PARAMETERS *)out_buffer );
482 break;
483 case IOCTL_TAPE_GET_POSITION:
484 status = TAPE_GetPosition( fd, ((TAPE_GET_POSITION *)in_buffer)->Type,
485 (TAPE_GET_POSITION *)out_buffer );
486 break;
487 case IOCTL_TAPE_GET_STATUS:
488 status = FILE_GetNtStatus();
489 break;
490 case IOCTL_TAPE_PREPARE:
491 status = TAPE_Prepare( fd, (TAPE_PREPARE *)in_buffer );
492 break;
493 case IOCTL_TAPE_SET_DRIVE_PARAMS:
494 status = TAPE_SetDriveParams( fd, (TAPE_SET_DRIVE_PARAMETERS *)in_buffer );
495 break;
496 case IOCTL_TAPE_SET_MEDIA_PARAMS:
497 status = TAPE_SetMediaParams( fd, (TAPE_SET_MEDIA_PARAMETERS *)in_buffer );
498 break;
499 case IOCTL_TAPE_SET_POSITION:
500 status = TAPE_SetPosition( fd, (TAPE_SET_POSITION *)in_buffer );
501 break;
502 case IOCTL_TAPE_WRITE_MARKS:
503 status = TAPE_WriteMarks( fd, (TAPE_WRITE_MARKS *)in_buffer );
504 break;
506 case IOCTL_TAPE_CHECK_VERIFY:
507 case IOCTL_TAPE_FIND_NEW_DEVICES:
508 break;
509 default:
510 FIXME( "Unsupported IOCTL %lx (type=%lx access=%lx func=%lx meth=%lx)\n",
511 io_control, io_control >> 16, (io_control >> 14) & 3,
512 (io_control >> 2) & 0xfff, io_control & 3 );
513 break;
516 wine_server_release_fd( device, fd );
518 error:
519 io_status->u.Status = status;
520 io_status->Information = sz;
521 if (event) NtSetEvent( event, NULL );
522 return status;