~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/programs/regedit/edit.c

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  1 /*
  2  * Registry editing UI functions.
  3  *
  4  * Copyright (C) 2003 Dimitrie O. Paun
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #define WIN32_LEAN_AND_MEAN     /* Exclude rarely-used stuff from Windows headers */
 22 
 23 #include <windows.h>
 24 #include <commctrl.h>
 25 #include <commdlg.h>
 26 #include <cderr.h>
 27 #include <stdlib.h>
 28 #include <stdio.h>
 29 #include <shellapi.h>
 30 #include <shlwapi.h>
 31 
 32 #include "wine/unicode.h"
 33 #include "main.h"
 34 #include "regproc.h"
 35 #include "resource.h"
 36 
 37 static const WCHAR* editValueName;
 38 static WCHAR* stringValueData;
 39 static BOOL isDecimal;
 40 
 41 struct edit_params
 42 {
 43     HKEY    hKey;
 44     LPCWSTR lpszValueName;
 45     void   *pData;
 46     LONG    cbData;
 47 };
 48 
 49 static INT vmessagebox(HWND hwnd, INT buttons, INT titleId, INT resId, va_list ap)
 50 {
 51     static const WCHAR errorW[] = {'E','r','r','o','r',0};
 52     static const WCHAR unknownW[] = {'U','n','k','n','o','w','n',' ','e','r','r','o','r',' ','s','t','r','i','n','g','!',0};
 53 
 54     WCHAR title[256];
 55     WCHAR errfmt[1024];
 56     WCHAR errstr[1024];
 57 
 58     if (!LoadStringW(hInst, titleId, title, COUNT_OF(title))) lstrcpyW(title, errorW);
 59     if (!LoadStringW(hInst, resId, errfmt, COUNT_OF(errfmt))) lstrcpyW(errfmt, unknownW);
 60 
 61     vsnprintfW(errstr, COUNT_OF(errstr), errfmt, ap);
 62 
 63     return MessageBoxW(hwnd, errstr, title, buttons);
 64 }
 65 
 66 static INT messagebox(HWND hwnd, INT buttons, INT titleId, INT resId, ...)
 67 {
 68     va_list ap;
 69     INT result;
 70 
 71     va_start(ap, resId);
 72     result = vmessagebox(hwnd, buttons, titleId, resId, ap);
 73     va_end(ap);
 74 
 75     return result;
 76 }
 77 
 78 void error(HWND hwnd, INT resId, ...)
 79 {
 80     va_list ap;
 81 
 82     va_start(ap, resId);
 83     vmessagebox(hwnd, MB_OK | MB_ICONERROR, IDS_ERROR, resId, ap);
 84     va_end(ap);
 85 }
 86 
 87 static void error_code_messagebox(HWND hwnd, DWORD error_code)
 88 {
 89     LPWSTR lpMsgBuf;
 90     DWORD status;
 91     WCHAR title[256];
 92     static WCHAR fallback[] = {'E','r','r','o','r',' ','d','i','s','p','l','a','y','i','n','g',' ','e','r','r','o','r',' ','m','e','s','s','a','g','e','.','\n',0};
 93     static const WCHAR title_error[] = {'E','r','r','o','r',0};
 94 
 95     if (!LoadStringW(hInst, IDS_ERROR, title, COUNT_OF(title)))
 96         lstrcpyW(title, title_error);
 97     status = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
 98                            NULL, error_code, 0, (LPWSTR)&lpMsgBuf, 0, NULL);
 99     if (!status)
