internal static void ImportExportEncryptedFileDirectoryRawCore(bool isExport, bool isFolder, Stream stream, string destinationPath, PathFormat pathFormat, bool overwriteHidden) { string destinationPathLp = Path.GetExtendedLengthPathCore(null, destinationPath, pathFormat, GetFullPathOptions.FullCheck | GetFullPathOptions.TrimEnd); NativeMethods.EncryptedFileRawMode mode = isExport ? NativeMethods.EncryptedFileRawMode.CreateForExport : NativeMethods.EncryptedFileRawMode.CreateForImport; if (isFolder) { mode = mode | NativeMethods.EncryptedFileRawMode.CreateForDir; } if (overwriteHidden) { mode = mode | NativeMethods.EncryptedFileRawMode.OverwriteHidden; } // OpenEncryptedFileRaw() // In the ANSI version of this function, the name is limited to 248 characters. // To extend this limit to 32,767 wide characters, call the Unicode version of the function and prepend "\\?\" to the path. // 2015-08-02: MSDN does not confirm LongPath usage but a Unicode version of this function exists. SafeEncryptedFileRawHandle context; var lastError = NativeMethods.OpenEncryptedFileRaw(destinationPathLp, mode, out context); try { if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(lastError, destinationPathLp); } lastError = isExport ? NativeMethods.ReadEncryptedFileRaw((pbData, pvCallbackContext, length) => { try { var data = new byte[length]; Marshal.Copy(pbData, data, 0, (int)length); stream.Write(data, 0, (int)length); } catch (Exception ex) { return(Marshal.GetHRForException(ex) & NativeMethods.OverflowExceptionBitShift); } return((int)Win32Errors.ERROR_SUCCESS); }, IntPtr.Zero, context) : NativeMethods.WriteEncryptedFileRaw((IntPtr pbData, IntPtr pvCallbackContext, ref uint length) => { try { var data = new byte[length]; length = (uint)stream.Read(data, 0, (int)length); if (length == 0) { return((int)Win32Errors.ERROR_SUCCESS); } Marshal.Copy(data, 0, pbData, (int)length); } catch (Exception ex) { return(Marshal.GetHRForException(ex) & NativeMethods.OverflowExceptionBitShift); } return((int)Win32Errors.ERROR_SUCCESS); }, IntPtr.Zero, context); if (lastError != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(lastError, destinationPathLp); } } finally { if (context != null) { context.Dispose(); } } }
internal static void ImportEncryptedFileRawCore(System.IO.Stream inputStream, string destinationFilePath, PathFormat pathFormat, NativeMethods.EncryptedFileRawMode mode) { string lpPath = Path.GetExtendedLengthPathCore(null, destinationFilePath, pathFormat, GetFullPathOptions.FullCheck | GetFullPathOptions.TrimEnd); SafeEncryptedFileRawHandle context = null; int errorCode = NativeMethods.OpenEncryptedFileRaw(lpPath, mode, out context); try { if (errorCode != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(errorCode, null, destinationFilePath); } errorCode = NativeMethods.WriteEncryptedFileRaw((IntPtr pbData, IntPtr pvCallbackContext, ref uint ulLength) => { try { byte[] buffer = new byte[ulLength]; ulLength = (uint)inputStream.Read(buffer, 0, (int)ulLength); if (ulLength == 0) { return((int)Win32Errors.ERROR_SUCCESS); } Marshal.Copy(buffer, 0, pbData, (int)ulLength); } catch (Exception ex) { return(Marshal.GetHRForException(ex)); } return((int)Win32Errors.ERROR_SUCCESS); }, IntPtr.Zero, context); if (errorCode != Win32Errors.ERROR_SUCCESS) { NativeError.ThrowException(errorCode, null, destinationFilePath); } } finally { if (context != null) { context.Dispose(); } } }