Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

822 lines
24 KiB

/*******************************************************************************
*
* (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, ARRAYSIZE(FileName));
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 security 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 = 50 * sizeof(TCHAR);
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);
//
// REVIEW:
// What if EditValueParam.pValueData is greater than 50 characters that have been allocated ?
// Is it NULL terminated ?
//
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);
// DebugAssert(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 = ARRAYSIZE(achComputerName);
// 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);
}
}