internal static SMB1Command GetQueryInformationResponse(SMB1Header header, QueryInformationRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, request.FileName)) { state.LogToServer(Severity.Verbose, "Query Information on '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } FileNetworkOpenInformation fileInfo; header.Status = SMB1FileStoreHelper.QueryInformation(out fileInfo, share.FileStore, request.FileName, session.SecurityContext); if (header.Status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName)); } QueryInformationResponse response = new QueryInformationResponse(); response.FileAttributes = SMB1FileStoreHelper.GetFileAttributes(fileInfo.FileAttributes); response.LastWriteTime = fileInfo.LastWriteTime; response.FileSize = (uint)Math.Min(UInt32.MaxValue, fileInfo.EndOfFile); return(response); }
internal static SMB1Command GetFindClose2Request(SMB1Header header, FindClose2Request request, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); session.RemoveOpenSearch(request.SearchHandle); return(new FindClose2Response()); }
internal static SMB1Command GetRenameResponse(SMB1Header header, RenameRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.OldFileName)) { state.LogToServer(Severity.Verbose, "Rename '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.OldFileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.NewFileName)) { state.LogToServer(Severity.Verbose, "Rename '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.OldFileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } header.Status = SMB1FileStoreHelper.Rename(share.FileStore, request.OldFileName, request.NewFileName, request.SearchAttributes, session.SecurityContext); if (header.Status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName)); } return(new RenameResponse()); }
internal static SMB1Command GetSetInformation2Response(SMB1Header header, SetInformation2Request request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { header.Status = NTStatus.STATUS_SMB_BAD_FID; return(new ErrorResponse(request.CommandName)); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "Set Information 2 on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } header.Status = SMB1FileStoreHelper.SetInformation2(share.FileStore, openFile.Handle, request.CreationDateTime, request.LastAccessDateTime, request.LastWriteDateTime); if (header.Status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName)); } return(new SetInformation2Response()); }
internal static SMB1Command GetTreeDisconnectResponse(SMB1Header header, TreeDisconnectRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); session.DisconnectTree(header.TID); state.LogToServer(Severity.Information, "Tree Disconnect: User '{0}' disconnected from '{1}' (UID: {2}, TID: {3})", session.UserName, share.Name, header.UID, header.TID); return(new TreeDisconnectResponse()); }
internal static Transaction2QueryFileInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryFileInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "QueryFileInformation failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, subcommand.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "QueryFileInformation on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } } Transaction2QueryFileInformationResponse response = new Transaction2QueryFileInformationResponse(); if (subcommand.IsPassthroughInformationLevel && subcommand.FileInformationClass != FileInformationClass.FileAllInformation) { FileInformation fileInfo; NTStatus status = share.FileStore.GetFileInformation(out fileInfo, openFile.Handle, subcommand.FileInformationClass); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.FileInformationClass, status, subcommand.FID); header.Status = status; return(null); } state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information class: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.FileInformationClass, subcommand.FID); response.SetFileInformation(fileInfo); } else { // The FILE_ALL_INFORMATION structure described in [MS-FSCC], is NOT used by [MS-SMB] if (subcommand.IsPassthroughInformationLevel && subcommand.FileInformationClass == FileInformationClass.FileAllInformation) { subcommand.QueryInformationLevel = QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO; } QueryInformation queryInformation; NTStatus status = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, openFile.Handle, subcommand.QueryInformationLevel); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.QueryInformationLevel, status, subcommand.FID); header.Status = status; return(null); } state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}. (FID: {3})", share.Name, openFile.Path, subcommand.QueryInformationLevel, subcommand.FID); response.SetQueryInformation(queryInformation); } return(response); }
internal static Transaction2QueryPathInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2QueryPathInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); string path = subcommand.FileName; if (!path.StartsWith(@"\")) { path = @"\" + path; } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, path)) { state.LogToServer(Severity.Verbose, "QueryPathInformation on '{0}{1}' failed. User '{2}' was denied access.", share.Name, path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } } Transaction2QueryPathInformationResponse response = new Transaction2QueryPathInformationResponse(); if (subcommand.IsPassthroughInformationLevel && subcommand.FileInformationClass != FileInformationClass.FileAllInformation) { FileInformation fileInfo; NTStatus status = SMB1FileStoreHelper.GetFileInformation(out fileInfo, share.FileStore, path, subcommand.FileInformationClass, session.SecurityContext); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information class: {2}, NTStatus: {3}", share.Name, path, subcommand.FileInformationClass, status); header.Status = status; return(null); } state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information class: {2}", share.Name, path, subcommand.FileInformationClass); response.SetFileInformation(fileInfo); } else { // The FILE_ALL_INFORMATION structure described in [MS-FSCC], is NOT used by [MS-SMB] if (subcommand.IsPassthroughInformationLevel && subcommand.FileInformationClass == FileInformationClass.FileAllInformation) { subcommand.QueryInformationLevel = QueryInformationLevel.SMB_QUERY_FILE_ALL_INFO; } QueryInformation queryInformation; NTStatus status = SMB1FileStoreHelper.GetFileInformation(out queryInformation, share.FileStore, path, subcommand.QueryInformationLevel, session.SecurityContext); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "GetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}", share.Name, path, subcommand.QueryInformationLevel, status); header.Status = status; return(null); } state.LogToServer(Severity.Information, "GetFileInformation on '{0}{1}' succeeded. Information level: {2}", share.Name, path, subcommand.QueryInformationLevel); response.SetQueryInformation(queryInformation); } return(response); }
internal static Transaction2SetFileInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2SetFileInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } } SetInformation information; try { information = SetInformation.GetSetInformation(subcommand.InformationBytes, subcommand.InformationLevel); } catch (UnsupportedInformationLevelException) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_OS2_INVALID_LEVEL", share.Name, openFile.Path, subcommand.InformationLevel); header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; return(null); } catch (Exception) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: STATUS_INVALID_PARAMETER", share.Name, openFile.Path, subcommand.InformationLevel); header.Status = NTStatus.STATUS_INVALID_PARAMETER; return(null); } NTStatus status = SMB1FileStoreHelper.SetFileInformation(share.FileStore, openFile.Handle, information); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "SetFileInformation on '{0}{1}' failed. Information level: {2}, NTStatus: {3}", share.Name, openFile.Path, subcommand.InformationLevel, status); header.Status = status; return(null); } state.LogToServer(Severity.Information, "SetFileInformation on '{0}{1}' succeeded. Information level: {2}", share.Name, openFile.Path, subcommand.InformationLevel); Transaction2SetFileInformationResponse response = new Transaction2SetFileInformationResponse(); return(response); }
internal static SMB1Command GetReadResponse(SMB1Header header, ReadAndXRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "Read failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, request.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(new ErrorResponse(request.CommandName)); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "Read from '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } uint maxCount = request.MaxCount; if ((share is FileSystemShare) && state.LargeRead) { maxCount = request.MaxCountLarge; } byte[] data; header.Status = share.FileStore.ReadFile(out data, openFile.Handle, (long)request.Offset, (int)maxCount); if (header.Status == NTStatus.STATUS_END_OF_FILE) { // [MS-CIFS] Windows servers set the DataLength field to 0x0000 and return STATUS_SUCCESS. // JCIFS expects the same response. data = new byte[0]; header.Status = NTStatus.STATUS_SUCCESS; } else if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Read from '{0}{1}' failed. NTStatus: {2}. (FID: {3})", share.Name, openFile.Path, header.Status, request.FID); return(new ErrorResponse(request.CommandName)); } ReadAndXResponse response = new ReadAndXResponse(); if (share is FileSystemShare) { // If the client reads from a disk file, this field MUST be set to -1 (0xFFFF) response.Available = 0xFFFF; } response.Data = data; return(response); }
internal static Transaction2SetFSInformationResponse GetSubcommandResponse(SMB1Header header, Transaction2SetFSInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, @"\")) { state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } } if (!subcommand.IsPassthroughInformationLevel) { state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Not a pass-through information level.", share.Name); header.Status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } FileSystemInformation fileSystemInfo; try { fileSystemInfo = FileSystemInformation.GetFileSystemInformation(subcommand.InformationBytes, 0, subcommand.FileSystemInformationClass); } catch (UnsupportedInformationLevelException) { state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: STATUS_OS2_INVALID_LEVEL.", share.Name, subcommand.FileSystemInformationClass); header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; return(null); } catch (Exception) { state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: STATUS_INVALID_PARAMETER.", share.Name, subcommand.FileSystemInformationClass); header.Status = NTStatus.STATUS_INVALID_PARAMETER; return(null); } NTStatus status = share.FileStore.SetFileSystemInformation(fileSystemInfo); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: {2}.", share.Name, subcommand.FileSystemInformationClass, status); header.Status = status; return(null); } state.LogToServer(Severity.Verbose, "SetFileSystemInformation on '{0}' succeeded. Information class: {1}.", share.Name, subcommand.FileSystemInformationClass); return(new Transaction2SetFSInformationResponse()); }
internal static SMB1Command GetTreeConnectResponse(SMB1Header header, TreeConnectAndXRequest request, SMB1ConnectionState state, NamedPipeShare services, SMBShareCollection shares) { SMB1Session session = state.GetSession(header.UID); bool isExtended = (request.Flags & TreeConnectFlags.ExtendedResponse) > 0; string shareName = ServerPathUtils.GetShareName(request.Path); ISMBShare share; ServiceName serviceName; OptionalSupportFlags supportFlags; if (String.Equals(shareName, NamedPipeShare.NamedPipeShareName, StringComparison.InvariantCultureIgnoreCase)) { share = services; serviceName = ServiceName.NamedPipe; supportFlags = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS | OptionalSupportFlags.SMB_CSC_NO_CACHING; } else { share = shares.GetShareFromName(shareName); serviceName = ServiceName.DiskShare; supportFlags = OptionalSupportFlags.SMB_SUPPORT_SEARCH_BITS | OptionalSupportFlags.SMB_CSC_CACHE_MANUAL_REINT; if (share == null) { header.Status = NTStatus.STATUS_OBJECT_PATH_NOT_FOUND; return(new ErrorResponse(request.CommandName)); } if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\")) { state.LogToServer(Severity.Verbose, "Tree Connect to '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } ushort?treeID = session.AddConnectedTree(share); if (!treeID.HasValue) { header.Status = NTStatus.STATUS_INSUFF_SERVER_RESOURCES; return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Information, "Tree Connect: User '{0}' connected to '{1}'", session.UserName, share.Name); header.TID = treeID.Value; if (isExtended) { return(CreateTreeConnectResponseExtended(serviceName, supportFlags)); } else { return(CreateTreeConnectResponse(serviceName, supportFlags)); } }
internal static Transaction2QueryFSInformationResponse GetSubcommandResponse(SMB1Header header, uint maxDataCount, Transaction2QueryFSInformationRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, @"\")) { state.LogToServer(Severity.Verbose, "QueryFileSystemInformation on '{0}' failed. User '{1}' was denied access.", share.Name, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(null); } } Transaction2QueryFSInformationResponse response = new Transaction2QueryFSInformationResponse(); if (subcommand.IsPassthroughInformationLevel) { FileSystemInformation fileSystemInfo; NTStatus status = share.FileStore.GetFileSystemInformation(out fileSystemInfo, subcommand.FileSystemInformationClass); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "GetFileSystemInformation on '{0}' failed. Information class: {1}, NTStatus: {2}", share.Name, subcommand.FileSystemInformationClass, status); header.Status = status; return(null); } state.LogToServer(Severity.Information, "GetFileSystemInformation on '{0}' succeeded. Information class: {1}", share.Name, subcommand.FileSystemInformationClass); response.SetFileSystemInformation(fileSystemInfo); } else { QueryFSInformation queryFSInformation; NTStatus status = SMB1FileStoreHelper.GetFileSystemInformation(out queryFSInformation, share.FileStore, subcommand.QueryFSInformationLevel); if (status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "GetFileSystemInformation on '{0}' failed. Information level: {1}, NTStatus: {2}", share.Name, subcommand.QueryFSInformationLevel, status); header.Status = status; return(null); } state.LogToServer(Severity.Information, "GetFileSystemInformation on '{0}' succeeded. Information level: {1}", share.Name, subcommand.QueryFSInformationLevel); response.SetQueryFSInformation(queryFSInformation, header.UnicodeFlag); } if (response.InformationBytes.Length > maxDataCount) { header.Status = NTStatus.STATUS_BUFFER_OVERFLOW; response.InformationBytes = ByteReader.ReadBytes(response.InformationBytes, 0, (int)maxDataCount); } return(response); }
internal static SMB1Command GetReadResponse(SMB1Header header, ReadAndXRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "ReadAndX from '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } uint maxCount = request.MaxCount; if ((share is FileSystemShare) && state.LargeRead) { maxCount = request.MaxCountLarge; } byte[] data; header.Status = share.FileStore.ReadFile(out data, openFile.Handle, (long)request.Offset, (int)maxCount); if (header.Status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName)); } ReadAndXResponse response = new ReadAndXResponse(); if (share is FileSystemShare) { // If the client reads from a disk file, this field MUST be set to -1 (0xFFFF) response.Available = 0xFFFF; } response.Data = data; return(response); }
internal static void ProcessNTCancelRequest(SMB1Header header, NTCancelRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); SMB1AsyncContext context = state.GetAsyncContext(header.UID, header.TID, header.PID, header.MID); if (context != null) { NTStatus status = share.FileStore.Cancel(context.IORequest); OpenFileObject openFile = session.GetOpenFileObject(context.FileID); if (openFile != null) { state.LogToServer(Severity.Information, "Cancel: Requested cancel on '{0}{1}', NTStatus: {2}. PID: {3}. MID: {4}.", share.Name, openFile.Path, status, context.PID, context.MID); } if (status == NTStatus.STATUS_SUCCESS || status == NTStatus.STATUS_CANCELLED) { state.RemoveAsyncContext(context); } } }
internal static SMB1Command GetCloseResponse(SMB1Header header, CloseRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { header.Status = NTStatus.STATUS_SMB_BAD_FID; return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Information, "Close: Closing '{0}{1}'", share.Name, openFile.Path); header.Status = share.FileStore.CloseFile(openFile.Handle); if (header.Status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName)); } session.RemoveOpenFile(request.FID); return(new CloseResponse()); }
internal static Transaction2FindNext2Response GetSubcommandResponse(SMB1Header header, uint maxDataCount, Transaction2FindNext2Request subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenSearch openSearch = session.GetOpenSearch(subcommand.SID); if (openSearch == null) { state.LogToServer(Severity.Verbose, "FindNext2 failed. Invalid SID."); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } bool returnResumeKeys = (subcommand.Flags & FindFlags.SMB_FIND_RETURN_RESUME_KEYS) > 0; int maxLength = (int)maxDataCount; int maxCount = Math.Min(openSearch.Entries.Count - openSearch.EnumerationLocation, subcommand.SearchCount); List <QueryDirectoryFileInformation> segment = openSearch.Entries.GetRange(openSearch.EnumerationLocation, maxCount); FindInformationList findInformationList; try { findInformationList = FindInformationHelper.ToFindInformationList(segment, header.UnicodeFlag, maxLength); } catch (UnsupportedInformationLevelException) { state.LogToServer(Severity.Verbose, "FindNext2: Unsupported information level: {0}.", subcommand.InformationLevel); header.Status = NTStatus.STATUS_OS2_INVALID_LEVEL; return(null); } int returnCount = findInformationList.Count; Transaction2FindNext2Response response = new Transaction2FindNext2Response(); response.SetFindInformationList(findInformationList, header.UnicodeFlag); openSearch.EnumerationLocation += returnCount; response.EndOfSearch = (openSearch.EnumerationLocation == openSearch.Entries.Count); if (response.EndOfSearch) { session.RemoveOpenSearch(subcommand.SID); } return(response); }
internal static SMB1Command GetWriteResponse(SMB1Header header, WriteAndXRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "Write failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, request.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(new ErrorResponse(request.CommandName)); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "Write to '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } int numberOfBytesWritten; header.Status = share.FileStore.WriteFile(out numberOfBytesWritten, openFile.Handle, (long)request.Offset, request.Data); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Write to '{0}{1}' failed. NTStatus: {2}. (FID: {3})", share.Name, openFile.Path, header.Status, request.FID); return(new ErrorResponse(request.CommandName)); } WriteAndXResponse response = new WriteAndXResponse(); response.Count = (uint)numberOfBytesWritten; if (share is FileSystemShare) { // If the client wrote to a disk file, this field MUST be set to 0xFFFF. response.Available = 0xFFFF; } return(response); }
internal static void ProcessNTTransactNotifyChangeRequest(SMB1Header header, uint maxParameterCount, NTTransactNotifyChangeRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); SMB1AsyncContext context = state.CreateAsyncContext(header.UID, header.TID, header.PID, header.MID, subcommand.FID, state); // We wish to make sure that the 'Monitoring started' will appear before the 'Monitoring completed' in the log lock (context) { header.Status = share.FileStore.NotifyChange(out context.IORequest, openFile.Handle, subcommand.CompletionFilter, subcommand.WatchTree, (int)maxParameterCount, OnNotifyChangeCompleted, context); if (header.Status == NTStatus.STATUS_PENDING) { state.LogToServer(Severity.Verbose, "NotifyChange: Monitoring of '{0}{1}' started. PID: {2}. MID: {3}.", share.Name, openFile.Path, context.PID, context.MID); } else if (header.Status == NTStatus.STATUS_NOT_SUPPORTED) { // [MS-CIFS] If the server does not support the NT_TRANSACT_NOTIFY_CHANGE subcommand, it can return an // error response with STATUS_NOT_IMPLEMENTED [..] in response to an NT_TRANSACT_NOTIFY_CHANGE Request. header.Status = NTStatus.STATUS_NOT_IMPLEMENTED; } } }
internal static SMB1Command GetDeleteResponse(SMB1Header header, DeleteRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.FileName)) { state.LogToServer(Severity.Verbose, "Delete '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } // [MS-CIFS] This command cannot delete directories or volumes. header.Status = SMB1FileStoreHelper.DeleteFile(share.FileStore, request.FileName, session.SecurityContext); if (header.Status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName)); } return(new DeleteResponse()); }
internal static SMB1Command GetCheckDirectoryResponse(SMB1Header header, CheckDirectoryRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, request.DirectoryName)) { state.LogToServer(Severity.Verbose, "Check Directory '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.DirectoryName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } header.Status = SMB1FileStoreHelper.CheckDirectory(share.FileStore, request.DirectoryName, session.SecurityContext); if (header.Status != NTStatus.STATUS_SUCCESS) { return(new ErrorResponse(request.CommandName)); } return(new CheckDirectoryResponse()); }
private static NTTransactIOCTLResponse GetSubcommandResponse(SMB1Header header, uint maxDataCount, NTTransactIOCTLRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); string ctlCode = Enum.IsDefined(typeof(IoControlCode), subcommand.FunctionCode) ? ((IoControlCode)subcommand.FunctionCode).ToString() : ("0x" + subcommand.FunctionCode.ToString("X8")); if (!subcommand.IsFsctl) { // [MS-SMB] If the IsFsctl field is set to zero, the server SHOULD fail the request with STATUS_NOT_SUPPORTED state.LogToServer(Severity.Verbose, "IOCTL: Non-FSCTL requests are not supported. CTL Code: {0}", ctlCode); header.Status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "IOCTL failed. CTL Code: {0}. Invalid FID. (UID: {1}, TID: {2}, FID: {3})", ctlCode, header.UID, header.TID, subcommand.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } int maxOutputLength = (int)maxDataCount; byte[] output; header.Status = share.FileStore.DeviceIOControl(openFile.Handle, subcommand.FunctionCode, subcommand.Data, out output, maxOutputLength); if (header.Status != NTStatus.STATUS_SUCCESS && header.Status != NTStatus.STATUS_BUFFER_OVERFLOW) { state.LogToServer(Severity.Verbose, "IOCTL failed. CTL Code: {0}. NTStatus: {1}. (FID: {2})", ctlCode, header.Status, subcommand.FID); return(null); } state.LogToServer(Severity.Verbose, "IOCTL succeeded. CTL Code: {0}. (FID: {1})", ctlCode, subcommand.FID); NTTransactIOCTLResponse response = new NTTransactIOCTLResponse(); response.Data = output; return(response); }
internal static SMB1Command GetCloseResponse(SMB1Header header, CloseRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "Close failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, request.FID); header.Status = NTStatus.STATUS_SMB_BAD_FID; return(new ErrorResponse(request.CommandName)); } header.Status = share.FileStore.CloseFile(openFile.Handle); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Information, "Close: Closing '{0}{1}' failed. NTStatus: {2}. (UID: {3}, TID: {4}, FID: {5})", share.Name, openFile.Path, header.Status, header.UID, header.TID, request.FID); return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Information, "Close: Closed '{0}{1}'. (UID: {2}, TID: {3}, FID: {4})", share.Name, openFile.Path, header.UID, header.TID, request.FID); session.RemoveOpenFile(request.FID); return(new CloseResponse()); }
private static NTTransactQuerySecurityDescriptorResponse GetSubcommandResponse(SMB1Header header, uint maxDataCount, NTTransactQuerySecurityDescriptorRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "GetSecurityInformation failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, subcommand.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } int maxOutputLength = (int)maxDataCount; SecurityDescriptor securityDescriptor; header.Status = share.FileStore.GetSecurityInformation(out securityDescriptor, openFile.Handle, subcommand.SecurityInfoFields); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.SecurityInfoFields.ToString("X"), header.Status, subcommand.FID); return(null); } NTTransactQuerySecurityDescriptorResponse response = new NTTransactQuerySecurityDescriptorResponse(); response.LengthNeeded = (uint)securityDescriptor.Length; if (response.LengthNeeded <= maxDataCount) { state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' succeeded. Security information: 0x{2}. (FID: {3})", share.Name, openFile.Path, subcommand.SecurityInfoFields.ToString("X"), subcommand.FID); response.SecurityDescriptor = securityDescriptor; } else { state.LogToServer(Severity.Verbose, "GetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: STATUS_BUFFER_TOO_SMALL. (FID: {3})", share.Name, openFile.Path, subcommand.SecurityInfoFields.ToString("X"), subcommand.FID); header.Status = NTStatus.STATUS_BUFFER_TOO_SMALL; } return(response); }
internal static TransactionTransactNamedPipeResponse GetSubcommandResponse(SMB1Header header, TransactionTransactNamedPipeRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } int maxOutputLength = UInt16.MaxValue; byte[] output; header.Status = share.FileStore.DeviceIOControl(openFile.Handle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, subcommand.WriteData, out output, maxOutputLength); if (header.Status != NTStatus.STATUS_SUCCESS) { return(null); } TransactionTransactNamedPipeResponse response = new TransactionTransactNamedPipeResponse(); response.ReadData = output; return(response); }
private static NTTransactSetSecurityDescriptorResponse GetSubcommandResponse(SMB1Header header, NTTransactSetSecurityDescriptorRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "SetSecurityInformation failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, subcommand.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } header.Status = share.FileStore.SetSecurityInformation(openFile.Handle, subcommand.SecurityInformation, subcommand.SecurityDescriptor); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' failed. Security information: 0x{2}, NTStatus: {3}. (FID: {4})", share.Name, openFile.Path, subcommand.SecurityInformation.ToString("X"), header.Status, subcommand.FID); return(null); } state.LogToServer(Severity.Verbose, "SetSecurityInformation on '{0}{1}' succeeded. Security information: 0x{2}. (FID: {3})", share.Name, openFile.Path, subcommand.SecurityInformation.ToString("X"), subcommand.FID); NTTransactSetSecurityDescriptorResponse response = new NTTransactSetSecurityDescriptorResponse(); return(response); }
internal static SMB1Command GetSetInformationResponse(SMB1Header header, SetInformationRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasWriteAccess(session.SecurityContext, request.FileName)) { state.LogToServer(Severity.Verbose, "Set Information on '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } header.Status = SMB1FileStoreHelper.SetInformation(share.FileStore, request.FileName, request.FileAttributes, request.LastWriteTime, session.SecurityContext); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Set Information on '{0}{1}' failed. NTStatus: {2}", share.Name, request.FileName, header.Status); return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Verbose, "Set Information on '{0}{1}' succeeded.", share.Name, request.FileName); return(new SetInformationResponse()); }
internal static SMB1Command GetReadResponse(SMB1Header header, ReadRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); OpenFileObject openFile = session.GetOpenFileObject(request.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "Read failed. Invalid FID. (UID: {0}, TID: {1}, FID: {2})", header.UID, header.TID, request.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(new ErrorResponse(request.CommandName)); } if (share is FileSystemShare) { if (!((FileSystemShare)share).HasReadAccess(session.SecurityContext, openFile.Path)) { state.LogToServer(Severity.Verbose, "Read from '{0}{1}' failed. User '{2}' was denied access.", share.Name, openFile.Path, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } byte[] data; header.Status = share.FileStore.ReadFile(out data, openFile.Handle, request.ReadOffsetInBytes, request.CountOfBytesToRead); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Read from '{0}{1}' failed. NTStatus: {2}. (FID: {3})", share.Name, openFile.Path, header.Status, request.FID); return(new ErrorResponse(request.CommandName)); } ReadResponse response = new ReadResponse(); response.Bytes = data; response.CountOfBytesReturned = (ushort)data.Length; return(response); }
internal static SMB1Command GetOpenAndXResponse(SMB1Header header, OpenAndXRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); bool isExtended = (request.Flags & OpenFlags.SMB_OPEN_EXTENDED_RESPONSE) > 0; string path = request.FileName; if (!path.StartsWith(@"\")) { path = @"\" + path; } AccessMask desiredAccess; ShareAccess shareAccess; CreateDisposition createDisposition; try { desiredAccess = ToAccessMask(request.AccessMode.AccessMode); shareAccess = ToShareAccess(request.AccessMode.SharingMode); createDisposition = ToCreateDisposition(request.OpenMode); } catch (ArgumentException) { // Invalid input according to MS-CIFS header.Status = NTStatus.STATUS_OS2_INVALID_ACCESS; return(new ErrorResponse(request.CommandName)); } CreateOptions createOptions = ToCreateOptions(request.AccessMode); FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(desiredAccess, createDisposition); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess)) { state.LogToServer(Severity.Verbose, "OpenAndX: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } object handle; FileStatus fileStatus; header.Status = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, 0, shareAccess, createDisposition, createOptions, session.SecurityContext); if (header.Status != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "OpenAndX: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, header.Status); return(new ErrorResponse(request.CommandName)); } FileAccess fileAccess = ToFileAccess(request.AccessMode.AccessMode); ushort? fileID = session.AddOpenFile(header.TID, share.Name, path, handle, fileAccess); if (!fileID.HasValue) { share.FileStore.CloseFile(handle); state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. Too many open files.", share.Name, path); header.Status = NTStatus.STATUS_TOO_MANY_OPENED_FILES; return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Verbose, "OpenAndX: Opened '{0}{1}'. (UID: {2}, TID: {3}, FID: {4})", share.Name, path, header.UID, header.TID, fileID.Value); OpenResult openResult = ToOpenResult(fileStatus); if (share is NamedPipeShare) { if (isExtended) { return(CreateResponseExtendedForNamedPipe(fileID.Value, openResult)); } else { return(CreateResponseForNamedPipe(fileID.Value, openResult)); } } else // FileSystemShare { FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle); if (isExtended) { return(CreateResponseExtendedFromFileInfo(fileInfo, fileID.Value, openResult)); } else { return(CreateResponseFromFileInfo(fileInfo, fileID.Value, openResult)); } } }
internal static SMB1Command GetNTCreateResponse(SMB1Header header, NTCreateAndXRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); bool isExtended = (request.Flags & NTCreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE) > 0; string path = request.FileName; FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess)) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } object handle; FileStatus fileStatus; NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, request.DesiredAccess, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext); if (createStatus != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: '{2}'.", share.Name, path, createStatus); header.Status = createStatus; return(new ErrorResponse(request.CommandName)); } state.LogToServer(Severity.Verbose, "Create: Opened '{0}{1}'.", share.Name, path); ushort?fileID = session.AddOpenFile(header.TID, path, handle); if (!fileID.HasValue) { share.FileStore.CloseFile(handle); header.Status = NTStatus.STATUS_TOO_MANY_OPENED_FILES; return(new ErrorResponse(request.CommandName)); } if (share is NamedPipeShare) { if (isExtended) { return(CreateResponseExtendedForNamedPipe(fileID.Value, FileStatus.FILE_OPENED)); } else { return(CreateResponseForNamedPipe(fileID.Value, FileStatus.FILE_OPENED)); } } else // FileSystemShare { FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle); if (isExtended) { NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileInformation(fileInfo, fileID.Value, fileStatus); if ((request.Flags & NTCreateFlags.NT_CREATE_REQUEST_OPBATCH) > 0) { response.OpLockLevel = OpLockLevel.BatchOpLockGranted; } return(response); } else { NTCreateAndXResponse response = CreateResponseFromFileInformation(fileInfo, fileID.Value, fileStatus); if ((request.Flags & NTCreateFlags.NT_CREATE_REQUEST_OPBATCH) > 0) { response.OpLockLevel = OpLockLevel.BatchOpLockGranted; } return(response); } } }
internal static SMB1Command GetNTCreateResponse(SMB1Header header, NTCreateAndXRequest request, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); bool isExtended = (request.Flags & NTCreateFlags.NT_CREATE_REQUEST_EXTENDED_RESPONSE) > 0; string path = request.FileName; if (!path.StartsWith(@"\")) { path = @"\" + path; } FileAccess createAccess = NTFileStoreHelper.ToCreateFileAccess(request.DesiredAccess, request.CreateDisposition); if (share is FileSystemShare) { if (!((FileSystemShare)share).HasAccess(session.SecurityContext, path, createAccess)) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. User '{2}' was denied access.", share.Name, request.FileName, session.UserName); header.Status = NTStatus.STATUS_ACCESS_DENIED; return(new ErrorResponse(request.CommandName)); } } object handle; FileStatus fileStatus; FileAttributes fileAttributes = ToFileAttributes(request.ExtFileAttributes); // GetFileInformation/FileNetworkOpenInformation requires FILE_READ_ATTRIBUTES AccessMask desiredAccess = request.DesiredAccess | (AccessMask)FileAccessMask.FILE_READ_ATTRIBUTES; NTStatus createStatus = share.FileStore.CreateFile(out handle, out fileStatus, path, desiredAccess, fileAttributes, request.ShareAccess, request.CreateDisposition, request.CreateOptions, session.SecurityContext); if (createStatus != NTStatus.STATUS_SUCCESS) { state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. NTStatus: {2}.", share.Name, path, createStatus); header.Status = createStatus; return(new ErrorResponse(request.CommandName)); } FileAccess fileAccess = NTFileStoreHelper.ToFileAccess(desiredAccess); ushort? fileID = session.AddOpenFile(header.TID, share.Name, path, handle, fileAccess); if (!fileID.HasValue) { share.FileStore.CloseFile(handle); state.LogToServer(Severity.Verbose, "Create: Opening '{0}{1}' failed. Too many open files.", share.Name, path); header.Status = NTStatus.STATUS_TOO_MANY_OPENED_FILES; return(new ErrorResponse(request.CommandName)); } string fileAccessString = fileAccess.ToString().Replace(", ", "|"); string shareAccessString = request.ShareAccess.ToString().Replace(", ", "|"); state.LogToServer(Severity.Verbose, "Create: Opened '{0}{1}', FileAccess: {2}, ShareAccess: {3}. (UID: {4}, TID: {5}, FID: {6})", share.Name, path, fileAccessString, shareAccessString, header.UID, header.TID, fileID.Value); if (share is NamedPipeShare) { if (isExtended) { return(CreateResponseExtendedForNamedPipe(fileID.Value, FileStatus.FILE_OPENED)); } else { return(CreateResponseForNamedPipe(fileID.Value, FileStatus.FILE_OPENED)); } } else // FileSystemShare { FileNetworkOpenInformation fileInfo = NTFileStoreHelper.GetNetworkOpenInformation(share.FileStore, handle); if (isExtended) { NTCreateAndXResponseExtended response = CreateResponseExtendedFromFileInformation(fileInfo, fileID.Value, fileStatus); return(response); } else { NTCreateAndXResponse response = CreateResponseFromFileInformation(fileInfo, fileID.Value, fileStatus); return(response); } } }