1 /* $Id$ 2 * 3 * COPYRIGHT: See COPYING in the top level directory 4 * PROJECT: ReactOS system libraries 5 * FILE: lib/kernel32/file/tape.c 6 * PURPOSE: Tape functions 7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl) 8 * UPDATE HISTORY: 9 * Created 01/11/98 10 */ 11 12 /* INCLUDES *******************************************************************/ 13 14 #include <k32.h> 15 #define NDEBUG 16 #include <debug.h> 17 18 /* PRIVATE FUNCTIONS **********************************************************/ 19 20 DWORD 21 WINAPI 22 BasepDoTapeOperation(IN HANDLE DeviceHandle, 23 IN ULONG Ioctl, 24 IN PVOID Input, 25 IN ULONG InputLength, 26 IN PVOID Output, 27 IN ULONG OutputLength) 28 { 29 HANDLE TapeEvent; 30 DWORD ErrorCode; 31 NTSTATUS Status; 32 IO_STATUS_BLOCK IoStatusBlock; 33 34 /* Create the wait event */ 35 TapeEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 36 if (!TapeEvent) return GetLastError(); 37 38 /* Send the IOCTL */ 39 Status = NtDeviceIoControlFile(DeviceHandle, 40 TapeEvent, 41 0, 42 0, 43 &IoStatusBlock, 44 Ioctl, 45 Input, 46 InputLength, 47 Output, 48 OutputLength); 49 if (Status == STATUS_PENDING) 50 { 51 /* Wait for its completion */ 52 WaitForSingleObject(TapeEvent, INFINITE); 53 Status = IoStatusBlock.Status; 54 } 55 56 /* Get rid of the wait event and check status */ 57 CloseHandle(TapeEvent); 58 if (!NT_SUCCESS(Status)) 59 { 60 /* Convert to Win32 */ 61 BaseSetLastNTError(Status); 62 ErrorCode = GetLastError(); 63 } 64 else 65 { 66 /* Set sucess */ 67 ErrorCode = ERROR_SUCCESS; 68 } 69 70 /* Return the Win32 error code */ 71 return ErrorCode; 72 } 73 74 /* PUBLIC FUNCTIONS ***********************************************************/ 75 76 /* 77 * @implemented 78 */ 79 DWORD 80 WINAPI 81 CreateTapePartition(IN HANDLE hDevice, 82 IN DWORD dwPartitionMethod, 83 IN DWORD dwCount, 84 IN DWORD dwSize) 85 { 86 TAPE_CREATE_PARTITION TapeCreatePartition; 87 88 TapeCreatePartition.Method = dwPartitionMethod; 89 TapeCreatePartition.Count = dwCount; 90 TapeCreatePartition.Size = dwSize; 91 return BasepDoTapeOperation(hDevice, 92 IOCTL_TAPE_CREATE_PARTITION, 93 &TapeCreatePartition, 94 sizeof(TapeCreatePartition), 95 NULL, 96 0); 97 } 98 99 /* 100 * @implemented 101 */ 102 DWORD 103 WINAPI 104 EraseTape(IN HANDLE hDevice, 105 IN DWORD dwEraseType, 106 IN BOOL bImmediate) 107 { 108 TAPE_ERASE TapeErase; 109 110 TapeErase.Type = dwEraseType; 111 TapeErase.Immediate = (BOOLEAN)bImmediate; 112 return BasepDoTapeOperation(hDevice, 113 IOCTL_TAPE_ERASE, 114 &TapeErase, 115 sizeof(TapeErase), 116 NULL, 117 0); 118 } 119 120 /* 121 * @implemented 122 */ 123 DWORD 124 WINAPI 125 GetTapeParameters(IN HANDLE hDevice, 126 IN DWORD dwOperation, 127 IN LPDWORD lpdwSize, 128 IN LPVOID lpTapeInformation) 129 { 130 if (dwOperation == GET_TAPE_MEDIA_INFORMATION) 131 { 132 if (*lpdwSize < sizeof(TAPE_GET_MEDIA_PARAMETERS)) 133 { 134 *lpdwSize = sizeof(TAPE_GET_MEDIA_PARAMETERS); 135 return ERROR_MORE_DATA; 136 } 137 138 return BasepDoTapeOperation(hDevice, 139 IOCTL_TAPE_GET_MEDIA_PARAMS, 140 NULL, 141 0, 142 lpTapeInformation, 143 sizeof(TAPE_GET_MEDIA_PARAMETERS)); 144 } 145 else if (dwOperation == GET_TAPE_DRIVE_INFORMATION) 146 { 147 if (*lpdwSize < sizeof(TAPE_GET_DRIVE_PARAMETERS)) 148 { 149 *lpdwSize = sizeof(TAPE_GET_DRIVE_PARAMETERS); 150 return ERROR_MORE_DATA; 151 } 152 153 return BasepDoTapeOperation(hDevice, 154 IOCTL_TAPE_GET_DRIVE_PARAMS, 155 NULL, 156 0, 157 lpTapeInformation, 158 sizeof(TAPE_GET_DRIVE_PARAMETERS)); 159 } 160 161 return ERROR_INVALID_FUNCTION; 162 } 163 164 /* 165 * @implemented 166 */ 167 DWORD 168 WINAPI 169 GetTapePosition(IN HANDLE hDevice, 170 IN DWORD dwPositionType, 171 IN LPDWORD lpdwPartition, 172 IN LPDWORD lpdwOffsetLow, 173 IN LPDWORD lpdwOffsetHigh) 174 { 175 TAPE_GET_POSITION TapeGetPosition; 176 DWORD Result; 177 178 TapeGetPosition.Type = dwPositionType; 179 Result = BasepDoTapeOperation(hDevice, 180 IOCTL_TAPE_GET_POSITION, 181 &TapeGetPosition, 182 sizeof(TapeGetPosition), 183 &TapeGetPosition, 184 sizeof(TapeGetPosition)); 185 186 if (Result) 187 { 188 *lpdwPartition = 0; 189 *lpdwOffsetLow = 0; 190 *lpdwOffsetHigh = 0; 191 } 192 else 193 { 194 *lpdwPartition = TapeGetPosition.Partition; 195 *lpdwOffsetLow = TapeGetPosition.Offset.u.LowPart; 196 *lpdwOffsetHigh = TapeGetPosition.Offset.u.HighPart; 197 } 198 199 return Result; 200 } 201 202 /* 203 * @implemented 204 */ 205 DWORD 206 WINAPI 207 GetTapeStatus(IN HANDLE hDevice) 208 { 209 return BasepDoTapeOperation(hDevice, 210 IOCTL_TAPE_GET_STATUS, 211 NULL, 212 0, 213 NULL, 214 0); 215 } 216 217 /* 218 * @implemented 219 */ 220 DWORD 221 WINAPI 222 PrepareTape(IN HANDLE hDevice, 223 IN DWORD dwOperation, 224 IN BOOL bImmediate) 225 { 226 TAPE_PREPARE TapePrepare; 227 228 TapePrepare.Operation = dwOperation; 229 TapePrepare.Immediate = (BOOLEAN)bImmediate; 230 return BasepDoTapeOperation(hDevice, 231 IOCTL_TAPE_PREPARE, 232 &TapePrepare, 233 sizeof(TapePrepare), 234 NULL, 235 0); 236 } 237 238 /* 239 * @implemented 240 */ 241 DWORD 242 WINAPI 243 SetTapeParameters(IN HANDLE hDevice, 244 IN DWORD dwOperation, 245 IN LPVOID lpTapeInformation) 246 { 247 if (dwOperation == SET_TAPE_MEDIA_INFORMATION) 248 { 249 return BasepDoTapeOperation(hDevice, 250 IOCTL_TAPE_SET_MEDIA_PARAMS, 251 lpTapeInformation, 252 sizeof(TAPE_SET_MEDIA_PARAMETERS), 253 NULL, 254 0); 255 } 256 else if (dwOperation == SET_TAPE_DRIVE_INFORMATION) 257 { 258 return BasepDoTapeOperation(hDevice, 259 IOCTL_TAPE_SET_DRIVE_PARAMS, 260 lpTapeInformation, 261 sizeof(TAPE_SET_DRIVE_PARAMETERS), 262 NULL, 263 0); 264 } 265 266 return ERROR_INVALID_FUNCTION; 267 } 268 269 /* 270 * @implemented 271 */ 272 DWORD 273 WINAPI 274 SetTapePosition(IN HANDLE hDevice, 275 IN DWORD dwPositionMethod, 276 IN DWORD dwPartition, 277 IN DWORD dwOffsetLow, 278 IN DWORD dwOffsetHigh, 279 IN BOOL bImmediate) 280 { 281 TAPE_SET_POSITION TapeSetPosition; 282 283 TapeSetPosition.Method = dwPositionMethod; 284 TapeSetPosition.Partition = dwPartition; 285 TapeSetPosition.Offset.u.LowPart = dwOffsetLow; 286 TapeSetPosition.Offset.u.HighPart = dwOffsetHigh; 287 TapeSetPosition.Immediate = (BOOLEAN)bImmediate; 288 return BasepDoTapeOperation(hDevice, 289 IOCTL_TAPE_SET_POSITION, 290 &TapeSetPosition, 291 sizeof(TapeSetPosition), 292 NULL, 293 0); 294 } 295 296 /* 297 * @implemented 298 */ 299 DWORD 300 WINAPI 301 WriteTapemark(IN HANDLE hDevice, 302 IN DWORD dwTapemarkType, 303 IN DWORD dwTapemarkCount, 304 IN BOOL bImmediate) 305 { 306 TAPE_WRITE_MARKS TapeWriteMarks; 307 308 TapeWriteMarks.Type = dwTapemarkType; 309 TapeWriteMarks.Count = dwTapemarkCount; 310 TapeWriteMarks.Immediate = (BOOLEAN)bImmediate; 311 return BasepDoTapeOperation(hDevice, 312 IOCTL_TAPE_WRITE_MARKS, 313 &TapeWriteMarks, 314 sizeof(TapeWriteMarks), 315 NULL, 316 0); 317 } 318 319 /* EOF */ 320