public ModelReplayCreateRequest(ModelReplayChannel channel, ReplayModelSwitchChannelType switchChannelType, ReplayModelChannelSequenceType channelSequence, ReplayModelDurableHandle modelDurableHandle, ReplayModelRequestedOplockLevel requestedOplockLevel, ReplayModelFileName fileName, ReplayModelCreateGuid createGuid, ReplayModelFileAttributes fileAttributes, ReplayModelCreateDisposition createDisposition, ReplayModelLeaseState leaseState, ReplayModelSetReplayFlag isSetReplayFlag, ReplayModelLeaseKey leaseKey) : base(0) { this.channel = channel; this.switchChannelType = switchChannelType; this.channelSequence = channelSequence; this.modelDurableHandle = modelDurableHandle; this.requestedOplockLevel = requestedOplockLevel; this.fileName = fileName; this.createGuid = createGuid; this.fileAttributes = fileAttributes; this.createDisposition = createDisposition; this.leaseState = leaseState; this.isSetReplayFlag = isSetReplayFlag; this.leaseKey = leaseKey; }
public void CreateRequest( ModelDialectRevision maxSmbVersionClientSupported, ReplayModelShareType shareType, ReplayModelClientSupportPersistent isClientSupportPersistent, ReplayModelSwitchChannelType switchChannelType, ReplayModelChannelSequenceType channelSequence, ReplayModelSetReplayFlag isSetReplayFlag, ReplayModelDurableHandle modelDurableHandle, ReplayModelRequestedOplockLevel requestedOplockLevel, ReplayModelLeaseState leaseState, ReplayModelFileName fileName, ReplayModelCreateGuid createGuid, ReplayModelFileAttributes fileAttributes, ReplayModelCreateDisposition createDisposition, ReplayModelLeaseKey leaseKey) { Smb2FunctionalClient client = null; switch (switchChannelType) { case ReplayModelSwitchChannelType.MainChannel: { if (smb2ClientMainChannel == null) { InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType, out treeIdMainChannel, false, isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent); } break; } case ReplayModelSwitchChannelType.ReconnectMainChannel: { Site.Assume.IsNotNull(smb2ClientMainChannel, "Main channel is expected to exist."); smb2ClientMainChannel.Disconnect(); smb2ClientMainChannel = null; InitializeMainChannel(maxSmbVersionClientSupported, clientGuidMainChannel, shareType, out treeIdMainChannel, true, isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent); break; } default: //AlternativeChannelWithMainChannel, AlternativeChannelWithDisconnectMainChannel, MainChannelWithAlternativeChannel { InitializeAlternativeChannel( clientGuidMainChannel, treeIdMainChannel, isClientSupportPersistent == ReplayModelClientSupportPersistent.ClientSupportPersistent); if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel) { smb2ClientMainChannel.Disconnect(); smb2ClientMainChannel = null; } break; } } if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel || switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel) { client = smb2ClientAlternativeChannel; } else { client = smb2ClientMainChannel; } Smb2CreateContextRequest[] contexts; RequestedOplockLevel_Values oplockLevel; LeaseStateValues requestLeaseState; FillParameters(leaseState, requestedOplockLevel, modelDurableHandle, createGuid == ReplayModelCreateGuid.DefaultCreateGuid ? createGuidMainChannel : Guid.NewGuid(), leaseKey == ReplayModelLeaseKey.DefaultLeaseKey ? leaseKeyMainChannel : Guid.NewGuid(), out requestLeaseState, out oplockLevel, out contexts); FillChannelSequence(client, channelSequence); Smb2CreateContextResponse[] serverCreateContexts; ulong createRequestId; client.CreateRequest( treeIdMainChannel, fileName == ReplayModelFileName.DefaultFileName ? fileNameMainChannel : Guid.NewGuid().ToString(), CreateOptions_Values.FILE_NON_DIRECTORY_FILE, (isSetReplayFlag == ReplayModelSetReplayFlag.WithReplayFlag ? Packet_Header_Flags_Values.FLAGS_REPLAY_OPERATION : Packet_Header_Flags_Values.NONE) | (testConfig.SendSignedRequest ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE), out createRequestId, oplockLevel, contexts, createDisposition: createDisposition == ReplayModelCreateDisposition.DefaultCreateDisposition ? CreateDisposition_Values.FILE_OPEN_IF : CreateDisposition_Values.FILE_OVERWRITE_IF, fileAttributes: fileAttributes == ReplayModelFileAttributes.DefaultFileAttributes ? File_Attributes.NONE : File_Attributes.FILE_ATTRIBUTE_TEMPORARY ); uint status = client.CreateResponse( createRequestId, out fileIdMainChannel, out serverCreateContexts, checker: (header, response) => { } ); CreateResponse( (ModelSmb2Status)status, ConvertHandle(serverCreateContexts), replayConfig); }
public static void CreateRequest( ModelDialectRevision maxSmbVersionClientSupported, ReplayModelShareType shareType, ReplayModelClientSupportPersistent clientPersistentCapability, ReplayModelSwitchChannelType switchChannelType, ReplayModelChannelSequenceType channelSequence, ReplayModelSetReplayFlag isSetReplayFlag, ReplayModelDurableHandle modelDurableHandle, ReplayModelRequestedOplockLevel requestedOplockLevel, ReplayModelLeaseState leaseState, ReplayModelFileName fileName, ReplayModelCreateGuid createGuid, ReplayModelFileAttributes fileAttributes, ReplayModelCreateDisposition createDisposition, ReplayModelLeaseKey leaseKey) { Condition.IsTrue(State == ModelState.Connected || State == ModelState.Initialized); Condition.IsNull(Request); Combination.NWise(2, maxSmbVersionClientSupported, shareType, clientPersistentCapability, switchChannelType, channelSequence, isSetReplayFlag, modelDurableHandle, requestedOplockLevel, leaseState, fileName, createGuid, fileAttributes, createDisposition, leaseKey); Combination.Isolated(channelSequence == ReplayModelChannelSequenceType.InvalidChannelSequence); Combination.Isolated(channelSequence == ReplayModelChannelSequenceType.ChannelSequenceBoundaryValid); //No lease for non durable handle Condition.IfThen(modelDurableHandle == ReplayModelDurableHandle.NormalHandle, requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 && requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV2); //No lease state or lease key(default) if not requesting lease Condition.IfThen( requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 && requestedOplockLevel != ReplayModelRequestedOplockLevel.OplockLevelLeaseV2, leaseState == ReplayModelLeaseState.LeaseStateIsNone && leaseKey == ReplayModelLeaseKey.DefaultLeaseKey); //Ensure valid lease state if requesting lease Condition.IfThen( requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 || requestedOplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2, leaseState != ReplayModelLeaseState.LeaseStateIsNone); if (State == ModelState.Initialized) { Condition.IsTrue(switchChannelType == ReplayModelSwitchChannelType.MainChannel); DialectRevision negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, Config.MaxSmbVersionSupported); MainChannel = new ModelReplayChannel(negotiateDialect, shareType, clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent); } else // There's already an open exist { //Open eixsts Condition.IsTrue(Open != null); // Ensure same dialect Condition.IsTrue(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported) == MainChannel.Connection_NegotiateDialect); // Ensure connect to same share Condition.IsTrue(shareType == MainChannel.Connection_Session_TreeConnect_Share_IsCA); switch (switchChannelType) { case ReplayModelSwitchChannelType.MainChannel: { Condition.IsTrue((clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent) == MainChannel.Connection_ClientCapabilities_SupportPersistent); break; } case ReplayModelSwitchChannelType.ReconnectMainChannel: { MainChannel.Connection_ClientCapabilities_SupportPersistent = (clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent); break; } case ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel: case ReplayModelSwitchChannelType.AlternativeChannelWithMainChannel: case ReplayModelSwitchChannelType.MainChannelWithAlternativeChannel: { AlternativeChannel = new ModelReplayChannel(MainChannel.Connection_NegotiateDialect, shareType, clientPersistentCapability == ReplayModelClientSupportPersistent.ClientSupportPersistent); break; } } #region Handle state changes when there's connection lost or reconnection if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel || switchChannelType == ReplayModelSwitchChannelType.ReconnectMainChannel) { bool isPreserved = false; ModelHelper.Log( LogType.Requirement, "3.3.7.1: The server MUST iterate over the Session.OpenTable and determine whether each Open is to be preserved for reconnect." + " If any of the following conditions is satisfied, it indicates that the Open is to be preserved for reconnect"); ModelHelper.Log( LogType.TestInfo, "Open.OplockLevel is {0}, Open.OplockState is {1}, Open.IsDurable {2}", Open.OplockLevel, Open.OplockStateIsHeld ? "Held" : "not Held", Open.IsDurable); if (Open.Lease != null) { ModelHelper.Log( LogType.TestInfo, "LeaseState is {0}", Open.Lease.LeaseState); } if (switchChannelType == ReplayModelSwitchChannelType.AlternativeChannelWithDisconnectMainChannel) { ModelHelper.Log( LogType.TestInfo, "TD does not states the open is preserved when multi channels exist."); isPreserved = true; } else if (Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelBatch && Open.OplockStateIsHeld && Open.IsDurable) // Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH { ModelHelper.Log( LogType.Requirement, "Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_BATCH and Open.OplockState is equal to Held, and Open.IsDurable is TRUE"); isPreserved = true; ModelHelper.Log( LogType.TestInfo, "Open is to be preserved for reconnect"); } else if (((Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV1 || Open.OplockLevel == ReplayModelRequestedOplockLevel.OplockLevelLeaseV2) && Open.Lease != null && Open.Lease.LeaseState == ReplayModelLeaseState.LeaseStateIncludeH && Open.OplockStateIsHeld && Open.IsDurable)) // Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_LEASE and contains SMB2_LEASE_HANDLE_CACHING { ModelHelper.Log( LogType.Requirement, "Open.OplockLevel is equal to SMB2_OPLOCK_LEVEL_LEASE, Lease.LeaseState contains SMB2_LEASE_HANDLE_CACHING," + " Open.OplockState is equal to Held, and Open.IsDurable is TRUE."); isPreserved = true; ModelHelper.Log( LogType.TestInfo, "Open is to be preserved for reconnect"); } // "The server supports leasing and Open.IsResilient is TRUE" covered by resilient model if (isPreserved) { ModelHelper.Log( LogType.Requirement, "If the Open is to be preserved for reconnect, perform the following actions:"); ModelHelper.Log( LogType.Requirement, "Set Open.Connection to NULL"); //Skip requirement for resilient handle which covered by resilient model Open.ConnectionIsNotNull = false; } else { ModelHelper.Log( LogType.Requirement, "If the Open is not to be preserved for reconnect, the server MUST close the Open as specified in section 3.3.4.17"); LastOpen = Open; Open = null; ModelHelper.Log( LogType.TestInfo, "Open is set to NULL"); } } #endregion } ModelReplayChannel channel = GetChannel(switchChannelType); ModelReplayCreateRequest replayCreateRequest = new ModelReplayCreateRequest(channel, switchChannelType, channelSequence, modelDurableHandle, requestedOplockLevel, fileName, createGuid, fileAttributes, createDisposition, leaseState, isSetReplayFlag, leaseKey); Request = replayCreateRequest; State = ModelState.Connected; }