1 /**
2 * Inkscape Registry Tool
3 *
4 * This simple tool is intended for allowing Inkscape to append subdirectories
5 * to its path. This will allow extensions and other files to be accesses
6 * without explicit user intervention.
7 *
8 * Authors:
9 * Bob Jamison
10 *
11 * Copyright (C) 2005-2008 Bob Jamison
12 *
13 * This library is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU Lesser General Public
15 * License as published by the Free Software Foundation; either
16 * version 2.1 of the License, or (at your option) any later version.
17 *
18 * This library is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * Lesser General Public License for more details.
22 *
23 * You should have received a copy of the GNU Lesser General Public
24 * License along with this library; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
26 */
28 #include <windows.h>
29 #include <string>
30 #include <cstdio>
32 #include "registrytool.h"
35 typedef struct
36 {
37 HKEY key;
38 int strlen;
39 const char *str;
40 } KeyTableEntry;
44 KeyTableEntry keyTable[] =
45 {
46 { HKEY_CLASSES_ROOT, 18, "HKEY_CLASSES_ROOT\\" },
47 { HKEY_CURRENT_CONFIG, 20, "HKEY_CURRENT_CONFIG\\" },
48 { HKEY_CURRENT_USER, 18, "HKEY_CURRENT_USER\\" },
49 { HKEY_LOCAL_MACHINE, 19, "HKEY_LOCAL_MACHINE\\" },
50 { HKEY_USERS, 11, "HKEY_USERS\\" },
51 { NULL, 0, NULL }
52 };
55 /**
56 * Set the string value of a key/name registry entry
57 */
58 bool RegistryTool::setStringValue(const Glib::ustring &keyNameArg,
59 const Glib::ustring &valueName,
60 const Glib::ustring &value)
61 {
62 Glib::ustring keyName = keyNameArg;
63 bool ret = false;
65 HKEY rootKey = HKEY_LOCAL_MACHINE; //default root
66 //Trim out the root key if necessary
67 for (KeyTableEntry *entry = keyTable; entry->key; entry++)
68 {
69 if (keyName.compare(0, entry->strlen, entry->str)==0)
70 {
71 rootKey = entry->key;
72 keyName = keyName.substr(entry->strlen);
73 }
74 }
75 //printf("trimmed string: '%s'\n", keyName.c_str());
77 //Get or create the key
78 gunichar2 *keyw = g_utf8_to_utf16(keyName.data(), -1, 0,0,0);
79 gunichar2 *valuenamew = g_utf8_to_utf16(valueName.data(), -1, 0,0,0);
81 HKEY key;
82 if (RegCreateKeyExW(rootKey, (WCHAR*) keyw,
83 0, NULL, REG_OPTION_NON_VOLATILE,
84 KEY_WRITE, NULL, &key, NULL))
85 {
86 fprintf(stderr, "RegistryTool: Could not create the registry key '%s'\n", keyName.c_str());
87 goto fail;
88 }
90 // Set the value
91 if (RegSetValueExW(key, (WCHAR*) valuenamew,
92 0, REG_SZ, (LPBYTE) value.data(), (DWORD) (value.size() + 1)))
93 {
94 fprintf(stderr, "RegistryTool: Could not set the value '%s'\n", value.c_str());
95 goto failkey;
96 }
98 ret = true;
100 failkey:
101 RegCloseKey(key);
103 fail:
104 g_free(keyw);
105 g_free(valuenamew);
106 return ret;
107 }
111 /**
112 * Get the full path, directory, and base file name of this running executable
113 */
114 bool RegistryTool::getExeInfo(Glib::ustring &fullPath,
115 Glib::ustring &path,
116 Glib::ustring &exeName)
117 {
118 const int pathbuf = 2048;
119 gunichar2 pathw[pathbuf];
120 GetModuleFileNameW(NULL, (WCHAR*) pathw, pathbuf);
122 gchar *utf8path = g_utf16_to_utf8(pathw, -1, 0,0,0);
123 fullPath = utf8path;
124 g_free(utf8path);
126 path = "";
127 exeName = "";
128 Glib::ustring::size_type pos = fullPath.rfind('\\');
129 if (pos != fullPath.npos)
130 {
131 path = fullPath.substr(0, pos);
132 exeName = fullPath.substr(pos+1);
133 }
135 return true;
136 }
140 /**
141 * Append our subdirectories to the Application Path for this
142 * application
143 */
144 bool RegistryTool::setPathInfo()
145 {
146 Glib::ustring fullPath;
147 Glib::ustring path;
148 Glib::ustring exeName;
150 if (!getExeInfo(fullPath, path, exeName))
151 return false;
153 //printf("full:'%s' path:'%s' exe:'%s'\n",
154 // fullPath.c_str(), path.c_str(), exeName.c_str());
156 Glib::ustring keyName =
157 "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\";
158 keyName.append(exeName);
160 Glib::ustring valueName = "";
161 Glib::ustring value = fullPath;
163 if (!setStringValue(keyName, valueName, value))
164 return false;
166 //add our subdirectories
167 Glib::ustring appPath = path;
168 appPath.append("\\python;");
169 appPath.append(path);
170 appPath.append("\\perl");
171 valueName = "Path";
172 value = appPath;
174 if (!setStringValue(keyName, valueName, value))
175 return false;
177 return true;
178 }
181 #ifdef TESTREG
184 /**
185 * Compile this file with
186 * g++ -DTESTREG registrytool.cpp -o registrytool
187 * to run these tests.
188 */
192 void testReg()
193 {
194 RegistryTool rt;
195 char *key =
196 "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\inkscape.exe";
197 char const *name = "";
198 char const *value = "c:\\inkscape\\inkscape.exe";
199 if (!rt.setStringValue(key, name, value))
200 {
201 printf("Test failed\n");
202 }
203 else
204 {
205 printf("Test succeeded\n");
206 }
207 name = "Path";
208 value = "c:\\inkscape\\python";
209 if (!rt.setStringValue(key, name, value))
210 {
211 printf("Test failed\n");
212 }
213 else
214 {
215 printf("Test succeeded\n");
216 }
217 }
220 void testPath()
221 {
222 RegistryTool rt;
223 rt.setPathInfo();
224 }
227 int main(int argc, char **argv)
228 {
229 //testReg();
230 testPath();
231 return 0;
232 }
234 #endif /* TESTREG */
236 //########################################################################
237 //# E N D O F F I L E
238 //########################################################################