|
|
/*******************************************************************************
* * (C) COPYRIGHT MICROSOFT CORP., 1993-1994 * * TITLE: REGFILE.C * * VERSION: 4.0 * * AUTHOR: Tracy Sharpe * * DATE: 21 Nov 1993 * * File import and export user interface routines for the Registry Editor. * *******************************************************************************/
#include "pch.h"
#include "regedit.h"
#include "regkey.h"
#include "regfile.h"
#include "regcdhk.h"
#include "regresid.h"
#include "reghelp.h"
#include "regstred.h"
#include "regprint.h"
INT_PTR CALLBACK RegProgressDlgProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam );
/*******************************************************************************
* * RegEdit_ImportRegFile * * DESCRIPTION: * * PARAMETERS: * hWnd, handle of RegEdit window. * fSilentMode, TRUE if no messages should be displayed, else FALSE. * lpFileName, address of file name buffer. * *******************************************************************************/
VOID RegEdit_ImportRegFile(HWND hWnd, BOOL fSilentMode, LPTSTR lpFileName, HTREEITEM hComputerItem) {
if (!fSilentMode && hWnd != NULL) {
if ((g_hRegProgressWnd = CreateDialogParam(g_hInstance, MAKEINTRESOURCE(IDD_REGPROGRESS), hWnd, RegProgressDlgProc, (LPARAM) lpFileName)) != NULL) EnableWindow(hWnd, FALSE);
}
else g_hRegProgressWnd = NULL;
//
// Prompt user to confirm importing a .reg file if running in silent mode
// without a window (i.e. invoked .reg from a folder)
//
if (!fSilentMode && !hWnd) { if (InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(IDS_CONFIRMIMPFILE), MAKEINTRESOURCE(IDS_REGEDIT), MB_ICONQUESTION | MB_YESNO , lpFileName) != IDYES) { return; } }
ImportRegFile(hWnd, lpFileName, hComputerItem);
if (g_hRegProgressWnd != NULL) {
EnableWindow(hWnd, TRUE); DestroyWindow(g_hRegProgressWnd);
}
if (!fSilentMode && g_FileErrorStringID != IDS_IMPFILEERRORCANCEL) { //
// set defaults
//
UINT uStyle = MB_ICONERROR;
TCHAR szComputerName[MAXKEYNAME + 1]; LPTSTR pszComputerName = szComputerName; KeyTree_GetKeyName(hComputerItem, pszComputerName, ARRAYSIZE(szComputerName));
//
// For the resource messages that take the pszComputerName parameter,
// map them to a local-computer version if pszComputerName is empty.
// (Alternatively, we could fill in "this computer" or somesuch for
// pszComputerName, but the resulting text is sort of weird, which
// which isn't acceptable since local-computer is the 99% case.)
//
// Also map the uStyle as needed.
//
switch (g_FileErrorStringID) { case IDS_IMPFILEERRSUCCESS: if (!hWnd || *pszComputerName == 0) { g_FileErrorStringID += LOCAL_OFFSET; } uStyle = MB_ICONINFORMATION | MB_OK; break;
case IDS_IMPFILEERRREGOPEN: case IDS_IMPFILEERRNOFILE: if (*pszComputerName == 0) { g_FileErrorStringID += LOCAL_OFFSET; } break; }
//
// Put up the message box
//
InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(g_FileErrorStringID), MAKEINTRESOURCE(IDS_REGEDIT), uStyle, lpFileName, pszComputerName);
}
}
/*******************************************************************************
* * RegEdit_OnDropFiles * * DESCRIPTION: * * PARAMETERS: * hWnd, handle of RegEdit window. * *******************************************************************************/
VOID PASCAL RegEdit_OnDropFiles( HWND hWnd, HDROP hDrop ) {
TCHAR FileName[MAX_PATH]; UINT NumberOfDrops; UINT CurrentDrop;
BOOL me;
HTREEITEM hSelectedTreeItem = TreeView_GetSelection(g_RegEditData.hKeyTreeWnd); TreeView_SelectDropTarget(g_RegEditData.hKeyTreeWnd, hSelectedTreeItem);
RegEdit_SetWaitCursor(TRUE);
NumberOfDrops = DragQueryFile(hDrop, (UINT) -1, NULL, 0);
for (CurrentDrop = 0; CurrentDrop < NumberOfDrops; CurrentDrop++) { DragQueryFile(hDrop, CurrentDrop, FileName, sizeof(FileName)/sizeof(TCHAR));
if (TreeView_GetNextSibling(g_RegEditData.hKeyTreeWnd, TreeView_GetRoot(g_RegEditData.hKeyTreeWnd)) != NULL) { // Remote connections exist
RegEdit_ImportToConnectedComputer(hWnd, FileName); } else { RegEdit_ImportRegFile(hWnd, FALSE, FileName, RegEdit_GetComputerItem(hSelectedTreeItem)); }
}
DragFinish(hDrop); TreeView_SelectDropTarget(g_RegEditData.hKeyTreeWnd, NULL);
RegEdit_OnKeyTreeRefresh(hWnd);
RegEdit_SetWaitCursor(FALSE);
}
//------------------------------------------------------------------------------
// RegEdit_SetPrivilege
//
// DESCRIPTION: Enable a priviledge
//
// PARAMETERS: lpszPrivilege - the securty constant or its corresponding string
// bEnablePrivilege - TRUE = enable, False = disable
//
//------------------------------------------------------------------------------
BOOL RegEdit_SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) { TOKEN_PRIVILEGES tp; LUID luid; HANDLE hToken; BOOL fSuccess = FALSE; HRESULT hr;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) { if (LookupPrivilegeValue(NULL, lpszPrivilege, &luid)) { tp.PrivilegeCount = 1; tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = (bEnablePrivilege) ? SE_PRIVILEGE_ENABLED : 0; // Enable or disable the privilege
if (AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL)) { fSuccess = TRUE; } } CloseHandle(hToken); } return fSuccess; }
//------------------------------------------------------------------------------
// RegEdit_OnCommandLoadHive
//
// DESCRIPTION: Open and Load a Hive
//
// PARAMETERS: hWnd - handle of RegEdit window.
//
//------------------------------------------------------------------------------
VOID RegEdit_OnCommandLoadHive(HWND hWnd) { TCHAR achFileName[MAX_PATH];
if (RegEdit_GetFileName(hWnd, IDS_LOADHVREGFILETITLE, IDS_REGLOADHVFILEFILTER, IDS_REGNODEFEXT, achFileName, ARRAYSIZE(achFileName), TRUE)) { EDITVALUEPARAM EditValueParam;
RegEdit_SetWaitCursor(TRUE); EditValueParam.cbValueData = sizeof(TCHAR) * 50; EditValueParam.pValueData = LocalAlloc(LPTR, EditValueParam.cbValueData); if (EditValueParam.pValueData) { EditValueParam.pValueData[0] = TEXT('\0');
if (DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_INPUTHIVENAME), hWnd, EditStringValueDlgProc, (LPARAM) &EditValueParam) == IDOK) { HRESULT hr;
RegEdit_SetPrivilege(SE_RESTORE_NAME, TRUE);
if ((hr = RegLoadKey(g_RegEditData.hCurrentSelectionKey, (PTSTR)EditValueParam.pValueData, achFileName)) == ERROR_SUCCESS) { RegEdit_OnKeyTreeRefresh(hWnd); } else { UINT uErrorStringID = IDS_ERRORLOADHV; switch (hr) { case ERROR_PRIVILEGE_NOT_HELD: uErrorStringID = IDS_ERRORLOADHVPRIV; break; case ERROR_SHARING_VIOLATION: uErrorStringID = IDS_ERRORLOADHVNOSHARE; break;
case ERROR_ACCESS_DENIED: uErrorStringID = IDS_ERRORLOADHVNOACC; break;
} InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(uErrorStringID), MAKEINTRESOURCE(IDS_LOADHVREGFILETITLE), MB_ICONERROR | MB_OK, achFileName); }
RegEdit_SetPrivilege(SE_RESTORE_NAME, FALSE); } LocalFree(EditValueParam.pValueData); }
RegEdit_SetWaitCursor(FALSE); } }
//------------------------------------------------------------------------------
// RegEdit_OnCommandUnloadHive
//
// DESCRIPTION: Open and Load a Hive
//
// PARAMETERS: hWnd - handle of RegEdit window.
//
//------------------------------------------------------------------------------
VOID RegEdit_OnCommandUnloadHive(HWND hWnd) { if (InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(IDS_CONFIRMDELHIVETEXT), MAKEINTRESOURCE(IDS_CONFIRMDELHIVETITLE), MB_ICONWARNING | MB_YESNO) == IDYES) { HRESULT hr; TCHAR achKeyName[MAXKEYNAME]; HTREEITEM hSelectedTreeItem = TreeView_GetSelection(g_RegEditData.hKeyTreeWnd); RegEdit_SetPrivilege(SE_RESTORE_NAME, TRUE);
// must close key to unload it
RegCloseKey(g_RegEditData.hCurrentSelectionKey);
if ((hr = RegUnLoadKey(KeyTree_GetRootKey(hSelectedTreeItem), KeyTree_GetKeyName(hSelectedTreeItem, achKeyName, ARRAYSIZE(achKeyName)))) == ERROR_SUCCESS) { g_RegEditData.hCurrentSelectionKey = NULL; RegEdit_OnKeyTreeRefresh(hWnd); } else { UINT uErrorStringID = IDS_ERRORUNLOADHV;
switch (hr) { case ERROR_PRIVILEGE_NOT_HELD: uErrorStringID = IDS_ERRORUNLOADHVPRIV; break; case ERROR_ACCESS_DENIED: uErrorStringID = IDS_ERRORUNLOADHVNOACC; break; } InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(uErrorStringID), MAKEINTRESOURCE(IDS_UNLOADHIVETITLE), MB_ICONERROR | MB_OK, achKeyName); // The key couldn't be unloaded so select it again
g_RegEditData.hCurrentSelectionKey = NULL; RegEdit_KeyTreeSelChanged(hWnd); } RegEdit_SetPrivilege(SE_RESTORE_NAME, FALSE); } }
/*******************************************************************************
* * RegEdit_OnCommandImportRegFile * * DESCRIPTION: * * PARAMETERS: * hWnd, handle of RegEdit window. * *******************************************************************************/ VOID RegEdit_OnCommandImportRegFile(HWND hWnd) {
TCHAR achFileName[MAX_PATH];
if (RegEdit_GetFileName(hWnd, IDS_IMPORTREGFILETITLE, IDS_REGIMPORTFILEFILTER, IDS_REGFILEDEFEXT, achFileName, ARRAYSIZE(achFileName), TRUE)) { // check for networked registries
if (TreeView_GetNextSibling(g_RegEditData.hKeyTreeWnd, TreeView_GetRoot(g_RegEditData.hKeyTreeWnd)) != NULL) { // Remote connections exist
RegEdit_ImportToConnectedComputer(hWnd, achFileName); } else { RegEdit_SetWaitCursor(TRUE); RegEdit_ImportRegFile(hWnd, FALSE, achFileName, NULL); // PERF: Only need to refresh the computer that we imported the
// file into, not the whole thing.
RegEdit_OnKeyTreeRefresh(hWnd); RegEdit_SetWaitCursor(FALSE); } } }
/*******************************************************************************
* * RegEdit_ExportRegFile * * DESCRIPTION: * * PARAMETERS: * hWnd, handle of RegEdit window. * fSilentMode, TRUE if no messages should be displayed, else FALSE. * lpFileName, address of file name buffer. * lpSelectedPath, * *******************************************************************************/
VOID PASCAL RegEdit_ExportRegFile( HWND hWnd, BOOL fSilentMode, LPTSTR lpFileName, LPTSTR lpSelectedPath ) {
//
// Fix a bug where /a or /e is specified and no file is passed in
//
if (lpFileName == NULL) { InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(IDS_NOFILESPECIFIED), MAKEINTRESOURCE(IDS_REGEDIT), MB_ICONERROR | MB_OK, lpFileName); return; }
switch (g_RegEditData.uExportFormat) { case FILE_TYPE_REGEDT32: ExportRegedt32File(lpFileName, lpSelectedPath); break;
case FILE_TYPE_REGEDIT4: ExportWin40RegFile(lpFileName, lpSelectedPath); break;
case FILE_TYPE_TEXT: RegEdit_SaveAsSubtree(lpFileName, lpSelectedPath); break;
default: ExportWinNT50RegFile(lpFileName, lpSelectedPath); break; }
if (g_FileErrorStringID != IDS_EXPFILEERRSUCCESS && g_FileErrorStringID != IDS_IMPFILEERRSUCCESSLOCAL) { InternalMessageBox(g_hInstance, hWnd, MAKEINTRESOURCE(g_FileErrorStringID), MAKEINTRESOURCE(IDS_REGEDIT), MB_ICONERROR | MB_OK, lpFileName); }
}
//------------------------------------------------------------------------------
// RegEdit_OnCommandExportRegFile
//
// DESCRIPTION:
//
// PARAMETERS: - hWnd, handle of RegEdit window.
//------------------------------------------------------------------------------
VOID RegEdit_OnCommandExportRegFile(HWND hWnd) { TCHAR achFileName[MAX_PATH]; LPTSTR lpSelectedPath;
if (RegEdit_GetFileName(hWnd, IDS_EXPORTREGFILETITLE, IDS_REGEXPORTFILEFILTER, IDS_REGFILEDEFEXT, achFileName, ARRAYSIZE(achFileName), FALSE)) { RegEdit_SetWaitCursor(TRUE);
lpSelectedPath = g_fRangeAll ? NULL : g_SelectedPath; RegEdit_ExportRegFile(hWnd, FALSE, achFileName, lpSelectedPath);
RegEdit_SetWaitCursor(FALSE); } }
//------------------------------------------------------------------------------
// RegEdit_GetFileName
//
// DESCRIPTION: Gets a file name
//
// PARAMETERS: hWnd - handle of RegEdit window.
// fOpen - TRUE if importing a file, else FALSE if exporting a file.
// lpFileName - address of file name buffer.
// cchFileName - size of file name buffer in TCHARacters.
//
// RETURN: True, if successfull
//------------------------------------------------------------------------------
BOOL RegEdit_GetFileName(HWND hWnd, UINT uTitleStringID, UINT uFilterStringID, UINT uDefExtStringID, LPTSTR lpFileName, DWORD cchFileName, BOOL fOpen) {
PTSTR pTitle = NULL; PTSTR pDefaultExtension = NULL; PTSTR pFilter = NULL; PTSTR pFilterChar; OPENFILENAME OpenFileName; BOOL fSuccess;
//
// Load various strings that will be displayed and used by the common open
// or save dialog box. Note that if any of these fail, the error is not
// fatal-- the common dialog box may look odd, but will still work.
//
pTitle = LoadDynamicString(uTitleStringID);
if (uDefExtStringID != IDS_REGNODEFEXT) { pDefaultExtension = LoadDynamicString(uDefExtStringID); }
if ((pFilter = LoadDynamicString(uFilterStringID)) != NULL) { // The common dialog library requires that the substrings of the
// filter string be separated by nulls, but we cannot load a string
// containing nulls. So we use some dummy character in the resource
// that we now convert to nulls.
for (pFilterChar = pFilter; *pFilterChar != 0; pFilterChar = CharNext(pFilterChar)) { if (*pFilterChar == TEXT('#')) *pFilterChar++ = 0;
}
}
*lpFileName = 0;
memset(&OpenFileName, 0, sizeof(OPENFILENAME));
OpenFileName.lStructSize = sizeof(OPENFILENAME); OpenFileName.hwndOwner = hWnd; OpenFileName.hInstance = g_hInstance; OpenFileName.lpstrFilter = pFilter; OpenFileName.lpstrFile = lpFileName; OpenFileName.nMaxFile = cchFileName; OpenFileName.lpstrTitle = pTitle; if (fOpen) { OpenFileName.Flags = OFN_HIDEREADONLY | OFN_EXPLORER | OFN_FILEMUSTEXIST;
fSuccess = GetOpenFileName(&OpenFileName);
}
else { OpenFileName.lpstrDefExt = pDefaultExtension; OpenFileName.Flags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_NOREADONLYRETURN | OFN_PATHMUSTEXIST | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE; OpenFileName.lpfnHook = RegCommDlgHookProc; OpenFileName.lpTemplateName = MAKEINTRESOURCE(IDD_REGEXPORT); g_RegCommDlgDialogTemplate = IDD_REGEXPORT;
fSuccess = GetSaveFileName(&OpenFileName);
}
//
// Delete all of the dynamic strings that we loaded.
//
if (pTitle != NULL) DeleteDynamicString(pTitle);
if (pDefaultExtension != NULL) DeleteDynamicString(pDefaultExtension);
if (pFilter != NULL) DeleteDynamicString(pFilter);
return fSuccess;
}
/*******************************************************************************
* * RegProgressDlgProc * * DESCRIPTION: * Callback procedure for the RegAbort dialog box. * * PARAMETERS: * hWnd, handle of RegProgress window. * Message, * wParam, * lParam, * (returns), * *******************************************************************************/
INT_PTR CALLBACK RegProgressDlgProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam ) {
switch (Message) {
case WM_INITDIALOG: //PathSetDlgItemPath(hWnd, IDC_FILENAME, (LPTSTR)lParam);
SetDlgItemText(hWnd, IDC_FILENAME, (LPTSTR) lParam); break;
default: return FALSE;
}
return TRUE;
}
/*******************************************************************************
* * ImportRegFileUICallback * * DESCRIPTION: * * PARAMETERS: * *******************************************************************************/
VOID ImportRegFileUICallback(UINT uPercentage) {
if (g_hRegProgressWnd != NULL) { SendDlgItemMessage(g_hRegProgressWnd, IDC_PROGRESSBAR, PBM_SETPOS, (WPARAM) uPercentage, 0);
while (MessagePump(g_hRegProgressWnd)); }
}
//------------------------------------------------------------------------------
// RegEdit_ImportToConnectedComputer
//
// DESCRIPTION: Imports a reg. file one or more of the connected computers
//
// PARAMETERS: HWND hWnd
// PTSTR pszFileName - import file
//------------------------------------------------------------------------------
void RegEdit_ImportToConnectedComputer(HWND hWnd, PTSTR pszFileName) { DialogBoxParam(g_hInstance, MAKEINTRESOURCE(IDD_REGIMPORTNET), hWnd, RegConnectedComputerDlgProc, (LPARAM) pszFileName); }
//------------------------------------------------------------------------------
// RegConnectedComputerDlgProc
//
// DESCRIPTION: Dlg Proc for selecting a connected computer
//
// PARAMETERS:
//------------------------------------------------------------------------------
INT_PTR RegConnectedComputerDlgProc(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam) { switch (uMessage) { case WM_INITDIALOG: SetWindowLongPtr(hWnd, DWLP_USER, lParam); return RegImport_OnInitDialog(hWnd); case WM_COMMAND: switch (GET_WM_COMMAND_ID(wParam, lParam)) { case IDOK: { PTSTR pszFileName = (PTSTR) GetWindowLongPtr(hWnd, DWLP_USER); // (pszFileName == NULL) is checked later
RegImport_OnCommandOk(hWnd, pszFileName); } // FALL THROUGH
case IDCANCEL: EndDialog(hWnd, 0); break; } return TRUE; } return FALSE; }
//------------------------------------------------------------------------------
// RegImport_OnInitDialog
//
// DESCRIPTION: Create a list of all the connected computers
//
// PARAMETERS: HWND hWnd
//------------------------------------------------------------------------------
INT_PTR RegImport_OnInitDialog(HWND hWnd) { HWND hComputerListWnd; RECT ClientRect; LV_COLUMN LVColumn; LV_ITEM LVItem; TCHAR achComputerName[MAX_PATH]; HWND hKeyTreeWnd; TV_ITEM TVItem;
hComputerListWnd = GetDlgItem(hWnd, IDC_COMPUTERLIST);
// Initialize the ListView control.
ListView_SetImageList(hComputerListWnd, g_RegEditData.hImageList, LVSIL_SMALL);
LVColumn.mask = LVCF_FMT | LVCF_WIDTH; LVColumn.fmt = LVCFMT_LEFT;
GetClientRect(hComputerListWnd, &ClientRect); LVColumn.cx = ClientRect.right - GetSystemMetrics(SM_CXVSCROLL) - 2 * GetSystemMetrics(SM_CXEDGE);
ListView_InsertColumn(hComputerListWnd, 0, &LVColumn); // Walk through the local machine and each remote connection listed
// in the KeyTree and add it to our RemoteList.
LVItem.mask = LVIF_TEXT | LVIF_IMAGE | LVIF_PARAM; LVItem.pszText = achComputerName; LVItem.iItem = 0; LVItem.iSubItem = 0; LVItem.iImage = IMAGEINDEX(IDI_COMPUTER);
hKeyTreeWnd = g_RegEditData.hKeyTreeWnd;
TVItem.mask = TVIF_TEXT; TVItem.hItem = TreeView_GetRoot(hKeyTreeWnd); TVItem.pszText = achComputerName; TVItem.cchTextMax = sizeof(achComputerName)/sizeof(TCHAR);
// Set "local computer" in list
LVItem.lParam = (LPARAM) TVItem.hItem; TreeView_GetItem(hKeyTreeWnd, &TVItem); ListView_InsertItem(hComputerListWnd, &LVItem);
LVItem.iItem++;
LVItem.iImage = IMAGEINDEX(IDI_REMOTE);
while ((TVItem.hItem = TreeView_GetNextSibling(hKeyTreeWnd, TVItem.hItem)) != NULL) {
LVItem.lParam = (LPARAM) TVItem.hItem; TreeView_GetItem(hKeyTreeWnd, &TVItem); ListView_InsertItem(hComputerListWnd, &LVItem);
LVItem.iItem++; }
ListView_SetItemState(hComputerListWnd, 0, LVIS_FOCUSED, LVIS_FOCUSED);
return TRUE;
}
//------------------------------------------------------------------------------
// RegImport_OnCommandOk
//
// DESCRIPTION: Import key to selected computers
//
// PARAMETERS: HWND hWnd,
// PTSTR pszFileName - file to import
//------------------------------------------------------------------------------
void RegImport_OnCommandOk(HWND hWnd, PTSTR pszFileName) { LV_ITEM LVItem; HWND hComputerListWnd;
// Walk through each selected item in the ListView and import the reg file
LVItem.mask = LVIF_PARAM; LVItem.iItem = -1; LVItem.iSubItem = 0;
hComputerListWnd = GetDlgItem(hWnd, IDC_COMPUTERLIST);
while ((LVItem.iItem = ListView_GetNextItem(hComputerListWnd, LVItem.iItem, LVNI_SELECTED)) != -1) { ListView_GetItem(hComputerListWnd, &LVItem);
RegEdit_SetWaitCursor(TRUE); RegEdit_ImportRegFile(hWnd, FALSE, pszFileName, (HTREEITEM) LVItem.lParam);
RegEdit_OnKeyTreeRefresh(hWnd); RegEdit_SetWaitCursor(FALSE); } }
|