ServerServiceHelper.cs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
  2. *
  3. * You can redistribute this program and/or modify it under the terms of
  4. * the GNU Lesser Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. */
  7. using System;
  8. using System.Collections.Generic;
  9. using SMBLibrary.RPC;
  10. using SMBLibrary.Services;
  11. namespace SMBLibrary.Client
  12. {
  13. public class ServerServiceHelper
  14. {
  15. public static List<string> ListShares(INTFileStore namedPipeShare, ShareType? shareType, out NTStatus status)
  16. {
  17. object pipeHandle;
  18. FileStatus fileStatus;
  19. status = namedPipeShare.CreateFile(out pipeHandle, out fileStatus, ServerService.ServicePipeName, (AccessMask)(FileAccessMask.FILE_READ_DATA | FileAccessMask.FILE_WRITE_DATA), 0, ShareAccess.FILE_SHARE_READ | ShareAccess.FILE_SHARE_WRITE, CreateDisposition.FILE_OPEN, 0, null);
  20. if (status != NTStatus.STATUS_SUCCESS)
  21. {
  22. return null;
  23. }
  24. BindPDU bindPDU = new BindPDU();
  25. bindPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
  26. bindPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII;
  27. bindPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian;
  28. bindPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
  29. bindPDU.MaxTransmitFragmentSize = 5680;
  30. bindPDU.MaxReceiveFragmentSize = 5680;
  31. ContextElement serverServiceContext = new ContextElement();
  32. serverServiceContext.AbstractSyntax = new SyntaxID(ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion);
  33. serverServiceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion));
  34. bindPDU.ContextList.Add(serverServiceContext);
  35. byte[] input = bindPDU.GetBytes();
  36. byte[] output;
  37. status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096);
  38. if (status != NTStatus.STATUS_SUCCESS)
  39. {
  40. return null;
  41. }
  42. BindAckPDU bindAckPDU = RPCPDU.GetPDU(output, 0) as BindAckPDU;
  43. if (bindAckPDU == null)
  44. {
  45. status = NTStatus.STATUS_NOT_SUPPORTED;
  46. return null;
  47. }
  48. NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest();
  49. shareEnumRequest.InfoStruct = new ShareEnum();
  50. shareEnumRequest.InfoStruct.Level = 1;
  51. shareEnumRequest.InfoStruct.Info = new ShareInfo1Container();
  52. shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue;
  53. shareEnumRequest.ServerName = "*";
  54. RequestPDU requestPDU = new RequestPDU();
  55. requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
  56. requestPDU.DataRepresentation.CharacterFormat = CharacterFormat.ASCII;
  57. requestPDU.DataRepresentation.ByteOrder = ByteOrder.LittleEndian;
  58. requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
  59. requestPDU.OpNum = (ushort)ServerServiceOpName.NetrShareEnum;
  60. requestPDU.Data = shareEnumRequest.GetBytes();
  61. requestPDU.AllocationHint = (uint)requestPDU.Data.Length;
  62. input = requestPDU.GetBytes();
  63. status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096);
  64. if (status != NTStatus.STATUS_SUCCESS)
  65. {
  66. return null;
  67. }
  68. ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;
  69. if (responsePDU == null)
  70. {
  71. status = NTStatus.STATUS_NOT_SUPPORTED;
  72. return null;
  73. }
  74. NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responsePDU.Data);
  75. ShareInfo1Container shareInfo1 = shareEnumResponse.InfoStruct.Info as ShareInfo1Container;
  76. if (shareInfo1 == null)
  77. {
  78. if (shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED)
  79. {
  80. status = NTStatus.STATUS_ACCESS_DENIED;
  81. }
  82. else
  83. {
  84. status = NTStatus.STATUS_NOT_SUPPORTED;
  85. }
  86. return null;
  87. }
  88. List<string> result = new List<string>();
  89. foreach (ShareInfo1Entry entry in shareInfo1.Entries)
  90. {
  91. if (!shareType.HasValue || shareType.Value == entry.ShareType.ShareType)
  92. {
  93. result.Add(entry.NetName.Value);
  94. }
  95. }
  96. return result;
  97. }
  98. }
  99. }