internal static SafeTransactionHandle Create(Transaction managedTransaction) { if (managedTransaction == null) { throw new InvalidOperationException(RegistryProviderStrings.InvalidOperation_NeedTransaction); } // MSDTC is not available on WinPE machine. // CommitableTransaction will use DTC APIs under the covers to get KTM transaction manager interface. // KTM is kernel Transaction Manager to handle file, registry etc and MSDTC provides an integration support // with KTM to handle transaction across kernel resources and MSDTC resources like SQL, MSMQ etc. // We need KTMRM service as well. WinPE doesn’t have these services installed if (Utils.IsWinPEHost() || PsUtils.IsRunningOnProcessorArchitectureARM()) { throw new NotSupportedException(RegistryProviderStrings.NotSupported_KernelTransactions); } IDtcTransaction dtcTransaction = TransactionInterop.GetDtcTransaction(managedTransaction); IKernelTransaction ktmInterface = dtcTransaction as IKernelTransaction; if (null == ktmInterface) { throw new NotSupportedException(RegistryProviderStrings.NotSupported_KernelTransactions); } IntPtr ktmTxHandle; int hr = ktmInterface.GetHandle(out ktmTxHandle); HandleError(hr); return(new SafeTransactionHandle(ktmTxHandle)); }
/// <summary> /// Read a file with transaction /// </summary> /// <param name="path">Path to file</param> /// <returns>Donnes lu</returns> public object ReadFileTransacted(string path) { if (!File.Exists(path)) { return(null); } SafeTransactionHandle txHandle = null; SafeFileHandle fileHandle = null; object raw = null; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(System.Transactions.Transaction.Current); kernelTx.GetHandle(out txHandle); fileHandle = CreateFileTransacted( path , SafeTransactionHandle.FileAccess.GENERIC_READ , SafeTransactionHandle.FileShare.FILE_SHARE_READ , IntPtr.Zero , SafeTransactionHandle.FileMode.OPEN_ALWAYS , 0 , IntPtr.Zero , txHandle , IntPtr.Zero , IntPtr.Zero); if (fileHandle.IsInvalid) { throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); } using (FileStream stream = new FileStream(fileHandle, FileAccess.Read, 1024, false)) { BinaryFormatter reader = new BinaryFormatter(); raw = reader.Deserialize(stream); } } catch { raw = null; } finally { if (fileHandle != null && !fileHandle.IsInvalid) { fileHandle.Close(); fileHandle.Dispose(); } if (txHandle != null && !txHandle.IsInvalid) { txHandle.Close(); txHandle.Dispose(); } } return(raw); }
/// <summary> /// Moves an existing file or a directory, including its children, as a transacted operation. /// </summary> /// <param name="sourceFilePath"> /// The current name of the existing file or directory on the local computer. /// </param> /// <param name="targetFilePath"> /// The new name for the file or directory. The new name must not already exist. A new file may be on a different /// file system or drive. A new directory must be on the same drive. /// </param> /// <param name="transaction"> /// A handle to the transaction. /// </param> /// <seealso href="https://msdn.microsoft.com/en-us/library/windows/desktop/aa365241(v=vs.85).aspx"/> public static void Move(string sourceFilePath, string targetFilePath, IKernelTransaction transaction) { if (sourceFilePath.IsNullOrEmpty()) { throw new ArgumentNullException("sourceFilePath"); } if (targetFilePath.IsNullOrEmpty()) { throw new ArgumentNullException("targetFilePath"); } if (!_operatingSystem.SupportTransactionalFileSystem()) { throw new InvalidOperationException("File system is not transactional."); } IntPtr transactionHandle; transaction.GetHandle(out transactionHandle); if (transactionHandle == IntPtr.Zero) { throw new TransactionException("Cannot get handle to kernel transaction."); } var result = MoveFileTransacted(sourceFilePath, targetFilePath, IntPtr.Zero, IntPtr.Zero, 0, transactionHandle); if (!result) { Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); } }
/// <summary> /// Write a file with transaction /// </summary> /// <param name="data">Data to write</param> /// <param name="path">Path to file</param> /// <returns>Statut de l'opration</returns> public static bool WriteStateFileTransacted(string path, XmlSerializer stateSerializer, AtomState atomState, System.Transactions.Transaction transaction) { if (atomState == null) { return(false); } SafeTransactionHandle txHandle = null; SafeFileHandle fileHandle = null; bool response = true; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(transaction); kernelTx.GetHandle(out txHandle); fileHandle = CreateFileTransacted( path , SafeTransactionHandle.FileAccess.GENERIC_WRITE , SafeTransactionHandle.FileShare.FILE_SHARE_NONE , IntPtr.Zero , SafeTransactionHandle.FileMode.CREATE_ALWAYS , 0 , IntPtr.Zero , txHandle , IntPtr.Zero , IntPtr.Zero); if (fileHandle.IsInvalid) { throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()); } using (FileStream stateFile = new FileStream(fileHandle, FileAccess.Write, 1024, false)) { stateSerializer.Serialize(stateFile, atomState); } } catch { transaction.Rollback(); response = false; } finally { if (fileHandle != null && !fileHandle.IsInvalid) { fileHandle.Close(); fileHandle.Dispose(); } if (txHandle != null && !txHandle.IsInvalid) { txHandle.Close(); txHandle.Dispose(); } } return(response); }
/// <summary> /// Creates a new file in the specified path. /// </summary> /// <param name="path"> /// The path and name of the file to create. /// </param> /// <param name="bufferSize"> /// The number of bytes buffered for writes to the file. /// </param> /// <param name="transaction"> /// </param> /// A non-<c>null</c> <see cref="IKernelTransaction"/> transaction that must already be enlisted with a DTC. /// <returns> /// A <see cref="FileStream"/> with the specified buffer size that provides write access to the file specified in /// path. /// </returns> private static FileStream CreateTransacted(string path, int bufferSize, IKernelTransaction transaction) { if (Path.IsNetworkPath(path)) { throw new ArgumentException("Cannot create a transacted file in a network volume.", "path"); } if (transaction == null) { throw new ArgumentNullException("transaction"); } if (!_operatingSystem.SupportTransactionalFileSystem()) { throw new InvalidOperationException("File system is not transactional."); } IntPtr transactionHandle; transaction.GetHandle(out transactionHandle); if (transactionHandle == IntPtr.Zero) { throw new TransactionException("Cannot get handle to kernel transaction."); } // FileStreamTransacted unnecessary as the transaction is DTC enlisted: transaction is implicitly managed return(new FileStream(CreateFileTransactedHandle(transactionHandle, path), FileAccess.Write, bufferSize)); }
public static bool DeleteFiles(FileArgs args) { bool response = true; string message = String.Empty; return(TransactionActionHelper.DoActionWithCheckOnTransaction((ref string s) => { foreach (var file in args.Files) { if (!response) { return false; } if (!TransactionActionHelper.CheckConditions((ref string mes) => { if (!File.Exists(file)) { mes = "Wrong path or file exists"; Transaction.Current.Rollback(); return false; } return true; }, ref s)) { return false; } SafeTransactionHandle txHandle = null; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current); kernelTx.GetHandle(out txHandle); if (!DeleteFileTransacted(file, txHandle)) { Transaction.Current.Rollback(); response = false; } } catch (Exception ex) { response = false; s = ex.Message; Transaction.Current.Rollback(); } finally { if (txHandle != null && !txHandle.IsInvalid) { txHandle.Dispose(); } } } return response; }, ref message)); }
public static KtmTransactionHandle CreateKtmTransactionHandle(Transaction managedTransaction) { IDtcTransaction dtcTransaction = TransactionInterop.GetDtcTransaction(managedTransaction); IKernelTransaction ktmInterface = (IKernelTransaction)dtcTransaction; IntPtr ktmTxHandle; int hr = ktmInterface.GetHandle(out ktmTxHandle); HandleError(hr); return(new KtmTransactionHandle(ktmTxHandle)); }
/// <summary> /// Get KTM transaction from the specified managed <paramref name="managedTransaction" /> /// </summary> /// <param name="managedTransaction"> /// Owning managed transaction /// </param> /// <remarks> /// Currently this will require MS DTC service running. The created transaction should not be committed /// or rolled back itself explicitly. Use the owning managed transaction to control it. /// http://msdn.microsoft.com/en-us/library/cc303707.aspx /// </remarks> public static KtmTransactionHandle GetFromManaged(Transaction managedTransaction) { IKernelTransaction tx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current); IntPtr txHandle; tx.GetHandle(out txHandle); if (txHandle == IntPtr.Zero) { throw new Win32Exception("Could not get KTM transaction handle."); } return(new KtmTransactionHandle(txHandle)); }
public static FileStream GetTransactedFileStream(string fileName) { IKernelTransaction ktx = (IKernelTransaction) TransactionInterop.GetDtcTransaction(Transaction.Current); SafeTransactionHandle txHandle; ktx.GetHandle(out txHandle); SafeFileHandle fileHandle = NativeMethods.CreateFileTransacted( fileName, GENERIC_WRITE, 0, IntPtr.Zero, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero, txHandle, IntPtr.Zero, IntPtr.Zero); return(new FileStream(fileHandle, FileAccess.Write)); }
private static SafeFileHandle CreateFileHandled(string path, ref string message) { SafeTransactionHandle txHandle = null; SafeFileHandle fileHandle = null; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current); kernelTx.GetHandle(out txHandle); fileHandle = CreateFileTransacted( path , SafeTransactionHandle.FileAccess.GENERIC_WRITE , SafeTransactionHandle.FileShare.FILE_SHARE_NONE , IntPtr.Zero , SafeTransactionHandle.FileMode.CREATE_ALWAYS , 0 , IntPtr.Zero , txHandle , IntPtr.Zero , IntPtr.Zero); if (Path.GetExtension(path) == ".xaml") { WriteToFile(Properties.Resources.Template, path, ref message, fileHandle); } if (fileHandle.IsInvalid) { throw new Win32Exception(Marshal.GetLastWin32Error()); } } catch (Exception ex) { message = ex.Message; Transaction.Current.Rollback(); } finally { if (txHandle != null) { txHandle.Dispose(); } } return(fileHandle); }
public static bool MoveFile(string existingFile, string newFile) { bool success = true; using (TransactionScope tx = new TransactionScope()) { if (Transaction.Current != null) { IKernelTransaction kt = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current); IntPtr txh; kt.GetHandle(out txh); if (txh == IntPtr.Zero) { success = false; return(success); } success = MoveFileTransactedW(existingFile, newFile, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, txh); if (success) { CloseHandle(txh); tx.Complete(); } else { CloseHandle(txh); } } else { try { File.Move(existingFile, newFile); return(success); } catch (Exception ex) { success = false; } } return(success); } }
public static bool CopyFileTo(string path, string pathCopy, ref string message) { return(TransactionActionHelper.DoActionWithCheckOnTransaction((ref string s) => { if (!TransactionActionHelper.CheckConditions((ref string mes) => { if (!File.Exists(path) || File.Exists(pathCopy)) { mes = "Wrong path or file exists"; Transaction.Current.Rollback(); return false; } return true; }, ref s)) { return false; } bool response = false; SafeTransactionHandle txHandle = null; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current); kernelTx.GetHandle(out txHandle); response = CopyFileTransacted(path, pathCopy, IntPtr.Zero, IntPtr.Zero, false, SafeTransactionHandle.Copy.COPY_FILE_FAIL_IF_EXISTS, txHandle); } catch (Exception ex) { s = ex.Message; Transaction.Current.Rollback(); } finally { if (txHandle != null) { txHandle.Dispose(); } } return response; }, ref message)); }
private static bool CreateDir(string path, ref string message) { bool response = false; SafeTransactionHandle txHandle = null; try { IKernelTransaction kernelTx = (IKernelTransaction)TransactionInterop.GetDtcTransaction(Transaction.Current); kernelTx.GetHandle(out txHandle); response = CreateDirectoryTransacted(IntPtr.Zero, path, IntPtr.Zero, txHandle); } catch (Exception ex) { message = ex.ToString(); response = false; Transaction.Current.Rollback(); } return(response); }
internal static SafeTransactionHandle Create(Transaction managedTransaction) { IntPtr ptr; if (managedTransaction == null) { throw new InvalidOperationException(RegistryProviderStrings.InvalidOperation_NeedTransaction); } if (RemotingCommandUtil.IsWinPEHost() || PsUtils.IsRunningOnProcessorArchitectureARM()) { throw new NotSupportedException(RegistryProviderStrings.NotSupported_KernelTransactions); } IKernelTransaction dtcTransaction = TransactionInterop.GetDtcTransaction(managedTransaction) as IKernelTransaction; if (dtcTransaction == null) { throw new NotSupportedException(RegistryProviderStrings.NotSupported_KernelTransactions); } HandleError(dtcTransaction.GetHandle(out ptr)); return(new SafeTransactionHandle(ptr)); }