100         lpMsgBuf = fallback;
101     MessageBoxW(hwnd, lpMsgBuf, title, MB_OK | MB_ICONERROR);
102     if (lpMsgBuf != fallback)
103         LocalFree(lpMsgBuf);
104 }
105 
106 static BOOL change_dword_base(HWND hwndDlg, BOOL toHex)
107 {
108     static const WCHAR percent_u[] = {'%','u',0};
109     static const WCHAR percent_x[] = {'%','x',0};
110 
111     WCHAR buf[128];
112     DWORD val;
113 
114     if (!GetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, buf, COUNT_OF(buf))) return FALSE;
115     if (!swscanf(buf, toHex ? percent_u : percent_x, &val)) return FALSE;
116     wsprintfW(buf, toHex ? percent_x : percent_u, val);
117     return SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, buf);
118 }
119 
120 static INT_PTR CALLBACK modify_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
121 {
122     WCHAR* valueData;
123     HWND hwndValue;
124     int len;
125 
126     switch(uMsg) {
127     case WM_INITDIALOG:
128         SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
129         SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, stringValueData);
130         CheckRadioButton(hwndDlg, IDC_DWORD_HEX, IDC_DWORD_DEC, isDecimal ? IDC_DWORD_DEC : IDC_DWORD_HEX);
131         return TRUE;
132     case WM_COMMAND:
133         switch (LOWORD(wParam)) {
134         case IDC_DWORD_HEX:
135             if (isDecimal && change_dword_base(hwndDlg, TRUE)) isDecimal = FALSE;
136         break;
137         case IDC_DWORD_DEC:
138             if (!isDecimal && change_dword_base(hwndDlg, FALSE)) isDecimal = TRUE;
139         break;
140         case IDOK:
141             if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA))) {
142                 len = GetWindowTextLengthW(hwndValue);
143                 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(WCHAR)))) {
144                     stringValueData = valueData;
145                     if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
146                         *stringValueData = 0;
147                 }
148             }
149             /* Fall through */
150         case IDCANCEL:
151             EndDialog(hwndDlg, wParam);
152             return TRUE;
153         }
154     }
155     return FALSE;
156 }
157 
158 static INT_PTR CALLBACK bin_modify_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
159 {
160     struct edit_params *params;
161     LPBYTE pData;
162     LONG cbData;
163     LONG lRet;
164 
165     switch(uMsg) {
166     case WM_INITDIALOG:
167         params = (struct edit_params *)lParam;
168         SetWindowLongPtrW(hwndDlg, DWLP_USER, (ULONG_PTR)params);
169         if (params->lpszValueName)
170             SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, params->lpszValueName);
171         else
172             SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, g_pszDefaultValueName);
173         SendDlgItemMessageW(hwndDlg, IDC_VALUE_DATA, HEM_SETDATA, (WPARAM)params->cbData, (LPARAM)params->pData);
174         return TRUE;
175     case WM_COMMAND:
176         switch (LOWORD(wParam)) {
177         case IDOK:
178             params = (struct edit_params *)GetWindowLongPtrW(hwndDlg, DWLP_USER);
179             cbData = SendDlgItemMessageW(hwndDlg, IDC_VALUE_DATA, HEM_GETDATA, 0, 0);
180             pData = HeapAlloc(GetProcessHeap(), 0, cbData);
181 
182             if (pData)
183             {
184                 SendDlgItemMessageW(hwndDlg, IDC_VALUE_DATA, HEM_GETDATA, (WPARAM)cbData, (LPARAM)pData);
185                 lRet = RegSetValueExW(params->hKey, params->lpszValueName, 0, REG_BINARY, pData, cbData);
186             }
187             else
188                 lRet = ERROR_OUTOFMEMORY;
189 
190             if (lRet == ERROR_SUCCESS)
191                 EndDialog(hwndDlg, 1);
192             else
193             {
194                 error_code_messagebox(hwndDlg, lRet);
195                 EndDialog(hwndDlg, 0);
196             }
197             return TRUE;
198         case IDCANCEL:
199             EndDialog(hwndDlg, 0);
200             return TRUE;
201         }
202     }
203     return FALSE;
204 }
205 
206 static BOOL check_value(HWND hwnd, HKEY hKey, LPCWSTR valueName)
207 {
208     WCHAR empty = 0;
209     LONG lRet = RegQueryValueExW(hKey, valueName ? valueName : &empty, 0, NULL, 0, NULL);
210     if(lRet != ERROR_SUCCESS) return FALSE;
211     return TRUE;
212 }
213 
214 static LPWSTR read_value(HWND hwnd, HKEY hKey, LPCWSTR valueName, DWORD *lpType, LONG *len)
215 {
216     DWORD valueDataLen;
217     LPWSTR buffer = NULL;
218     LONG lRet;
219         WCHAR empty = 0;
220 
221     lRet = RegQueryValueExW(hKey, valueName ? valueName : &empty, 0, lpType, 0, &valueDataLen);
222     if (lRet != ERROR_SUCCESS) {
223         if (lRet == ERROR_FILE_NOT_FOUND && !valueName) { /* no default value here, make it up */
224             if (len) *len = 1;
225             if (lpType) *lpType = REG_SZ;
226             buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR));
227             *buffer = '\0';
228             return buffer;
229         }
230         error(hwnd, IDS_BAD_VALUE, valueName);
231         goto done;
232     }
233     if ( *lpType == REG_DWORD ) valueDataLen = sizeof(DWORD);
234     if (!(buffer = HeapAlloc(GetProcessHeap(), 0, valueDataLen+sizeof(WCHAR)))) {
235         error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
236         goto done;
237     }
238     lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)buffer, &valueDataLen);
239     if (lRet != ERROR_SUCCESS) {
240         error(hwnd, IDS_BAD_VALUE, valueName);
241         goto done;
242     }
243     if((valueDataLen % sizeof(WCHAR)) == 0)
244         buffer[valueDataLen / sizeof(WCHAR)] = 0;
245     if(len) *len = valueDataLen;
246     return buffer;
247 
248 done:
249     HeapFree(GetProcessHeap(), 0, buffer);
250     return NULL;
251 }
252 
253 BOOL CreateKey(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath, LPWSTR keyName)
254 {
255     BOOL result = FALSE;
256     LONG lRet = ERROR_SUCCESS;
257     HKEY retKey = NULL;
258     WCHAR newKey[MAX_NEW_KEY_LEN - 4];
259     int keyNum;
260     HKEY hKey;
261          
262     lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_CREATE_SUB_KEY, &hKey);
263     if (lRet != ERROR_SUCCESS) {
264         error_code_messagebox(hwnd, lRet);
265         goto done;
266     }
267 
268     if (!LoadStringW(GetModuleHandleW(0), IDS_NEWKEY, newKey, COUNT_OF(newKey))) goto done;
269 
270     /* try to find out a name for the newly create key (max 100 times) */
271     for (keyNum = 1; keyNum < 100; keyNum++) {
272         wsprintfW(keyName, newKey, keyNum);
273         lRet = RegOpenKeyW(hKey, keyName, &retKey);
274         if (lRet != ERROR_SUCCESS) break;
275         RegCloseKey(retKey);
276     }
277     if (lRet == ERROR_SUCCESS) goto done;
278     
279     lRet = RegCreateKeyW(hKey, keyName, &retKey);
280     if (lRet != ERROR_SUCCESS) {
281         error_code_messagebox(hwnd, lRet);
282         goto done;
283     }
284 
285     result = TRUE;
286 
287 done:
288     RegCloseKey(retKey);
289     return result;
290 }
291 
292 BOOL ModifyValue(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath, LPCWSTR valueName)
293 {
294     BOOL result = FALSE;
295     DWORD type;
296     LONG lRet;
297     HKEY hKey;
298     LONG len;
299 
300     lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_READ | KEY_SET_VALUE, &hKey);
301     if (lRet != ERROR_SUCCESS) {
302         error_code_messagebox(hwnd, lRet);
303         return FALSE;
304     }
305 
306     editValueName = valueName ? valueName : g_pszDefaultValueName;
307     if(!(stringValueData = read_value(hwnd, hKey, valueName, &type, &len))) goto done;
308 
309     if ( (type == REG_SZ) || (type == REG_EXPAND_SZ) ) {
310         if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_STRING), hwnd, modify_dlgproc) == IDOK) {
311             lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)stringValueData, (lstrlenW(stringValueData) + 1) * sizeof(WCHAR));
312             if (lRet == ERROR_SUCCESS) result = TRUE;
313             else error_code_messagebox(hwnd, lRet);
314         }
315     } else if ( type == REG_DWORD ) {
316         const WCHAR u[] = {'%','u',0};
317         const WCHAR x[] = {'%','x',0};
318         wsprintfW(stringValueData, isDecimal ? u : x, *((DWORD*)stringValueData));
319         if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_DWORD), hwnd, modify_dlgproc) == IDOK) {
320             DWORD val;
321             CHAR* valueA = GetMultiByteString(stringValueData);
322             if (sscanf(valueA, isDecimal ? "%u" : "%x", &val)) {
323                 lRet = RegSetValueExW(hKey, valueName, 0, type, (BYTE*)&val, sizeof(val));
324                 if (lRet == ERROR_SUCCESS) result = TRUE;
325                 else error_code_messagebox(hwnd, lRet);
326             }
327             HeapFree(GetProcessHeap(), 0, valueA);
328         }
329     } else if ( type == REG_BINARY ) {
330         struct edit_params params;
331         params.hKey = hKey;
332         params.lpszValueName = valueName;
333         params.pData = stringValueData;
334         params.cbData = len;
335         result = DialogBoxParamW(NULL, MAKEINTRESOURCEW(IDD_EDIT_BINARY), hwnd,
336             bin_modify_dlgproc, (LPARAM)&params);
337     } else if ( type == REG_MULTI_SZ ) {
338         WCHAR char1 = '\r', char2 = '\n';
339         WCHAR *tmpValueData = NULL;
340         INT i, j, count;
341 
342         for ( i = 0, count = 0; i < len - 1; i++)
343             if ( !stringValueData[i] && stringValueData[i + 1] )
344                 count++;
345         tmpValueData = HeapAlloc( GetProcessHeap(), 0, ( len + count ) * sizeof(WCHAR));
346         if ( !tmpValueData ) goto done;
347 
348         for ( i = 0, j = 0; i < len - 1; i++)
349         {
350             if ( !stringValueData[i] && stringValueData[i + 1])
351             {
352                 tmpValueData[j++] = char1;
353                 tmpValueData[j++] = char2;
354             }
355             else
356                 tmpValueData[j++] = stringValueData[i];
357         }
358         tmpValueData[j] = stringValueData[i];
359         HeapFree( GetProcessHeap(), 0, stringValueData);
360         stringValueData = tmpValueData;
361         tmpValueData = NULL;
362 
363         if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_MULTI_STRING), hwnd, modify_dlgproc) == IDOK)
364         {
365             len = lstrlenW( stringValueData );
366             tmpValueData = HeapAlloc( GetProcessHeap(), 0, (len + 2) * sizeof(WCHAR));
367             if ( !tmpValueData ) goto done;
368 
369             for ( i = 0, j = 0; i < len - 1; i++)
370             {
371                 if ( stringValueData[i] == char1 && stringValueData[i + 1] == char2)
372                 {
373                     if ( tmpValueData[j - 1] != 0)
374                         tmpValueData[j++] = 0;
375                     i++;
376                 }
377                 else
378                     tmpValueData[j++] = stringValueData[i];
379             }
380             tmpValueData[j++] = stringValueData[i];
381             tmpValueData[j++] = 0;
382             tmpValueData[j++] = 0;
383             HeapFree( GetProcessHeap(), 0, stringValueData);
384             stringValueData = tmpValueData;
385 
386             lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)stringValueData, j * sizeof(WCHAR));
387             if (lRet == ERROR_SUCCESS) result = TRUE;
388             else error_code_messagebox(hwnd, lRet);
389         }
390     } else {
391         error(hwnd, IDS_UNSUPPORTED_TYPE, type);
392     }
393 
394 done:
395     HeapFree(GetProcessHeap(), 0, stringValueData);
396     stringValueData = NULL;
397     RegCloseKey(hKey);
398     return result;
399 }
400 
401 BOOL DeleteKey(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath)
402 {
403     BOOL result = FALSE;
404     LONG lRet;
405     HKEY hKey;
406 
407     lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_READ|KEY_SET_VALUE, &hKey);
408     if (lRet != ERROR_SUCCESS) {
409         error_code_messagebox(hwnd, lRet);
410         return FALSE;
411     }
412     
413     if (messagebox(hwnd, MB_YESNO | MB_ICONEXCLAMATION, IDS_DELETE_BOX_TITLE, IDS_DELETE_BOX_TEXT, keyPath) != IDYES)
414         goto done;
415         
416     lRet = SHDeleteKeyW(hKeyRoot, keyPath);
417     if (lRet != ERROR_SUCCESS) {
418         error(hwnd, IDS_BAD_KEY, keyPath);
419         goto done;
420     }
421     result = TRUE;
422     
423 done:
424     RegCloseKey(hKey);
425     return result;
426 }
427 
428 BOOL DeleteValue(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath, LPCWSTR valueName, BOOL showMessageBox)
429 {
430     BOOL result = FALSE;
431     LONG lRet;
432     HKEY hKey;
433     LPCWSTR visibleValueName = valueName ? valueName : g_pszDefaultValueName;
434     WCHAR empty = 0;
435 
436     lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_READ | KEY_SET_VALUE, &hKey);
437     if (lRet != ERROR_SUCCESS) return FALSE;
438 
439     if (showMessageBox)
440     {
441         if (messagebox(hwnd, MB_YESNO | MB_ICONEXCLAMATION, IDS_DELETE_BOX_TITLE, IDS_DELETE_BOX_TEXT, visibleValueName) != IDYES)
442             goto done;
443     }
444 
445     lRet = RegDeleteValueW(hKey, valueName ? valueName : &empty);
446     if (lRet != ERROR_SUCCESS && valueName) {
447         error(hwnd, IDS_BAD_VALUE, valueName);
448     }
449     if (lRet != ERROR_SUCCESS) goto done;
450     result = TRUE;
451 
452 done:
453     RegCloseKey(hKey);
454     return result;
455 }
456 
457 BOOL CreateValue(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath, DWORD valueType, LPWSTR valueName)
458 {
459     LONG lRet = ERROR_SUCCESS;
460     WCHAR newValue[256];
461     DWORD valueDword = 0;
462     BOOL result = FALSE;
463     int valueNum;
464     HKEY hKey;
465          
466     lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_READ | KEY_SET_VALUE, &hKey);
467     if (lRet != ERROR_SUCCESS) {
468         error_code_messagebox(hwnd, lRet);
469         return FALSE;
470     }
471 
472     if (!LoadStringW(GetModuleHandleW(0), IDS_NEWVALUE, newValue, COUNT_OF(newValue))) goto done;
473 
474     /* try to find out a name for the newly create key (max 100 times) */
475     for (valueNum = 1; valueNum < 100; valueNum++) {
476         wsprintfW(valueName, newValue, valueNum);
477         lRet = RegQueryValueExW(hKey, valueName, 0, 0, 0, 0);
478         if (lRet == ERROR_FILE_NOT_FOUND) break;
479     }
480     if (lRet != ERROR_FILE_NOT_FOUND) {
481         error_code_messagebox(hwnd, lRet);
482         goto done;
483     }
484    
485     lRet = RegSetValueExW(hKey, valueName, 0, valueType, (BYTE*)&valueDword, sizeof(DWORD));
486     if (lRet != ERROR_SUCCESS) {
487         error_code_messagebox(hwnd, lRet);
488         goto done;
489     }
490     result = TRUE;
491 
492 done:
493     RegCloseKey(hKey);
494     return result;
495 }
496 
497 BOOL RenameValue(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath, LPCWSTR oldName, LPCWSTR newName)
498 {
499     LPWSTR value = NULL;
500     DWORD type;
501     LONG len, lRet;
502     BOOL result = FALSE;
503     HKEY hKey;
504 
505     if (!oldName) return FALSE;
506     if (!newName) return FALSE;
507 
508     lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_READ | KEY_SET_VALUE, &hKey);
509     if (lRet != ERROR_SUCCESS) {
510         error_code_messagebox(hwnd, lRet);
511         return FALSE;
512     }
513     /* check if value already exists */
514     if (check_value(hwnd, hKey, newName)) goto done;
515     value = read_value(hwnd, hKey, oldName, &type, &len);
516     if(!value) goto done;
517     lRet = RegSetValueExW(hKey, newName, 0, type, (BYTE*)value, len);
518     if (lRet != ERROR_SUCCESS) {
519         error_code_messagebox(hwnd, lRet);
520         goto done;
521     }
522     lRet = RegDeleteValueW(hKey, oldName);
523     if (lRet != ERROR_SUCCESS) {
524         RegDeleteValueW(hKey, newName);
525         error_code_messagebox(hwnd, lRet);
526         goto done;
527     }
528     result = TRUE;
529 
530 done:
531     HeapFree(GetProcessHeap(), 0, value);
532     RegCloseKey(hKey);
533     return result;
534 }
535 
536 
537 BOOL RenameKey(HWND hwnd, HKEY hRootKey, LPCWSTR keyPath, LPCWSTR newName)
538 {
539     LPWSTR parentPath = 0;
540     LPCWSTR srcSubKey = 0;
541     HKEY parentKey = 0;
542     HKEY destKey = 0;
543     BOOL result = FALSE;
544     LONG lRet;
545     DWORD disposition;
546 
547     if (!keyPath || !newName) return FALSE;
548 
549     if (!strrchrW(keyPath, '\\')) {
550         parentKey = hRootKey;
551         srcSubKey = keyPath;
552     } else {
553         LPWSTR srcSubKey_copy;
554 
555         parentPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(keyPath)+1)*sizeof(WCHAR));
556         lstrcpyW(parentPath, keyPath);
557         srcSubKey_copy = strrchrW(parentPath, '\\');
558         *srcSubKey_copy = 0;
559         srcSubKey = srcSubKey_copy + 1;
560         lRet = RegOpenKeyExW(hRootKey, parentPath, 0, KEY_READ | KEY_CREATE_SUB_KEY, &parentKey);
561         if (lRet != ERROR_SUCCESS) {
562             error_code_messagebox(hwnd, lRet);
563             goto done;
564         }
565     }
566 
567     /* The following fails if the old name is the same as the new name. */
568     if (!lstrcmpW(srcSubKey, newName)) goto done;
569 
570     lRet = RegCreateKeyExW(parentKey, newName, 0, NULL, REG_OPTION_NON_VOLATILE,
571         KEY_WRITE, NULL /* FIXME */, &destKey, &disposition);
572     if (disposition == REG_OPENED_EXISTING_KEY)
573         lRet = ERROR_FILE_EXISTS; /* FIXME: we might want a better error message than this */
574     if (lRet != ERROR_SUCCESS) {
575         error_code_messagebox(hwnd, lRet);
576         goto done;
577     }
578 
579     /* FIXME: SHCopyKey does not copy the security attributes */
580     lRet = SHCopyKeyW(parentKey, srcSubKey, destKey, 0);
581     if (lRet != ERROR_SUCCESS) {
582         RegCloseKey(destKey);
583         RegDeleteKeyW(parentKey, newName);
584         error_code_messagebox(hwnd, lRet);
585         goto done;
586     }
587 
588     lRet = SHDeleteKeyW(hRootKey, keyPath);
589     if (lRet != ERROR_SUCCESS) {
590         error_code_messagebox(hwnd, lRet);
591         goto done;
592     }
593 
594     result = TRUE;
595 
596 done:
597     RegCloseKey(destKey);
598     if (parentKey) {
599         RegCloseKey(parentKey); 
600         HeapFree(GetProcessHeap(), 0, parentPath);
601     }
602     return result;
603 }
604 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.