Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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