/// <summary> /// Create or delete a file or directory with a given name. /// </summary> /// <param name="client">the functional client used to create</param> /// <param name="isDirectory">true for file and false for directory</param> /// <param name="isDeleteFlagSet">true for delete flag set</param> /// <param name="isNonAdmin">true for non admin account credential</param> /// <param name="fileNametype">the file name type: ValidFileName, SymbolicLinkInMiddle, SymbolicLinkAtLast, InvalidSymbolicLink</param> /// <param name="isValidAccessMask">true for valid access mask, which should contain DELETE or GENERIC_ALL</param> private void OperateFileOrDirectory(Smb2FunctionalClient client, bool isDirectory, bool isDeleteFlagSet, bool isNonAdmin, FileNameType fileNameType, bool isValidAccessMask) { CreateOptions_Values createOption; CreateDisposition_Values createDisposition; if (isDirectory) { createOption = CreateOptions_Values.FILE_DIRECTORY_FILE; } else { createOption = CreateOptions_Values.FILE_NON_DIRECTORY_FILE; } BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT."); client.Negotiate(TestConfig.RequestDialects, TestConfig.IsSMB1NegotiateEnabled); AccountCredential accountCredential = isNonAdmin ? TestConfig.NonAdminAccountCredential : TestConfig.AccountCredential; client.SessionSetup(TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, accountCredential, false); uint treeId; client.TreeConnect(sharePath, out treeId); //FILEID fileId; //Smb2CreateContextResponse[] createContextResponse; AccessMask accessMask = AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE; accessMask = isValidAccessMask ? accessMask : AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE; // The delete flag is set in the following situations: 1. Delete an existed file; 2. Test CreateOptions_Values.FILE_DELETE_ON_CLOSE combined with DesiredAccess createOption = isDeleteFlagSet ? (createOption | CreateOptions_Values.FILE_DELETE_ON_CLOSE) : createOption; // The createDisposition is set to FILE_OPEN if the file already existed; else, if it's the first time to create a file, this field should be set to FILE_CREATE createDisposition = (fileNameType == FileNameType.ExistedValidFileName) ? CreateDisposition_Values.FILE_OPEN : CreateDisposition_Values.FILE_CREATE; //fileName = GetFileName(isDirectory, fileNameType); //BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with create option: {0} and create disposition: {1}", createOption, createDisposition); //uint status = client.Create( // treeId, // fileName, // createOption, // out fileId, // out createContextResponse, // accessMask: accessMask, // createDisposition: createDisposition, // checker: (header, response) => // { // CheckCreateResponse(isNonAdmin, createOption, accessMask, header, response, fileNameType); // }); client.StopThreads(); List <ulong> messageIdsList = new List <ulong>(); //Task t1 = Task.Factory.StartNew(() => //{ for (int i = 0; i <= 3; i++) { AsyncCreateRequest(client, isDirectory, fileNameType, createOption, createDisposition, treeId, accessMask, messageIdsList); } //}); //t1.Wait(); //messageIdsList.Add(t2.Result); //if (t1.IsCompleted) //{ foreach (ulong messageId in messageIdsList) { Task <TCPResponse> taskResponse = Task.Factory.StartNew(() => client.CreateResponse1(messageId, checker: (header, response) => { CheckCreateResponse(isNonAdmin, createOption, accessMask, header, response, fileNameType); })); if (taskResponse.Result.status == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF."); client.Close(treeId, taskResponse.Result.fileId); } } //if (status == Smb2Status.STATUS_SUCCESS) //{ // BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF."); //client.Close(treeId, fileId); //} client.StartThreads(); client.TreeDisconnect(treeId); client.LogOff(); //} }