Imported Upstream version 0.3
[anytun.git] / src / win32 / registryKey.cpp
1 /*
2  *  anytun
3  *
4  *  The secure anycast tunneling protocol (satp) defines a protocol used
5  *  for communication between any combination of unicast and anycast
6  *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
7  *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
8  *  ethernet, ip, arp ...). satp directly includes cryptography and
9  *  message authentication based on the methodes used by SRTP.  It is
10  *  intended to deliver a generic, scaleable and secure solution for
11  *  tunneling and relaying of packets of any protocol.
12  *
13  *
14  *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
15  *                          Christian Pointner <satp@wirdorange.org>
16  *
17  *  This file is part of Anytun.
18  *
19  *  Anytun is free software: you can redistribute it and/or modify
20  *  it under the terms of the GNU General Public License version 3 as
21  *  published by the Free Software Foundation.
22  *
23  *  Anytun is distributed in the hope that it will be useful,
24  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
25  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
26  *  GNU General Public License for more details.
27  *
28  *  You should have received a copy of the GNU General Public License
29  *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
30  */
31
32 #include <string.h>
33 #include <sstream>
34 #include <windows.h>
35
36 #include "registryKey.h"
37
38 #include "../anytunError.h"
39
40 RegistryKey::RegistryKey() : opened_(false)
41 {
42 }
43
44 RegistryKey::RegistryKey(HKEY hkey, std::string subKey, REGSAM samDesired) : opened_(false)
45 {
46   open(hkey, subKey, samDesired);
47 }
48
49 RegistryKey::~RegistryKey()
50 {
51   close();
52 }
53
54 bool RegistryKey::isOpen() const
55 {
56   return opened_;
57 }
58
59 std::string RegistryKey::getName() const
60 {
61   return name_;
62 }
63
64 DWORD RegistryKey::open(HKEY hkey, std::string subKey, REGSAM samDesired)
65 {
66   if(opened_)
67     RegCloseKey(key_);
68
69   opened_ = false;
70   name_ = "";
71   LONG err = RegOpenKeyExA(hkey, subKey.c_str(), 0, samDesired, &key_);
72   if(err != ERROR_SUCCESS)
73     return err;
74
75   name_ = subKey;
76   opened_ = true;
77   return ERROR_SUCCESS;
78 }
79
80 void RegistryKey::close()
81 {
82   if(opened_)
83     RegCloseKey(key_);
84   opened_ = false;
85 }
86
87 std::string RegistryKey::operator[](std::string const& name) const
88 {
89   if(!opened_)
90     throw AnytunErrno(ERROR_INVALID_HANDLE);
91
92   char value[STRING_VALUE_LENGTH];
93   DWORD len = sizeof(value);
94   LONG err = RegQueryValueExA(key_, name.c_str(), NULL, NULL, (LPBYTE)value, &len);
95   if(err != ERROR_SUCCESS)
96     throw AnytunErrno(err);
97
98   if(value[len-1] != 0) {
99     if(len < sizeof(value))
100       value[len++] = 0;
101     else
102       throw AnytunErrno(ERROR_INSUFFICIENT_BUFFER);
103   }  
104   return std::string(value);
105 }
106
107 DWORD RegistryKey::getSubKey(DWORD index, RegistryKey& subKey, REGSAM sam) const
108 {
109   char subkeyname[NAME_LENGTH];
110   DWORD len = sizeof(subkeyname);
111   DWORD err = RegEnumKeyExA(key_, index, subkeyname, &len, NULL, NULL, NULL, NULL);
112   if(err != ERROR_SUCCESS)
113     return err;
114
115   return subKey.open(key_, subkeyname, sam);
116 }
117
118 DWORD RegistryKey::getSubKey(std::string name, RegistryKey& subKey, REGSAM sam) const
119 {
120   return subKey.open(key_, name.c_str(), sam);
121 }