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.
1201 lines
27 KiB
1201 lines
27 KiB
|
|
/*++
|
|
|
|
Copyright (c) 1991-1994 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ftreg.c
|
|
|
|
Abstract:
|
|
|
|
This module contains the routines for Disk Administrator that deal
|
|
with registry manipulation
|
|
|
|
Author:
|
|
|
|
Edward (Ted) Miller (TedM) 11/15/91
|
|
|
|
Environment:
|
|
|
|
User process.
|
|
|
|
Notes:
|
|
|
|
Revision History:
|
|
|
|
1-Feb-94 (bobri) Clean up and handle missing floppy disk on registry
|
|
save/restore.
|
|
|
|
--*/
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
|
|
#include "fdisk.h"
|
|
#include "ftregres.h"
|
|
|
|
|
|
|
|
// attempt to avoid conflict
|
|
|
|
#define TEMP_KEY_NAME TEXT("xzss3___$$Temp$Hive$$___")
|
|
|
|
#define DISK_KEY_NAME TEXT("DISK")
|
|
#define DISK_VALUE_NAME TEXT("Information")
|
|
|
|
|
|
LONG
|
|
FdpLoadHiveIntoRegistry(
|
|
IN LPTSTR HiveFilename
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine writes the contents of a given hive file into the registry,
|
|
rooted at a temporary key in HKEY_LOCAL_MACHINE.
|
|
|
|
Arguments:
|
|
|
|
HiveFilename - supplies filename of the hive to be loaded into
|
|
the registry
|
|
|
|
Return Value:
|
|
|
|
Windows error code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
BOOLEAN OldPrivState;
|
|
LONG Err;
|
|
|
|
// Attempt to get restore privilege
|
|
|
|
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE,
|
|
TRUE,
|
|
FALSE,
|
|
&OldPrivState);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return RtlNtStatusToDosError(Status);
|
|
}
|
|
|
|
// Load the hive into our registry
|
|
|
|
Err = RegLoadKey(HKEY_LOCAL_MACHINE,TEMP_KEY_NAME,HiveFilename);
|
|
|
|
// Restore old privilege if necessary
|
|
|
|
if (!OldPrivState) {
|
|
|
|
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE,
|
|
FALSE,
|
|
FALSE,
|
|
&OldPrivState);
|
|
}
|
|
|
|
return Err;
|
|
}
|
|
|
|
|
|
LONG
|
|
FdpUnloadHiveFromRegistry(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine removes a tree (previously loaded with
|
|
FdpLoadHiveIntoRegistry) from the temporary key in HKEY_LOCAL_MACHINE.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Windows error code.
|
|
|
|
--*/
|
|
|
|
{
|
|
NTSTATUS Status;
|
|
BOOLEAN OldPrivState;
|
|
LONG Err;
|
|
|
|
// Attempt to get restore privilege
|
|
|
|
Status = RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE,
|
|
TRUE,
|
|
FALSE,
|
|
&OldPrivState);
|
|
if (!NT_SUCCESS(Status)) {
|
|
return RtlNtStatusToDosError(Status);
|
|
}
|
|
|
|
// Unload the hive from our registry
|
|
|
|
Err = RegUnLoadKey(HKEY_LOCAL_MACHINE,TEMP_KEY_NAME);
|
|
|
|
// Restore old privilege if necessary
|
|
|
|
if (!OldPrivState) {
|
|
|
|
RtlAdjustPrivilege(SE_RESTORE_PRIVILEGE,
|
|
FALSE,
|
|
FALSE,
|
|
&OldPrivState);
|
|
}
|
|
|
|
return Err;
|
|
}
|
|
|
|
|
|
LONG
|
|
FdpGetDiskInfoFromKey(
|
|
IN LPTSTR RootKeyName,
|
|
OUT PVOID *DiskInfo,
|
|
OUT PULONG DiskInfoSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine pulls the binary blob containing disk ft, drive letter,
|
|
and layout information out of a given registry key.
|
|
|
|
The info is found in HKEY_LOCAL_MACHINE,<RootKeyName>\DISK:Information.
|
|
|
|
Arguments:
|
|
|
|
RootKeyName - name of the subkey of HKEY_LOCAL_MACHINE that is to
|
|
contain the DISK key.
|
|
|
|
DiskInfo - receives a pointer to a buffer containing the disk info.
|
|
|
|
DiskInfoSize - receives size of the disk buffer.
|
|
|
|
Return Value:
|
|
|
|
Windows error code. If NO_ERROR, DiskInfo and DiskInfoSize are
|
|
filled in, and it is the caller's responsibility to free the buffer
|
|
when it is finished (via LocalFree()).
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG Err;
|
|
HKEY hkeyDisk;
|
|
ULONG BufferSize;
|
|
ULONG ValueType;
|
|
PVOID Buffer;
|
|
LPTSTR DiskKeyName;
|
|
|
|
// Form the name of the DISK key
|
|
|
|
DiskKeyName = (LPTSTR)LocalAlloc( LMEM_FIXED,
|
|
( lstrlen(RootKeyName)
|
|
+ lstrlen(DISK_KEY_NAME)
|
|
+ 2 // the \ and nul
|
|
)
|
|
* sizeof(TCHAR)
|
|
);
|
|
|
|
if (DiskKeyName == NULL) {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
lstrcpy(DiskKeyName,RootKeyName);
|
|
lstrcat(DiskKeyName,TEXT("\\"));
|
|
lstrcat(DiskKeyName,DISK_KEY_NAME);
|
|
|
|
// Open the DISK key.
|
|
|
|
Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
DiskKeyName,
|
|
REG_OPTION_RESERVED,
|
|
KEY_READ,
|
|
&hkeyDisk);
|
|
|
|
if (Err != NO_ERROR) {
|
|
goto CleanUp2;
|
|
}
|
|
|
|
// Determine how large we need the buffer to be
|
|
|
|
Err = RegQueryValueEx(hkeyDisk,
|
|
DISK_VALUE_NAME,
|
|
NULL,
|
|
&ValueType,
|
|
NULL,
|
|
&BufferSize);
|
|
|
|
if ((Err != NO_ERROR) && (Err != ERROR_MORE_DATA)) {
|
|
goto CleanUp1;
|
|
}
|
|
|
|
// Allocate a buffer of appropriate size
|
|
|
|
Buffer = (PVOID)LocalAlloc(LMEM_FIXED,BufferSize);
|
|
if (Buffer == NULL) {
|
|
Err = ERROR_NOT_ENOUGH_MEMORY;
|
|
goto CleanUp1;
|
|
}
|
|
|
|
// Query the data
|
|
|
|
Err = RegQueryValueEx(hkeyDisk,
|
|
DISK_VALUE_NAME,
|
|
NULL,
|
|
&ValueType,
|
|
Buffer,
|
|
&BufferSize);
|
|
|
|
if (Err != NO_ERROR) {
|
|
LocalFree(Buffer);
|
|
goto CleanUp1;
|
|
}
|
|
|
|
*DiskInfo = Buffer;
|
|
*DiskInfoSize = BufferSize;
|
|
|
|
CleanUp1:
|
|
|
|
RegCloseKey(hkeyDisk);
|
|
|
|
CleanUp2:
|
|
|
|
LocalFree(DiskKeyName);
|
|
|
|
return Err;
|
|
}
|
|
|
|
|
|
LONG
|
|
FdpGetDiskInfoFromHive(
|
|
IN PCHAR HiveFilename,
|
|
OUT PVOID *DiskInfo,
|
|
OUT PULONG DiskInfoSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine pulls the binary blob containing disk ft, drive letter,
|
|
and layout information out of a given registry hive, which must be
|
|
a file in an alternate NT tree (ie, can't be an active hive).
|
|
|
|
The info is found in \DISK:Information within the hive.
|
|
|
|
Arguments:
|
|
|
|
HiveFilename - supplies filename of hive
|
|
|
|
DiskInfo - receives a pointer to a buffer containing the disk info.
|
|
|
|
DiskInfoSize - receives size of the disk buffer.
|
|
|
|
Return Value:
|
|
|
|
Windows error code. If NO_ERROR, DiskInfo and DiskInfoSize are
|
|
filled in, and it is the caller's responsibility to free the buffer
|
|
when it is finished (via LocalFree()).
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG windowsError;
|
|
|
|
windowsError = FdpLoadHiveIntoRegistry(HiveFilename);
|
|
if (windowsError == NO_ERROR) {
|
|
windowsError = FdpGetDiskInfoFromKey(TEMP_KEY_NAME,DiskInfo,DiskInfoSize);
|
|
FdpUnloadHiveFromRegistry();
|
|
}
|
|
|
|
return windowsError;
|
|
}
|
|
|
|
|
|
LONG
|
|
FdTransferOldDiskInfoToRegistry(
|
|
IN PCHAR HiveFilename
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine transfers disk configuration from a given hive file
|
|
(which should be an inactive system hive) to the current registry.
|
|
|
|
Arguments:
|
|
|
|
HiveFilename - supplies filename of source hive
|
|
|
|
Return Value:
|
|
|
|
Windows error code.
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG windowsError;
|
|
PVOID diskInfo;
|
|
ULONG diskInfoSize;
|
|
HKEY hkeyDisk;
|
|
|
|
|
|
// Load up the hive and pull the disk info from it.
|
|
|
|
windowsError = FdpGetDiskInfoFromHive(HiveFilename,&diskInfo,&diskInfoSize);
|
|
if (windowsError != NO_ERROR) {
|
|
return windowsError;
|
|
}
|
|
|
|
// Propogate the disk info into the current registry.
|
|
//
|
|
// Start by opening HKEY_LOCAL_MACHINE,System\DISK
|
|
|
|
windowsError = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("System\\") DISK_KEY_NAME,
|
|
REG_OPTION_RESERVED,
|
|
KEY_WRITE,
|
|
&hkeyDisk);
|
|
|
|
if (windowsError != NO_ERROR) {
|
|
LocalFree(diskInfo);
|
|
return windowsError;
|
|
}
|
|
|
|
// Set the Information value in the DISK key.
|
|
|
|
windowsError = RegSetValueEx(hkeyDisk,
|
|
DISK_VALUE_NAME,
|
|
0,
|
|
REG_BINARY,
|
|
diskInfo,
|
|
diskInfoSize);
|
|
RegCloseKey(hkeyDisk);
|
|
LocalFree(diskInfo);
|
|
return windowsError;
|
|
}
|
|
|
|
|
|
typedef struct _STRING_LIST_NODE {
|
|
struct _STRING_LIST_NODE *Next;
|
|
LPTSTR String;
|
|
} STRING_LIST_NODE, *PSTRING_LIST_NODE;
|
|
|
|
PSTRING_LIST_NODE FoundDirectoryList;
|
|
ULONG FoundDirectoryCount;
|
|
|
|
TCHAR Pattern[MAX_PATH+1];
|
|
WIN32_FIND_DATA FindData;
|
|
OFSTRUCT OfStruct;
|
|
HWND hwndStatus;
|
|
BOOLEAN ScanDrive[26];
|
|
BOOLEAN UserCancelled;
|
|
|
|
|
|
typedef
|
|
BOOL
|
|
(*PFOUND_HIVE_ROUTINE)(
|
|
IN LPTSTR Directory
|
|
);
|
|
|
|
VOID
|
|
ProcessPendingMessages(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Preprocess messages.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
MSG msg;
|
|
|
|
while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
|
|
DispatchMessage(&msg);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
PUCHAR ConfigRegistryPath = "\\system32\\config\\system";
|
|
BOOL
|
|
FdpSearchTreeForSystemHives(
|
|
IN LPTSTR CurrentDirectory,
|
|
IN PFOUND_HIVE_ROUTINE FoundHiveRoutine,
|
|
IN HWND hdlg
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Search an entire directory tree for system and system.alt hive files.
|
|
When found, call a callback function with the directory in which
|
|
system32\config\system[.alt] was found, and the full path of the hive
|
|
file.
|
|
|
|
The root directory is not included in the search.
|
|
|
|
The top-level call to this function should have a current directory
|
|
like "C:." (ie, no slash for the root directory).
|
|
|
|
Arguments:
|
|
|
|
CurrentDirectory - supplies current directory search path
|
|
|
|
Return Value:
|
|
|
|
FALSE if error (callback function returned FALSE when we found an entry).
|
|
|
|
--*/
|
|
|
|
{
|
|
HANDLE findHandle;
|
|
TCHAR newDirectory[MAX_PATH+1];
|
|
BOOL found = FALSE;
|
|
|
|
// Iterate through the current directory, looking for subdirectories.
|
|
|
|
lstrcpy(Pattern, CurrentDirectory);
|
|
lstrcat(Pattern, "\\*");
|
|
findHandle = FindFirstFile(Pattern, &FindData);
|
|
|
|
if (findHandle != INVALID_HANDLE_VALUE) {
|
|
|
|
do {
|
|
|
|
ProcessPendingMessages();
|
|
if (UserCancelled) {
|
|
return FALSE;
|
|
}
|
|
|
|
// If the current match is not a directory then skip it.
|
|
|
|
if (!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
|| !lstrcmp(FindData.cFileName,TEXT("."))
|
|
|| !lstrcmp(FindData.cFileName,TEXT(".."))) {
|
|
continue;
|
|
}
|
|
|
|
found = FALSE;
|
|
|
|
// Form the name of the file we are looking for
|
|
// [<currentdirectory>\<match>\system32\config\system]
|
|
|
|
lstrcpy(Pattern, CurrentDirectory);
|
|
lstrcat(Pattern, "\\");
|
|
lstrcat(Pattern, FindData. cFileName);
|
|
|
|
lstrcpy(newDirectory, Pattern);
|
|
|
|
// Don't decend into the directory unless the path to the
|
|
// hive.alt name is within MAX_PATH length.
|
|
|
|
if ((ULONG)(lstrlen(newDirectory) / sizeof(TCHAR)) < (MAX_PATH - strlen(ConfigRegistryPath) - 4)) {
|
|
|
|
SetDlgItemText(hdlg, IDC_SIMPLE_TEXT_LINE, newDirectory);
|
|
|
|
lstrcat(Pattern, TEXT(ConfigRegistryPath));
|
|
|
|
if (OpenFile(Pattern, &OfStruct, OF_EXIST) != (HFILE)(-1)) {
|
|
found = TRUE;
|
|
}
|
|
|
|
// Also check for a system.alt file there
|
|
|
|
lstrcat(Pattern,TEXT(".alt"));
|
|
|
|
if (OpenFile(Pattern, &OfStruct, OF_EXIST) != (HFILE)(-1)) {
|
|
found = TRUE;
|
|
}
|
|
|
|
if (found) {
|
|
if (!FoundHiveRoutine(newDirectory)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// Descend into the directory we just found
|
|
|
|
if (!FdpSearchTreeForSystemHives(newDirectory, FoundHiveRoutine, hdlg)) {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
} while (FindNextFile(findHandle,&FindData));
|
|
|
|
FindClose(findHandle);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
FdpFoundHiveCallback(
|
|
IN PCHAR Directory
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
This routine is called when a directory containing a system hive
|
|
has been located. If all goes well (allocate memory and the like)
|
|
this routine will save the directory name in a list for later use.
|
|
NOTE: No checks are made on the directory name being greater in
|
|
length than MAX_PATH. It is the responsibility of the caller to
|
|
insure that this is true.
|
|
|
|
Arguments:
|
|
|
|
Directory - the pointer to the character string for the directory
|
|
where a hive has been located.
|
|
|
|
Return Value:
|
|
|
|
TRUE - did something with it.
|
|
FALSE - did not save the directory.
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR windowsDir[MAX_PATH+1];
|
|
PSTRING_LIST_NODE dirItem;
|
|
LPTSTR p;
|
|
|
|
// If this is the current windows directory, skip it.
|
|
|
|
GetWindowsDirectory(windowsDir, sizeof(windowsDir)/sizeof(TCHAR));
|
|
|
|
if (!lstrcmpi(Directory, windowsDir)) {
|
|
return TRUE;
|
|
}
|
|
|
|
// Save the directory information away
|
|
|
|
dirItem = (PSTRING_LIST_NODE)LocalAlloc(LMEM_FIXED|LMEM_ZEROINIT, sizeof(STRING_LIST_NODE));
|
|
if (dirItem == NULL) {
|
|
return FALSE;
|
|
}
|
|
|
|
p = (LPTSTR)LocalAlloc(LMEM_FIXED,(lstrlen(Directory)+1) * sizeof(TCHAR));
|
|
if (p == NULL) {
|
|
LocalFree(dirItem);
|
|
return FALSE;
|
|
}
|
|
|
|
dirItem->String = p;
|
|
lstrcpy(p, Directory);
|
|
|
|
// Update the global chain of found directories.
|
|
|
|
dirItem->Next = FoundDirectoryList;
|
|
FoundDirectoryList = dirItem;
|
|
FoundDirectoryCount++;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
FdpFreeDirectoryList(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Go through the list of directories containing system hives and
|
|
free the entries.
|
|
|
|
Arguments:
|
|
|
|
None
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
|
|
{
|
|
PSTRING_LIST_NODE n,
|
|
p = FoundDirectoryList;
|
|
|
|
while (p) {
|
|
n = p->Next;
|
|
if (p->String) {
|
|
LocalFree(p->String);
|
|
}
|
|
LocalFree(p);
|
|
p = n;
|
|
}
|
|
|
|
FoundDirectoryCount = 0;
|
|
FoundDirectoryList = NULL;
|
|
}
|
|
|
|
|
|
BOOL CALLBACK
|
|
FdpScanningDirsDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT msg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Display the "scanning" dialog, then when the IDLE message arrives
|
|
process all drive letters and search for system hives.
|
|
|
|
Arguments:
|
|
|
|
Windows dialog proc
|
|
|
|
Return Value:
|
|
|
|
Windows dialog proc
|
|
|
|
--*/
|
|
|
|
{
|
|
TCHAR LetterColon[3];
|
|
TCHAR Letter;
|
|
|
|
switch (msg) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
CenterDialog(hwnd);
|
|
break;
|
|
|
|
case WM_ENTERIDLE:
|
|
|
|
// Sent to us by the main window after the dialog is displayed.
|
|
// Perform the search here.
|
|
|
|
ConfigurationSearchIdleTrigger = FALSE;
|
|
|
|
UserCancelled = FALSE;
|
|
|
|
lstrcpy(LetterColon,TEXT("?:"));
|
|
for (Letter = TEXT('A'); Letter <= TEXT('Z'); Letter++) {
|
|
|
|
if (!ScanDrive[Letter-TEXT('A')]) {
|
|
continue;
|
|
}
|
|
|
|
LetterColon[0] = Letter;
|
|
|
|
if (!FdpSearchTreeForSystemHives(LetterColon, FdpFoundHiveCallback, hwnd)) {
|
|
EndDialog(hwnd,IDCANCEL);
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
|
|
EndDialog(hwnd,IDOK);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch (LOWORD(wParam)) {
|
|
|
|
case IDCANCEL:
|
|
|
|
UserCancelled = TRUE;
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL CALLBACK
|
|
FdpSelectDirDlgProc(
|
|
IN HWND hwnd,
|
|
IN UINT msg,
|
|
IN WPARAM wParam,
|
|
IN LPARAM lParam
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Using the list of directories containing system hives, display the
|
|
selections to the user and save the selected item if the user so
|
|
chooses.
|
|
|
|
Arguments:
|
|
|
|
Windows dialog proc.
|
|
|
|
Return Value:
|
|
|
|
Windows dialog proc.
|
|
|
|
--*/
|
|
|
|
{
|
|
PSTRING_LIST_NODE Str;
|
|
LONG i;
|
|
static HANDLE ListBoxHandle;
|
|
|
|
switch (msg) {
|
|
|
|
case WM_INITDIALOG:
|
|
|
|
CenterDialog(hwnd);
|
|
|
|
// Add each item in the directory list to the listbox
|
|
|
|
ListBoxHandle = GetDlgItem(hwnd,IDC_LISTBOX);
|
|
|
|
for (Str = FoundDirectoryList; Str; Str = Str->Next) {
|
|
|
|
i = SendMessage(ListBoxHandle,LB_ADDSTRING ,0,(LONG)Str->String);
|
|
SendMessage(ListBoxHandle,LB_SETITEMDATA,i,(LONG)Str );
|
|
}
|
|
|
|
// select the zeroth item
|
|
|
|
SendMessage(ListBoxHandle,LB_SETCURSEL,0,0);
|
|
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
|
|
switch (LOWORD(wParam)) {
|
|
|
|
case IDOK:
|
|
|
|
// Get the index of the current list box selection and the
|
|
// pointer to the string node associated with it.
|
|
|
|
i = SendMessage(ListBoxHandle,LB_GETCURSEL,0,0);
|
|
EndDialog(hwnd,SendMessage(ListBoxHandle,LB_GETITEMDATA,i,0));
|
|
break;
|
|
|
|
case IDCANCEL:
|
|
|
|
EndDialog(hwnd,(int)NULL);
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
DoMigratePreviousFtConfig(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allow the user to move the disk config info from a different Windows NT
|
|
installation into the current registry.
|
|
|
|
For each fixed disk volume, scan it for system hives and present the
|
|
results to the user so he can select the installation to migrate.
|
|
|
|
Then load the system hive from that instllation (system.alt if the system
|
|
hive is corrupt, etc) and transfer the DISK:Information binary blob.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
FALSE if error or user cancelled, TRUE if info was migrated and reboot
|
|
is required.
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG windowsError;
|
|
TCHAR letter;
|
|
TCHAR letterColon[4];
|
|
PSTRING_LIST_NODE stringNode;
|
|
|
|
// Tell the user what this will do and prompt for confirmation
|
|
|
|
if (ConfirmationDialog(MSG_CONFIRM_MIGRATE_CONFIG, MB_ICONEXCLAMATION | MB_YESNO) != IDYES) {
|
|
return FALSE;
|
|
}
|
|
|
|
ProcessPendingMessages();
|
|
|
|
// Figure out which drives are relevent
|
|
|
|
SetCursor(hcurWait);
|
|
|
|
RtlZeroMemory(ScanDrive,sizeof(ScanDrive));
|
|
lstrcpy(letterColon,TEXT("?:\\"));
|
|
for (letter=TEXT('A'); letter<=TEXT('Z'); letter++) {
|
|
|
|
letterColon[0] = letter;
|
|
|
|
if (GetDriveType(letterColon) == DRIVE_FIXED) {
|
|
|
|
ScanDrive[letter-TEXT('A')] = TRUE;
|
|
}
|
|
}
|
|
|
|
SetCursor(hcurNormal);
|
|
|
|
// Create a window that will list the directories being scanned, to
|
|
// keep the user entertained.
|
|
|
|
ConfigurationSearchIdleTrigger = TRUE;
|
|
|
|
windowsError = DialogBox(hModule,
|
|
MAKEINTRESOURCE(IDD_SIMPLETEXT),
|
|
hwndFrame,
|
|
FdpScanningDirsDlgProc);
|
|
|
|
if (windowsError == IDCANCEL) {
|
|
FdpFreeDirectoryList();
|
|
return FALSE;
|
|
}
|
|
|
|
ProcessPendingMessages();
|
|
|
|
if (!FoundDirectoryCount) {
|
|
|
|
InfoDialog(MSG_NO_OTHER_NTS);
|
|
return FALSE;
|
|
}
|
|
|
|
// Display a dialog box that allows the user to select one of the
|
|
// directories we found.
|
|
|
|
stringNode = (PSTRING_LIST_NODE)DialogBox(hModule,
|
|
MAKEINTRESOURCE(IDD_SELDIR),
|
|
hwndFrame,
|
|
FdpSelectDirDlgProc);
|
|
|
|
if (stringNode == NULL) {
|
|
FdpFreeDirectoryList();
|
|
return FALSE;
|
|
}
|
|
|
|
// User made a selection. One last confirmation.
|
|
|
|
if (ConfirmationDialog(MSG_ABSOLUTELY_SURE,MB_ICONEXCLAMATION | MB_YESNO) != IDYES) {
|
|
FdpFreeDirectoryList();
|
|
return FALSE;
|
|
}
|
|
|
|
ProcessPendingMessages();
|
|
|
|
SetCursor(hcurWait);
|
|
|
|
lstrcpy(Pattern,stringNode->String);
|
|
lstrcat(Pattern,TEXT(ConfigRegistryPath));
|
|
|
|
windowsError = FdTransferOldDiskInfoToRegistry(Pattern);
|
|
if (windowsError != NO_ERROR) {
|
|
lstrcat(Pattern,TEXT(".alt"));
|
|
windowsError = FdTransferOldDiskInfoToRegistry(Pattern);
|
|
}
|
|
FdpFreeDirectoryList();
|
|
SetCursor(hcurNormal);
|
|
|
|
if (windowsError != NO_ERROR) {
|
|
|
|
if (windowsError == ERROR_FILE_NOT_FOUND) {
|
|
ErrorDialog(MSG_NO_DISK_INFO);
|
|
} else if (windowsError == ERROR_SHARING_VIOLATION) {
|
|
ErrorDialog(MSG_DISK_INFO_BUSY);
|
|
} else {
|
|
ErrorDialog(windowsError);
|
|
}
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
DoRestoreFtConfig(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Restore previously saved disk configuration information into the
|
|
active registry.
|
|
|
|
The saved config info will come from a floppy that the user is
|
|
prompted to insert.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
FALSE if error or user cancelled, TRUE if info was restored and reboot
|
|
is required.
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG Err;
|
|
TCHAR caption[256];
|
|
UINT errorMode;
|
|
va_list arglist =
|
|
#ifdef _ALPHA_ // Alpha defines va_list as a struct. Init as such
|
|
{0};
|
|
#else
|
|
NULL;
|
|
#endif
|
|
|
|
|
|
// Get confirmation
|
|
|
|
if (ConfirmationDialog(MSG_CONFIRM_RESTORE_CONFIG, MB_ICONEXCLAMATION | MB_YESNO) != IDYES) {
|
|
return FALSE;
|
|
}
|
|
|
|
// Get the diskette into A:.
|
|
|
|
errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
LoadString(hModule,IDS_INSERT_DISK,caption,sizeof(caption)/sizeof(TCHAR));
|
|
if (CommonDialog(MSG_INSERT_REGSAVEDISK,caption,MB_OKCANCEL | MB_TASKMODAL, arglist) != IDOK) {
|
|
return FALSE;
|
|
}
|
|
|
|
ProcessPendingMessages();
|
|
SetCursor(hcurWait);
|
|
|
|
// If there is no file called SYSTEM on a:\, it appears that the registry
|
|
// creates one and then keeps it open. To avoid this, check to see
|
|
// whether there is one first.
|
|
|
|
if (OpenFile(TEXT("A:\\SYSTEM"),&OfStruct,OF_EXIST) == (HFILE)(-1)) {
|
|
Err = ERROR_FILE_NOT_FOUND;
|
|
} else {
|
|
Err = FdTransferOldDiskInfoToRegistry(TEXT("A:\\SYSTEM"));
|
|
}
|
|
|
|
SetErrorMode(errorMode);
|
|
SetCursor(hcurNormal);
|
|
|
|
if (Err != NO_ERROR) {
|
|
ErrorDialog(Err);
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DoSaveFtConfig(
|
|
VOID
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Allow the user to update the registry save diskette with the currently
|
|
defined disk configuration. The saved info excludes any changes made
|
|
during this session of disk manager.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
None.
|
|
|
|
--*/
|
|
|
|
{
|
|
LONG Err,
|
|
ErrAlt;
|
|
LPTSTR SystemHiveName = TEXT("a:\\system");
|
|
HKEY hkey;
|
|
TCHAR caption[256];
|
|
DWORD disposition;
|
|
UINT errorMode;
|
|
va_list arglist =
|
|
#ifdef _ALPHA_
|
|
{0}; // Alpha defines va_list as a struct. Init as such.
|
|
#else
|
|
NULL;
|
|
#endif
|
|
|
|
// Get a diskette into A:.
|
|
|
|
LoadString(hModule,
|
|
IDS_INSERT_DISK,
|
|
caption,
|
|
sizeof(caption)/sizeof(TCHAR));
|
|
if (CommonDialog(MSG_INSERT_REGSAVEDISK2,caption,MB_OKCANCEL | MB_TASKMODAL, arglist) != IDOK) {
|
|
return;
|
|
}
|
|
|
|
// Decide what to do based on the presence of a a:\system. If that file
|
|
// is present, just update the DISK entry in it. If it is not present,
|
|
// then blast out the entire system hive.
|
|
|
|
errorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
|
|
ProcessPendingMessages();
|
|
SetCursor(hcurWait);
|
|
|
|
if (OpenFile(SystemHiveName,&OfStruct,OF_EXIST) == (HFILE)(-1)) {
|
|
|
|
BOOLEAN OldPrivState;
|
|
NTSTATUS Status;
|
|
|
|
// Blast the entire system hive out to the floppy.
|
|
// Start by attempting to get backup privilege.
|
|
|
|
Status = RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,
|
|
TRUE,
|
|
FALSE,
|
|
&OldPrivState);
|
|
|
|
Err = RtlNtStatusToDosError(Status);
|
|
if (Err == NO_ERROR) {
|
|
|
|
Err = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEXT("system"),
|
|
REG_OPTION_RESERVED,
|
|
KEY_READ,
|
|
&hkey);
|
|
|
|
if (Err == NO_ERROR) {
|
|
|
|
Err = RegSaveKey(hkey,SystemHiveName,NULL);
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
if (!OldPrivState) {
|
|
RtlAdjustPrivilege(SE_BACKUP_PRIVILEGE,FALSE,FALSE,&OldPrivState);
|
|
}
|
|
}
|
|
} else {
|
|
|
|
PVOID DiskInfo;
|
|
ULONG DiskInfoSize;
|
|
|
|
// Load up the saved system hive
|
|
|
|
Err = FdpLoadHiveIntoRegistry(SystemHiveName);
|
|
if (Err == NO_ERROR) {
|
|
|
|
// Get the current DISK information
|
|
|
|
Err = FdpGetDiskInfoFromKey(TEXT("system"),&DiskInfo,&DiskInfoSize);
|
|
if (Err == NO_ERROR) {
|
|
|
|
// Place the current disk information into the saved hive
|
|
|
|
Err = RegCreateKeyEx(HKEY_LOCAL_MACHINE,
|
|
TEMP_KEY_NAME TEXT("\\") DISK_KEY_NAME,
|
|
0,
|
|
"Disk and fault tolerance information.",
|
|
REG_OPTION_NON_VOLATILE,
|
|
KEY_WRITE,
|
|
NULL,
|
|
&hkey,
|
|
&disposition );
|
|
|
|
if (Err == NO_ERROR) {
|
|
|
|
Err = RegSetValueEx(hkey,
|
|
DISK_VALUE_NAME,
|
|
REG_OPTION_RESERVED,
|
|
REG_BINARY,
|
|
DiskInfo,
|
|
DiskInfoSize);
|
|
|
|
RegFlushKey(hkey);
|
|
RegCloseKey(hkey);
|
|
}
|
|
|
|
LocalFree(DiskInfo);
|
|
}
|
|
|
|
ErrAlt = FdpUnloadHiveFromRegistry();
|
|
|
|
if (Err == NO_ERROR && ErrAlt != NO_ERROR) {
|
|
|
|
Err = ErrAlt;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetCursor(hcurNormal);
|
|
SetErrorMode(errorMode);
|
|
|
|
if (Err == NO_ERROR) {
|
|
InfoDialog(MSG_CONFIG_SAVED_OK);
|
|
} else {
|
|
ErrorDialog(Err);
|
|
}
|
|
|
|
return;
|
|
}
|