]>
git.proxmox.com Git - cargo.git/blob - vendor/cc-1.0.0/src/registry.rs
1 // Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 use std
::ffi
::{OsString, OsStr}
;
13 use std
::ops
::RangeFrom
;
15 use std
::os
::windows
::prelude
::*;
17 pub struct RegistryKey(Repr
);
21 type LPDWORD
= *mut DWORD
;
22 type LPCWSTR
= *const u16;
23 type LPWSTR
= *mut u16;
24 type LONG
= raw
::c_long
;
25 type PHKEY
= *mut HKEY
;
26 type PFILETIME
= *mut u8;
27 type LPBYTE
= *mut u8;
30 const ERROR_SUCCESS
: DWORD
= 0;
31 const ERROR_NO_MORE_ITEMS
: DWORD
= 259;
32 const HKEY_LOCAL_MACHINE
: HKEY
= 0x80000002 as HKEY
;
33 const REG_SZ
: DWORD
= 1;
34 const KEY_READ
: DWORD
= 0x20019;
35 const KEY_WOW64_32KEY
: DWORD
= 0x200;
37 #[link(name = "advapi32")]
39 fn RegOpenKeyExW(key
: HKEY
,
45 fn RegEnumKeyExW(key
: HKEY
,
52 lpftLastWriteTime
: PFILETIME
)
54 fn RegQueryValueExW(hKey
: HKEY
,
61 fn RegCloseKey(hKey
: HKEY
) -> LONG
;
64 struct OwnedKey(HKEY
);
72 idx
: RangeFrom
<DWORD
>,
76 unsafe impl Sync
for Repr {}
77 unsafe impl Send
for Repr {}
79 pub static LOCAL_MACHINE
: RegistryKey
= RegistryKey(Repr
::Const(HKEY_LOCAL_MACHINE
));
82 fn raw(&self) -> HKEY
{
84 Repr
::Const(val
) => val
,
85 Repr
::Owned(ref val
) => val
.0,
89 pub fn open(&self, key
: &OsStr
) -> io
::Result
<RegistryKey
> {
90 let key
= key
.encode_wide().chain(Some(0)).collect
::<Vec
<_
>>();
91 let mut ret
= 0 as *mut _
;
93 RegOpenKeyExW(self.raw(),
96 KEY_READ
| KEY_WOW64_32KEY
,
99 if err
== ERROR_SUCCESS
as LONG
{
100 Ok(RegistryKey(Repr
::Owned(OwnedKey(ret
))))
102 Err(io
::Error
::from_raw_os_error(err
as i32))
106 pub fn iter(&self) -> Iter
{
113 pub fn query_str(&self, name
: &str) -> io
::Result
<OsString
> {
114 let name
: &OsStr
= name
.as_ref();
115 let name
= name
.encode_wide().chain(Some(0)).collect
::<Vec
<_
>>();
119 let err
= RegQueryValueExW(self.raw(),
125 if err
!= ERROR_SUCCESS
as LONG
{
126 return Err(io
::Error
::from_raw_os_error(err
as i32));
129 return Err(io
::Error
::new(io
::ErrorKind
::Other
, "registry key wasn't a string"));
132 // The length here is the length in bytes, but we're using wide
133 // characters so we need to be sure to halve it for the capacity
135 let mut v
= Vec
::with_capacity(len
as usize / 2);
136 let err
= RegQueryValueExW(self.raw(),
140 v
.as_mut_ptr() as *mut _
,
142 if err
!= ERROR_SUCCESS
as LONG
{
143 return Err(io
::Error
::from_raw_os_error(err
as i32));
145 v
.set_len(len
as usize / 2);
147 // Some registry keys may have a terminating nul character, but
148 // we're not interested in that, so chop it off if it's there.
149 if v
[v
.len() - 1] == 0 {
152 Ok(OsString
::from_wide(&v
))
157 impl Drop
for OwnedKey
{
165 impl<'a
> Iterator
for Iter
<'a
> {
166 type Item
= io
::Result
<OsString
>;
168 fn next(&mut self) -> Option
<io
::Result
<OsString
>> {
169 self.idx
.next().and_then(|i
| unsafe {
170 let mut v
= Vec
::with_capacity(256);
171 let mut len
= v
.capacity() as DWORD
;
172 let ret
= RegEnumKeyExW(self.key
.raw(),
180 if ret
== ERROR_NO_MORE_ITEMS
as LONG
{
182 } else if ret
!= ERROR_SUCCESS
as LONG
{
183 Some(Err(io
::Error
::from_raw_os_error(ret
as i32)))
185 v
.set_len(len
as usize);
186 Some(Ok(OsString
::from_wide(&v
)))