/* rawf_nt.c * * Win32 raw file I/O for MIDAS Sound System * * $Id: rawf_nt.c,v 1.3 1997/01/16 18:41:59 pekangas Exp $ * * Copyright 1996,1997 Housemarque Inc. * * This file is part of the MIDAS Sound System, and may only be * used, modified and distributed under the terms of the MIDAS * Sound System license, LICENSE.TXT. By continuing to use, * modify or distribute this file you indicate that you have * read the license and understand and accept it fully. */ #define WIN32_LEAN_AND_MEAN #include #include "lang.h" #include "mtypes.h" #include "errors.h" #include "mmem.h" #include "rawfile.h" RCSID(const char *rawf_nt_rcsid = "$Id: rawf_nt.c,v 1.3 1997/01/16 18:41:59 pekangas Exp $";) /****************************************************************************\ * * Function: int ErrorCode(void) * * Description: Get the MIDAS error code corresponding to GetLastError() * * Returns: MIDAS error code * \****************************************************************************/ static int ErrorCode(void) { #define MAPERR(win32, midas) case win32: return midas; switch ( GetLastError() ) { MAPERR( NO_ERROR, OK ) MAPERR( ERROR_ACCESS_DENIED, errAccessDenied ) MAPERR( ERROR_ALREADY_EXISTS, errFileExists ) MAPERR( ERROR_BAD_NET_NAME, errInvalidPath ) MAPERR( ERROR_BAD_NETPATH, errInvalidPath ) MAPERR( ERROR_CANNOT_MAKE, errFileWrite ) MAPERR( ERROR_DEV_NOT_EXIST, errInvalidPath ) MAPERR( ERROR_DIRECTORY, errInvalidPath ) MAPERR( ERROR_DISK_FULL, errDiskFull ) MAPERR( ERROR_FILE_EXISTS, errFileExists ) MAPERR( ERROR_FILE_NOT_FOUND, errFileNotFound ) MAPERR( ERROR_HANDLE_DISK_FULL, errDiskFull ) MAPERR( ERROR_INVALID_COMPUTERNAME, errInvalidPath ) MAPERR( ERROR_INVALID_DRIVE, errInvalidPath ) MAPERR( ERROR_INVALID_HANDLE, errInvalidFileHandle ) MAPERR( ERROR_INVALID_NAME, errInvalidPath ) MAPERR( ERROR_INVALID_SHARENAME, errInvalidPath ) MAPERR( ERROR_NOT_ENOUGH_MEMORY, errOutOfMemory ) MAPERR( ERROR_OPEN_FAILED, errFileOpen ) MAPERR( ERROR_OUTOFMEMORY, errOutOfMemory ) MAPERR( ERROR_READ_FAULT, errFileRead ) MAPERR( ERROR_SEEK, errFileRead ) MAPERR( ERROR_TOO_MANY_OPEN_FILES, errTooManyFiles ) MAPERR( ERROR_WRITE_FAULT, errFileWrite ) default: return errUndefined; } } /****************************************************************************\ * * Function: int rfOpen(char *fileName, int openMode, rfHandle *file); * * Description: Opens a file for reading or writing * * Input: char *fileName name of file * int openMode file opening mode, see enum rfOpenMode * rfHandle *file pointer to file handle * * Returns: MIDAS error code. * File handle is stored in *file. * \****************************************************************************/ int CALLING rfOpen(char *fileName, int openMode, rfHandle *file) { int error; rfHandle hdl; HANDLE handle; /* allocate file structure */ if ( (error = memAlloc(sizeof(rfFile), (void**) &hdl)) != OK ) PASSERROR(ID_rfOpen) switch ( openMode ) { case rfOpenRead: /* open file for reading */ handle = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); break; case rfOpenWrite: /* open file for writing */ handle = CreateFile(fileName, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); break; case rfOpenReadWrite: /* open file for reading and writing */ handle = CreateFile(fileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); break; } /* If an error occurred during opening file, return the error code specified by GetLastError(): */ if ( handle == INVALID_HANDLE_VALUE ) { error = ErrorCode(); if ( error == OK ) error = errFileNotFound; ERROR(error, ID_rfOpen); return error; } /* Store handle: */ hdl->f = (U32) handle; /* store file handle in *file: */ *file = hdl; return OK; } /****************************************************************************\ * * Function: int rfClose(rfHandle file); * * Description: Closes a file opened with rfOpen(). * * Input: rfHandle file handle of an open file * * Returns: MIDAS error code * \****************************************************************************/ int CALLING rfClose(rfHandle file) { int error; HANDLE handle = (HANDLE) file->f; /* close file: */ if ( !CloseHandle(handle) ) { /* error occurred - return error code from GetLastError: */ error = ErrorCode(); ERROR(error, ID_rfClose); return error; } /* deallocate file structure: */ if ( (error = memFree(file)) != OK ) PASSERROR(ID_rfClose) return OK; } /****************************************************************************\ * * Function: int rfGetSize(rfHandle file, long *fileSize); * * Description: Get the size of a file * * Input: rfHandle file handle of an open file * ulong *fileSize pointer to file size * * Returns: MIDAS error code. * File size is stored in *fileSize. * \****************************************************************************/ int CALLING rfGetSize(rfHandle file, long *fileSize) { int error; static long fpos; /* store current file position: */ if ( (error = rfGetPosition(file, &fpos)) != OK ) PASSERROR(ID_rfGetSize) /* seek to end of file: */ if ( (error = rfSeek(file, 0, rfSeekEnd)) != OK ) PASSERROR(ID_rfGetSize) /* read file position to *filesize: */ if ( (error = rfGetPosition(file, fileSize)) != OK ) PASSERROR(ID_rfGetSize) /* return original file position: */ if ( (error = rfSeek(file, fpos, rfSeekAbsolute)) != OK ) PASSERROR(ID_rfGetSize) return OK; } /****************************************************************************\ * * Function: int rfRead(rfHandle file, void *buffer, ulong numBytes); * * Description: Reads binary data from a file * * Input: rfHandle file file handle * void *buffer reading buffer * ulong numBytes number of bytes to read * * Returns: MIDAS error code. * Read data is stored in *buffer, which must be large enough * for it. * \****************************************************************************/ int CALLING rfRead(rfHandle file, void *buffer, ulong numBytes) { int error; HANDLE handle = (HANDLE) file->f; DWORD numRead; if ( !ReadFile(handle, buffer, numBytes, &numRead, NULL) ) { /* Return error code from GetLastError: */ error = ErrorCode(); ERROR(error, ID_rfRead); return error; } /* Check that we did read all data: */ if ( numRead != numBytes ) { ERROR(errEndOfFile, ID_rfRead); return errEndOfFile; } return OK; } /****************************************************************************\ * * Function: int rfWrite(rfHandle file, void *buffer, ulong numBytes); * * Description: Writes binary data to a file * * Input: rfHandle file file handle * void *buffer pointer to data to be written * ulong numBytes number of bytes to write * * Returns: MIDAS error code * \****************************************************************************/ int CALLING rfWrite(rfHandle file, void *buffer, ulong numBytes) { int error; HANDLE handle = (HANDLE) file->f; DWORD numWritten; if ( !WriteFile(handle, buffer, numBytes, &numWritten, NULL) ) { /* Return error code from GetLastError: */ error = ErrorCode(); ERROR(error, ID_rfWrite); return error; } /* Check that we did write all data: */ if ( numWritten != numBytes ) { ERROR(errFileWrite, ID_rfWrite); return errFileWrite; } return OK; } /****************************************************************************\ * * Function: int rfSeek(rfHandle file, long newPosition, int seekMode); * * Description: Seeks to a new position in file. Subsequent reads and writes * go to the new position. * * Input: rfHandle file file handle * long newPosition new file position * int seekMode file seek mode, see enum rfSeekMode * * Returns: MIDAS error code * \****************************************************************************/ int CALLING rfSeek(rfHandle file, long newPosition, int seekMode) { HANDLE handle = (HANDLE) file->f; int error; DWORD moveMethod; LONG moveDist = newPosition; /* Select pointer move starting point: */ switch ( seekMode ) { case rfSeekAbsolute: /* seek to an absolute offset */ moveMethod = FILE_BEGIN; break; case rfSeekRelative: /* seek relative to current */ moveMethod = FILE_CURRENT; break; case rfSeekEnd: /* seek from end of file */ moveMethod = FILE_END; break; default: /* invalid seek mode: */ ERROR(errInvalidArguments, ID_rfSeek); return errInvalidArguments; } /* Seek to new position: */ if ( SetFilePointer(handle, moveDist, NULL, moveMethod) == 0xFFFFFFFF ) { /* Unable to seek - check the error from GetLastError(): */ error = ErrorCode(); ERROR(error, ID_rfSeek); return error; } return OK; } /****************************************************************************\ * * Function: int rfGetPosition(rfHandle file, long *position); * * Description: Reads the current position in a file * * Input: rfHandle file file handle * long *position pointer to file position * * Returns: MIDAS error code. * Current file position is stored in *position. * \****************************************************************************/ int CALLING rfGetPosition(rfHandle file, long *position) { HANDLE handle = (HANDLE) file->f; int error; DWORD pos; /* Get position by using SetFilePointer(): */ if ( (pos = SetFilePointer(handle, 0, NULL, FILE_CURRENT)) == 0xFFFFFFFF ) { /* Error - check GetLastError(): */ error = ErrorCode(); ERROR(error, ID_rfGetPosition); return error; } *position = pos; /* store position in *position */ return OK; } /****************************************************************************\ * * Function: int rfFileExists(char *fileName, int *exists); * * Description: Checks if a file exists or not * * Input: char *fileName file name, ASCIIZ * int *exists pointer to file exists status * * Returns: MIDAS error code. * *exists contains 1 if file exists, 0 if not. * \****************************************************************************/ int CALLING rfFileExists(char *fileName, int *exists) { HANDLE handle; /* Attempt to open the file: */ handle = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); if ( handle == INVALID_HANDLE_VALUE ) { /* Couldn't be opened: return 0: */ *exists = 0; return OK; } /* Close the file: */ CloseHandle(handle); return OK; } /* * $Log: rawf_nt.c,v $ * Revision 1.3 1997/01/16 18:41:59 pekangas * Changed copyright messages to Housemarque * * Revision 1.2 1996/09/22 23:16:33 pekangas * Fixed to always return an error from rfOpenFile if CreateFile fails * * Revision 1.1 1996/08/13 20:49:10 pekangas * Initial revision * */