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
);
857 * WARNING: An empty multi-string has only one null char.
858 * Indeed, multi-strings are built in the following form:
859 * str1\0str2\0...strN\0\0
860 * where each strI\0 is a null-terminated string, and it
861 * ends with a terminating empty string.
862 * Therefore an empty multi-string contains only the terminating
863 * empty string, that is, one null char.
865 cbData
= sizeof(WCHAR
);
867 case REG_QWORD
: /* REG_QWORD_LITTLE_ENDIAN */
868 cbData
= sizeof(DWORDLONG
); // == sizeof(DWORD) * 2;
874 memset(data
, 0, cbData
);
875 lResult
= RegSetValueExW(hKey
, szNewValue
, 0, dwType
, data
, cbData
);
877 if (lResult
!= ERROR_SUCCESS
)
882 RefreshListView(g_pChildWnd
->hListWnd
, hRootKey
, pszKeyPath
);
884 /* locate the newly added value, and get ready to rename it */
885 memset(&lvfi
, 0, sizeof(lvfi
));
886 lvfi
.flags
= LVFI_STRING
;
887 lvfi
.psz
= szNewValue
;
888 iIndex
= ListView_FindItem(g_pChildWnd
->hListWnd
, -1, &lvfi
);
890 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, iIndex
);
896 InitializeRemoteRegistryPicker(OUT IDsObjectPicker
**pDsObjectPicker
)
900 *pDsObjectPicker
= NULL
;
902 hRet
= CoCreateInstance(&CLSID_DsObjectPicker
,
904 CLSCTX_INPROC_SERVER
,
905 &IID_IDsObjectPicker
,
906 (LPVOID
*)pDsObjectPicker
);
909 DSOP_INIT_INFO InitInfo
;
910 static DSOP_SCOPE_INIT_INFO Scopes
[] =
913 sizeof(DSOP_SCOPE_INIT_INFO
),
914 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE
| DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE
|
915 DSOP_SCOPE_TYPE_GLOBAL_CATALOG
| DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN
|
916 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN
| DSOP_SCOPE_TYPE_WORKGROUP
|
917 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN
| DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN
,
921 DSOP_FILTER_COMPUTERS
,
925 DSOP_DOWNLEVEL_FILTER_COMPUTERS
933 InitInfo
.cbSize
= sizeof(InitInfo
);
934 InitInfo
.pwzTargetComputer
= NULL
;
935 InitInfo
.cDsScopeInfos
= COUNT_OF(Scopes
);
936 InitInfo
.aDsScopeInfos
= Scopes
;
937 InitInfo
.flOptions
= 0;
938 InitInfo
.cAttributesToFetch
= 0;
939 InitInfo
.apwzAttributeNames
= NULL
;
941 hRet
= (*pDsObjectPicker
)->lpVtbl
->Initialize(*pDsObjectPicker
,
946 /* delete the object picker in case initialization failed! */
947 (*pDsObjectPicker
)->lpVtbl
->Release(*pDsObjectPicker
);
955 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker
*pDsObjectPicker
,
956 IN HWND hwndParent OPTIONAL
,
960 IDataObject
*pdo
= NULL
;
963 hRet
= pDsObjectPicker
->lpVtbl
->InvokeDialog(pDsObjectPicker
,
971 fe
.cfFormat
= (CLIPFORMAT
) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST
);
973 fe
.dwAspect
= DVASPECT_CONTENT
;
975 fe
.tymed
= TYMED_HGLOBAL
;
977 hRet
= pdo
->lpVtbl
->GetData(pdo
,
982 PDS_SELECTION_LIST SelectionList
= (PDS_SELECTION_LIST
)GlobalLock(stm
.hGlobal
);
983 if (SelectionList
!= NULL
)
985 if (SelectionList
->cItems
== 1)
987 size_t nlen
= wcslen(SelectionList
->aDsSelection
[0].pwzName
);
994 SelectionList
->aDsSelection
[0].pwzName
,
995 nlen
* sizeof(WCHAR
));
997 lpBuffer
[nlen
] = L
'\0';
1000 GlobalUnlock(stm
.hGlobal
);
1003 ReleaseStgMedium(&stm
);
1006 pdo
->lpVtbl
->Release(pdo
);
1013 FreeObjectPicker(IN IDsObjectPicker
*pDsObjectPicker
)
1015 pDsObjectPicker
->lpVtbl
->Release(pDsObjectPicker
);
1018 /*******************************************************************************
1020 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
1022 * PURPOSE: Processes WM_COMMAND messages for the main frame window.
1025 static BOOL
_CmdWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1027 HKEY hKeyRoot
= 0, hKey
= 0;
1031 REGSAM regsam
= KEY_READ
;
1035 UNREFERENCED_PARAMETER(lParam
);
1036 UNREFERENCED_PARAMETER(message
);
1038 switch (LOWORD(wParam
))
1040 case ID_REGISTRY_LOADHIVE
:
1043 case ID_REGISTRY_UNLOADHIVE
:
1046 case ID_REGISTRY_IMPORTREGISTRYFILE
:
1047 ImportRegistryFile(hWnd
);
1049 case ID_REGISTRY_EXPORTREGISTRYFILE
:
1050 ExportRegistryFile(hWnd
);
1052 case ID_REGISTRY_CONNECTNETWORKREGISTRY
:
1054 IDsObjectPicker
*ObjectPicker
;
1055 WCHAR szComputerName
[MAX_COMPUTERNAME_LENGTH
+ 1];
1058 hRet
= CoInitialize(NULL
);
1059 if (SUCCEEDED(hRet
))
1061 hRet
= InitializeRemoteRegistryPicker(&ObjectPicker
);
1062 if (SUCCEEDED(hRet
))
1064 hRet
= InvokeRemoteRegistryPickerDialog(ObjectPicker
,
1067 COUNT_OF(szComputerName
));
1070 /* FIXME - connect to the registry */
1073 FreeObjectPicker(ObjectPicker
);
1081 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY
:
1083 case ID_REGISTRY_PRINT
:
1084 PrintRegistryHive(hWnd
, L
"");
1086 case ID_REGISTRY_EXIT
:
1087 DestroyWindow(hWnd
);
1089 case ID_VIEW_STATUSBAR
:
1090 toggle_child(hWnd
, LOWORD(wParam
), hStatusBar
);
1092 case ID_HELP_HELPTOPICS
:
1093 WinHelpW(hWnd
, getAppName(), HELP_FINDER
, 0);
1102 GetClientRect(g_pChildWnd
->hWnd
, &rt
);
1103 pt
.x
= rt
.left
+ g_pChildWnd
->nSplitPos
;
1104 pt
.y
= (rt
.bottom
/ 2);
1106 if(ClientToScreen(g_pChildWnd
->hWnd
, &pts
))
1108 SetCursorPos(pts
.x
, pts
.y
);
1109 SetCursor(LoadCursorW(0, IDC_SIZEWE
));
1110 SendMessageW(g_pChildWnd
->hWnd
, WM_LBUTTONDOWN
, 0, MAKELPARAM(pt
.x
, pt
.y
));
1114 case ID_EDIT_RENAME
:
1115 case ID_EDIT_MODIFY
:
1116 case ID_EDIT_MODIFY_BIN
:
1117 case ID_EDIT_DELETE
:
1118 regsam
|= KEY_WRITE
;
1122 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1123 valueName
= GetValueName(g_pChildWnd
->hListWnd
, -1);
1126 lRet
= RegOpenKeyExW(hKeyRoot
, keyPath
, 0, regsam
, &hKey
);
1127 if (lRet
!= ERROR_SUCCESS
) hKey
= 0;
1130 switch (LOWORD(wParam
))
1132 case ID_EDIT_MODIFY
:
1133 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, FALSE
))
1134 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1136 case ID_EDIT_MODIFY_BIN
:
1137 if (valueName
&& ModifyValue(hWnd
, hKey
, valueName
, TRUE
))
1138 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1140 case ID_EDIT_RENAME
:
1141 if (GetFocus() == g_pChildWnd
->hListWnd
)
1143 if(ListView_GetSelectedCount(g_pChildWnd
->hListWnd
) == 1)
1145 item
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, -1, LVNI_SELECTED
);
1148 (void)ListView_EditLabel(g_pChildWnd
->hListWnd
, item
);
1152 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1154 /* Get focused entry of treeview (if any) */
1155 HTREEITEM hItem
= TreeView_GetSelection(g_pChildWnd
->hTreeWnd
);
1157 (void)TreeView_EditLabel(g_pChildWnd
->hTreeWnd
, hItem
);
1160 case ID_EDIT_DELETE
:
1162 if (GetFocus() == g_pChildWnd
->hListWnd
)
1164 UINT nSelected
= ListView_GetSelectedCount(g_pChildWnd
->hListWnd
);
1167 WCHAR msg
[128], caption
[128];
1168 LoadStringW(hInst
, IDS_QUERY_DELETE_CONFIRM
, caption
, COUNT_OF(caption
));
1169 LoadStringW(hInst
, (nSelected
== 1 ? IDS_QUERY_DELETE_ONE
: IDS_QUERY_DELETE_MORE
), msg
, COUNT_OF(msg
));
1170 if(MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONQUESTION
| MB_YESNO
) == IDYES
)
1176 while((ni
= ListView_GetNextItem(g_pChildWnd
->hListWnd
, item
, LVNI_SELECTED
)) > -1)
1178 valueName
= GetValueName(g_pChildWnd
->hListWnd
, item
);
1179 if(RegDeleteValueW(hKey
, valueName
) != ERROR_SUCCESS
)
1186 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1189 LoadStringW(hInst
, IDS_ERR_DELVAL_CAPTION
, caption
, COUNT_OF(caption
));
1190 LoadStringW(hInst
, IDS_ERR_DELETEVALUE
, msg
, COUNT_OF(msg
));
1191 MessageBoxW(g_pChildWnd
->hWnd
, msg
, caption
, MB_ICONSTOP
);
1196 else if (GetFocus() == g_pChildWnd
->hTreeWnd
)
1198 if (keyPath
== 0 || *keyPath
== 0)
1200 MessageBeep(MB_ICONHAND
);
1202 else if (DeleteKey(hWnd
, hKeyRoot
, keyPath
))
1204 DeleteNode(g_pChildWnd
->hTreeWnd
, 0);
1205 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1210 case ID_EDIT_NEW_STRINGVALUE
:
1211 CreateNewValue(hKeyRoot
, keyPath
, REG_SZ
);
1213 case ID_EDIT_NEW_BINARYVALUE
:
1214 CreateNewValue(hKeyRoot
, keyPath
, REG_BINARY
);
1216 case ID_EDIT_NEW_DWORDVALUE
:
1217 CreateNewValue(hKeyRoot
, keyPath
, REG_DWORD
);
1219 case ID_EDIT_NEW_MULTISTRINGVALUE
:
1220 CreateNewValue(hKeyRoot
, keyPath
, REG_MULTI_SZ
);
1222 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE
:
1223 CreateNewValue(hKeyRoot
, keyPath
, REG_EXPAND_SZ
);
1228 case ID_EDIT_FINDNEXT
:
1231 case ID_EDIT_COPYKEYNAME
:
1232 CopyKeyName(hWnd
, hKeyRoot
, keyPath
);
1234 case ID_EDIT_PERMISSIONS
:
1235 RegKeyEditPermissions(hWnd
, hKeyRoot
, NULL
, keyPath
);
1237 case ID_REGISTRY_PRINTERSETUP
:
1240 /*PAGESETUPDLG psd;*/
1241 /*PageSetupDlg(&psd);*/
1243 case ID_REGISTRY_OPENLOCAL
:
1246 case ID_VIEW_REFRESH
:
1247 RefreshTreeView(g_pChildWnd
->hTreeWnd
);
1248 keyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
1249 RefreshListView(g_pChildWnd
->hListWnd
, hKeyRoot
, keyPath
);
1251 /*case ID_OPTIONS_TOOLBAR:*/
1252 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
1254 case ID_EDIT_NEW_KEY
:
1255 CreateNewKey(g_pChildWnd
->hTreeWnd
, TreeView_GetSelection(g_pChildWnd
->hTreeWnd
));
1258 if ((LOWORD(wParam
) >= ID_FAVORITES_MIN
) && (LOWORD(wParam
) <= ID_FAVORITES_MAX
))
1262 WCHAR szFavorite
[512];
1264 hMenu
= GetSubMenu(GetMenu(hWnd
), FAVORITES_MENU_POSITION
);
1266 memset(&mii
, 0, sizeof(mii
));
1267 mii
.cbSize
= sizeof(mii
);
1268 mii
.fMask
= MIIM_TYPE
;
1269 mii
.fType
= MFT_STRING
;
1270 mii
.dwTypeData
= szFavorite
;
1271 mii
.cch
= COUNT_OF(szFavorite
);
1273 if (GetMenuItemInfo(hMenu
, LOWORD(wParam
) - ID_FAVORITES_MIN
, TRUE
, &mii
))
1275 ChooseFavorite(szFavorite
);
1290 /********************************************************************************
1292 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG)
1294 * PURPOSE: Processes messages for the main frame window.
1296 * WM_COMMAND - process the application menu
1297 * WM_DESTROY - post a quit message and return
1301 LRESULT CALLBACK
FrameWndProc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
1306 CreateWindowExW(0, szChildClass
, NULL
, WS_CHILD
| WS_VISIBLE
,
1307 CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
, CW_USEDEFAULT
,
1308 hWnd
, (HMENU
)0, hInst
, 0);
1311 if (!_CmdWndProc(hWnd
, message
, wParam
, lParam
))
1312 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);
1316 SetFocus(g_pChildWnd
->hWnd
);
1319 resize_frame_client(hWnd
);
1326 case WM_ENTERMENULOOP
:
1327 OnEnterMenuLoop(hWnd
);
1329 case WM_EXITMENULOOP
:
1330 OnExitMenuLoop(hWnd
);
1333 OnMenuSelect(hWnd
, LOWORD(wParam
), HIWORD(wParam
), (HMENU
)lParam
);
1335 case WM_SYSCOLORCHANGE
:
1336 /* Forward WM_SYSCOLORCHANGE to common controls */
1337 SendMessageW(g_pChildWnd
->hListWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1338 SendMessageW(g_pChildWnd
->hTreeWnd
, WM_SYSCOLORCHANGE
, 0, 0);
1341 WinHelpW(hWnd
, getAppName(), HELP_QUIT
, 0);
1345 return DefWindowProcW(hWnd
, message
, wParam
, lParam
);