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.
344 lines
11 KiB
344 lines
11 KiB
/*++
|
|
|
|
Copyright (C) 1998-2001 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
PERSISTCFG.cpp
|
|
|
|
Abstract:
|
|
|
|
This file implements the WinMgmt persistent configuration operations.
|
|
|
|
Classes implemented:
|
|
CPersistentConfig persistent configuration manager
|
|
|
|
History:
|
|
|
|
1/13/98 paulall Created.
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include <sync.h>
|
|
#include <memory.h>
|
|
#include <stdio.h>
|
|
#include "PersistCfg.h"
|
|
#include "reg.h"
|
|
|
|
#define WinMgmt_CFG_ACTUAL __TEXT("$WinMgmt.CFG")
|
|
#define WinMgmt_CFG_PENDING __TEXT("$WinMgmt.$FG")
|
|
#define WinMgmt_CFG_BACKUP __TEXT("$WinMgmt.CFG.BAK")
|
|
|
|
CDirectoryPath CPersistentConfig::m_Directory;
|
|
|
|
|
|
/*=============================================================================
|
|
* CDirectoryPath::CDirectoryPath
|
|
*
|
|
* Initialised the directory path
|
|
*
|
|
*=============================================================================
|
|
*/
|
|
CDirectoryPath::CDirectoryPath()
|
|
{
|
|
|
|
Registry r(WBEM_REG_WINMGMT);
|
|
OnDeleteIf0<void(*)(void),&CStaticCritSec::SetFailure> Fail;
|
|
|
|
pszDirectory = NULL;
|
|
|
|
if (r.GetStr(__TEXT("Repository Directory"), &pszDirectory))
|
|
{
|
|
size_t sizeString = MAX_PATH + LENGTH_OF(__TEXT("\\wbem\\repository"));
|
|
wmilib::auto_buffer<TCHAR> pWindir(new TCHAR[sizeString]);
|
|
if (NULL == pWindir.get()) return;
|
|
|
|
UINT ReqSize = GetSystemDirectory(pWindir.get(),MAX_PATH+1);
|
|
if (ReqSize > MAX_PATH)
|
|
{
|
|
sizeString = ReqSize + LENGTH_OF(__TEXT("\\wbem\\repository"));
|
|
pWindir.reset(new TCHAR[sizeString]);
|
|
if (NULL == pWindir.get()) return;
|
|
|
|
if (0 == GetSystemDirectory(pWindir.get(),ReqSize+1)) return;
|
|
}
|
|
|
|
StringCchCat(pWindir.get(),sizeString,__TEXT("\\wbem\\repository"));
|
|
|
|
r.SetExpandStr(__TEXT("Repository Directory"),__TEXT("%systemroot%\\system32\\wbem\\repository"));
|
|
|
|
TCHAR * pDiscard = NULL;
|
|
if (r.GetStr(__TEXT("Working Directory"), &pDiscard))
|
|
{
|
|
r.SetExpandStr(__TEXT("Working Directory"),__TEXT("%systemroot%\\system32\\wbem"));
|
|
}
|
|
delete [] pDiscard;
|
|
|
|
pszDirectory = pWindir.release();
|
|
Fail.dismiss();
|
|
return;
|
|
}
|
|
Fail.dismiss();
|
|
}
|
|
|
|
/*=============================================================================
|
|
* GetPersistentCfgValue
|
|
*
|
|
* Retrieves the configuration from the configuration file if it
|
|
* has not yet been retrieved into memory, or retrieves it from a
|
|
* memory cache.
|
|
*
|
|
* Parameters:
|
|
* dwOffset needs to be less than MaxNumberConfigEntries and specifies
|
|
* the configuration entry required.
|
|
* dwValue if sucessful this will contain the value. If the value
|
|
* has not been set this will return 0.
|
|
*
|
|
* Return value:
|
|
* BOOL returns TRUE if successful.
|
|
*=============================================================================
|
|
*/
|
|
|
|
BOOL CPersistentConfig::GetPersistentCfgValue(DWORD dwOffset, DWORD &dwValue)
|
|
{
|
|
dwValue = 0;
|
|
if (dwOffset >= MaxNumberConfigEntries)
|
|
return FALSE;
|
|
|
|
//Try and read the file if it exists, otherwise it does not matter, we just
|
|
|
|
wmilib::auto_buffer<TCHAR> pszFilename( GetFullFilename(WinMgmt_CFG_ACTUAL));
|
|
if (NULL == pszFilename.get()) return FALSE;
|
|
|
|
HANDLE hFile = CreateFile(pszFilename.get(), //Name of file
|
|
GENERIC_READ, //Read only at
|
|
0, //Don't need to allow anyone else in
|
|
0, //Shouldn't need security
|
|
OPEN_EXISTING, //Only open the file if it exists
|
|
0, //No attributes needed
|
|
0); //No template file required
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
DWORD dwNumBytesRead;
|
|
if ((GetFileSize(hFile, NULL) >= sizeof(DWORD)*(dwOffset+1)) &&
|
|
(SetFilePointer (hFile, sizeof(DWORD)*dwOffset, 0, FILE_BEGIN) != INVALID_SET_FILE_POINTER) &&
|
|
ReadFile(hFile, &dwValue, sizeof(DWORD), &dwNumBytesRead, NULL))
|
|
{
|
|
}
|
|
|
|
CloseHandle(hFile);
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
/*=============================================================================
|
|
* WriteConfig
|
|
*
|
|
* Writes the $WinMgmt.CFG file into the memory cache and to the file. It
|
|
* protects the existing file until the last minute.
|
|
*
|
|
* return value:
|
|
* BOOL returns TRUE if successful.
|
|
*=============================================================================
|
|
*/
|
|
BOOL CPersistentConfig::SetPersistentCfgValue(DWORD dwOffset, DWORD dwValue)
|
|
{
|
|
if (dwOffset >= MaxNumberConfigEntries)
|
|
return FALSE;
|
|
|
|
BOOL bRet = FALSE;
|
|
|
|
wmilib::auto_buffer<TCHAR> pszActual(GetFullFilename(WinMgmt_CFG_ACTUAL));
|
|
|
|
if (NULL == pszActual.get()) return FALSE;
|
|
|
|
//Create a new file to write to...
|
|
HANDLE hFile = CreateFile(pszActual.get(), //Name of file
|
|
GENERIC_WRITE | GENERIC_READ ,
|
|
0, //Don't need to allow anyone else in
|
|
0, //Shouldn't need security
|
|
OPEN_ALWAYS, //create if does not exist
|
|
0, //No attributes needed
|
|
0); //No template file required
|
|
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
|
|
DWORD dwNumBytesWritten;
|
|
DWORD dwNumBytesReaded;
|
|
|
|
DWORD lowSize = GetFileSize(hFile, NULL);
|
|
|
|
if (GetFileSize(hFile, NULL) != MaxNumberConfigEntries*sizeof(DWORD))
|
|
{
|
|
DWORD buff[MaxNumberConfigEntries]={0};
|
|
ReadFile(hFile, buff, sizeof(buff), &dwNumBytesWritten, NULL);
|
|
buff[dwOffset] = dwValue;
|
|
|
|
if (SetFilePointer(hFile,0,0, FILE_BEGIN)!=INVALID_SET_FILE_POINTER)
|
|
{
|
|
bRet = WriteFile(hFile, buff, sizeof(buff), &dwNumBytesWritten, NULL);
|
|
if (bRet)
|
|
{
|
|
SetEndOfFile(hFile);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bRet = (SetFilePointer (hFile, sizeof(DWORD)*dwOffset, 0, FILE_BEGIN) != INVALID_SET_FILE_POINTER) ;
|
|
if (!bRet || !WriteFile(hFile, &dwValue, sizeof(DWORD), &dwNumBytesWritten, NULL) ||
|
|
(dwNumBytesWritten != (sizeof(DWORD))))
|
|
{
|
|
//OK, this failed!!!
|
|
CloseHandle(hFile);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
//Make sure it really is flushed to the disk
|
|
FlushFileBuffers(hFile);
|
|
CloseHandle(hFile);
|
|
|
|
return bRet;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
TCHAR *CPersistentConfig::GetFullFilename(const TCHAR *pszFilename)
|
|
{
|
|
size_t bufferLength = lstrlen(m_Directory.GetStr()) + lstrlen(pszFilename) + 2;
|
|
|
|
TCHAR *pszPathFilename = new TCHAR[bufferLength];
|
|
|
|
if (pszPathFilename)
|
|
{
|
|
StringCchCopy(pszPathFilename, bufferLength, m_Directory.GetStr());
|
|
if ((lstrlen(pszPathFilename)) && (pszPathFilename[lstrlen(pszPathFilename)-1] != __TEXT('\\')))
|
|
{
|
|
StringCchCat(pszPathFilename, bufferLength, __TEXT("\\"));
|
|
}
|
|
StringCchCat(pszPathFilename, bufferLength, pszFilename);
|
|
}
|
|
|
|
return pszPathFilename;
|
|
}
|
|
|
|
void CPersistentConfig::TidyUp()
|
|
{
|
|
//Recover the configuration file.
|
|
//-------------------------------
|
|
wmilib::auto_buffer<TCHAR> pszOriginalFile(GetFullFilename(WinMgmt_CFG_ACTUAL));
|
|
wmilib::auto_buffer<TCHAR> pszPendingFile(GetFullFilename(WinMgmt_CFG_PENDING));
|
|
wmilib::auto_buffer<TCHAR> pszBackupFile(GetFullFilename(WinMgmt_CFG_BACKUP));
|
|
|
|
if (NULL == pszOriginalFile.get() ||
|
|
NULL == pszPendingFile.get() ||
|
|
NULL == pszBackupFile.get()) return;
|
|
|
|
if (FileExists(pszOriginalFile.get()))
|
|
{
|
|
if (FileExists(pszPendingFile.get()))
|
|
{
|
|
if (FileExists(pszBackupFile.get()))
|
|
{
|
|
//BAD - Unexpected situation.
|
|
DeleteFile(pszPendingFile.get());
|
|
DeleteFile(pszBackupFile.get());
|
|
//Back to the point where the interrupted operation did not
|
|
//happen
|
|
}
|
|
else
|
|
{
|
|
//Pending file with original file means we cannot guarentee
|
|
//the integrety of the pending file so the last operation
|
|
//will be lost.
|
|
DeleteFile(pszPendingFile.get());
|
|
//Back to the point where the interrupted operation did not
|
|
//happen
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (FileExists(pszBackupFile.get()))
|
|
{
|
|
//Means we successfully copied the pending file to the original
|
|
DeleteFile(pszBackupFile.get());
|
|
//Everything is now normal. Interrupted Operation completed!
|
|
}
|
|
else
|
|
{
|
|
//Nothing out of the ordinary here.
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (FileExists(pszPendingFile.get()))
|
|
{
|
|
if (FileExists(pszBackupFile.get()))
|
|
{
|
|
//This is an expected behaviour at the point we have renamed
|
|
//the original file to the backup file.
|
|
MoveFile(pszPendingFile.get(), pszOriginalFile.get());
|
|
DeleteFile(pszBackupFile.get());
|
|
//Everything is now normal. Interrupted operation completed!
|
|
}
|
|
else
|
|
{
|
|
//BAD - Unexpected situation.
|
|
DeleteFile(pszPendingFile.get());
|
|
//There are now no files! Operation did not take place
|
|
//and there are now no files left. This should be a
|
|
//recoverable scenario!
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (FileExists(pszBackupFile.get()))
|
|
{
|
|
//BAD - Unexpected situation.
|
|
DeleteFile(pszBackupFile.get());
|
|
//There are now no files! Operation did not take place
|
|
//and there are now no files left. This should be a
|
|
//recoverable scenario!
|
|
}
|
|
else
|
|
{
|
|
//May be BAD! There are no files! This should be a
|
|
//recoverable scenario!
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//*****************************************************************************
|
|
//
|
|
// FileExists()
|
|
//
|
|
// Returns TRUE if the file exists, FALSE otherwise (or if an error
|
|
// occurs while opening the file.
|
|
//*****************************************************************************
|
|
BOOL CPersistentConfig::FileExists(const TCHAR *pszFilename)
|
|
{
|
|
BOOL bExists = FALSE;
|
|
HANDLE hFile = CreateFile(pszFilename, 0, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
|
|
if (hFile != INVALID_HANDLE_VALUE)
|
|
{
|
|
bExists = TRUE;
|
|
CloseHandle(hFile);
|
|
}
|
|
else
|
|
{
|
|
//If the file does not exist we should have a LastError of ERROR_NOT_FOUND
|
|
DWORD dwError = GetLastError();
|
|
if (dwError != ERROR_FILE_NOT_FOUND)
|
|
{
|
|
// DEBUGTRACE((LOG_WBEMCORE,"File %s could not be opened for a reason other than not existing\n", pszFilename));
|
|
}
|
|
}
|
|
return bExists;
|
|
}
|