blob: fcb309b5b9155b3e0bbcc08d4d3b7d1f282808e4 [file] [log] [blame]
Constantin Kaplinsky47ed8d32004-10-08 09:43:57 +00001/* Copyright (C) 2002-2003 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19// -=- RegConfig.cxx
20
21#include <malloc.h>
22
23#include <rfb_win32/RegConfig.h>
24#include <rfb/LogWriter.h>
25#include <rfb/util.h>
26#include <rdr/HexOutStream.h>
27
28using namespace rfb;
29using namespace rfb::win32;
30
31
32static LogWriter vlog("RegConfig");
33
34
35class rfb::win32::RegReaderThread : public Thread {
36public:
37 RegReaderThread(RegistryReader& reader, const HKEY key);
38 ~RegReaderThread();
39 virtual void run();
40 virtual Thread* join();
41protected:
42 RegistryReader& reader;
43 RegKey key;
44 HANDLE event;
45};
46
47RegReaderThread::RegReaderThread(RegistryReader& reader_, const HKEY key_) : Thread("RegConfig"), reader(reader_), key(key_) {
48}
49
50RegReaderThread::~RegReaderThread() {
51}
52
53void
54RegReaderThread::run() {
55 vlog.debug("RegReaderThread started");
56 while (key) {
57 // - Wait for changes
58 vlog.debug("waiting for changes");
59 key.awaitChange(true, REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET);
60
61 // - Load settings
62 RegistryReader::loadRegistryConfig(key);
63
64 // - Notify specified thread of changes
65 if (reader.notifyThread)
66 PostThreadMessage(reader.notifyThread->getThreadId(),
67 reader.notifyMsg.message,
68 reader.notifyMsg.wParam,
69 reader.notifyMsg.lParam);
70 else if (reader.notifyWindow)
71 PostMessage(reader.notifyWindow,
72 reader.notifyMsg.message,
73 reader.notifyMsg.wParam,
74 reader.notifyMsg.lParam);
75 }
76}
77
78Thread*
79RegReaderThread::join() {
80 RegKey old_key = key;
81 key.close();
82 if ((HKEY)old_key) {
83 // *** Closing the key doesn't always seem to work
84 // Writing to it always will, instead...
85 vlog.debug("closing key");
86 old_key.setString(_T("dummy"), _T(""));
87 }
88 return Thread::join();
89}
90
91
92RegistryReader::RegistryReader() : thread(0), notifyThread(0) {
93 memset(&notifyMsg, 0, sizeof(notifyMsg));
94}
95
96RegistryReader::~RegistryReader() {
97 if (thread) delete thread->join();
98}
99
100bool RegistryReader::setKey(const HKEY rootkey, const TCHAR* keyname) {
101 if (thread) delete thread->join();
102 thread = 0;
103
104 RegKey key;
105 try {
106 key.createKey(rootkey, keyname);
107 loadRegistryConfig(key);
108 } catch (rdr::Exception& e) {
109 vlog.debug(e.str());
110 return false;
111 }
112 thread = new RegReaderThread(*this, key);
113 if (thread) thread->start();
114 return true;
115}
116
117void
118RegistryReader::loadRegistryConfig(RegKey& key) {
119 DWORD i = 0;
120 try {
121 while (1) {
122 TCharArray name = tstrDup(key.getValueName(i++));
123 if (!name.buf) break;
124 TCharArray value = key.getRepresentation(name.buf);
125 if (!value.buf || !Configuration::setParam(CStr(name.buf), CStr(value.buf)))
126 vlog.info("unable to process %s", CStr(name.buf));
127 }
128 } catch (rdr::SystemException& e) {
129 if (e.err != 6)
130 vlog.error(e.str());
131 }
132}
133
134bool RegistryReader::setNotifyThread(Thread* thread, UINT winMsg, WPARAM wParam, LPARAM lParam) {
135 notifyMsg.message = winMsg;
136 notifyMsg.wParam = wParam;
137 notifyMsg.lParam = lParam;
138 notifyThread = thread;
139 notifyWindow = 0;
140 return true;
141}
142
143bool RegistryReader::setNotifyWindow(HWND window, UINT winMsg, WPARAM wParam, LPARAM lParam) {
144 notifyMsg.message = winMsg;
145 notifyMsg.wParam = wParam;
146 notifyMsg.lParam = lParam;
147 notifyWindow = window;
148 notifyThread = 0;
149 return true;
150}
151