rsaenh/tests: import & export of a plaintext public key + algID check.
[wine/multimedia.git] / dlls / ntdll / tape.c
blob01cf7970d8f692cb0e71ae660530f30e7ffb6892
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 #if !defined(MTCOMPRESSION) && defined(MTCOMP)
34 #define MTCOMPRESSION MTCOMP
35 #endif
36 #if !defined(MTSETBLK) && defined(MTSETBSIZ)
37 #define MTSETBLK MTSETBSIZ
38 #endif
39 #if !defined(MTSETBLK) && defined(MTSRSZ)
40 #define MTSETBLK MTSRSZ
41 #endif
42 #ifndef MT_ST_BLKSIZE_MASK
43 #define MT_ST_BLKSIZE_MASK 0xffffff
44 #endif
46 #define NONAMELESSUNION
47 #define NONAMELESSSTRUCT
48 #include "ntstatus.h"
49 #define WIN32_NO_STATUS
50 #include "windef.h"
51 #include "winternl.h"
52 #include "winioctl.h"
53 #include "ddk/ntddtape.h"
54 #include "ntdll_misc.h"
55 #include "wine/server.h"
56 #include "wine/debug.h"
58 WINE_DEFAULT_DEBUG_CHANNEL(tape);
60 static const char *io2str( DWORD io )
62 switch (io)
64 #define X(x) case (x): return #x;
65 X(IOCTL_TAPE_CHECK_VERIFY);
66 X(IOCTL_TAPE_CREATE_PARTITION);
67 X(IOCTL_TAPE_ERASE);
68 X(IOCTL_TAPE_FIND_NEW_DEVICES);
69 X(IOCTL_TAPE_GET_DRIVE_PARAMS);
70 X(IOCTL_TAPE_GET_MEDIA_PARAMS);
71 X(IOCTL_TAPE_GET_POSITION);
72 X(IOCTL_TAPE_GET_STATUS);
73 X(IOCTL_TAPE_PREPARE);
74 X(IOCTL_TAPE_SET_DRIVE_PARAMS);
75 X(IOCTL_TAPE_SET_MEDIA_PARAMS);
76 X(IOCTL_TAPE_SET_POSITION);
77 X(IOCTL_TAPE_WRITE_MARKS);
78 #undef X
79 default: { static char tmp[32]; sprintf(tmp, "IOCTL_TAPE_%ld\n", io); return tmp; }
83 /******************************************************************
84 * TAPE_GetStatus
86 static NTSTATUS TAPE_GetStatus( int error )
88 if (!error) return STATUS_SUCCESS;
89 return FILE_GetNtStatus();
92 /******************************************************************
93 * TAPE_CreatePartition
95 static NTSTATUS TAPE_CreatePartition( int fd, TAPE_CREATE_PARTITION *data )
97 #ifdef HAVE_SYS_MTIO_H
98 struct mtop cmd;
100 TRACE( "fd: %d method: 0x%08lx count: 0x%08lx size: 0x%08lx\n",
101 fd, data->Method, data->Count, data->Size );
103 if (data->Count > 1)
105 WARN( "Creating more than 1 partition is not supported\n" );
106 return STATUS_INVALID_PARAMETER;
109 switch (data->Method)
111 #ifdef MTMKPART
112 case TAPE_FIXED_PARTITIONS:
113 case TAPE_SELECT_PARTITIONS:
114 cmd.mt_op = MTMKPART;
115 cmd.mt_count = 0;
116 break;
117 case TAPE_INITIATOR_PARTITIONS:
118 cmd.mt_op = MTMKPART;
119 cmd.mt_count = data->Size;
120 break;
121 #endif
122 default:
123 ERR( "Unhandled method: 0x%08lx\n", data->Method );
124 return STATUS_INVALID_PARAMETER;
127 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
128 #else
129 FIXME( "Not implemented.\n" );
130 return STATUS_NOT_SUPPORTED;
131 #endif
134 /******************************************************************
135 * TAPE_Erase
137 static NTSTATUS TAPE_Erase( int fd, TAPE_ERASE *data )
139 #ifdef HAVE_SYS_MTIO_H
140 struct mtop cmd;
142 TRACE( "fd: %d type: 0x%08lx immediate: 0x%02x\n",
143 fd, data->Type, data->Immediate );
145 switch (data->Type)
147 case TAPE_ERASE_LONG:
148 cmd.mt_op = MTERASE;
149 cmd.mt_count = 1;
150 break;
151 case TAPE_ERASE_SHORT:
152 cmd.mt_op = MTERASE;
153 cmd.mt_count = 0;
154 break;
155 default:
156 ERR( "Unhandled type: 0x%08lx\n", data->Type );
157 return STATUS_INVALID_PARAMETER;
160 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
161 #else
162 FIXME( "Not implemented.\n" );
163 return STATUS_NOT_SUPPORTED;
164 #endif
167 /******************************************************************
168 * TAPE_GetDriveParams
170 static NTSTATUS TAPE_GetDriveParams( int fd, TAPE_GET_DRIVE_PARAMETERS *data )
172 #ifdef HAVE_SYS_MTIO_H
173 struct mtget get;
174 NTSTATUS status;
176 TRACE( "fd: %d\n", fd );
178 memset( data, 0, sizeof(TAPE_GET_DRIVE_PARAMETERS) );
180 status = TAPE_GetStatus( ioctl( fd, MTIOCGET, &get ) );
181 if (status != STATUS_SUCCESS)
182 return status;
184 data->ECC = FALSE;
185 data->Compression = FALSE;
186 data->DataPadding = FALSE;
187 data->ReportSetmarks = FALSE;
188 #ifdef HAVE_STRUCT_MTGET_MT_BLKSIZ
189 data->DefaultBlockSize = get.mt_blksiz;
190 #else
191 data->DefaultBlockSize = get.mt_dsreg & MT_ST_BLKSIZE_MASK;
192 #endif
193 data->MaximumBlockSize = data->DefaultBlockSize;
194 data->MinimumBlockSize = data->DefaultBlockSize;
195 data->MaximumPartitionCount = 1;
197 return status;
198 #else
199 FIXME( "Not implemented.\n" );
200 return STATUS_NOT_SUPPORTED;
201 #endif
204 /******************************************************************
205 * TAPE_GetMediaParams
207 static NTSTATUS TAPE_GetMediaParams( int fd, TAPE_GET_MEDIA_PARAMETERS *data )
209 #ifdef HAVE_SYS_MTIO_H
210 struct mtget get;
211 NTSTATUS status;
213 TRACE( "fd: %d\n", fd );
215 memset( data, 0, sizeof(TAPE_GET_MEDIA_PARAMETERS) );
217 status = TAPE_GetStatus( ioctl( fd, MTIOCGET, &get ) );
218 if (status != STATUS_SUCCESS)
219 return status;
221 data->Capacity.u.LowPart = 1024 * 1024 * 1024;
222 data->Remaining.u.LowPart = 1024 * 1024 * 1024;
223 #ifdef HAVE_STRUCT_MTGET_MT_BLKSIZ
224 data->BlockSize = get.mt_blksiz;
225 #else
226 data->BlockSize = get.mt_dsreg & MT_ST_BLKSIZE_MASK;
227 #endif
228 data->PartitionCount = 1;
229 #ifdef HAVE_STRUCT_MTGET_MT_GSTAT
230 data->WriteProtected = GMT_WR_PROT(get.mt_gstat);
231 #else
232 data->WriteProtected = 0;
233 #endif
235 return status;
236 #else
237 FIXME( "Not implemented.\n" );
238 return STATUS_NOT_SUPPORTED;
239 #endif
242 /******************************************************************
243 * TAPE_GetPosition
245 static NTSTATUS TAPE_GetPosition( int fd, ULONG type, TAPE_GET_POSITION *data )
247 #ifdef HAVE_SYS_MTIO_H
248 struct mtget get;
249 #ifndef HAVE_STRUCT_MTGET_MT_BLKNO
250 struct mtpos pos;
251 #endif
252 NTSTATUS status;
254 TRACE( "fd: %d type: 0x%08lx\n", fd, type );
256 memset( data, 0, sizeof(TAPE_GET_POSITION) );
258 status = TAPE_GetStatus( ioctl( fd, MTIOCGET, &get ) );
259 if (status != STATUS_SUCCESS)
260 return status;
262 #ifndef HAVE_STRUCT_MTGET_MT_BLKNO
263 status = TAPE_GetStatus( ioctl( fd, MTIOCPOS, &pos ) );
264 if (status != STATUS_SUCCESS)
265 return status;
266 #endif
268 switch (type)
270 case TAPE_ABSOLUTE_BLOCK:
271 data->Type = type;
272 data->Partition = get.mt_resid;
273 #ifdef HAVE_STRUCT_MTGET_MT_BLKNO
274 data->OffsetLow = get.mt_blkno;
275 #else
276 data->OffsetLow = pos.mt_blkno;
277 #endif
278 break;
279 case TAPE_LOGICAL_BLOCK:
280 case TAPE_PSEUDO_LOGICAL_BLOCK:
281 WARN( "Positioning type not supported\n" );
282 break;
283 default:
284 ERR( "Unhandled type: 0x%08lx\n", type );
285 return STATUS_INVALID_PARAMETER;
288 return status;
289 #else
290 FIXME( "Not implemented.\n" );
291 return STATUS_NOT_SUPPORTED;
292 #endif
295 /******************************************************************
296 * TAPE_Prepare
298 static NTSTATUS TAPE_Prepare( int fd, TAPE_PREPARE *data )
300 #ifdef HAVE_SYS_MTIO_H
301 struct mtop cmd;
303 TRACE( "fd: %d type: 0x%08lx immediate: 0x%02x\n",
304 fd, data->Operation, data->Immediate );
306 switch (data->Operation)
308 #ifdef MTLOAD
309 case TAPE_LOAD:
310 cmd.mt_op = MTLOAD;
311 break;
312 #endif
313 #ifdef MTUNLOAD
314 case TAPE_UNLOAD:
315 cmd.mt_op = MTUNLOAD;
316 break;
317 #endif
318 #ifdef MTRETEN
319 case TAPE_TENSION:
320 cmd.mt_op = MTRETEN;
321 break;
322 #endif
323 #ifdef MTLOCK
324 case TAPE_LOCK:
325 cmd.mt_op = MTLOCK;
326 break;
327 #endif
328 #ifdef MTUNLOCK
329 case TAPE_UNLOCK:
330 cmd.mt_op = MTUNLOCK;
331 break;
332 #endif
333 case TAPE_FORMAT:
334 /* Native ignores this if the drive doesn't support it */
335 return STATUS_SUCCESS;
336 default:
337 ERR( "Unhandled operation: 0x%08lx\n", data->Operation );
338 return STATUS_INVALID_PARAMETER;
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_SetDriveParams
351 static NTSTATUS TAPE_SetDriveParams( int fd, TAPE_SET_DRIVE_PARAMETERS *data )
353 #if defined(HAVE_SYS_MTIO_H) && defined(MTCOMPRESSION)
354 struct mtop cmd;
356 TRACE( "fd: %d ECC: 0x%02x, compression: 0x%02x padding: 0x%02x\n",
357 fd, data->ECC, data->Compression, data->DataPadding );
358 TRACE( "setmarks: 0x%02x zonesize: 0x%08lx\n",
359 data->ReportSetmarks, data->EOTWarningZoneSize );
361 if (data->ECC || data->DataPadding || data->ReportSetmarks ||
362 data->EOTWarningZoneSize ) WARN( "Setting not supported\n" );
364 cmd.mt_op = MTCOMPRESSION;
365 cmd.mt_count = data->Compression;
367 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
368 #else
369 FIXME( "Not implemented.\n" );
370 return STATUS_NOT_SUPPORTED;
371 #endif
374 /******************************************************************
375 * TAPE_SetMediaParams
377 static NTSTATUS TAPE_SetMediaParams( int fd, TAPE_SET_MEDIA_PARAMETERS *data )
379 #ifdef HAVE_SYS_MTIO_H
380 struct mtop cmd;
382 TRACE( "fd: %d blocksize: 0x%08lx\n", fd, data->BlockSize );
384 cmd.mt_op = MTSETBLK;
385 cmd.mt_count = data->BlockSize;
387 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
388 #else
389 FIXME( "Not implemented.\n" );
390 return STATUS_NOT_SUPPORTED;
391 #endif
394 /******************************************************************
395 * TAPE_SetPosition
397 static NTSTATUS TAPE_SetPosition( int fd, TAPE_SET_POSITION *data )
399 #ifdef HAVE_SYS_MTIO_H
400 struct mtop cmd;
402 TRACE( "fd: %d method: 0x%08lx partition: 0x%08lx offset: 0x%08lx immediate: 0x%02x\n",
403 fd, data->Method, data->Partition, data->Offset.u.LowPart, data->Immediate );
405 if (data->Offset.u.HighPart > 0)
406 return STATUS_INVALID_PARAMETER;
408 switch (data->Method)
410 case TAPE_REWIND:
411 cmd.mt_op = MTREW;
412 break;
413 #ifdef MTSEEK
414 case TAPE_ABSOLUTE_BLOCK:
415 cmd.mt_op = MTSEEK;
416 cmd.mt_count = data->Offset.u.LowPart;
417 break;
418 #endif
419 #ifdef MTEOM
420 case TAPE_SPACE_END_OF_DATA:
421 cmd.mt_op = MTEOM;
422 break;
423 #endif
424 case TAPE_SPACE_FILEMARKS:
425 if (data->Offset.u.LowPart >= 0) {
426 cmd.mt_op = MTFSF;
427 cmd.mt_count = data->Offset.u.LowPart;
429 else {
430 cmd.mt_op = MTBSF;
431 cmd.mt_count = -data->Offset.u.LowPart;
433 break;
434 #if defined(MTFSS) && defined(MTBSS)
435 case TAPE_SPACE_SETMARKS:
436 if (data->Offset.u.LowPart >= 0) {
437 cmd.mt_op = MTFSS;
438 cmd.mt_count = data->Offset.u.LowPart;
440 else {
441 cmd.mt_op = MTBSS;
442 cmd.mt_count = -data->Offset.u.LowPart;
444 break;
445 #endif
446 case TAPE_LOGICAL_BLOCK:
447 case TAPE_PSEUDO_LOGICAL_BLOCK:
448 case TAPE_SPACE_RELATIVE_BLOCKS:
449 case TAPE_SPACE_SEQUENTIAL_FMKS:
450 case TAPE_SPACE_SEQUENTIAL_SMKS:
451 WARN( "Positioning method not supported\n" );
452 return STATUS_INVALID_PARAMETER;
453 default:
454 ERR( "Unhandled method: 0x%08lx\n", data->Method );
455 return STATUS_INVALID_PARAMETER;
458 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
459 #else
460 FIXME( "Not implemented.\n" );
461 return STATUS_NOT_SUPPORTED;
462 #endif
465 /******************************************************************
466 * TAPE_WriteMarks
468 static NTSTATUS TAPE_WriteMarks( int fd, TAPE_WRITE_MARKS *data )
470 #ifdef HAVE_SYS_MTIO_H
471 struct mtop cmd;
473 TRACE( "fd: %d type: 0x%08lx count: 0x%08lx immediate: 0x%02x\n",
474 fd, data->Type, data->Count, data->Immediate );
476 switch (data->Type)
478 #ifdef MTWSM
479 case TAPE_SETMARKS:
480 cmd.mt_op = MTWSM;
481 cmd.mt_count = data->Count;
482 break;
483 #endif
484 case TAPE_FILEMARKS:
485 case TAPE_SHORT_FILEMARKS:
486 case TAPE_LONG_FILEMARKS:
487 cmd.mt_op = MTWEOF;
488 cmd.mt_count = data->Count;
489 break;
490 default:
491 ERR( "Unhandled type: 0x%08lx\n", data->Type );
492 return STATUS_INVALID_PARAMETER;
495 return TAPE_GetStatus( ioctl( fd, MTIOCTOP, &cmd ) );
496 #else
497 FIXME( "Not implemented.\n" );
498 return STATUS_NOT_SUPPORTED;
499 #endif
502 /******************************************************************
503 * TAPE_DeviceIoControl
505 * SEE ALSO
506 * NtDeviceIoControl.
508 NTSTATUS TAPE_DeviceIoControl( HANDLE device, HANDLE event,
509 PIO_APC_ROUTINE apc, PVOID apc_user, PIO_STATUS_BLOCK io_status,
510 ULONG io_control, LPVOID in_buffer, DWORD in_size,
511 LPVOID out_buffer, DWORD out_size )
513 DWORD sz = 0;
514 NTSTATUS status = STATUS_INVALID_PARAMETER;
515 int fd;
517 TRACE( "%p %s %p %ld %p %ld %p\n", device, io2str(io_control),
518 in_buffer, in_size, out_buffer, out_size, io_status );
520 io_status->Information = 0;
522 if ((status = wine_server_handle_to_fd( device, 0, &fd, NULL )))
523 goto error;
525 switch (io_control)
527 case IOCTL_TAPE_CREATE_PARTITION:
528 status = TAPE_CreatePartition( fd, (TAPE_CREATE_PARTITION *)in_buffer );
529 break;
530 case IOCTL_TAPE_ERASE:
531 status = TAPE_Erase( fd, (TAPE_ERASE *)in_buffer );
532 break;
533 case IOCTL_TAPE_GET_DRIVE_PARAMS:
534 status = TAPE_GetDriveParams( fd, (TAPE_GET_DRIVE_PARAMETERS *)out_buffer );
535 break;
536 case IOCTL_TAPE_GET_MEDIA_PARAMS:
537 status = TAPE_GetMediaParams( fd, (TAPE_GET_MEDIA_PARAMETERS *)out_buffer );
538 break;
539 case IOCTL_TAPE_GET_POSITION:
540 status = TAPE_GetPosition( fd, ((TAPE_GET_POSITION *)in_buffer)->Type,
541 (TAPE_GET_POSITION *)out_buffer );
542 break;
543 case IOCTL_TAPE_GET_STATUS:
544 status = FILE_GetNtStatus();
545 break;
546 case IOCTL_TAPE_PREPARE:
547 status = TAPE_Prepare( fd, (TAPE_PREPARE *)in_buffer );
548 break;
549 case IOCTL_TAPE_SET_DRIVE_PARAMS:
550 status = TAPE_SetDriveParams( fd, (TAPE_SET_DRIVE_PARAMETERS *)in_buffer );
551 break;
552 case IOCTL_TAPE_SET_MEDIA_PARAMS:
553 status = TAPE_SetMediaParams( fd, (TAPE_SET_MEDIA_PARAMETERS *)in_buffer );
554 break;
555 case IOCTL_TAPE_SET_POSITION:
556 status = TAPE_SetPosition( fd, (TAPE_SET_POSITION *)in_buffer );
557 break;
558 case IOCTL_TAPE_WRITE_MARKS:
559 status = TAPE_WriteMarks( fd, (TAPE_WRITE_MARKS *)in_buffer );
560 break;
562 case IOCTL_TAPE_CHECK_VERIFY:
563 case IOCTL_TAPE_FIND_NEW_DEVICES:
564 break;
565 default:
566 FIXME( "Unsupported IOCTL %lx (type=%lx access=%lx func=%lx meth=%lx)\n",
567 io_control, io_control >> 16, (io_control >> 14) & 3,
568 (io_control >> 2) & 0xfff, io_control & 3 );
569 break;
572 wine_server_release_fd( device, fd );
574 error:
575 io_status->u.Status = status;
576 io_status->Information = sz;
577 if (event) NtSetEvent( event, NULL );
578 return status;