winqueryreg can list subkey with argument "key"
[scilab.git] / scilab / modules / windows_tools / src / c / registry.c
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) INRIA - Allan CORNET
4 * Copyright (C) DIGITEO - 2011 - Allan CORNET
5 *
6 * This file must be used under the terms of the CeCILL.
7 * This source file is licensed as described in the file COPYING, which
8 * you should have received as part of this distribution.  The terms
9 * are also available at
10 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11 *
12 */
13
14 /*--------------------------------------------------------------------------*/
15 #include "registry.h"
16 #include "PATH_MAX.h"
17 #include "MALLOC.h"
18 #include "GetWindowsVersion.h"
19 #include "strdup_windows.h"
20 /*--------------------------------------------------------------------------*/
21 #define MAX_KEY_LENGTH 255
22 #define MAX_VALUE_NAME 16383
23 /*--------------------------------------------------------------------------*/
24
25 static BOOL WindowsOpenRegistry(char* _pstRoot, char* _pstKey, HKEY* _pKeyOut)
26 {
27     DWORD OpensKeyOptions = 0;
28     HKEY hKeyToOpen = NULL;
29
30     hKeyToOpen = GetHkeyrootFromString(_pstRoot);
31     if (hKeyToOpen == NULL)
32     {
33         return FALSE;
34     }
35
36 #ifdef _WIN64 /* Scilab x64 on x64 windows */
37     OpensKeyOptions = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_64KEY;
38     if ( RegOpenKeyEx(hKeyToOpen, _pstKey, 0, OpensKeyOptions, _pKeyOut) != ERROR_SUCCESS)
39     {
40         OpensKeyOptions = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_32KEY;
41         if ( RegOpenKeyEx(hKeyToOpen, _pstKey, 0, OpensKeyOptions, _pKeyOut) != ERROR_SUCCESS)
42         {
43             return FALSE;
44         }
45     }
46 #else
47     if (IsWow64()) /* Scilab 32 bits on x64 windows */
48     {
49         OpensKeyOptions = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_64KEY;
50         if ( RegOpenKeyEx(hKeyToOpen, _pstKey, 0, OpensKeyOptions, _pKeyOut) != ERROR_SUCCESS)
51         {
52             OpensKeyOptions = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE | KEY_WOW64_32KEY;
53             if ( RegOpenKeyEx(hKeyToOpen, _pstKey, 0, OpensKeyOptions, _pKeyOut) != ERROR_SUCCESS)
54             {
55                 return FALSE;
56             }
57         }
58     }
59     else /* Scilab 32 bits on windows 32 bits */
60     {
61         OpensKeyOptions = KEY_ENUMERATE_SUB_KEYS | KEY_QUERY_VALUE;
62         if ( RegOpenKeyEx(hKeyToOpen, _pstKey, 0, OpensKeyOptions, _pKeyOut) != ERROR_SUCCESS)
63         {
64             return FALSE;
65         }
66     }
67 #endif
68     return TRUE;
69 }
70
71 BOOL WindowsQueryRegistry(char *ParamIn1, char *ParamIn2, char *ParamIn3, char *ParamOut1, int *ParamOut2, BOOL *OuputIsREG_SZ)
72 {
73     BOOL bOK = TRUE;
74     HKEY key;
75     DWORD type = 0;
76
77     if (WindowsOpenRegistry(ParamIn1, ParamIn2, &key) == FALSE)
78     {
79         return FALSE;
80     }
81
82     if ( RegQueryValueEx(key, ParamIn3, NULL, &type, NULL, NULL) == ERROR_SUCCESS )
83     {
84         if ( (type == REG_EXPAND_SZ) || (type == REG_SZ) )
85         {
86             DWORD Length = PATH_MAX;
87             char Line[PATH_MAX];
88             if (RegQueryValueEx(key, ParamIn3, NULL, &type, (LPBYTE)&Line, &Length) == ERROR_SUCCESS )
89             {
90                 wsprintf(ParamOut1, "%s", Line);
91                 *OuputIsREG_SZ = TRUE;
92             }
93         }
94         else
95         {
96             DWORD size = 4;
97             int Num = 0;
98             if (RegQueryValueEx(key, ParamIn3, NULL, &type, (LPBYTE)&Num, &size) == ERROR_SUCCESS )
99             {
100                 *ParamOut2 = Num;
101                 *OuputIsREG_SZ = FALSE;
102             }
103         }
104     }
105     else
106     {
107         bOK = FALSE;
108     }
109
110     RegCloseKey(key);
111
112     return bOK;
113 }
114 /*--------------------------------------------------------------------------*/
115 BOOL WindowsQueryRegistryValuesList(char *ParamIn1, char *ParamIn2, int dimMax, char **ListKeys)
116 {
117     HKEY key;
118     int i = 0;
119
120     if (WindowsOpenRegistry(ParamIn1, ParamIn2, &key) == FALSE)
121     {
122         return FALSE;
123     }
124
125     for (i = 0; i < dimMax; i++)
126     {
127         TCHAR achKey[MAX_KEY_LENGTH];
128         DWORD cbName = MAX_KEY_LENGTH;
129         DWORD Type = 0;
130         DWORD retCode = 0;
131
132         retCode = RegEnumValue(key, i,
133                                achKey,
134                                &cbName,
135                                NULL,
136                                &Type,
137                                NULL,
138                                NULL);
139
140         if (retCode != ERROR_SUCCESS)
141         {
142             RegCloseKey(key);
143             return FALSE;
144         }
145         else
146         {
147             ListKeys[i] = strdup(achKey);
148         }
149     }
150
151     RegCloseKey(key);
152
153     return TRUE;
154 }
155
156 BOOL WindowsQueryRegistryKeysList(char *ParamIn1, char *ParamIn2, int dimMax, char **ListKeys)
157 {
158     HKEY key;
159     int i = 0;
160
161     if (WindowsOpenRegistry(ParamIn1, ParamIn2, &key) == FALSE)
162     {
163         return FALSE;
164     }
165
166     for (i = 0; i < dimMax; i++)
167     {
168         TCHAR achKey[MAX_KEY_LENGTH];
169         DWORD cbName = MAX_KEY_LENGTH;
170
171         LONG Err = RegEnumKey(key, i, achKey, cbName);
172         if (Err != ERROR_SUCCESS)
173         {
174             RegCloseKey(key);
175             return FALSE;
176         }
177         else
178         {
179             ListKeys[i] = strdup(achKey);
180         }
181     }
182
183     RegCloseKey(key);
184
185     return TRUE;
186 }
187 /*--------------------------------------------------------------------------*/
188 HKEY GetHkeyrootFromString(char *string)
189 {
190     if ( strcmp(string, "HKEY_CLASSES_ROOT") == 0 || strcmp(string, "HKCR") == 0)
191     {
192         return HKEY_CLASSES_ROOT;
193     }
194
195     if ( strcmp(string, "HKEY_CURRENT_USER") == 0 || strcmp(string, "HKCU") == 0 )
196     {
197         return HKEY_CURRENT_USER;
198     }
199
200     if ( strcmp(string, "HKEY_LOCAL_MACHINE") == 0 || strcmp(string, "HKLM") == 0 )
201     {
202         return HKEY_LOCAL_MACHINE;
203     }
204
205     if ( strcmp(string, "HKEY_USERS") == 0 || strcmp(string, "HKU") == 0 )
206     {
207         return HKEY_USERS;
208     }
209
210     if ( strcmp(string, "HKEY_DYN_DATA") == 0 || strcmp(string, "HKDD") == 0 )
211     {
212         return HKEY_DYN_DATA;
213     }
214
215     if ( strcmp(string, "HKEY_CURRENT_CONFIG") == 0 || strcmp(string, "HKCC") == 0 )
216     {
217         return HKEY_CURRENT_CONFIG;
218     }
219
220     return NULL;
221 }
222 /*--------------------------------------------------------------------------*/
223 static BOOL WindowsQueryRegistryNumberOfItemsInList(char *ParamIn1, char *ParamIn2, int* _piKeyNumber, int* _piValueNumber)
224 {
225     BOOL bOK = TRUE;
226
227     HKEY key;
228     DWORD retCode = 0;
229
230     TCHAR    achClass[PATH_MAX] = TEXT(""); // buffer for class name
231     DWORD    cchClassName = PATH_MAX;       // size of class string
232     DWORD    cSubKeys = 0;                  // number of subkeys
233     DWORD    cbMaxSubKey = 0;               // longest subkey size
234     DWORD    cchMaxClass = 0;               // longest class string
235     DWORD    cValues = 0;                   // number of values for key
236     DWORD    cchMaxValue = 0;               // longest value name
237     DWORD    cbMaxValueData = 0;            // longest value data
238     DWORD    cbSecurityDescriptor = 0;      // size of security descriptor
239     FILETIME ftLastWriteTime;               // last write time
240
241     if (WindowsOpenRegistry(ParamIn1, ParamIn2, &key) == FALSE)
242     {
243         return FALSE;
244     }
245
246     retCode = RegQueryInfoKey(
247                   key,                      // key handle
248                   achClass,                 // buffer for class name
249                   &cchClassName,            // size of class string
250                   NULL,                     // reserved
251                   &cSubKeys,                // number of subkeys
252                   &cbMaxSubKey,             // longest subkey size
253                   &cchMaxClass,             // longest class string
254                   &cValues,                 // number of values for this key
255                   &cchMaxValue,             // longest value name
256                   &cbMaxValueData,          // longest value data
257                   &cbSecurityDescriptor,    // security descriptor
258                   &ftLastWriteTime);        // last write time
259
260     if (retCode != ERROR_SUCCESS)
261     {
262         bOK = FALSE;
263     }
264     else
265     {
266         *_piValueNumber = cValues;
267         *_piKeyNumber   = cSubKeys;
268     }
269
270     RegCloseKey(key);
271
272     return bOK;
273 }
274 /*--------------------------------------------------------------------------*/
275 BOOL WindowsQueryRegistryNumberOfValuesInList(char *ParamIn1, char *ParamIn2, int *Number)
276 {
277     int iKey = 0;
278     return WindowsQueryRegistryNumberOfItemsInList(ParamIn1, ParamIn2, &iKey, Number);
279 }
280 /*--------------------------------------------------------------------------*/
281 BOOL WindowsQueryRegistryNumberOfKeysInList(char *ParamIn1, char *ParamIn2, int *Number)
282 {
283     int iValue = 0;
284     return WindowsQueryRegistryNumberOfItemsInList(ParamIn1, ParamIn2, Number, &iValue);
285 }
286 /*--------------------------------------------------------------------------*/