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 #define LOADHIVE_KEYNAMELENGTH 128
293 static INT_PTR CALLBACK
LoadHive_KeyNameInHookProc(HWND hWndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
295 static LPWSTR sKey
= NULL
;
299 sKey
= (LPWSTR
)lParam
;
302 switch(LOWORD(wParam
))
305 if(GetDlgItemTextW(hWndDlg
, IDC_EDIT_KEY
, sKey
, LOADHIVE_KEYNAMELENGTH
))
306 return EndDialog(hWndDlg
, -1);
308 return EndDialog(hWndDlg
, 0);
310 return EndDialog(hWndDlg
, 0);
317 static BOOL
EnablePrivilege(LPCWSTR lpszPrivilegeName
, LPCWSTR lpszSystemName
, BOOL bEnablePrivilege
)
320 HANDLE hToken
= NULL
;
322 if (OpenProcessToken(GetCurrentProcess(),
323 TOKEN_ADJUST_PRIVILEGES
,
328 tp
.PrivilegeCount
= 1;
329 tp
.Privileges
[0].Attributes
= (bEnablePrivilege
? SE_PRIVILEGE_ENABLED
: 0);
331 if (LookupPrivilegeValueW(lpszSystemName
,
333 &tp
.Privileges
[0].Luid
))
335 bRet
= AdjustTokenPrivileges(hToken
, FALSE
, &tp
, 0, NULL
, NULL
);
337 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED
)
347 static BOOL
LoadHive(HWND hWnd
)
352 WCHAR xPath
[LOADHIVE_KEYNAMELENGTH
];
356 /* get the item key to load the hive in */
357 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
358 /* initialize the "open file" dialog */
359 InitOpenFileName(hWnd
, &ofn
);
360 /* build the "All Files" filter up */
361 filter
.DisplayID
= IDS_FLT_ALLFILES
;
362 filter
.FilterID
= IDS_FLT_ALLFILES_FLT
;
363 BuildFilterStrings(Filter
, &filter
, sizeof(filter
));
364 ofn
.lpstrFilter
= Filter
;
365 /* load and set the caption and flags for dialog */
366 LoadStringW(hInst
, IDS_LOAD_HIVE
, Caption
, COUNT_OF(Caption
));
367 ofn
.lpstrTitle
= Caption
;
368 ofn
.Flags
|= OFN_ENABLESIZING
;
369 /* ofn.lCustData = ;*/
370 /* now load the hive */
371 if (GetOpenFileName(&ofn
))
373 if (DialogBoxParamW(hInst
, MAKEINTRESOURCEW(IDD_LOADHIVE
), hWnd
,
374 &LoadHive_KeyNameInHookProc
, (LPARAM
)xPath
))
378 /* Enable the 'restore' privilege, load the hive, disable the privilege */
379 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
380 regLoadResult
= RegLoadKeyW(hRootKey
, xPath
, ofn
.lpstrFile
);
381 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
383 if(regLoadResult
== ERROR_SUCCESS
)
385 /* refresh tree and list views */
386 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
387 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
388 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
392 ErrorMessageBox(hWnd
, Caption
, regLoadResult
);
399 CheckCommDlgError(hWnd
);
404 static BOOL
UnloadHive(HWND hWnd
)
409 LONG regUnloadResult
;
411 /* get the item key to unload */
412 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
413 /* load and set the caption and flags for dialog */
414 LoadStringW(hInst
, IDS_UNLOAD_HIVE
, Caption
, COUNT_OF(Caption
));
416 /* Enable the 'restore' privilege, unload the hive, disable the privilege */
417 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
418 regUnloadResult
= RegUnLoadKeyW(hRootKey
, pszKeyPath
);
419 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
421 if(regUnloadResult
== ERROR_SUCCESS
)
423 /* refresh tree and list views */
424 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
425 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hRootKey
);
426 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
430 ErrorMessageBox(hWnd
, Caption
, regUnloadResult
);
436 static BOOL
ImportRegistryFile(HWND hWnd
)
440 WCHAR Caption
[128], szTitle
[512], szText
[512];
444 /* Figure out in which key path we are importing */
445 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
447 InitOpenFileName(hWnd
, &ofn
);
448 LoadStringW(hInst
, IDS_IMPORT_REG_FILE
, Caption
, COUNT_OF(Caption
));
449 ofn
.lpstrTitle
= Caption
;
450 ofn
.Flags
|= OFN_ENABLESIZING
;
451 /* ofn.lCustData = ;*/
452 if (GetOpenFileName(&ofn
))
454 /* Look at the extension of the file to determine its type */
455 if (ofn
.nFileExtension
>= 1 &&
456 _wcsicmp(ofn
.lpstrFile
+ ofn
.nFileExtension
, L
"reg") == 0) /* REGEDIT4 or Windows Registry Editor Version 5.00 */
459 FILE* fp
= _wfopen(ofn
.lpstrFile
, L
"r");
462 if (fp
== NULL
|| !import_registry_file(fp
))
464 /* Error opening the file */
465 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
466 LoadStringW(hInst
, IDS_IMPORT_ERROR
, szText
, COUNT_OF(szText
));
467 InfoMessageBox(hWnd
, MB_OK
| MB_ICONERROR
, szTitle
, szText
, ofn
.lpstrFile
);
472 /* Show successful import */
473 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
474 LoadStringW(hInst
, IDS_IMPORT_OK
, szText
, COUNT_OF(szText
));
475 InfoMessageBox(hWnd
, MB_OK
| MB_ICONINFORMATION
, szTitle
, szText
, ofn
.lpstrFile
);
482 else /* Registry Hive Files */
484 LoadStringW(hInst
, IDS_QUERY_IMPORT_HIVE_CAPTION
, szTitle
, COUNT_OF(szTitle
));
485 LoadStringW(hInst
, IDS_QUERY_IMPORT_HIVE_MSG
, szText
, COUNT_OF(szText
));
487 /* Display a confirmation message */
488 if (MessageBoxW(g_pChildWnd
->hWnd
, szText
, szTitle
, MB_ICONWARNING
| MB_YESNO
) == IDYES
)
493 /* Open the subkey */
494 lResult
= RegOpenKeyExW(hKeyRoot
, pszKeyPath
, 0, KEY_WRITE
, &hSubKey
);
495 if (lResult
== ERROR_SUCCESS
)
497 /* Enable the 'restore' privilege, restore the hive then disable the privilege */
498 EnablePrivilege(SE_RESTORE_NAME
, NULL
, TRUE
);
499 lResult
= RegRestoreKey(hSubKey
, ofn
.lpstrFile
, REG_FORCE_RESTORE
);
500 EnablePrivilege(SE_RESTORE_NAME
, NULL
, FALSE
);
502 /* Flush the subkey and close it */
503 RegFlushKey(hSubKey
);
504 RegCloseKey(hSubKey
);
507 /* Set the return value */
508 bRet
= (lResult
== ERROR_SUCCESS
);
510 /* Display error, if any */
511 if (!bRet
) ErrorMessageBox(hWnd
, Caption
, lResult
);
517 CheckCommDlgError(hWnd
);
520 /* refresh tree and list views */
521 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
522 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
523 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, pszKeyPath
);
528 static UINT_PTR CALLBACK
ExportRegistryFile_OFNHookProc(HWND hdlg
, UINT uiMsg
, WPARAM wParam
, LPARAM lParam
)
531 HWND hwndExportBranch
;
532 HWND hwndExportBranchText
;
533 UINT_PTR iResult
= 0;
535 LPWSTR pszSelectedKey
;
536 OFNOTIFY
*pOfnNotify
;
538 UNREFERENCED_PARAMETER(wParam
);
543 pOfn
= (OPENFILENAME
*) lParam
;
544 pszSelectedKey
= (LPWSTR
) pOfn
->lCustData
;
546 hwndExportAll
= GetDlgItem(hdlg
, IDC_EXPORT_ALL
);
548 SendMessageW(hwndExportAll
, BM_SETCHECK
, pszSelectedKey
? BST_UNCHECKED
: BST_CHECKED
, 0);
550 hwndExportBranch
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH
);
551 if (hwndExportBranch
)
552 SendMessageW(hwndExportBranch
, BM_SETCHECK
, pszSelectedKey
? BST_CHECKED
: BST_UNCHECKED
, 0);
554 hwndExportBranchText
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH_TEXT
);
555 if (hwndExportBranchText
)
556 SetWindowTextW(hwndExportBranchText
, pszSelectedKey
);
560 if (((NMHDR
*) lParam
)->code
== CDN_FILEOK
)
562 pOfnNotify
= (OFNOTIFY
*) lParam
;
563 pszSelectedKey
= (LPWSTR
) pOfnNotify
->lpOFN
->lCustData
;
565 hwndExportBranch
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH
);
566 hwndExportBranchText
= GetDlgItem(hdlg
, IDC_EXPORT_BRANCH_TEXT
);
567 if (hwndExportBranch
&& hwndExportBranchText
568 && (SendMessageW(hwndExportBranch
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
570 GetWindowTextW(hwndExportBranchText
, pszSelectedKey
, _MAX_PATH
);
574 pszSelectedKey
[0] = L
'\0';
582 BOOL
ExportRegistryFile(HWND hWnd
)
586 WCHAR ExportKeyPath
[_MAX_PATH
];
587 WCHAR Caption
[128], szTitle
[512], szText
[512];
591 /* Figure out which key path we are exporting */
592 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
593 GetKeyName(ExportKeyPath
, COUNT_OF(ExportKeyPath
), hKeyRoot
, pszKeyPath
);
595 InitOpenFileName(hWnd
, &ofn
);
596 LoadStringW(hInst
, IDS_EXPORT_REG_FILE
, Caption
, COUNT_OF(Caption
));
597 ofn
.lpstrTitle
= Caption
;
599 /* Only set the path if a key (not the root node) is selected */
602 ofn
.lCustData
= (LPARAM
) ExportKeyPath
;
604 ofn
.Flags
= OFN_ENABLETEMPLATE
| OFN_EXPLORER
| OFN_ENABLEHOOK
| OFN_OVERWRITEPROMPT
;
605 ofn
.lpfnHook
= ExportRegistryFile_OFNHookProc
;
606 ofn
.lpTemplateName
= MAKEINTRESOURCEW(IDD_EXPORTRANGE
);
607 if (GetSaveFileName(&ofn
))
609 switch (ofn
.nFilterIndex
)
611 case 2: /* Registry Hive Files */
616 /* Open the subkey */
617 lResult
= RegOpenKeyExW(hKeyRoot
, pszKeyPath
, 0, KEY_READ
, &hSubKey
);
618 if (lResult
== ERROR_SUCCESS
)
620 /* Enable the 'backup' privilege, save the hive then disable the privilege */
621 EnablePrivilege(SE_BACKUP_NAME
, NULL
, TRUE
);
622 lResult
= RegSaveKeyW(hSubKey
, ofn
.lpstrFile
, NULL
);
623 if (lResult
== ERROR_ALREADY_EXISTS
)
626 * We are here, that means that we already said "yes" to the confirmation dialog.
627 * So we absolutely want to replace the hive file.
629 if (DeleteFileW(ofn
.lpstrFile
))
632 lResult
= RegSaveKeyW(hSubKey
, ofn
.lpstrFile
, NULL
);
635 EnablePrivilege(SE_BACKUP_NAME
, NULL
, FALSE
);
637 if (lResult
!= ERROR_SUCCESS
)
640 * If we are here, it's because RegSaveKeyW has failed for any reason.
641 * The problem is that even if it has failed, it has created or
642 * replaced the exported hive file with a new empty file. We don't
643 * want to keep this file, so we delete it.
645 DeleteFileW(ofn
.lpstrFile
);
648 /* Close the subkey */
649 RegCloseKey(hSubKey
);
652 /* Set the return value */
653 bRet
= (lResult
== ERROR_SUCCESS
);
655 /* Display error, if any */
656 if (!bRet
) ErrorMessageBox(hWnd
, Caption
, lResult
);
661 case 1: /* Windows Registry Editor Version 5.00 */
662 case 3: /* REGEDIT4 */
663 default: /* All files ==> use Windows Registry Editor Version 5.00 */
665 if (!export_registry_key(ofn
.lpstrFile
, ExportKeyPath
,
666 (ofn
.nFilterIndex
== 3 ? REG_FORMAT_4
669 /* Error creating the file */
670 LoadStringW(hInst
, IDS_APP_TITLE
, szTitle
, COUNT_OF(szTitle
));
671 LoadStringW(hInst
, IDS_EXPORT_ERROR
, szText
, COUNT_OF(szText
));
672 InfoMessageBox(hWnd
, MB_OK
| MB_ICONERROR
, szTitle
, szText
, ofn
.lpstrFile
);
686 CheckCommDlgError(hWnd
);
692 BOOL
PrintRegistryHive(HWND hWnd
, LPWSTR path
)
696 UNREFERENCED_PARAMETER(path
);
698 ZeroMemory(&pd
, sizeof(PRINTDLG
));
699 pd
.lStructSize
= sizeof(PRINTDLG
);
701 pd
.hDevMode
= NULL
; /* Don't forget to free or store hDevMode*/
702 pd
.hDevNames
= NULL
; /* Don't forget to free or store hDevNames*/
703 pd
.Flags
= PD_USEDEVMODECOPIESANDCOLLATE
| PD_RETURNDC
;
705 pd
.nFromPage
= 0xFFFF;
708 pd
.nMaxPage
= 0xFFFF;
711 /* GDI calls to render output. */
712 DeleteDC(pd
.hDC
); /* Delete DC when done.*/
718 hResult
= PrintDlgEx(&pd
);
721 switch (pd
.dwResultAction
)
723 case PD_RESULT_APPLY
:
724 /*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. */
726 case PD_RESULT_CANCEL
:
727 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */
729 case PD_RESULT_PRINT
:
730 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */
741 /*Insufficient memory. */
744 /* One or more arguments are invalid. */
747 /*Invalid pointer. */
753 /*Unspecified error. */
764 static void ChooseFavorite(LPCWSTR pszFavorite
)
767 WCHAR szFavoritePath
[512];
768 DWORD cbData
, dwType
;
770 if (RegOpenKeyExW(HKEY_CURRENT_USER
, s_szFavoritesRegKey
, 0, KEY_QUERY_VALUE
, &hKey
) != ERROR_SUCCESS
)
773 cbData
= (sizeof(szFavoritePath
) / sizeof(szFavoritePath
[0])) - 1;
774 memset(szFavoritePath
, 0, sizeof(szFavoritePath
));
775 if (RegQueryValueExW(hKey
, pszFavorite
, NULL
, &dwType
, (LPBYTE
) szFavoritePath
, &cbData
) != ERROR_SUCCESS
)
778 if (dwType
== REG_SZ
)
779 SelectNode(g_pChildWnd
->hTreeWnd
, szFavoritePath
);
786 BOOL
CopyKeyName(HWND hWnd
, HKEY hRootKey
, LPCWSTR keyName
)
788 BOOL bClipboardOpened
= FALSE
;
789 BOOL bSuccess
= FALSE
;
794 if (!OpenClipboard(hWnd
))
796 bClipboardOpened
= TRUE
;
798 if (!EmptyClipboard())
801 if (!GetKeyName(szBuffer
, COUNT_OF(szBuffer
), hRootKey
, keyName
))
804 hGlobal
= GlobalAlloc(GMEM_MOVEABLE
, (wcslen(szBuffer
) + 1) * sizeof(WCHAR
));
808 s
= GlobalLock(hGlobal
);
810 GlobalUnlock(hGlobal
);
812 SetClipboardData(CF_UNICODETEXT
, hGlobal
);
816 if (bClipboardOpened
)
821 static BOOL
CreateNewValue(HKEY hRootKey
, LPCWSTR pszKeyPath
, DWORD dwType
)
823 WCHAR szNewValueFormat
[128];
824 WCHAR szNewValue
[128];
827 DWORD dwExistingType
, cbData
;
832 if (RegOpenKeyExW(hRootKey
, pszKeyPath
, 0, KEY_QUERY_VALUE
| KEY_SET_VALUE
,
833 &hKey
) != ERROR_SUCCESS
)
836 LoadStringW(hInst
, IDS_NEW_VALUE
, szNewValueFormat
, COUNT_OF(szNewValueFormat
));
840 wsprintf(szNewValue
, szNewValueFormat
, iIndex
++);
841 cbData
= sizeof(data
);
842 lResult
= RegQueryValueExW(hKey
, szNewValue
, NULL
, &dwExistingType
, data
, &cbData
);
844 while(lResult
== ERROR_SUCCESS
);
849 cbData
= sizeof(DWORD
);
853 cbData
= sizeof(WCHAR
);
856 cbData
= sizeof(WCHAR
) * 2;
859 cbData
= sizeof(DWORD
) * 2;
865 memset(data
, 0, cbData
);
866 lResult
= RegSetValueExW(hKey
, szNewValue
, 0, dwType
, data
, cbData
);
868 if (lResult
!= ERROR_SUCCESS
)
873 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
875 /* locate the newly added value, and get ready to rename it */
876 memset(&lvfi
, 0, sizeof(lvfi
));
877 lvfi
.flags
= LVFI_STRING
;
878 lvfi
.psz
= szNewValue
;
879 iIndex
= ListView_FindItem(g_pChildWnd
->hListWnd
, -1, &lvfi
);
881 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, iIndex
);
887 InitializeRemoteRegistryPicker(OUT IDsObjectPicker
**pDsObjectPicker
)
891 *pDsObjectPicker
= NULL
;
893 hRet
= CoCreateInstance(&CLSID_DsObjectPicker
,
895 CLSCTX_INPROC_SERVER
,
896 &IID_IDsObjectPicker
,
897 (LPVOID
*)pDsObjectPicker
);
900 DSOP_INIT_INFO InitInfo
;
901 static DSOP_SCOPE_INIT_INFO Scopes
[] =
904 sizeof(DSOP_SCOPE_INIT_INFO
),
905 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
| DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE
|
906 DSOP_SCOPE_TYPE_GLOBAL_CATALOG
| DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
|
907 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
| DSOP_SCOPE_TYPE_WORKGROUP
|
908 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN
,
912 DSOP_FILTER_COMPUTERS
,
916 DSOP_DOWNLEVEL_FILTER_COMPUTERS
924 InitInfo
.cbSize
= sizeof(InitInfo
);
925 InitInfo
.pwzTargetComputer
= NULL
;
926 InitInfo
.cDsScopeInfos
= COUNT_OF(Scopes
);
927 InitInfo
.aDsScopeInfos
= Scopes
;
928 InitInfo
.flOptions
= 0;
929 InitInfo
.cAttributesToFetch
= 0;
930 InitInfo
.apwzAttributeNames
= NULL
;
932 hRet
= (*pDsObjectPicker
)->lpVtbl
->Initialize(*pDsObjectPicker
,
937 /* delete the object picker in case initialization failed! */
938 (*pDsObjectPicker
)->lpVtbl
->Release(*pDsObjectPicker
);
946 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker
*pDsObjectPicker
,
947 IN HWND hwndParent OPTIONAL
,
951 IDataObject
*pdo
= NULL
;
954 hRet
= pDsObjectPicker
->lpVtbl
->InvokeDialog(pDsObjectPicker
,
962 fe
.cfFormat
= (CLIPFORMAT
) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST
);
964 fe
.dwAspect
= DVASPECT_CONTENT
;
966 fe
.tymed
= TYMED_HGLOBAL
;
968 hRet
= pdo
->lpVtbl
->GetData(pdo
,
973 PDS_SELECTION_LIST SelectionList
= (PDS_SELECTION_LIST
)GlobalLock(stm
.hGlobal
);
974 if (SelectionList
!= NULL
)
976 if (SelectionList
->cItems
== 1)
978 size_t nlen
= wcslen(SelectionList
->aDsSelection
[0].pwzName
);
985 SelectionList
->aDsSelection
[0].pwzName
,
986 nlen
* sizeof(WCHAR
));
988 lpBuffer
[nlen
] = L
'\0';
991 GlobalUnlock(stm
.hGlobal
);
994 ReleaseStgMedium(&stm
);
997 pdo
->lpVtbl
->Release(pdo
);
1004 FreeObjectPicker(IN IDsObjectPicker
*pDsObjectPicker
)
1006 pDsObjectPicker
->lpVtbl
->Release(pDsObjectPicker
);
1009 /*******************************************************************************
1011 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
1013 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
1016 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1018 HKEY hKeyRoot
= 0, hKey
= 0;
1022 REGSAM regsam
= KEY_READ
;
1026 UNREFERENCED_PARAMETER(lParam
);
1027 UNREFERENCED_PARAMETER(message
);
1029 switch (LOWORD(wParam
))
1031 case ID_REGISTRY_LOADHIVE
:
1034 case ID_REGISTRY_UNLOADHIVE
:
1037 case ID_REGISTRY_IMPORTREGISTRYFILE
:
1038 ImportRegistryFile(hWnd
);
1040 case ID_REGISTRY_EXPORTREGISTRYFILE
:
1041 ExportRegistryFile(hWnd
);
1043 case ID_REGISTRY_CONNECTNETWORKREGISTRY
:
1045 IDsObjectPicker
*ObjectPicker
;
1046 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1049 hRet
= CoInitialize(NULL
);
1050 if (SUCCEEDED(hRet
))
1052 hRet
= InitializeRemoteRegistryPicker(&ObjectPicker
);
1053 if (SUCCEEDED(hRet
))
1055 hRet
= InvokeRemoteRegistryPickerDialog(ObjectPicker
,
1058 COUNT_OF(szComputerName
));
1061 /* FIXME - connect to the registry */
1064 FreeObjectPicker(ObjectPicker
);
1072 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY
:
1074 case ID_REGISTRY_PRINT
:
1075 PrintRegistryHive(hWnd
, L
"");
1077 case ID_REGISTRY_EXIT
:
1078 DestroyWindow(hWnd
);
1080 case ID_VIEW_STATUSBAR
:
1081 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1083 case ID_HELP_HELPTOPICS
:
1084 WinHelpW(hWnd
, getAppName(), HELP_FINDER
, 0);
1093 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1094 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1095 pt
.y
= (rt
.bottom
/ 2);
1097 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
))
1099 SetCursorPos(pts
.x
, pts
.y
);
1100 SetCursor(LoadCursorW(0, IDC_SIZEWE
));
1101 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1105 case ID_EDIT_RENAME
:
1106 case ID_EDIT_MODIFY
:
1107 case ID_EDIT_MODIFY_BIN
:
1108 case ID_EDIT_DELETE
:
1109 regsam
|= KEY_WRITE
;
1113 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1114 valueName
= GetValueName(g_pChildWnd
->hListWnd
, -1);
1117 lRet
= RegOpenKeyExW(hKeyRoot
, keyPath
, 0, regsam
, &hKey
);
1118 if (lRet
!= ERROR_SUCCESS
) hKey
= 0;
1121 switch (LOWORD(wParam
))
1123 case ID_EDIT_MODIFY
:
1124 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, FALSE
))
1125 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1127 case ID_EDIT_MODIFY_BIN
:
1128 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, TRUE
))
1129 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1131 case ID_EDIT_RENAME
:
1132 if (GetFocus() == g_pChildWnd
->hListWnd
)
1134 if(ListView_GetSelectedCount(g_pChildWnd
->hListWnd
) == 1)
1136 item
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, -1, LVNI_SELECTED
);
1139 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, item
);
1143 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1145 /* Get focused entry of treeview (if any) */
1146 HTREEITEM hItem
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
1148 (void)TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, hItem
);
1151 case ID_EDIT_DELETE
:
1153 if (GetFocus() == g_pChildWnd
->hListWnd
)
1155 UINT nSelected
= ListView_GetSelectedCount(g_pChildWnd
->hListWnd
);
1158 WCHAR msg
[128], caption
[128];
1159 LoadStringW(hInst
, IDS_QUERY_DELETE_CONFIRM
, caption
, COUNT_OF(caption
));
1160 LoadStringW(hInst
, (nSelected
== 1 ? IDS_QUERY_DELETE_ONE
: IDS_QUERY_DELETE_MORE
), msg
, COUNT_OF(msg
));
1161 if(MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONQUESTION
| MB_YESNO
) == IDYES
)
1167 while((ni
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, item
, LVNI_SELECTED
)) > -1)
1169 valueName
= GetValueName(g_pChildWnd
->hListWnd
, item
);
1170 if(RegDeleteValueW(hKey
, valueName
) != ERROR_SUCCESS
)
1177 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1180 LoadStringW(hInst
, IDS_ERR_DELVAL_CAPTION
, caption
, COUNT_OF(caption
));
1181 LoadStringW(hInst
, IDS_ERR_DELETEVALUE
, msg
, COUNT_OF(msg
));
1182 MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONSTOP
);
1187 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1189 if (keyPath
== 0 || *keyPath
== 0)
1191 MessageBeep(MB_ICONHAND
);
1193 else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
))
1195 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
1196 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1201 case ID_EDIT_NEW_STRINGVALUE
:
1202 CreateNewValue(hKeyRoot
, keyPath
, REG_SZ
);
1204 case ID_EDIT_NEW_BINARYVALUE
:
1205 CreateNewValue(hKeyRoot
, keyPath
, REG_BINARY
);
1207 case ID_EDIT_NEW_DWORDVALUE
:
1208 CreateNewValue(hKeyRoot
, keyPath
, REG_DWORD
);
1210 case ID_EDIT_NEW_MULTISTRINGVALUE
:
1211 CreateNewValue(hKeyRoot
, keyPath
, REG_MULTI_SZ
);
1213 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE
:
1214 CreateNewValue(hKeyRoot
, keyPath
, REG_EXPAND_SZ
);
1219 case ID_EDIT_FINDNEXT
:
1222 case ID_EDIT_COPYKEYNAME
:
1223 CopyKeyName(hWnd
, hKeyRoot
, keyPath
);
1225 case ID_EDIT_PERMISSIONS
:
1226 RegKeyEditPermissions(hWnd
, hKeyRoot
, NULL
, keyPath
);
1228 case ID_REGISTRY_PRINTERSETUP
:
1231 /*PAGESETUPDLG psd;*/
1232 /*PageSetupDlg(&psd);*/
1234 case ID_REGISTRY_OPENLOCAL
:
1237 case ID_VIEW_REFRESH
:
1238 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1239 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1240 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1242 /*case ID_OPTIONS_TOOLBAR:*/
1243 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1245 case ID_EDIT_NEW_KEY
:
1246 CreateNewKey(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
1249 if ((LOWORD(wParam
) >= ID_FAVORITES_MIN
) && (LOWORD(wParam
) <= ID_FAVORITES_MAX
))
1253 WCHAR szFavorite
[512];
1255 hMenu
= GetSubMenu(GetMenu(hWnd
), FAVORITES_MENU_POSITION
);
1257 memset(&mii
, 0, sizeof(mii
));
1258 mii
.cbSize
= sizeof(mii
);
1259 mii
.fMask
= MIIM_TYPE
;
1260 mii
.fType
= MFT_STRING
;
1261 mii
.dwTypeData
= szFavorite
;
1262 mii
.cch
= COUNT_OF(szFavorite
);
1264 if (GetMenuItemInfo(hMenu
, LOWORD(wParam
) - ID_FAVORITES_MIN
, TRUE
, &mii
))
1266 ChooseFavorite(szFavorite
);
1281 /********************************************************************************
1283 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1285 * PURPOSE: Processes messages for the main frame window.
1287 * WM_COMMAND - process the application menu
1288 * WM_DESTROY - post a quit message and return
1292 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1297 CreateWindowExW(0, szChildClass
, NULL
, WS_CHILD
| WS_VISIBLE
,
1298 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1299 hWnd
, (HMENU
)0, hInst
, 0);
1302 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1303 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1307 SetFocus(g_pChildWnd
->hWnd
);
1310 resize_frame_client(hWnd
);
1317 case WM_ENTERMENULOOP
:
1318 OnEnterMenuLoop(hWnd
);
1320 case WM_EXITMENULOOP
:
1321 OnExitMenuLoop(hWnd
);
1324 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1326 case WM_SYSCOLORCHANGE
:
1327 /* Forward WM_SYSCOLORCHANGE to common controls */
1328 SendMessageW(g_pChildWnd
->hListWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1329 SendMessageW(g_pChildWnd
->hTreeWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1332 WinHelpW(hWnd
, getAppName(), HELP_QUIT
, 0);
1336 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);