public static SafeFileHandle CreateSafeFileHandle( this IStorageFolder rootDirectory, string relativePath, FileMode mode, FileAccess access, FileShare share = FileShare.Read, FileOptions options = FileOptions.None) { if (rootDirectory == null) { throw new ArgumentNullException(nameof(rootDirectory)); } if (relativePath == null) { throw new ArgumentNullException(nameof(relativePath)); } HANDLE_CREATION_OPTIONS creationOptions = FileModeToCreationOptions(mode); HANDLE_ACCESS_OPTIONS accessOptions = FileAccessToHandleAccessOptions(access); HANDLE_SHARING_OPTIONS sharingOptions = FileShareToHandleSharingOptions(share); HANDLE_OPTIONS handleOptions = FileOptionsToHandleOptions(options); IStorageFolderHandleAccess handleAccess = ((object)rootDirectory) as IStorageFolderHandleAccess; if (handleAccess == null) { return(null); } SafeFileHandle handle; int result = handleAccess.Create( relativePath, creationOptions, accessOptions, sharingOptions, handleOptions, IntPtr.Zero, out handle); if (result != 0) { throw Win32Marshal.GetExceptionForWin32Error(Win32Marshal.TryMakeWin32ErrorCodeFromHR(result), relativePath); } return(handle); }
public static Exception TranslateWinRTException(this Exception exception, string filePath, bool isDirectory = false) { int errorCode = Win32Marshal.TryMakeWin32ErrorCodeFromHR(exception.HResult); if (isDirectory) { // WinRT remaps all ERROR_PATH_NOT_FOUND to ERROR_FILE_NOT_FOUND if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND) { errorCode = Interop.Errors.ERROR_PATH_NOT_FOUND; } } else { // Existing comment from FileStream: // NT5 oddity - when trying to open "C:\" as a FileStream, // we usually get ERROR_PATH_NOT_FOUND from the OS. We should // probably be consistent w/ every other directory. // This remaps the error for non-existent drives which is incorrect // but we need to preserve it for compatibility if (errorCode == Interop.Errors.ERROR_PATH_NOT_FOUND && filePath.Equals(Directory.InternalGetDirectoryRoot(filePath))) { errorCode = Interop.Errors.ERROR_ACCESS_DENIED; } // Known issue: WinRT pre-check's the find data of a fullPath before trying to create it, if the type doesn't match // (IE: open file on a directory) it will return E_INVALIDARG instead of ERROR_ACCESS_DENIED // CreateFile returns ERROR_PATH_NOT_FOUND when given a fullPath that ends in a backslash. // WinRT remaps all ERROR_PATH_NOT_FOUND to ERROR_FILE_NOT_FOUND if (errorCode == Interop.Errors.ERROR_FILE_NOT_FOUND && filePath.Length > 0 && filePath[filePath.Length - 1] == Path.DirectorySeparatorChar) { errorCode = Interop.Errors.ERROR_PATH_NOT_FOUND; } } // Known issue: We still can't handle ERROR_SHARING_VIOLATION because WinRT APIs are mapping this to ERROR_ACCESS_DENIED // Maps all unknown exceptions to IOException to be consistent with Win32 behavior return(Win32Marshal.GetExceptionForWin32Error(errorCode, filePath)); }
public static SafeFileHandle CreateSafeFileHandle( this IStorageFile windowsRuntimeFile, FileAccess access = FileAccess.ReadWrite, FileShare share = FileShare.Read, FileOptions options = FileOptions.None) { if (windowsRuntimeFile == null) { throw new ArgumentNullException(nameof(windowsRuntimeFile)); } HANDLE_ACCESS_OPTIONS accessOptions = FileAccessToHandleAccessOptions(access); HANDLE_SHARING_OPTIONS sharingOptions = FileShareToHandleSharingOptions(share); HANDLE_OPTIONS handleOptions = FileOptionsToHandleOptions(options); IStorageItemHandleAccess handleAccess = ((object)windowsRuntimeFile) as IStorageItemHandleAccess; if (handleAccess == null) { return(null); } SafeFileHandle handle; int result = handleAccess.Create( accessOptions, sharingOptions, handleOptions, IntPtr.Zero, out handle); if (result != 0) { throw Win32Marshal.GetExceptionForWin32Error(Win32Marshal.TryMakeWin32ErrorCodeFromHR(result), windowsRuntimeFile.Name); } return(handle); }