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.
 
 
 
 
 
 

487 lines
13 KiB

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
rswriter.cpp
Abstract:
Implements CRssJetWriter methods
Author:
Ran Kalach [rankala] 4/4/2000
Revision History:
--*/
#include "stdafx.h"
#include "rsevents.h"
#include "rswriter.h"
// Include these 2 files just for VSS_E_WRITERERROR_TIMEOUT definition
#include "vss.h"
#include "vswriter.h"
#include "aclapi.h"
#ifndef INITGUID
#define INITGUID
#include <guiddef.h>
#undef INITGUID
#else
#include <guiddef.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
DEFINE_GUID(RSS_WRITER_GUID, 0xb959d2c3L, 0x18bb, 0x4607, 0xb0, 0xca,
0x68, 0x8c, 0xd0, 0xd4, 0x1a, 0x50); // {b959d2c3-18bb-4607-b0ca-688cd0d41a50}
#ifdef __cplusplus
}
#endif
#define FILES_TO_EXCLUDE OLESTR("%SystemRoot%\\System32\\RemoteStorage\\FsaDb\\*;%SystemRoot%\\System32\\RemoteStorage\\Trace\\*")
#define FILES_TO_INCLUDE OLESTR("")
CRssJetWriter::CRssJetWriter()
/*++
Routine Description:
Constructor
Arguments:
None
Return Value:
None
Notes:
We create the events in the constructor because these events might be required
before the Init code could be done (Init must be called after Jet is initialized
--*/
{
HRESULT hr = S_OK;
PSID pSystemSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
#define WRITER_EVENTS_NUM_ACE 1
EXPLICIT_ACCESS ea[WRITER_EVENTS_NUM_ACE];
SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
SECURITY_ATTRIBUTES sa;
WsbTraceIn(OLESTR("CRssJetWriter::CRssJetWriter"), OLESTR(""));
m_bTerminating = FALSE;
try {
for (int index=0; index<WRITER_EVENTS_NUM; index++) {
m_syncHandles[index] = NULL;
}
// Create the events
// Note: Currently Engine and IDB sync events are created here, FSA event already should already exist
// If initializtion order of RSS modles is changed - the CreateEent and OpenEvent calls for these
// named events may need to switch.
// Method of interest for this matter (of init order) are CHsmServer::Init and CFsaServer::Init
// Create an SD with ACL for local-system only
memset(ea, 0, sizeof(EXPLICIT_ACCESS) * WRITER_EVENTS_NUM_ACE);
WsbAssertStatus( AllocateAndInitializeSid( &SIDAuthNT, 1,
SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0,
&pSystemSID) );
ea[0].grfAccessPermissions = FILE_ALL_ACCESS;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance = SUB_CONTAINERS_AND_OBJECTS_INHERIT;
ea[0].Trustee.pMultipleTrustee = NULL;
ea[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
ea[0].Trustee.ptstrName = (LPTSTR) pSystemSID;
WsbAffirmNoError(SetEntriesInAcl(WRITER_EVENTS_NUM_ACE, ea, NULL, &pACL));
pSD = (PSECURITY_DESCRIPTOR) WsbAlloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
WsbAffirmPointer(pSD);
WsbAffirmStatus(InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION));
WsbAffirmStatus(SetSecurityDescriptorDacl(
pSD,
TRUE, // fDaclPresent flag
pACL,
FALSE)); // not a default DACL
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
// Create teh actual events
WsbAffirmHandle(m_syncHandles[INTERNAL_EVENT_INDEX] = CreateEvent(NULL, FALSE, TRUE, NULL));
WsbAffirmHandle(m_syncHandles[1] = OpenEvent(EVENT_ALL_ACCESS, FALSE, HSM_FSA_STATE_EVENT));
WsbAffirmHandle(m_syncHandles[2] = CreateEvent(&sa, FALSE, TRUE, HSM_ENGINE_STATE_EVENT));
WsbAffirmHandle(m_syncHandles[3] = CreateEvent(&sa, FALSE, TRUE, HSM_IDB_STATE_EVENT));
} WsbCatch(hr);
m_hrInit = hr;
if (pSystemSID) {
FreeSid(pSystemSID);
}
if (pACL) {
LocalFree(pACL);
}
if (pSD) {
WsbFree(pSD);
}
WsbTraceOut(OLESTR("CRssJetWriter::CRssJetWriter"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
}
CRssJetWriter::~CRssJetWriter( )
/*++
Routine Description:
Destructor - free resources
Arguments:
None
Return Value:
None
--*/
{
WsbTraceIn(OLESTR("CRssJetWriter::~CRssJetWriter"), OLESTR(""));
// Close event handles
for (int index=0; index<WRITER_EVENTS_NUM; index++) {
if (NULL != m_syncHandles[index]) {
CloseHandle(m_syncHandles[index]);
m_syncHandles[index] = NULL;
}
}
WsbTraceOut(OLESTR("CRssJetWriter::~CRssJetWriter"), OLESTR(""));
}
HRESULT CRssJetWriter::Init(void)
/*++
Routine Description:
Initialize Snapshot synchronization
Arguments:
None
Return Value:
S_OK - Success
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CRssJetWriter::Init"), OLESTR(""));
try {
// Don't do anything if the basic initialization done in the constructor failed
WsbAffirmHr(m_hrInit);
GUID rssGuid = RSS_WRITER_GUID;
WsbAffirmHr(Initialize(
rssGuid,
RSS_BACKUP_NAME,
TRUE,
FALSE,
FILES_TO_INCLUDE,
FILES_TO_EXCLUDE
));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CRssJetWriter::Init"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr;
}
HRESULT CRssJetWriter::Terminate(void)
/*++
Routine Description:
Terminate Snapshot synchronization
Arguments:
None
Return Value:
S_OK - Success
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CRssJetWriter::Terminate"), OLESTR(""));
try {
DWORD status, errWait;
WsbAffirmHr(m_hrInit);
// Avoid terminating in the middle of snapshot
status = WaitForSingleObject(m_syncHandles[INTERNAL_EVENT_INDEX], INTERNAL_WAIT_TIMEOUT);
errWait = GetLastError();
// Whatever the status is - uninitialize underlying writer mechanizm
m_bTerminating = TRUE;
Uninitialize();
// Check Wait status:
if (status == WAIT_OBJECT_0) {
// The expected case
if (! SetEvent(m_syncHandles[INTERNAL_EVENT_INDEX])) {
// Don't abort, just trace error
WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: SetEvent returned unexpected error %lu\n"), GetLastError());
}
WsbTrace(OLESTR("CRssJetWriter::Terminate: Terminating after a successful wait\n"));
} else {
// In case of failure we cannot trust Thaw/Abort to be called so we signal the evnets
InternalEnd();
switch (status) {
case WAIT_TIMEOUT:
WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object timed out after %lu ms\n"), INTERNAL_WAIT_TIMEOUT);
hr = E_FAIL;
break;
case WAIT_FAILED:
WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object returned error %lu\n"), errWait);
hr = HRESULT_FROM_WIN32(errWait);
break;
default:
WsbTraceAlways(OLESTR("CRssJetWriter::Terminate: Wait for Single Object returned unexpected status %lu\n"), status);
hr = E_UNEXPECTED;
break;
}
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CRssJetWriter::Terminate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr;
}
HRESULT CRssJetWriter::InternalEnd(void)
/*++
Routine Description:
Set all events
Arguments:
None
Return Value:
S_OK - Success
--*/
{
HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CRssJetWriter::InternalEnd"), OLESTR(""));
try {
WsbAffirmHr(m_hrInit);
// Set all events
DWORD errSet;
for (int index=0; index<WRITER_EVENTS_NUM; index++) {
if (NULL != m_syncHandles[index]) {
if (! SetEvent(m_syncHandles[index])) {
// Don't abort, just save error
errSet = GetLastError();
WsbTraceAlways(OLESTR("CRssJetWriter::InternalEnd: SetEvent returned error %lu for event number %d\n"), errSet, index);
hr = HRESULT_FROM_WIN32(errSet);
}
}
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CRssJetWriter::InternalEnd"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return hr;
}
//
// CVssJetWriter overloaded methods
//
bool STDMETHODCALLTYPE CRssJetWriter::OnFreezeBegin()
/*++
Routine Description:
Handles Freeze Start event
Arguments:
None
Return Value:
TRUE - Success, OK to freeze
FALSE - Failure, Don't freeze
--*/
{
HRESULT hr = S_OK;
bool bRet;
WsbTraceIn(OLESTR("CRssJetWriter::OnFreezeBegin"), OLESTR(""));
try {
WsbAffirmHr(m_hrInit);
// Just wait for all sync events
DWORD status = WaitForMultipleObjects(WRITER_EVENTS_NUM, m_syncHandles, TRUE, EVENT_WAIT_TIMEOUT);
// Comparing (status == WAIT_OBJECT_0) || (status > WAIT_OBJECT_0) intsead of (status >= WAIT_OBJECT_0)
// to avoid error C4296 - "expression is always true"
if ( ((status == WAIT_OBJECT_0) || (status > WAIT_OBJECT_0)) &&
(status <= WAIT_OBJECT_0 + WRITER_EVENTS_NUM - 1) ) {
// Freeze is ready to go...
WsbTrace(OLESTR("CRssJetWriter::OnFreezeBegin: All events are nonsignaled, freeze is reday to go\n"));
// If we are terminating, no Thaw/Abort will be called - therefore, set the events
if (m_bTerminating) {
InternalEnd();
}
} else {
// Something wrong...
DWORD errWait = GetLastError();
// Set all events in case of an error
InternalEnd();
switch(status) {
case WAIT_FAILED:
WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects returned error %lu\n"), errWait);
WsbThrow(HRESULT_FROM_WIN32(errWait));
break;
case WAIT_TIMEOUT:
// Timeout means that one of the sync components is taking too long
WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects timed out after %lu ms\n"), EVENT_WAIT_TIMEOUT);
WsbThrow(VSS_E_WRITERERROR_TIMEOUT);
break;
default:
WsbTraceAlways(OLESTR("CRssJetWriter::OnFreezeBegin: Wait for Multiple Objects returned unexpected status %lu\n"), status);
WsbThrow(E_UNEXPECTED);
break;
}
}
} WsbCatch(hr);
if (S_OK == hr) {
bRet = CVssJetWriter::OnFreezeBegin();
} else {
bRet = false;
}
WsbTraceOut(OLESTR("CRssJetWriter::OnFreezeBegin"), OLESTR("hr = <%ls> , bRet = <%ls>"), WsbHrAsString(hr), WsbBoolAsString(bRet));
return bRet;
}
bool STDMETHODCALLTYPE CRssJetWriter::OnThawEnd(IN bool fJetThawSucceeded)
/*++
Routine Description:
Handles Thaw End event
Arguments:
fJetThawSucceeded - Ignored
Return Value:
TRUE - Success
FALSE - Failure
--*/
{
bool bRet;
WsbTraceIn(OLESTR("CRssJetWriter::OnThawEnd"), OLESTR(""));
// Return value is determined by base class, ignore internal errors here
bRet = CVssJetWriter::OnThawEnd(fJetThawSucceeded);
// Release all waiting events
InternalEnd();
WsbTraceOut(OLESTR("CRssJetWriter::OnThawEnd"), OLESTR("bRet = <%ls>"), WsbBoolAsString(bRet));
return bRet;
}
void STDMETHODCALLTYPE CRssJetWriter::OnAbortEnd()
/*++
Routine Description:
Handles Abort End event
Arguments:
None
Return Value:
None
--*/
{
WsbTraceIn(OLESTR("CRssJetWriter::OnAbortEnd"), OLESTR(""));
// Call base class imp.
CVssJetWriter::OnAbortEnd();
// Release all waiting events
InternalEnd();
WsbTraceOut(OLESTR("CRssJetWriter::OnAbortEnd"), OLESTR(""));
}