// Insert a row into the SYNC_POINT table private void RecordSyncPoint( bool isLeftToRight, Guid sourceMigrationSourceId, Guid targetMigrationSourceId) { using (RuntimeEntityModel context = RuntimeEntityModel.CreateInstance()) { // Get the current source high water mark var highWaterMarkQuery = (from h in context.RTHighWaterMarkSet where (h.SessionUniqueId == SessionId && h.SourceUniqueId == sourceMigrationSourceId) select h).Take(1); if (highWaterMarkQuery.Count() > 0) { RTHighWaterMark sourceHighWaterMark = highWaterMarkQuery.First(); // Get the corresponding target item MigrationItemId lastMigratedTargetItem = MigrationEngine.TranslationService.GetLastMigratedItemId(targetMigrationSourceId); // find last ChangeGroupId as of the sync point var lastChangeGroupQuery = (from g in context.RTChangeGroupSet where g.SessionUniqueId.Equals(this.SessionId) && (g.SourceUniqueId.Equals(sourceMigrationSourceId) || g.SourceUniqueId.Equals(targetMigrationSourceId)) orderby g.Id descending select g.Id).Take(1); long lastChangeGroupId = (lastChangeGroupQuery.Count() > 0 ? lastChangeGroupQuery.First() : 0); // Use the previous sync point's values lastMigratedTargetItem the sync point if there is no value for lastMigratedTargetItem.ItemId if (string.IsNullOrEmpty(lastMigratedTargetItem.ItemId)) { IQueryable<RTSyncPoint> lastChangeSyncPointQuery = (from syncPt in context.RTSyncPointSet where syncPt.SessionUniqueId.Equals(this.SessionId) && syncPt.SourceUniqueId.Equals(sourceMigrationSourceId) && syncPt.SourceHighWaterMarkName.Equals(sourceHighWaterMark.Name) orderby syncPt.Id descending select syncPt).Take(1); if (lastChangeSyncPointQuery.Count() > 0) { RTSyncPoint previousSyncPoint = lastChangeSyncPointQuery.First(); lastMigratedTargetItem.ItemId = previousSyncPoint.LastMigratedTargetItemId; lastMigratedTargetItem.ItemVersion = previousSyncPoint.LastMigratedTargetItemVersion; } } // Don't write the sync point if there is still no value for lastMigratedTargetItem.ItemId if (!string.IsNullOrEmpty(lastMigratedTargetItem.ItemId)) { // Populate and save the SyncPoint info RTSyncPoint syncPoint = RTSyncPoint.CreateRTSyncPoint( 0, // Id SessionId, sourceMigrationSourceId, sourceHighWaterMark.Name, lastMigratedTargetItem.ItemId, lastMigratedTargetItem.ItemVersion ); syncPoint.SourceHighWaterMarkValue = sourceHighWaterMark.Value; syncPoint.LastChangeGroupId = lastChangeGroupId; context.AddToRTSyncPointSet(syncPoint); context.TrySaveChanges(); TraceManager.TraceInformation("Recorded sync point for migration source {0} of session {1} with Source High Water Mark '{2}' value of '{3}'", sourceMigrationSourceId, SessionId, syncPoint.SourceHighWaterMarkName, syncPoint.SourceHighWaterMarkValue); } } } }
private void OneDirectionProcessPipeline( bool isLeftToRight, Guid sourceMigrationSourceId, Guid targetMigrationSourceId, bool contextSyncNeeded, bool bidirection) { try { m_orchPolicy.Check(); AnalysisEngine.SourceMigrationSourceId = sourceMigrationSourceId; AnalysisEngine.InvokePreAnalysisAddins(sourceMigrationSourceId); if (!AnalysisEngine.InvokeProceedToAnalysisOnAnalysisAddins(sourceMigrationSourceId)) { // In case any of the AnalysisAddins perform cleanup in the PostAnalysis method AnalysisEngine.InvokePostAnalysisAddins(sourceMigrationSourceId); return; } TraceManager.TraceInformation("Pipeline flow from {0} to {1}", sourceMigrationSourceId, targetMigrationSourceId); if (contextSyncNeeded) { TraceManager.TraceInformation("Generating context info tables for the migration source {0}", sourceMigrationSourceId); AnalysisEngine.GenerateContextInfoTables(sourceMigrationSourceId); m_orchPolicy.Check(); } TraceManager.TraceInformation("Generating delta tables for the migration source {0}", sourceMigrationSourceId); AnalysisEngine.GenerateDeltaTables(sourceMigrationSourceId); m_orchPolicy.Check(); AnalysisEngine.InvokePostDeltaComputationAddins(sourceMigrationSourceId); TraceManager.TraceInformation("Generating linking delta for the migration source {0}", sourceMigrationSourceId); LinkEngine.GenerateLinkDelta(SessionId, sourceMigrationSourceId); m_orchPolicy.Check(); AnalysisEngine.InvokePostAnalysisAddins(sourceMigrationSourceId); // Mark the items provided by the ForceSyncItemService processed at this time IForceSyncItemService forceSyncItemService = AnalysisEngine[sourceMigrationSourceId].GetService(typeof(IForceSyncItemService)) as IForceSyncItemService; if (forceSyncItemService != null) { forceSyncItemService.MarkCurrentItemsProcessed(); } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Above: data collection at source side // // Below: data migration/submission at target side // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// MigrationEngine.InvokePreMigrationAddins(targetMigrationSourceId); if (contextSyncNeeded) { TraceManager.TraceInformation("Establishing context for the migration source {0}", targetMigrationSourceId); MigrationEngine.EstablishContext(targetMigrationSourceId); m_orchPolicy.Check(); } if (!AnalysisEngine.DisableTargetAnalysis) { TraceManager.TraceInformation("Generating delta tables for the migration source {0}", targetMigrationSourceId); AnalysisEngine.GenerateDeltaTables(targetMigrationSourceId); m_orchPolicy.Check(); // Mark the items provided by the ForceSyncItemService (if any) processed at this time forceSyncItemService = AnalysisEngine[targetMigrationSourceId].GetService(typeof(IForceSyncItemService)) as IForceSyncItemService; if (forceSyncItemService != null) { forceSyncItemService.MarkCurrentItemsProcessed(); } } TraceManager.TraceInformation("Generating migration instructions for the migration source {0}", targetMigrationSourceId); AnalysisEngine.GenerateMigrationInstructions(targetMigrationSourceId); m_orchPolicy.Check(); TraceManager.TraceInformation("Post-processing delta table entries from the migration source {0}", targetMigrationSourceId); AnalysisEngine.PostProcessDeltaTableEntries(targetMigrationSourceId, bidirection); m_orchPolicy.Check(); TraceManager.TraceInformation("Migrating to the migration source {0}", targetMigrationSourceId); MigrationEngine.Migrate(targetMigrationSourceId, m_orchPolicy); m_orchPolicy.Check(); MigrationEngine.InvokePostMigrationAddins(targetMigrationSourceId); TraceManager.TraceInformation("Processing linking delta"); LinkEngine.AnalyzeLinkDelta(SessionId, sourceMigrationSourceId, bidirection); m_orchPolicy.Check(); TraceManager.TraceInformation("Migrating links to the migration source {0}", targetMigrationSourceId); LinkEngine.MigrateLinks(SessionId, targetMigrationSourceId); m_orchPolicy.Check(); } finally { // Record a sync point in the database try { RecordSyncPoint(isLeftToRight, sourceMigrationSourceId, targetMigrationSourceId); } catch (Exception ex) { TraceManager.TraceWarning("{0}: Unable to record SyncPoint data due to exception: {1}", m_thread.Name, ex.ToString()); } } }
private void ProcessPipeline(WorkFlowType workFlowType) { bool bidirection = IsBidirectionalWorkFlowType(workFlowType); bool leftToRightContextSyncNeeded = IsLeftToRightContextSyncNeeded(workFlowType); bool rightToLeftContextSyncNeeded = IsRightToLeftContextSyncNeeded(workFlowType); // Don't start processing the pipeline if the session was previously paused by conflicts until they are resolved if (m_syncStateMachine.CurrentState == PipelineState.PausedByConflict) { m_orchPolicy.PauseSessionUntilConflictsResolved(this); } do { // always notifying the listeners the pipeline is (re)starting SessionControlResume(this, new SessionControlEventArgs()); try { #region ----- LEFT TO RIGHT ----- OneDirectionProcessPipeline(true, LeftMigrationSourceid, RightMigrationSourceid, leftToRightContextSyncNeeded, bidirection); #endregion TraceManager.TraceInformation(""); #region ----- RIGHT TO LEFT ----- if (bidirection) { OneDirectionProcessPipeline(false, RightMigrationSourceid, LeftMigrationSourceid, rightToLeftContextSyncNeeded, bidirection); } else { CleanupDeltaTable(RightMigrationSourceid); } #endregion #region ----- The current round-trip is stopping ----- if (m_syncStateMachine.TryTransit(PipelineSyncCommand.STOP_CURRENT_TRIP)) { m_syncStateMachine.CommandTransitFinished(PipelineSyncCommand.STOP_CURRENT_TRIP); } #endregion } catch (SessionOrchestrationPolicy.PauseConflictedSessionException) { // When PausedConflictedSession is requested, we continue and TryNextRoundTrip will delay // until the conflicts are resolved TraceManager.TraceInformation("{0}: Session paused until conflicts are resolved!", m_thread.Name); continue; } catch (SessionOrchestrationPolicy.StopSessionException) { TraceManager.TraceInformation("{0}: Session aborted!", m_thread.Name); return; } catch (SessionOrchestrationPolicy.StopSingleTripException) { // When Stop is requested, we continue and let the policy to decide // whether it should start another round trip or not TraceManager.TraceInformation("{0}: Session stopped!", m_thread.Name); continue; } catch (Exception) { throw; } switch (workFlowType.Frequency) { case Frequency.ContinuousAutomatic: TraceManager.TraceInformation("{0}: Sync is done!", m_thread.Name); TraceManager.TraceInformation("{0}: Waiting {1} seconds before next synchronization", m_thread.Name, MilliSecondsSyncWaitInterval / 1000); break; case Frequency.ContinuousManual: case Frequency.OneTime: TraceManager.TraceInformation("{0}: Migration is done!", m_thread.Name); MigrationSessionCompleted(); break; default: throw new ArgumentException("m_orchPolicy.WorkFlowType.Frequency"); } } while (m_orchPolicy.TryStartNextRoundTrip(this, MilliSecondsSyncWaitInterval)); }
/// <summary> /// Generate migration instructions /// </summary> internal void GenerateMigrationInstructions(Guid targetSystemId) { try { // Given target system, find change group service for source and for ourselves... ConfigurationService configurationService = m_serviceContainers[targetSystemId].GetService(typeof(ConfigurationService)) as ConfigurationService; // ToDo, not sure, we can probably just pass in ource system id to let target change group service to load it. But source/target may be different, not sqlchangegroupmanager ChangeGroupService sourceChangeGroupService = m_serviceContainers[configurationService.MigrationPeer].GetService(typeof(ChangeGroupService)) as ChangeGroupService; ChangeGroupService targetChangeGroupService = m_serviceContainers[targetSystemId].GetService(typeof(ChangeGroupService)) as ChangeGroupService; // CopySourceDeltaTableToTarget //ChangeGroup deltaTableEntry; if (StopMigrationEngineOnBasicConflict) { // if one of the delta table entry on source side is conflicted, we stop long?firstConflictedChangeGroupId = sourceChangeGroupService.GetFirstConflictedChangeGroup(ChangeStatus.DeltaPending); if (firstConflictedChangeGroupId.HasValue) { return; } // if one of the migration instruction for target side is conflict, we also stop firstConflictedChangeGroupId = targetChangeGroupService.GetFirstConflictedChangeGroup(ChangeStatus.Pending); if (firstConflictedChangeGroupId.HasValue) { return; } } ChangeActionRegistrationService changeActionRegistrationService = m_serviceContainers[targetSystemId].GetService(typeof(ChangeActionRegistrationService)) as ChangeActionRegistrationService; int pageNumber = 0; IEnumerable <ChangeGroup> changeGroups; do { // NOTE: we do not increment pageNumber here, because the processed ChangeGroups are marked "DeltaComplete" and no longer // appear in the delta table changeGroups = sourceChangeGroupService.NextDeltaTablePage(pageNumber, m_pageSize, false); foreach (ChangeGroup deltaTableEntry in changeGroups) { TraceManager.TraceInformation(string.Format( "Generating migration instruction for ChangeGroup {0}", deltaTableEntry.ChangeGroupId)); ChangeGroup migrationInstructionChangeGroup = targetChangeGroupService.CreateChangeGroupForMigrationInstructionTable(deltaTableEntry); // NOTE: // migration instruction change group is created using the target change group manager/service // however, the MigrationItems in it are created by the source-side adapter // by setting the UseOtherSideMigrationItemSerializers flag, we tell this change group to use the source-side change group manager // to find the registered IMigrationItem serializer to persist these MigrationItems migrationInstructionChangeGroup.UseOtherSideMigrationItemSerializers = true; migrationInstructionChangeGroup.ReflectedChangeGroupId = deltaTableEntry.ChangeGroupId; foreach (MigrationAction action in deltaTableEntry.Actions) { try { BeforeCopyDeltaTableEntryToMigrationInstructionTable(action, configurationService.MigrationPeer); } catch (UnmappedWorkItemTypeException unmappedWITEx) { ConflictManager conflictManager = m_serviceContainers[configurationService.MigrationPeer].GetService(typeof(ConflictManager)) as ConflictManager; var conflict = WITUnmappedWITConflictType.CreateConflict(unmappedWITEx.SourceWorkItemType, action); List <MigrationAction> actions; var result = conflictManager.TryResolveNewConflict(conflictManager.SourceId, conflict, out actions); if (!result.Resolved) { continue; } else { if (result.ResolutionType == ConflictResolutionType.SkipConflictedChangeAction) { action.State = ActionState.Skipped; continue; } else { // NOTE: // So far this conflict can only be: // 1. manually resolved (skipped) AFTER // the configuration is updated with the requirement WIT mapping; // 2. skipping the conflicted migration action (i.e. not migrating the source // Work Item type. Debug.Assert( false, string.Format("WITUnmappedWITConflict is auto-resolved. Skipping this assertion will SKIP the original conflicted action '{0}'.", action.ActionId.ToString())); action.State = ActionState.Skipped; continue; } } } if (action.State == ActionState.Skipped || action.ChangeGroup.ContainsBackloggedAction) { continue; } ChangeActionHandler actionHandler; if (changeActionRegistrationService.TryGetChangeActionHandler(action.Action, action.ItemTypeReferenceName, out actionHandler)) { try { actionHandler(action, migrationInstructionChangeGroup); } catch (MigrationUnresolvedConflictException) { // We have already created an unresolved conflict, just return. return; } catch (Exception e) { ConflictManager manager = m_serviceContainers[targetSystemId].GetService(typeof(ConflictManager)) as ConflictManager; ErrorManager.TryHandleException(e, manager); } } else { string analysisProviderName; IAnalysisProvider analysisProvider; if (m_analysisProviders.TryGetValue(targetSystemId, out analysisProvider)) { analysisProviderName = analysisProvider.GetType().ToString(); } else { Debug.Fail("Unable to find IAnalysisProvider with Id: " + targetSystemId); analysisProviderName = "Unknown"; } throw new MigrationException( string.Format(MigrationToolkitResources.Culture, MigrationToolkitResources.UnknownChangeAction, action.Action.ToString(), analysisProviderName)); } } if (!migrationInstructionChangeGroup.ContainsBackloggedAction && migrationInstructionChangeGroup.Actions.Count > 0) { ChangeStatus status = migrationInstructionChangeGroup.Status; migrationInstructionChangeGroup.Status = ChangeStatus.ChangeCreationInProgress; migrationInstructionChangeGroup.Owner = deltaTableEntry.Owner; // owner may be translated too // Save the partial Change group into DB. migrationInstructionChangeGroup.Save(); // Commit the status change together. migrationInstructionChangeGroup.Status = status; deltaTableEntry.Status = ChangeStatus.DeltaComplete; migrationInstructionChangeGroup.Manager.BatchUpdateStatus( new ChangeGroup[] { migrationInstructionChangeGroup, deltaTableEntry }); } else { // If all change actions in the delta table entry are skipped. // Just mark the delta table entry as completed. deltaTableEntry.UpdateStatus(ChangeStatus.DeltaComplete); } if (this.StopRequested) { return; } } }while (changeGroups.Count() == m_pageSize); DetectBasicConflicts(targetChangeGroupService, targetSystemId, configurationService.MigrationPeer); if (this.StopRequested) { return; } ProviderDetectConflicts(targetSystemId, targetChangeGroupService); if (this.StopRequested) { return; } // dispose the target side delta table entries after we've done all conflict analysis targetChangeGroupService.BatchMarkMigrationInstructionsAsPending(); } catch (Exception e) { ConflictManager manager = m_serviceContainers[targetSystemId].GetService(typeof(ConflictManager)) as ConflictManager; ErrorManager.TryHandleException(e, manager); } }
internal void Migrate(Guid targetSideSourceId, SessionOrchestrationPolicy orchPolicy) { try { Debug.Assert(m_serviceContainers.ContainsKey(targetSideSourceId), string.Format(MigrationToolkitResources.UnknownSourceId, targetSideSourceId)); ChangeGroupService changegroupService = (ChangeGroupService)m_serviceContainers[targetSideSourceId].GetService( typeof(ChangeGroupService)); Debug.Assert(changegroupService != null, string.Format("Change group service on {0} is not loaded", targetSideSourceId)); changegroupService.DemoteInProgressActionsToPending(); int pageNumber = 0; IEnumerable <ChangeGroup> changeGroups = null; long?firstConflictedChangeGroupId = null; if (StopMigrationEngineOnBasicConflict) { firstConflictedChangeGroupId = changegroupService.GetFirstConflictedChangeGroup(ChangeStatus.Pending); } do { // NOTE: we do not increment pageNumber here, because the processed ChangeGroups are marked "Complete" and no longer // appear in the table TraceManager.TraceInformation("Loading {0} ChangeGroup(s)", m_pageSize); changeGroups = changegroupService.NextMigrationInstructionTablePage(pageNumber, m_pageSize, false, false); foreach (ChangeGroup nextChangeGroup in changeGroups) { if (firstConflictedChangeGroupId.HasValue && firstConflictedChangeGroupId <= nextChangeGroup.ChangeGroupId) { // we should not process any conflicted change group or the following ones // if StopMigrationEngineOnBasicConflict is the policy return; } //ToDo Session.OnMigratingChangeStarting(args); TraceManager.TraceInformation("Processing ChangeGroup #{0}, change {1}", nextChangeGroup.ChangeGroupId, nextChangeGroup.Name); ProcessMigrInstructionTableEntry(nextChangeGroup, targetSideSourceId); nextChangeGroup.UpdateStatus(ChangeStatus.InProgress); if (NoActiveMigrationInstructionInChangeGroup(nextChangeGroup)) { nextChangeGroup.Complete(); continue; } ConversionResult result; try { result = m_migrationProviders[targetSideSourceId].ProcessChangeGroup(nextChangeGroup); } catch (MigrationUnresolvedConflictException) { // We have already created an unresolved conflict, just return. return; } catch (Exception e) { ConflictManager manager = m_serviceContainers[targetSideSourceId].GetService(typeof(ConflictManager)) as ConflictManager; ErrorManager.TryHandleException(e, manager); return; } if (!result.ContinueProcessing) { return; } if (!string.IsNullOrEmpty(result.ChangeId)) { FinishChangeGroupMigration(nextChangeGroup, result); InvokePostChangeGroupMigrationAddins(targetSideSourceId, nextChangeGroup); } orchPolicy.Check(); } }while (changeGroups.Count() == m_pageSize); } catch (Microsoft.TeamFoundation.Migration.Toolkit.SessionOrchestrationPolicy.StopSingleTripException) { throw; } catch (Microsoft.TeamFoundation.Migration.Toolkit.SessionOrchestrationPolicy.StopSessionException) { throw; } catch (Exception e) { ConflictManager manager = m_serviceContainers[targetSideSourceId].GetService(typeof(ConflictManager)) as ConflictManager; ErrorManager.TryHandleException(e, manager); } }
public void UpdatePerItemAttachmentChangesByCheckingRelatedItemRecords( string workItemId, ChangeGroup attachmentChangeGroup, out List <FileAttachmentMetadata> additionalAttachmentToDelete) { if (string.IsNullOrEmpty(workItemId)) { throw new ArgumentNullException("workItemId"); } additionalAttachmentToDelete = new List <FileAttachmentMetadata>(); var queryByItem = QueryByItem(workItemId); var perItemExistingAttachments = from attch in queryByItem where attch.RelationshipExistsOnServer select attch; if (attachmentChangeGroup.Actions == null || attachmentChangeGroup.Actions.Count == 0) { GenericSerializer <FileAttachmentMetadata> serializer = new GenericSerializer <FileAttachmentMetadata>(); foreach (var attch in perItemExistingAttachments) { if (!attch.OtherProperty.HasValue) { continue; } for (int i = 0; i < attch.OtherProperty.Value; ++i) { try { additionalAttachmentToDelete.Add(serializer.Deserialize(attch.RelatedArtifactId)); } catch (Exception e) { TraceManager.TraceVerbose(e.ToString()); } } } foreach (var attch in perItemExistingAttachments) { attch.OtherProperty = 0; attch.RelationshipExistsOnServer = false; } m_context.TrySaveChanges(); } else { Dictionary <IMigrationFileAttachment, List <IMigrationAction> > perAttachmentChangeActions = GroupAttachmentByMetadata(attachmentChangeGroup); List <IMigrationAction> skippedActions = new List <IMigrationAction>(attachmentChangeGroup.Actions.Count); foreach (var attchSpecificActions in perAttachmentChangeActions) { if (attchSpecificActions.Value.Count == 0) { continue; } string attachmentStorageId = attchSpecificActions.Key.ToString(); int deltaAttachmentCount = GetAttachmentCountInDelta(attchSpecificActions.Value); var attachmentInStore = QueryItemSpecificAttachment(perItemExistingAttachments, attachmentStorageId); int attachmentInStoreCount = GetAttachmentInStoreCount(attachmentInStore); int serverStoreCountDiff = deltaAttachmentCount - attachmentInStoreCount; if (serverStoreCountDiff >= 0) { int redundantAttachmentActionCount = deltaAttachmentCount - serverStoreCountDiff; var addAttachmentActionToSkip = attchSpecificActions.Value.Where(a => a.Action == WellKnownChangeActionId.AddAttachment).Take(redundantAttachmentActionCount); skippedActions.AddRange(addAttachmentActionToSkip); } else if (serverStoreCountDiff < 0) { IMigrationAction action = attchSpecificActions.Value[0]; do { attachmentChangeGroup.Actions.Add(CreateDeleteAttachmentAction(action)); }while (++serverStoreCountDiff < 0); } int countAfterUpdateStore = UpdateStore(workItemId, attachmentStorageId, serverStoreCountDiff); foreach (IMigrationAction action in attchSpecificActions.Value) { XmlElement attachmentNode = action.MigrationActionDescription.DocumentElement.SelectSingleNode("/WorkItemChanges/Attachment") as XmlElement; System.Diagnostics.Debug.Assert(null != attachmentNode, "attachmentNode is NULL"); attachmentNode.SetAttribute("CountInSourceSideStore", countAfterUpdateStore.ToString()); } } foreach (IMigrationAction skippedAction in skippedActions) { attachmentChangeGroup.Actions.Remove(skippedAction); } } }
public static int TryGetSidsOfLocalGroupMembers(string serverName, string localGroupName, out List <SecurityIdentifier> sids) { if (string.IsNullOrEmpty(localGroupName)) { throw new ArgumentNullException("localGroupName"); } sids = new List <SecurityIdentifier>(); // Note: serverName can be (and usually is) null. uint entriesRead; uint totalEntries; IntPtr resumeHandle = IntPtr.Zero; IntPtr bufPtr = IntPtr.Zero; try { int returnCode = Win32GroupInterop.NetLocalGroupGetMembers(serverName, localGroupName, 0, // level 0. return the security identifier (SID) associated with the local group member. The bufptr parameter points to an array of LOCALGROUP_MEMBERS_INFO_0 structures out bufPtr, uint.MaxValue, // maximum preferred length. The method MUST allocate as much space as the data requires. out entriesRead, out totalEntries, out resumeHandle); if (returnCode != Win32GroupInterop.ReturnCode.S_OK) { return(returnCode); //if (returnCode == Win32GroupInterop.ReturnCode.ERROR_ACCESS_DENIED) //{ // //throw new UnauthorizedAccessException(AdminResources.AccessDenied()); //} //else if (returnCode == Win32GroupInterop.ReturnCode.NERR_GroupNotFound || // returnCode == Win32GroupInterop.ReturnCode.ERROR_NO_SUCH_ALIAS) //{ // //throw new ArgumentException(AdminResources.GroupNotExist(), "localGroupName"); //} ////throw new ConfigurationException(AdminResources.ErrorOperationWithReturnCode("NetLocalGroupGetMembers", returnCode.ToString(CultureInfo.CurrentCulture))); } for (int index = 0; index < entriesRead; ++index) { IntPtr ptr = new IntPtr((long)bufPtr + Marshal.SizeOf(typeof(Win32GroupInterop.LocalGroupMemberInfo0)) * index); Win32GroupInterop.LocalGroupMemberInfo0 groupMemberInfo = (Win32GroupInterop.LocalGroupMemberInfo0)Marshal.PtrToStructure(ptr, typeof(Win32GroupInterop.LocalGroupMemberInfo0)); SecurityIdentifier sid = new SecurityIdentifier(groupMemberInfo.Sid); sids.Add(sid); } return(Win32GroupInterop.ReturnCode.S_OK); } finally { if (bufPtr != IntPtr.Zero) { int rc = Win32GroupInterop.NetApiBufferFree(bufPtr); if (rc != Win32GroupInterop.ReturnCode.S_OK) { TraceManager.TraceError("Failed to free buffer returned by NetLocalGroupGetMembers(). Error: {0}", rc); } } } }
private void UpdatePerItemLinkChangeGroupsByCheckingRelatedItemRecords( string sourceItemUri, LinkChangeGroup group, ILinkProvider linkProvider, bool createDeleteActionImplicitly) { var queryByItem = QueryByItem(sourceItemUri); var perItemExistingLinks = from link in queryByItem where link.RelationshipExistsOnServer select link; if (perItemExistingLinks.Count() == 0) { // no link existed before, all 'add' link actions should be pushed to the other side // AND we are going to record these links as existing on this side now AddLinks(group.Actions); } else { // check the delta link change actions // this list contains all the actions that do not need to push into the pipeline List <LinkChangeAction> actionThatEstablishExistingLinkRelationship = new List <LinkChangeAction>(); foreach (LinkChangeAction action in group.Actions) { Debug.Assert(sourceItemUri.Equals(action.Link.SourceArtifact.Uri), "link of different action exists in the same group"); var linkQuery = from l in perItemExistingLinks where l.Relationship.Equals(action.Link.LinkType.ReferenceName) && l.RelatedArtifactId.Equals(action.Link.TargetArtifact.Uri) select l; if (action.ChangeActionId.Equals(WellKnownChangeActionId.Add)) { if (linkQuery.Count() > 0) { if (!linkQuery.First().OtherProperty.HasValue) { // link lock property is not available - required by backward-compability UpdateLink(action, true); } else { bool linkInStoreHasLock = (((WorkItemLinkStore.LinkLockStatus)linkQuery.First().OtherProperty.Value) == WorkItemLinkStore.LinkLockStatus.Locked); if (action.Link.IsLocked == linkInStoreHasLock) { // link already exist and lock-property matches - no need to push to the other side actionThatEstablishExistingLinkRelationship.Add(action); } else { UpdateLink(action, true); } } } else { // link does not exist, keep it and push through the pipeline // AND we are going to record these links as existing on this side now UpdateLink(action, true); } } else // delete { if (linkQuery.Count() > 0) { // link exists, so we will mark in our store that it no longer exists UpdateLink(action, false); } else { // link does not exist, no need to migrate this action actionThatEstablishExistingLinkRelationship.Add(action); } } } // make sure we generate "Delete Link" action for ones that exist in the our recorded link table but is not included // in delta link actions List <LinkChangeAction> deletionActions = new List <LinkChangeAction>(); if (createDeleteActionImplicitly) { foreach (var recordedExistingLink in perItemExistingLinks) { bool recordedActionInGroup = false; foreach (LinkChangeAction action in group.Actions) { if (action.Link.LinkType.ReferenceName.Equals(recordedExistingLink.Relationship, StringComparison.OrdinalIgnoreCase) && action.Link.TargetArtifact.Uri.Equals(recordedExistingLink.RelatedArtifactId, StringComparison.OrdinalIgnoreCase)) { recordedActionInGroup = true; break; } } if (!recordedActionInGroup) { TraceManager.TraceInformation("Link '{0}'->'{1}' ({2}) appears to have been deleted - generating link deletion action to be migrated", recordedExistingLink.ItemId, recordedExistingLink.RelatedArtifactId, recordedExistingLink.Relationship); Debug.Assert(linkProvider.SupportedLinkTypes.ContainsKey(recordedExistingLink.Relationship), "linkProvider.SupportedLinkTypes.ContainsKey(recordedExistingLink.Relationship) returns false"); LinkType linkType = linkProvider.SupportedLinkTypes[recordedExistingLink.Relationship]; LinkChangeAction linkDeleteAction = linkType.CreateLinkDeletionAction( recordedExistingLink.ItemId, recordedExistingLink.RelatedArtifactId, recordedExistingLink.Relationship); if (null != linkDeleteAction) { deletionActions.Add(linkDeleteAction); } recordedExistingLink.RelationshipExistsOnServer = false; } } } if (actionThatEstablishExistingLinkRelationship.Count > 0) { foreach (LinkChangeAction actionToDelete in actionThatEstablishExistingLinkRelationship) { group.DeleteChangeAction(actionToDelete); } } if (deletionActions.Count > 0) { group.PrependActions(deletionActions); } } m_context.TrySaveChanges(); }