public void SetExternalProperty(PropertyID propertyID, PropertyTypeName propertyType, byte[] propertyBytes) { PropertyContextRecord record = GetRecordByPropertyID(propertyID); if (record != null) { if (record.wPropType != propertyType) { throw new InvalidPropertyException("Property type mismatch"); } if (record.IsExternal) { HeapOrNodeID newHeapOrNodeID = NodeStorageHelper.StoreExternalProperty(this.File, this.Heap, ref m_subnodeBTree, record.HeapOrNodeID, propertyBytes); if (record.HeapOrNodeID.Value != newHeapOrNodeID.Value) { record.HeapOrNodeID = newHeapOrNodeID; UpdateRecord(record); } } else { // old record is not external but new record is, this should never happen. throw new InvalidPropertyException("Old record should be external but is not"); } } else // old record does not exist { record = new PropertyContextRecord(); record.HeapOrNodeID = NodeStorageHelper.StoreExternalProperty(this.File, this.Heap, ref m_subnodeBTree, propertyBytes); record.wPropId = propertyID; record.wPropType = propertyType; AddRecord(record); } }
public bool IsCellInUse(int rowIndex, PropertyID propertyID, PropertyTypeName propertyType) { int columnIndex = GetColumnIndexByPropertyTag(propertyID, propertyType); TableColumnDescriptor columnDescriptor = m_tcInfo.rgTCOLDESC[columnIndex]; byte[] rowBytes = GetRowBytes(rowIndex); return(IsCellInUse(columnDescriptor, rowBytes)); }
/// <returns>True if property column was added</returns> public bool AddPropertyColumnIfNotExist(PropertyID propertyID, PropertyTypeName propertyTypeName) { if (!ContainsPropertyColumn(propertyID, propertyTypeName)) { AddPropertyColumn(propertyID, propertyTypeName); return(true); } return(false); }
public void RemoveProperty(int rowIndex, PropertyName propertyName, PropertyTypeName propertyType) { Nullable <PropertyID> propertyID = m_map.GetIDFromName(propertyName); if (propertyID.HasValue) { RemoveProperty(rowIndex, propertyID.Value, propertyType); } }
public int FindColumnIndexByPropertyTag(PropertyName propertyName, PropertyTypeName propertyType) { Nullable <PropertyID> propertyID = m_map.GetIDFromName(propertyName); if (propertyID.HasValue) { return(FindColumnIndexByPropertyTag(propertyID.Value, propertyType)); } return(-1); }
public PropertyContextRecord(byte[] buffer, int offset) { wPropId = (PropertyID)LittleEndianConverter.ToUInt16(buffer, offset + 0); wPropType = (PropertyTypeName)LittleEndianConverter.ToUInt16(buffer, offset + 2); dwValueHnid = LittleEndianConverter.ToUInt32(buffer, offset + 4); if (!IsPropertyStoredInternally(wPropType)) { HeapOrNodeID = new HeapOrNodeID(buffer, offset + 4); } }
public int GetColumnIndexByPropertyTag(PropertyID propertyID, PropertyTypeName propertyType) { int columnIndex = FindColumnIndexByPropertyTag(propertyID, propertyType); if (columnIndex == -1) { throw new Exception(String.Format("Column {0} does not belong to table", GetPropertyIDString((ushort)propertyID))); } return(columnIndex); }
public bool ContainsPropertyColumn(PropertyName propertyName, PropertyTypeName propertyType) { Nullable <PropertyID> propertyID = m_map.GetIDFromName(propertyName); if (propertyID.HasValue) { return(ContainsPropertyColumn(propertyID.Value, propertyType)); } return(false); }
public void RemoveProperty(int rowIndex, PropertyID propertyID, PropertyTypeName propertyType) { int columnIndex = GetColumnIndexByPropertyTag(propertyID, propertyType); TableColumnDescriptor columnDescriptor = m_tcInfo.rgTCOLDESC[columnIndex]; if (columnDescriptor.IsStoredExternally) { RemoveExternalProperty(rowIndex, columnIndex); } byte[] rowBytes = GetRowBytes(rowIndex); UpdateCellExistenceBlock(columnDescriptor, rowBytes, false); SetRowBytes(rowIndex, rowBytes); }
public int FindColumnIndexByPropertyTag(PropertyID propertyID, PropertyTypeName propertyType) { for (int index = 0; index < m_tcInfo.rgTCOLDESC.Count; index++) { TableColumnDescriptor descriptor = m_tcInfo.rgTCOLDESC[index]; if (descriptor.PropertyID == propertyID && descriptor.PropertyType == propertyType) { return(index); } } return(-1); }
public static bool IsPropertyStoredInternally(PropertyTypeName wPropType) { // if wPropType is fixed and <= 4 bytes, then dwValueHnid is either NID or HID if (wPropType == PropertyTypeName.PtypBoolean || wPropType == PropertyTypeName.PtypInteger16 || wPropType == PropertyTypeName.PtypInteger32 || wPropType == PropertyTypeName.PtypFloating32 || wPropType == PropertyTypeName.PtypErrorCode) { return(true); } else { return(false); } }
public static bool IsPropertyStoredExternally(PropertyTypeName wPropType) { // if wPropType is fixed and <= 8 bytes then it's internal, otherwise dwValueHnid is either NID or HID if (wPropType == PropertyTypeName.PtypString || wPropType == PropertyTypeName.PtypString8 || wPropType == PropertyTypeName.PtypBinary || wPropType == PropertyTypeName.PtypObject || wPropType == PropertyTypeName.PtypGuid || wPropType == PropertyTypeName.PtypMultiString) { return(true); } else { return(false); } }
public static int GetPropertyDataLength(PropertyTypeName propertyType) { switch (propertyType) { case PropertyTypeName.PtypBoolean: return(1); case PropertyTypeName.PtypInteger16: return(2); case PropertyTypeName.PtypTime: return(8); default: return(4); } }
public void SetInternalProperty(PropertyID propertyID, PropertyTypeName propertyType, uint propertyValue) { PropertyContextRecord oldRecord = GetRecordByPropertyID(propertyID); if (oldRecord == null) { PropertyContextRecord record = new PropertyContextRecord(); record.wPropId = propertyID; record.wPropType = propertyType; record.dwValueHnid = propertyValue; this.AddRecord(record); } else { oldRecord.dwValueHnid = propertyValue; this.UpdateRecord(oldRecord); } }
public bool ContainsPropertyColumn(PropertyID propertyID, PropertyTypeName propertyTypeName) { int index = FindColumnIndexByPropertyTag(propertyID, propertyTypeName); return(index >= 0); }
public static void RopOpenStreamWithDifferentPropertyType( ObjectToOperate objectToOperate, PropertyTypeName propertyType, out CPRPTErrorCode error) { Condition.IsTrue(isInitialized); Condition.IsTrue(globalObj != ServerObjectType.Logon); Condition.IfThen(globalObj == ServerObjectType.Message || globalObj == ServerObjectType.Attachment, propertyType == PropertyTypeName.PtypBinary || propertyType == PropertyTypeName.PtypString || propertyType == PropertyTypeName.PtypObject); if (objectToOperate == ObjectToOperate.FirstObject) { Condition.IfThen(globalObj == ServerObjectType.Folder, propertyType == PropertyTypeName.PtypBinary); } else if (objectToOperate == ObjectToOperate.FifthObject) { Condition.IfThen(globalObj == ServerObjectType.Folder, propertyType == PropertyTypeName.PtypBinary || propertyType == PropertyTypeName.PtypString); } // openFlag and error is designed for negative test case. error = CPRPTErrorCode.None; if (globalObj == ServerObjectType.Attachment && propertyType == PropertyTypeName.PtypBinary) { ModelHelper.CaptureRequirement( 25502, @"[In RopOpenStream ROP] Single-valued PtypBinary type properties ([MS-OXCDATA] section 2.11.1) is supported for Attachment objects."); } if (globalObj == ServerObjectType.Attachment && propertyType == PropertyTypeName.PtypObject) { ModelHelper.CaptureRequirement( 25503, @"[In RopOpenStream ROP] Single-valued PtypObject type properties ([MS-OXCDATA] section 2.11.1) is supported for Attachment objects."); } if (globalObj == ServerObjectType.Message && propertyType == PropertyTypeName.PtypBinary) { ModelHelper.CaptureRequirement( 25506, @"[In RopOpenStream ROP] Single-valued PtypBinary type properties ([MS-OXCDATA] section 2.11.1) is supported for Message objects."); } if (globalObj == ServerObjectType.Message && propertyType == PropertyTypeName.PtypObject) { ModelHelper.CaptureRequirement( 25507, @"[In RopOpenStream ROP] Single-valued PtypObject type properties ([MS-OXCDATA] section 2.11.1) is supported for Message objects."); } if (globalObj == ServerObjectType.Message && propertyType == PropertyTypeName.PtypString) { ModelHelper.CaptureRequirement( 25509, @"[In RopOpenStream ROP] Single-valued PtypString type properties ([MS-OXCDATA] section 2.11.1) is supported for Message objects."); } if (globalObj == ServerObjectType.Attachment && propertyType == PropertyTypeName.PtypString) { if (requirementContainer[25505]) { ModelHelper.CaptureRequirement( 25505, @"[In RopOpenStream ROP] Single-valued PtypString type properties ([MS-OXCDATA] section 2.11.1) is supported for Attachment objects."); } else { error = CPRPTErrorCode.NotSupported; } } }
/// <summary> /// For discovery purposes /// </summary> public List <string> ListTable() { List <string> result = new List <string>(); result.Add("Number of Columns: " + this.ColumnCount); for (int index = 0; index < m_tcInfo.rgTCOLDESC.Count; index++) { TableColumnDescriptor descriptor = m_tcInfo.rgTCOLDESC[index]; result.Add(String.Format("Column {0}, Property Type: {1}, PropertyName: {2}, Data Length: {3}, Offset: {4}, iBit: {5}", index, descriptor.PropertyType, GetPropertyIDString((ushort)descriptor.PropertyID), descriptor.cbData, descriptor.ibData, descriptor.iBit)); } result.Add("Number of Rows: " + m_rowIndex.Count); result.Add("4-byte entries length: " + (m_tcInfo.rgib[TableContextInfo.TCI_4b])); result.Add("2-byte entries length: " + (m_tcInfo.rgib[TableContextInfo.TCI_2b] - m_tcInfo.rgib[TableContextInfo.TCI_4b])); result.Add("1-byte entries length: " + (m_tcInfo.rgib[TableContextInfo.TCI_1b] - m_tcInfo.rgib[TableContextInfo.TCI_2b])); result.Add("Row length (net): " + m_tcInfo.rgib[TableContextInfo.TCI_1b]); result.Add("Row length: " + this.RowLength); for (int rowIndex = 0; rowIndex < m_rowIndex.Count; rowIndex++) { result.Add("--------------------------------------------------------------------------------"); result.Add("Row ID: " + m_rowIndex[rowIndex].dwRowID); result.Add("Data Length: " + m_rowIndex[rowIndex].DataLength); result.Add("Row Index: " + m_rowIndex[rowIndex].dwRowIndex); for (int columnIndex = 0; columnIndex < m_tcInfo.rgTCOLDESC.Count; columnIndex++) { TableColumnDescriptor descriptor = m_tcInfo.rgTCOLDESC[columnIndex]; PropertyTypeName propertyType = descriptor.PropertyType; PropertyID propertyID = descriptor.PropertyID; string value; if (IsCellInUse(rowIndex, propertyID, propertyType)) { if (propertyType == PropertyTypeName.PtypBoolean) { bool boolValue = GetBooleanProperty(rowIndex, propertyID).Value; value = boolValue.ToString(); } else if (propertyType == PropertyTypeName.PtypInteger16) { value = GetInt16Property(rowIndex, propertyID).ToString() + " (Int16)"; } else if (propertyType == PropertyTypeName.PtypInteger32) { value = GetInt32Property(rowIndex, propertyID).ToString(); } else if (propertyType == PropertyTypeName.PtypInteger64) { value = GetInt64Property(rowIndex, propertyID).ToString() + " (Int64)"; } else if (propertyType == PropertyTypeName.PtypTime) { value = GetDateTimeProperty(rowIndex, propertyID).ToString(); } else if (propertyType == PropertyTypeName.PtypString) { value = GetStringProperty(rowIndex, propertyID); } else if (propertyType == PropertyTypeName.PtypBinary) { value = StringHelper.GetByteArrayString(GetBytesProperty(rowIndex, propertyID)); } else { value = "-" + propertyType.ToString(); } } else { value = "(Unused)"; } result.Add(GetPropertyIDString((ushort)propertyID) + ": " + value); } } return(result); }
/// <summary> /// This method is used to open a different type of properties as a Stream object, enabling the client to perform various streaming operations on the property. /// </summary> /// <param name="obj">Specifies which object will be operated.</param> /// <param name="propertyType">Specifies which type of property will be operated.</param> /// <param name="error">Returned error code.</param> public void RopOpenStreamWithDifferentPropertyType(ObjectToOperate obj, PropertyTypeName propertyType, out CPRPTErrorCode error) { #region Initialize properties and parameter error = CPRPTErrorCode.None; TaggedPropertyValue propertyTag = this.GetTaggedPropertyTag(obj); uint handle = 0; switch (this.cprptCurrentType) { case ServerObjectType.Folder: int index = obj == ObjectToOperate.FifthObject ? (int)ObjectToOperate.FirstObject : (int)obj; handle = cprptFolderHandle[index]; break; case ServerObjectType.Message: handle = cprptMessageHandle[(int)obj]; break; case ServerObjectType.Attachment: handle = cprptAttachmentHandle[(int)obj]; break; default: break; } byte openModeFlags = ConstValues.OpenModeFlagsCreate; propertyTag.PropertyTag.PropertyType = (ushort)propertyType; if (this.cprptCurrentType != ServerObjectType.Folder) { propertyTag.PropertyTag.PropertyId++; } else { if (obj == ObjectToOperate.FifthObject) { switch (propertyType) { case PropertyTypeName.PtypBinary: propertyTag.PropertyTag.PropertyId = 0x0e09; propertyTag.PropertyTag.PropertyType = 0x0102; break; case PropertyTypeName.PtypString: propertyTag.PropertyTag.PropertyId = 0x3001; propertyTag.PropertyTag.PropertyType = 0x001f; break; default: break; } openModeFlags = ConstValues.OpenModeFlagsReadOnly; } else { // Set PTagRulesData property for Folder object propertyTag.PropertyTag.PropertyId = ushort.Parse(Common.GetConfigurationPropertyValue("FolderPropertyID2", this.Site)); } } error = CPRPTErrorCode.Other; #endregion RopOpenStreamResponse openStreamResponse; uint openHandle = this.RopOpenStream(handle, out openStreamResponse, propertyTag.PropertyTag, openModeFlags, false); error = (CPRPTErrorCode)openStreamResponse.ReturnValue; #region Write stream to verify having write permission if (this.cprptCurrentType == ServerObjectType.Message) { RopWriteStreamResponse writeStreamResponse = this.RopWriteStream(openHandle, WriteData, false); this.RopCommitStream(openHandle, false); this.VerifyRopWriteStreamWithCreatePermission(writeStreamResponse); } #endregion }
/// <summary> /// Add column to an empty table context. /// If this is a Contents Table, the caller should call UpdateMessage() afterwards. /// Similarly, for attachment table, the caller should call UpdateAttachment(). /// </summary> public void AddPropertyColumn(PropertyID propertyID, PropertyTypeName propertyType) { TableColumnDescriptor newColumnDescriptor = new TableColumnDescriptor(); newColumnDescriptor.PropertyID = propertyID; newColumnDescriptor.PropertyType = propertyType; newColumnDescriptor.iBit = (byte)m_tcInfo.ColumnCount; newColumnDescriptor.cbData = (byte)GetPropertyDataLength(propertyType); // Set the ibData: // http://social.msdn.microsoft.com/Forums/en-US/os_binaryfile/thread/a5f9c653-40f5-4638-85d3-00c54607d984/ // PidTagLtpRowId and PidTagLtpRowVer must not be relocated if (newColumnDescriptor.DataLengthGroup == TableContextInfo.TCI_4b) { newColumnDescriptor.ibData = m_tcInfo.rgib[TableContextInfo.TCI_4b]; } else if (newColumnDescriptor.DataLengthGroup == TableContextInfo.TCI_2b) { newColumnDescriptor.ibData = m_tcInfo.rgib[TableContextInfo.TCI_2b]; } else { newColumnDescriptor.ibData = m_tcInfo.rgib[TableContextInfo.TCI_1b]; } // We call GetRedistributedRows() before adding the new column: List <byte[]> rows = GetRedistributedRows(newColumnDescriptor.ibData, newColumnDescriptor.cbData); // add the new column m_tcInfo.rgTCOLDESC.Add(newColumnDescriptor); // redistribute column descriptions ushort offset = (ushort)(newColumnDescriptor.ibData + newColumnDescriptor.cbData); for (int groupIndex = newColumnDescriptor.DataLengthGroup + 1; groupIndex < 3; groupIndex++) { for (int index = 0; index < m_tcInfo.rgTCOLDESC.Count; index++) { TableColumnDescriptor descriptor = m_tcInfo.rgTCOLDESC[index]; if (groupIndex == descriptor.DataLengthGroup) { // changes to descriptor will be saved when calling UpdateTableContextInfo() descriptor.ibData = offset; offset += descriptor.cbData; } } } // update the group ending offset m_tcInfo.UpdateDataLayout(); m_rowsPerBlock = (int)Math.Floor((double)DataBlock.MaximumDataLength / RowLength); // Update the rows data if (!m_tcInfo.hnidRows.IsEmpty) { if (m_tcInfo.hnidRows.IsHeapID) { m_heap.RemoveItemFromHeap(m_tcInfo.hnidRows.HeapID); CreateSubnodeForRows(); } else { if (m_subnodeRows == null) { m_subnodeRows = m_subnodeBTree.GetSubnode(m_tcInfo.hnidRows.NodeID); } m_subnodeRows.Delete(); // this will set the subnode data-tree to null // New data tree will be created when the first row will be added m_subnodeBTree.UpdateSubnodeEntry(m_tcInfo.hnidRows.NodeID, null, null); } for (int index = 0; index < rows.Count; index++) { AddRowToSubnode(index, rows[index]); } } UpdateTableContextInfo(); }
/// <returns>True if property column was added</returns> public bool AddPropertyColumnIfNotExist(PropertyName propertyName, PropertyTypeName propertyType) { PropertyID propertyID = m_map.ObtainIDFromName(propertyName); return(AddPropertyColumnIfNotExist(propertyID, propertyType)); }
protected override void Execute(NativeActivityContext context) { var prModel = new PropertyModel(PropertyName.Get(context), PropertyTypeName.Get(context), Description.Get(context), RequiresInitialization.Get(context), MarkRequiredInBuilder.Get(context)); ((ClassModel)context.Properties.Find("ClassModel")).AddProperty(prModel); }