Source code of Windows XP (NT5)
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.

2475 lines
104 KiB

  1. /*++
  2. Copyright (c) 1997-1999 Microsoft Corporation
  3. Module Name:
  4. schema.h
  5. Abstract:
  6. Defines the layout of the tables in Jet for the NT File Replication Service.
  7. Note: The initial values for these tables are defined in schema.c
  8. Any change here must be reflected there.
  9. To add a new table xx:
  10. 1. Clone the structs for a current table.
  11. 2. Change the name prefixes appropriately
  12. 3. Create the xx_COL_LIST enum
  13. 4. Create the xxTABLE_RECORD struct
  14. 5. Create the xxTABLE_INDEX_LIST struct
  15. 6. Add an entry to the TABLE_TYPE enum
  16. Then go to schema.c and:
  17. 7. create the entries for the xxTableColDesc struct.
  18. 8. create the entries for the xxTableRecordFields struct.
  19. 9. create the entries for the xxTableIndexDesc struct.
  20. 10. add defines for INIT_xxTABLE_PAGES and INIT_xxTABLE_DENSITY.
  21. 11. Add an entry for the new table in the DBTables struct.
  22. 12. Add an entry for the new table in the FrsTableProperties struct.
  23. Then go to frsalloc.h and:
  24. 13. Add an entry for the table context struct in the
  25. REPLICA_THREAD_CTX struct or the REPLICA_CTX struct as appropriate.
  26. 14. if there is any table specific init code needed as part of
  27. the allocation of another FRS struct then add this to FRS_ALLOC.
  28. Currently, once you have described the table as above the table
  29. init code is generic.
  30. 15. Add code to create the record data for the table.
  31. To add a new column to an existing table:
  32. In schema.h -
  33. 1. Add entry to the record struct.
  34. 2. Add entry to the field typedef with an 'x' suffix and in the
  35. correct position relative to the other fields in the table.
  36. In schema.c -
  37. 3. Add entry in the ColumnCreate struct for the record.
  38. 4. Add entry in the record fields struct.
  39. 5. Add code to update the new record data field.
  40. Author:
  41. David Orbits (davidor) - 14-Mar-1997
  42. Revision History:
  43. --*/
  44. //
  45. // A Flag name table is an array of structures. Each entry contains a flag
  46. // mask and a ptr to a string describing the flag.
  47. //
  48. typedef struct _FLAG_NAME_TABLE_ {
  49. ULONG Flag;
  50. PSTR Name;
  51. } FLAG_NAME_TABLE, *PFLAG_NAME_TABLE;
  52. //
  53. // Flag name tables for log output.
  54. //
  55. extern FLAG_NAME_TABLE CxtionFlagNameTable[];
  56. extern FLAG_NAME_TABLE CoIFlagNameTable[];
  57. extern FLAG_NAME_TABLE CoFlagNameTable[];
  58. extern FLAG_NAME_TABLE CoeFlagNameTable[];
  59. extern FLAG_NAME_TABLE IscuFlagNameTable[];
  60. extern FLAG_NAME_TABLE IDRecFlagNameTable[];
  61. extern FLAG_NAME_TABLE UsnReasonNameTable[];
  62. extern FLAG_NAME_TABLE FileAttrFlagNameTable[];
  63. extern FLAG_NAME_TABLE ConfigFlagNameTable[];
  64. #define JET_DIR L"jet"
  65. #define JET_FILE L"ntfrs.jdb"
  66. #define JET_FILE_COMPACT L"ntfrs_compact.jdb"
  67. #define JET_SYS L"sys\\"
  68. #define JET_TEMP L"temp\\"
  69. #define JET_LOG L"log\\"
  70. //
  71. // System wide defines for the database.
  72. //
  73. #define DBS_TEMPLATE_TABLE_NUMBER 0
  74. #define DBS_FIRST_REPLICA_NUMBER 1
  75. #define DBS_MAX_REPLICA_NUMBER 0xfffffff0
  76. #define FRS_SYSTEM_INIT_REPLICA_NUMBER 0xffffffff
  77. #define FRS_SYSTEM_INIT_RECORD TEXT("<init>")
  78. #define FRS_SYSTEM_INIT_PATH TEXT("::::Unused")
  79. #define FRS_UNDEFINED_REPLICA_NUMBER 0xfffffffe
  80. #define NTFRS_RECORD_0 L"NtFrs Record Zero (DB Templates)"
  81. #define NTFRS_RECORD_0_ROOT L"A:\\NtFrs Record Zero (DB Templates)\\Root"
  82. #define NTFRS_RECORD_0_STAGE L"A:\\NtFrs Record Zero (DB Templates)\\Stage"
  83. //
  84. // Convert local replica pointer to local replica ID for storing in database.
  85. //
  86. #define ReplicaAddrToId(_ra_) (((_ra_) != NULL) ? \
  87. (_ra_)->ReplicaNumber : FRS_UNDEFINED_REPLICA_NUMBER)
  88. #define ReplicaIdToAddr(_id_) RcsFindReplicaById(_id_)
  89. #define GuidToReplicaAddr(_pguid_) RcsFindReplicaByGuid(_pguid_)
  90. //
  91. // The replication state for each file in a replica tree is stored in a Jet
  92. // database because jet provides crash recovery. This is required because if a
  93. // file is deleted and the system crashes then we have lost the replication
  94. // state associated with the file.
  95. //
  96. // The database consists of several tables each composed of several columns.
  97. //
  98. // IDTable -
  99. // This table contains information about each file in the replica tree.
  100. // It is indexed by both NTFS File ID and the Object ID Guid associated with
  101. // the file. Neither of these indexes are clustered since inserts could occur
  102. // anywhere in the table. When a remote Change Order (CO) arrives the IDTable
  103. // tells us where the file is now (except for local operations on the file that
  104. // have not yet been processed) and the current version info on the file. When
  105. // a local CO is processed the IDTable tells us where the file exists on the other
  106. // replica set partners (modulo concurrent local operations on the file elsewhere).
  107. //
  108. //
  109. // DIRTable
  110. //
  111. //
  112. // Tunnel Table
  113. //
  114. // Version Vector Table
  115. //
  116. // The Version Vector Table (VVTable) is a per-Replica table.
  117. // It is used by the replication service to dampen propagation of updates
  118. // to replicas that already are up to date. There is one entry per member of
  119. // the replica set. Each entry has the GUID of the originating member and
  120. // the Volume Sequence Number (VSN) of the most recent change this member has
  121. // seen from that member. We keep our own VSN instead of using the NTFS
  122. // volume USN because the replica set can be moved to a different volume
  123. // and the volume could be reformatted and the replica tree restored from backup.
  124. // In both cases the NTFS USN could move backwards.
  125. //
  126. //
  127. // Inbound Change Order Table
  128. //
  129. // When a change order (local or remote) is accepted it is inserted into the
  130. // inbound change order table where it stays until it is completed. State
  131. // variables in the record track the progress of the change order and determine
  132. // where to continue in the event of a crash or a retry of a failed operation
  133. // (e.g. Install).
  134. //
  135. // Outbound Change Order Table
  136. //
  137. // We need to be able to cancel an outbound change order that is still pending
  138. // if we get either a second local change or an inbound update that wins the
  139. // resolution decision. If a pile of NEW files get put into the tree and then
  140. // are deleted before they can be replicated we need to be able to cancel
  141. // the replication or we need to send out a delete if the repl has already
  142. // been done. Note that the combination of local changes and inbound updates
  143. // can generate multiple outbound change orders with the same file Guid.
  144. // If we get several changes to different file properties spread over time
  145. // we need to consolidate them into a single change order and a single file
  146. // snapshot.
  147. //
  148. // Connection Table
  149. //
  150. // This table tracks the state of each inbound and outbound connection for the
  151. // replica set. In addtion it tracks the delivery state of each outbound
  152. // change order using a bit vector window on the outbound change order stream.
  153. // The outbound change orders are stored in the outbound log in order by
  154. // the originating guid. When all outbound partners have received the change
  155. // order it is then deleted from the outbound log along with the staging file
  156. // assuming the local install (if any) is complete.
  157. //
  158. //
  159. //
  160. // The Data Structures below provide the definitions of the Jet Tables.
  161. // There are several related structures for each table. See the comments in
  162. // jet.h for a description of the relationship between them.
  163. //
  164. //
  165. //
  166. typedef struct _RECORD_FIELDS {
  167. USHORT Offset;
  168. USHORT DataType;
  169. ULONG Size;
  170. } RECORD_FIELDS, *PRECORD_FIELDS;
  171. //
  172. // The following data type defs originally came from mapidefs.h
  173. // We use modified names and a different set of values.
  174. //
  175. typedef enum _FRS_DATA_TYPES {
  176. DT_UNSPECIFIED=0, // (Reserved for interface use) type doesn't matter to caller
  177. DT_NULL , // NULL property value
  178. DT_I2 , // Signed 16-bit value
  179. DT_LONG , // Signed 32-bit value
  180. DT_ULONG , // Unsigned 32-bit
  181. DT_R4 , // 4-byte floating point
  182. DT_DOUBLE , // Floating point double
  183. DT_CURRENCY , // Signed 64-bit int (decimal w/4 digits right of decimal pt)
  184. DT_APDTIME , // Application time
  185. DT_ERROR , // 32-bit error value
  186. DT_BOOL , // 32-bit boolean (non-zero true)
  187. DT_OBJECT , // Embedded object in a property
  188. DT_I8 , // 8-byte signed integer
  189. DT_X8 , // 8-byte Hex number
  190. DT_STRING8 , // Null terminated 8-bit character string
  191. DT_UNICODE , // Null terminated Unicode string
  192. DT_FILETIME , // FILETIME 64-bit int w/ number of 100ns periods since Jan 1,1601
  193. DT_GUID , // GUID
  194. DT_BINARY , // Uninterpreted (counted byte array)
  195. DT_OBJID , // NTFS Object ID
  196. DT_USN , // Update Sequence Number
  197. DT_FSVOLINFO , // FD Volume Info
  198. DT_FILENAME , // A unicode file name path (could be dos, NT, UNC, ...)
  199. DT_IDT_FLAGS , // The flags word in an IDTable record.
  200. DT_COCMD_FLAGS , // The flags word in a change order command record.
  201. DT_USN_FLAGS , // The reason flags word in a change order command record.
  202. DT_CXTION_FLAGS , // The reason flags word in a connection record.
  203. DT_FILEATTR , // The file attribute flags word.
  204. DT_FILE_LIST , // A comma list of file or dir names, UNICODE.
  205. DT_DIR_PATH , // A unicode directory path.
  206. DT_ACCESS_CHK , // A unicode string for access check enable and rights.
  207. DT_COSTATE , // The change order state in a change order command record.
  208. DT_COCMD_IFLAGS , // The Interlocked flags word in a change order command record.
  209. DT_IDT_EXTENSION, // THe data extension field of an IDTable record.
  210. DT_COCMD_EXTENSION, // THe data extension field of a change order command record.
  211. DT_CO_LOCN_CMD , // The Change order location command.
  212. DT_REPLICA_ID , // Local ID number of replica set.
  213. DT_CXTION_GUID , // A Cxtion guid which we can translate to the string.
  214. FRS_DATA_TYPES_MAX
  215. } FRS_DATA_TYPES;
  216. //
  217. // Used for those var len binary records that are prefixed with a 4 byte length.
  218. //
  219. #define FIELD_DT_IS_BINARY(_t_) \
  220. (((_t_) == DT_BINARY) || \
  221. ((_t_) == DT_IDT_EXTENSION) || \
  222. ((_t_) == DT_COCMD_EXTENSION))
  223. //
  224. // Alternate property type names for ease of use
  225. //
  226. #define DT_SHORT DT_I2
  227. #define DT_I4 DT_LONG
  228. #define DT_FLOAT DT_R4
  229. #define DT_R8 DT_DOUBLE
  230. #define DT_LONGLONG DT_I8
  231. //
  232. // Fields marked spare aren't skipped when buffers are allocated and
  233. // database fields are read/written. They are part of the Jet schema for
  234. // future use so we don't have to rev the DB.
  235. //
  236. #define DT_SPARE_FLAG ((USHORT) 0x4000)
  237. //
  238. // Do not allocate a default sized buffer for this field.
  239. //
  240. #define DT_NO_DEFAULT_ALLOC_FLAG ((USHORT) 0x2000)
  241. //
  242. // The record buffer for this field is of fixed size even though the schema
  243. // may allow a variable amount of data for the field. An example is the
  244. // IDTable record extension which fixed with any given version of FRS but which
  245. // could grow in a future rev so we use a long bin datatype in the schema with
  246. // a max column width of 2 meg.
  247. //
  248. #define DT_FIXED_SIZE_BUFFER ((USHORT) 0x1000)
  249. #define IsSpareField(_x_) (((_x_) & DT_SPARE_FLAG) != 0)
  250. #define IsNoDefaultAllocField(_x_) (((_x_) & DT_NO_DEFAULT_ALLOC_FLAG) != 0)
  251. #define IsFixedSzBufferField(_x_) (((_x_) & DT_FIXED_SIZE_BUFFER) != 0)
  252. #define MaskPropFlags(_x_) \
  253. ((_x_) & (~(DT_SPARE_FLAG | DT_NO_DEFAULT_ALLOC_FLAG | DT_FIXED_SIZE_BUFFER)))
  254. //
  255. // Define codes for spare fields. No storage is allocated.
  256. //
  257. #define DT_UNSPECIFIED_SPARE (DT_UNSPECIFIED | DT_SPARE_FLAG)
  258. #define DT_NULL_SPARE (DT_NULL | DT_SPARE_FLAG)
  259. #define DT_I2_SPARE (DT_I2 | DT_SPARE_FLAG)
  260. #define DT_LONG_SPARE (DT_LONG | DT_SPARE_FLAG)
  261. #define DT_ULONG_SPARE (DT_ULONG | DT_SPARE_FLAG)
  262. #define DT_R4_SPARE (DT_R4 | DT_SPARE_FLAG)
  263. #define DT_DOUBLE_SPARE (DT_DOUBLE | DT_SPARE_FLAG)
  264. #define DT_CURRENCY_SPARE (DT_CURRENCY | DT_SPARE_FLAG)
  265. #define DT_APDTIME_SPARE (DT_APDTIME | DT_SPARE_FLAG)
  266. #define DT_ERROR_SPARE (DT_ERROR | DT_SPARE_FLAG)
  267. #define DT_BOOL_SPARE (DT_BOOL | DT_SPARE_FLAG)
  268. #define DT_OBJECT_SPARE (DT_OBJECT | DT_SPARE_FLAG)
  269. #define DT_I8_SPARE (DT_I8 | DT_SPARE_FLAG)
  270. #define DT_X8_SPARE (DT_X8 | DT_SPARE_FLAG)
  271. #define DT_STRING8_SPARE (DT_STRING8 | DT_SPARE_FLAG)
  272. #define DT_UNICODE_SPARE (DT_UNICODE | DT_SPARE_FLAG)
  273. #define DT_FILETIME_SPARE (DT_FILETIME | DT_SPARE_FLAG)
  274. #define DT_GUID_SPARE (DT_GUID | DT_SPARE_FLAG)
  275. #define DT_BINARY_SPARE (DT_BINARY | DT_SPARE_FLAG)
  276. #define DT_OBJID_SPARE (DT_OBJID | DT_SPARE_FLAG)
  277. #define DT_USN_SPARE (DT_USN | DT_SPARE_FLAG)
  278. #define DT_FSVOLINFO_SPARE (DT_FSVOLINFO | DT_SPARE_FLAG)
  279. #define DT_SHORT_SPARE DT_I2_SPARE
  280. #define DT_I4_SPARE DT_LONG_SPARE
  281. #define DT_FLOAT_SPARE DT_R4_SPARE
  282. #define DT_R8_SPARE DT_DOUBLE_SPARE
  283. #define DT_LONGLONG_SPARE DT_I8_SPARE
  284. //
  285. // Data Extension Record Fields
  286. //
  287. // The following declarations define data extensions that are assembled into
  288. // a variable length binary data field of a database record. They are self
  289. // describing, each has a size and type code, so downlevel versions of FRS
  290. // can skip components it doesn't understand. All components must begin
  291. // on a quadword boundary.
  292. //
  293. // The specific record layout uses the component declarations below and are
  294. // described with the containing table record.
  295. //
  296. typedef enum _DATA_EXTENSION_TYPE_CODES_ {
  297. DataExtend_End = 0, // Terminates a data extension record.
  298. DataExtend_MD5_CheckSum, // A Data Checksum record.
  299. DataExtend_Max
  300. } DATA_EXTENSION_TYPE_CODES;
  301. typedef struct _DATA_EXTENSION_PREFIX_ {
  302. union {
  303. ULONGLONG SizeType; // Force quadword alignment.
  304. struct {
  305. ULONG Size; // Size of Data Component including this Prefix.
  306. LONG Type; // omponent type from DATA_EXTENSION_TYPE_CODES
  307. };
  308. };
  309. } DATA_EXTENSION_PREFIX, *PDATA_EXTENSION_PREFIX;
  310. //
  311. // All variable length data extension record fields must end with a
  312. // DATA_EXTENSION_END component to terminate the component scan.
  313. //
  314. typedef struct _DATA_EXTENSION_END_ {
  315. DATA_EXTENSION_PREFIX Prefix;
  316. } DATA_EXTENSION_END, *PDATA_EXTENSION_END;
  317. //
  318. // The DATA_EXTENSION_CHECKSUM component describes an MD5 checksum.
  319. //
  320. typedef struct _DATA_EXTENSION_CHECKSUM_ {
  321. DATA_EXTENSION_PREFIX Prefix;
  322. BYTE Data[MD5DIGESTLEN]; // The MD5 Checksum.
  323. } DATA_EXTENSION_CHECKSUM, *PDATA_EXTENSION_CHECKSUM;
  324. //
  325. // For error checking. Make it bigger if any data extension record exceeds this.
  326. //
  327. #define REALLY_BIG_EXTENSION_SIZE 8192
  328. //
  329. // The database table descriptions for each replica set are as follows.
  330. // Note - the order of the enum and the table entries must be kept in sync.
  331. // Also note - The addition of new tables to define a replica set may require
  332. // some lines of init code be added to FrsCreate/Open replica tables
  333. // and FrsAllocate.
  334. //
  335. // The table names are suffixed by an integer digit string NUM_REPLICA_DIGITS long.
  336. //
  337. #define NUM_REPLICA_DIGITS 5
  338. typedef enum _TABLE_TYPE {
  339. INLOGTablex = 0, // The inbound change order table
  340. OUTLOGTablex, // the outbound change order table.
  341. IDTablex, // The ID table description.
  342. DIRTablex, // The DIR table description.
  343. VVTablex, // The Version Vector table description.
  344. CXTIONTablex, // The connection record table.
  345. // <<<--- Add more per-replica tables here.
  346. _TABLE_TYPE_MAX_, // The tables above this line are per-replica
  347. ConfigTablex, // The config table description (a single table)
  348. ServiceTablex, // The config table description (a single table)
  349. // <<<--- Add more single tables here.
  350. TABLE_TYPE_INVALID
  351. } TABLE_TYPE;
  352. #define TABLE_TYPE_MAX _TABLE_TYPE_MAX_
  353. #define IS_REPLICA_TABLE(_TableType_) ((_TableType_) < TABLE_TYPE_INVALID)
  354. #define IS_INLOG_TABLE(_TableCtx_) ((_TableCtx_)->TableType == INLOGTablex)
  355. #define IS_OUTLOG_TABLE(_TableCtx_) ((_TableCtx_)->TableType == OUTLOGTablex)
  356. #define IS_ID_TABLE(_TableCtx_) ((_TableCtx_)->TableType == IDTablex)
  357. #define IS_DIR_TABLE(_TableCtx_) ((_TableCtx_)->TableType == DIRTablex)
  358. #define IS_VV_TABLE(_TableCtx_) ((_TableCtx_)->TableType == VVTablex)
  359. #define IS_CXTION_TABLE(_TableCtx_) ((_TableCtx_)->TableType == CXTIONTablex)
  360. #define IS_CONFIG_TABLE(_TableCtx_) ((_TableCtx_)->TableType == ConfigTablex)
  361. #define IS_SERVICE_TABLE(_TableCtx_)((_TableCtx_)->TableType == ServiceTablex)
  362. #define IS_INVALID_TABLE(_TableCtx_)((_TableCtx_)->TableType == TABLE_TYPE_INVALID)
  363. #define IS_TABLE_OPEN(_TableCtx_) ((_TableCtx_)->Tid != JET_tableidNil)
  364. typedef struct _FRS_TABLE_PROPERTIES {
  365. PCHAR BaseName; // Base table name (must match name in Table Create struct)
  366. PRECORD_FIELDS RecordFields; // pointer to the record fields descriptor.
  367. ULONG PropertyFlags; // See below.
  368. } FRS_TABLE_PROPERTIES, *PFRS_TABLE_PROPERTIES;
  369. //
  370. // FRS Table Property Flags.
  371. //
  372. #define FRS_TPF_NONE 0x00000000
  373. #define FRS_TPF_SINGLE 0x00000001
  374. #define FRS_TPF_NOT_CALLER_DATAREC 0x00000002
  375. //
  376. // Max table types is used to limit the max number of table version numbers
  377. // tracked in the database config <init> record.
  378. //
  379. #define FRS_MAX_TABLE_TYPES 16
  380. //
  381. // The table version numbers are a major/minor pair in the upper/lower short.
  382. // The Version Count is the first element in the TableVersionNumbers array.
  383. // The upper short is the count of per-replica tables and the lower short is
  384. // the count of single tables.
  385. //
  386. #define VersionCount 0x00060002
  387. #define VersionINLOGTable 0x00010000
  388. #define VersionOUTLOGTable 0x00010000
  389. #define VersionIDTable 0x00010000
  390. #define VersionDIRTable 0x00010000
  391. #define VersionVVTable 0x00010000
  392. #define VersionCXTIONTable 0x00010000
  393. #define VersionConfigTable 0x00010000
  394. #define VersionServiceTable 0x00010000
  395. #define VersionInvalid 0xffffffff
  396. //
  397. // The TableVersionNumbers array as saved in the init record when new tables
  398. // are created. This is used to detect a mismatch between a database and
  399. // the version of FRS running.
  400. //
  401. extern ULONG TableVersionNumbers[FRS_MAX_TABLE_TYPES];
  402. //
  403. // GET_TABLE_VERSION maps a table type ID as compiled to the corresponding
  404. // entry in either the per-replica or single table portion of the TableVersionNumber
  405. // array. This is used to compare the table version array of the database with
  406. // the version of NTFRS that is running. It is also used to compare table version
  407. // numbers of two copies of NTFRS communicating as partners. The idea is that
  408. // newer versions of the service will provide conversion functions to allow it
  409. // to talk with data bases created with older versions and / or partner members
  410. // running older versions of the service.
  411. //
  412. // TBD: How do we store the TableVersionNumbers array in the database so
  413. // a newer version of the service can read it from an older database
  414. // Can we use the table descriptors in the DB to get the config record
  415. // and then use the record descriptor to get the TableVersionNumbers array?
  416. //
  417. #define GET_TABLE_VERSION(_VerArray_, _TableType_) \
  418. (((_TableType_) < TABLE_TYPE_MAX) \
  419. ? (((_TableType_) < ((_VerArray_[0])>>16) \
  420. ? _VerArray_[(_TableType_)+1)] \
  421. : VersionInvalid) \
  422. : ((((_TableType_)-(TABLE_TYPE_MAX+1)) < ((_VerArray_[0]) & 0xffff) \
  423. ? (_VerArray_+((_VerArray_[0])>>16)+1))[(_TableType_)-(TABLE_TYPE_MAX+1)]\
  424. : VersionInvalid) \
  425. )
  426. //
  427. // The list of Jet Tables created for each replica set and their properties.
  428. //
  429. extern JET_TABLECREATE DBTables[];
  430. extern FRS_TABLE_PROPERTIES FrsTableProperties[];
  431. //
  432. // MAX_RDN_VALUE_SIZE is used as a limit on the machine name
  433. // lengths. It is currently 64 in the Dir Service.
  434. //
  435. #define MAX_RDN_VALUE_SIZE 64
  436. //
  437. // This is what the DS uses.
  438. //
  439. #define CP_NON_UNICODE_FOR_JET 1252
  440. #define CP_UNICODE_FOR_JET 1200
  441. //
  442. // An NTFS File Object ID contains a 16 byte GUID followed by 48 bytes of
  443. // extended information.
  444. //
  445. #define FILE_OBJECTID_SIZE sizeof(FILE_OBJECTID_BUFFER)
  446. /******************************************************************************
  447. *******************************************************************************
  448. ** **
  449. ** P a r t n e r C o n n e c t i o n T a b l e **
  450. ** **
  451. ** **
  452. *******************************************************************************
  453. ******************************************************************************/
  454. //
  455. // The partner connections as defined by the topology are kept in this table.
  456. // Each connection is marked as either an inbound or outbound, has its own
  457. // schedule and partner identification info. In addition, outbound connections
  458. // record the state describing where we are in the outbound log and what
  459. // change orders have been acknowledged.
  460. //
  461. // The max number of change orders outstanding for any one partner is limited
  462. // by the ACK_VECTOR_SIZE (number of bits). This must be a power of 2.
  463. //
  464. // The Connection Record column descriptions are as follows.
  465. // Note - the order of the enum and the table entries must be kept in sync.
  466. //
  467. typedef enum _CXTION_RECORD_COL_LIST_{
  468. CrCxtionGuidx = 0, // Cxtion guid from the DS (DS Cxtion obj guid)
  469. CrCxtionNamex, // Cxtion name from the DS (DS Cxtion obj RDN)
  470. CrPartnerGuidx, // Partner guid from the DS (DS Replica set obj)
  471. CrPartnerNamex, // Partner name from the DS (DS server obj RDN)
  472. CrPartSrvNamex, // Partner server name
  473. CrPartnerDnsNamex, // DNS name of partner (from DS server obj)
  474. CrInboundx, // TRUE if inbound cxtion
  475. CrSchedulex, // schedule
  476. CrTerminationCoSeqNumx, // The Seq Num of most recent Termination CO inserted.
  477. CrLastJoinTimex, // Time of last Join by this partner.
  478. CrFlagsx, // misc state flags.
  479. CrCOLxx, // Leading change order index / sequence number.
  480. CrCOTxx, // Trailing change order index / sequence number.
  481. CrCOTxNormalModeSavex, // Saved Normal Mode COTx while in VV Join Mode.
  482. CrCOTslotx, // Slot in Ack Vector corresponding to COTx.
  483. CrOutstandingQuotax, // The maximum number of COs outstanding.
  484. CrAckVectorx, // The partner ack vector.
  485. CrPartnerNetBiosNamex, // SAM-Account-Name from Computer (minus the $)
  486. CrPartnerPrincNamex, // NT4 account name cracked from Computer
  487. CrPartnerCoDnx, // Distinguished name from Computer
  488. CrPartnerCoGuidx, // Object-GUID from Computer
  489. CrPartnerSidx, // SID of computer object of NTFRS-Member
  490. CrOptionsx, // Options from NTDS-Connection
  491. CrOverSitex, // Over-Site-Connection from NTDS-Connection
  492. CrPartnerAuthLevelx, // Frs-Partner-Auth-Level
  493. CrAckVersionx, // Version number of current AckVector state.
  494. CrSpare2Ullx,
  495. CrSpare1Guidx,
  496. CrSpare2Guidx,
  497. CrSpare1Binx,
  498. CrSpare2Binx,
  499. CXTION_TABLE_MAX_COL
  500. } CXTION_RECORD_COL_LIST;
  501. extern JET_COLUMNCREATE CXTIONTableColDesc[];
  502. //
  503. // Connection record definition.
  504. //
  505. //
  506. // Note: Buffers are allocated at runtime to hold data for fields with
  507. // a ColMaxWidth greater than sizeof(PVOID) where the field def in the corresponding
  508. // record struct is sizeof(PVOID) (i.e. it holds a pointer). For fields where the
  509. // ColMaxWidth equals the field size in the record struct the data is in the
  510. // record struct and no buffer is allocated.
  511. //
  512. //
  513. // ** Note ** a change to this size requires the Data Base to be recreated since
  514. // this is the field length in the DB.
  515. #define ACK_VECTOR_SIZE 128
  516. #define ACK_VECTOR_BYTES (ACK_VECTOR_SIZE >> 3)
  517. #define ACK_VECTOR_LONGS (ACK_VECTOR_SIZE >> 5)
  518. #define ACK_VECTOR_LONG_MASK (ACK_VECTOR_LONGS-1)
  519. //
  520. // Authentication type and levels
  521. //
  522. #define CXTION_AUTH_KERBEROS_FULL (0) // DEFAULT; Encrypted Kerberos
  523. #define CXTION_AUTH_NONE (1) // No authentication
  524. typedef struct _CXTION_RECORD_ {
  525. GUID CxtionGuid; // Cxtion name/guid from the DS
  526. WCHAR CxtionName[MAX_RDN_VALUE_SIZE+1];
  527. GUID PartnerGuid; // Partner name/guid from the DS
  528. WCHAR PartnerName[MAX_RDN_VALUE_SIZE+1];
  529. WCHAR PartSrvName[MAX_RDN_VALUE_SIZE+1];
  530. WCHAR PartnerDnsName[DNS_MAX_NAME_LENGTH+1]; // DNS name of partner machine
  531. BOOL Inbound; // TRUE if inbound cxtion
  532. PVOID Schedule; // schedule
  533. ULONG TerminationCoSeqNum; // The Seq Num of most recent Termination CO inserted.
  534. FILETIME LastJoinTime; // Time of last Join by this partner.
  535. ULONG Flags; // misc state flags.
  536. ULONG COLx; // Leading change order index / sequence number.
  537. ULONG COTx; // Trailing change order index / sequence number.
  538. ULONG COTxNormalModeSave; // Saved Normal Mode COTx while in VV Join Mode.
  539. ULONG COTslot; // Slot in Ack Vector corresponding to COTx.
  540. ULONG OutstandingQuota; // The maximum number of COs outstanding.
  541. ULONG AckVector[ACK_VECTOR_LONGS]; // The partner ack vector.
  542. PWCHAR PartnerNetBiosName; // SAM-Account-Name from Computer (minus the $)
  543. PWCHAR PartnerPrincName; // NT4 account name cracked from Computer
  544. PWCHAR PartnerCoDn; // Distinguished name from Computer
  545. GUID PartnerCoGuid; // Object-GUID from Computer
  546. PWCHAR PartnerSid; // Partner's string'ized SID
  547. ULONG Options; // Options from NTDS-Connection
  548. PWCHAR OverSite; // Over-Site-Connection from NTDS-Connection
  549. ULONG PartnerAuthLevel; // Frs-Partner-Auth-Level
  550. ULONGLONG AckVersion; // Version number of current AckVector state.
  551. ULONGLONG Spare2Ull;
  552. GUID Spare1Guid;
  553. GUID Spare2Guid;
  554. PVOID Spare1Bin;
  555. PVOID Spare2Bin;
  556. } CXTION_RECORD, *PCXTION_RECORD;
  557. //
  558. // The RECORD_FIELDS struct is used to build the Jet Set Column struct.
  559. //
  560. extern RECORD_FIELDS CXTIONTableRecordFields[];
  561. extern JET_SETCOLUMN CXTIONTableJetSetCol[CXTION_TABLE_MAX_COL];
  562. //
  563. // The ConnectionRecord index descriptions are as follows.
  564. // Note - the order of the enum and the table entries must be kept in sync.
  565. //
  566. typedef enum _CXTION_TABLE_INDEX_LIST {
  567. CrCxtionGuidxIndexx, // The primary index is on the connection GUID.
  568. CXTION_TABLE_MAX_INDEX
  569. } CXTION_TABLE_INDEX_LIST;
  570. extern JET_INDEXCREATE CXTIONTableIndexDesc[];
  571. /******************************************************************************
  572. *******************************************************************************
  573. ** **
  574. ** I n b o u n d & O u t b o u n d L o g **
  575. ** C h a n g e O r d e r R e c o r d **
  576. ** **
  577. ** **
  578. *******************************************************************************
  579. ******************************************************************************/
  580. // The Change Order Command is what is actually transmitted to our partners
  581. // and stored in the database while the operation is pending. Generally the
  582. // data elements declared in the change order entry are relevant to the local
  583. // system only while the data elements in the change order command are
  584. // invarient across replica set members. The Change Order Entry is defined
  585. // in frsalloc.h.
  586. //
  587. //
  588. // A change order has two file change components, Content and Location.
  589. //
  590. // The content changes are cumulative and are the logical OR of the content
  591. // related USN Reason flags. Content changes don't change the File ID. A
  592. // Usn Record that specifies a content change where we have a pending change
  593. // order causes the new reason mask to be ORed into the change order reason
  594. // mask. A rename that changes only the filename is a content change.
  595. //
  596. // The Location changes are transitive since a file can exist in only one
  597. // location on the volume. Only the final location matters. A USN Record that
  598. // specifies a location change where we have a pending change order causes the
  599. // Location command in the change order to be updated with the new location
  600. // information. Create and Delete are location changes as are renames that
  601. // change the parent directory of the file.
  602. //
  603. //
  604. // The ChangeOrder column descriptions are as follows. Note - the order of the
  605. // enum and the table entries must be kept in sync.
  606. //
  607. // ChangeOrders are used in the inbound and outbound log tables. Initially the
  608. // record structure is the same but that is likely to change.
  609. // ***** WARNING ****** As long as they are the same be sure to update both
  610. // the inbound and outbound log table defs in schema.c
  611. //
  612. typedef enum _CHANGE_ORDER_COL_LIST {
  613. COSequenceNumberx = 0, // Jet assigned changeorder sequence number
  614. COFlagsx, // Change order flags
  615. COIFlagsx, // Change order flags REQUIRING interlocked modify
  616. COStatex, // State is sep DWORD to avoid locking.
  617. COContentCmdx, // File content changes from UsnReason
  618. COLcmdx, // The CO location command.
  619. COFileAttributesx,
  620. COFileVersionNumberx, // The file version number, inc on each close.
  621. COPartnerAckSeqNumberx, // The sequence number to Ack this CO with.
  622. COFileSizex,
  623. COFileOffsetx, // The current committed progress for staging file.
  624. COFrsVsnx, // Originator Volume sequence number
  625. COFileUsnx, // Last USN of file being staged
  626. COJrnlUsnx, // Latest USN of jrnl record contributing to CO.
  627. COJrnlFirstUsnx, // First USN of jrnl record contributing to CO.
  628. COOriginalReplicaNumx, // Contains Replica ID when in DB
  629. CONewReplicaNumx, // Contains Replica ID when in DB
  630. COChangeOrderGuidx, // GUID to identify the change order
  631. COOriginatorGuidx, // The GUID of the originating member
  632. COFileGuidx, // The obj ID of the file
  633. COOldParentGuidx, // The Obj ID of the file's original parent directory
  634. CONewParentGuidx, // The Obj ID of the file's current parent directory
  635. COCxtionGuidx, // The obj ID of remote CO connection.
  636. COAckVersionx, // Version number of AckVector state when this CO was sent.
  637. COSpare2Ullx,
  638. COSpare1Guidx,
  639. COSpare2Guidx,
  640. COSpare1Wcsx,
  641. COSpare2Wcsx,
  642. COExtensionx,
  643. COSpare2Binx,
  644. COEventTimex, // The USN Journal Entry Timestamp.
  645. COFileNameLengthx, // The filename length.
  646. COFileNamex, // The file name. (Must be Last)
  647. CHANGE_ORDER_MAX_COL
  648. } CHANGE_ORDER_COL_LIST;
  649. extern JET_COLUMNCREATE ILChangeOrderTableColDesc[];
  650. extern JET_COLUMNCREATE OLChangeOrderTableColDesc[];
  651. //
  652. // ChangeOrder record definition.
  653. //
  654. //
  655. // Note: Buffers are allocated at runtime to hold data for fields with
  656. // a ColMaxWidth greater than sizeof(PVOID) where the field def in the corresponding
  657. // record struct is sizeof(PVOID) (i.e. it holds a pointer). For fields where the
  658. // ColMaxWidth equals the field size in the record struct the data is in the
  659. // record struct and no buffer is allocated.
  660. //
  661. //
  662. //
  663. // The Data Extension Field for a Change Order Record.
  664. //
  665. // Unlike the extension in the IDTable this record field is a pointer to
  666. // allocated memory containing this struct. This was done so the extension
  667. // can be packed as a separate item by the COMM layer and leave the size of
  668. // the change order command unchanged for compatibility with down rev
  669. // partners. The change order command size can't change without doing
  670. // format conversions for down rev partners. The storage for this
  671. // extension field is allocated when the change order is allocated.
  672. //
  673. // WARNING: While this struct is extensible in the database it is not
  674. // extensible when sent to down level FRS members because the size of the
  675. // friggen struct is checked by the receiving comm routines. So if you need
  676. // to enlarge this struct you need to send it as COMM_CO_EXTENSION_2
  677. // so it is ignored by down level members.
  678. // Further, you need to build a copy of this struct and send it as type
  679. // COMM_CO_EXT_WIN2K when sending to a down level member. This is what
  680. // CO_RECORD_EXTENSION_WIN2K is for.
  681. //
  682. typedef struct _CHANGE_ORDER_RECORD_EXTENSION_ {
  683. ULONG FieldSize;
  684. USHORT Major;
  685. USHORT OffsetCount;
  686. //
  687. // use offsets from the base of the struct to each component so we avoid
  688. // problems with alignement packing.
  689. //
  690. ULONG Offset[1]; // Offsets to data components.
  691. ULONG OffsetLast; // The last offset is always zero.
  692. DATA_EXTENSION_CHECKSUM DataChecksum;
  693. // Add new components in here.
  694. } CHANGE_ORDER_RECORD_EXTENSION, *PCHANGE_ORDER_RECORD_EXTENSION;
  695. //
  696. // See comment above for why you can't extend this struct.
  697. //
  698. typedef struct _CO_RECORD_EXTENSION_WIN2K_ {
  699. ULONG FieldSize;
  700. USHORT Major;
  701. USHORT OffsetCount;
  702. //
  703. // use offsets from the base of the struct to each component so we avoid
  704. // problems with alignement packing.
  705. //
  706. ULONG Offset[1]; // Offsets to data components.
  707. ULONG OffsetLast; // The last offset is always zero.
  708. DATA_EXTENSION_CHECKSUM DataChecksum;
  709. } CO_RECORD_EXTENSION_WIN2K, *PCO_RECORD_EXTENSION_WIN2K;
  710. typedef struct _CO_LOCATION_CMD {
  711. unsigned DirOrFile : 1;
  712. unsigned Command : 4;
  713. unsigned filler : 27;
  714. } CO_LOCATION_CMD, *PCO_LOCATION_CMD;
  715. typedef struct _CHANGE_ORDER_RECORD_ {
  716. ULONG SequenceNumber; // Unique sequence number for change order.
  717. ULONG Flags; // Change order flags
  718. ULONG IFlags; // These flags can ONLY be updated with interlocked exchange.
  719. ULONG State; // State is sep DWORD to avoid locking.
  720. ULONG ContentCmd; // File content changes from UsnReason
  721. union {
  722. ULONG LocationCmd;
  723. CO_LOCATION_CMD Field; // File Location command
  724. } Lcmd;
  725. ULONG FileAttributes;
  726. ULONG FileVersionNumber; // The file version number, inc on each close.
  727. ULONG PartnerAckSeqNumber; // Save seq number for Partner Ack.
  728. ULONGLONG FileSize;
  729. ULONGLONG FileOffset; // The current committed progress for staging file.
  730. ULONGLONG FrsVsn; // Originator Volume sequence number
  731. USN FileUsn; // The USN of the file must match on the Fetch request.
  732. USN JrnlUsn; // USN of last journal record contributing to this CO.
  733. USN JrnlFirstUsn; // USN of first journal record contributing to this CO.
  734. ULONG OriginalReplicaNum; // Contains Replica ID number
  735. ULONG NewReplicaNum; // Contains Replica ID number
  736. GUID ChangeOrderGuid; // Guid that identifies the change order everywhere.
  737. GUID OriginatorGuid; // The GUID of the originating member
  738. GUID FileGuid; // The obj ID of the file
  739. GUID OldParentGuid; // The Obj ID of the file's original parent directory
  740. GUID NewParentGuid; // The Obj ID of the file's current parent directory
  741. GUID CxtionGuid; // The obj ID of remote CO connection.
  742. ULONGLONG AckVersion; // Version number of AckVector state when this CO was sent.
  743. ULONGLONG Spare2Ull;
  744. GUID Spare1Guid;
  745. //
  746. // The following four pointers -
  747. // Spare1Wcs, Spare2Wcs, Extension, Spare2Bin
  748. // occupy 16 bytes on 32 bit architectures and 32 bytes on 64 bit architectures.
  749. // The CO is included in the stage file header and in the change order Comm
  750. // packet causing 32-64 interop problems in both stage file processing and
  751. // comm transfers between 32 and 64 bit machines. The contents of these
  752. // pointers are irrelevant in both comm packets and staging files since they
  753. // point to allocated buffers.
  754. //
  755. // To preserve the size of the change order in the staging file on 64 bit
  756. // machines the unused field Spare2Guid is unioned with the two 8 byte
  757. // pointers Spare1Wcs and Spare2Wcs, saving 16 bytes. On 32 bit
  758. // architectures these fields are left separate.
  759. //
  760. // Note: in the future you can either used Spare2Guid or the two pointers
  761. // but not both or the 64 bit version will be broken. It would have been
  762. // simpler to just ifdef out Spare1Wcs and Spare2Wcs on the 64 bit compile
  763. // but the ifdef would then have to be extended to the enum and the DB
  764. // descriptor tables in schema.c.
  765. //
  766. // Note: The only way you can change the size or layout of the change order
  767. // command is to adjust the version level and provide a translation function
  768. // for both the change order comm packet and the stage file. Of course
  769. // even if you do this you still have a problem of converting the change
  770. // order in a stage file header from the new format to the old format when
  771. // you prop the stage file to a down level member.
  772. //
  773. #ifdef _WIN64
  774. union {
  775. GUID Spare2Guid;
  776. struct {
  777. PWCHAR Spare1Wcs;
  778. PWCHAR Spare2Wcs;
  779. };
  780. };
  781. #else
  782. GUID Spare2Guid;
  783. PWCHAR Spare1Wcs;
  784. PWCHAR Spare2Wcs;
  785. #endif
  786. PCHANGE_ORDER_RECORD_EXTENSION Extension; // see above.
  787. PVOID Spare2Bin;
  788. LARGE_INTEGER EventTime; // The USN Journal Entry Timestamp.
  789. USHORT FileNameLength;
  790. WCHAR FileName[MAX_PATH+1]; // The file name. (Must be Last)
  791. } CHANGE_ORDER_COMMAND, *PCHANGE_ORDER_COMMAND,
  792. CHANGE_ORDER_RECORD, *PCHANGE_ORDER_RECORD;
  793. //#define CO_PART1_OFFSET OFFSET(CHANGE_ORDER_COMMAND, SequenceNumber)
  794. //#define CO_PART1_SIZE OFFSET(CHANGE_ORDER_COMMAND, Spare1Wcs)
  795. //#define CO_PART2_OFFSET OFFSET(CHANGE_ORDER_COMMAND, Spare1Wcs)
  796. //#define CO_PART2_SIZE (4*sizeof(ULONG))
  797. //#define CO_PART3_OFFSET OFFSET(CHANGE_ORDER_COMMAND, EventTime)
  798. //#define CO_PART3_SIZE (sizeof(CHANGE_ORDER_COMMAND) - CO_PART3_OFFSET)
  799. //
  800. // The RECORD_FIELDS struct is used to build the Jet Set Column struct.
  801. //
  802. extern RECORD_FIELDS ILChangeOrderRecordFields[];
  803. extern RECORD_FIELDS OLChangeOrderRecordFields[];
  804. extern JET_SETCOLUMN ILChangeOrderJetSetCol[CHANGE_ORDER_MAX_COL];
  805. extern JET_SETCOLUMN OLChangeOrderJetSetCol[CHANGE_ORDER_MAX_COL];
  806. //
  807. // The Inbound log ChangeOrder Table index descriptions are as follows.
  808. // Note - the order of the enum and the table entries must be kept in sync.
  809. //
  810. typedef enum _ILCHANGE_ORDER_INDEX_LIST {
  811. ILSequenceNumberIndexx, // The primary index on the change order sequence number.
  812. ILFileGuidIndexx, // The index on the file object ID.
  813. ILChangeOrderGuidIndexx, // The index on the change order GUID.
  814. ILCxtionGuidCoGuidIndexx, // The 2 key index on Connection Guid and Change order Guid.
  815. ILCHANGE_ORDER_MAX_INDEX
  816. } ILCHANGE_ORDER_INDEX_LIST;
  817. //
  818. // The Outbound log ChangeOrder Table index descriptions are as follows.
  819. // Note - the order of the enum and the table entries must be kept in sync.
  820. //
  821. typedef enum _OLCHANGE_ORDER_INDEX_LIST {
  822. OLSequenceNumberIndexx, // The primary index on the change order sequence number.
  823. OLFileGuidIndexx, // The index on the file object ID.
  824. OLChangeOrderGuidIndexx, // The index on the change order GUID.
  825. OLCHANGE_ORDER_MAX_INDEX
  826. } OLCHANGE_ORDER_INDEX_LIST;
  827. extern JET_INDEXCREATE ILChangeOrderIndexDesc[];
  828. extern JET_INDEXCREATE OLChangeOrderIndexDesc[];
  829. #define SET_CO_LOCATION_CMD(_Entry_, _Field_, _Val_) \
  830. (_Entry_).Lcmd.Field._Field_ = _Val_
  831. #define GET_CO_LOCATION_CMD(_Entry_, _Field_) \
  832. (ULONG)((_Entry_).Lcmd.Field._Field_)
  833. #define CO_LOCATION_DIR 1 // Location change is for a directory
  834. #define CO_LOCATION_FILE 0 // Location change is for a file.
  835. //
  836. // Note - Any change here must be reflected in journal.c
  837. //
  838. #define FILE_NOT_IN_REPLICA_SET (-1)
  839. #define CO_LOCATION_CREATE 0 // Create a File or Dir (New FID Generated)
  840. #define CO_LOCATION_DELETE 1 // Delete a file or Dir (FID retired)
  841. #define CO_LOCATION_MOVEIN 2 // Rename into a R.S.
  842. #define CO_LOCATION_MOVEIN2 3 // Rename into a R.S. from a prev MOVEOUT
  843. #define CO_LOCATION_MOVEOUT 4 // Rename out of any R.S.
  844. #define CO_LOCATION_MOVERS 5 // Rename from one R.S. to another R.S.
  845. #define CO_LOCATION_MOVEDIR 6 // Rename from one dir to another (Same R.S.)
  846. #define CO_LOCATION_NUM_CMD 7
  847. #define CO_LOCATION_CREATE_FILENAME_MASK 0x0000006D // 0110 1101
  848. #define CO_LOCATION_REMOVE_FILENAME_MASK 0x00000072 // 0111 0010
  849. #define CO_LOCATION_NEW_FILE_IN_REPLICA 0x0000000D // 0000 1101
  850. #define CO_LOCATION_MOVEIN_FILE_IN_REPLICA 0x0000000C // 0000 1100
  851. #define CO_LOCATION_DELETE_FILENAME_MASK 0x00000012 // 0001 0010
  852. #define CO_LOCATION_MOVE_RS_OR_DIR_MASK 0x00000060 // 0110 0000
  853. #define CO_LOCATION_MOVE_OUT_RS_OR_DIR_MASK 0x00000070 // 0111 0000
  854. #define CO_LOCATION_NO_CMD CO_LOCATION_NUM_CMD
  855. //
  856. // Note: Any of the following bits being set can cause us to replicate the file.
  857. // Some of the causes such as USN_REASON_BASIC_INFO_CHANGE may not replicate if
  858. // all that has changed is the archive flag or the last access time. Currently
  859. // USN_REASON_REPARSE_POINT_CHANGE does not cause us to replciate the file
  860. // because both HSM (Hierarchical Storage Mgt) and SIS (Single Instance Store)
  861. // will turn a file record into a reparse point and migrate the physical data
  862. // elsewhere. The underlying data did not actually change. Eventually if
  863. // symbolic links come back new code will have to be added to detect this type
  864. // of reparse point and replicate the reparse point create or change. There is
  865. // no data in this case though.
  866. //
  867. #define CO_CONTENT_MASK \
  868. (USN_REASON_DATA_OVERWRITE | \
  869. USN_REASON_DATA_EXTEND | \
  870. USN_REASON_DATA_TRUNCATION | \
  871. USN_REASON_NAMED_DATA_OVERWRITE | \
  872. USN_REASON_NAMED_DATA_EXTEND | \
  873. USN_REASON_NAMED_DATA_TRUNCATION | \
  874. USN_REASON_EA_CHANGE | \
  875. USN_REASON_SECURITY_CHANGE | \
  876. USN_REASON_RENAME_OLD_NAME | \
  877. USN_REASON_RENAME_NEW_NAME | \
  878. USN_REASON_BASIC_INFO_CHANGE | \
  879. USN_REASON_COMPRESSION_CHANGE | \
  880. USN_REASON_ENCRYPTION_CHANGE | \
  881. USN_REASON_OBJECT_ID_CHANGE | \
  882. USN_REASON_STREAM_CHANGE \
  883. )
  884. #define CO_CONTENT_NEED_STAGE (CO_CONTENT_MASK & ~(0))
  885. #define CO_LOCATION_MASK \
  886. (USN_REASON_FILE_DELETE | \
  887. USN_REASON_FILE_CREATE | \
  888. USN_REASON_RENAME_NEW_NAME \
  889. )
  890. //
  891. // The following is true if this CO creates a new filename in a directory.
  892. //
  893. #define DOES_CO_CREATE_FILE_NAME(_cocmd_) \
  894. ((( 1 << (ULONG)((_cocmd_)->Lcmd.Field.Command)) & \
  895. CO_LOCATION_CREATE_FILENAME_MASK) != 0)
  896. //
  897. // The following is true if this CO removes a filename from a directory.
  898. //
  899. #define DOES_CO_REMOVE_FILE_NAME(_cocmd_) \
  900. ((( 1 << (ULONG)((_cocmd_)->Lcmd.Field.Command)) & \
  901. CO_LOCATION_REMOVE_FILENAME_MASK) != 0)
  902. //
  903. // The following is true if this CO deletes a filename from a directory.
  904. //
  905. #define DOES_CO_DELETE_FILE_NAME(_cocmd_) \
  906. ((( 1 << (ULONG)((_cocmd_)->Lcmd.Field.Command)) & \
  907. CO_LOCATION_DELETE_FILENAME_MASK) != 0)
  908. //
  909. // The following checks for a simple name change. No parent location change.
  910. //
  911. #define DOES_CO_DO_SIMPLE_RENAME(_cocmd_) ( \
  912. ((ULONG)((_cocmd_)->Lcmd.Field.Command) == CO_LOCATION_NO_CMD) && \
  913. BooleanFlagOn((_cocmd_)->ContentCmd, USN_REASON_RENAME_OLD_NAME | \
  914. USN_REASON_RENAME_NEW_NAME) \
  915. )
  916. //
  917. // The following are various predicates for testing the type of CO location cmd.
  918. //
  919. #define CO_NEW_FILE(_loc_) \
  920. ((( 1 << (_loc_)) & CO_LOCATION_NEW_FILE_IN_REPLICA) != 0)
  921. #define CO_MOVEIN_FILE(_loc_) \
  922. ((( 1 << (_loc_)) & CO_LOCATION_MOVEIN_FILE_IN_REPLICA) != 0)
  923. #define CO_DELETE_FILE(_loc_) \
  924. ((( 1 << (_loc_)) & CO_LOCATION_DELETE_FILENAME_MASK) != 0)
  925. #define CO_LOCN_CMD_IS(_co_, _Loc_) \
  926. (GET_CO_LOCATION_CMD((_co_)->Cmd, Command) == (_Loc_))
  927. #define CO_MOVE_RS_OR_DIR(_loc_) \
  928. ((( 1 << (_loc_)) & CO_LOCATION_MOVE_RS_OR_DIR_MASK) != 0)
  929. #define CO_MOVE_OUT_RS_OR_DIR(_loc_) \
  930. ((( 1 << (_loc_)) & CO_LOCATION_MOVE_OUT_RS_OR_DIR_MASK) != 0)
  931. #define CoIsDirectory(_co_) \
  932. (BooleanFlagOn((_co_)->Cmd.FileAttributes, FILE_ATTRIBUTE_DIRECTORY) || \
  933. GET_CO_LOCATION_CMD((_co_)->Cmd, DirOrFile))
  934. #define CoCmdIsDirectory(_coc_) \
  935. (BooleanFlagOn((_coc_)->FileAttributes, FILE_ATTRIBUTE_DIRECTORY) || \
  936. GET_CO_LOCATION_CMD(*(_coc_), DirOrFile))
  937. //
  938. // Change order Flags
  939. //
  940. // ** WARNING ** WARNING ** WARNING **
  941. // Code in the Inlog process retire path may overwrite these
  942. // flags after the CO is transferred into the Outlog. It may need to clear
  943. // INSTALL_INCOMPLETE or set the ABORT_CO flag. The Outlog process
  944. // currently has no need to modify these bits so this is OK. Change orders
  945. // generated during VVJoin set these flags but these change orders are never
  946. // processed by the inlog process so it will not write to their flags field.
  947. // If the Outlog process needs to write these bits code in chgorder.c must
  948. // be updated so state is not lost.
  949. //
  950. #define CO_FLAG_ABORT_CO 0x00000001 // Set when CO is being aborted
  951. #define CO_FLAG_VV_ACTIVATED 0x00000002 // Set when VV activate req is made.
  952. #define CO_FLAG_CONTENT_CMD 0x00000004 // Valid content command
  953. #define CO_FLAG_LOCATION_CMD 0x00000008 // valid location command
  954. #define CO_FLAG_ONLIST 0x00000010 // On a change order process list.
  955. #define CO_FLAG_LOCALCO 0x00000020 // CO is a locally generated.
  956. #define CO_FLAG_RETRY 0x00000040 // CO needs to retry.
  957. #define CO_FLAG_INSTALL_INCOMPLETE 0x00000080 // Local install not completed.
  958. #define CO_FLAG_REFRESH 0x00000100 // CO is an upstream originated file refresh request.
  959. #define CO_FLAG_OUT_OF_ORDER 0x00000200 // Don't check/update version vector
  960. #define CO_FLAG_NEW_FILE 0x00000400 // If CO fails, delete IDTable entry.
  961. #define CO_FLAG_FILE_USN_VALID 0x00000800 // CO FileUsn is valid.
  962. #define CO_FLAG_CONTROL 0x00001000 // This is a Control CO (see below)
  963. #define CO_FLAG_DIRECTED_CO 0x00002000 // This CO is directed to a single connection.
  964. #define CO_FLAG_UNUSED4000 0x00004000 // This CO is a reanimation request.
  965. #define CO_FLAG_UNUSED8000 0x00008000 // This CO is for a reanimated parent.
  966. #define CO_FLAG_UNUSED10000 0x00010000 // This CO has previously requested
  967. // reanimation of its parent.
  968. #define CO_FLAG_DEMAND_REFRESH 0x00020000 // CO is a downstream demand for refresh.
  969. #define CO_FLAG_VVJOIN_TO_ORIG 0x00040000 // CO is from vvjoin to originator
  970. #define CO_FLAG_MORPH_GEN 0x00080000 // CO generated as part of name morph resolution
  971. #define CO_FLAG_SKIP_ORIG_REC_CHK 0x00100000 // Skip originator reconcile check
  972. #define CO_FLAG_MOVEIN_GEN 0x00200000 // This CO was gened as part of a sub-dir MOVEIN.
  973. #define CO_FLAG_MORPH_GEN_LEADER 0x00400000 // This is a MorphGenLeader and it needs to
  974. // refabricate the MorphGenFollower if it's retried.
  975. #define CO_FLAG_JUST_OID_RESET 0x00800000 // All CO did was reset OID back to FRS defined value.
  976. #define CO_FLAG_COMPRESSED_STAGE 0x01000000 // The stage file for this CO is compressed.
  977. //
  978. // Control Change Order Function Codes (passed in the ContentCmd field)
  979. //
  980. #define FCN_CORETRY_LOCAL_ONLY 0x1
  981. #define FCN_CORETRY_ONE_CXTION 0x2
  982. #define FCN_CORETRY_ALL_CXTIONS 0x3
  983. #define FCN_CO_NORMAL_VVJOIN_TERM 0x4
  984. #define FCN_CO_ABNORMAL_VVJOIN_TERM 0x5
  985. #define FCN_CO_END_OF_JOIN 0x6
  986. //
  987. // Flag group for testing any type of refresh request.
  988. //
  989. #define CO_FLAG_GROUP_ANY_REFRESH (CO_FLAG_DEMAND_REFRESH | CO_FLAG_REFRESH)
  990. //
  991. // Flags that are only valid locally; they should be cleared by the
  992. // machine that receives the remote change order before inserting
  993. // the remote change order into the change order stream.
  994. //
  995. #define CO_FLAG_NOT_REMOTELY_VALID (CO_FLAG_ABORT_CO | \
  996. CO_FLAG_VV_ACTIVATED | \
  997. CO_FLAG_ONLIST | \
  998. CO_FLAG_MORPH_GEN | \
  999. CO_FLAG_MORPH_GEN_LEADER | \
  1000. CO_FLAG_MOVEIN_GEN | \
  1001. CO_FLAG_RETRY | \
  1002. CO_FLAG_LOCALCO | \
  1003. CO_FLAG_INSTALL_INCOMPLETE)
  1004. //
  1005. // The following group of flags are cleared before the Change Order is inserted
  1006. // in the Outbound Log. When the CO is propagated they would confuse the
  1007. // outbound partner.
  1008. //
  1009. #define CO_FLAG_GROUP_OL_CLEAR (CO_FLAG_ABORT_CO | \
  1010. CO_FLAG_VV_ACTIVATED | \
  1011. CO_FLAG_ONLIST | \
  1012. CO_FLAG_MORPH_GEN | \
  1013. CO_FLAG_MORPH_GEN_LEADER | \
  1014. CO_FLAG_MOVEIN_GEN | \
  1015. CO_FLAG_RETRY | \
  1016. CO_FLAG_NEW_FILE)
  1017. //
  1018. // The following group of flags are used to create a reanimation change order
  1019. // to fetch a deleted parent dir for our inbound partner.
  1020. // - It is a create CO,
  1021. // - demand refresh keeps it from propagating to outlog and keeps us
  1022. // from reserving a VV retire slot since no ACK or VV update is needed,
  1023. // - directed means inbound partner sends it only to us (not really
  1024. // needed but makes it coinsistent),
  1025. // - out-of-order lets it pass VV checks,
  1026. // - onlist means it is on the change order process queue (or will be soon),
  1027. // - this is a reanimation CO (in COE_FLAGS...),
  1028. // - and this is a parent reanimation CO so it does not go into the inlog
  1029. // since it will be regenerated as needed if the base CO fails and has to
  1030. // be retried (in COE_FLAGS...).
  1031. //
  1032. #define CO_FLAG_GROUP_RAISE_DEAD_PARENT (CO_FLAG_LOCATION_CMD | \
  1033. CO_FLAG_DEMAND_REFRESH | \
  1034. CO_FLAG_DIRECTED_CO | \
  1035. CO_FLAG_OUT_OF_ORDER | \
  1036. CO_FLAG_ONLIST)
  1037. #define COC_FLAG_ON(_COC_, _F_) (BooleanFlagOn((_COC_)->Flags, (_F_)))
  1038. #define CO_FLAG_ON(_COE_, _F_) (BooleanFlagOn((_COE_)->Cmd.Flags, (_F_)))
  1039. #define SET_CO_FLAG(_COE_, _F_) SetFlag((_COE_)->Cmd.Flags, (_F_))
  1040. #define SET_COC_FLAG(_COC_, _F_) SetFlag((_COC_)->Flags, (_F_))
  1041. #define CLEAR_CO_FLAG(_COE_, _F_) ClearFlag((_COE_)->Cmd.Flags, (_F_))
  1042. #define CLEAR_COC_FLAG(_COC_, _F_) ClearFlag((_COC_)->Flags, (_F_))
  1043. //
  1044. // The interlocked flags word is used to hold change order flags that could
  1045. // be accessed by multiple threads. They must be set and cleared using
  1046. // the interlock macros SET_FLAG_INTERLOCKED and CLEAR_FLAG_INTERLOCKED.
  1047. // A crit sec may still be needed if the bits must remain stable during
  1048. // some period of time. But using the interlock macros by all threads
  1049. // ensures that no bit changes are lost even without a critsec.
  1050. //
  1051. #define CO_IFLAG_VVRETIRE_EXEC 0x00000001 // VV retire has been executed.
  1052. #define CO_IFLAG_CO_ABORT 0x00000002 // CO has been aborted
  1053. #define CO_IFLAG_DIR_ENUM_PENDING 0x00000004 // This CO needs to enumerate it's
  1054. // children as part of a sub-dir MOVEIN.
  1055. //
  1056. // The following IFlags are cleared before the CO is sent to an outbound
  1057. // partner. See Outlog.c
  1058. //
  1059. #define CO_IFLAG_GROUP_OL_CLEAR (CO_IFLAG_VVRETIRE_EXEC | \
  1060. CO_IFLAG_DIR_ENUM_PENDING)
  1061. #define CO_IFLAG_ON(_COE_, _F_) (BooleanFlagOn((_COE_)->Cmd.IFlags, (_F_)))
  1062. #define SET_CO_IFLAG(_COE_, _F_) \
  1063. SET_FLAG_INTERLOCKED(&(_COE_)->Cmd.IFlags, (_F_))
  1064. #define CLEAR_CO_IFLAG(_COE_, _F_) \
  1065. CLEAR_FLAG_INTERLOCKED(&(_COE_)->Cmd.IFlags, (_F_))
  1066. // As the change order progresses we update the current state in the
  1067. // change order entry in Jet at points where we need to preserve persistence.
  1068. // Inbound Change Order Stages:
  1069. // ** WARNING ** The order matters for compares.
  1070. // E.g., RcsCmdPktCompletionRoutine in replica.c
  1071. // *** update name list in Chgorder.c if any changes here.
  1072. // ** WARNING ** If you change these values be sure that the new code
  1073. // will work on a pre-existing database with the OLD VALUES.
  1074. // If the number of states goes past 32 then some of the macros which
  1075. // build a mask of state bits won't work. See below.
  1076. #define IBCO_INITIALIZING (0) // Initial state when CO is first put in log.
  1077. #define IBCO_STAGING_REQUESTED (1) // Alloc staging file space for local CO
  1078. #define IBCO_STAGING_INITIATED (2) // LocalCO Staging file copy has started
  1079. #define IBCO_STAGING_COMPLETE (3) // LocalCO Staging file complete
  1080. // At this point prelim accept rechecked and
  1081. // becomes either final accept of abort.
  1082. // Abort is caused by more recent local change.
  1083. #define IBCO_STAGING_RETRY (4) // Waiting to retry local CO stage file generation.
  1084. #define IBCO_FETCH_REQUESTED (5) // Alloc staging file space for remote co
  1085. #define IBCO_FETCH_INITIATED (6) // RemoteCO staging file fetch has started
  1086. #define IBCO_FETCH_COMPLETE (7) // RemoteCO Staging file fetch complete
  1087. #define IBCO_FETCH_RETRY (8) // Waiting to retry remote CO stage file fetch
  1088. #define IBCO_INSTALL_REQUESTED (9) // File install requested
  1089. #define IBCO_INSTALL_INITIATED (10) // File install has started
  1090. #define IBCO_INSTALL_COMPLETE (11) // File install is complete
  1091. #define IBCO_INSTALL_WAIT (12) // File install is waiting to try again.
  1092. #define IBCO_INSTALL_RETRY (13) // File install is retrying.
  1093. #define IBCO_INSTALL_REN_RETRY (14) // File install rename is retrying.
  1094. #define IBCO_INSTALL_DEL_RETRY (15) // File install delete is retrying.
  1095. #define IBCO_UNUSED_16 (16) // Unused state
  1096. #define IBCO_UNUSED_17 (17) // Unused state
  1097. #define IBCO_UNUSED_18 (18) // Unused state
  1098. #define IBCO_ENUM_REQUESTED (19) // CO is being recycled to do a dir enum.
  1099. #define IBCO_OUTBOUND_REQUEST (20) // Request outbound propagaion
  1100. #define IBCO_OUTBOUND_ACCEPTED (21) // Request accepted and now in Outbound log
  1101. #define IBCO_COMMIT_STARTED (22) // DB state update started.
  1102. #define IBCO_RETIRE_STARTED (23) // DB state update done, freeing change order.
  1103. #define IBCO_ABORTING (24) // CO is being aborted.
  1104. #define IBCO_MAX_STATE (24)
  1105. extern PCHAR IbcoStateNames[IBCO_MAX_STATE+1];
  1106. #define CO_STATE(_Entry_) ((_Entry_)->Cmd.State)
  1107. #define CO_STATE_IS(_Entry_, _State_) ((_Entry_)->Cmd.State == (_State_))
  1108. #define CO_STATE_IS_LE(_Entry_, _State_) ((_Entry_)->Cmd.State <= (_State_))
  1109. #define PRINT_CO_STATE(_Entry_) IbcoStateNames[CO_STATE(_Entry_)]
  1110. #define PRINT_COCMD_STATE(_Entry_) IbcoStateNames[(_Entry_)->State]
  1111. #define SAVE_CHANGE_ORDER_STATE(_Entry_, _Save_, _Flags_) \
  1112. _Save_ = ((_Entry_)->Cmd.State); \
  1113. _Flags_ = ((_Entry_)->Cmd.Flags);
  1114. #define RESTORE_CHANGE_ORDER_STATE(_Entry_, _Save_, _Flags_) \
  1115. (_Entry_)->Cmd.State = (_Save_); \
  1116. (_Entry_)->Cmd.Flags = (_Flags_);
  1117. #define CO_STATE_IS_INSTALL_RETRY(_co_) \
  1118. (0 != ((1 << CO_STATE(_co_)) & ((1 << IBCO_INSTALL_RETRY) | \
  1119. (1 << IBCO_INSTALL_REN_RETRY) | \
  1120. (1 << IBCO_INSTALL_DEL_RETRY))))
  1121. #define CO_STATE_IS_REMOTE_RETRY(_co_) \
  1122. (CO_STATE_IS(_co_, IBCO_FETCH_RETRY) || \
  1123. CO_STATE_IS_INSTALL_RETRY(_co_))
  1124. #define CO_STATE_IS_LOCAL_RETRY(_co_) \
  1125. (0 != ((1 << CO_STATE(_co_)) & (1 << IBCO_STAGING_RETRY)))
  1126. //
  1127. // Macro to update state field of change order and log the event.
  1128. //
  1129. #define SET_CHANGE_ORDER_STATE_CMD(_cmd_, _state_) \
  1130. { \
  1131. (_cmd_)->State = (_state_); \
  1132. CHANGE_ORDER_COMMAND_TRACE(3, (_cmd_), PRINT_COCMD_STATE(_cmd_)); \
  1133. \
  1134. }
  1135. #define SET_CHANGE_ORDER_STATE(_coe_, _state_) \
  1136. (_coe_)->Cmd.State = (_state_); \
  1137. CHANGE_ORDER_TRACE(3, (_coe_), PRINT_CO_STATE(_coe_));
  1138. /******************************************************************************
  1139. *******************************************************************************
  1140. ** **
  1141. ** **
  1142. ** D i r T a b l e **
  1143. ** **
  1144. ** **
  1145. *******************************************************************************
  1146. ******************************************************************************/
  1147. //
  1148. // The DirTable column descriptions are as follows. Note - the order of the
  1149. // enum and the table entries must be kept in sync.
  1150. //
  1151. // The DirTable is a per-replica table. It is used by the USN Journal process
  1152. // to determine if a file on a given volume is in a replica set. When the
  1153. // Journal process is initialized the table is loaded into the inmemory
  1154. // volume filter table so we can quickly determine if the file is in a
  1155. // replica tree and if so, which one.
  1156. //
  1157. typedef enum _DIRTABLE_COL_LIST {
  1158. DFileGuidx = 0, // The guid assigned to the Dir
  1159. DFileIDx, // The local NTFS volume file ID.
  1160. DParentFileIDx, // The file ID of the parent directory
  1161. DReplicaNumberx, // The replica set number (integer, for suffix on table names).
  1162. DFileNamex, // The file name part, no dir prefix. (UNICODE)
  1163. DIRTABLE_MAX_COL
  1164. } DIRTABLE_COL_LIST;
  1165. extern JET_COLUMNCREATE DIRTableColDesc[];
  1166. //
  1167. // DIRTable record definition.
  1168. //
  1169. //
  1170. // Note: Buffers are allocated at runtime to hold data for fields with
  1171. // a ColMaxWidth greater than sizeof(PVOID) where the field def in the corresponding
  1172. // record struct is sizeof(PVOID) (i.e. it holds a pointer). For fields where the
  1173. // ColMaxWidth equals the field size in the record struct the data is in the
  1174. // record struct and no buffer is allocated.
  1175. //
  1176. // WARNING: If anything changes here make the corresponding change to
  1177. // FILTER_TABLE_ENTRY in journal.c
  1178. //
  1179. typedef struct _DIRTABLE_RECORD {
  1180. GUID DFileGuid;
  1181. LONGLONG DFileID;
  1182. LONGLONG DParentFileID;
  1183. ULONG DReplicaNumber;
  1184. WCHAR DFileName[MAX_PATH+1];
  1185. } DIRTABLE_RECORD, *PDIRTABLE_RECORD;
  1186. //
  1187. // The RECORD_FIELDS struct is used to build the Jet Set Column struct.
  1188. //
  1189. extern RECORD_FIELDS DIRTableRecordFields[];
  1190. extern JET_SETCOLUMN DIRTableJetSetCol[DIRTABLE_MAX_COL];
  1191. //
  1192. // The DIRTable index descriptions are as follows. Note - the order of the
  1193. // enum and the table entries must be kept in sync.
  1194. //
  1195. typedef enum _DIRTABLE_INDEX_LIST {
  1196. DFileGuidIndexx = 0, // The index on the file GUID.
  1197. DFileIDIndexx, // The index on the file ID.
  1198. DIRTABLE_MAX_INDEX
  1199. } DIRTABLE_INDEX_LIST;
  1200. extern JET_INDEXCREATE DIRTableIndexDesc[];
  1201. /******************************************************************************
  1202. *******************************************************************************
  1203. ** **
  1204. ** **
  1205. ** I D T a b l e **
  1206. ** **
  1207. ** **
  1208. *******************************************************************************
  1209. ******************************************************************************/
  1210. //
  1211. // The IDTable column descriptions are as follows. Note - the order of the
  1212. // enum and the table entries must be kept in sync.
  1213. //
  1214. // Perf: Consider breaking out the data that changes less frequently from the
  1215. // rest of the data. For example, fileguid, fileid, parentguid, parentid,
  1216. // file name, fileobjid, Flags, replenabled and fileisdir
  1217. // probably don't change often. These could
  1218. // be in a different table with an autoinc column whose value is used to index
  1219. // a second table with the more volatile data.
  1220. //
  1221. // Perf: Also think about breaking up the tables based on the data accessed or
  1222. // modified by the different threads so as to minimize lock contention.
  1223. typedef enum _IDTABLE_COL_LIST {
  1224. FileGuidx = 0, // The guid assigned to the file.
  1225. FileIDx, // The local NTFS volume file ID.
  1226. ParentGuidx, // The guid of the parent directory
  1227. ParentFileIDx, // The file ID of the parent directory
  1228. VersionNumberx, // The version number of the file, bumped on close.
  1229. EventTimex, // The event time from the USN Journal entry.
  1230. OriginatorGuidx, // The GUID of the member that originated the last file update.
  1231. OriginatorVSNx, // The USN number of the originating member.
  1232. CurrentFileUsnx, // The close USN of the last modify to the file.
  1233. FileCreateTimex, // The file create time.
  1234. FileWriteTimex, // The file last write time.
  1235. FileSizex, // The file size.
  1236. FileObjIDx, // The file object ID (guid part matches our FileGuid).
  1237. FileNamex, // The file name part, no dir prefix. (UNICODE)
  1238. FileIsDirx, // True if the file is a directory.
  1239. FileAttributesx, // The file attributes.
  1240. Flagsx, // File is deleted, create deleted, etc. This is a tombstone.
  1241. ReplEnabledx, // True if replication is enabled for this file/dir.
  1242. TombStoneGCx, // Tombstone expiration / Garbage Collection time.
  1243. OutLogSeqNumx, // The sequence number of most recent CO inserted into OutLog.
  1244. IdtSpare1Ullx, // Spare Ulonglong
  1245. IdtSpare2Ullx, // Spare Ulonglong
  1246. IdtSpare1Guidx, // Spare Guid
  1247. IdtSpare2Guidx, // Spare Guid
  1248. IdtSpare1Wcsx, // Spare wide char
  1249. IdtSpare2Wcsx, // Spare wide char
  1250. IdtExtensionx, // IDTable Extension Field
  1251. IdtSpare2Binx, // Spare binary blob
  1252. IDTABLE_MAX_COL
  1253. } IDTABLE_COL_LIST;
  1254. extern JET_COLUMNCREATE IDTableColDesc[];
  1255. //
  1256. // IDTable record definition.
  1257. //
  1258. //
  1259. // Note: Buffers are allocated at runtime to hold data for fields with
  1260. // a ColMaxWidth greater than sizeof(PVOID) where the field def in the corresponding
  1261. // record struct is sizeof(PVOID) (i.e. it holds a pointer). For fields where the
  1262. // ColMaxWidth equals the field size in the record struct the data is in the
  1263. // record struct and no buffer is allocated.
  1264. //
  1265. #if 0
  1266. // Note: Consider using tagged data in jet so the external world just picks up
  1267. // the version element specific to the given type of change order
  1268. // Each file component that can be independently updated needs its own version
  1269. // info to drive reconcilliation. Currently there are only two such components,
  1270. // (1) The data and (2) the non-data.
  1271. //
  1272. typedef struct _IDTABLE_OBJECT_VERSION_ {
  1273. ULONG VersionNumber;
  1274. LONGLONG EventTime;
  1275. GUID OriginatorGuid;
  1276. ULONGLONG OriginatorVSN;
  1277. } IDTABLE_OBJECT_VERSION, *PIDTABLE_OBJECT_VERSION
  1278. #define IDT_OBJECT_DATA 0
  1279. #define IDT_OBJECT_NONDATA 1
  1280. #define MAX_IDTABLE_OBJECTS 2
  1281. #define IdtDataVersionNumber(_rec_) ((_rec_)->OV[IDT_OBJECT_DATA].VersionNumber)
  1282. #define IdtDataEventTime(_rec_) ((_rec_)->OV[IDT_OBJECT_DATA].EventTime)
  1283. #define IdtDataOriginatorGuid(_rec_) ((_rec_)->OV[IDT_OBJECT_DATA].OriginatorGuid)
  1284. #define IdtDataOriginatorVSN(_rec_) ((_rec_)->OV[IDT_OBJECT_DATA].OriginatorVSN)
  1285. #define IdtNonDataVersionNumber(_rec_) ((_rec_)->OV[IDT_OBJECT_NONDATA].VersionNumber)
  1286. #define IdtNonDataEventTime(_rec_) ((_rec_)->OV[IDT_OBJECT_NONDATA].EventTime)
  1287. #define IdtNonDataOriginatorGuid(_rec_) ((_rec_)->OV[IDT_OBJECT_NONDATA].OriginatorGuid)
  1288. #define IdtNonDataOriginatorVSN(_rec_) ((_rec_)->OV[IDT_OBJECT_NONDATA].OriginatorVSN)
  1289. #define IdtVersionNumber(_rec_, _x_) ((_rec_)->OV[(_x_)].VersionNumber)
  1290. #define IdtEventTime(_rec_, _x_) ((_rec_)->OV[(_x_)].EventTime)
  1291. #define IdtOriginatorGuid(_rec_, _x_) ((_rec_)->OV[(_x_)].OriginatorGuid)
  1292. #define IdtOriginatorVSN(_rec_, _x_) ((_rec_)->OV[(_x_)].OriginatorVSN)
  1293. #endif
  1294. //
  1295. // The Data Extension Field for the IDTable Record.
  1296. //
  1297. // This field has a fixed Size buffer with var len data. For backward compat
  1298. // with older databases NEVER shrink the size of this struct.
  1299. // DbsFieldDataSize in createdb.c for details.
  1300. //
  1301. typedef struct _IDTABLE_RECORD_EXTENSION_ {
  1302. ULONG FieldSize;
  1303. USHORT Major;
  1304. USHORT OffsetCount;
  1305. //
  1306. // use offsets from the base of the struct to each component so we avoid
  1307. // problems with alignement packing.
  1308. //
  1309. ULONG Offset[1]; // Offsets to data components.
  1310. ULONG OffsetLast; // The last offset is always zero.
  1311. DATA_EXTENSION_CHECKSUM DataChecksum;
  1312. // Add new components in here.
  1313. } IDTABLE_RECORD_EXTENSION, *PIDTABLE_RECORD_EXTENSION;
  1314. typedef struct _IDTABLE_RECORD {
  1315. GUID FileGuid;
  1316. LONGLONG FileID;
  1317. GUID ParentGuid;
  1318. LONGLONG ParentFileID;
  1319. // IDTABLE_OBJECT_VERSION OV[MAX_IDTABLE_OBJECTS];
  1320. ULONG VersionNumber;
  1321. LONGLONG EventTime;
  1322. GUID OriginatorGuid;
  1323. ULONGLONG OriginatorVSN;
  1324. USN CurrentFileUsn;
  1325. LARGE_INTEGER FileCreateTime;
  1326. LARGE_INTEGER FileWriteTime;
  1327. ULONGLONG FileSize;
  1328. FILE_OBJECTID_BUFFER FileObjID;
  1329. WCHAR FileName[MAX_PATH+1];
  1330. BOOL FileIsDir;
  1331. ULONG FileAttributes;
  1332. ULONG Flags;
  1333. BOOL ReplEnabled;
  1334. FILETIME TombStoneGC;
  1335. ULONGLONG OutLogSeqNum;
  1336. ULONGLONG Spare1Ull;
  1337. ULONGLONG Spare2Ull;
  1338. GUID Spare1Guid;
  1339. GUID Spare2Guid;
  1340. PWCHAR Spare1Wcs;
  1341. PWCHAR Spare2Wcs;
  1342. IDTABLE_RECORD_EXTENSION Extension; // See above
  1343. PVOID Spare2Bin;
  1344. } IDTABLE_RECORD, *PIDTABLE_RECORD;
  1345. //
  1346. // IDTable Record Flags -
  1347. //
  1348. // IDREC_FLAGS_DELETE_DEFERRED:
  1349. //
  1350. // Deferred delete deals with the resolution of a delete dir on one member while
  1351. // a second member simultaneously creates a child file or dir. With the
  1352. // previous solution (see below) the delete dir gets stuck in a retry loop (AND
  1353. // the unjoin prevents us from sending the ACK so the partner resends the CO at
  1354. // rejoin anyway). To resolve this the delete dir must be able to determine if
  1355. // there are currently any valid children when we get a dir_not_empty return
  1356. // status while executing the delete dir. If there are valid children then the
  1357. // delete dir loses and gets aborted. If there are no valid children the dir
  1358. // gets marked as deleted with deferred delete set and is sent to retry so it
  1359. // can finally get a shot at deleting the dir.
  1360. //
  1361. // We can get into this situation in one of two ways:
  1362. // (1) A sharing violation prevented the prior deletion of a child under the
  1363. // dir in question. The child delete was sent to retry. Then the parent
  1364. // dir delete arrived and failed with dir_not_empty.
  1365. //
  1366. // (2) A new child file was created just before the delete for the parent
  1367. // arrived. There is no delete pending for the second case so the parent
  1368. // delete dir should be aborted. (The parent dir is reanimated on other
  1369. // members where parent delete dir arrived first. The arrival of the child
  1370. // create triggers the parent reanimation.)
  1371. //
  1372. // For the first case, the sharing violation on the child sent the delete
  1373. // change order to retry but delete deferred is set for the file so when the
  1374. // parent delete dir arrives it will find no valid children and it, in turn,
  1375. // sets delete deferred on the parent.
  1376. //
  1377. // The previous solution was to unjoin the connection when the delete dir
  1378. // failed. This forced the change order stream arriving from that connection
  1379. // through retry which is later resubmitted in order. But this doesn't work for
  1380. // case (2) above because no delete for the child will be forthcoming. Using
  1381. // deferred delete solves this and in addition it eliminates the problem of
  1382. // spurious name morph conflicts if a conflicting dir create were to arrive from
  1383. // another connection. This would occur in case (1) above where the parent
  1384. // delete dir is in retry because of the sharing violation on the child. Since
  1385. // the dir name is still in use, the arrival of a new dir create with the same
  1386. // name would cause an unintended name morph collision.
  1387. //
  1388. #define IDREC_FLAGS_DELETED 0x00000001
  1389. #define IDREC_FLAGS_CREATE_DEFERRED 0x00000002
  1390. #define IDREC_FLAGS_DELETE_DEFERRED 0x00000004
  1391. #define IDREC_FLAGS_RENAME_DEFERRED 0x00000008
  1392. #define IDREC_FLAGS_NEW_FILE_IN_PROGRESS 0x00000010
  1393. #define IDREC_FLAGS_ENUM_PENDING 0x00000020
  1394. #define IDREC_FLAGS_ALL 0xFFFFFFFF
  1395. #define IsIdRecFlagSet(_p_, _f_) BooleanFlagOn((_p_)->Flags, (_f_))
  1396. #define SetIdRecFlag(_p_, _f_) SetFlag( (_p_)->Flags, (_f_))
  1397. #define ClearIdRecFlag(_p_, _f_) ClearFlag( (_p_)->Flags, (_f_))
  1398. #define IDTRecIsDirectory(_idrec_) \
  1399. (BooleanFlagOn((_idrec_)->FileAttributes, FILE_ATTRIBUTE_DIRECTORY) || \
  1400. (_idrec_)->FileIsDir)
  1401. //
  1402. // The RECORD_FIELDS struct is used to build the Jet Set Column struct.
  1403. //
  1404. extern RECORD_FIELDS IDTableRecordFields[];
  1405. extern JET_SETCOLUMN IDTableJetSetCol[IDTABLE_MAX_COL];
  1406. //
  1407. // The IDTable index descriptions are as follows. Note - the order of the
  1408. // enum and the table entries must be kept in sync.
  1409. //
  1410. typedef enum _IDTABLE_INDEX_LIST {
  1411. GuidIndexx = 0, // The index on the file GUID.
  1412. FileIDIndexx, // The index on the file ID.
  1413. ParGuidFileNameIndexx, // The index on the parent Guid and the file name.
  1414. IDTABLE_MAX_INDEX
  1415. } IDTABLE_INDEX_LIST;
  1416. extern JET_INDEXCREATE IDTableIndexDesc[];
  1417. /******************************************************************************
  1418. *******************************************************************************
  1419. ** **
  1420. ** **
  1421. ** V V T a b l e **
  1422. ** **
  1423. ** **
  1424. *******************************************************************************
  1425. ******************************************************************************/
  1426. //
  1427. // The VVTable column descriptions are as follows. Note - the order of the
  1428. // enum and the table entries must be kept in sync.
  1429. //
  1430. // The Version Vector Table (VVTable) is a per-Replica table.
  1431. // It is used by the replication service to dampen propagation of updates
  1432. // to replicas that already are up to date. There is one entry per member of
  1433. // the replica set. Each entry has the GUID of the originating member and
  1434. // the Volume Sequence Number (VSN) of the most recent change this member has
  1435. // seen from that member.
  1436. //
  1437. typedef enum _VVTABLE_COL_LIST {
  1438. VVOriginatorGuidx = 0, // The replica set member Guid.
  1439. VVOriginatorVsnx, // The VSN of the most recent change from this member.
  1440. VVSpare1Ullx,
  1441. VVSpare2Ullx,
  1442. VVTABLE_MAX_COL
  1443. } VVTABLE_COL_LIST;
  1444. extern JET_COLUMNCREATE VVTableColDesc[];
  1445. //
  1446. // VVTable record definition.
  1447. //
  1448. //
  1449. // Note: Buffers are allocated at runtime to hold data for fields with
  1450. // a ColMaxWidth greater than sizeof(PVOID) where the field def in the corresponding
  1451. // record struct is sizeof(PVOID) (i.e. it holds a pointer). For fields where the
  1452. // ColMaxWidth equals the field size in the record struct the data is in the
  1453. // record struct and no buffer is allocated.
  1454. //
  1455. //
  1456. typedef struct _VVTABLE_RECORD {
  1457. GUID VVOriginatorGuid;
  1458. ULONGLONG VVOriginatorVsn;
  1459. ULONGLONG Spare1Ull;
  1460. ULONGLONG Spare2Ull;
  1461. } VVTABLE_RECORD, *PVVTABLE_RECORD;
  1462. //
  1463. // The RECORD_FIELDS struct is used to build the Jet Set Column struct.
  1464. //
  1465. extern RECORD_FIELDS VVTableRecordFields[];
  1466. extern JET_SETCOLUMN VVTableJetSetCol[VVTABLE_MAX_COL];
  1467. //
  1468. // The VVTable index descriptions are as follows. Note - the order of the
  1469. // enum and the table entries must be kept in sync.
  1470. //
  1471. typedef enum _VVTABLE_INDEX_LIST {
  1472. VVOriginatorGuidIndexx, // The index on the originator Guid.
  1473. VVTABLE_MAX_INDEX
  1474. } VVTABLE_INDEX_LIST;
  1475. extern JET_INDEXCREATE VVTableIndexDesc[];
  1476. /******************************************************************************
  1477. *******************************************************************************
  1478. ** **
  1479. ** **
  1480. ** R E P L I C A S E T C O N F I G T A B L E **
  1481. ** **
  1482. ** **
  1483. *******************************************************************************
  1484. ******************************************************************************/
  1485. //
  1486. //
  1487. //
  1488. // There is only one config table in the database. Each row in the table
  1489. // describes the configuration info for a single replica set.
  1490. //
  1491. // Jet is limited in the number if databases that can be open at one time to
  1492. // about 5. The limit on open tables is much larger and is configurable.
  1493. // As a result instead of having a single database per replica set all replica
  1494. // sets must use the same database. We use a replica set table indexed by the
  1495. // replica set GUID to tell us which group of tables is used to manage that
  1496. // replica set.
  1497. // What should go in registry and what should go in jet Table?
  1498. // The registry must have the path to the jet database area.
  1499. // Time DB was created.
  1500. // Time DB was last verified.
  1501. // Time DB was last compacted.
  1502. // Time DB was last backed up.
  1503. // DS Polling interval
  1504. // Local machine name and guid
  1505. // Jet parameters like max number of open tables.
  1506. //
  1507. // Maybe just put stuff in registry that we need if Jet Table is corrupted.
  1508. // Need to be able to tell if JDB is a diff version from the one that we
  1509. // used when we last ran by comparing state in a reg key. This way we know
  1510. // to go thru VERIFICATION. (content and FID checking) If the replica tree
  1511. // was just copied or restored from backup all the FIDs can be different.
  1512. // We need a way to check this. Perhaps if we save the Volume USN at last
  1513. // shutdown (or periodically in case of dirty shutdown) we can use this as
  1514. // a hint to do a VERIFICATION. The saved vol USN also tells us if we missed
  1515. // volume activity while FRS was not running.
  1516. //
  1517. // If any of the following consistency checks fail then we do a full
  1518. // VERIFICATION between the files and the DB entries for the replication set.
  1519. //
  1520. // NTFS Vol ID - to check for a restore that makes the fids wrong.
  1521. // NTFS Volume Guid
  1522. // NTFS Volume USN Checkpoint -- to see if we missed USN records.
  1523. //
  1524. //typedef struct _FILE_FS_VOLUME_INFORMATION {
  1525. // LARGE_INTEGER VolumeCreationTime;
  1526. // ULONG VolumeSerialNumber;
  1527. // ULONG VolumeLabelLength;
  1528. // BOOLEAN SupportsObjects;
  1529. // WCHAR VolumeLabel[1];
  1530. //} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
  1531. //
  1532. // Registry Sequence Number -- to sanity check DB
  1533. // RootPath of replica tree -- If this changes we need to check fids.
  1534. // Inbound partner state (name, guid, connect info & status of last connect, last time repl occurred, stats, comm protocol)
  1535. // Resource stats (disk space used/free, disk I/Os, DB space used/free, memory, error counts, #times update was blocked);
  1536. // ********************************************************
  1537. // On all binary structs include a rev level and a size.
  1538. // Also include a rev level on the table defs.
  1539. // (**) config params that are service wide are only present in the
  1540. // system init '<init>' record.
  1541. // ********************************************************
  1542. //
  1543. //
  1544. // Definition of the Jet System Parameters. Each entry consists of a Jet
  1545. // defined parameter code and either a long or a string argument. The ParamType
  1546. // tells which. If a long the value is in ParamValue. If a string the value
  1547. // is an offset from the base of the struct to the start of the string.
  1548. // The strings are stored at the end of the struct.
  1549. //
  1550. #define MAX_JET_SYSTEM_PARAMS 38
  1551. #define JPARAM_TYPE_LAST 0xf0f0f0f0
  1552. #define JPARAM_TYPE_LONG 1
  1553. #define JPARAM_TYPE_STRING 2
  1554. #define JPARAM_TYPE_SKIP 3
  1555. typedef struct _JET_PARAM_ENTRY {
  1556. CHAR ParamName[24];
  1557. ULONG ParamId;
  1558. ULONG ParamType;
  1559. ULONG ParamValue;
  1560. } JET_PARAM_ENTRY, *PJET_PARAM_ENTRY;
  1561. typedef struct _JET_SYSTEM_PARAMS {
  1562. ULONG Size;
  1563. JET_PARAM_ENTRY ParamEntry[MAX_JET_SYSTEM_PARAMS];
  1564. CHAR ChkPointFilePath[MAX_PATH];
  1565. CHAR TempFilePath[MAX_PATH];
  1566. CHAR LogFilePath[MAX_PATH];
  1567. CHAR EventSource[20];
  1568. } JET_SYSTEM_PARAMS, *PJET_SYSTEM_PARAMS;
  1569. typedef struct _CHANGE_ORDER_STATS {
  1570. ULONGLONG NumCoIssued;
  1571. ULONGLONG NumCoRetired;
  1572. ULONGLONG NumCoAborts;
  1573. ULONGLONG NumCoStageGenReq;
  1574. ULONGLONG NumCoStageGenBytes;
  1575. ULONGLONG NumCoStageRetries;
  1576. ULONGLONG NumCoFetchReq;
  1577. ULONGLONG NumCoFetchBytes;
  1578. ULONGLONG NumCoFetchRetries;
  1579. ULONGLONG NumCoInstallRetries;
  1580. ULONGLONG NumFilesUpdated;
  1581. ULONGLONG NumInCoDampened;
  1582. ULONGLONG NumOutCoDampened;
  1583. ULONGLONG NumCoPropagated;
  1584. } CHANGE_ORDER_STATS, *PCHANGE_ORDER_STATS;
  1585. typedef struct _COMM_STATS {
  1586. ULONGLONG NumCoCmdPktsSent;
  1587. ULONGLONG NumCoCmdBytesSent;
  1588. ULONGLONG NumCoCmdPktsRcvd;
  1589. ULONGLONG NumCoCmdBytesRcvd;
  1590. ULONGLONG NumCoDataPktsSent;
  1591. ULONGLONG NumCoDataBytesSent;
  1592. ULONGLONG NumCoDataPktsRcvd;
  1593. ULONGLONG NumCoDataBytesRcvd;
  1594. ULONGLONG NumJoinReq;
  1595. ULONGLONG NumJoinReqDenied;
  1596. ULONGLONG NumJoinError;
  1597. } COMM_STATS, *PCOMM_STATS;
  1598. typedef struct _REPLICA_STATS {
  1599. ULONG Size;
  1600. ULONG Version;
  1601. FILETIME UpdateTime;
  1602. CHANGE_ORDER_STATS Local;
  1603. CHANGE_ORDER_STATS Remote;
  1604. COMM_STATS InBound;
  1605. COMM_STATS OutBound;
  1606. } REPLICA_STATS, *PREPLICA_STATS;
  1607. #define TALLY_STATS(_cr_, _category_, _field_, _data_) \
  1608. FRS_ASSERT((_cr_) != NULL); \
  1609. (_cr_)->PerfStats->_category_._field_ += (ULONGLONG)(_data_)
  1610. #define TALLY_LOCALCO_STATS(_cr_, _field_, _data_) \
  1611. TALLY_STATS(_cr_, Local, _field_, _data_)
  1612. #define TALLY_REMOTECO_STATS(_cr_, _field_, _data_) \
  1613. TALLY_STATS(_cr_, Remote, _field_, _data_)
  1614. #define TALLY_INBOUND_COMM_STATS(_cr_, _field_, _data_) \
  1615. TALLY_STATS(_cr_, InBound, _field_, _data_)
  1616. #define TALLY_OUTBOUND_COMM_STATS(_cr_, _field_, _data_) \
  1617. TALLY_STATS(_cr_, OutBound, _field_, _data_)
  1618. #define READ_STATS(_cr_, _category_, _field_) \
  1619. (((_cr_) != NULL) ? (_cr_)->PerfStats->_category_._field \
  1620. : (FRS_ASSERT((_cr_) != NULL), (ULONGLONG) 0))
  1621. typedef enum _CONFIG_TABLE_COL_LIST {
  1622. ReplicaSetGuidx = 0, // The guid assigned to the tree root dir and the replica set.
  1623. ReplicaMemberGuidx, // The guid assigned to this member of the replica set. (INDEXED)
  1624. ReplicaSetNamex, // The replica set name.
  1625. ReplicaNumberx, // The replica set number (integer, for suffix on table names).
  1626. ReplicaMemberUSNx, // The Replica member USN. Saved in the registry for consistency check.
  1627. ReplicaMemberNamex, // Common-Name from NTFRS-Member
  1628. ReplicaMemberDnx, // Distinguished name from NTFRS-Member
  1629. ReplicaServerDnx, // Distinguished name from Server
  1630. ReplicaSubscriberDnx, // Distinguished name from Subscriber
  1631. ReplicaRootGuidx, // GUID assigned to the root directory.
  1632. MembershipExpiresx, // Membership Tombstone expiration time
  1633. ReplicaVersionGuidx, // originator guid for version vector
  1634. ReplicaSetExtx, // Frs-Extensions from NTFRS-Replica-Set
  1635. ReplicaMemberExtx, // Frs-Extensions from NTFRS-Member
  1636. ReplicaSubscriberExtx, // Frs-Extensions from NTFRS-Subscriber
  1637. ReplicaSubscriptionsExtx, // Frs-Extensions from NTFRS-Subscriptions
  1638. ReplicaSetTypex, // Frs-Replica-Set-Type from NTFRS-Replica-Set
  1639. ReplicaSetFlagsx, // Frs-Flags from NTFRS-Replica-Set
  1640. ReplicaMemberFlagsx, // Frs-Flags from NTFRS-Member
  1641. ReplicaSubscriberFlagsx,// Frs-Flags from NTFRS-Subscriber
  1642. ReplicaDsPollx, // Frs-DS-Poll
  1643. ReplicaAuthLevelx, // Frs-Partner-Auth-Level
  1644. ReplicaCtlDataCreationx, // Frs-Control-Data-Creation
  1645. ReplicaCtlInboundBacklogx, // Frs-Control-Inbound-Backlog
  1646. ReplicaCtlOutboundBacklogx, // Frs-Control-Outbound-Backlog
  1647. ReplicaFaultConditionx, // Frs-Fault-Condition
  1648. TimeLastCommandx, // Frs-Time-Last-Command
  1649. DSConfigVersionNumberx, // The version number of the DS config info.
  1650. FSVolInfox, // The NTFS volume info of the replica tree.
  1651. FSVolGuidx, // The NTFS volume Guid.
  1652. FSVolLastUSNx, // The last volume USN we saw from the journal when service stopped or paused.
  1653. FrsVsnx, // The Frs defined Volume sequence number exported by all R.S. on volume.
  1654. LastShutdownx, // The UTC time service on this replica set was last shutdown.
  1655. LastPausex, // The UTC time updates to this replica set were last paused.
  1656. LastDSCheckx, // The UTC time we last checked the DS for config info.
  1657. LastDSChangeAcceptedx, // The UTC time we last accepted a DS config change for this replica set.
  1658. LastReplCycleStartx, // The UTC time the last replication cycle started.
  1659. DirLastReplCycleEndedx, // The UTC time the last replication cycle ended.
  1660. ReplicaDeleteTimex, // The UTC time the replica set was deleted.
  1661. LastReplCycleStatusx, // The termination status of the last replication cycle.
  1662. FSRootPathx, // The path of the root of the replica tree.
  1663. FSRootSDx, // The security descriptor on the root. Used in the single-master case. Not replicated.
  1664. FSStagingAreaPathx, // The path to the file system staging area.
  1665. SnapFileSizeLimitx, // The maximum size of a file (KB units) that we will snapshot. (0 if no limit)
  1666. ActiveServCntlCommandx, // The currently active service control command.
  1667. ServiceStatex, // The current service state (see below)
  1668. ReplDirLevelLimitx, // The max number of dir levels files are replicated. 0x7FFFFFFF means no limit.
  1669. InboundPartnerStatex, // A binary struct of the inbound partner config info.
  1670. DsInfox, // A binary struct of the Dir Service Information.
  1671. CnfFlagsx, // Misc config flags. See below.
  1672. AdminAlertListx, // A string of Admin IDs to alert on exceptional conditions.
  1673. ThrottleSchedx, // The schedule of bandwidth throttling.
  1674. ReplSchedx, // The schedule of replication activity.
  1675. FileTypePrioListx, // A list of file types and repl priority levels.
  1676. ResourceStatsx, // A binary struct of resource stats like disk & DB space used/free.
  1677. PerfStatsx, // A binary struct of perf stats like number of I/Os done, # Files repl, ...
  1678. ErrorStatsx, // A binary struct of error stats like number of share viol blocking update, ...
  1679. FileFilterListx, // A list of file types that are not replicated.
  1680. DirFilterListx, // A list of dir paths (relative to the root) of dirs that are not replicated.
  1681. TombstoneLifex, // Tombstone life time for deleted files in days.
  1682. GarbageCollPeriodx, // The time between garbage collection in seconds.
  1683. MaxOutBoundLogSizex, // The maximum number of entries to be kept in the outbound log.
  1684. MaxInBoundLogSizex, // The maximum number of entries to be kept in the inbound log.
  1685. UpdateBlockedTimex, // The max time an update can be blocked before an alert is gen. (sec).
  1686. EventTimeDiffThresholdx,// Two event times are the same if their diff is less than this. (ms)
  1687. FileCopyWarningLevelx, // The maximum tries to copy a file before a warning alert is generated. (kb)
  1688. FileSizeWarningLevelx, // New files greater than this size generate a warning alert. (kb)
  1689. FileSizeNoRepLevelx, // New files greater than this size generate an alert and are not replicated. (kb)
  1690. CnfUsnJournalIDx, // Journal Instance ID to detect journal recreation.
  1691. CnfSpare2Ullx,
  1692. CnfSpare1Guidx,
  1693. CnfSpare2Guidx,
  1694. CnfSpare1Wcsx,
  1695. CnfSpare2Wcsx,
  1696. CnfSpare1Binx,
  1697. CnfSpare2Binx,
  1698. // --------------------------------------------------------------------------------
  1699. // The above is per-replica data. Below this is data in the FRS init record '<init>'.
  1700. // --------------------------------------------------------------------------------
  1701. //
  1702. // Note: Consider adding Version number of the USN Journal Records the service
  1703. // can work with.
  1704. //
  1705. MachineNamex, // The local machine name. (**)
  1706. MachineGuidx, // The local machine GUID. (**)
  1707. MachineDnsNamex, // The local machine DNS name. (**)
  1708. TableVersionNumbersx, // An array of version numbers, one per table type. (**)
  1709. FSDatabasePathx, // The path to the jet database. (**)
  1710. FSBackupDatabasePathx, // The path to the backup jet database. (**)
  1711. ReplicaNetBiosNamex, // SAM-Account-Name from Computer (minus the $)
  1712. ReplicaPrincNamex, // NT4 account name cracked from Computer
  1713. ReplicaCoDnx, // Distinguished name from Computer
  1714. ReplicaCoGuidx, // Object-GUID from Computer
  1715. ReplicaWorkingPathx, // Frs-Working-Path
  1716. ReplicaVersionx, // Frs-Version "NTFRS Major.Minor.Patch (build date)"
  1717. FrsDbMajorx, // Binary major version number of DB
  1718. FrsDbMinorx, // Binary minor version number of DB
  1719. JetParametersx, // The list of jet parameters in affect. Only present in the first record.
  1720. // Used to set up config on a restore or new machine build.
  1721. CONFIG_TABLE_MAX_COL
  1722. } CONFIG_TABLE_COL_LIST;
  1723. //
  1724. // Define the boundary between per-replica fields and the additional fields in
  1725. // the <init> record. This makes the DB access a little quicker since the
  1726. // <init> record is only read once at startup.
  1727. //
  1728. #define REPLICA_CONFIG_RECORD_MAX_COL (MachineNamex)
  1729. #define CONTROL_STRING_MAX 32
  1730. extern JET_COLUMNCREATE ConfigTableColDesc[];
  1731. //
  1732. // ConfigTable record definition.
  1733. //
  1734. // Note: Buffers are allocated at runtime to hold data for fields with
  1735. // a ColMaxWidth greater than sizeof(PVOID) where the field def in the corresponding
  1736. // record struct is sizeof(PVOID) (i.e. it holds a pointer). For fields where the
  1737. // ColMaxWidth equals the field size in the record struct the data is in the
  1738. // record struct and no buffer is allocated.
  1739. //
  1740. typedef struct _CONFIG_TABLE_RECORD {
  1741. GUID ReplicaSetGuid;
  1742. GUID ReplicaMemberGuid;
  1743. WCHAR ReplicaSetName[DNS_MAX_NAME_LENGTH+1];
  1744. ULONG ReplicaNumber;
  1745. LONGLONG ReplicaMemberUSN;
  1746. PWCHAR ReplicaMemberName; // Common-Name from NTFRS-Member
  1747. PWCHAR ReplicaMemberDn; // Distinguished name from NTFRS-Member
  1748. PWCHAR ReplicaServerDn; // Distinguished name from Server
  1749. PWCHAR ReplicaSubscriberDn; // Distinguished name from Subscriber
  1750. GUID ReplicaRootGuid; // GUID assigned to the root directory.
  1751. FILETIME MembershipExpires; // Membership Tombstone expiration time
  1752. GUID ReplicaVersionGuid; // Frs-Version-GUID
  1753. PVOID ReplicaSetExt; // Frs-Extensions from NTFRS-Replica-Set
  1754. PVOID ReplicaMemberExt; // Frs-Extensions from NTFRS-Member
  1755. PVOID ReplicaSubscriberExt; // Frs-Extensions from NTFRS-Subscriber
  1756. PVOID ReplicaSubscriptionsExt;// Frs-Extensions from NTFRS-Subscriptions
  1757. ULONG ReplicaSetType; // Frs-Replica-Set-Type from NTFRS-Replica-Set
  1758. ULONG ReplicaSetFlags; // Frs-Flags from NTFRS-Replica-Set, see below.
  1759. ULONG ReplicaMemberFlags; // Frs-Flags from NTFRS-Member, see below.
  1760. ULONG ReplicaSubscriberFlags; // Frs-Flags from NTFRS-Subscriber, see below.
  1761. ULONG ReplicaDsPoll; // Frs-DS-Poll
  1762. ULONG ReplicaAuthLevel; // Frs-Partner-Auth-Level
  1763. WCHAR ReplicaCtlDataCreation[CONTROL_STRING_MAX]; // Frs-Control-Data-Creation
  1764. WCHAR ReplicaCtlInboundBacklog[CONTROL_STRING_MAX]; // Frs-Control-Inbound-Backlog
  1765. WCHAR ReplicaCtlOutboundBacklog[CONTROL_STRING_MAX]; // Frs-Control-Outbound-Backlog
  1766. ULONG ReplicaFaultCondition; // Frs-Fault-Condition, see below.
  1767. FILETIME TimeLastCommand; // Frs-Time-Last-Command
  1768. ULONG DSConfigVersionNumber;
  1769. PFILE_FS_VOLUME_INFORMATION FSVolInfo;
  1770. GUID FSVolGuid;
  1771. LONGLONG FSVolLastUSN; // Keep this here so the file
  1772. ULONGLONG FrsVsn; // times are quadword aligned.
  1773. ULONGLONG LastShutdown; // A FILETIME.
  1774. FILETIME LastPause;
  1775. FILETIME LastDSCheck;
  1776. FILETIME LastDSChangeAccepted;
  1777. FILETIME LastReplCycleStart;
  1778. FILETIME DirLastReplCycleEnded;
  1779. FILETIME ReplicaDeleteTime; // Time replica set was deleted.
  1780. ULONG LastReplCycleStatus;
  1781. WCHAR FSRootPath[MAX_PATH+1];
  1782. SECURITY_DESCRIPTOR *FSRootSD; // var len (or use ACLID table)
  1783. WCHAR FSStagingAreaPath[MAX_PATH+1];
  1784. ULONG SnapFileSizeLimit;
  1785. PVOID ActiveServCntlCommand; // struct needed for pars?
  1786. ULONG ServiceState;
  1787. ULONG ReplDirLevelLimit;
  1788. PVOID InboundPartnerState; // need struct // delete
  1789. PVOID DsInfo;
  1790. ULONG CnfFlags;
  1791. PWCHAR AdminAlertList; // var len
  1792. PVOID ThrottleSched; // need array or struct
  1793. PVOID ReplSched; // need array or struct
  1794. PVOID FileTypePrioList; // need array or struct
  1795. PVOID ResourceStats; // need array or struct
  1796. PREPLICA_STATS PerfStats;
  1797. PVOID ErrorStats; // need array or struct
  1798. PWCHAR FileFilterList; // var len
  1799. PWCHAR DirFilterList; // var len
  1800. ULONG TombstoneLife;
  1801. ULONG GarbageCollPeriod;
  1802. ULONG MaxOutBoundLogSize;
  1803. ULONG MaxInBoundLogSize;
  1804. ULONG UpdateBlockedTime;
  1805. ULONG EventTimeDiffThreshold;
  1806. ULONG FileCopyWarningLevel;
  1807. ULONG FileSizeWarningLevel;
  1808. ULONG FileSizeNoRepLevel;
  1809. ULONGLONG CnfUsnJournalID; // Used for UsnJournalID.
  1810. ULONGLONG Spare2Ull;
  1811. GUID Spare1Guid;
  1812. GUID Spare2Guid;
  1813. PWCHAR Spare1Wcs;
  1814. PWCHAR Spare2Wcs;
  1815. PVOID Spare1Bin;
  1816. PVOID Spare2Bin;
  1817. //
  1818. // Everything below this line is present only in the FRS <init> record.
  1819. // Everything above is per-replica state.
  1820. //
  1821. WCHAR MachineName[MAX_RDN_VALUE_SIZE+1];
  1822. GUID MachineGuid;
  1823. WCHAR MachineDnsName[DNS_MAX_NAME_LENGTH+1];
  1824. ULONG TableVersionNumbers[FRS_MAX_TABLE_TYPES];
  1825. WCHAR FSDatabasePath[MAX_PATH+1];
  1826. WCHAR FSBackupDatabasePath[MAX_PATH+1];
  1827. PWCHAR ReplicaNetBiosName; // SAM-Account-Name from Computer (minus the $)
  1828. PWCHAR ReplicaPrincName; // NT4 account name cracked from Computer
  1829. PWCHAR ReplicaCoDn; // Distinguished name from Computer
  1830. GUID ReplicaCoGuid; // Object-GUID from Computer
  1831. PWCHAR ReplicaWorkingPath; // Frs-Working-Path
  1832. PWCHAR ReplicaVersion; // Frs-Version "NTFRS Major.Minor.Patch (build date)"
  1833. ULONG FrsDbMajor; // Binary major version number of DB
  1834. ULONG FrsDbMinor; // Binary minor version number of DB
  1835. PJET_SYSTEM_PARAMS JetParameters;
  1836. } CONFIG_TABLE_RECORD, *PCONFIG_TABLE_RECORD;
  1837. //
  1838. // Definitions of the CnfFlags ULONG.
  1839. //
  1840. // Note that Primary is specified by a field in the Replica Set Object in the DS.
  1841. // This field refs a member object so it is not possible to have more than
  1842. // one member be primary.
  1843. //
  1844. #define CONFIG_FLAG_MULTIMASTER 0x00000001 // This is a multi-master replica set.
  1845. #define CONFIG_FLAG_MASTER 0x00000002 // This machine is a master and will propagate Local COs.
  1846. #define CONFIG_FLAG_PRIMARY 0x00000004 // This is the first replica.
  1847. #define CONFIG_FLAG_SEEDING 0x00000008 // replica set has not been seeded.
  1848. #define CONFIG_FLAG_ONLINE 0x00000010 // replica set is ready to join with outbound.
  1849. // This flag is set when the init sync
  1850. // command server completes one pass.
  1851. //
  1852. // ReplicaMemberFlags -- (From Frs-Flags in NTFRS-Member Object)
  1853. //
  1854. #define FRS_MEMBER_FLAG_LEAF_NODE 0x00000001 // Don't propagate or originate files
  1855. // or respond to fetch requests.
  1856. #define FRS_MEMBER_FLAG_CANT_ORIGINATE 0x00000002 // Don't originate local file changes
  1857. //
  1858. // ReplicaSetFlags -- (From Frs-Flags in NTFRS-Replica-Set Object)
  1859. //
  1860. #define FRS_SETTINGS_FLAG_DELFILE_ON_REMOVE 0x00000001 // Delete files when member is removed.
  1861. //
  1862. // ReplicaSetType -- (From Frs-Replica-Set-Type in NTFRS-Replica-Set Object)
  1863. //
  1864. #define FRS_RSTYPE_ENTERPRISE_SYSVOL 1 // This replica set is enterprise system volume
  1865. #define FRS_RSTYPE_ENTERPRISE_SYSVOLW L"1" // for ldap
  1866. #define FRS_RSTYPE_DOMAIN_SYSVOL 2 // This replica set is domain system volume
  1867. #define FRS_RSTYPE_DOMAIN_SYSVOLW L"2" // for ldap
  1868. #define FRS_RSTYPE_DFS 3 // A DFS alternate set
  1869. #define FRS_RSTYPE_DFSW L"3" // for ldap
  1870. #define FRS_RSTYPE_OTHER 4 // None of the above.
  1871. #define FRS_RSTYPE_OTHERW L"4" // for ldap
  1872. //
  1873. // Is this replica set a sysvol?
  1874. //
  1875. #define FRS_RSTYPE_IS_SYSVOL(_T_) \
  1876. ((_T_) == FRS_RSTYPE_ENTERPRISE_SYSVOL || \
  1877. (_T_) == FRS_RSTYPE_DOMAIN_SYSVOL)
  1878. #define FRS_RSTYPE_IS_SYSVOLW(_TW_) \
  1879. (_TW_ && \
  1880. (WSTR_EQ(_TW_, FRS_RSTYPE_ENTERPRISE_SYSVOLW) || \
  1881. WSTR_EQ(_TW_, FRS_RSTYPE_DOMAIN_SYSVOLW)))
  1882. //
  1883. // ReplicaSubscriberFlags -- (From Frs-Flags in NTFRS-Subscriber Object)
  1884. //
  1885. #define FRS_SUBSCRIBE_FLAG_DELFILE_ON_REMOVE 0x00000001 // Delete files when member is removed.
  1886. //
  1887. // ReplicaFaultCondition -- (From Frs-Fault-Condition in NTFRS-Subscriber Object)
  1888. //
  1889. #define FRS_SUBSCRIBE_FAULT_CONDITION_NORMAL 0 // Operating normally on this R/S
  1890. #define FRS_SUBSCRIBE_FAULT_CONDITION_STOPPED 1 // Replication stopped by request.
  1891. #define FRS_SUBSCRIBE_FAULT_CONDITION_WARNING 2 // Replication running but attention is needed.
  1892. #define FRS_SUBSCRIBE_FAULT_CONDITION_ERROR 3 // Replication stopped by error condition.
  1893. extern JET_SETCOLUMN ConfigTableJetSetCol[CONFIG_TABLE_MAX_COL];
  1894. //
  1895. // The ConfigTable index descriptions are as follows. Note - the order of the
  1896. // enum and the table entries must be kept in sync.
  1897. //
  1898. //
  1899. typedef enum _CONFIG_TABLE_INDEX_LIST {
  1900. ReplicaNumberIndexx = 0, // The index on the Replica set number.
  1901. ReplicaMemberGuidIndexx, // The index on the Replica Set member GUID.
  1902. ReplicaSetNameIndexx, // The index on the Replica Set name
  1903. CONFIG_TABLE_MAX_INDEX
  1904. } CONFIG_TABLE_INDEX_LIST;
  1905. extern JET_INDEXCREATE ConfigTableIndexDesc[];
  1906. //
  1907. // Service State of this replica set. Update DbsDBInitialize if states change.
  1908. //
  1909. typedef enum _SERVICE_STATE_LIST {
  1910. CNF_SERVICE_STATE_CREATING = 0, // Creating a new replica set
  1911. CNF_SERVICE_STATE_INIT, // Initializing an exisiting replica set
  1912. CNF_SERVICE_STATE_RECOVERY, // Recovering exisitng replica set
  1913. CNF_SERVICE_STATE_RUNNING, // Replica set up and running (modulo sched, cxtions, etc)
  1914. CNF_SERVICE_STATE_CLEAN_SHUTDOWN, // Replica set did a clean shutdown
  1915. CNF_SERVICE_STATE_ERROR, // Replica set is in an Error state.
  1916. CNF_SERVICE_STATE_TOMBSTONE, // Replica set has been marked for deletion.
  1917. CNF_SERVICE_STATE_MAX
  1918. } SERVICE_STATE_LIST;
  1919. //
  1920. // Macro to update service state on this replica.
  1921. //
  1922. #define CNF_RECORD(_Replica_) \
  1923. ((PCONFIG_TABLE_RECORD) ((_Replica_)->ConfigTable.pDataRecord))
  1924. #define SET_SERVICE_STATE(_Replica_, _state_) \
  1925. { \
  1926. DPRINT3(4, ":S: Service State change from %s to %s for %ws\n", \
  1927. (CNF_RECORD(_Replica_)->ServiceState < CNF_SERVICE_STATE_MAX ) ? \
  1928. ServiceStateNames[CNF_RECORD(_Replica_)->ServiceState] : \
  1929. ServiceStateNames[CNF_SERVICE_STATE_CREATING], \
  1930. ServiceStateNames[(_state_)], \
  1931. \
  1932. ((_Replica_)->ReplicaName != NULL) ? \
  1933. (_Replica_)->ReplicaName->Name : L"<null>"); \
  1934. \
  1935. CNF_RECORD(_Replica_)->ServiceState = (_state_); \
  1936. }
  1937. #define SET_SERVICE_STATE2(_Cr_, _state_) \
  1938. { \
  1939. DPRINT3(4, ":S: Service State change from %s to %s for %ws\n", \
  1940. ((_Cr_)->ServiceState < CNF_SERVICE_STATE_MAX ) ? \
  1941. ServiceStateNames[(_Cr_)->ServiceState] : \
  1942. ServiceStateNames[CNF_SERVICE_STATE_CREATING], \
  1943. \
  1944. ServiceStateNames[(_state_)], \
  1945. ((_Cr_)->ReplicaSetName != NULL) ? \
  1946. (_Cr_)->ReplicaSetName : L"<null>"); \
  1947. \
  1948. (_Cr_)->ServiceState = (_state_); \
  1949. }
  1950. #define SERVICE_STATE(_Replica_) (CNF_RECORD(_Replica_)->ServiceState)
  1951. extern PCHAR ServiceStateNames[CNF_SERVICE_STATE_MAX];
  1952. /******************************************************************************
  1953. *******************************************************************************
  1954. ** **
  1955. ** **
  1956. ** S e r v i c e T a b l e **
  1957. ** **
  1958. ** **
  1959. *******************************************************************************
  1960. ******************************************************************************/
  1961. //
  1962. // The ServiceTable column descriptions are as follows. Note - the order of the
  1963. // enum and the table entries must be kept in sync.
  1964. //
  1965. // The service table contains service wide init/config params.
  1966. // There is only one Service Table.
  1967. //
  1968. typedef enum _SERVICE_TABLE_COL_LIST {
  1969. SvcFrsDbMajorx = 0, // Binary major version number of DB
  1970. SvcFrsDbMinorx, // Binary minor version number of DB
  1971. SvcMachineNamex, // The local machine name.
  1972. SvcMachineGuidx, // The local machine GUID.
  1973. SvcMachineDnsNamex, // The local machine DNS name.
  1974. SvcTableVersionNumbersx, // An array of version numbers, one per table type.
  1975. SvcFSDatabasePathx, // The path to the jet database.
  1976. SvcFSBackupDatabasePathx, // The path to the backup jet database.
  1977. SvcReplicaNetBiosNamex, // SAM-Account-Name from Computer (minus the $)
  1978. SvcReplicaPrincNamex, // NT4 account name cracked from Computer
  1979. SvcReplicaCoDnx, // Distinguished name from Computer
  1980. SvcReplicaCoGuidx, // Object-GUID from Computer
  1981. SvcReplicaWorkingPathx, // Frs-Working-Path
  1982. SvcReplicaVersionx, // Frs-Version "NTFRS Major.Minor.Patch (build date)"
  1983. SvcSpare1Ullx,
  1984. SvcSpare2Ullx,
  1985. SvcSpare1Guidx,
  1986. SvcSpare2Guidx,
  1987. SvcSpare1Wcsx,
  1988. SvcSpare2Wcsx,
  1989. SvcSpare1Binx,
  1990. SvcSpare2Binx,
  1991. SvcJetParametersx, // The list of jet parameters in affect. Only present in the first record.
  1992. // Used to set up config on a restore or new machine build.
  1993. SERVICE_TABLE_MAX_COL
  1994. } SERVICE_TABLE_COL_LIST;
  1995. extern JET_COLUMNCREATE ServiceTableColDesc[];
  1996. //
  1997. // Service Table record definition.
  1998. //
  1999. //
  2000. // Note: Buffers are allocated at runtime to hold data for fields with
  2001. // a ColMaxWidth greater than sizeof(PVOID) where the field def in the corresponding
  2002. // record struct is sizeof(PVOID) (i.e. it holds a pointer). For fields where the
  2003. // ColMaxWidth equals the field size in the record struct the data is in the
  2004. // record struct and no buffer is allocated.
  2005. //
  2006. //
  2007. typedef struct _SERVICE_TABLE_RECORD {
  2008. ULONG FrsDbMajor; // Binary major version number of DB
  2009. ULONG FrsDbMinor; // Binary minor version number of DB
  2010. WCHAR MachineName[MAX_RDN_VALUE_SIZE+1];
  2011. GUID MachineGuid;
  2012. WCHAR MachineDnsName[DNS_MAX_NAME_LENGTH+1];
  2013. ULONG TableVersionNumbers[FRS_MAX_TABLE_TYPES];
  2014. WCHAR FSDatabasePath[MAX_PATH+1];
  2015. WCHAR FSBackupDatabasePath[MAX_PATH+1];
  2016. PWCHAR ReplicaNetBiosName; // SAM-Account-Name from Computer (minus the $)
  2017. PWCHAR ReplicaPrincName; // NT4 account name cracked from Computer
  2018. PWCHAR ReplicaCoDn; // Distinguished name from Computer
  2019. GUID ReplicaCoGuid; // Object-GUID from Computer
  2020. PWCHAR ReplicaWorkingPath; // Frs-Working-Path
  2021. PWCHAR ReplicaVersion; // Frs-Version "NTFRS Major.Minor.Patch (build date)"
  2022. ULONGLONG Spare1Ull;
  2023. ULONGLONG Spare2Ull;
  2024. GUID Spare1Guid;
  2025. GUID Spare2Guid;
  2026. PWCHAR Spare1Wcs;
  2027. PWCHAR Spare2Wcs;
  2028. PVOID Spare1Bin;
  2029. PVOID Spare2Bin;
  2030. PJET_SYSTEM_PARAMS JetParameters;
  2031. } SERVICE_TABLE_RECORD, *PSERVICE_TABLE_RECORD;
  2032. //
  2033. // The RECORD_FIELDS struct is used to build the Jet Set Column struct.
  2034. //
  2035. extern RECORD_FIELDS ServiceTableRecordFields[];
  2036. extern JET_SETCOLUMN ServiceTableJetSetCol[SERVICE_TABLE_MAX_COL];
  2037. //
  2038. // The Service Table index descriptions are as follows. Note - the order of the
  2039. // enum and the table entries must be kept in sync.
  2040. //
  2041. typedef enum _SERVICE_TABLE_INDEX_LIST {
  2042. FrsDbMajorIndexx, // The index on the major version number.
  2043. SERVICE_TABLE_MAX_INDEX
  2044. } SERVICE_TABLE_INDEX_LIST;
  2045. extern JET_INDEXCREATE ServiceTableIndexDesc[];