Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

688 lines
26 KiB

  1. /*++
  2. Copyright (c) 1991-2000 Microsoft Corporation
  3. Module Name:
  4. attrdef.cxx
  5. Abstract:
  6. This module contains the member function implementation for
  7. the NTFS_ATTRIBUTE_DEFINITION_TABLE class, which models
  8. the attribute definition table file for an NTFS volume.
  9. Author:
  10. Bill McJohn (billmc) 17-June-91
  11. Environment:
  12. ULIB, User Mode
  13. --*/
  14. #include <pch.cxx>
  15. #define _NTAPI_ULIB_
  16. #define _UNTFS_MEMBER_
  17. #include "ulib.hxx"
  18. #include "error.hxx"
  19. #include "untfs.hxx"
  20. #include "drive.hxx"
  21. #include "attrib.hxx"
  22. #include "ntfsbit.hxx"
  23. #include "attrdef.hxx"
  24. #include "ifssys.hxx"
  25. #include "message.hxx"
  26. #include "rtmsg.h"
  27. #include "attrcol.hxx"
  28. // This is the initial table for NT 4.0:
  29. CONST ATTRIBUTE_DEFINITION_COLUMNS NtfsAttributeDefinitions_1[$EA_DATA+1] =
  30. {
  31. {{'$','S','T','A','N','D','A','R','D','_','I','N','F','O','R','M','A','T','I','O','N'},
  32. $STANDARD_INFORMATION, // Attribute code
  33. 0, // Display rule
  34. 0, // Collation rule
  35. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  36. {sizeof(STANDARD_INFORMATION), 0}, // Minimum length
  37. {sizeof(STANDARD_INFORMATION), 0}}, // Maximum length
  38. {{'$','A','T','T','R','I','B','U','T','E','_','L','I','S','T'},
  39. $ATTRIBUTE_LIST, // Attribute code
  40. 0, // Display rule
  41. 0, // Collation rule
  42. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  43. {0,0}, // Minimum length
  44. {MAXULONG,MAXULONG}}, // Maximum length
  45. {{'$','F','I','L','E','_','N','A','M','E'},
  46. $FILE_NAME, // Attribute code
  47. 0, // Display rule
  48. 0, // Collation rule
  49. ATTRIBUTE_DEF_MUST_BE_RESIDENT | ATTRIBUTE_DEF_INDEXABLE, // Flags
  50. {sizeof(FILE_NAME), 0}, // Minimum length
  51. {sizeof(FILE_NAME) + (255 * sizeof(WCHAR)), 0}}, // Maximum length
  52. {{'$','V','O','L','U','M','E','_','V','E','R','S','I','O','N'},
  53. $VOLUME_VERSION, // Attribute code
  54. 0, // Display rule
  55. 0, // Collation rule
  56. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  57. {sizeof(VOLUME_VERSION), 0}, // Minimum length
  58. {sizeof(VOLUME_VERSION), 0}}, // Maximum length
  59. {{'$','S','E','C','U','R','I','T','Y','_','D','E','S','C','R','I','P','T','O','R'},
  60. $SECURITY_DESCRIPTOR, // Attribute code
  61. 0, // Display rule
  62. 0, // Collation rule
  63. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  64. {0,0}, // Minimum length
  65. {MAXULONG,MAXULONG}}, // Maximum length
  66. {{'$','V','O','L','U','M','E','_','N','A','M','E'},
  67. $VOLUME_NAME, // Attribute code
  68. 0, // Display rule
  69. 0, // Collation rule
  70. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  71. {2,0}, // Minimum length
  72. {256,0}}, // Maximum length
  73. {{'$','V','O','L','U','M','E','_','I','N','F','O','R','M','A','T','I','O','N'},
  74. $VOLUME_INFORMATION, // Attribute code
  75. 0, // Display rule
  76. 0, // Collation rule
  77. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  78. {sizeof(VOLUME_INFORMATION),0}, // Minimum length
  79. {sizeof(VOLUME_INFORMATION),0}}, // Maximum length
  80. {{'$','D','A','T','A'},
  81. $DATA, // Attribute code
  82. 0, // Display rule
  83. 0, // Collation rule
  84. 0, // Flags
  85. {0,0}, // Minimum length
  86. {MAXULONG,MAXULONG}}, // Maximum length
  87. {{'$','I','N','D','E','X','_','R','O','O','T'},
  88. $INDEX_ROOT, // Attribute code
  89. 0, // Display rule
  90. 0, // Collation rule
  91. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  92. {0,0}, // Minimum length
  93. {MAXULONG,MAXULONG}}, // Maximum length
  94. {{'$','I','N','D','E','X','_','A','L','L','O','C','A','T','I','O','N'},
  95. $INDEX_ALLOCATION, // Attribute code
  96. 0, // Display rule
  97. 0, // Collation rule
  98. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  99. {0,0}, // Minimum length
  100. {MAXULONG,MAXULONG}}, // Maximum length
  101. {{'$','B','I','T','M','A','P'},
  102. $BITMAP, // Attribute code
  103. 0, // Display rule
  104. 0, // Collation rule
  105. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  106. {0,0}, // Minimum length
  107. {MAXULONG,MAXULONG}}, // Maximum length
  108. {{'$','S','Y','M','B','O','L','I','C','_','L','I','N','K'},
  109. $SYMBOLIC_LINK, // Attribute code
  110. 0, // Display rule
  111. 0, // Collation rule
  112. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  113. {0,0}, // Minimum length
  114. {MAXULONG,MAXULONG}}, // Maximum length
  115. {{'$','E','A','_','I','N','F','O','R','M','A','T','I','O','N'},
  116. $EA_INFORMATION, // Attribute code
  117. 0, // Display rule
  118. 0, // Collation rule
  119. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  120. {sizeof(EA_INFORMATION), 0}, // Minimum length
  121. {sizeof(EA_INFORMATION), 0}}, // Maximum length
  122. {{'$','E','A',},
  123. $EA_DATA, // Attribute code
  124. 0, // Display rule
  125. 0, // Collation rule
  126. 0, // Flags
  127. {0,0}, // Minimum length
  128. {0x10000,0}}, // Maximum length
  129. {{0, 0, 0, 0},
  130. $UNUSED, // Attribute code
  131. 0, // Display rule
  132. 0, // Collation rule
  133. 0, // Flags
  134. {0,0}, // Minimum length
  135. {0,0}} // Maximum length
  136. };
  137. // This is the initial table for NT 5.0 (W2K):
  138. CONST ATTRIBUTE_DEFINITION_COLUMNS NtfsAttributeDefinitions_2[] =
  139. {
  140. {{'$','S','T','A','N','D','A','R','D','_','I','N','F','O','R','M','A','T','I','O','N'},
  141. $STANDARD_INFORMATION, // Attribute code
  142. 0, // Display rule
  143. 0, // Collation rule
  144. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  145. {sizeof(STANDARD_INFORMATION), 0}, // Minimum length
  146. {sizeof(STANDARD_INFORMATION2), 0}}, // Maximum length
  147. {{'$','A','T','T','R','I','B','U','T','E','_','L','I','S','T'},
  148. $ATTRIBUTE_LIST, // Attribute code
  149. 0, // Display rule
  150. 0, // Collation rule
  151. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  152. {0,0}, // Minimum length
  153. {MAXULONG,MAXULONG}}, // Maximum length
  154. {{'$','F','I','L','E','_','N','A','M','E'},
  155. $FILE_NAME, // Attribute code
  156. 0, // Display rule
  157. 0, // Collation rule
  158. ATTRIBUTE_DEF_MUST_BE_RESIDENT | ATTRIBUTE_DEF_INDEXABLE, // Flags
  159. {sizeof(FILE_NAME), 0}, // Minimum length
  160. {sizeof(FILE_NAME) + (255 * sizeof(WCHAR)), 0}}, // Maximum length
  161. {{'$','O','B','J','E','C','T','_','I','D'},
  162. $OBJECT_ID, // Attribute code
  163. 0, // Display rule
  164. 0, // Collation rule
  165. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  166. {0, 0}, // Minimum length
  167. {256, 0}}, // Maximum length
  168. {{'$','S','E','C','U','R','I','T','Y','_','D','E','S','C','R','I','P','T','O','R'},
  169. $SECURITY_DESCRIPTOR, // Attribute code
  170. 0, // Display rule
  171. 0, // Collation rule
  172. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  173. {0,0}, // Minimum length
  174. {MAXULONG,MAXULONG}}, // Maximum length
  175. {{'$','V','O','L','U','M','E','_','N','A','M','E'},
  176. $VOLUME_NAME, // Attribute code
  177. 0, // Display rule
  178. 0, // Collation rule
  179. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  180. {2,0}, // Minimum length
  181. {256,0}}, // Maximum length
  182. {{'$','V','O','L','U','M','E','_','I','N','F','O','R','M','A','T','I','O','N'},
  183. $VOLUME_INFORMATION, // Attribute code
  184. 0, // Display rule
  185. 0, // Collation rule
  186. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  187. {sizeof(VOLUME_INFORMATION),0}, // Minimum length
  188. {sizeof(VOLUME_INFORMATION),0}}, // Maximum length
  189. {{'$','D','A','T','A'},
  190. $DATA, // Attribute code
  191. 0, // Display rule
  192. 0, // Collation rule
  193. 0, // Flags
  194. {0,0}, // Minimum length
  195. {MAXULONG,MAXULONG}}, // Maximum length
  196. {{'$','I','N','D','E','X','_','R','O','O','T'},
  197. $INDEX_ROOT, // Attribute code
  198. 0, // Display rule
  199. 0, // Collation rule
  200. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  201. {0,0}, // Minimum length
  202. {MAXULONG,MAXULONG}}, // Maximum length
  203. {{'$','I','N','D','E','X','_','A','L','L','O','C','A','T','I','O','N'},
  204. $INDEX_ALLOCATION, // Attribute code
  205. 0, // Display rule
  206. 0, // Collation rule
  207. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  208. {0,0}, // Minimum length
  209. {MAXULONG,MAXULONG}}, // Maximum length
  210. {{'$','B','I','T','M','A','P'},
  211. $BITMAP, // Attribute code
  212. 0, // Display rule
  213. 0, // Collation rule
  214. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  215. {0,0}, // Minimum length
  216. {MAXULONG,MAXULONG}}, // Maximum length
  217. {{'$','R','E','P','A','R','S','E','_','P','O','I','N','T'},
  218. $REPARSE_POINT, // Attribute code
  219. 0, // Display rule
  220. 0, // Collation rule
  221. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  222. {0,0}, // Minimum length
  223. {16*1024,0}}, // Maximum length
  224. {{'$','E','A','_','I','N','F','O','R','M','A','T','I','O','N'},
  225. $EA_INFORMATION, // Attribute code
  226. 0, // Display rule
  227. 0, // Collation rule
  228. ATTRIBUTE_DEF_MUST_BE_RESIDENT, // Flags
  229. {sizeof(EA_INFORMATION), 0}, // Minimum length
  230. {sizeof(EA_INFORMATION), 0}}, // Maximum length
  231. {{'$','E','A'},
  232. $EA_DATA, // Attribute code
  233. 0, // Display rule
  234. 0, // Collation rule
  235. 0, // Flags
  236. {0,0}, // Minimum length
  237. {0x10000,0}}, // Maximum length
  238. {{'$','L','O','G','G','E','D','_','U','T','I','L','I','T','Y','_','S','T','R','E','A','M'},
  239. $LOGGED_UTILITY_STREAM, // Attribute code
  240. 0, // Display rule
  241. 0, // Collation rule
  242. ATTRIBUTE_DEF_LOG_NONRESIDENT, // Flags
  243. {0,0}, // Minimum length
  244. {0x10000,0}}, // Maximum length
  245. {{0, 0, 0, 0},
  246. $UNUSED, // Attribute code
  247. 0, // Display rule
  248. 0, // Collation rule
  249. 0, // Flags
  250. {0,0}, // Minimum length
  251. {0,0}} // Maximum length
  252. };
  253. CONST NumberOfNtfsAttributeDefinitions_1 = sizeof(NtfsAttributeDefinitions_1)/
  254. sizeof(ATTRIBUTE_DEFINITION_COLUMNS);
  255. CONST NumberOfNtfsAttributeDefinitions_2 = sizeof(NtfsAttributeDefinitions_2)/
  256. sizeof(ATTRIBUTE_DEFINITION_COLUMNS);
  257. DEFINE_EXPORTED_CONSTRUCTOR( NTFS_ATTRIBUTE_DEFINITION_TABLE,
  258. NTFS_FILE_RECORD_SEGMENT, UNTFS_EXPORT );
  259. UNTFS_EXPORT
  260. NTFS_ATTRIBUTE_DEFINITION_TABLE::~NTFS_ATTRIBUTE_DEFINITION_TABLE(
  261. )
  262. {
  263. Destroy();
  264. }
  265. VOID
  266. NTFS_ATTRIBUTE_DEFINITION_TABLE::Construct(
  267. )
  268. /*++
  269. Routine Description:
  270. Worker function for the construtor.
  271. Arguments:
  272. None.
  273. Return Value:
  274. None.
  275. --*/
  276. {
  277. (void) this;
  278. }
  279. VOID
  280. NTFS_ATTRIBUTE_DEFINITION_TABLE::Destroy(
  281. )
  282. /*++
  283. Routine Description:
  284. Worker function for destruction/reinitialization.
  285. Arguments:
  286. None.
  287. Return Value:
  288. None.
  289. --*/
  290. {
  291. (void) this;
  292. }
  293. UNTFS_EXPORT
  294. BOOLEAN
  295. NTFS_ATTRIBUTE_DEFINITION_TABLE::Initialize(
  296. IN OUT PNTFS_MASTER_FILE_TABLE Mft,
  297. IN UCHAR VolumeMajorVersion
  298. )
  299. /*++
  300. Routine Description:
  301. This method initializes an Attribute Definition Table object.
  302. The only special knowledge that it adds to the File Record Segment
  303. initialization is the location within the Master File Table of the
  304. Attribute Definition Table.
  305. Arguments:
  306. Drive -- Supplies the drive on which the segment resides.
  307. Mft -- Supplies the volume MasterFile Table.
  308. ClusterFactor -- Supplies the volume Cluster Factor.
  309. Return Value:
  310. TRUE upon successful completion
  311. Notes:
  312. This class is reinitializable.
  313. --*/
  314. {
  315. Destroy();
  316. _volume_major_version = VolumeMajorVersion;
  317. return( NTFS_FILE_RECORD_SEGMENT::Initialize( ATTRIBUTE_DEF_TABLE_NUMBER,
  318. Mft ) );
  319. }
  320. BOOLEAN
  321. NTFS_ATTRIBUTE_DEFINITION_TABLE::Create(
  322. IN PCSTANDARD_INFORMATION StandardInformation,
  323. IN OUT PNTFS_BITMAP VolumeBitmap
  324. )
  325. /*++
  326. Routine Description:
  327. This method formats a Attribute Definition Table File Record
  328. Segment in memory (without writing it to disk).
  329. Arguments:
  330. StandardInformation -- supplies the standard information for the
  331. file record segment.
  332. VolumeBitmap -- supplies the bitmap for the volume on
  333. which this object resides.
  334. Return Value:
  335. TRUE upon successful completion.
  336. --*/
  337. {
  338. NTFS_ATTRIBUTE DataAttribute;
  339. NTFS_EXTENT_LIST Extents;
  340. LCN FirstLcn;
  341. ULONG Size;
  342. ULONG NumberOfClusters;
  343. ULONG BytesWritten;
  344. ULONG ClusterSize;
  345. // Set this object up as a File Record Segment.
  346. if( !NTFS_FILE_RECORD_SEGMENT::Create( StandardInformation ) ) {
  347. return FALSE;
  348. }
  349. // The Attribute Definition Table has a data attribute whose value
  350. // consists of the attribute definition table. The initial table,
  351. // with the system-defined attributes, is copied into this attribute.
  352. Size = QueryDefaultSize();
  353. ClusterSize = GetDrive()->QuerySectorSize() * QueryClusterFactor();
  354. NumberOfClusters = Size/ClusterSize;
  355. if( Size % ClusterSize ) {
  356. NumberOfClusters += 1;
  357. }
  358. if( !Extents.Initialize( 0, 0 ) ||
  359. !Extents.Resize( NumberOfClusters, VolumeBitmap ) ||
  360. !DataAttribute.Initialize( GetDrive(),
  361. QueryClusterFactor(),
  362. &Extents,
  363. Size,
  364. Size,
  365. $DATA ) ||
  366. !DataAttribute.Write( (PVOID) (_volume_major_version >= 2) ?
  367. NtfsAttributeDefinitions_2 :
  368. NtfsAttributeDefinitions_1,
  369. 0,
  370. Size,
  371. &BytesWritten,
  372. VolumeBitmap ) ||
  373. BytesWritten != Size ||
  374. !DataAttribute.InsertIntoFile( this, VolumeBitmap ) ) {
  375. return FALSE;
  376. }
  377. return TRUE;
  378. }
  379. BOOLEAN
  380. NTFS_ATTRIBUTE_DEFINITION_TABLE::VerifyAndFix(
  381. IN OUT PNTFS_ATTRIBUTE_COLUMNS AttributeDefTable,
  382. IN OUT PNTFS_BITMAP VolumeBitmap,
  383. IN OUT PNUMBER_SET BadClusters,
  384. IN OUT PNTFS_INDEX_TREE RootIndex,
  385. OUT PBOOLEAN Changes,
  386. IN FIX_LEVEL FixLevel,
  387. IN OUT PMESSAGE Message,
  388. IN BOOLEAN SilentMode
  389. )
  390. /*++
  391. Routine Description:
  392. This routine compares the given attribute definition table with
  393. the one contained in this file's DATA attribute and ensures
  394. that both are the same. The in-memory version will override the
  395. on-disk version.
  396. Arguments:
  397. AttributeDefTable - Supplies the in-memory version of the table.
  398. VolumeBitmap - Supplies the volume bitmap.
  399. BadClusters - Supplies the list of bad clusters.
  400. RootIndex - Supplies the root index.
  401. Changes - Returns whether or not changes were made.
  402. FixLevel - Supplies the fix up level.
  403. Message - Supplies an outlet for messages.
  404. SilentMode - Suppresses changes message as errors is expected
  405. Return Value:
  406. FALSE - Failure.
  407. TRUE - Success.
  408. --*/
  409. {
  410. NTFS_ATTRIBUTE data_attribute;
  411. BOOLEAN error;
  412. ULONG num_columns;
  413. ULONG value_length;
  414. PCATTRIBUTE_DEFINITION_COLUMNS mem_columns;
  415. PATTRIBUTE_DEFINITION_COLUMNS disk_columns;
  416. ULONG num_bytes;
  417. NTFS_EXTENT_LIST extent_list;
  418. BOOLEAN ErrorInAttribute;
  419. *Changes = FALSE;
  420. mem_columns = AttributeDefTable->GetColumns(&num_columns);
  421. value_length = num_columns*sizeof(ATTRIBUTE_DEFINITION_COLUMNS);
  422. if (!(disk_columns = new ATTRIBUTE_DEFINITION_COLUMNS[num_columns])) {
  423. Message->DisplayMsg(MSG_CHK_NO_MEMORY);
  424. return FALSE;
  425. }
  426. if (!QueryAttribute(&data_attribute, &ErrorInAttribute, $DATA)) {
  427. *Changes = TRUE;
  428. if (!extent_list.Initialize(0, 0) ) {
  429. Message->DisplayMsg(MSG_CHK_NO_MEMORY);
  430. DELETE(disk_columns);
  431. return FALSE;
  432. }
  433. if (!data_attribute.Initialize(GetDrive(),
  434. QueryClusterFactor(),
  435. &extent_list,
  436. 0,
  437. 0,
  438. $DATA)) {
  439. Message->DisplayMsg(MSG_CHK_NO_MEMORY);
  440. DELETE(disk_columns);
  441. return FALSE;
  442. }
  443. }
  444. error = FALSE;
  445. if (value_length != data_attribute.QueryValueLength()) {
  446. Message->LogMsg(MSG_CHKLOG_NTFS_INCORRECT_ATTR_DEF_TABLE_LENGTH,
  447. "%I64x%x",
  448. data_attribute.QueryValueLength().GetLargeInteger(),
  449. value_length);
  450. error = TRUE;
  451. } else if (!data_attribute.Read(disk_columns, 0, value_length, &num_bytes)) {
  452. Message->LogMsg(MSG_CHKLOG_NTFS_UNABLE_TO_READ_ATTR_DEF_TABLE);
  453. error = TRUE;
  454. } else if (num_bytes != value_length) {
  455. Message->LogMsg(MSG_CHKLOG_NTFS_UNABLE_TO_READ_ATTR_DEF_TABLE);
  456. error = TRUE;
  457. } else if (memcmp(mem_columns, disk_columns, value_length)) {
  458. Message->LogMsg(MSG_CHKLOG_NTFS_INCORRECT_ATTR_DEF_TABLE);
  459. error = TRUE;
  460. }
  461. if (error) {
  462. *Changes = TRUE;
  463. if (!SilentMode) {
  464. Message->DisplayMsg(MSG_CHK_NTFS_CORRECTING_ATTR_DEF);
  465. }
  466. if (FixLevel != CheckOnly) {
  467. if (!data_attribute.MakeNonresident(VolumeBitmap) ||
  468. !data_attribute.Resize(value_length, VolumeBitmap) ||
  469. !data_attribute.Write(mem_columns, 0, value_length, &num_bytes,
  470. VolumeBitmap) ||
  471. value_length != num_bytes) {
  472. if (!data_attribute.RecoverAttribute(VolumeBitmap, BadClusters) ||
  473. !data_attribute.Write(mem_columns, 0, value_length,
  474. &num_bytes, VolumeBitmap) ||
  475. value_length != num_bytes) {
  476. Message->DisplayMsg(MSG_CHK_NTFS_CANT_FIX_ATTR_DEF);
  477. DELETE(disk_columns);
  478. return FALSE;
  479. }
  480. }
  481. }
  482. if (!data_attribute.InsertIntoFile(this, VolumeBitmap)) {
  483. Message->DisplayMsg(MSG_CHK_NTFS_CANT_FIX_ATTR_DEF);
  484. DELETE(disk_columns);
  485. return FALSE;
  486. }
  487. }
  488. if (FixLevel != CheckOnly && !Flush(VolumeBitmap, RootIndex)) {
  489. Message->DisplayMsg(MSG_CHK_NTFS_CANT_FIX_ATTR_DEF);
  490. DELETE(disk_columns);
  491. return FALSE;
  492. }
  493. DELETE(disk_columns);
  494. return TRUE;
  495. }
  496. ULONG
  497. NTFS_ATTRIBUTE_DEFINITION_TABLE::QueryDefaultSize(
  498. )
  499. /*++
  500. Routine Description:
  501. This method returns the size of the default upcase table.
  502. Arguments:
  503. None.
  504. Return Value:
  505. The size of the default upcase table;
  506. --*/
  507. {
  508. if (_volume_major_version >= 2)
  509. return (sizeof( NtfsAttributeDefinitions_2 ));
  510. else
  511. return( sizeof( NtfsAttributeDefinitions_1 ) );
  512. }
  513. ULONG
  514. NTFS_ATTRIBUTE_DEFINITION_TABLE::QueryDefaultMaxSize(
  515. )
  516. /*++
  517. Routine Description:
  518. This method returns the maximum size of the default upcase table.
  519. Arguments:
  520. None.
  521. Return Value:
  522. The maximum size of the default upcase table;
  523. --*/
  524. {
  525. return max(sizeof( NtfsAttributeDefinitions_1 ),
  526. sizeof( NtfsAttributeDefinitions_2 ));
  527. }