1202 lines
26 KiB
C
1202 lines
26 KiB
C
|
||
/*++
|
||
|
||
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
|
||
FdpScanningDirsDlgProc(
|
||
IN HWND hwnd,
|
||
IN UINT msg,
|
||
IN DWORD wParam,
|
||
IN LONG 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
|
||
FdpSelectDirDlgProc(
|
||
IN HWND hwnd,
|
||
IN UINT msg,
|
||
IN DWORD wParam,
|
||
IN LONG 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,
|
||
(DLGPROC)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,
|
||
(DLGPROC)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;
|
||
}
|