Home |
Function RTFSetDefaultOpenFlags Function RTFSetCriticalErrorHandler |
Function RTFSetCriticalErrorHandlerRTFSetCriticalErrorHandler installs a critical error handler to be called by RTFiles-32 in case of a device error: void RTFSetCriticalErrorHandler(RTFCriticalErrorHandler Handler); ParametersHandlerMust be a function of the following type: typedef enum { RTFRetry, RTFFail } RTFErrorAction; typedef RTFErrorAction (__cdecl * RTFCriticalErrorHandler)(char Drive, DWORD SerialNumber, int ErrorCode); If the application never calls RTFSetCriticalErrorHandler, RTFiles-32 will fail all device errors. In other words, the error will be passed to the application as a return code of the RTFiles-32 API function in which the error occurred; if media has been removed or replaced, all files of that media are closed. This behavior is implemented with the default critical error handler RTFDefaultCriticalErrorHandler. The critical error handler will be called by RTFiles-32 on every error reported by a device driver in a read or write operation. The handler is not called when the device is being mounted. Errors in this phase simply cause the device not to be mounted. Also, device error RTF_MEDIA_CHANGED detected while no files are open on a device simply cause the device to be remounted without calling the critical error handler. When the critical error handler is called, RTFiles-32 may have unflushed data in its buffer cache. If the error cannot be recovered, data loss must be expected and the volume could be left in an inconsistent state. The error handler receives parameters Drive, SerialNumber, and ErrorCode, which will contain the drive letter of the drive on which the error occurred, the serial number of the volume being accessed, and the RTFiles-32 error code which was reported by the device. The only valid return values are RTFFail or RTFRetry. If the handler returns RTFRetry, RTFiles-32 will attempt to perform the I/O operation again. If it fails again (for the same or some other reason), the error handler will be called again. The only way to get out of this situation is by failing the operation (the handler would have to return RTFFail) or a retry succeeds. RTFiles-32 does not support ignoring errors as other file systems may. If the handler decides to fail the operation by returning RTFFail, control passes back to the application. The current RTFiles-32 API function will return with the return code last passed to the critical error handler. If the error is one of the following,
RTFiles-32 will assume that the media is no longer available and all data for this drive in the internal buffer cache is discarded. This may include dirty buffers; their data will be lost. In addition, all open files on the drive are closed without flushing any dirty data and the drive is unmounted. Please note that files closed in this way do not need to be closed by the application, but this is nevertheless recommended. In particular, if the files have been opened through a non-RTFiles-32 API, high level API file references may still need to be closed (e.g., Win32 file handles, FILE pointers, stream objects, etc.). A critical error handler must be programmed very carefully. Some rules to be observed are given below:
When a critical error handler is called in a multithreaded environment, the device on which the error occurred is locked and cannot be accessed by other tasks. Access to other devices, however, is not limited. Below is an example of a critical error handler, taken from the RTFCmd demo program. It shows how a critical error handler might look like in a multitasking environment: RTFErrorAction __cdecl MyCriticalErrorHandler(char Drive, DWORD SerialNumber, int ErrorCode) { char Temp[4]; if (RTKCurrentTaskHandle() != MainHandle) return RTFFail; // can't talk to the user in other tasks switch (ErrorCode) { case RTF_WRONG_MEDIA: // we only want to case RTF_BAD_SECTOR: // handle these errors case RTF_DATA_ERROR: case RTF_MEDIA_CHANGED: case RTF_SECTOR_NOT_FOUND: case RTF_ADDRESS_MARK_NOT_FOUND: case RTF_CRC_ERROR: Wprintf(MainWindow, "RTFiles-32 Error on Drive %c:, " "Volume: %p: %s\r\n", Drive, SerialNumber, RTFErrorMessage(ErrorCode)); while (1) { Wprintf(MainWindow, "Please enter 'F'ail or 'R'etry:"); Temp[0] = '\0'; WGets(MainWindow, Temp, 4); switch (toupper(Temp[0])) { case 'F': return RTFFail; case 'R': return RTFRetry; } } default: return RTFFail; // can't do anything about other errors } } Function RTFSetDefaultOpenFlags Function RTFDefaultCriticalErrorHandler
|