|
|
/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name: frs.h
Abstract: This header handles information global to the ntrepl\frs modules
Author: Billy Fuller (billyf) - 20-Mar-1997 --*/
#ifndef _FRSH_
#define _FRSH_
#include <schedule.h>
#include <debug.h>
#include <frsrpc.h>
#include <frsapi.h>
#include <frsalloc.h>
#include <winldap.h>
#include <dsgetdc.h>
#include <mmsystem.h>
#include <global.h>
#include <winsvc.h>
#include <ntfrsres.h>
#include <eventlog.h>
#include <resource.h>
#ifndef FRSCONN_PRIORITY_MASK
//
// The following is here to support this function in WIN2K since it is not
// defined in ntdsapi.h for win2K
//
//
// The high 4 bits of the options attribute are used by NTFRS to assign priority
// for inbound connections. Bit 31 is used to force FRS to ignore schedule during
// the initial sync. Bits 30 - 28 are used to specify a priority between 0-7.
//
#define FRSCONN_PRIORITY_MASK 0x70000000
#define FRSCONN_MAX_PRIORITY 0x8
#define NTDSCONN_OPT_IGNORE_SCHEDULE_MASK 0x80000000
#define NTDSCONN_IGNORE_SCHEDULE(_options_)\
(((_options_) & NTDSCONN_OPT_IGNORE_SCHEDULE_MASK) >> 31)
#define FRSCONN_GET_PRIORITY(_options_) \
(((((_options_) & FRSCONN_PRIORITY_MASK) >> 28) != 0 ) ? \ (((_options_) & FRSCONN_PRIORITY_MASK) >> 28) : \ FRSCONN_MAX_PRIORITY \ ) #endif
//
// Types for the common comm subsystem
//
typedef enum _COMMAND_SERVER_ID { CS_NONE = 0, CS_RS,
CS_MAX } COMMAND_SERVER_ID, *PCOMMAND_SERVER_ID;
//
// GLOBALS
//
#define NTFRS_MAJOR (0)
#define NTFRS_MINOR (0)
extern ULONG NtFrsMajor; extern ULONG NtFrsMinor; extern PCHAR NtFrsModule; extern PCHAR NtFrsDate; extern PCHAR NtFrsTime;
//
// Staging File Version Levels
//
#define NTFRS_STAGE_MAJOR (0)
#define NTFRS_STAGE_MINOR_0 (0)
#define NTFRS_STAGE_MINOR_1 (1) // ChangeOrder Record extension added to stage file.
#define NTFRS_STAGE_MINOR_2 (2) // Compression Guid added to stage file.
#define NTFRS_STAGE_MINOR_3 (3) // Reparse Point data added to stage file.
extern ULONG NtFrsStageMajor; extern ULONG NtFrsStageMinor;
//
// Communication packet version levels.
//
#define NTFRS_COMM_MINOR_0 (0)
#define NTFRS_COMM_MINOR_1 (1) // MD5
#define NTFRS_COMM_MINOR_2 (2) // Trigger schedule
#define NTFRS_COMM_MINOR_3 (3) // ChangeOrder Record Extension.
//
// The following minor rev forces the Replica Number fields in the change order
// to be a ULONG (v.s. ULONG_PTR) for 32 - 64 bit interop. Add hack to always
// ship the 4 ptrs in the CO as 32 bits of zeros for 32 bit compat (see schema.h).
//
// Also the change order extension supports a var len comm element v.s. fixed
// size as in rev_3. When sending the CO Externsion to rev 3 servers you can
// only send the COMM_CO_EXT_WIN2K element with the MD5 checksum. For Rev 4
// servers and above you can send COMM_CO_EXTENSION_2 data elements.
//
// Added COMM_COMPRESSION_GUID as part of Join request.
//
#define NTFRS_COMM_MINOR_4 (4) // ChangeOrder Record Extension. COMM_CO_EXTENSION_2
//
// will send out COMM_CO_EXTENSION_2 to level 4 and 5 partners.
//
#define NTFRS_COMM_MINOR_5 (5)
//
// Bump minor for SP3 QFE so CONNSTAT can tell.
//
#define NTFRS_COMM_MINOR_6 (6)
//
// Bump minor for SP3 QFE+1 so CONNSTAT can tell. (.xls file fix)
//
#define NTFRS_COMM_MINOR_7 (7)
//
// Bump minor for .NET server
//
#define NTFRS_COMM_MINOR_8 (8)
//
// Bump minor for WIN2K SP4
//
#define NTFRS_COMM_MINOR_9 (9)
extern ULONG NtFrsCommMinor;
//
// Version number for the perfmon counters.
// Change this version any time the counters change or
// any help text associated with the counters changes.
// Change in version will trigger the counters to be
// loaded again.
//
#define NTFRS_PERF_COUNTER_VER_1 (1)
extern ULONG NtFrsPerfCounterVer;
//
// SCHEDULE
// Defines for both an byte-per-hour and a nibble-per-hour
//
#ifdef SCHEDULE_NIBBLE_PER_HOUR
//
// Each hour in a schedule is 4 bits (rounded up).
//
#define SCHEDULE_DATA_BYTES ((SCHEDULE_DATA_ENTRIES + 1) / 2)
//
// Each hour in a schedule is 8 bits (byte).
//
#else SCHEDULE_NIBBLE_PER_HOUR
#define SCHEDULE_DATA_BYTES SCHEDULE_DATA_ENTRIES
#endif SCHEDULE_NIBBLE_PER_HOUR
//
// Defines for checking Service state transitions.
// Used in FrsSetServiceStatus()
//
#define FRS_SVC_TRANSITION_TABLE_SIZE 5
#define FRS_SVC_TRANSITION_LEGAL 0
#define FRS_SVC_TRANSITION_NOOP 1
#define FRS_SVC_TRANSITION_ILLEGAL 2
//
// FRS MEMORY MANAGEMENT
//
VOID FrsInitializeMemAlloc( VOID ); VOID FrsUnInitializeMemAlloc( VOID );
//
// DS
//
//
// Some useful DS search constants
//
#define CONFIG_NAMING_CONTEXT L"cn=configuration"
#define CLASS_ANY L"(objectClass=*)"
#define CLASS_CXTION L"(objectClass=nTDSConnection)"
#define CLASS_MEMBER L"(objectClass=nTFRSMember)"
#define CLASS_REPLICA_SET L"(objectClass=nTFRSReplicaSet)"
#define CLASS_NTFRS_SETTINGS L"(objectClass=nTFRSSettings)"
#define CLASS_NTDS_SETTINGS L"(objectClass=nTDSSettings)"
#define CLASS_SUBSCRIBER L"(objectClass=nTFRSSubscriber)"
#define CLASS_SUBSCRIPTIONS L"(objectClass=nTFRSSubscriptions)"
#define CLASS_NTDS_DSA L"(objectClass=nTDSDSA)"
#define CLASS_COMPUTER L"(objectClass=computer)"
#define CLASS_USER L"(objectClass=user)"
#define CLASS_SERVER L"(objectClass=server)"
#define CATEGORY_ANY L"(objectCategory=*)"
#define CATEGORY_CXTION L"(objectCategory=nTDSConnection)"
#define CATEGORY_MEMBER L"(objectCategory=nTFRSMember)"
#define CATEGORY_REPLICA_SET L"(objectCategory=nTFRSReplicaSet)"
#define CATEGORY_NTFRS_SETTINGS L"(objectCategory=nTFRSSettings)"
#define CATEGORY_NTDS_SETTINGS L"(objectCategory=nTDSSettings)"
#define CATEGORY_SUBSCRIBER L"(objectCategory=nTFRSSubscriber)"
#define CATEGORY_SUBSCRIPTIONS L"(objectCategory=nTFRSSubscriptions)"
#define CATEGORY_NTDS_DSA L"(objectCategory=nTDSDSA)"
#define CATEGORY_COMPUTER L"(objectCategory=computer)"
#define CATEGORY_USER L"(objectCategory=user)"
#define CATEGORY_SERVER L"(objectCategory=server)"
//
// Codes for the various Config Node to Object Type mappings
// Note: Update string array DsConfigTypeName[] when this changes.
//
#define CONFIG_TYPE_UNDEFINED (0)
#define CONFIG_TYPE_IN_CXTION (1)
#define CONFIG_TYPE_MEMBER (2)
#define CONFIG_TYPE_REPLICA_SET (3)
#define CONFIG_TYPE_NTFRS_SETTINGS (4)
#define CONFIG_TYPE_NTDS_SETTINGS (5)
#define CONFIG_TYPE_SUBSCRIBER (6)
#define CONFIG_TYPE_SUBSCRIPTIONS (7)
#define CONFIG_TYPE_NTDS_DSA (8)
#define CONFIG_TYPE_COMPUTER (9)
#define CONFIG_TYPE_USER (10)
#define CONFIG_TYPE_SERVER (11)
#define CONFIG_TYPE_SERVICES_ROOT (12)
#define CONFIG_TYPE_OUT_CXTION (13)
#define ATTR_DIRECTORY_FILTER L"frsDirectoryFilter"
#define ATTR_FILE_FILTER L"frsFileFilter"
#define ATTR_NEW_SET_GUID L"frsReplicaSetGUID"
#define ATTR_OLD_SET_GUID L"replicaSetGUID"
#define ATTR_CLASS L"objectClass"
#define ATTR_DN L"distinguishedName"
#define ATTR_OBJECT_GUID L"objectGUID"
#define ATTR_SCHEDULE L"schedule"
#define ATTR_NEW_VERSION_GUID L"frsVersionGuid"
#define ATTR_OLD_VERSION_GUID L"replicaVersionGuid"
#define ATTR_REPLICA_SET L"nTFRSReplicaSet"
#define ATTR_NTFRS_SETTINGS L"nTFRSSettings"
#define ATTR_SERVER L"server"
#define ATTR_MEMBER L"nTFRSMember"
#define ATTR_REPLICA_ROOT L"frsRootPath"
#define ATTR_REPLICA_STAGE L"frsStagingPath"
#define ATTR_FROM_SERVER L"fromServer"
#define ATTR_PRIMARY_MEMBER L"frsPrimaryMember"
#define ATTR_SCHEDULE L"schedule"
#define ATTR_USN_CHANGED L"uSNChanged"
#define ATTR_FRS_FLAGS L"fRSFlags"
#define ATTR_NAMING_CONTEXTS L"namingContexts"
#define ATTR_DEFAULT_NAMING_CONTEXT L"defaultNamingContext"
#define ATTR_COMPUTER_REF L"frsComputerReference"
#define ATTR_COMPUTER_REF_BL L"frsComputerReferenceBL"
#define ATTR_SERVER_REF L"ServerReference"
#define ATTR_SERVER_REF_BL L"ServerReferenceBL"
#define ATTR_MEMBER_REF L"frsMemberReference"
#define ATTR_MEMBER_REF_BL L"frsMemberReferenceBL"
#define ATTR_WORKING L"frsWorkingPath"
#define ATTR_SET_TYPE L"frsReplicaSetType"
#define ATTR_SUBSCRIPTIONS L"nTFRSSubscriptions"
#define ATTR_SUBSCRIBER L"nTFRSSubscriber"
#define ATTR_CN L"cn"
#define ATTR_EXTENSIONS L"frsExtensions"
#define ATTR_SAM L"sAMAccountName"
#define ATTR_CXTION L"nTDSConnection"
#define ATTR_ENABLED_CXTION L"enabledConnection"
#define ATTR_OPTIONS L"options"
#define ATTR_TRANSPORT_TYPE L"transportType"
#define ATTR_USER_ACCOUNT_CONTROL L"userAccountControl"
#define ATTR_DNS_HOST_NAME L"dNSHostName"
#define ATTR_SERVICE_PRINCIPAL_NAME L"servicePrincipalName"
#define ATTR_TRUE L"TRUE"
#define ATTR_FALSE L"FALSE"
#define ATTR_WHEN_CHANGED L"whenChanged"
#define ATTR_WHEN_CREATED L"whenCreated"
#define CN_ROOT L""
#define CN_SYSVOLS L"Microsoft System Volumes"
#define CN_ENTERPRISE_SYSVOL NTFRSAPI_REPLICA_SET_TYPE_ENTERPRISE
#define CN_SERVERS L"Servers"
#define CN_NTDS_SETTINGS L"ntds settings"
#define CN_SUBSCRIPTIONS L"NTFRS Subscriptions"
#define CN_COMPUTERS L"Computers"
#define CN_DOMAIN_CONTROLLERS L"Domain Controllers"
#define CN_SERVICES L"Services"
#define CN_SITES L"Sites"
#define CN_SYSTEM L"System"
#define CN_NTFRS_SETTINGS L"File Replication Service"
#define CN_DOMAIN_SYSVOL L"Domain System Volume (SYSVOL share)"
//
// Some useful ldap macroes
//
#define LDAP_FREE_MSG(x) {if (x) {ldap_msgfree(x); (x) = NULL;}}
#define LDAP_FREE_VALUES(x) {if (x) {ldap_value_free(x); (x) = NULL;}}
#define LDAP_FREE_BER_VALUES(x) {if (x) {ldap_value_free_len(x); (x) = NULL;}}
//
// DS Poller
//
VOID FrsDsInitialize( VOID );
DWORD FrsDsSetDsPollingInterval( IN ULONG UseShortInterval, IN DWORD LongInterval, IN DWORD ShortInterval );
DWORD FrsDsGetDsPollingInterval( OUT ULONG *Interval, OUT ULONG *LongInterval, OUT ULONG *ShortInterval );
DWORD FrsDsStartDemotion( IN PWCHAR ReplicaSetName );
DWORD FrsDsCommitDemotion( VOID );
//
// Default File and Directory filter lists.
//
// The compiled in default is only used if no value is supplied in
// EITHER the DS or the Registry.
// The table below shows how the final filter is formed.
//
// value Value
// supplied supplied Resulting filter string Used
// in DS in Registry
// No No DEFAULT_xxx_FILTER_LIST
// No Yes Value from registry
// Yes No Value from DS
// Yes Yes Value from DS + Value from registry
//
//
#define FRS_DS_COMPOSE_FILTER_LIST(_DsFilterList, _RegFilterList, _DefaultFilterList) \
\ (((_DsFilterList) != NULL) ? \ ( ((_RegFilterList) != NULL) ? \ FrsWcsCat3((_DsFilterList), L",", (_RegFilterList)) : \ FrsWcsDup((_DsFilterList)) \ ) : \ ( ((_RegFilterList) != NULL) ? \ FrsWcsDup((_RegFilterList)) : \ FrsWcsDup((_DefaultFilterList)) \ ) \ )
//
// Add a new message to the ds polling summary.
//
#define FRS_DS_ADD_TO_POLL_SUMMARY(_DsPollSummaryBuf, _NewMessage, _NewMessageLen) \
\ if ((DsPollSummaryBufLen + _NewMessageLen) > DsPollSummaryMaxBufLen ) { \ PWCHAR _TempDsPollSummaryBuf = NULL; \ _TempDsPollSummaryBuf = FrsAlloc(DsPollSummaryMaxBufLen + 2 * 1000); \ DsPollSummaryMaxBufLen += (2 * 1000); \ CopyMemory(_TempDsPollSummaryBuf, DsPollSummaryBuf, DsPollSummaryBufLen); \ FrsFree(DsPollSummaryBuf); \ DsPollSummaryBuf = _TempDsPollSummaryBuf; \ } \ \ CopyMemory(&DsPollSummaryBuf[DsPollSummaryBufLen/2], _NewMessage, _NewMessageLen);\ DsPollSummaryBufLen += _NewMessageLen;
//
// FRS Dummy event logging routines
//
extern VOID LogFrsException(FRS_ERROR_CODE, ULONG_PTR, PWCHAR); extern VOID LogException(DWORD, PWCHAR);
//
// FRS Exception Handling
//
extern VOID FrsRaiseException(FRS_ERROR_CODE, ULONG_PTR); extern DWORD FrsException(EXCEPTION_POINTERS *); extern DWORD FrsExceptionLastCode(VOID); extern ULONG_PTR FrsExceptionLastInfo(VOID); extern VOID FrsExceptionQuiet(BOOL); extern PVOID MallocException(DWORD);
//
// FRS Events
//
extern HANDLE ShutDownEvent; // shutdown the service
extern HANDLE DataBaseEvent; // database is up and running
extern HANDLE JournalEvent; // journal is up and running
extern HANDLE ChgOrdEvent; // Change order accept is up and running
extern HANDLE ReplicaEvent; // replica is up and running
extern HANDLE CommEvent; // communication is up and running
extern HANDLE DsPollEvent; // used to poll the ds
extern HANDLE DsShutDownComplete; // ds polling thread has shut down
extern HANDLE FrsThawEvent; // Used to signal end of freeze.
// FrsThawEvent is used by backup.
extern HANDLE FrsNoInstallsInProgressEvent; // Used by Install CS to signal that
// there are no installs in progress.
// Used by backup.
//
// FRS Global flags
//
extern BOOL EventLogIsRunning; // is the event log service up and running?
extern BOOL RpcssIsRunning; // is the rpc endpoint service up and running?
//
// Main Initialization
//
VOID MainInit( VOID );
//
// Outbound Log Processor
//
VOID OutLogInitialize( VOID );
VOID ShutDownOutLog( VOID );
//
// Vv Join
//
VOID SubmitVvJoin( IN PREPLICA Replica, IN PCXTION Cxtion, IN USHORT Command );
DWORD SubmitVvJoinSync( IN PREPLICA Replica, IN PCXTION Cxtion, IN USHORT Command );
//
// FRS RPC
//
//
// The protocols sequences we think we know how to support
// XXX these constants should be in a win header file!
//
#define PROTSEQ_TCP_IP L"ncacn_ip_tcp"
//
// Perfmon APIs come over the local rpc.
//
#define PROTSEQ_LRPC L"ncalrpc"
//
// All computer names passed to RpcStringBindingCompose() using PROTSEQ_TCP_IP
// need to have the leading two back slashes removed or the call fails with
// RPC_S_SERVER_UNAVAILABLE.
//
#define FRS_TRIM_LEADING_2SLASH(_Name_) \
if (((_Name_) != NULL) && \ (wcslen(_Name_) > 1) && \ ((_Name_)[0] == L'\\' ) && \ ((_Name_)[1] == L'\\')) { \ (_Name_) += 2; \ }
DWORD FrsRpcBindToServer( IN PGNAME Name, IN PWCHAR PrincName, IN ULONG AuthLevel, OUT handle_t *Handle );
BOOL FrsRpcInitialize( VOID );
VOID FrsRpcUnInitialize( VOID );
VOID FrsRpcUnBindFromServer( handle_t *Handle );
//
// FRS threads
//
#if DBG
DWORD FrsTest( PVOID ); #endif DBG
//
// FRS Thread Management Support
//
VOID ThSupSubmitThreadExitCleanup( PFRS_THREAD );
VOID ThSupInitialize( VOID );
DWORD ThSupExitThreadGroup( DWORD (*)(PVOID) );
VOID ThSupExitSingleThread( PFRS_THREAD );
DWORD ThSupWaitThread( PFRS_THREAD FrsThread, DWORD Millisec );
PVOID ThSupGetThreadData( PFRS_THREAD );
PFRS_THREAD ThSupGetThread( DWORD (*)(PVOID) );
VOID ThSupReleaseRef( PFRS_THREAD );
BOOL ThSupCreateThread( PWCHAR Name, PVOID Param, DWORD (*Main)(PVOID), DWORD (*Exit)(PVOID) );
DWORD ThSupExitThreadNOP( PVOID );
DWORD ThSupExitWithTombstone( PVOID );
//
// shutdown functions called by ShutDown()
//
extern VOID ShutDownRpc(VOID); // Cleanup after StartRpc thread
//
// Globals
//
extern WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 2]; // A useful piece of info
extern PWCHAR ComputerDnsName; // A useful piece of info
//
// Service functions
//
DWORD FrsGetServiceState( PWCHAR, PWCHAR );
BOOL FrsWaitService( PWCHAR, PWCHAR, INT, INT );
BOOL FrsIsServiceRunning( PWCHAR, PWCHAR );
DWORD FrsSetServiceStatus( IN DWORD Status, IN DWORD CheckPoint, IN DWORD Hint, IN DWORD ExitCode );
//
// FRS Version Vector
//
#define LOCK_GEN_TABLE(_vv_) \
GTabLockTable(_vv_); \ DPRINT1(5, "LOCK_GEN_TABLE: "#_vv_":%08x\n", _vv_);
#define UNLOCK_GEN_TABLE(_vv_) \
DPRINT1(5, "UNLOCK_GEN_TABLE: "#_vv_":%08x\n", _vv_); \ GTabUnLockTable(_vv_);
PGEN_TABLE VVDupOutbound( IN PGEN_TABLE VV );
ULONG VVReserveRetireSlot( IN PREPLICA Replica, IN PCHANGE_ORDER_ENTRY Coe );
ULONG VVRetireChangeOrder( IN PTHREAD_CTX ThreadCtx, IN PREPLICA Replica, IN PCHANGE_ORDER_ENTRY ChangeOrder, IN ULONG CleanUpFlags );
PCHANGE_ORDER_ENTRY VVReferenceRetireSlot( IN PREPLICA Replica, IN PCHANGE_ORDER_COMMAND CoCmd );
VOID VVUpdate( IN PGEN_TABLE VV, IN ULONGLONG Vsn, IN GUID *Guid );
VOID VVInsertOutbound( IN PGEN_TABLE VV, IN PGVSN GVsn );
VOID VVUpdateOutbound( IN PGEN_TABLE VV, IN PGVSN GVsn );
BOOL VVHasVsnNoLock( IN PGEN_TABLE VV, IN GUID *OriginatorGuid, IN ULONGLONG Vsn );
BOOL VVHasOriginatorNoLock( IN PGEN_TABLE VV, IN GUID *OriginatorGuid );
BOOL VVHasVsn( IN PGEN_TABLE VV, IN PCHANGE_ORDER_COMMAND Coc );
PGVSN VVGetGVsn( IN PGEN_TABLE VV, IN GUID *Guid );
PVOID VVFreeOutbound( IN PGEN_TABLE VV );
VOID VVFree( IN PGEN_TABLE VV );
#if DBG
#define VV_PRINT(_Severity_, _Header_, _VV_) \
DPRINT1(_Severity_, "++ VV_PRINT :%08x\n", _VV_); \ VVPrint(_Severity_, _Header_, _VV_, FALSE) #define VV_PRINT_OUTBOUND(_Severity_, _Header_, _VV_) \
DPRINT1(_Severity_, "++ VV_PRINT_OUTBOUND :%08x\n", _VV_); \ VVPrint(_Severity_, _Header_, _VV_, TRUE) VOID VVPrint( IN ULONG Severity, IN PWCHAR Header, IN PGEN_TABLE VV, IN BOOL IsOutbound );
#else DBG
#define VV_PRINT(_Severity_, _Header_, _VV_)
#define VV_PRINT_OUTBOUND(_Severity_, _Header_, _VV_)
#endif DBG
//
// FRS Generic Table Routines
//
PGEN_TABLE GTabAllocTable( VOID );
PGEN_TABLE GTabAllocNumberTable( VOID );
PGEN_TABLE GTabAllocFileTimeTable( VOID );
PGEN_TABLE GTabAllocStringTable( VOID );
PGEN_TABLE GTabAllocStringAndBoolTable( VOID );
VOID GTabEmptyTableNoLock( IN PGEN_TABLE GTable, IN PVOID (*CallerFree)(PVOID) );
VOID GTabEmptyTable( IN PGEN_TABLE GTable, IN PVOID (*CallerFree)(PVOID) );
PVOID GTabFreeTable( PGEN_TABLE, PVOID (*)(PVOID) );
PVOID GTabLookup( PGEN_TABLE, PVOID, PWCHAR );
BOOL GTabIsEntryPresent( IN PGEN_TABLE GTable, IN GUID *Key1, IN PWCHAR Key2 );
PVOID GTabLookupTableString( IN PGEN_TABLE GTable, IN PWCHAR Key1, IN PWCHAR Key2 );
PVOID GTabLookupNoLock( PGEN_TABLE, PVOID, PWCHAR );
PGEN_ENTRY GTabLookupEntryNoLock( PGEN_TABLE, PVOID, PWCHAR );
PGEN_ENTRY GTabNextEntryNoLock( PGEN_TABLE, PVOID );
PVOID GTabNextDatumNoLock( IN PGEN_TABLE GTable, IN PVOID *Key );
PVOID GTabNextDatum( PGEN_TABLE, PVOID );
DWORD GTabNumberInTable( PGEN_TABLE );
VOID GTabLockTable( PGEN_TABLE );
VOID GTabUnLockTable( PGEN_TABLE );
PVOID GTabInsertUniqueEntry( IN PGEN_TABLE GTable, IN PVOID NewData, IN PVOID Key1, IN PVOID Key2 );
PVOID GTabInsertUniqueEntryNoLock( IN PGEN_TABLE GTable, IN PVOID NewData, IN PVOID Key1, IN PVOID Key2 );
VOID GTabInsertEntry( PGEN_TABLE, PVOID, PVOID, PWCHAR );
VOID GTabInsertEntryNoLock( IN PGEN_TABLE GTable, IN PVOID NewData, IN PVOID Key1, IN PWCHAR Key2 );
VOID GTabDelete( PGEN_TABLE, PVOID, PWCHAR, PVOID (*)(PVOID) );
VOID GTabDeleteNoLock( PGEN_TABLE, PVOID, PWCHAR, PVOID (*)(PVOID) );
VOID GTabPrintTable( PGEN_TABLE );
//
// GNAME
//
PVOID FrsFreeGName( PVOID );
PGNAME FrsBuildGName( GUID *, PWCHAR );
PGVSN FrsBuildGVsn( GUID *, ULONGLONG );
PGNAME FrsCopyGName( GUID *, PWCHAR );
PGNAME FrsDupGName( PGNAME );
VOID FrsPrintGName( PGNAME );
VOID FrsPrintGuid( GUID * );
GUID * FrsDupGuid( GUID * );
//
// FRS REPLICA COMMAND SERVER
//
#define FRS_CO_COMM_PROGRESS(_sev, _cmd, _sn, _partner, _text) \
DPRINT7(_sev, ":: CoG %08x, CxtG %08x, Sn %5d, vsn %08x %08x, FN: %-15ws, [%s], %ws\n", \ (_cmd)->ChangeOrderGuid.Data1, \ (_cmd)->CxtionGuid.Data1, \ (_sn), \ PRINTQUAD((_cmd)->FrsVsn), \ (_cmd)->FileName, \ (_text), \ (_partner));
#define FRS_CO_FILE_PROGRESS(_F_, _V_, _M_) \
DPRINT3(0, ":V: %-11ws (%08x): %s\n", _F_, (ULONG)(_V_), _M_);
#define FRS_CO_FILE_PROGRESS_WSTATUS(_F_, _V_, _M_, _W_) \
DPRINT4(0, ":V: %-11ws (%08x): %s (%d)\n", _F_, (ULONG)(_V_), _M_, _W_);
VOID RcsInitializeReplicaCmdServer( VOID );
VOID RcsFrsUnInitializeReplicaCmdServer( VOID );
VOID RcsShutDownReplicaCmdServer( VOID );
PREPLICA RcsFindReplicaByNumber( IN ULONG ReplicaNumber );
PREPLICA RcsFindReplicaByGuid( IN GUID *Guid );
PREPLICA RcsFindReplicaById( IN ULONG Id );
PREPLICA RcsFindSysVolByName( IN PWCHAR ReplicaSetName );
PREPLICA RcsFindSysVolByType( IN DWORD ReplicaSetType );
PREPLICA RcsFindNextReplica( IN PVOID *Key );
VOID RcsSubmitReplicaCxtion( IN PREPLICA Replica, IN PCXTION Cxtion, IN USHORT Command );
DWORD RcsSubmitReplicaSync( IN PREPLICA Replica, IN PREPLICA NewReplica, OPTIONAL IN PCXTION VolatileCxtion, OPTIONAL IN USHORT Command );
VOID RcsSubmitReplica( IN PREPLICA Replica, IN PREPLICA NewReplica, OPTIONAL IN USHORT Command );
DWORD RcsCreateReplicaSetMember( IN PREPLICA Replica );
VOID RcsMergeReplicaFromDs( IN PREPLICA Replica );
VOID RcsBeginMergeWithDs( VOID );
VOID RcsEndMergeWithDs( VOID );
ULONG RcsSubmitCommPktWithErrorToRcs( IN PCOMM_PACKET CommPkt );
VOID RcsSubmitTransferToRcs( IN PCOMMAND_PACKET Cmd, IN USHORT Command );
VOID RcsCmdPktCompletionRoutine( IN PCOMMAND_PACKET Cmd, IN PVOID Arg );
VOID RcsSubmitRemoteCoInstallRetry( IN PCHANGE_ORDER_ENTRY Coe );
VOID RcsSubmitRemoteCoAccepted( IN PCHANGE_ORDER_ENTRY Coe );
VOID RcsSubmitLocalCoAccepted( IN PCHANGE_ORDER_ENTRY Coe );
VOID RcsInboundCommitOk( IN PREPLICA Replica, IN PCHANGE_ORDER_ENTRY Coe );
BOOL RcsSendCoToOneOutbound( IN PREPLICA Replica, IN PCXTION Cxtion, IN PCHANGE_ORDER_COMMAND Coc );
PCXTION RcsCheckCxtion( IN PCOMMAND_PACKET Cmd, IN PCHAR Debsub, IN ULONG Flags );
//
// Flags for RcsCheckCxtion
//
#define CHECK_CXTION_EXISTS (0x00000001)
#define CHECK_CXTION_INBOUND (0x00000002)
#define CHECK_CXTION_OUTBOUND (0x00000004)
#define CHECK_CXTION_JRNLCXTION (0x00000008)
#define CHECK_CXTION_JOINGUID (0x00000010)
#define CHECK_CXTION_JOINED (0x00000020)
#define CHECK_CXTION_VVECTOR (0x00000040)
#define CHECK_CXTION_PARTNER (0x00000080)
#define CHECK_CXTION_AUTH (0x00000100)
#define CHECK_CXTION_FIXJOINED (0x00000200)
#define CHECK_CXTION_UNJOINGUID (0x00000400)
#define CHECK_CXTION_FOR_FETCHCS (0x00000800)
#define CHECK_CXTION_JOIN_OK (CHECK_CXTION_EXISTS | \
CHECK_CXTION_JOINED | \ CHECK_CXTION_JOINGUID )
//
// FRS COMMAND SERVER
//
VOID FrsSubmitCommandServer( PCOMMAND_SERVER, PCOMMAND_PACKET );
ULONG FrsSubmitCommandServerAndWait( IN PCOMMAND_SERVER Cs, IN PCOMMAND_PACKET Cmd, IN ULONG Timeout );
VOID FrsKickCommandServer( PCOMMAND_SERVER );
PCOMMAND_PACKET FrsGetCommandServer( PCOMMAND_SERVER );
PCOMMAND_PACKET FrsGetCommandServerIdled( IN PCOMMAND_SERVER, OUT PFRS_QUEUE * );
PCOMMAND_PACKET FrsGetCommandServerTimeout( IN PCOMMAND_SERVER, IN ULONG, OUT PBOOL );
PCOMMAND_PACKET FrsGetCommandServerTimeoutIdled( IN PCOMMAND_SERVER, IN ULONG, OUT PFRS_QUEUE *, OUT PBOOL );
DWORD FrsWaitForCommandServer( PCOMMAND_SERVER, DWORD );
VOID FrsExitCommandServer( PCOMMAND_SERVER, PFRS_THREAD );
VOID FrsRunDownCommandServer( PCOMMAND_SERVER, PFRS_QUEUE );
VOID FrsCancelCommandServer( PCOMMAND_SERVER, PFRS_QUEUE );
VOID FrsInitializeCommandServer( PCOMMAND_SERVER, DWORD, PWCHAR, DWORD (*)(PVOID) );
VOID FrsDeleteCommandServer( PCOMMAND_SERVER );
//
// FRS STAGING FILE GENERATOR SERVER
//
VOID ShutDownStageCs( VOID );
VOID FrsStageCsInitialize( VOID );
VOID FrsStageCsUnInitialize( VOID );
VOID FrsStageCsSubmitTransfer( IN PCOMMAND_PACKET, IN USHORT );
BOOL StageDeleteFile( IN PCHANGE_ORDER_COMMAND Coc, IN PREPLICA Replica, IN BOOL Acquire );
DWORD StageAcquire( IN GUID *ChangeOrderGuid, IN PWCHAR Name, IN ULONGLONG FileSize, IN OUT PULONG Flags, IN DWORD ReplicaNumber, OUT GUID *CompressionFormatUsed );
VOID StageRelease( IN GUID *ChangeOrderGuid, IN PWCHAR Name, IN ULONG Flags, IN PULONGLONG SizeOfFileGenerated, IN FILETIME *LastAccessTime, OUT GUID *CompressionFormatUsed );
VOID StageReleaseNotRecovered( );
VOID StageReleaseAll( );
//
// The argument functions passed to the get compression / decompression routines.
//
typedef DWORD (NTAPI *PFRS_DECOMPRESS_BUFFER) ( OUT PUCHAR DecompressedBuf, IN DWORD DecompressedBufLen, IN PUCHAR CompressedBuf, IN DWORD CompressedBufLen, OUT DWORD *pDecompressedSize, OUT DWORD *pBytesProcessed, OUT PVOID *pDecompressContext ); /*++
Arguments: DecompressedBuf : Resultant decompressed buffer. DecompressedBufLen : Max size of decompressed buffer. CompressedBuf : Input buffer. CompressedBufLen : Input buffer length. pDecompressedSize : Size of decompressed buffer. pBytesProcessed : Total bytes processed (could be over multiple calls to this function) pDecompressContext : Decompress context returned if multiple calls are needed to decompress this buffer. Valid context is returned when ERROR_MORE_DATA is returned.
Return Value: Win Status
--*/
typedef PVOID (NTAPI *PFRS_FREE_DECOMPRESS_BUFFER) ( IN PVOID *pDecompressContext ); /*++
Arguments: pDecompressContext : Decompress context to free.
Return Value: NULL ptr
--*/
typedef DWORD (NTAPI *PFRS_COMPRESS_BUFFER) ( IN PUCHAR UnCompressedBuf, IN DWORD UnCompressedBufLen, OUT PUCHAR CompressedBuf, IN DWORD CompressedBufLen, OUT DWORD *pCompressedSize ); /*++
UnCompressedBuf : Source buffer. UnCompressedBufLen : Length of source buffer. CompressedBuf : Resultant compressed buffer. CompressedBufLen : Length of compressed buffer supplied. CompressedSize : Actual size of the compressed data.
Return Value: Win Status
--*/
DWORD FrsGetCompressionRoutine( IN PWCHAR FileName, IN HANDLE FileHandle, OUT PFRS_COMPRESS_BUFFER *ppFrsCompressBuffer, //OUT DWORD (**ppFrsCompressBuffer)(
// IN UnCompressedBuf,
// IN UnCompressedBufLen,
// CompressedBuf,
// CompressedBufLen,
// CompressedSize),
OUT GUID *pCompressionFormatGuid );
DWORD FrsGetDecompressionRoutine( IN PCHANGE_ORDER_COMMAND Coc, IN PSTAGE_HEADER StageHeader, OUT PFRS_DECOMPRESS_BUFFER *ppFrsDecompressBuffer, OUT PFRS_FREE_DECOMPRESS_BUFFER *ppFrsFreeDecompressContext //OUT DWORD (**ppFrsDecompressBuffer)(OUT DecompressedBuf,
// IN DecompressedBufLen,
// IN CompressedBuf,
// IN CompressedBufLen,
// OUT DecompressedSize,
// OUT BytesProcessed),
//OUT PVOID (**ppFrsFreeDecompressContext)(IN pDecompressContext)
);
DWORD FrsGetDecompressionRoutineByGuid( IN GUID *CompressionFormatGuid, OUT PFRS_DECOMPRESS_BUFFER *ppFrsDecompressBuffer, OUT PFRS_FREE_DECOMPRESS_BUFFER *ppFrsFreeDecompressContext //OUT DWORD (**ppFrsDecompressBuffer)(OUT DecompressedBuf,
// IN DecompressedBufLen,
// IN CompressedBuf,
// IN CompressedBufLen,
// OUT DecompressedSize,
// OUT BytesProcessed),
//OUT PVOID (**ppFrsFreeDecompressContext)(IN pDecompressContext)
);
BOOL FrsDoesCoAlterNameSpace( IN PCHANGE_ORDER_COMMAND Coc );
BOOL FrsDoesCoNeedStage( IN PCHANGE_ORDER_COMMAND Coc );
DWORD FrsVerifyVolume( IN PWCHAR Name, IN PWCHAR SetName, IN ULONG Flags );
DWORD FrsDoesDirectoryExist( IN PWCHAR Name, OUT PDWORD pAttributes );
DWORD FrsCheckForNoReparsePoint( IN PWCHAR Name );
DWORD FrsDoesFileExist( IN PWCHAR Name );
DWORD FrsCreateDirectory( IN PWCHAR );
DWORD StuCreateFile( IN PWCHAR, OUT PHANDLE );
DWORD FrsDeleteFile( IN PWCHAR );
DWORD StuWriteFile( IN PWCHAR, IN HANDLE, IN PVOID, IN DWORD );
DWORD StuReadFile( IN PWCHAR, IN HANDLE, IN PVOID, IN DWORD, IN PULONG );
BOOL StuReadBlockFile( IN PWCHAR, IN HANDLE, IN PVOID, IN DWORD );
DWORD FrsSetCompression( IN PWCHAR, IN HANDLE, IN USHORT );
DWORD FrsGetCompression( IN PWCHAR, IN HANDLE, IN PUSHORT );
DWORD FrsSetFilePointer( IN PWCHAR, IN HANDLE, IN ULONG, IN ULONG );
DWORD FrsSetFileTime( IN PWCHAR, IN HANDLE, IN FILETIME *, IN FILETIME *, IN FILETIME * );
DWORD FrsSetEndOfFile( IN PWCHAR, IN HANDLE );
BOOL FrsGetFileInfoByHandle( IN PWCHAR, IN HANDLE, OUT PFILE_NETWORK_OPEN_INFORMATION );
DWORD FrsFlushFile( IN PWCHAR, IN HANDLE );
DWORD StuOpenFile( IN PWCHAR, IN DWORD, OUT PHANDLE );
DWORD FrsSetFileAttributes( IN PWCHAR, IN HANDLE, IN ULONG );
BOOL FrsCreateStageName( IN GUID *, OUT PWCHAR * );
PWCHAR StuCreStgPath( IN PWCHAR, IN GUID *, IN PWCHAR );
DWORD StuInstallRename( IN PCHANGE_ORDER_ENTRY, IN BOOL, IN BOOL );
ULONG StuInstallStage( IN PCHANGE_ORDER_ENTRY );
//
// FRS STAGING FILE FETCHER SERVER
//
VOID ShutDownFetchCs( VOID );
VOID FrsFetchCsInitialize( VOID );
VOID FrsFetchCsSubmitTransfer( PCOMMAND_PACKET, USHORT );
//
// FRS STAGING FILE INSTALLER SERVER
//
VOID ShutDownInstallCs( VOID );
VOID FrsInstallCsInitialize( VOID );
VOID FrsInstallCsSubmitTransfer( PCOMMAND_PACKET, USHORT );
//
// FRS INITIAL SYNC COOMMAND SERVER
//
VOID ShutDownInitSyncCs( VOID );
VOID InitSyncCsInitialize( VOID );
VOID InitSyncCsSubmitTransfer( PCOMMAND_PACKET, USHORT );
VOID InitSyncSubmitToInitSyncCs( IN PREPLICA Replica, IN USHORT Command );
//
// FRS DELAYED SERVER
//
VOID FrsDelCsSubmitSubmit( PCOMMAND_SERVER, PCOMMAND_PACKET, ULONG );
VOID FrsDelQueueSubmit( IN PCOMMAND_PACKET DelCmd, IN ULONG Timeout );
VOID FrsDelCsSubmitUnIdled( PCOMMAND_SERVER, PFRS_QUEUE, ULONG );
VOID FrsDelCsSubmitKick( PCOMMAND_SERVER, PFRS_QUEUE, ULONG );
VOID ShutDownDelCs( VOID );
VOID FrsDelCsInitialize( VOID );
//
// FRS COMM SUBSYSTEM
//
BOOL CommCheckPkt( PCOMM_PACKET );
BOOL CommValidatePkt( PCOMM_PACKET );
VOID CommDumpCommPkt( PCOMM_PACKET, DWORD );
//
// FRS utilities
//
DWORD FrsForceOpenId( OUT PHANDLE Handle, OUT OVERLAPPED *OpLock, IN PVOLUME_MONITOR_ENTRY pVme, IN PVOID Id, IN DWORD IdLen, IN ACCESS_MASK DesiredAccess, IN ULONG CreateOptions, IN ULONG ShareMode, IN ULONG CreateDispostion );
DWORD FrsRenameByHandle( IN PWCHAR Name, IN ULONG NameLen, IN HANDLE Handle, IN HANDLE TargetHandle, IN BOOL ReplicaIfExists );
DWORD FrsDeleteByHandle( IN PWCHAR Name, IN HANDLE Handle );
DWORD FrsCheckObjectId( IN PWCHAR Name, IN HANDLE Handle, IN GUID *Guid );
DWORD FrsOpenBaseNameForInstall( IN PCHANGE_ORDER_ENTRY Coe, OUT HANDLE *Handle );
DWORD FrsGetObjectId( IN HANDLE Handle, OUT PFILE_OBJECTID_BUFFER ObjectIdBuffer );
#define GENERIC_PREFIX L"NTFRS_"
#define STAGE_FINAL_PREFIX GENERIC_PREFIX
#define STAGE_FINAL_COMPRESSED_PREFIX L"NTFRS_CMP_"
#define PRE_INSTALL_PREFIX GENERIC_PREFIX
#define STAGE_GENERATE_PREFIX L"NTFRS_G_"
#define STAGE_GENERATE_COMPRESSED_PREFIX L"NTFRS_G_CMP_"
#define INSTALL_OVERRIDE_PREFIX L"NTFRS_DELETED_FILE_"
PWCHAR FrsCreateGuidName( IN GUID *Guid, IN PWCHAR Prefix );
//
// MISC
//
VOID FrsDsSwapPtrs( PVOID *, PVOID * ); #if DBG
#define INITIALIZE_HARD_WIRED() FrsDsInitializeHardWired()
VOID FrsDsInitializeHardWired( VOID ); #else DBG
#define INITIALIZE_HARD_WIRED()
#endif DBG
//
// Outbound Log Processor
//
ULONG OutLogSubmit( IN PREPLICA Replica, IN PCXTION Cxtion, IN USHORT Command );
//
// Database
//
JET_ERR DbsUpdateTable( IN PTABLE_CTX TableCtx );
ULONG DbsPackSchedule( IN PSCHEDULE Schedule, IN ULONG Fieldx, IN PTABLE_CTX TableCtx );
ULONG DbsPackStrW( IN PWCHAR StrW, IN ULONG Fieldx, IN PTABLE_CTX TableCtx );
ULONG DbsUnPackStrW( OUT PWCHAR *StrW, IN ULONG Fieldx, IN PTABLE_CTX TableCtx );
//
// The subsystem commands below apply to an entire subsystem, e.g. the
// journal. Some of the commands may not apply to a subsystem.
// The service level commands are the means to tell a subsystem that you
// want the subsystem to provide/perform a given service. For example
// a PREPARE_SERVICE command sent to the Journal subsystem tells the
// journal to initialize journalling for a specified replica set. Multiple
// prepare service commands are sent when the FRS first starts up. They are
// then followed by a START_SUBSYSTEM command. This way the journal knows
// to start processing the USN journal on a gvien volume at the lowest
// CommitUsn point for ANY replica set hosted by the volume.
//
// Some commands may not be implemented by all subsystems. For example
// the PAUSE_SERVICE command is not provided for a single replica set
// as long as the FRS is running because we have to continuously monitor
// the journal so as not to lose data. Some subsystems may not have any
// service level commands.
//
#define CMD_COMMAND_ERROR 0x00
#define CMD_INIT_SUBSYSTEM 0x01
#define CMD_START_SUBSYSTEM 0x02
#define CMD_STOP_SUBSYSTEM 0x03
#define CMD_PAUSE_SUBSYSTEM 0x04
#define CMD_QUERY_INFO_SUBSYSTEM 0x05
#define CMD_SET_CONFIG_SUBSYSTEM 0x06
#define CMD_QUERY_CONFIG_SUBSYSTEM 0x07
#define CMD_CANCEL_COMMAND_SUBSYSTEM 0x08
#define CMD_READ_SUBSYSTEM 0x09
#define CMD_WRITE_SUBSYSTEM 0x0A
#define CMD_PREPARE_SERVICE1 0x21
#define CMD_PREPARE_SERVICE2 0x22
#define CMD_START_SERVICE 0x23
#define CMD_STOP_SERVICE 0x24
#define CMD_PAUSE_SERVICE 0x25
#define CMD_QUERY_INFO_SERVICE 0x26
#define CMD_SET_CONFIG_SERVICE 0x27
#define CMD_QUERY_CONFIG_SERVICE 0x28
#define CMD_CANCEL_COMMAND_SERVICE 0x29
#define CMD_READ_SERVICE 0x2A
#define CMD_WRITE_SERVICE 0x2B
#define CMD_RESYNC_SERVICE 0x2C
#define CMD_VERIFY_SERVICE 0x2D
extern FRS_QUEUE JournalProcessQueue; extern FRS_QUEUE DBServiceProcessQueue;
//
// Service UNIQUE Commands start at 0x100 for each service.
//
/***********************************************************
* * * Commands specific to the Journal service. * * * ***********************************************************/ // sequence break
#define CMD_JOURNAL_PAUSED 0x101
#define CMD_JOURNAL_INIT_ONE_RS 0x102
#define CMD_JOURNAL_DELETE_DIR_FILTER_ENTRY 0x103
#define CMD_JOURNAL_CLEAN_WRITE_FILTER 0x104
/***********************************************************
* * * Commands specific to the Database service. * * * ***********************************************************/ // sequence break
#define CMD_CLOSE_TABLE 0x101
#define CMD_UPDATE_RECORD_FIELDS 0x102
#define CMD_UPDATE_TABLE_RECORD 0x103
#define CMD_INSERT_TABLE_RECORD 0x104
#define CMD_READ_TABLE_RECORD 0x105
#define CMD_CREATE_REPLICA_SET_MEMBER 0x106
#define CMD_OPEN_REPLICA_SET_MEMBER 0x107
#define CMD_CLOSE_REPLICA_SET_MEMBER 0x108
#define CMD_LOAD_REPLICA_FILE_TREE 0x109
#define CMD_DELETE_REPLICA_SET_MEMBER 0x10A
#define CMD_DELETE_TABLE_RECORD 0x10B
#define CMD_CREATE_START_NEW_MEMBER 0x10C
#define CMD_LOAD_ONE_REPLICA_FILE_TREE 0x10D
#define CMD_STOP_REPLICATION_SINGLE_REPLICA 0x10E
#define CMD_DBS_RETIRE_INBOUND_CO 0x10F
#define CMD_DBS_RETRY_INBOUND_CO 0x110
#define CMD_DBS_RETIRE_REJECTED_CO 0x111
#define CMD_UPDATE_REPLICA_SET_MEMBER 0x112
#define CMD_DBS_REPLICA_SAVE_MARK 0x113
#define CMD_DBS_INJECT_OUTBOUND_CO 0x114
#define CMD_DBS_REPLICA_SERVICE_STATE_SAVE 0x115
//
// Given a ptr to a DB_SERVICE_REQUEST return the ptr to the data record.
//
#define DBS_GET_RECORD_ADDRESS(_DbsRequest) \
((_DbsRequest)->TableCtx->pDataRecord)
#define DBS_GET_TABLECTX(_DbsRequest) \
((_DbsRequest)->TableCtx)
#define DBS_FREE_TABLECTX(_DbsRequest) \
DbsFreeTableCtx((_DbsRequest)->TableCtx, COMMAND_PACKET_TYPE); \ (_DbsRequest)->TableCtx = FrsFree((_DbsRequest)->TableCtx);
//
// The following access macros assume that the field buffers used for the record
// read and write operations are the same. That is that both the Jet Set and
// Ret structs point to the same buffer. They each take a table ctx parameter
// and a record field ID code (defined as an ENUM in schema.h).
//
// Get the field's receive buffer length.
#define DBS_GET_FIELD_SIZE(_TableCtx, _Field) \
((_TableCtx)->pJetRetCol[_Field].cbActual)
// Get the field's maximum buffer length.
#define DBS_GET_FIELD_SIZE_MAX( _TableCtx, _Field) \
((_TableCtx)->pJetRetCol[_Field].cbData)
// Get the address of the field's buffer.
#define DBS_GET_FIELD_ADDRESS( _TableCtx, _Field) \
((_TableCtx)->pJetRetCol[_Field].pvData)
//
// Set the size of the data in the field buffer.
// Warning - Don't do this on fixed size fields.
//
#define DBS_SET_FIELD_SIZE(_TableCtx, _Field, _NewSize) \
(_TableCtx)->pJetRetCol[_Field].cbActual = _NewSize; \ (_TableCtx)->pJetSetCol[_Field].cbData = _NewSize;
//
// Set the maximum size of the field buffer.
// Warning - Don't do this on fixed size fields.
// Warning - ONLY USE IF YOU KNOW WHAT YOU'RE DOING OTHERWISE USE DBS_REALLOC_FIELD
//
#define DBS_SET_FIELD_SIZE_MAX(_TableCtx, _Field, _NewSize) \
(_TableCtx)->pJetRetCol[_Field].cbData = _NewSize;
// Set the address of the field's buffer. It doesn't update the ptr in base record.
// Warning - Don't do this on fixed size fields.
// Warning - ONLY USE IF YOU KNOW WHAT YOU'RE DOING OTHERWISE USE DBS_REALLOC_FIELD
#define DBS_SET_FIELD_ADDRESS( _TableCtx, _Field, _NewAddr) \
(_TableCtx)->pJetRetCol[_Field].pvData = _NewAddr; \ (_TableCtx)->pJetSetCol[_Field].pvData = _NewAddr;
//
// Reallocate the buffer size for a variable length binary field.
// Set _NewSize to zero to delete the buffer.
// Set _KeepData to TRUE if you want to copy the data from the old buffer to the new.
// This function also updates the buffer pointer in the base record.
//
#define DBS_REALLOC_FIELD(_TableCtx, _FieldIndex, _NewSize, _KeepData) \
DbsTranslateJetError(DbsReallocateFieldBuffer(_TableCtx, \ _FieldIndex, \ _NewSize, \ _KeepData), TRUE)
#define DBS_ACCESS_BYKEY 0
#define DBS_ACCESS_FIRST 1
#define DBS_ACCESS_LAST 2
#define DBS_ACCESS_NEXT 3
#define DBS_ACCESS_MASK (0xF)
//
// If set the close the table after completing the operation.
//
#define DBS_ACCESS_CLOSE (0x80000000)
//
// If set then free the table context struct and the data record struct
// after completing the operation. Useful on record inserts and the table
// close command. (CMD_CLOSE_TABLE)
//
#define DBS_ACCESS_FREE_TABLECTX (0x40000000)
/***********************************************************
* * * Commands specific to the Outbound Log subsystem. * * * ***********************************************************/ // sequence break
#define CMD_OUTLOG_WORK_CO 0x100
#define CMD_OUTLOG_ADD_REPLICA 0x101
#define CMD_OUTLOG_REMOVE_REPLICA 0x102
#define CMD_OUTLOG_INIT_PARTNER 0x103
#define CMD_OUTLOG_ADD_NEW_PARTNER 0x104
#define CMD_OUTLOG_DEACTIVATE_PARTNER 0x105
#define CMD_OUTLOG_ACTIVATE_PARTNER 0x106
#define CMD_OUTLOG_CLOSE_PARTNER 0x107
#define CMD_OUTLOG_REMOVE_PARTNER 0x108
#define CMD_OUTLOG_RETIRE_CO 0x109
#define CMD_OUTLOG_UPDATE_PARTNER 0x10A
#define CMD_OUTLOG_CLEANUP 0x10B
/***********************************************************
* * * Commands specific to the test subsystem. * * * ***********************************************************/ // sequence break
#define CMD_NOP 0x100
/***********************************************************
* * * Commands specific to the replica command server * * * ***********************************************************/ // sequence break
//
//
#define CMD_UNKNOWN 0x100
#define CMD_START 0x108
#define CMD_DELETE 0x110
#define CMD_DELETE_RETRY 0x112
#define CMD_DELETE_NOW 0x114
#define CMD_START_REPLICAS 0x118
#define CMD_CHECK_SCHEDULES 0x119
#define CMD_JOIN_CXTION 0x120
#define CMD_NEED_JOIN 0x121
#define CMD_START_JOIN 0x122
#define CMD_JOINED 0x128
#define CMD_JOINING 0x130
#define CMD_JOINING_AFTER_FLUSH 0x131
#define CMD_VVJOIN_START 0x132
#define CMD_VVJOIN_SUCCESS 0x134
#define CMD_VVJOIN_DONE 0x136
#define CMD_VVJOIN_DONE_UNJOIN 0x138
#define CMD_UNJOIN 0x140
#define CMD_UNJOIN_REMOTE 0x148
#define CMD_CHECK_PROMOTION 0x150
#define CMD_HUNG_CXTION 0x160
#define CMD_LOCAL_CO_ACCEPTED 0x200
#define CMD_CREATE_STAGE 0x210
#define CMD_CREATE_EXISTING 0x212
#define CMD_CHECK_OID 0x214
#define CMD_REMOTE_CO 0x218
#define CMD_REMOTE_CO_ACCEPTED 0x220
#define CMD_SEND_STAGE 0x228
#define CMD_SENDING_STAGE 0x230
#define CMD_RECEIVING_STAGE 0x238
#define CMD_RECEIVED_STAGE 0x240
#define CMD_CREATED_EXISTING 0x242
#define CMD_RETRY_STAGE 0x243
#define CMD_RETRY_FETCH 0x244
#define CMD_SEND_RETRY_FETCH 0x245
#define CMD_ABORT_FETCH 0x246
#define CMD_SEND_ABORT_FETCH 0x247
#define CMD_INSTALL_STAGE 0x248
#define CMD_REMOTE_CO_DONE 0x250
/*****************************************************************
* * * Commands specific to the init sync controller command server * * * *****************************************************************/ // sequence break
//
//
#define CMD_INITSYNC_START_SYNC 0x100
#define CMD_INITSYNC_JOIN_NEXT 0x101
#define CMD_INITSYNC_START_JOIN 0x102
#define CMD_INITSYNC_VVJOIN_DONE 0x103
#define CMD_INITSYNC_KEEP_ALIVE 0x104
#define CMD_INITSYNC_CHECK_PROGRESS 0x105
#define CMD_INITSYNC_UNJOIN 0x106
#define CMD_INITSYNC_JOINED 0x107
#define CMD_INITSYNC_COMM_TIMEOUT 0x108
/***********************************************************
* * * Commands specific to the Delayed command server. * * * ***********************************************************/ // sequence break
//
#define CMD_DELAYED_SUBMIT 0x100
#define CMD_DELAYED_UNIDLED 0x101
#define CMD_DELAYED_KICK 0x102
#define CMD_DELAYED_QUEUE_SUBMIT 0x103
#define CMD_DELAYED_COMPLETE 0x104
/***********************************************************
* * * Commands specific to the DS command server. * * * ***********************************************************/ // sequence break
//
#define CMD_POLL_DS 0x100
/***********************************************************
* * * Commands specific to the thread command server. * * * ***********************************************************/ // sequence break
//
#define CMD_WAIT 0x100
/***********************************************************
* * * Commands specific to the Send command server. * * * ***********************************************************/ // sequence break
//
#define CMD_SND_COMM_PACKET 0x100
#define CMD_SND_CMD 0x110
/***********************************************************
* * * Commands specific to the Receive command server. * * * ***********************************************************/ // sequence break
//
#define CMD_RECEIVE 0x100
/***********************************************************
* * * Commands specific to the staging area command server. * * * ***********************************************************/ // sequence break
//
#define CMD_ALLOC_STAGING 0x100
#define CMD_FREE_STAGING 0x101
/***********************************************************
* * * Completion routine types for use in command packets. * * * ***********************************************************/ //
//
#define COMPLETION_INVOKE_ON_CANCEL 0x20
#define COMPLETION_INVOKE_ON_SUCCESS 0x40
#define COMPLETION_INVOKE_ON_ERROR 0x80
/*++
VOID FrsSetCompletionRoutine( IN PCOMMAND_PACKET CmdPkt, IN PCOMMAND_PACKET_COMPLETION_ROUTINE CompletionRoutine, IN PVOID Context, IN BOOLEAN InvokeOnSuccess, IN BOOLEAN InvokeOnError, IN BOOLEAN InvokeOnCancel )
Routine Description:
This routine is invoked to set the address of a completion routine which is to be invoked when a command packet has been completed by a subsystem.
If the completion routine and the completion queue are both null then the packet is freed at completion.
If both are specified the completion routine is called first and on return the packet is placed on the CompletionQueue. The Completion routine can of course modify the CompletionQueue.
If a Completion Routine is provided then the packet is never freed by the command packet completion dispatchet. This is the responsibility of the completion routine.
Arguments:
CmdPkt - Pointer to the Command Packet itself.
CompletionRoutine - Address of the completion routine that is to be invoked once the command packet is completed.
Context - Specifies a context parameter to be passed to the completion routine.
InvokeOnSuccess - Specifies that the completion routine is invoked when the operation is successfully completed.
InvokeOnError - Specifies that the completion routine is invoked when the operation completes with an error status.
InvokeOnCancel - Specifies that the completion routine is invoked when the operation is being canceled.
Return Value:
None.
--*/
#define FrsSetCompletionRoutine(_CmdPkt, _CompletionRoutine, _CompletionArg) { \
(_CmdPkt)->CompletionRoutine = (_CompletionRoutine); \ (_CmdPkt)->CompletionArg = (_CompletionArg); \ }
#define FrsSetCommandErrorStatus(_CmdPkt, _Status ) \
(_CmdPkt)->FrsErrorStatus = (_Status)
#define FrsSetCommand( _CmdPkt, _Queue, _Command, _Flags) { \
(_CmdPkt)->TargetQueue = (_Queue); \ (_CmdPkt)->Command = (USHORT) (_Command); \ (_CmdPkt)->Flags = (UCHAR) (_Flags); \ }
//
// Mark this command request as synchronous.
//
#define FrsSetCommandSynchronous( _CmdPkt) \
(_CmdPkt)->Flags |= CMD_PKT_FLAGS_SYNC;
//
// The following are special queues for handling commands.
//
VOID FrsSubmitCommand( IN PCOMMAND_PACKET CmdPkt, IN BOOL Headwise );
ULONG FrsSubmitCommandAndWait( IN PCOMMAND_PACKET Cmd, IN BOOL Headwise, IN ULONG Timeout );
VOID FrsUnSubmitCommand( IN PCOMMAND_PACKET CmdPkt );
VOID FrsCompleteCommand( IN PCOMMAND_PACKET CmdPkt, IN DWORD ErrorStatus );
VOID FrsCommandScheduler( PFRS_QUEUE Queue );
PCOMMAND_PACKET FrsAllocCommand( IN PFRS_QUEUE TargetQueue, IN USHORT Command );
PCOMMAND_PACKET FrsAllocCommandEx( IN PFRS_QUEUE TargetQueue, IN USHORT Command, IN ULONG Size );
VOID FrsFreeCommand( IN PCOMMAND_PACKET Cmd, IN PVOID Arg );
PCOMMAND_PACKET FrsGetCommand( IN PFRS_QUEUE Queue, IN DWORD MilliSeconds );
VOID FrsRunDownCommand( IN PFRS_QUEUE Queue );
extern FRS_QUEUE FrsScheduleQueue;
//
// Some Journal related functions.
//
ULONG JrnlMonitorInit( PFRS_QUEUE ReplicaListHead, ULONG Phase );
ULONG JrnlPauseVolume( IN PVOLUME_MONITOR_ENTRY pVme, IN DWORD MilliSeconds );
ULONG JrnlUnPauseVolume( IN PVOLUME_MONITOR_ENTRY pVme, IN PJBUFFER Jbuff, IN BOOL HaveLock );
BOOL JrnlSetReplicaState( IN PREPLICA Replica, IN ULONG NewState );
#if DBG
#define DUMP_USN_RECORD2(_Severity, _UsnRecord, _ReplicaNum, _LocCmd) \
DumpUsnRecord(_Severity, _UsnRecord, _ReplicaNum, _LocCmd, DEBSUB, __LINE__)
#define DUMP_USN_RECORD(_Severity, _UsnRecord) \
DumpUsnRecord(_Severity, _UsnRecord, 0, CO_LOCATION_NUM_CMD, DEBSUB, __LINE__)
VOID DumpUsnRecord( IN ULONG Severity, IN PUSN_RECORD UsnRecord, IN ULONG ReplicaNumber, IN ULONG LocationCmd, IN PCHAR Debsub, IN ULONG uLineNo );
#else DBG
#define DUMP_USN_RECORD(_Severity, _UsnRecord)
#endif DBG
ULONG ChgOrdInsertRemoteCo( IN PCOMMAND_PACKET Cmd, IN PCXTION Cxtion );
DWORD ChgOrdHammerObjectId( IN PWCHAR Name, IN PVOID Id, IN DWORD IdLen, IN PVOLUME_MONITOR_ENTRY pVme, IN BOOL CallerSupplied, OUT USN *Usn, IN OUT PFILE_OBJECTID_BUFFER FileObjID, IN OUT BOOL *ExistingOid );
DWORD ChgOrdSkipBasicInfoChange( IN PCHANGE_ORDER_ENTRY Coe, IN PBOOL SkipCo );
VOID JrnlCleanupVme( IN PVOLUME_MONITOR_ENTRY pVme );
//
// Waitable timer list
//
DWORD WaitSubmit( IN PCOMMAND_PACKET Cmd, IN DWORD Timeout, IN USHORT TimeoutCommand );
VOID WaitUnsubmit( IN PCOMMAND_PACKET Cmd );
VOID WaitInitialize( VOID );
VOID ShutDownWait( VOID );
BOOL ReparseTagReplicateFileData( DWORD ReparseTag );
BOOL ReparseTagReplicateReparsePoint( DWORD ReparseTag );
VOID FrsCheckLocalResources( );
#define ReparseTagReplicate(Tag) (ReparseTagReplicateFileData(Tag) || ReparseTagReplicateReparsePoint(Tag))
#define REPARSE_TAG_REPLICATION_TYPE_NONE L"None"
#define REPARSE_TAG_REPLICATION_TYPE_FILE_DATA L"File Data"
#define REPARSE_TAG_REPLICATION_TYPE_REPARSE_POINT L"Reparse Point"
typedef struct _FRS_VALID_PARTNER_TABLE_STRUCT {
// So we don't free the struct too soon.
// The ref count is set to 1 when the struct is created.
// Each function that uses the struct must increase the ref count before
// using it and decrement the count when done.
// When we change the global variable, pPartnerTableStruct, to point to
// a new struct the count gets decremented. The struct will not be freed
// until the ref count is zero.
ULONG ReferenceCount;
// indexed by partner sid.
// A hit means that machine is a valid partner.
// The table elements are meaningless.
PQHASH_TABLE pPartnerTable;
// Indexed by connection guid.
// Each table element is a string containing the name of the partner.
PQHASH_TABLE pPartnerConnectionTable;
// Used for linking the list of old structs.
struct _FRS_VALID_PARTNER_TABLE_STRUCT *Next; } FRS_VALID_PARTNER_TABLE_STRUCT, *PFRS_VALID_PARTNER_TABLE_STRUCT;
//
// See definition of pValidPartnerTableStruct for more info on these macros
//
#define ACQUIRE_VALID_PARTNER_TABLE_POINTER(_pptr) { \
EnterCriticalSection(&CritSec_pValidPartnerTableStruct); \ if(pValidPartnerTableStruct == NULL) { \ *(_pptr) = NULL; \ } else { \ FRS_ASSERT(pValidPartnerTableStruct->ReferenceCount != 0); \ InterlockedIncrement(&(pValidPartnerTableStruct->ReferenceCount));\ *(_pptr) = pValidPartnerTableStruct; \ } \ LeaveCriticalSection(&CritSec_pValidPartnerTableStruct); \ }
#define RELEASE_VALID_PARTNER_TABLE_POINTER(_ptr) \
InterlockedDecrement(&((_ptr)->ReferenceCount))
#define SWAP_VALID_PARTNER_TABLE_POINTER(_newPtr, _pOldPtr) { \
EnterCriticalSection(&CritSec_pValidPartnerTableStruct); \ if(pValidPartnerTableStruct != NULL) { \ FRS_ASSERT(pValidPartnerTableStruct->ReferenceCount != 0); \ InterlockedDecrement(&(pValidPartnerTableStruct->ReferenceCount));\ } \ *(_pOldPtr) = pValidPartnerTableStruct; \ pValidPartnerTableStruct = (_newPtr); \ InterlockedIncrement(&(pValidPartnerTableStruct->ReferenceCount)); \ LeaveCriticalSection(&CritSec_pValidPartnerTableStruct); \ }
//
// In most cases we can not proceed if we are unable to initialize
// the critical section. Instead of handling the return value at every place
// we raise a low memory exception here which will cause us to
// shutdown the service.
//
// Spin count for critical sections.
#define NTFRS_CRITSEC_SPIN_COUNT 4000
#define INITIALIZE_CRITICAL_SECTION(_CritSec) \
{ \ if (!InitializeCriticalSectionAndSpinCount(_CritSec, NTFRS_CRITSEC_SPIN_COUNT)) {\ RaiseException(ERROR_OUTOFMEMORY, 0, 0, NULL); \ }\ }
//
// For FRS writer support.
//
#define FREE_VALID_PARTNER_TABLE_STRUCT(_pStruct) { \
FRS_ASSERT((_pStruct)->ReferenceCount == 0); \ FrsFreeType((_pStruct)->pPartnerTable); \ FrsFreeType((_pStruct)->pPartnerConnectionTable); \ FrsFree(_pStruct); \ }
extern BOOL FrsFrozenForBackup; extern LONG FrsFilesInInstall;
DWORD FrsThawAfterBackup();
DWORD FrsFreezeForBackup();
DWORD InitializeFrsWriter();
VOID ShutDownFrsWriter();
#endif // _FRSH_
|