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 LPCWSTR pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
184 SendMessageW(hStatusBar
, SB_SETTEXTW
, 0, (LPARAM
)pszKeyPath
);
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
] = {0};
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
);
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
;
1038 UNREFERENCED_PARAMETER(lParam
);
1039 UNREFERENCED_PARAMETER(message
);
1041 switch (LOWORD(wParam
))
1043 case ID_REGISTRY_LOADHIVE
:
1046 case ID_REGISTRY_UNLOADHIVE
:
1049 case ID_REGISTRY_IMPORTREGISTRYFILE
:
1050 ImportRegistryFile(hWnd
);
1052 case ID_REGISTRY_EXPORTREGISTRYFILE
:
1053 ExportRegistryFile(hWnd
);
1055 case ID_REGISTRY_CONNECTNETWORKREGISTRY
:
1057 IDsObjectPicker
*ObjectPicker
;
1058 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1061 hRet
= CoInitialize(NULL
);
1062 if (SUCCEEDED(hRet
))
1064 hRet
= InitializeRemoteRegistryPicker(&ObjectPicker
);
1065 if (SUCCEEDED(hRet
))
1067 hRet
= InvokeRemoteRegistryPickerDialog(ObjectPicker
,
1070 COUNT_OF(szComputerName
));
1073 /* FIXME - connect to the registry */
1076 FreeObjectPicker(ObjectPicker
);
1084 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY
:
1086 case ID_REGISTRY_PRINT
:
1087 PrintRegistryHive(hWnd
, L
"");
1089 case ID_REGISTRY_EXIT
:
1090 DestroyWindow(hWnd
);
1092 case ID_VIEW_STATUSBAR
:
1093 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1095 case ID_HELP_HELPTOPICS
:
1096 WinHelpW(hWnd
, getAppName(), HELP_FINDER
, 0);
1105 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1106 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1107 pt
.y
= (rt
.bottom
/ 2);
1109 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
))
1111 SetCursorPos(pts
.x
, pts
.y
);
1112 SetCursor(LoadCursorW(0, IDC_SIZEWE
));
1113 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1117 case ID_EDIT_RENAME
:
1118 case ID_EDIT_MODIFY
:
1119 case ID_EDIT_MODIFY_BIN
:
1120 case ID_EDIT_DELETE
:
1121 regsam
|= KEY_WRITE
;
1125 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1126 valueName
= GetValueName(g_pChildWnd
->hListWnd
, -1);
1129 if (RegOpenKeyExW(hKeyRoot
, keyPath
, 0, regsam
, &hKey
) != ERROR_SUCCESS
)
1133 switch (LOWORD(wParam
))
1135 case ID_EDIT_MODIFY
:
1136 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, FALSE
))
1137 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1139 case ID_EDIT_MODIFY_BIN
:
1140 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, TRUE
))
1141 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1143 case ID_EDIT_RENAME
:
1144 if (GetFocus() == g_pChildWnd
->hListWnd
)
1146 if(ListView_GetSelectedCount(g_pChildWnd
->hListWnd
) == 1)
1148 item
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, -1, LVNI_SELECTED
);
1151 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, item
);
1155 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1157 /* Get focused entry of treeview (if any) */
1158 HTREEITEM hItem
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
1160 (void)TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, hItem
);
1163 case ID_EDIT_DELETE
:
1165 if (GetFocus() == g_pChildWnd
->hListWnd
&& hKey
)
1167 UINT nSelected
= ListView_GetSelectedCount(g_pChildWnd
->hListWnd
);
1170 WCHAR msg
[128], caption
[128];
1171 LoadStringW(hInst
, IDS_QUERY_DELETE_CONFIRM
, caption
, COUNT_OF(caption
));
1172 LoadStringW(hInst
, (nSelected
== 1 ? IDS_QUERY_DELETE_ONE
: IDS_QUERY_DELETE_MORE
), msg
, COUNT_OF(msg
));
1173 if(MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONQUESTION
| MB_YESNO
) == IDYES
)
1179 while((ni
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, item
, LVNI_SELECTED
)) > -1)
1181 valueName
= GetValueName(g_pChildWnd
->hListWnd
, item
);
1182 if(RegDeleteValueW(hKey
, valueName
) != ERROR_SUCCESS
)
1189 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1192 LoadStringW(hInst
, IDS_ERR_DELVAL_CAPTION
, caption
, COUNT_OF(caption
));
1193 LoadStringW(hInst
, IDS_ERR_DELETEVALUE
, msg
, COUNT_OF(msg
));
1194 MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONSTOP
);
1199 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1201 if (keyPath
== NULL
|| *keyPath
== UNICODE_NULL
)
1203 MessageBeep(MB_ICONHAND
);
1205 else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
))
1207 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
1208 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1213 case ID_EDIT_NEW_STRINGVALUE
:
1214 CreateNewValue(hKeyRoot
, keyPath
, REG_SZ
);
1216 case ID_EDIT_NEW_BINARYVALUE
:
1217 CreateNewValue(hKeyRoot
, keyPath
, REG_BINARY
);
1219 case ID_EDIT_NEW_DWORDVALUE
:
1220 CreateNewValue(hKeyRoot
, keyPath
, REG_DWORD
);
1222 case ID_EDIT_NEW_MULTISTRINGVALUE
:
1223 CreateNewValue(hKeyRoot
, keyPath
, REG_MULTI_SZ
);
1225 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE
:
1226 CreateNewValue(hKeyRoot
, keyPath
, REG_EXPAND_SZ
);
1231 case ID_EDIT_FINDNEXT
:
1234 case ID_EDIT_COPYKEYNAME
:
1235 CopyKeyName(hWnd
, hKeyRoot
, keyPath
);
1237 case ID_EDIT_PERMISSIONS
:
1238 RegKeyEditPermissions(hWnd
, hKeyRoot
, NULL
, keyPath
);
1240 case ID_REGISTRY_PRINTERSETUP
:
1243 /*PAGESETUPDLG psd;*/
1244 /*PageSetupDlg(&psd);*/
1246 case ID_REGISTRY_OPENLOCAL
:
1249 case ID_VIEW_REFRESH
:
1250 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1251 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1252 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1254 /*case ID_OPTIONS_TOOLBAR:*/
1255 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1257 case ID_EDIT_NEW_KEY
:
1258 CreateNewKey(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
1261 if ((LOWORD(wParam
) >= ID_FAVORITES_MIN
) && (LOWORD(wParam
) <= ID_FAVORITES_MAX
))
1265 WCHAR szFavorite
[512];
1267 hMenu
= GetSubMenu(GetMenu(hWnd
), FAVORITES_MENU_POSITION
);
1269 memset(&mii
, 0, sizeof(mii
));
1270 mii
.cbSize
= sizeof(mii
);
1271 mii
.fMask
= MIIM_TYPE
;
1272 mii
.fType
= MFT_STRING
;
1273 mii
.dwTypeData
= szFavorite
;
1274 mii
.cch
= COUNT_OF(szFavorite
);
1276 if (GetMenuItemInfo(hMenu
, LOWORD(wParam
) - ID_FAVORITES_MIN
, TRUE
, &mii
))
1278 ChooseFavorite(szFavorite
);
1293 /********************************************************************************
1295 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1297 * PURPOSE: Processes messages for the main frame window.
1299 * WM_COMMAND - process the application menu
1300 * WM_DESTROY - post a quit message and return
1304 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1309 CreateWindowExW(0, szChildClass
, NULL
, WS_CHILD
| WS_VISIBLE
,
1310 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1311 hWnd
, (HMENU
)0, hInst
, 0);
1314 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1315 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1318 if (LOWORD(hWnd
) && g_pChildWnd
)
1319 SetFocus(g_pChildWnd
->hWnd
);
1322 resize_frame_client(hWnd
);
1329 case WM_ENTERMENULOOP
:
1330 OnEnterMenuLoop(hWnd
);
1332 case WM_EXITMENULOOP
:
1333 OnExitMenuLoop(hWnd
);
1336 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1338 case WM_SYSCOLORCHANGE
:
1339 /* Forward WM_SYSCOLORCHANGE to common controls */
1340 SendMessageW(g_pChildWnd
->hListWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1341 SendMessageW(g_pChildWnd
->hTreeWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1344 WinHelpW(hWnd
, getAppName(), HELP_QUIT
, 0);
1348 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);