4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org>
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.
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.
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 Street, Fifth Floor, Boston, MA 02110-1301 USA
27 /********************************************************************************
28 * Global and Local Variables:
31 #define FAVORITES_MENU_POSITION 3
33 static WCHAR s_szFavoritesRegKey
[] = L
"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites";
35 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
37 /*******************************************************************************
38 * Local module support methods
41 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
45 if (IsWindowVisible(hToolBar)) {
46 SendMessageW(hToolBar, WM_SIZE, 0, 0);
47 GetClientRect(hToolBar, &rt);
48 prect->top = rt.bottom+3;
49 prect->bottom -= rt.bottom+3;
52 if (IsWindowVisible(hStatusBar
))
54 SetupStatusBar(hWnd
, TRUE
);
55 GetClientRect(hStatusBar
, &rt
);
56 prect
->bottom
-= rt
.bottom
;
58 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
61 static void resize_frame_client(HWND hWnd
)
65 GetClientRect(hWnd
, &rect
);
66 resize_frame_rect(hWnd
, &rect
);
69 /********************************************************************************/
71 static void OnInitMenu(HWND hWnd
)
75 DWORD dwIndex
, cbValueName
, cbValueData
, dwType
;
76 WCHAR szValueName
[256];
77 BYTE abValueData
[256];
78 static int s_nFavoriteMenuSubPos
= -1;
80 BOOL bDisplayedAny
= FALSE
;
82 /* Find Favorites menu and clear it out */
83 hMenu
= GetSubMenu(GetMenu(hWnd
), FAVORITES_MENU_POSITION
);
86 if (s_nFavoriteMenuSubPos
< 0)
88 s_nFavoriteMenuSubPos
= GetMenuItemCount(hMenu
);
92 while(RemoveMenu(hMenu
, s_nFavoriteMenuSubPos
, MF_BYPOSITION
)) ;
95 lResult
= RegOpenKeyW(HKEY_CURRENT_USER
, s_szFavoritesRegKey
, &hKey
);
96 if (lResult
!= ERROR_SUCCESS
)
102 cbValueName
= COUNT_OF(szValueName
);
103 cbValueData
= sizeof(abValueData
);
104 lResult
= RegEnumValueW(hKey
, dwIndex
, szValueName
, &cbValueName
, NULL
, &dwType
, abValueData
, &cbValueData
);
105 if ((lResult
== ERROR_SUCCESS
) && (dwType
== REG_SZ
))
109 AppendMenu(hMenu
, MF_SEPARATOR
, 0, NULL
);
110 bDisplayedAny
= TRUE
;
112 AppendMenu(hMenu
, 0, ID_FAVORITES_MIN
+ GetMenuItemCount(hMenu
), szValueName
);
116 while(lResult
== ERROR_SUCCESS
);
123 static void OnEnterMenuLoop(HWND hWnd
)
126 UNREFERENCED_PARAMETER(hWnd
);
128 /* Update the status bar pane sizes */
130 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
132 SendMessageW(hStatusBar
, SB_SETTEXTW
, (WPARAM
)0, (LPARAM
)L
"");
135 static void OnExitMenuLoop(HWND hWnd
)
138 /* Update the status bar pane sizes*/
139 SetupStatusBar(hWnd
, TRUE
);
143 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
148 if (nFlags
& MF_POPUP
)
150 if (hSysMenu
!= GetMenu(hWnd
))
152 if (nItemID
== 2) nItemID
= 5;
155 if (LoadStringW(hInst
, nItemID
, str
, 100))
157 /* load appropriate string*/
159 /* first newline terminates actual string*/
160 lpsz
= wcschr(lpsz
, L
'\n');
164 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
167 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
171 GetClientRect(hWnd
, &rc
);
175 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
176 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
179 void UpdateStatusBar(void)
182 ZeroMemory(&nmhdr
, sizeof(NMHDR
));
183 nmhdr
.code
= TVN_SELCHANGED
;
184 SendMessageW(g_pChildWnd
->hWnd
, WM_NOTIFY
, (WPARAM
)TREE_WINDOW
, (LPARAM
)&nmhdr
);
187 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
189 BOOL vis
= IsWindowVisible(hchild
);
190 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
192 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
193 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
194 resize_frame_client(hWnd
);
197 static BOOL
CheckCommDlgError(HWND hWnd
)
199 DWORD dwErrorCode
= CommDlgExtendedError();
200 UNREFERENCED_PARAMETER(hWnd
);
203 case CDERR_DIALOGFAILURE
:
205 case CDERR_FINDRESFAILURE
:
207 case CDERR_NOHINSTANCE
:
209 case CDERR_INITIALIZATION
:
213 case CDERR_LOCKRESFAILURE
:
215 case CDERR_NOTEMPLATE
:
217 case CDERR_LOADRESFAILURE
:
219 case CDERR_STRUCTSIZE
:
221 case CDERR_LOADSTRFAILURE
:
223 case FNERR_BUFFERTOOSMALL
:
225 case CDERR_MEMALLOCFAILURE
:
227 case FNERR_INVALIDFILENAME
:
229 case CDERR_MEMLOCKFAILURE
:
231 case FNERR_SUBCLASSFAILURE
:
239 WCHAR FileNameBuffer
[_MAX_PATH
];
240 WCHAR FileTitleBuffer
[_MAX_PATH
];
246 } FILTERPAIR
, *PFILTERPAIR
;
249 BuildFilterStrings(WCHAR
*Filter
, PFILTERPAIR Pairs
, int PairCount
)
254 for(i
= 0; i
< PairCount
; i
++)
256 c
+= LoadStringW(hInst
, Pairs
[i
].DisplayID
, &Filter
[c
], 255);
258 c
+= LoadStringW(hInst
, Pairs
[i
].FilterID
, &Filter
[c
], 255);
264 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAME
* pofn
)
266 FILTERPAIR FilterPairs
[4];
267 static WCHAR Filter
[1024];
269 memset(pofn
, 0, sizeof(OPENFILENAME
));
270 pofn
->lStructSize
= sizeof(OPENFILENAME
);
271 pofn
->hwndOwner
= hWnd
;
272 pofn
->hInstance
= hInst
;
274 /* create filter string */
275 FilterPairs
[0].DisplayID
= IDS_FLT_REGFILES
;
276 FilterPairs
[0].FilterID
= IDS_FLT_REGFILES_FLT
;
277 FilterPairs
[1].DisplayID
= IDS_FLT_HIVFILES
;
278 FilterPairs
[1].FilterID
= IDS_FLT_HIVFILES_FLT
;
279 FilterPairs
[2].DisplayID
= IDS_FLT_REGEDIT4
;
280 FilterPairs
[2].FilterID
= IDS_FLT_REGEDIT4_FLT
;
281 FilterPairs
[3].DisplayID
= IDS_FLT_ALLFILES
;
282 FilterPairs
[3].FilterID
= IDS_FLT_ALLFILES_FLT
;
283 BuildFilterStrings(Filter
, FilterPairs
, COUNT_OF(FilterPairs
));
285 pofn
->lpstrFilter
= Filter
;
286 pofn
->lpstrFile
= FileNameBuffer
;
287 pofn
->nMaxFile
= _MAX_PATH
;
288 pofn
->lpstrFileTitle
= FileTitleBuffer
;
289 pofn
->nMaxFileTitle
= _MAX_PATH
;
290 pofn
->Flags
= OFN_HIDEREADONLY
;
291 pofn
->lpstrDefExt
= L
"reg";
295 #define LOADHIVE_KEYNAMELENGTH 128
297 static INT_PTR CALLBACK
LoadHive_KeyNameInHookProc(HWND hWndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
299 static LPWSTR sKey
= NULL
;
303 sKey
= (LPWSTR
)lParam
;
306 switch(LOWORD(wParam
))
309 if(GetDlgItemTextW(hWndDlg
, IDC_EDIT_KEY
, sKey
, LOADHIVE_KEYNAMELENGTH
))
310 return EndDialog(hWndDlg
, -1);
312 return EndDialog(hWndDlg
, 0);
314 return EndDialog(hWndDlg
, 0);
321 static BOOL
EnablePrivilege(LPCWSTR lpszPrivilegeName
, LPCWSTR lpszSystemName
, BOOL bEnablePrivilege
)
324 HANDLE hToken
= NULL
;
326 if (OpenProcessToken(GetCurrentProcess(),
327 TOKEN_ADJUST_PRIVILEGES
,
332 tp
.PrivilegeCount
= 1;
333 tp
.Privileges
[0].Attributes
= (bEnablePrivilege
? SE_PRIVILEGE_ENABLED
: 0);
335 if (LookupPrivilegeValueW(lpszSystemName
,
337 &tp
.Privileges
[0].Luid
))
339 bRet
= AdjustTokenPrivileges(hToken
, FALSE
, &tp
, 0, NULL
, NULL
);
341 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED
)
351 static BOOL
LoadHive(HWND hWnd
)
356 WCHAR xPath
[LOADHIVE_KEYNAMELENGTH
];
360 /* get the item key to load the hive in */
361 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
362 /* initialize the "open file" dialog */
363 InitOpenFileName(hWnd
, &ofn
);
364 /* build the "All Files" filter up */
365 filter
.DisplayID
= IDS_FLT_ALLFILES
;
366 filter
.FilterID
= IDS_FLT_ALLFILES_FLT
;
367 BuildFilterStrings(Filter
, &filter
, 1);
368 ofn
.lpstrFilter
= Filter
;
369 /* load and set the caption and flags for dialog */
370 LoadStringW(hInst
, IDS_LOAD_HIVE
, Caption
, COUNT_OF(Caption
));
371 ofn
.lpstrTitle
= Caption
;
372 ofn
.Flags
|= OFN_ENABLESIZING
;
373 /* ofn.lCustData = ;*/
374 /* now load the hive */
375 if (GetOpenFileName(&ofn
))
377 if (DialogBoxParamW(hInst
, MAKEINTRESOURCEW(IDD_LOADHIVE
), hWnd
,
378 &LoadHive_KeyNameInHookProc
, (LPARAM
)xPath
))
382 /* Enable the 'restore' privilege, load the hive, disable the privilege */
383 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
384 regLoadResult
= RegLoadKeyW(hRootKey
, xPath
, ofn
.lpstrFile
);
385 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
387 if(regLoadResult
== ERROR_SUCCESS
)
389 /* refresh tree and list views */
390 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
391 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
392 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
396 ErrorMessageBox(hWnd
, Caption
, regLoadResult
);
403 CheckCommDlgError(hWnd
);
408 static BOOL
UnloadHive(HWND hWnd
)
413 LONG regUnloadResult
;
415 /* get the item key to unload */
416 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
417 /* load and set the caption and flags for dialog */
418 LoadStringW(hInst
, IDS_UNLOAD_HIVE
, Caption
, COUNT_OF(Caption
));
420 /* Enable the 'restore' privilege, unload the hive, disable the privilege */
421 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
422 regUnloadResult
= RegUnLoadKeyW(hRootKey
, pszKeyPath
);
423 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
425 if(regUnloadResult
== ERROR_SUCCESS
)
427 /* refresh tree and list views */
428 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
429 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
430 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
434 ErrorMessageBox(hWnd
, Caption
, regUnloadResult
);
440 static BOOL
ImportRegistryFile(HWND hWnd
)
444 WCHAR Caption
[128], szTitle
[512], szText
[512];
448 /* Figure out in which key path we are importing */
449 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
451 InitOpenFileName(hWnd
, &ofn
);
452 LoadStringW(hInst
, IDS_IMPORT_REG_FILE
, Caption
, COUNT_OF(Caption
));
453 ofn
.lpstrTitle
= Caption
;
454 ofn
.Flags
|= OFN_ENABLESIZING
;
455 /* ofn.lCustData = ;*/
456 if (GetOpenFileName(&ofn
))
458 /* Look at the extension of the file to determine its type */
459 if (ofn
.nFileExtension
>= 1 &&
460 _wcsicmp(ofn
.lpstrFile
+ ofn
.nFileExtension
, L
"reg") == 0) /* REGEDIT4 or Windows Registry Editor Version 5.00 */
463 FILE* fp
= _wfopen(ofn
.lpstrFile
, L
"r");
466 if (fp
== NULL
|| !import_registry_file(fp
))
468 /* Error opening the file */
469 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
470 LoadStringW(hInst
, IDS_IMPORT_ERROR
, szText
, COUNT_OF(szText
));
471 InfoMessageBox(hWnd
, MB_OK
| MB_ICONERROR
, szTitle
, szText
, ofn
.lpstrFile
);
476 /* Show successful import */
477 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
478 LoadStringW(hInst
, IDS_IMPORT_OK
, szText
, COUNT_OF(szText
));
479 InfoMessageBox(hWnd
, MB_OK
| MB_ICONINFORMATION
, szTitle
, szText
, ofn
.lpstrFile
);
486 else /* Registry Hive Files */
488 LoadStringW(hInst
, IDS_QUERY_IMPORT_HIVE_CAPTION
, szTitle
, COUNT_OF(szTitle
));
489 LoadStringW(hInst
, IDS_QUERY_IMPORT_HIVE_MSG
, szText
, COUNT_OF(szText
));
491 /* Display a confirmation message */
492 if (MessageBoxW(g_pChildWnd
->hWnd
, szText
, szTitle
, MB_ICONWARNING
| MB_YESNO
) == IDYES
)
497 /* Open the subkey */
498 lResult
= RegOpenKeyExW(hKeyRoot
, pszKeyPath
, 0, KEY_WRITE
, &hSubKey
);
499 if (lResult
== ERROR_SUCCESS
)
501 /* Enable the 'restore' privilege, restore the hive then disable the privilege */
502 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
503 lResult
= RegRestoreKey(hSubKey
, ofn
.lpstrFile
, REG_FORCE_RESTORE
);
504 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
506 /* Flush the subkey and close it */
507 RegFlushKey(hSubKey
);
508 RegCloseKey(hSubKey
);
511 /* Set the return value */
512 bRet
= (lResult
== ERROR_SUCCESS
);
514 /* Display error, if any */
515 if (!bRet
) ErrorMessageBox(hWnd
, Caption
, lResult
);
521 CheckCommDlgError(hWnd
);
524 /* refresh tree and list views */
525 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
526 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
527 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, pszKeyPath
);
532 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
535 HWND hwndExportBranch
;
536 HWND hwndExportBranchText
;
537 UINT_PTR iResult
= 0;
539 LPWSTR pszSelectedKey
;
540 OFNOTIFY
*pOfnNotify
;
542 UNREFERENCED_PARAMETER(wParam
);
547 pOfn
= (OPENFILENAME
*) lParam
;
548 pszSelectedKey
= (LPWSTR
) pOfn
->lCustData
;
550 hwndExportAll
= GetDlgItem(hdlg
, IDC_EXPORT_ALL
);
552 SendMessageW(hwndExportAll
, BM_SETCHECK
, pszSelectedKey
? BST_UNCHECKED
: BST_CHECKED
, 0);
554 hwndExportBranch
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH
);
555 if (hwndExportBranch
)
556 SendMessageW(hwndExportBranch
, BM_SETCHECK
, pszSelectedKey
? BST_CHECKED
: BST_UNCHECKED
, 0);
558 hwndExportBranchText
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH_TEXT
);
559 if (hwndExportBranchText
)
560 SetWindowTextW(hwndExportBranchText
, pszSelectedKey
);
564 if (((NMHDR
*) lParam
)->code
== CDN_FILEOK
)
566 pOfnNotify
= (OFNOTIFY
*) lParam
;
567 pszSelectedKey
= (LPWSTR
) pOfnNotify
->lpOFN
->lCustData
;
569 hwndExportBranch
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH
);
570 hwndExportBranchText
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH_TEXT
);
571 if (hwndExportBranch
&& hwndExportBranchText
572 && (SendMessageW(hwndExportBranch
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
574 GetWindowTextW(hwndExportBranchText
, pszSelectedKey
, _MAX_PATH
);
578 pszSelectedKey
[0] = L
'\0';
586 BOOL
ExportRegistryFile(HWND hWnd
)
590 WCHAR ExportKeyPath
[_MAX_PATH
];
591 WCHAR Caption
[128], szTitle
[512], szText
[512];
595 /* Figure out which key path we are exporting */
596 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
597 GetKeyName(ExportKeyPath
, COUNT_OF(ExportKeyPath
), hKeyRoot
, pszKeyPath
);
599 InitOpenFileName(hWnd
, &ofn
);
600 LoadStringW(hInst
, IDS_EXPORT_REG_FILE
, Caption
, COUNT_OF(Caption
));
601 ofn
.lpstrTitle
= Caption
;
603 /* Only set the path if a key (not the root node) is selected */
606 ofn
.lCustData
= (LPARAM
) ExportKeyPath
;
608 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_EXPLORER
| OFN_ENABLEHOOK
| OFN_OVERWRITEPROMPT
;
609 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
610 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORTRANGE
);
611 if (GetSaveFileName(&ofn
))
613 switch (ofn
.nFilterIndex
)
615 case 2: /* Registry Hive Files */
620 /* Open the subkey */
621 lResult
= RegOpenKeyExW(hKeyRoot
, pszKeyPath
, 0, KEY_READ
, &hSubKey
);
622 if (lResult
== ERROR_SUCCESS
)
624 /* Enable the 'backup' privilege, save the hive then disable the privilege */
625 EnablePrivilege(SE_BACKUP_NAME
, NULL
, TRUE
);
626 lResult
= RegSaveKeyW(hSubKey
, ofn
.lpstrFile
, NULL
);
627 if (lResult
== ERROR_ALREADY_EXISTS
)
630 * We are here, that means that we already said "yes" to the confirmation dialog.
631 * So we absolutely want to replace the hive file.
633 if (DeleteFileW(ofn
.lpstrFile
))
636 lResult
= RegSaveKeyW(hSubKey
, ofn
.lpstrFile
, NULL
);
639 EnablePrivilege(SE_BACKUP_NAME
, NULL
, FALSE
);
641 if (lResult
!= ERROR_SUCCESS
)
644 * If we are here, it's because RegSaveKeyW has failed for any reason.
645 * The problem is that even if it has failed, it has created or
646 * replaced the exported hive file with a new empty file. We don't
647 * want to keep this file, so we delete it.
649 DeleteFileW(ofn
.lpstrFile
);
652 /* Close the subkey */
653 RegCloseKey(hSubKey
);
656 /* Set the return value */
657 bRet
= (lResult
== ERROR_SUCCESS
);
659 /* Display error, if any */
660 if (!bRet
) ErrorMessageBox(hWnd
, Caption
, lResult
);
665 case 1: /* Windows Registry Editor Version 5.00 */
666 case 3: /* REGEDIT4 */
667 default: /* All files ==> use Windows Registry Editor Version 5.00 */
669 if (!export_registry_key(ofn
.lpstrFile
, ExportKeyPath
,
670 (ofn
.nFilterIndex
== 3 ? REG_FORMAT_4
673 /* Error creating the file */
674 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
675 LoadStringW(hInst
, IDS_EXPORT_ERROR
, szText
, COUNT_OF(szText
));
676 InfoMessageBox(hWnd
, MB_OK
| MB_ICONERROR
, szTitle
, szText
, ofn
.lpstrFile
);
690 CheckCommDlgError(hWnd
);
696 BOOL
PrintRegistryHive(HWND hWnd
, LPWSTR path
)
700 UNREFERENCED_PARAMETER(path
);
702 ZeroMemory(&pd
, sizeof(PRINTDLG
));
703 pd
.lStructSize
= sizeof(PRINTDLG
);
705 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
706 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
707 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
709 pd
.nFromPage
= 0xFFFF;
712 pd
.nMaxPage
= 0xFFFF;
715 /* GDI calls to render output. */
716 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
722 hResult
= PrintDlgEx(&pd
);
725 switch (pd
.dwResultAction
)
727 case PD_RESULT_APPLY
:
728 /*The user clicked the Apply button and later clicked the Cancel button. This indicates that the user wants to apply the changes made in the property sheet, but does not yet want to print. The PRINTDLGEX structure contains the information specified by the user at the time the Apply button was clicked. */
730 case PD_RESULT_CANCEL
:
731 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
733 case PD_RESULT_PRINT
:
734 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
745 /*Insufficient memory. */
748 /* One or more arguments are invalid. */
751 /*Invalid pointer. */
757 /*Unspecified error. */
768 static void ChooseFavorite(LPCWSTR pszFavorite
)
771 WCHAR szFavoritePath
[512];
772 DWORD cbData
, dwType
;
774 if (RegOpenKeyExW(HKEY_CURRENT_USER
, s_szFavoritesRegKey
, 0, KEY_QUERY_VALUE
, &hKey
) != ERROR_SUCCESS
)
777 cbData
= (sizeof(szFavoritePath
) / sizeof(szFavoritePath
[0])) - 1;
778 memset(szFavoritePath
, 0, sizeof(szFavoritePath
));
779 if (RegQueryValueExW(hKey
, pszFavorite
, NULL
, &dwType
, (LPBYTE
) szFavoritePath
, &cbData
) != ERROR_SUCCESS
)
782 if (dwType
== REG_SZ
)
783 SelectNode(g_pChildWnd
->hTreeWnd
, szFavoritePath
);
790 BOOL
CopyKeyName(HWND hWnd
, HKEY hRootKey
, LPCWSTR keyName
)
792 BOOL bClipboardOpened
= FALSE
;
793 BOOL bSuccess
= FALSE
;
798 if (!OpenClipboard(hWnd
))
800 bClipboardOpened
= TRUE
;
802 if (!EmptyClipboard())
805 if (!GetKeyName(szBuffer
, COUNT_OF(szBuffer
), hRootKey
, keyName
))
808 hGlobal
= GlobalAlloc(GMEM_MOVEABLE
, (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
812 s
= GlobalLock(hGlobal
);
814 GlobalUnlock(hGlobal
);
816 SetClipboardData(CF_UNICODETEXT
, hGlobal
);
820 if (bClipboardOpened
)
825 static BOOL
CreateNewValue(HKEY hRootKey
, LPCWSTR pszKeyPath
, DWORD dwType
)
827 WCHAR szNewValueFormat
[128];
828 WCHAR szNewValue
[128];
831 DWORD dwExistingType
, cbData
;
836 if (RegOpenKeyExW(hRootKey
, pszKeyPath
, 0, KEY_QUERY_VALUE
| KEY_SET_VALUE
,
837 &hKey
) != ERROR_SUCCESS
)
840 LoadStringW(hInst
, IDS_NEW_VALUE
, szNewValueFormat
, COUNT_OF(szNewValueFormat
));
844 wsprintf(szNewValue
, szNewValueFormat
, iIndex
++);
845 cbData
= sizeof(data
);
846 lResult
= RegQueryValueExW(hKey
, szNewValue
, NULL
, &dwExistingType
, data
, &cbData
);
848 while(lResult
== ERROR_SUCCESS
);
853 cbData
= sizeof(DWORD
);
857 cbData
= sizeof(WCHAR
);
861 * WARNING: An empty multi-string has only one null char.
862 * Indeed, multi-strings are built in the following form:
863 * str1\0str2\0...strN\0\0
864 * where each strI\0 is a null-terminated string, and it
865 * ends with a terminating empty string.
866 * Therefore an empty multi-string contains only the terminating
867 * empty string, that is, one null char.
869 cbData
= sizeof(WCHAR
);
871 case REG_QWORD
: /* REG_QWORD_LITTLE_ENDIAN */
872 cbData
= sizeof(DWORDLONG
); // == sizeof(DWORD) * 2;
878 memset(data
, 0, cbData
);
879 lResult
= RegSetValueExW(hKey
, szNewValue
, 0, dwType
, data
, cbData
);
881 if (lResult
!= ERROR_SUCCESS
)
886 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
888 /* locate the newly added value, and get ready to rename it */
889 memset(&lvfi
, 0, sizeof(lvfi
));
890 lvfi
.flags
= LVFI_STRING
;
891 lvfi
.psz
= szNewValue
;
892 iIndex
= ListView_FindItem(g_pChildWnd
->hListWnd
, -1, &lvfi
);
894 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, iIndex
);
900 InitializeRemoteRegistryPicker(OUT IDsObjectPicker
**pDsObjectPicker
)
904 *pDsObjectPicker
= NULL
;
906 hRet
= CoCreateInstance(&CLSID_DsObjectPicker
,
908 CLSCTX_INPROC_SERVER
,
909 &IID_IDsObjectPicker
,
910 (LPVOID
*)pDsObjectPicker
);
913 DSOP_INIT_INFO InitInfo
;
914 static DSOP_SCOPE_INIT_INFO Scopes
[] =
917 sizeof(DSOP_SCOPE_INIT_INFO
),
918 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
| DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE
|
919 DSOP_SCOPE_TYPE_GLOBAL_CATALOG
| DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
|
920 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
| DSOP_SCOPE_TYPE_WORKGROUP
|
921 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN
,
925 DSOP_FILTER_COMPUTERS
,
929 DSOP_DOWNLEVEL_FILTER_COMPUTERS
937 InitInfo
.cbSize
= sizeof(InitInfo
);
938 InitInfo
.pwzTargetComputer
= NULL
;
939 InitInfo
.cDsScopeInfos
= COUNT_OF(Scopes
);
940 InitInfo
.aDsScopeInfos
= Scopes
;
941 InitInfo
.flOptions
= 0;
942 InitInfo
.cAttributesToFetch
= 0;
943 InitInfo
.apwzAttributeNames
= NULL
;
945 hRet
= (*pDsObjectPicker
)->lpVtbl
->Initialize(*pDsObjectPicker
,
950 /* delete the object picker in case initialization failed! */
951 (*pDsObjectPicker
)->lpVtbl
->Release(*pDsObjectPicker
);
959 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker
*pDsObjectPicker
,
960 IN HWND hwndParent OPTIONAL
,
964 IDataObject
*pdo
= NULL
;
967 hRet
= pDsObjectPicker
->lpVtbl
->InvokeDialog(pDsObjectPicker
,
975 fe
.cfFormat
= (CLIPFORMAT
) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST
);
977 fe
.dwAspect
= DVASPECT_CONTENT
;
979 fe
.tymed
= TYMED_HGLOBAL
;
981 hRet
= pdo
->lpVtbl
->GetData(pdo
,
986 PDS_SELECTION_LIST SelectionList
= (PDS_SELECTION_LIST
)GlobalLock(stm
.hGlobal
);
987 if (SelectionList
!= NULL
)
989 if (SelectionList
->cItems
== 1)
991 size_t nlen
= wcslen(SelectionList
->aDsSelection
[0].pwzName
);
998 SelectionList
->aDsSelection
[0].pwzName
,
999 nlen
* sizeof(WCHAR
));
1001 lpBuffer
[nlen
] = L
'\0';
1004 GlobalUnlock(stm
.hGlobal
);
1007 ReleaseStgMedium(&stm
);
1010 pdo
->lpVtbl
->Release(pdo
);
1017 FreeObjectPicker(IN IDsObjectPicker
*pDsObjectPicker
)
1019 pDsObjectPicker
->lpVtbl
->Release(pDsObjectPicker
);
1022 /*******************************************************************************
1024 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
1026 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
1029 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1031 HKEY hKeyRoot
= 0, hKey
= 0;
1035 REGSAM regsam
= KEY_READ
;
1039 UNREFERENCED_PARAMETER(lParam
);
1040 UNREFERENCED_PARAMETER(message
);
1042 switch (LOWORD(wParam
))
1044 case ID_REGISTRY_LOADHIVE
:
1047 case ID_REGISTRY_UNLOADHIVE
:
1050 case ID_REGISTRY_IMPORTREGISTRYFILE
:
1051 ImportRegistryFile(hWnd
);
1053 case ID_REGISTRY_EXPORTREGISTRYFILE
:
1054 ExportRegistryFile(hWnd
);
1056 case ID_REGISTRY_CONNECTNETWORKREGISTRY
:
1058 IDsObjectPicker
*ObjectPicker
;
1059 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1062 hRet
= CoInitialize(NULL
);
1063 if (SUCCEEDED(hRet
))
1065 hRet
= InitializeRemoteRegistryPicker(&ObjectPicker
);
1066 if (SUCCEEDED(hRet
))
1068 hRet
= InvokeRemoteRegistryPickerDialog(ObjectPicker
,
1071 COUNT_OF(szComputerName
));
1074 /* FIXME - connect to the registry */
1077 FreeObjectPicker(ObjectPicker
);
1085 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY
:
1087 case ID_REGISTRY_PRINT
:
1088 PrintRegistryHive(hWnd
, L
"");
1090 case ID_REGISTRY_EXIT
:
1091 DestroyWindow(hWnd
);
1093 case ID_VIEW_STATUSBAR
:
1094 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1096 case ID_HELP_HELPTOPICS
:
1097 WinHelpW(hWnd
, getAppName(), HELP_FINDER
, 0);
1106 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1107 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1108 pt
.y
= (rt
.bottom
/ 2);
1110 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
))
1112 SetCursorPos(pts
.x
, pts
.y
);
1113 SetCursor(LoadCursorW(0, IDC_SIZEWE
));
1114 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1118 case ID_EDIT_RENAME
:
1119 case ID_EDIT_MODIFY
:
1120 case ID_EDIT_MODIFY_BIN
:
1121 case ID_EDIT_DELETE
:
1122 regsam
|= KEY_WRITE
;
1126 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1127 valueName
= GetValueName(g_pChildWnd
->hListWnd
, -1);
1130 lRet
= RegOpenKeyExW(hKeyRoot
, keyPath
, 0, regsam
, &hKey
);
1131 if (lRet
!= ERROR_SUCCESS
) hKey
= 0;
1134 switch (LOWORD(wParam
))
1136 case ID_EDIT_MODIFY
:
1137 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, FALSE
))
1138 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1140 case ID_EDIT_MODIFY_BIN
:
1141 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, TRUE
))
1142 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1144 case ID_EDIT_RENAME
:
1145 if (GetFocus() == g_pChildWnd
->hListWnd
)
1147 if(ListView_GetSelectedCount(g_pChildWnd
->hListWnd
) == 1)
1149 item
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, -1, LVNI_SELECTED
);
1152 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, item
);
1156 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1158 /* Get focused entry of treeview (if any) */
1159 HTREEITEM hItem
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
1161 (void)TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, hItem
);
1164 case ID_EDIT_DELETE
:
1166 if (GetFocus() == g_pChildWnd
->hListWnd
)
1168 UINT nSelected
= ListView_GetSelectedCount(g_pChildWnd
->hListWnd
);
1171 WCHAR msg
[128], caption
[128];
1172 LoadStringW(hInst
, IDS_QUERY_DELETE_CONFIRM
, caption
, COUNT_OF(caption
));
1173 LoadStringW(hInst
, (nSelected
== 1 ? IDS_QUERY_DELETE_ONE
: IDS_QUERY_DELETE_MORE
), msg
, COUNT_OF(msg
));
1174 if(MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONQUESTION
| MB_YESNO
) == IDYES
)
1180 while((ni
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, item
, LVNI_SELECTED
)) > -1)
1182 valueName
= GetValueName(g_pChildWnd
->hListWnd
, item
);
1183 if(RegDeleteValueW(hKey
, valueName
) != ERROR_SUCCESS
)
1190 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1193 LoadStringW(hInst
, IDS_ERR_DELVAL_CAPTION
, caption
, COUNT_OF(caption
));
1194 LoadStringW(hInst
, IDS_ERR_DELETEVALUE
, msg
, COUNT_OF(msg
));
1195 MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONSTOP
);
1200 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1202 if (keyPath
== 0 || *keyPath
== 0)
1204 MessageBeep(MB_ICONHAND
);
1206 else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
))
1208 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
1209 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1214 case ID_EDIT_NEW_STRINGVALUE
:
1215 CreateNewValue(hKeyRoot
, keyPath
, REG_SZ
);
1217 case ID_EDIT_NEW_BINARYVALUE
:
1218 CreateNewValue(hKeyRoot
, keyPath
, REG_BINARY
);
1220 case ID_EDIT_NEW_DWORDVALUE
:
1221 CreateNewValue(hKeyRoot
, keyPath
, REG_DWORD
);
1223 case ID_EDIT_NEW_MULTISTRINGVALUE
:
1224 CreateNewValue(hKeyRoot
, keyPath
, REG_MULTI_SZ
);
1226 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE
:
1227 CreateNewValue(hKeyRoot
, keyPath
, REG_EXPAND_SZ
);
1232 case ID_EDIT_FINDNEXT
:
1235 case ID_EDIT_COPYKEYNAME
:
1236 CopyKeyName(hWnd
, hKeyRoot
, keyPath
);
1238 case ID_EDIT_PERMISSIONS
:
1239 RegKeyEditPermissions(hWnd
, hKeyRoot
, NULL
, keyPath
);
1241 case ID_REGISTRY_PRINTERSETUP
:
1244 /*PAGESETUPDLG psd;*/
1245 /*PageSetupDlg(&psd);*/
1247 case ID_REGISTRY_OPENLOCAL
:
1250 case ID_VIEW_REFRESH
:
1251 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1252 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1253 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1255 /*case ID_OPTIONS_TOOLBAR:*/
1256 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1258 case ID_EDIT_NEW_KEY
:
1259 CreateNewKey(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
1262 if ((LOWORD(wParam
) >= ID_FAVORITES_MIN
) && (LOWORD(wParam
) <= ID_FAVORITES_MAX
))
1266 WCHAR szFavorite
[512];
1268 hMenu
= GetSubMenu(GetMenu(hWnd
), FAVORITES_MENU_POSITION
);
1270 memset(&mii
, 0, sizeof(mii
));
1271 mii
.cbSize
= sizeof(mii
);
1272 mii
.fMask
= MIIM_TYPE
;
1273 mii
.fType
= MFT_STRING
;
1274 mii
.dwTypeData
= szFavorite
;
1275 mii
.cch
= COUNT_OF(szFavorite
);
1277 if (GetMenuItemInfo(hMenu
, LOWORD(wParam
) - ID_FAVORITES_MIN
, TRUE
, &mii
))
1279 ChooseFavorite(szFavorite
);
1294 /********************************************************************************
1296 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1298 * PURPOSE: Processes messages for the main frame window.
1300 * WM_COMMAND - process the application menu
1301 * WM_DESTROY - post a quit message and return
1305 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1310 CreateWindowExW(0, szChildClass
, NULL
, WS_CHILD
| WS_VISIBLE
,
1311 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1312 hWnd
, (HMENU
)0, hInst
, 0);
1315 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1316 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1320 SetFocus(g_pChildWnd
->hWnd
);
1323 resize_frame_client(hWnd
);
1330 case WM_ENTERMENULOOP
:
1331 OnEnterMenuLoop(hWnd
);
1333 case WM_EXITMENULOOP
:
1334 OnExitMenuLoop(hWnd
);
1337 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1339 case WM_SYSCOLORCHANGE
:
1340 /* Forward WM_SYSCOLORCHANGE to common controls */
1341 SendMessageW(g_pChildWnd
->hListWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1342 SendMessageW(g_pChildWnd
->hTreeWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1345 WinHelpW(hWnd
, getAppName(), HELP_QUIT
, 0);
1349 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);