windows-nt/Source/XPSP1/NT/net/jet500/jetconv/convert.c
2020-09-26 16:20:57 +08:00

1314 lines
42 KiB
C

/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
convert.c
Abstract:
Contains the conversion related routines.
Author:
Sanjay Anand (SanjayAn) Nov. 14, 1995
Environment:
User mode
Revision History:
Sanjay Anand (SanjayAn) Nov. 14, 1995
Created
--*/
#include "defs.h"
#define MAX_TRIES 30
NTSTATUS
JCCallUpg(
IN SERVICES Id,
IN PSERVICE_INFO pServiceInfo
)
/*++
Routine Description:
This routine creates a process to convert a database file.
Arguments:
Id - service id
pServiceInfo - Pointer to the service information struct.
Return Value:
None.
--*/
{
TCHAR imageName[] = CONVERT_EXE_PATH;
TCHAR exImageName[MAX_PATH];
TCHAR curDir[MAX_PATH];
STARTUPINFO startInfo;
PROCESS_INFORMATION procInfo;
DWORD error;
DWORD exitCode, size;
TCHAR cmdLine[MAX_PATH+1000]="";
TCHAR exCmdLine[MAX_PATH+1000];
TCHAR temp[MAX_PATH];
TCHAR sId[3];
// upg351db c:\winnt\system32\wins\wins.mdb /e2 /@ /dc:\winnt\system32\jet.dll
// /yc:\winnt\system32\wins\system.mdb /lc:\winnt\system32\wins
// /bc:\winnt\system32\wins\backup /pc:\winnt\system32\wins\351db
if ((size = ExpandEnvironmentStrings( imageName,
exImageName,
MAX_PATH)) == 0) {
error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", imageName, error));
}
strcat(cmdLine, exImageName);
strcat(cmdLine, " ");
//
// Build the command line
//
strcat(cmdLine, pServiceInfo[Id].DBPath);
strcat(cmdLine, " /e");
sprintf(sId, "%d", Id+1);
strcat(cmdLine, sId);
//
// Passed in to indicate to upg351db that it was called by me and not from cmd line.
// This is so it can know whether CreateMutex shd fail.
//
strcat(cmdLine, " /@");
strcat(cmdLine, " /d");
strcat(cmdLine, SYSTEM_ROOT);
strcat(cmdLine, "jet.dll");
strcat(cmdLine, " /y");
strcat(cmdLine, pServiceInfo[Id].SystemFilePath);
strcat(cmdLine, " /l");
strcat(cmdLine, pServiceInfo[Id].LogFilePath);
//
// WINS does not have a default backup path
//
if (pServiceInfo[Id].BackupPath[0] != '\0') {
strcat(cmdLine, " /b");
strcat(cmdLine, pServiceInfo[Id].BackupPath);
}
strcat(cmdLine, " /p");
strcpy(temp, pServiceInfo[Id].LogFilePath);
strcat(temp, "\\351db");
strcat(cmdLine, temp);
if ((size = ExpandEnvironmentStrings( cmdLine,
exCmdLine,
MAX_PATH+1000)) == 0) {
error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", cmdLine, error));
}
if (!GetSystemDirectory( curDir,
MAX_PATH)) {
error = GetLastError();
MYDEBUG(("GetSystemDirectory returned error: %lx\n", error));
return error;
}
MYDEBUG(("cmdLine: %s\n", exCmdLine));
memset(&startInfo, 0, sizeof(startInfo));
startInfo.cb = sizeof(startInfo);
//
// Create a process for the convert.exe program.
//
if(!CreateProcess( exImageName, // image name
exCmdLine, // command line
(LPSECURITY_ATTRIBUTES )NULL, // process security attr.
(LPSECURITY_ATTRIBUTES )NULL, // thread security attr.
FALSE, // inherit handle?
0, // creation flags
(LPVOID )NULL, // new environ. block
curDir, // current directory
&startInfo, // startupinfo
&procInfo )) { // process info.
error = GetLastError();
MYDEBUG(("CreateProcess returned error: %lx\n", error));
return error;
}
MYDEBUG(("CreateProcess succeeded\n"));
//
// Get the exit code of the process to determine if the convert went through.
//
do {
if (!GetExitCodeProcess(procInfo.hProcess,
&exitCode)) {
error = GetLastError();
MYDEBUG(("GetExitCode returned error: %lx\n", error));
return error;
}
} while ( exitCode == STILL_ACTIVE );
//
// If non-zero exit code, report the error
//
if (exitCode) {
MYDEBUG(("ExitCode: %lx\n", exitCode));
return exitCode;
}
return STATUS_SUCCESS ;
}
NTSTATUS
JCCallESE(
IN SERVICES Id,
IN PSERVICE_INFO pServiceInfo
)
/*++
Routine Description:
This routine creates a process to convert a database file from jet500 to jet600.
Arguments:
Id - service id
pServiceInfo - Pointer to the service information struct.
Return Value:
None.
--*/
{
TCHAR imageName[] = CONVERT_EXE_PATH_ESE;
TCHAR exImageName[MAX_PATH];
TCHAR curDir[MAX_PATH];
STARTUPINFO startInfo;
PROCESS_INFORMATION procInfo;
DWORD error;
DWORD exitCode, size;
TCHAR cmdLine[MAX_PATH+1000]="";
TCHAR exCmdLine[MAX_PATH+1000];
TCHAR temp[MAX_PATH];
TCHAR sId[3];
TCHAR Preserve40DbPath[MAX_PATH];
TCHAR Preserve40BasePath[MAX_PATH];
TCHAR PreserveBasePath[MAX_PATH];
TCHAR PreserveDbPath[MAX_PATH];
TCHAR DbFile[MAX_PATH], DbFileName[MAX_PATH];
HANDLE HSearch = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA FileData;
ULONG index = 0, tries = 0;
TCHAR DatabaseFileName[MAX_PATH];
LPVOID lpMsgBuf;
DWORD MsgLen = 0, Error = 0;
// eseutil /u c:\winnt\system32\wins\wins.mdb /dc:\winnt\system32\edb.dll
//
if ((size = ExpandEnvironmentStrings( imageName,
exImageName,
MAX_PATH)) == 0) {
error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", imageName, error));
}
strcat(cmdLine, exImageName);
strcat(cmdLine, " /u "); // u for upgrade
//
// Build the command line
//
strcat(cmdLine, pServiceInfo[Id].DBPath);
strcat(cmdLine, " /d");
strcat(cmdLine, SYSTEM_ROOT);
strcat(cmdLine, "edb500.dll");
//
// WINS does not have a default backup path
//
if (pServiceInfo[Id].ESEBackupPath[0] != '\0') {
strcat(cmdLine, " /b");
strcat(cmdLine, pServiceInfo[Id].ESEBackupPath);
}
//
// Preserve the old database now. WINS does not get preserved
// because of its cool replication feature.
//
#if 0
MYDEBUG(("40DbPath = %s\n", pServiceInfo[Id].DBPath));
MYDEBUG(("SystemFilePath = %s\n", pServiceInfo[Id].SystemFilePath));
MYDEBUG(("LogFilePAth = %s\n", pServiceInfo[Id].LogFilePath));
MYDEBUG(("Backup = %s\n", pServiceInfo[Id].BackupPath));
MYDEBUG(("ESEBackup = %s\n", pServiceInfo[Id].ESEBackupPath));
MYDEBUG(("ESEPreserve = %s\n", pServiceInfo[Id].ESEPreservePath));
#endif
//
// First get the base path, then get the DB name and append
// as follows -
// DBBasePAth = whatever
// DBPath = whatever\wins.mdb
// 40BasePath = whatever\40db
// 40DbPath = whatever\40db\wins.mdb
//
strcpy(PreserveBasePath, pServiceInfo[Id].DBPath);
// now get the base path out
index = strlen(PreserveBasePath);
while (index && (L'\\' != PreserveBasePath[index])) {
index--;
}
strcpy(DatabaseFileName, &PreserveBasePath[index+1]);
PreserveBasePath[index] = L'\0';
// Now get the backup base path.
strcpy(Preserve40BasePath, PreserveBasePath);
strcat(Preserve40BasePath, "\\40db\\");
// The BaseDbPath already exists
strcpy(PreserveDbPath, pServiceInfo[Id].DBPath);
// Generate the backup database path.
strcpy(Preserve40DbPath, Preserve40BasePath);
strcat(Preserve40DbPath, DatabaseFileName);
MYDEBUG(("40BasePath = %s\n", Preserve40BasePath));
MYDEBUG(("40DbPath = %s\n", Preserve40DbPath));
MYDEBUG(("BasePath = %s\n", PreserveBasePath));
MYDEBUG(("DbPath = %s\n", PreserveDbPath));
wait_for_file:
if ((HSearch = FindFirstFile( PreserveDbPath, &FileData ))
== INVALID_HANDLE_VALUE ) {
MYDEBUG(("File not found yet (%d)! Sleep and try another %d times\n", GetLastError(), (MAX_TRIES - tries)));
Sleep(1000);
tries++;
if (tries < MAX_TRIES) {
goto wait_for_file;
}
}
error = PreserveCurrentDb(PreserveBasePath,
PreserveDbPath,
Preserve40BasePath,
Preserve40DbPath);
if (error != ERROR_SUCCESS) {
MYDEBUG(("FAILED Preserve Database!\n"));
return error;
}
if ((size = ExpandEnvironmentStrings( cmdLine,
exCmdLine,
MAX_PATH+1000)) == 0) {
error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", cmdLine, error));
}
if (!GetSystemDirectory( curDir,
MAX_PATH)) {
error = GetLastError();
MYDEBUG(("GetSystemDirectory returned error: %lx\n", error));
return error;
}
MYDEBUG(("cmdLine: %s\n", exCmdLine));
memset(&startInfo, 0, sizeof(startInfo));
startInfo.cb = sizeof(startInfo);
//
// Create a process for the convert.exe program.
//
if(!CreateProcess( exImageName, // image name
exCmdLine, // command line
(LPSECURITY_ATTRIBUTES )NULL, // process security attr.
(LPSECURITY_ATTRIBUTES )NULL, // thread security attr.
FALSE, // inherit handle?
0, // creation flags
(LPVOID )NULL, // new environ. block
curDir, // current directory
&startInfo, // startupinfo
&procInfo )) { // process info.
error = GetLastError();
MYDEBUG(("CreateProcess returned error: %lx\n", error));
return error;
}
MYDEBUG(("CreateProcess succeeded\n"));
//
// Get the exit code of the process to determine if the convert went through.
//
do {
if (!GetExitCodeProcess(procInfo.hProcess,
&exitCode)) {
error = GetLastError();
MYDEBUG(("GetExitCode returned error: %lx\n", error));
return error;
}
} while ( exitCode == STILL_ACTIVE );
//
// If non-zero exit code, report the error
//
if (exitCode) {
MYDEBUG(("ExitCode: %lx\n", exitCode));
//
// Check if the file exists
//
strcpy(DbFile, SYSTEM_ROOT);
strcat(DbFile, "edb500.dll");
if ((size = ExpandEnvironmentStrings( DbFile,
DbFileName,
MAX_PATH)) == 0) {
error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", DbFileName, error));
} else {
if ((HSearch = FindFirstFile( DbFileName, &FileData ))
== INVALID_HANDLE_VALUE ) {
MYDEBUG(("Error: Edb500.dll wasnt found on the DISK! Need to copy from the NT5.0 CDROM.\n"));
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_HMODULE,
NULL,
JC_DB_FAIL_MSG,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
if (!MsgLen) {
Error = GetLastError();
MYDEBUG(("FormatMessage failed with error = (%d)\n", Error ));
} else {
MYDEBUG(("FormatMessage : %d size\n", MsgLen));
}
if(MessageBoxEx(NULL,
lpMsgBuf,
__TEXT("Jet Conversion Process"),
MB_SYSTEMMODAL | MB_OK | MB_SETFOREGROUND | MB_SERVICE_NOTIFICATION | MB_ICONSTOP,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL)) == 0) {
DWORD Error;
Error = GetLastError();
MYDEBUG(("MessageBoxEx failed with error = (%d)\n", Error ));
}
ASSERT(lpMsgBuf);
LocalFree( lpMsgBuf );
}
}
return exitCode;
}
return STATUS_SUCCESS ;
}
DWORD
JCConvert(
IN PSERVICE_INFO pServiceInfo
)
/*++
Routine Description:
This routine gets the sizes of the dbase files; if there is enough disk space, calls convert
for each service.
Arguments:
pServiceInfo - Pointer to the service information struct.
Return Value:
None.
--*/
{
SERVICES i ;
LARGE_INTEGER diskspace = {0, 0};
LARGE_INTEGER totalsize = {0, 0};
DWORD error;
HANDLE hFile;
DWORD SectorsPerCluster;
DWORD BytesPerSector;
DWORD NumberOfFreeClusters;
DWORD TotalNumberOfClusters;
TCHAR eventStr[MAX_PATH];
DWORD j = 0;
BOOLEAN fYetToStart = FALSE;
BOOLEAN fFirstTime = TRUE;
SC_HANDLE hScmCheck = NULL;
#if 0
SERVICES order[NUM_SERVICES];
SERVICES k = NUM_SERVICES - 1;
//
// Build the service invocation order
//
for (i = 0; i < NUM_SERVICES; i++) {
JCGetMutex(hMutex, INFINITE);
if (shrdMemPtr->InvokedByService[i]) {
order[j++] = i;
} else {
order[k--] = i;
}
JCFreeMutex(hMutex);
}
#if DBG
for (i = 0; i < NUM_SERVICES; i++) {
MYDEBUG(("order[%d]=%d\n", i, order[i]));
}
#endif
#endif
do {
fYetToStart = FALSE;
//
// Get the size of the dbase files
//
for (j = 0; j < NUM_SERVICES; j++) {
// i = order[j];
i = j;
if (!pServiceInfo[i].Installed ) {
MYDEBUG(("Service# %d not installed - skipping to next\n", i));
continue;
}
JCGetMutex(hMutex, INFINITE);
//
// If JetConv was invoked by this service and it has not been started yet
//
if (shrdMemPtr->InvokedByService[i] &&
!pServiceInfo[i].ServiceStarted) {
JCFreeMutex(hMutex);
MYDEBUG(("Check if the service has stopped\n"));
if ((hScmCheck = OpenSCManager( NULL, // address of machine name string
NULL, // address of database name string
SC_MANAGER_ALL_ACCESS)) == NULL) { // type of access
MYDEBUG(("OpenSCManager returned error: %lx\n", GetLastError()));
exit(1);
}
{
SC_HANDLE hService;
SERVICE_STATUS serviceStatus;
TCHAR eventStr[MAX_PATH];
int numtries = 0;
//
// Make sure that the service has stopped.
//
if ((hService = OpenService( hScmCheck,
pServiceInfo[i].ServiceName,
SERVICE_START | SERVICE_QUERY_STATUS)) == NULL) {
MYDEBUG(("OpenService: %s returned error: %lx\n", pServiceInfo[i].ServiceName, GetLastError()));
//
// just mark it as started, so we dont re-try this.
//
pServiceInfo[i].ServiceStarted = TRUE;
CloseServiceHandle(hScmCheck);
MYDEBUG(("Marking service: %d as started since the Service cant be opened.\n", i));
continue;
}
tryagain:
if (!QueryServiceStatus( hService,
&serviceStatus)) {
MYDEBUG(("QueryServiceStatus: %s returned error: %lx\n", pServiceInfo[i].ServiceName, GetLastError()));
//
// just mark it as started, so we dont re-try this.
//
pServiceInfo[i].ServiceStarted = TRUE;
MYDEBUG(("Marking service: %d as started since we cant query it.\n", i));
continue;
}
if ((SERVICE_RUNNING == serviceStatus.dwCurrentState) ||
(SERVICE_STOP_PENDING == serviceStatus.dwCurrentState)) {
//
// Service is about to stop/start - we wait for it to stop/start completely.
//
MYDEBUG(("Service (%s) state STOP pending - will loop until it goes down\n", pServiceInfo[i].ServiceName));
MYDEBUG(("Sleep(15000)\n"));
Sleep(15000);
if (++numtries < MAX_TRIES) {
goto tryagain;
} else {
MYDEBUG(("Service (%s) is NOT STOPPING!! We don't bother with it anymore.\n", pServiceInfo[i].ServiceName));
pServiceInfo[i].ServiceStarted = TRUE;
MYDEBUG(("Marking service: %d as started since we can't STOP it.\n", i));
continue;
}
} else if (SERVICE_STOPPED == serviceStatus.dwCurrentState) {
MYDEBUG(("YAY!! Finally stopped.\n"));
} else {
MYDEBUG(("Service (%s) in state (%d)- will loop until it goes down\n", pServiceInfo[i].ServiceName,
serviceStatus.dwCurrentState));
MYDEBUG(("Sleep(15000)\n"));
Sleep(15000);
if (++numtries < MAX_TRIES) {
goto tryagain;
} else {
MYDEBUG(("Service (%s) is NOT STOPPING!! We don't bother with it anymore.\n", pServiceInfo[i].ServiceName));
pServiceInfo[i].ServiceStarted = TRUE;
MYDEBUG(("Marking service: %d as started since we cant STOP it.\n", i));
continue;
}
MYDEBUG(("Problem! - %s is currently in %d\n", pServiceInfo[i].ServiceName, serviceStatus.dwCurrentState));
}
CloseServiceHandle(hService);
CloseServiceHandle(hScmCheck);
}
//
// Get a handle to the file
//
if ((hFile = CreateFile ( pServiceInfo[i].DBPath,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL)) == INVALID_HANDLE_VALUE) {
MYDEBUG(("Could not get handle to file: %s, %lx\n", pServiceInfo[i].DBPath, GetLastError()));
if (pServiceInfo[i].DefaultDbPath) {
//
// Log event that the default database file is not around
//
JCLogEvent(JC_COULD_NOT_ACCESS_DEFAULT_FILE, pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath, NULL);
} else {
//
// Log event that the database file in the registry is not around
//
JCLogEvent(JC_COULD_NOT_ACCESS_FILE, pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath, NULL);
}
//
// If this was not the default path, try the default path
//
if (!pServiceInfo[i].DefaultDbPath) {
TCHAR tempPath[MAX_PATH];
DWORD size;
switch (i) {
case DHCP:
strcpy(tempPath, DEFAULT_DHCP_DBFILE_PATH);
break;
case WINS:
strcpy(tempPath, DEFAULT_WINS_DBFILE_PATH);
break;
case RPL:
strcpy(tempPath, DEFAULT_RPL_DBFILE_PATH);
break;
}
if ((size = ExpandEnvironmentStrings( tempPath,
pServiceInfo[i].DBPath,
MAX_PATH)) == 0) {
error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", pServiceInfo[i].ServiceName, error));
}
pServiceInfo[i].DefaultDbPath = TRUE;
//
// so we recheck this service
//
j--;
} else {
//
// just mark it as started, so we dont re-try this.
//
pServiceInfo[i].ServiceStarted = TRUE;
MYDEBUG(("Marking service: %d as started since the dbase is not accessible.\n", i));
}
continue;
}
//
// Try to obtain hFile's huge size.
//
if ((pServiceInfo[i].DBSize.LowPart = GetFileSize ( hFile,
&pServiceInfo[i].DBSize.HighPart)) == 0xFFFFFFFF) {
if ((error = GetLastError()) != NO_ERROR) {
sprintf(eventStr, "Could not get size of file: %s, %lx\n", pServiceInfo[i].DBPath, GetLastError());
MYDEBUG((eventStr));
//
// Log event
//
JCLogEvent(JC_COULD_NOT_ACCESS_FILE, pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath, NULL);
continue;
}
}
totalsize.QuadPart = pServiceInfo[i].DBSize.QuadPart;
CloseHandle(hFile);
//
// Get the free disk space for comparison.
//
if (!GetDiskFreeSpace( SystemDrive,
&SectorsPerCluster, // address of sectors per cluster
&BytesPerSector, // address of bytes per sector
&NumberOfFreeClusters, // address of number of free clusters
&TotalNumberOfClusters)) {
sprintf(eventStr, "Could not get free space on: %s, %lx\n", SystemDrive, GetLastError());
MYDEBUG((eventStr));
//
// Log event
//
JCLogEvent(JC_COULD_NOT_GET_FREE_SPACE, SystemDrive, NULL, NULL);
}
diskspace.QuadPart = UInt32x32To64 (NumberOfFreeClusters, SectorsPerCluster * BytesPerSector);
MYDEBUG(("Disk size: low: %d high: %d\n", diskspace.LowPart, diskspace.HighPart));
//
// if there is enough disk space, call convert for this service.
//
if (totalsize.QuadPart + PAD < diskspace.QuadPart) {
SC_HANDLE hScm;
MYDEBUG(("Enough free space available\n"));
if ((hScm = OpenSCManager( NULL, // address of machine name string
NULL, // address of database name string
SC_MANAGER_ALL_ACCESS)) == NULL) { // type of access
MYDEBUG(("OpenSCManager returned error: %lx\n", GetLastError()));
exit(1);
}
{
SC_HANDLE hService;
SERVICE_STATUS serviceStatus;
TCHAR eventStr[MAX_PATH];
//
// Invoke the services that had their databases converted and that tried to call us.
//
//
// Make sure that the service is not already running
//
if ((hService = OpenService( hScm,
pServiceInfo[i].ServiceName,
SERVICE_START | SERVICE_QUERY_STATUS)) == NULL) {
MYDEBUG(("OpenService: %s returned error: %lx\n", pServiceInfo[i].ServiceName, GetLastError()));
continue;
}
if (!QueryServiceStatus( hService,
&serviceStatus)) {
MYDEBUG(("QueryServiceStatus: %s returned error: %lx\n", pServiceInfo[i].ServiceName, GetLastError()));
continue;
}
switch (serviceStatus.dwCurrentState) {
case SERVICE_STOP_PENDING:
case SERVICE_START_PENDING:
//
// Service is about to stop/start - we wait for it to stop/start completely.
//
MYDEBUG(("Service state pending - will come later: %s\n", pServiceInfo[i].ServiceName));
fYetToStart = TRUE;
//
// We re-try the service that called us once; else go to the next one.
//
if (fFirstTime) {
MYDEBUG(("Service state pending - re-trying: %s\n", pServiceInfo[i].ServiceName));
fFirstTime = FALSE;
MYDEBUG(("Sleep(15000)\n"));
Sleep(15000);
j--;
}
break;
case SERVICE_RUNNING:
//
// Service is already running - mark it as started
//
pServiceInfo[i].ServiceStarted = TRUE;
break;
case SERVICE_STOPPED:
default:
MYDEBUG(("%s size: low: %d high: %d\n", pServiceInfo[i].ServiceName, pServiceInfo[i].DBSize.LowPart, pServiceInfo[i].DBSize.HighPart));
error = ERROR_SUCCESS;
if (Jet200) {
if ((error = JCCallUpg(i, pServiceInfo)) != ERROR_SUCCESS) {
sprintf(eventStr, "%sCONV failed: %lx\n", pServiceInfo[i].ServiceName, error);
MYDEBUG((eventStr));
sprintf(eventStr, "%lx", error);
JCLogEvent(JC_CONVERT_FAILED, pServiceInfo[i].ServiceName, eventStr, NULL);
} else {
sprintf(eventStr, "%sCONV passed, converted database %s\n", pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath);
MYDEBUG((eventStr));
JCLogEvent(JC_CONVERTED_SUCCESSFULLY, pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath, pServiceInfo[i].BackupPath);
pServiceInfo[i].DBConverted = TRUE;
}
}
//
// Now, we convert to jet600, if the 200 -> 500 was a success - MS
// RPL does not want to convert to Jet600, so ESEPreservePath for RPL
// is overloaded with NULL to figure this out.
//
if (ERROR_SUCCESS == error && pServiceInfo[i].ESEPreservePath[0] != TEXT('\0')) {
if ((error = JCCallESE(i, pServiceInfo)) != ERROR_SUCCESS) {
sprintf(eventStr, "%sCONV failed: %lx\n", pServiceInfo[i].ServiceName, error);
MYDEBUG((eventStr));
sprintf(eventStr, "%lx", error);
JCLogEvent(JC_CONVERT2_FAILED, pServiceInfo[i].ServiceName, eventStr, NULL);
//break;
} else {
sprintf(eventStr, "%sCONV passed, converted database %s\n", pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath);
MYDEBUG((eventStr));
JCLogEvent(JC_CONVERTED_SUCCESSFULLY, pServiceInfo[i].ServiceName, pServiceInfo[i].DBPath, pServiceInfo[i].BackupPath);
pServiceInfo[i].DBConverted = TRUE;
if (ERROR_SUCCESS != DeleteLogFiles(pServiceInfo[i].LogFilePath)) {
MYDEBUG(("Could not delete log files!\n"));
}
}
//
// If service is not already running, start it.
//
if (ERROR_SUCCESS == error) {
if (!StartService( hService,
0,
NULL)) {
error = GetLastError();
MYDEBUG(("StartService: %s returned error: %lx\n", pServiceInfo[i].ServiceName, error));
sprintf(eventStr, "%lx", error);
JCLogEvent(JC_COULD_NOT_START_SERVICE, pServiceInfo[i].ServiceName, eventStr, NULL);
} else {
MYDEBUG(("StartService: %s done\n", pServiceInfo[i].ServiceName));
}
} else {
MYDEBUG(("NOT starting Service: %s because the conversion failed\n", pServiceInfo[i].ServiceName));
}
}
//
// Set this so we dont re-try this service.
//
pServiceInfo[i].ServiceStarted = TRUE;
break;
}
//
// Sleep for a while to let the services stabilize
//
if (fYetToStart) {
MYDEBUG(("Sleep(15000)\n"));
Sleep(15000);
}
}
CloseServiceHandle(hScm);
} else {
//
// Log an event to indicate that enough space was not available to
// do the conversion.
//
sprintf(eventStr, "Not enough free space on: %s to proceed with conversion of WINS/DHCP/RPL databases\n", SystemDrive);
MYDEBUG((eventStr));
//
// Bug 104808: break the infinite loop if not enough disk space.
//
error = ERROR_DISK_FULL;
fYetToStart = FALSE;
//
// Search for the installed service here
//
for ( i = 0; i < NUM_SERVICES; i++) {
if (pServiceInfo[i].Installed) {
JCLogEvent(JC_SPACE_NOT_AVAILABLE, SystemDrive, NULL, NULL);
}
}
}
} else {
JCFreeMutex(hMutex);
}
}
if (!fYetToStart) {
INT i;
//
// If there are no pending services, do one last check to see if someone else
// invoked us in the meantime.
//
JCGetMutex(hMutex, INFINITE);
for (i=0; i<NUM_SERVICES; i++) {
//
// If the flag is on, and this is not started yet, then it is a candidate
// for conversion.
//
if (shrdMemPtr->InvokedByService[i] &&
!pServiceInfo[i].ServiceStarted) {
MYDEBUG(("Service: %d invoked during conversion.\n", i));
fYetToStart = TRUE;
}
}
//
// If still no more invocations, we are done; destroy the shared mem
//
if (!fYetToStart) {
MYDEBUG(("No more Services invoked during conversion.\n"));
//
// Destroy the shared mem.
//
if (!UnmapViewOfFile(shrdMemPtr)) {
MYDEBUG(("UnmapViewOfFile returned error: %lx\n", GetLastError()));
exit(1);
}
CloseHandle(hFileMapping);
}
JCFreeMutex(hMutex);
}
} while (fYetToStart);
return error;
}
/*++
Routine Description:
DeleteLogFiles: Deletes the log files after a successful conversion in the
main directory. That way, the program that uses the database
knows that the conversion was successful.
Arguments:
Complete path to the directory where the log files exist.
Returns: NTSTATUS
--*/
NTSTATUS
DeleteLogFiles(TCHAR * LogFilePath )
{
TCHAR *FileNameInPath;
HANDLE HSearch = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA FileData;
TCHAR CurrentDir[ MAX_PATH ];
DWORD Error;
//
// now move the log files
//
if( GetCurrentDirectory( MAX_PATH, CurrentDir ) == 0 ) {
Error = GetLastError();
MYDEBUG(("DeleteCurrentDb: GetCurrentDirctory failed, Error = %ld.\n", Error ));
goto Cleanup;
}
//
// set current directory to logfile path.
//
if( SetCurrentDirectory( LogFilePath ) == FALSE ) {
Error = GetLastError();
MYDEBUG(("DeleteCurrentDb: SetCurrentDirctory failed, Error = %ld.\n", Error ));
goto Cleanup;
}
//
// Start file search on current dir.
//
HSearch = FindFirstFile( "j50*.log", &FileData );
if( HSearch == INVALID_HANDLE_VALUE ) {
Error = GetLastError();
MYDEBUG(("Error: No Log files were found in %s\n", LogFilePath ));
goto Cleanup;
}
//
// Delete log files
//
for( ;; ) {
if( DeleteFile( FileData.cFileName ) == FALSE ) {
Error = GetLastError();
MYDEBUG(("DeleteCurrentDb: could not delete log file, Error = %ld.\n", Error ));
goto Cleanup;
}
//
// Find next file.
//
if ( FindNextFile( HSearch, &FileData ) == FALSE ) {
Error = GetLastError();
if( ERROR_NO_MORE_FILES == Error ) {
break;
}
MYDEBUG(("Error: FindNextFile failed, Error = %ld.\n", Error ));
goto Cleanup;
}
}
Error = ERROR_SUCCESS;
Cleanup:
if( Error != ERROR_SUCCESS ){
MYDEBUG(("Error deleting log files %ld", Error));
}
if( HSearch != INVALID_HANDLE_VALUE ) {
FindClose( HSearch );
}
//
// reset current currectory.
//
SetCurrentDirectory( CurrentDir );
//
// always return success!
//
return ERROR_SUCCESS;
}
DWORD
PreserveCurrentDb( TCHAR * InBasePath,
TCHAR * InSourceDb,
TCHAR * InPreserveDbPath,
TCHAR * InPreserveDb)
/*++
Routine Description:
Preserve the current DB in a preserve path, so that we can always revert.
Arguments:
szBasePath
szSourceDb
szPreserveDbPath
Directories from/to preserve
Return Value:
None.
--*/
{
DWORD WinError;
DWORD FileAttributes;
TCHAR TempPath[MAX_PATH];
TCHAR Temp2Path[MAX_PATH];
TCHAR *FileNameInPath;
HANDLE HSearch = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA FileData;
TCHAR CurrentDir[ MAX_PATH ];
DWORD Error, size;
TCHAR szBasePath[MAX_PATH];
TCHAR szSourceDb[MAX_PATH];
TCHAR szPreserveDbPath[MAX_PATH];
TCHAR szPreserveDB[MAX_PATH];
if ((size = ExpandEnvironmentStrings( InBasePath,
szBasePath,
MAX_PATH)) == 0) {
Error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %ws returned error: %lx\n", InBasePath, Error));
goto Cleanup;
}
if ((size = ExpandEnvironmentStrings( InSourceDb,
szSourceDb,
MAX_PATH)) == 0) {
Error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", InSourceDb, Error));
goto Cleanup;
}
if ((size = ExpandEnvironmentStrings( InPreserveDbPath,
szPreserveDbPath,
MAX_PATH)) == 0) {
Error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", InPreserveDbPath, Error));
goto Cleanup;
}
if ((size = ExpandEnvironmentStrings( InPreserveDb,
szPreserveDB,
MAX_PATH)) == 0) {
Error = GetLastError();
MYDEBUG(("ExpandEnvironmentVaraibles %s returned error: %lx\n", InPreserveDb, Error));
goto Cleanup;
}
FileAttributes = GetFileAttributes( szPreserveDbPath );
if( FileAttributes == 0xFFFFFFFF ) {
WinError = GetLastError();
if( WinError == ERROR_FILE_NOT_FOUND ) {
//
// Create this directory.
//
if( !CreateDirectory( szPreserveDbPath, NULL) ) {
goto Cleanup;
}
}
else {
goto Cleanup;
}
}
//
// move the database file.
//
if ( !CopyFile( szSourceDb,
szPreserveDB,
FALSE ) ){
MYDEBUG(("PreserveCurrentDb: could not save database file: Error %ld\n",GetLastError()));
MYDEBUG(("Src %s, Dest %s\n",szSourceDb, szPreserveDB));
goto Cleanup;
}
//
// Start file search on current dir.
//
strcpy(Temp2Path, szBasePath);
strcat(Temp2Path,"\\");
strcat(Temp2Path,"j*.log");
HSearch = FindFirstFile( Temp2Path, &FileData );
if( HSearch == INVALID_HANDLE_VALUE ) {
Error = GetLastError();
MYDEBUG(("Error: No Log files were found in %s\n", Temp2Path ));
goto Cleanup;
}
//
// Move files.
//
for( ;; ) {
strcpy(TempPath, szPreserveDbPath);
strcat(TempPath,"\\");
strcat(TempPath, FileData.cFileName );
strcpy(Temp2Path,szBasePath);
strcat(Temp2Path,"\\");
strcat(Temp2Path,FileData.cFileName );
if( CopyFile( Temp2Path, TempPath, FALSE ) == FALSE ) {
Error = GetLastError();
MYDEBUG(("PreserveCurrentDb: could not save log file, Error = %ld.\n", Error ));
MYDEBUG(("File %s, Src %s, Dest %s\n",FileData.cFileName,Temp2Path,TempPath));
goto Cleanup;
}
//
// Find next file.
//
if ( FindNextFile( HSearch, &FileData ) == FALSE ) {
Error = GetLastError();
if( ERROR_NO_MORE_FILES == Error ) {
break;
}
// printf("Error: FindNextFile failed, Error = %ld.\n", Error );
goto Cleanup;
}
}
Error = ERROR_SUCCESS;
Cleanup:
if( Error != ERROR_SUCCESS ){
MYDEBUG(("CONVERT_ERR_PRESERVEDB_FAIL2_ID %x\n", GetLastError()));
}
if( HSearch != INVALID_HANDLE_VALUE ) {
FindClose( HSearch );
}
//
// always return same!
//
return Error;
}