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.
2556 lines
63 KiB
2556 lines
63 KiB
/*++
|
|
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_
|