DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (1aeaa33a64f9)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
// Copyright 2015, Igor Shaula
// Licensed under the MIT License <LICENSE or
// http://opensource.org/licenses/MIT>. This file
// may not be copied, modified, or distributed
// except according to those terms.

//! Structure for a registry transaction.
//! Part of `transactions` feature.
//!
//!```no_run
//!extern crate winreg;
//!use std::io;
//!use winreg::RegKey;
//!use winreg::enums::*;
//!use winreg::transaction::Transaction;
//!
//!fn main() {
//!    let t = Transaction::new().unwrap();
//!    let hkcu = RegKey::predef(HKEY_CURRENT_USER);
//!    let key = hkcu.create_subkey_transacted("Software\\RustTransaction", &t).unwrap();
//!    key.set_value("TestQWORD", &1234567891011121314u64).unwrap();
//!    key.set_value("TestDWORD", &1234567890u32).unwrap();
//!
//!    println!("Commit transaction? [y/N]:");
//!    let mut input = String::new();
//!    io::stdin().read_line(&mut input).unwrap();
//!    input = input.trim_right().to_owned();
//!    if input == "y" || input == "Y" {
//!        t.commit().unwrap();
//!        println!("Transaction committed.");
//!    }
//!    else {
//!        // this is optional, if transaction wasn't committed,
//!        // it will be rolled back on disposal
//!        t.rollback().unwrap();
//!
//!        println!("Transaction wasn't committed, it will be rolled back.");
//!    }
//!}
//!```
#![cfg(feature = "transactions")]
use std::ptr;
use std::io;
use winapi::um::winnt;
use winapi::um::handleapi;
use winapi::um::ktmw32;

#[derive(Debug)]
pub struct Transaction {
    pub handle: winnt::HANDLE,
}

impl Transaction {
    //TODO: add arguments
    pub fn new() -> io::Result<Transaction> {
        unsafe {
            let handle = ktmw32::CreateTransaction(
                ptr::null_mut(),
                ptr::null_mut(),
                0,
                0,
                0,
                0,
                ptr::null_mut(),
            );
            if handle == handleapi::INVALID_HANDLE_VALUE {
                return Err(io::Error::last_os_error())
            };
            Ok(Transaction{ handle: handle })
        }
    }

    pub fn commit(&self) -> io::Result<()> {
        unsafe {
            match ktmw32::CommitTransaction(self.handle) {
                0 => Err(io::Error::last_os_error()),
                _ => Ok(())
            }
        }
    }

    pub fn rollback(&self) -> io::Result<()> {
        unsafe {
            match ktmw32::RollbackTransaction(self.handle) {
                0 => Err(io::Error::last_os_error()),
                _ => Ok(())
            }
        }
    }

    fn close_(&mut self) -> io::Result<()> {
        unsafe {
            match handleapi::CloseHandle(self.handle) {
                0 => Err(io::Error::last_os_error()),
                _ => Ok(())
            }
        }
    }
}

impl Drop for Transaction {
    fn drop(&mut self) {
        self.close_().unwrap_or(());
    }
}