/*++ Copyright (c) 1989-1996 Microsoft Corporation Module Name: ntfsprop.h Abstract: This module contains the structure definitions for nt property Fsctl calls. Author: Mark Zbikowski (MarkZ) 23-April-1996 --*/ #ifndef _NTFSPROP_ #define _NTFSPROP_ // // WARNING! This file requires OBJIDL.H. // // // VARIABLE_STRUCTURE_SIZE returns the size of a structure S that contains // an array of C structures V // #define VARIABLE_STRUCTURE_SIZE(S,V,C) ((int)sizeof( S ) + ((C) - 1) * (int)sizeof( V )) // // COUNTED_STRING is length-preceded unicode string. This does NOT include // a trailing L'\0' // typedef struct _COUNTED_STRING { USHORT Length; WCHAR Text[1]; } COUNTED_STRING, *PCOUNTED_STRING; #define COUNTED_STRING_SIZE(l) \ (sizeof( COUNTED_STRING ) - sizeof ( WCHAR ) + (l)) #define COUNTED_STRING_LENGTH(c) \ ((c)->Length) #define COUNTED_STRING_TEXT(c) \ (&(c)->Text[0]) // // PROPERTY_SPECIFIER is a serialized form of a PROPSPEC. Instead of // a LPWSTR, there is an offset from the beginning of the // PROPERTY_SPECIFICATIONS to a COUNTED_STRING // // #define PRSPEC_LPWSTR ( 0 ) // #define PRSPEC_PROPID ( 1 ) typedef struct _PROPERTY_SPECIFIER { ULONG Variant; // Distinguish the type union { // Switch on Variant PROPID Id; // Property ID ULONG NameOffset; // Offset to COUNTED_STRING }; } PROPERTY_SPECIFIER, *PPROPERTY_SPECIFIER; // // PROPERTY_SPECIFICATIONS is a serialized form of an array PROPERTY_SPECIFIERs. // Immediately following PROPERTY_SPECIFICATIONS on a USHORT boundary are // of the name strings. Each name string is a COUNTED_STRING // typedef struct _PROPERTY_SPECIFICATIONS { ULONG Length; // Length in bytes of structure and name strings ULONG Count; // Count of PROPERTY_SPECIFIERS PROPERTY_SPECIFIER Specifiers[1]; // Array of actual specifiers, length Count } PROPERTY_SPECIFICATIONS, *PPROPERTY_SPECIFICATIONS; #define PROPERTY_SPECIFICATIONS_SIZE(c) \ (VARIABLE_STRUCTURE_SIZE( PROPERTY_SPECIFICATIONS, PROPERTY_SPECIFIER, (c) )) #define PROPERTY_SPECIFIER_ID(PS,I) \ ((PS)->Specifiers[(I)].Id) #define PROPERTY_SPECIFIER_COUNTED_STRING(PS,I) \ ((PCOUNTED_STRING)Add2Ptr( (PS), (PS)->Specifiers[(I)].NameOffset)) #define PROPERTY_SPECIFIER_NAME(PS,I) \ (&PROPERTY_SPECIFIER_COUNTED_STRING( PS, I )->Text[0]) #define PROPERTY_SPECIFIER_NAME_LENGTH(PS,I) \ (PROPERTY_SPECIFIER_COUNTED_STRING( PS, I )->Length) // // PROPERTY_VALUES is a serialized form of an array of SERIALIZEDPROPERTYVALUES. // Immediately following the structure are the values, each of which is on a DWORD // boundary. The last PropertyValue (count+1) is used only to help determine the // size of the last property value. The offsets to the values are relative // to the address of the PROPERTY_VALUES structure itself. // typedef struct _PROPERTY_VALUES { ULONG Length; // Length in bytes of structure and values ULONG Count; // Count of SERIALIZEDPROPERTYVALUES ULONG PropertyValueOffset[1]; // Array of offsets to actual values, length count + 1 } PROPERTY_VALUES, *PPROPERTY_VALUES; #define PROPERTY_VALUES_SIZE(c) \ (VARIABLE_STRUCTURE_SIZE( PROPERTY_VALUES, ULONG, (c) + 1 )) #define PROPERTY_VALUE_LENGTH(v,i) \ ((v)->PropertyValueOffset[(i) + 1] - (v)->PropertyValueOffset[(i)]) #define PROPERTY_VALUE(v,i) \ ((SERIALIZEDPROPERTYVALUE *) Add2Ptr( (v), (v)->PropertyValueOffset[(i)])) // // PROPERTY_IDS is a serialized form of an array of PROPIDs // typedef struct _PROPERTY_IDS { ULONG Count; // Count of the number of propids PROPID PropertyIds[1]; // Array of propids, length Count } PROPERTY_IDS, *PPROPERTY_IDS; #define PROPERTY_IDS_SIZE(c) \ (VARIABLE_STRUCTURE_SIZE( PROPERTY_IDS, PROPID, (c) )) #define PROPERTY_ID(p,i) \ ((p)->PropertyIds[i]) // // INDIRECT_PROPERTIES is a serialized form of an array of PROPID/string-value // pairs. Immediately following the structure are the INDIRECT_ENTRIES, each of // which is on a WCHAR boundary. // typedef struct _INDIRECT_ENTRY { PROPID PropertyId; // Propid of indirect property ULONG IndirectValueOffset; // Offset to the string text, L'\0' terminated } INDIRECT_ENTRY; typedef struct _INDIRECT_PROPERTIES { ULONG Length; // Length in bytes of structure and values ULONG Count; // Count of indirect properties being replaced INDIRECT_ENTRY Entrys[1]; // First indirect entry } INDIRECT_PROPERTIES, *PINDIRECT_PROPERTIES; #define INDIRECT_PROPERTIES_SIZE(c) \ (VARIABLE_STRUCTURE_SIZE( INDIRECT_PROPERTIES, INDIRECT_ENTRY, (c) + 1 )) #define INDIRECT_VALUE_ID(v,i) \ ((v)->Entrys[i].PropertyId) #define INDIRECT_VALUE_LENGTH(v,i) \ ((v)->IndirectValueOffset[(i) + 1] - (v)->IndirectValueOffset[(i)]) #define INDIRECT_VALUE(v,i) \ ((SERIALIZED_PROPERTY_VALUE *) Add2Ptr( (v), (v)->Entrys[i].IndirectValueOffset)) // // PROPERTY_STAT_DATA is a serialized array of STATPROPSTG. Following the // structure are the individual STATPROPSTG instances each of which is on a DWORD // boundary. // typedef struct _PROPERTY_STAT_DATA { ULONG Length; // Length in bytes of structure and values ULONG Count; // Count of STATPROPSTG entries that follow STATPROPSTG PropertyStat[1]; // First statpropstg } PROPERTY_STAT_DATA, *PPROPERTY_STAT_DATA; // // PROPERTY_NAMES is a serialized array of strings's. Following the structure // are the individual strings, each of which is on a WCHAR boundary. The // offsets to the property names are relative to the beginning of the // PROPERTY_NAMES structure. There are count+1 offsets allowing the length // of each to be calculated. // typedef struct _PROPERTY_NAMES { ULONG Length; // Length in bytes of structure and values ULONG Count; // Count of strings ULONG PropertyNameOffset[1]; // Array of offsets to property names. } PROPERTY_NAMES, *PPROPERTY_NAMES; #define PROPERTY_NAMES_SIZE(c) \ (VARIABLE_STRUCTURE_SIZE( PROPERTY_NAMES, ULONG, (c) + 1 )) #define PROPERTY_NAME_LENGTH(v,i) \ ((v)->PropertyNameOffset[(i) + 1] - (v)->PropertyNameOffset[(i)]) #define PROPERTY_NAME(v,i) \ ((PWCHAR) Add2Ptr( (v), (v)->PropertyNameOffset[(i)])) // // PROPERTY_READ_CONTROL is the structure used to control all property read // operations. Following the structure on a DWORD boundary is either // an instance of PROPERTY_IDS or PROPERTY_SPECIFICATIONS, depending on // the operation code. // // On successful output, the data buffer will contain, on DWORD boundaries, // in order PROPERTY_VALUES, PROPERTY_IDS, and PROPERTY_NAMES. Each structure // may be absent depending on the setting of the operation code: // // PRC_READ_PROP: PROPERTY_SPECIFICATIONS => PROPERTY_VALUES // // PRC_READ_NAME: PROPERTY_IDS => PROPERTY_NAMES // // / PROPERTY_IDS // PRC_READ_ALL: => PROPERTY_NAMES // \ PROPERTY_VALUES // // typedef enum _READ_CONTROL_OPERATION { PRC_READ_PROP = 0, PRC_READ_NAME = 1, PRC_READ_ALL = 2, } READ_CONTROL_OPERATION; typedef struct _PROPERTY_READ_CONTROL { READ_CONTROL_OPERATION Op; } PROPERTY_READ_CONTROL, *PPROPERTY_READ_CONTROL; // // PROPERTY_WRITE_CONTROL is the structure used to control all property write // operations. Following the structure on a DWORD boundary is either an instance // of PROPERTY_IDS or PROPERTY_SPECIFICATIONS (used to control which properties are // being changed) and followed by PROPERTY_VALUES and PROPERTY_NAMES. The // presence of these are dependent on the operation code. // // On successful outputs, the data buffer will contain, on DWORD boundaries, // in order PROPERTY_IDS and INDIRECT_PROPERTIES. Each structure may be absent // depending on the setting of the operation code: // // PWC_WRITE_PROP: PROPERTY_SPECIFICATIONS \__/ PROPERTY_IDS // PROPERTY_VALUES / \ INDIRECT_PROPERTIES // // PWC_DELETE_PROP: PROPERTY_SPECIFICATIONS => // // PWC_WRITE_NAME: PROPERTY_IDS \__ // PROPERTY_NAMES / // // PWC_DELETE_NAME: PROPERTY_IDS => // // PROPERTY_IDS \ // PWC_WRITE_ALL: PROPERTY_NAMES => // PROPERTY_VALUES / typedef enum _WRITE_CONTROL_OPERATION { PWC_WRITE_PROP = 0, PWC_DELETE_PROP = 1, PWC_WRITE_NAME = 2, PWC_DELETE_NAME = 3, PWC_WRITE_ALL = 4, } WRITE_CONTROL_OPERATION; typedef struct _PROPERTY_WRITE_CONTROL { WRITE_CONTROL_OPERATION Op; PROPID NextPropertyId; } PROPERTY_WRITE_CONTROL, *PPROPERTY_WRITE_CONTROL; #endif // _NTFSPROP_