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
23 /********************************************************************************
24 * Global and Local Variables:
27 #define FAVORITES_MENU_POSITION 3
29 static WCHAR s_szFavoritesRegKey
[] = L
"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites";
31 static BOOL bInMenuLoop
= FALSE
; /* Tells us if we are in the menu loop */
33 /*******************************************************************************
34 * Local module support methods
37 static void resize_frame_rect(HWND hWnd
, PRECT prect
)
41 if (IsWindowVisible(hToolBar)) {
42 SendMessageW(hToolBar, WM_SIZE, 0, 0);
43 GetClientRect(hToolBar, &rt);
44 prect->top = rt.bottom+3;
45 prect->bottom -= rt.bottom+3;
48 if (IsWindowVisible(hStatusBar
))
50 SetupStatusBar(hWnd
, TRUE
);
51 GetClientRect(hStatusBar
, &rt
);
52 prect
->bottom
-= rt
.bottom
;
54 MoveWindow(g_pChildWnd
->hWnd
, prect
->left
, prect
->top
, prect
->right
, prect
->bottom
, TRUE
);
57 static void resize_frame_client(HWND hWnd
)
61 GetClientRect(hWnd
, &rect
);
62 resize_frame_rect(hWnd
, &rect
);
65 /********************************************************************************/
67 static void OnInitMenu(HWND hWnd
)
71 DWORD dwIndex
, cbValueName
, cbValueData
, dwType
;
72 WCHAR szValueName
[256];
73 BYTE abValueData
[256];
74 static int s_nFavoriteMenuSubPos
= -1;
76 BOOL bDisplayedAny
= FALSE
;
78 /* Find Favorites menu and clear it out */
79 hMenu
= GetSubMenu(GetMenu(hWnd
), FAVORITES_MENU_POSITION
);
82 if (s_nFavoriteMenuSubPos
< 0)
84 s_nFavoriteMenuSubPos
= GetMenuItemCount(hMenu
);
88 while(RemoveMenu(hMenu
, s_nFavoriteMenuSubPos
, MF_BYPOSITION
)) ;
91 lResult
= RegOpenKeyW(HKEY_CURRENT_USER
, s_szFavoritesRegKey
, &hKey
);
92 if (lResult
!= ERROR_SUCCESS
)
98 cbValueName
= COUNT_OF(szValueName
);
99 cbValueData
= sizeof(abValueData
);
100 lResult
= RegEnumValueW(hKey
, dwIndex
, szValueName
, &cbValueName
, NULL
, &dwType
, abValueData
, &cbValueData
);
101 if ((lResult
== ERROR_SUCCESS
) && (dwType
== REG_SZ
))
105 AppendMenu(hMenu
, MF_SEPARATOR
, 0, NULL
);
106 bDisplayedAny
= TRUE
;
108 AppendMenu(hMenu
, 0, ID_FAVORITES_MIN
+ GetMenuItemCount(hMenu
), szValueName
);
112 while(lResult
== ERROR_SUCCESS
);
119 static void OnEnterMenuLoop(HWND hWnd
)
122 UNREFERENCED_PARAMETER(hWnd
);
124 /* Update the status bar pane sizes */
126 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
128 SendMessageW(hStatusBar
, SB_SETTEXTW
, (WPARAM
)0, (LPARAM
)L
"");
131 static void OnExitMenuLoop(HWND hWnd
)
134 /* Update the status bar pane sizes*/
135 SetupStatusBar(hWnd
, TRUE
);
139 static void OnMenuSelect(HWND hWnd
, UINT nItemID
, UINT nFlags
, HMENU hSysMenu
)
144 if (nFlags
& MF_POPUP
)
146 if (hSysMenu
!= GetMenu(hWnd
))
148 if (nItemID
== 2) nItemID
= 5;
151 if (LoadStringW(hInst
, nItemID
, str
, 100))
153 /* load appropriate string*/
155 /* first newline terminates actual string*/
156 lpsz
= wcschr(lpsz
, L
'\n');
160 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)str
);
163 void SetupStatusBar(HWND hWnd
, BOOL bResize
)
167 GetClientRect(hWnd
, &rc
);
171 SendMessageW(hStatusBar
, WM_SIZE
, 0, 0);
172 SendMessageW(hStatusBar
, SB_SETPARTS
, 1, (LPARAM
)&nParts
);
175 void UpdateStatusBar(void)
178 ZeroMemory(&nmhdr
, sizeof(NMHDR
));
179 nmhdr
.code
= TVN_SELCHANGED
;
180 SendMessageW(g_pChildWnd
->hWnd
, WM_NOTIFY
, (WPARAM
)TREE_WINDOW
, (LPARAM
)&nmhdr
);
183 static void toggle_child(HWND hWnd
, UINT cmd
, HWND hchild
)
185 BOOL vis
= IsWindowVisible(hchild
);
186 HMENU hMenuView
= GetSubMenu(hMenuFrame
, ID_VIEW_MENU
);
188 CheckMenuItem(hMenuView
, cmd
, vis
?MF_BYCOMMAND
:MF_BYCOMMAND
|MF_CHECKED
);
189 ShowWindow(hchild
, vis
?SW_HIDE
:SW_SHOW
);
190 resize_frame_client(hWnd
);
193 static BOOL
CheckCommDlgError(HWND hWnd
)
195 DWORD dwErrorCode
= CommDlgExtendedError();
196 UNREFERENCED_PARAMETER(hWnd
);
199 case CDERR_DIALOGFAILURE
:
201 case CDERR_FINDRESFAILURE
:
203 case CDERR_NOHINSTANCE
:
205 case CDERR_INITIALIZATION
:
209 case CDERR_LOCKRESFAILURE
:
211 case CDERR_NOTEMPLATE
:
213 case CDERR_LOADRESFAILURE
:
215 case CDERR_STRUCTSIZE
:
217 case CDERR_LOADSTRFAILURE
:
219 case FNERR_BUFFERTOOSMALL
:
221 case CDERR_MEMALLOCFAILURE
:
223 case FNERR_INVALIDFILENAME
:
225 case CDERR_MEMLOCKFAILURE
:
227 case FNERR_SUBCLASSFAILURE
:
235 WCHAR FileNameBuffer
[_MAX_PATH
];
236 WCHAR FileTitleBuffer
[_MAX_PATH
];
242 } FILTERPAIR
, *PFILTERPAIR
;
245 BuildFilterStrings(WCHAR
*Filter
, PFILTERPAIR Pairs
, int PairCount
)
250 for(i
= 0; i
< PairCount
; i
++)
252 c
+= LoadStringW(hInst
, Pairs
[i
].DisplayID
, &Filter
[c
], 255 * sizeof(WCHAR
));
254 c
+= LoadStringW(hInst
, Pairs
[i
].FilterID
, &Filter
[c
], 255 * sizeof(WCHAR
));
260 static BOOL
InitOpenFileName(HWND hWnd
, OPENFILENAME
* pofn
)
262 FILTERPAIR FilterPairs
[4];
263 static WCHAR Filter
[1024];
265 memset(pofn
, 0, sizeof(OPENFILENAME
));
266 pofn
->lStructSize
= sizeof(OPENFILENAME
);
267 pofn
->hwndOwner
= hWnd
;
268 pofn
->hInstance
= hInst
;
270 /* create filter string */
271 FilterPairs
[0].DisplayID
= IDS_FLT_REGFILES
;
272 FilterPairs
[0].FilterID
= IDS_FLT_REGFILES_FLT
;
273 FilterPairs
[1].DisplayID
= IDS_FLT_HIVFILES
;
274 FilterPairs
[1].FilterID
= IDS_FLT_HIVFILES_FLT
;
275 FilterPairs
[2].DisplayID
= IDS_FLT_REGEDIT4
;
276 FilterPairs
[2].FilterID
= IDS_FLT_REGEDIT4_FLT
;
277 FilterPairs
[3].DisplayID
= IDS_FLT_ALLFILES
;
278 FilterPairs
[3].FilterID
= IDS_FLT_ALLFILES_FLT
;
279 BuildFilterStrings(Filter
, FilterPairs
, COUNT_OF(FilterPairs
));
281 pofn
->lpstrFilter
= Filter
;
282 pofn
->lpstrFile
= FileNameBuffer
;
283 pofn
->nMaxFile
= _MAX_PATH
;
284 pofn
->lpstrFileTitle
= FileTitleBuffer
;
285 pofn
->nMaxFileTitle
= _MAX_PATH
;
286 pofn
->Flags
= OFN_HIDEREADONLY
;
287 pofn
->lpstrDefExt
= L
"reg";
291 static INT_PTR CALLBACK
LoadHive_KeyNameInHookProc(HWND hWndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
293 static LPWSTR sKey
= NULL
;
294 static INT sLength
= 0;
298 sKey
= (LPWSTR
)lParam
;
299 sLength
= 128; /* FIXME: Ugly hack! */
301 switch(LOWORD(wParam
))
304 if(GetDlgItemTextW(hWndDlg
, IDC_EDIT_KEY
, sKey
, sLength
))
305 return EndDialog(hWndDlg
, -1);
307 return EndDialog(hWndDlg
, 0);
309 return EndDialog(hWndDlg
, 0);
316 static BOOL
EnablePrivilege(LPCWSTR lpszPrivilegeName
, LPCWSTR lpszSystemName
, BOOL bEnablePrivilege
)
319 HANDLE hToken
= NULL
;
321 if (OpenProcessToken(GetCurrentProcess(),
322 TOKEN_ADJUST_PRIVILEGES
,
327 tp
.PrivilegeCount
= 1;
328 tp
.Privileges
[0].Attributes
= (bEnablePrivilege
? SE_PRIVILEGE_ENABLED
: 0);
330 if (LookupPrivilegeValueW(lpszSystemName
,
332 &tp
.Privileges
[0].Luid
))
334 bRet
= AdjustTokenPrivileges(hToken
, FALSE
, &tp
, 0, NULL
, NULL
);
336 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED
)
346 static BOOL
LoadHive(HWND hWnd
)
355 /* get the item key to load the hive in */
356 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
357 /* initialize the "open file" dialog */
358 InitOpenFileName(hWnd
, &ofn
);
359 /* build the "All Files" filter up */
360 filter
.DisplayID
= IDS_FLT_ALLFILES
;
361 filter
.FilterID
= IDS_FLT_ALLFILES_FLT
;
362 BuildFilterStrings(Filter
, &filter
, sizeof(filter
));
363 ofn
.lpstrFilter
= Filter
;
364 /* load and set the caption and flags for dialog */
365 LoadStringW(hInst
, IDS_LOAD_HIVE
, Caption
, COUNT_OF(Caption
));
366 ofn
.lpstrTitle
= Caption
;
367 ofn
.Flags
|= OFN_ENABLESIZING
;
368 /* ofn.lCustData = ;*/
369 /* now load the hive */
370 if (GetOpenFileName(&ofn
))
372 if(DialogBoxParamW(hInst
, MAKEINTRESOURCEW(IDD_LOADHIVE
), hWnd
, &LoadHive_KeyNameInHookProc
, (LPARAM
)xPath
))
376 /* Enable the 'restore' privilege, load the hive, disable the privilege */
377 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
378 regLoadResult
= RegLoadKeyW(hRootKey
, xPath
, ofn
.lpstrFile
);
379 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
381 if(regLoadResult
== ERROR_SUCCESS
)
383 /* refresh tree and list views */
384 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
385 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
386 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
390 ErrorMessageBox(hWnd
, Caption
, regLoadResult
);
397 CheckCommDlgError(hWnd
);
402 static BOOL
UnloadHive(HWND hWnd
)
407 LONG regUnloadResult
;
409 /* get the item key to unload */
410 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
411 /* load and set the caption and flags for dialog */
412 LoadStringW(hInst
, IDS_UNLOAD_HIVE
, Caption
, COUNT_OF(Caption
));
414 /* Enable the 'restore' privilege, unload the hive, disable the privilege */
415 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
416 regUnloadResult
= RegUnLoadKeyW(hRootKey
, pszKeyPath
);
417 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
419 if(regUnloadResult
== ERROR_SUCCESS
)
421 /* refresh tree and list views */
422 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
423 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
424 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
428 ErrorMessageBox(hWnd
, Caption
, regUnloadResult
);
434 static BOOL
ImportRegistryFile(HWND hWnd
)
438 WCHAR Caption
[128], szTitle
[512], szText
[512];
442 /* Figure out in which key path we are importing */
443 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
445 InitOpenFileName(hWnd
, &ofn
);
446 LoadStringW(hInst
, IDS_IMPORT_REG_FILE
, Caption
, COUNT_OF(Caption
));
447 ofn
.lpstrTitle
= Caption
;
448 ofn
.Flags
|= OFN_ENABLESIZING
;
449 /* ofn.lCustData = ;*/
450 if (GetOpenFileName(&ofn
))
452 /* Look at the extension of the file to determine its type */
453 if (ofn
.nFileExtension
>= 1 &&
454 wcsicmp(ofn
.lpstrFile
+ ofn
.nFileExtension
, L
"reg") == 0) /* REGEDIT4 or Windows Registry Editor Version 5.00 */
457 FILE* fp
= _wfopen(ofn
.lpstrFile
, L
"r");
460 if (fp
== NULL
|| !import_registry_file(fp
))
462 /* Error opening the file */
463 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
464 LoadStringW(hInst
, IDS_IMPORT_ERROR
, szText
, COUNT_OF(szText
));
465 InfoMessageBox(hWnd
, MB_OK
| MB_ICONERROR
, szTitle
, szText
, ofn
.lpstrFile
);
470 /* Show successful import */
471 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
472 LoadStringW(hInst
, IDS_IMPORT_OK
, szText
, COUNT_OF(szText
));
473 InfoMessageBox(hWnd
, MB_OK
| MB_ICONINFORMATION
, szTitle
, szText
, ofn
.lpstrFile
);
480 else /* Registry Hive Files */
482 LoadStringW(hInst
, IDS_QUERY_IMPORT_HIVE_CAPTION
, szTitle
, COUNT_OF(szTitle
));
483 LoadStringW(hInst
, IDS_QUERY_IMPORT_HIVE_MSG
, szText
, COUNT_OF(szText
));
485 /* Display a confirmation message */
486 if (MessageBoxW(g_pChildWnd
->hWnd
, szText
, szTitle
, MB_ICONWARNING
| MB_YESNO
) == IDYES
)
491 /* Open the subkey */
492 lResult
= RegOpenKeyExW(hKeyRoot
, pszKeyPath
, 0, KEY_WRITE
, &hSubKey
);
493 if (lResult
== ERROR_SUCCESS
)
495 /* Enable the 'restore' privilege, restore the hive then disable the privilege */
496 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
497 lResult
= RegRestoreKey(hSubKey
, ofn
.lpstrFile
, REG_FORCE_RESTORE
);
498 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
500 /* Flush the subkey and close it */
501 RegFlushKey(hSubKey
);
502 RegCloseKey(hSubKey
);
505 /* Set the return value */
506 bRet
= (lResult
== ERROR_SUCCESS
);
508 /* Display error, if any */
509 if (!bRet
) ErrorMessageBox(hWnd
, Caption
, lResult
);
515 CheckCommDlgError(hWnd
);
518 /* refresh tree and list views */
519 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
520 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
521 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, pszKeyPath
);
526 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
529 HWND hwndExportBranch
;
530 HWND hwndExportBranchText
;
531 UINT_PTR iResult
= 0;
533 LPWSTR pszSelectedKey
;
534 OFNOTIFY
*pOfnNotify
;
536 UNREFERENCED_PARAMETER(wParam
);
541 pOfn
= (OPENFILENAME
*) lParam
;
542 pszSelectedKey
= (LPWSTR
) pOfn
->lCustData
;
544 hwndExportAll
= GetDlgItem(hdlg
, IDC_EXPORT_ALL
);
546 SendMessageW(hwndExportAll
, BM_SETCHECK
, pszSelectedKey
? BST_UNCHECKED
: BST_CHECKED
, 0);
548 hwndExportBranch
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH
);
549 if (hwndExportBranch
)
550 SendMessageW(hwndExportBranch
, BM_SETCHECK
, pszSelectedKey
? BST_CHECKED
: BST_UNCHECKED
, 0);
552 hwndExportBranchText
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH_TEXT
);
553 if (hwndExportBranchText
)
554 SetWindowTextW(hwndExportBranchText
, pszSelectedKey
);
558 if (((NMHDR
*) lParam
)->code
== CDN_FILEOK
)
560 pOfnNotify
= (OFNOTIFY
*) lParam
;
561 pszSelectedKey
= (LPWSTR
) pOfnNotify
->lpOFN
->lCustData
;
563 hwndExportBranch
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH
);
564 hwndExportBranchText
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH_TEXT
);
565 if (hwndExportBranch
&& hwndExportBranchText
566 && (SendMessageW(hwndExportBranch
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
568 GetWindowTextW(hwndExportBranchText
, pszSelectedKey
, _MAX_PATH
);
572 pszSelectedKey
[0] = L
'\0';
580 BOOL
ExportRegistryFile(HWND hWnd
)
584 WCHAR ExportKeyPath
[_MAX_PATH
];
585 WCHAR Caption
[128], szTitle
[512], szText
[512];
589 /* Figure out which key path we are exporting */
590 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
591 GetKeyName(ExportKeyPath
, COUNT_OF(ExportKeyPath
), hKeyRoot
, pszKeyPath
);
593 InitOpenFileName(hWnd
, &ofn
);
594 LoadStringW(hInst
, IDS_EXPORT_REG_FILE
, Caption
, COUNT_OF(Caption
));
595 ofn
.lpstrTitle
= Caption
;
597 /* Only set the path if a key (not the root node) is selected */
600 ofn
.lCustData
= (LPARAM
) ExportKeyPath
;
602 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_EXPLORER
| OFN_ENABLEHOOK
| OFN_OVERWRITEPROMPT
;
603 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
604 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORTRANGE
);
605 if (GetSaveFileName(&ofn
))
607 switch (ofn
.nFilterIndex
)
609 case 2: /* Registry Hive Files */
614 /* Open the subkey */
615 lResult
= RegOpenKeyExW(hKeyRoot
, pszKeyPath
, 0, KEY_READ
, &hSubKey
);
616 if (lResult
== ERROR_SUCCESS
)
618 /* Enable the 'backup' privilege, save the hive then disable the privilege */
619 EnablePrivilege(SE_BACKUP_NAME
, NULL
, TRUE
);
620 lResult
= RegSaveKeyW(hSubKey
, ofn
.lpstrFile
, NULL
);
621 if (lResult
== ERROR_ALREADY_EXISTS
)
624 * We are here, that means that we already said "yes" to the confirmation dialog.
625 * So we absolutely want to replace the hive file.
627 if (DeleteFileW(ofn
.lpstrFile
))
630 lResult
= RegSaveKeyW(hSubKey
, ofn
.lpstrFile
, NULL
);
633 EnablePrivilege(SE_BACKUP_NAME
, NULL
, FALSE
);
635 if (lResult
!= ERROR_SUCCESS
)
638 * If we are here, it's because RegSaveKeyW has failed for any reason.
639 * The problem is that even if it has failed, it has created or
640 * replaced the exported hive file with a new empty file. We don't
641 * want to keep this file, so we delete it.
643 DeleteFileW(ofn
.lpstrFile
);
646 /* Close the subkey */
647 RegCloseKey(hSubKey
);
650 /* Set the return value */
651 bRet
= (lResult
== ERROR_SUCCESS
);
653 /* Display error, if any */
654 if (!bRet
) ErrorMessageBox(hWnd
, Caption
, lResult
);
659 case 1: /* Windows Registry Editor Version 5.00 */
660 case 3: /* REGEDIT4 */
661 default: /* All files ==> use Windows Registry Editor Version 5.00 */
663 if (!export_registry_key(ofn
.lpstrFile
, ExportKeyPath
,
664 (ofn
.nFilterIndex
== 3 ? REG_FORMAT_4
667 /* Error creating the file */
668 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
669 LoadStringW(hInst
, IDS_EXPORT_ERROR
, szText
, COUNT_OF(szText
));
670 InfoMessageBox(hWnd
, MB_OK
| MB_ICONERROR
, szTitle
, szText
, ofn
.lpstrFile
);
684 CheckCommDlgError(hWnd
);
690 BOOL
PrintRegistryHive(HWND hWnd
, LPWSTR path
)
694 UNREFERENCED_PARAMETER(path
);
696 ZeroMemory(&pd
, sizeof(PRINTDLG
));
697 pd
.lStructSize
= sizeof(PRINTDLG
);
699 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
700 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
701 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
703 pd
.nFromPage
= 0xFFFF;
706 pd
.nMaxPage
= 0xFFFF;
709 /* GDI calls to render output. */
710 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
716 hResult
= PrintDlgEx(&pd
);
719 switch (pd
.dwResultAction
)
721 case PD_RESULT_APPLY
:
722 /*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. */
724 case PD_RESULT_CANCEL
:
725 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
727 case PD_RESULT_PRINT
:
728 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
739 /*Insufficient memory. */
742 /* One or more arguments are invalid. */
745 /*Invalid pointer. */
751 /*Unspecified error. */
762 static void ChooseFavorite(LPCWSTR pszFavorite
)
765 WCHAR szFavoritePath
[512];
766 DWORD cbData
, dwType
;
768 if (RegOpenKeyExW(HKEY_CURRENT_USER
, s_szFavoritesRegKey
, 0, KEY_QUERY_VALUE
, &hKey
) != ERROR_SUCCESS
)
771 cbData
= (sizeof(szFavoritePath
) / sizeof(szFavoritePath
[0])) - 1;
772 memset(szFavoritePath
, 0, sizeof(szFavoritePath
));
773 if (RegQueryValueExW(hKey
, pszFavorite
, NULL
, &dwType
, (LPBYTE
) szFavoritePath
, &cbData
) != ERROR_SUCCESS
)
776 if (dwType
== REG_SZ
)
777 SelectNode(g_pChildWnd
->hTreeWnd
, szFavoritePath
);
784 BOOL
CopyKeyName(HWND hWnd
, HKEY hRootKey
, LPCWSTR keyName
)
786 BOOL bClipboardOpened
= FALSE
;
787 BOOL bSuccess
= FALSE
;
792 if (!OpenClipboard(hWnd
))
794 bClipboardOpened
= TRUE
;
796 if (!EmptyClipboard())
799 if (!GetKeyName(szBuffer
, COUNT_OF(szBuffer
), hRootKey
, keyName
))
802 hGlobal
= GlobalAlloc(GMEM_MOVEABLE
, (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
806 s
= GlobalLock(hGlobal
);
808 GlobalUnlock(hGlobal
);
810 SetClipboardData(CF_UNICODETEXT
, hGlobal
);
814 if (bClipboardOpened
)
819 static BOOL
CreateNewValue(HKEY hRootKey
, LPCWSTR pszKeyPath
, DWORD dwType
)
821 WCHAR szNewValueFormat
[128];
822 WCHAR szNewValue
[128];
825 DWORD dwExistingType
, cbData
;
830 if (RegOpenKeyExW(hRootKey
, pszKeyPath
, 0, KEY_QUERY_VALUE
| KEY_SET_VALUE
,
831 &hKey
) != ERROR_SUCCESS
)
834 LoadStringW(hInst
, IDS_NEW_VALUE
, szNewValueFormat
, COUNT_OF(szNewValueFormat
));
838 wsprintf(szNewValue
, szNewValueFormat
, iIndex
++);
839 cbData
= sizeof(data
);
840 lResult
= RegQueryValueExW(hKey
, szNewValue
, NULL
, &dwExistingType
, data
, &cbData
);
842 while(lResult
== ERROR_SUCCESS
);
847 cbData
= sizeof(DWORD
);
851 cbData
= sizeof(WCHAR
);
854 cbData
= sizeof(WCHAR
) * 2;
857 cbData
= sizeof(DWORD
) * 2;
863 memset(data
, 0, cbData
);
864 lResult
= RegSetValueExW(hKey
, szNewValue
, 0, dwType
, data
, cbData
);
866 if (lResult
!= ERROR_SUCCESS
)
871 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
873 /* locate the newly added value, and get ready to rename it */
874 memset(&lvfi
, 0, sizeof(lvfi
));
875 lvfi
.flags
= LVFI_STRING
;
876 lvfi
.psz
= szNewValue
;
877 iIndex
= ListView_FindItem(g_pChildWnd
->hListWnd
, -1, &lvfi
);
879 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, iIndex
);
885 InitializeRemoteRegistryPicker(OUT IDsObjectPicker
**pDsObjectPicker
)
889 *pDsObjectPicker
= NULL
;
891 hRet
= CoCreateInstance(&CLSID_DsObjectPicker
,
893 CLSCTX_INPROC_SERVER
,
894 &IID_IDsObjectPicker
,
895 (LPVOID
*)pDsObjectPicker
);
898 DSOP_INIT_INFO InitInfo
;
899 static DSOP_SCOPE_INIT_INFO Scopes
[] =
902 sizeof(DSOP_SCOPE_INIT_INFO
),
903 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
| DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE
|
904 DSOP_SCOPE_TYPE_GLOBAL_CATALOG
| DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
|
905 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
| DSOP_SCOPE_TYPE_WORKGROUP
|
906 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN
,
910 DSOP_FILTER_COMPUTERS
,
914 DSOP_DOWNLEVEL_FILTER_COMPUTERS
922 InitInfo
.cbSize
= sizeof(InitInfo
);
923 InitInfo
.pwzTargetComputer
= NULL
;
924 InitInfo
.cDsScopeInfos
= COUNT_OF(Scopes
);
925 InitInfo
.aDsScopeInfos
= Scopes
;
926 InitInfo
.flOptions
= 0;
927 InitInfo
.cAttributesToFetch
= 0;
928 InitInfo
.apwzAttributeNames
= NULL
;
930 hRet
= (*pDsObjectPicker
)->lpVtbl
->Initialize(*pDsObjectPicker
,
935 /* delete the object picker in case initialization failed! */
936 (*pDsObjectPicker
)->lpVtbl
->Release(*pDsObjectPicker
);
944 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker
*pDsObjectPicker
,
945 IN HWND hwndParent OPTIONAL
,
949 IDataObject
*pdo
= NULL
;
952 hRet
= pDsObjectPicker
->lpVtbl
->InvokeDialog(pDsObjectPicker
,
960 fe
.cfFormat
= (CLIPFORMAT
) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST
);
962 fe
.dwAspect
= DVASPECT_CONTENT
;
964 fe
.tymed
= TYMED_HGLOBAL
;
966 hRet
= pdo
->lpVtbl
->GetData(pdo
,
971 PDS_SELECTION_LIST SelectionList
= (PDS_SELECTION_LIST
)GlobalLock(stm
.hGlobal
);
972 if (SelectionList
!= NULL
)
974 if (SelectionList
->cItems
== 1)
976 size_t nlen
= wcslen(SelectionList
->aDsSelection
[0].pwzName
);
983 SelectionList
->aDsSelection
[0].pwzName
,
984 nlen
* sizeof(WCHAR
));
986 lpBuffer
[nlen
] = L
'\0';
989 GlobalUnlock(stm
.hGlobal
);
992 ReleaseStgMedium(&stm
);
995 pdo
->lpVtbl
->Release(pdo
);
1002 FreeObjectPicker(IN IDsObjectPicker
*pDsObjectPicker
)
1004 pDsObjectPicker
->lpVtbl
->Release(pDsObjectPicker
);
1007 /*******************************************************************************
1009 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
1011 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
1014 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1016 HKEY hKeyRoot
= 0, hKey
= 0;
1020 REGSAM regsam
= KEY_READ
;
1024 UNREFERENCED_PARAMETER(lParam
);
1025 UNREFERENCED_PARAMETER(message
);
1027 switch (LOWORD(wParam
))
1029 case ID_REGISTRY_LOADHIVE
:
1032 case ID_REGISTRY_UNLOADHIVE
:
1035 case ID_REGISTRY_IMPORTREGISTRYFILE
:
1036 ImportRegistryFile(hWnd
);
1038 case ID_REGISTRY_EXPORTREGISTRYFILE
:
1039 ExportRegistryFile(hWnd
);
1041 case ID_REGISTRY_CONNECTNETWORKREGISTRY
:
1043 IDsObjectPicker
*ObjectPicker
;
1044 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1047 hRet
= CoInitialize(NULL
);
1048 if (SUCCEEDED(hRet
))
1050 hRet
= InitializeRemoteRegistryPicker(&ObjectPicker
);
1051 if (SUCCEEDED(hRet
))
1053 hRet
= InvokeRemoteRegistryPickerDialog(ObjectPicker
,
1056 COUNT_OF(szComputerName
));
1059 /* FIXME - connect to the registry */
1062 FreeObjectPicker(ObjectPicker
);
1070 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY
:
1072 case ID_REGISTRY_PRINT
:
1073 PrintRegistryHive(hWnd
, L
"");
1075 case ID_REGISTRY_EXIT
:
1076 DestroyWindow(hWnd
);
1078 case ID_VIEW_STATUSBAR
:
1079 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1081 case ID_HELP_HELPTOPICS
:
1082 WinHelpW(hWnd
, getAppName(), HELP_FINDER
, 0);
1091 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1092 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1093 pt
.y
= (rt
.bottom
/ 2);
1095 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
))
1097 SetCursorPos(pts
.x
, pts
.y
);
1098 SetCursor(LoadCursorW(0, IDC_SIZEWE
));
1099 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1103 case ID_EDIT_RENAME
:
1104 case ID_EDIT_MODIFY
:
1105 case ID_EDIT_MODIFY_BIN
:
1106 case ID_EDIT_DELETE
:
1107 regsam
|= KEY_WRITE
;
1111 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1112 valueName
= GetValueName(g_pChildWnd
->hListWnd
, -1);
1115 lRet
= RegOpenKeyExW(hKeyRoot
, keyPath
, 0, regsam
, &hKey
);
1116 if (lRet
!= ERROR_SUCCESS
) hKey
= 0;
1119 switch (LOWORD(wParam
))
1121 case ID_EDIT_MODIFY
:
1122 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, FALSE
))
1123 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1125 case ID_EDIT_MODIFY_BIN
:
1126 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, TRUE
))
1127 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1129 case ID_EDIT_RENAME
:
1130 if (GetFocus() == g_pChildWnd
->hListWnd
)
1132 if(ListView_GetSelectedCount(g_pChildWnd
->hListWnd
) == 1)
1134 item
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, -1, LVNI_SELECTED
);
1137 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, item
);
1141 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1143 /* Get focused entry of treeview (if any) */
1144 HTREEITEM hItem
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
1146 (void)TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, hItem
);
1149 case ID_EDIT_DELETE
:
1151 if (GetFocus() == g_pChildWnd
->hListWnd
)
1153 UINT nSelected
= ListView_GetSelectedCount(g_pChildWnd
->hListWnd
);
1156 WCHAR msg
[128], caption
[128];
1157 LoadStringW(hInst
, IDS_QUERY_DELETE_CONFIRM
, caption
, COUNT_OF(caption
));
1158 LoadStringW(hInst
, (nSelected
== 1 ? IDS_QUERY_DELETE_ONE
: IDS_QUERY_DELETE_MORE
), msg
, COUNT_OF(msg
));
1159 if(MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONQUESTION
| MB_YESNO
) == IDYES
)
1165 while((ni
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, item
, LVNI_SELECTED
)) > -1)
1167 valueName
= GetValueName(g_pChildWnd
->hListWnd
, item
);
1168 if(RegDeleteValueW(hKey
, valueName
) != ERROR_SUCCESS
)
1175 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1178 LoadStringW(hInst
, IDS_ERR_DELVAL_CAPTION
, caption
, COUNT_OF(caption
));
1179 LoadStringW(hInst
, IDS_ERR_DELETEVALUE
, msg
, COUNT_OF(msg
));
1180 MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONSTOP
);
1185 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1187 if (keyPath
== 0 || *keyPath
== 0)
1189 MessageBeep(MB_ICONHAND
);
1191 else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
))
1193 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
1194 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1199 case ID_EDIT_NEW_STRINGVALUE
:
1200 CreateNewValue(hKeyRoot
, keyPath
, REG_SZ
);
1202 case ID_EDIT_NEW_BINARYVALUE
:
1203 CreateNewValue(hKeyRoot
, keyPath
, REG_BINARY
);
1205 case ID_EDIT_NEW_DWORDVALUE
:
1206 CreateNewValue(hKeyRoot
, keyPath
, REG_DWORD
);
1208 case ID_EDIT_NEW_MULTISTRINGVALUE
:
1209 CreateNewValue(hKeyRoot
, keyPath
, REG_MULTI_SZ
);
1211 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE
:
1212 CreateNewValue(hKeyRoot
, keyPath
, REG_EXPAND_SZ
);
1217 case ID_EDIT_FINDNEXT
:
1220 case ID_EDIT_COPYKEYNAME
:
1221 CopyKeyName(hWnd
, hKeyRoot
, keyPath
);
1223 case ID_EDIT_PERMISSIONS
:
1224 RegKeyEditPermissions(hWnd
, hKeyRoot
, NULL
, keyPath
);
1226 case ID_REGISTRY_PRINTERSETUP
:
1229 /*PAGESETUPDLG psd;*/
1230 /*PageSetupDlg(&psd);*/
1232 case ID_REGISTRY_OPENLOCAL
:
1235 case ID_VIEW_REFRESH
:
1236 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1237 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1238 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1240 /*case ID_OPTIONS_TOOLBAR:*/
1241 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1243 case ID_EDIT_NEW_KEY
:
1244 CreateNewKey(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
1247 if ((LOWORD(wParam
) >= ID_FAVORITES_MIN
) && (LOWORD(wParam
) <= ID_FAVORITES_MAX
))
1251 WCHAR szFavorite
[512];
1253 hMenu
= GetSubMenu(GetMenu(hWnd
), FAVORITES_MENU_POSITION
);
1255 memset(&mii
, 0, sizeof(mii
));
1256 mii
.cbSize
= sizeof(mii
);
1257 mii
.fMask
= MIIM_TYPE
;
1258 mii
.fType
= MFT_STRING
;
1259 mii
.dwTypeData
= szFavorite
;
1260 mii
.cch
= COUNT_OF(szFavorite
);
1262 if (GetMenuItemInfo(hMenu
, LOWORD(wParam
) - ID_FAVORITES_MIN
, TRUE
, &mii
))
1264 ChooseFavorite(szFavorite
);
1279 /********************************************************************************
1281 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1283 * PURPOSE: Processes messages for the main frame window.
1285 * WM_COMMAND - process the application menu
1286 * WM_DESTROY - post a quit message and return
1290 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1295 CreateWindowExW(0, szChildClass
, NULL
, WS_CHILD
| WS_VISIBLE
,
1296 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1297 hWnd
, (HMENU
)0, hInst
, 0);
1300 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1301 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1305 SetFocus(g_pChildWnd
->hWnd
);
1308 resize_frame_client(hWnd
);
1315 case WM_ENTERMENULOOP
:
1316 OnEnterMenuLoop(hWnd
);
1318 case WM_EXITMENULOOP
:
1319 OnExitMenuLoop(hWnd
);
1322 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1324 case WM_SYSCOLORCHANGE
:
1325 /* Forward WM_SYSCOLORCHANGE to common controls */
1326 SendMessageW(g_pChildWnd
->hListWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1327 SendMessageW(g_pChildWnd
->hTreeWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1330 WinHelpW(hWnd
, getAppName(), HELP_QUIT
, 0);
1334 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);