예제 #1
0
        private void PduRequestProcessorCallback(RequestPDU pdu)
        {
            ResponsePDU resp = null;

            if (pdu is Unbind)
            {
                resp = pdu.CreateDefaultResponce();
                try { SendPduBase(resp); }
                catch { /*silent catch*/ }
                EndSession(SmppSessionCloseReason.UnbindRequested, null);
                return;
            }
            resp = RaisePduReceivedEvent(pdu);
            if (resp == null)
            {
                if (pdu.HasResponse)
                {
                    resp = pdu.CreateDefaultResponce();
                }
            }
            if (resp != null)
            {
                try { SendPduBase(resp); } catch { /*Silent catch*/ }
            }
        }
예제 #2
0
        public ResponsePDU SendPdu(RequestPDU pdu)
        {
            int timeout = 0;

            lock (vSyncRoot) { timeout = vDefaultResponseTimeout; }
            return(SendPdu(pdu, timeout));
        }
예제 #3
0
        public IAsyncResult BeginSendPdu(RequestPDU pdu, AsyncCallback callback, object @object)
        {
            int timeout = 0;

            lock (vSyncRoot) { timeout = vDefaultResponseTimeout; }
            return(BeginSendPdu(pdu, timeout, callback, @object));
        }
예제 #4
0
        public static List <ResponsePDU> GetRPCResponse(RequestPDU requestPDU, RemoteService service, int maxTransmitFragmentSize)
        {
            byte[]             responseBytes    = service.GetResponseBytes(requestPDU.OpNum, requestPDU.Data);
            int                offset           = 0;
            List <ResponsePDU> result           = new List <ResponsePDU>();
            int                maxPDUDataLength = maxTransmitFragmentSize - RPCPDU.CommonFieldsLength - ResponsePDU.ResponseFieldsLength;

            do
            {
                ResponsePDU responsePDU   = new ResponsePDU();
                int         pduDataLength = Math.Min(responseBytes.Length - offset, maxPDUDataLength);
                responsePDU.DataRepresentation = requestPDU.DataRepresentation;
                responsePDU.CallID             = requestPDU.CallID;
                responsePDU.AllocationHint     = (uint)(responseBytes.Length - offset);
                responsePDU.Data = ByteReader.ReadBytes(responseBytes, offset, pduDataLength);
                if (offset == 0)
                {
                    responsePDU.Flags |= PacketFlags.FirstFragment;
                }
                if (offset + pduDataLength == responseBytes.Length)
                {
                    responsePDU.Flags |= PacketFlags.LastFragment;
                }
                result.Add(responsePDU);
                offset += pduDataLength;
            }while (offset < responseBytes.Length);

            return(result);
        }
예제 #5
0
        public ResponsePDU WaitResponse(RequestPDU pdu, int timeOut)
        {
            uint        sequenceNumber = pdu.Header.SequenceNumber;
            ResponsePDU resp           = FetchResponse(sequenceNumber);

            if (resp != null)
            {
                return(resp);
            }
            if (timeOut < 5000)
            {
                timeOut = vDefaultResponseTimeout;
            }
            PDUWaitContext waitContext = new PDUWaitContext(sequenceNumber, timeOut);

            vWaitingEvent.WaitOne();
            try { vWaitingQueue[sequenceNumber] = waitContext; }
            finally { vWaitingEvent.Set(); }
            waitContext.WaitForAlert();
            resp = FetchResponse(sequenceNumber);
            if (resp == null)
            {
                throw new SmppResponseTimedOutException();
            }
            return(resp);
        }
예제 #6
0
        public static List <string> ListShares(INtFileStore namedPipeShare, ShareType?shareType)
        {
            NamedPipeHelper.BindPipe(namedPipeShare, ServerService.ServicePipeName, ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion, out NtHandle? pipeHandle, out int maxTransmitFragmentSize).IsSuccessElseThrow();

            NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest
            {
                InfoStruct = new ShareEnum
                {
                    Level = 1,
                    Info  = new ShareInfo1Container()
                },
                PreferedMaximumLength = uint.MaxValue,
                ServerName            = "*"
            };

            byte[]     data       = shareEnumRequest.GetBytes();
            RequestPDU requestPdu = new RequestPDU
            {
                Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment,
                DataRepresentation =
                {
                    CharacterFormat             = CharacterFormat.ASCII,
                    ByteOrder                   = ByteOrder.LittleEndian,
                    FloatingPointRepresentation = FloatingPointRepresentation.IEEE
                },
                OpNum          = (ushort)ServerServiceOpName.NetrShareEnum,
                Data           = data,
                AllocationHint = (uint)data.Length
            };

            byte[] input = requestPdu.GetBytes();
            namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out byte[]? output, maxTransmitFragmentSize);

            if (!(RPCPDU.GetPDU(output, 0) is ResponsePDU responsePdu))
            {
                throw new NtStatusException(NTStatus.STATUS_NOT_SUPPORTED);
            }

            byte[] responseData = responsePdu.Data;
            while ((responsePdu.Flags & PacketFlags.LastFragment) == 0)
            {
                namedPipeShare.ReadFile(out output, pipeHandle, 0, maxTransmitFragmentSize);

                if (!(RPCPDU.GetPDU(output, 0) is ResponsePDU responsePdu2))
                {
                    throw new NtStatusException(NTStatus.STATUS_NOT_SUPPORTED);
                }
                responseData = ByteUtils.Concatenate(responseData, responsePdu2.Data);
            }
            namedPipeShare.CloseFile(pipeHandle);
            NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responseData);

            if (shareEnumResponse.InfoStruct.Info is ShareInfo1Container shareInfo1 && shareInfo1.Entries != null)
            {
                return((from entry in shareInfo1.Entries where !shareType.HasValue || shareType.Value == entry.ShareType.ShareType select entry.NetName.Value).ToList());
            }

            throw new NtStatusException(shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED ? NTStatus.STATUS_ACCESS_DENIED : NTStatus.STATUS_NOT_SUPPORTED);
        }
예제 #7
0
        public IAsyncResult BeginSendPdu(RequestPDU pdu, int timeout, AsyncCallback callback, object @object)
        {
#if NET40
            return(vCallback.BeginInvoke(pdu, timeout, callback, @object));
#else
            return(System.Threading.Tasks.Task.Run(() => vCallback(pdu, timeout)));
#endif
        }
예제 #8
0
        private static ResponsePDU GetRPCResponse(RequestPDU requestPDU, RemoteService service)
        {
            ResponsePDU responsePDU = new ResponsePDU();

            PrepareReply(responsePDU, requestPDU);
            responsePDU.Data = service.GetResponseBytes(requestPDU.OpNum, requestPDU.Data);
            return(responsePDU);
        }
예제 #9
0
        /// <summary>
        /// Send PDU to a remote SMPP server
        /// </summary>
        /// <param name="pdu"><see cref="RequestPDU"/></param>
        /// <param name="timeout">A value in miliseconds after which the send operation times out</param>
        /// <returns><see cref="ResponsePDU"/></returns>
        public ResponsePDU SendPdu(RequestPDU pdu, int timeout)
        {
            var resp = vTrans.SendPdu(pdu, timeout);

            if (resp.Header.ErrorCode != SmppErrorCode.ESME_ROK)
            {
                throw new SmppException(resp.Header.ErrorCode);
            }

            return(resp);
        }
예제 #10
0
        public static NTStatus ExecuteCall <I, O>(INTFileStore namedPipeShare, object pipeHandle, ushort OpNum, I inputArgs, out O outputData) where I : IRPCRequest
        {
            byte[]   output;
            NTStatus status;

            outputData = default(O);

            RequestPDU requestPDU = new RequestPDU();

            requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
            requestPDU.DataRepresentation.CharacterFormat             = CharacterFormat.ASCII;
            requestPDU.DataRepresentation.ByteOrder                   = ByteOrder.LittleEndian;
            requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
            requestPDU.OpNum          = OpNum;
            requestPDU.Data           = inputArgs.GetBytes();
            requestPDU.AllocationHint = (uint)requestPDU.Data.Length;
            byte[] input           = requestPDU.GetBytes();
            int    maxOutputLength = MaxTransmitFragmentSize;

            status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, maxOutputLength);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                return(status);
            }
            ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;

            if (responsePDU == null)
            {
                status = NTStatus.STATUS_NOT_SUPPORTED;
                return(status);
            }

            byte[] responseData = responsePDU.Data;
            while ((responsePDU.Flags & PacketFlags.LastFragment) == 0)
            {
                status = namedPipeShare.ReadFile(out output, pipeHandle, 0, maxOutputLength);
                if (status != NTStatus.STATUS_SUCCESS)
                {
                    return(status);
                }
                responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;
                if (responsePDU == null)
                {
                    status = NTStatus.STATUS_NOT_SUPPORTED;
                    return(status);
                }
                responseData = ByteUtils.Concatenate(responseData, responsePDU.Data);
            }
            outputData = (O)Activator.CreateInstance(typeof(O), new object[] { responseData });
            return(NTStatus.STATUS_SUCCESS);
        }
예제 #11
0
        public static List <RPCPDU> GetRPCResponse(RequestPDU requestPDU, RemoteService service, int maxTransmitFragmentSize)
        {
            List <RPCPDU> result = new List <RPCPDU>();

            byte[] responseBytes;
            try
            {
                responseBytes = service.GetResponseBytes(requestPDU.OpNum, requestPDU.Data);
            }
            catch (UnsupportedOpNumException)
            {
                FaultPDU faultPDU = new FaultPDU
                {
                    Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment | PacketFlags.DidNotExecute,
                    DataRepresentation = requestPDU.DataRepresentation,
                    CallID             = requestPDU.CallID,
                    AllocationHint     = RPCPDU.CommonFieldsLength + FaultPDU.FaultFieldsLength,
                    // Windows will return either nca_s_fault_ndr or nca_op_rng_error.
                    Status = FaultStatus.OpRangeError
                };
                result.Add(faultPDU);
                return(result);
            }

            int offset           = 0;
            int maxPDUDataLength = maxTransmitFragmentSize - RPCPDU.CommonFieldsLength - ResponsePDU.ResponseFieldsLength;

            do
            {
                ResponsePDU responsePDU   = new ResponsePDU();
                int         pduDataLength = Math.Min(responseBytes.Length - offset, maxPDUDataLength);
                responsePDU.DataRepresentation = requestPDU.DataRepresentation;
                responsePDU.CallID             = requestPDU.CallID;
                responsePDU.AllocationHint     = (uint)(responseBytes.Length - offset);
                responsePDU.Data = ByteReader.ReadBytes(responseBytes, offset, pduDataLength);
                if (offset == 0)
                {
                    responsePDU.Flags |= PacketFlags.FirstFragment;
                }
                if (offset + pduDataLength == responseBytes.Length)
                {
                    responsePDU.Flags |= PacketFlags.LastFragment;
                }
                result.Add(responsePDU);
                offset += pduDataLength;
            }while (offset < responseBytes.Length);

            return(result);
        }
예제 #12
0
        private ResponsePDU RaisePduReceivedEvent(RequestPDU pdu)
        {
            /*
             * PduReceived event is not raised asynchronously as this method is
             * being called asynchronously by a worker thread from the thread pool.
             */
            if (PduReceived == null)
            {
                return(null);
            }
            PduReceivedEventArgs e = new PduReceivedEventArgs(pdu);

            PduReceived(this, e);
            return(e.Response);
        }
예제 #13
0
        private void PduErrorEventHandler(object sender, PDUErrorEventArgs e)
        {
            ResponsePDU resp = null;

            if (e.Pdu is RequestPDU)
            {
                RequestPDU req = (RequestPDU)e.Pdu;
                resp = req.CreateDefaultResponce();
                resp.Header.ErrorCode = e.Exception.ErrorCode;
            }
            else
            {
                resp = new GenericNack(e.Header);
                resp.Header.ErrorCode = e.Exception.ErrorCode;
            }
            try { SendPduBase(resp); }
            catch { /*silent catch*/ }
        }
예제 #14
0
 public ResponsePDU SendPdu(RequestPDU pdu, int timeout)
 {
     SendPduBase(pdu);
     if (pdu.HasResponse)
     {
         try { return(vRespHandler.WaitResponse(pdu, timeout)); }
         catch (SmppResponseTimedOutException)
         {
             if (vTraceSwitch.TraceWarning)
             {
                 Trace.WriteLine("200016:PDU send operation timed out;");
             }
             throw;
         }
     }
     else
     {
         return(null);
     }
 }
예제 #15
0
        public static List <string> ListShares(INTFileStore namedPipeShare, ShareType?shareType, out NTStatus status)
        {
            object pipeHandle;
            int    maxTransmitFragmentSize;

            status = NamedPipeHelper.BindPipe(namedPipeShare, ServerService.ServicePipeName, ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion, out pipeHandle, out maxTransmitFragmentSize);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                return(null);
            }

            NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest();

            shareEnumRequest.InfoStruct            = new ShareEnum();
            shareEnumRequest.InfoStruct.Level      = 1;
            shareEnumRequest.InfoStruct.Info       = new ShareInfo1Container();
            shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue;
            shareEnumRequest.ServerName            = "*";
            RequestPDU requestPDU = new RequestPDU();

            requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
            requestPDU.DataRepresentation.CharacterFormat             = CharacterFormat.ASCII;
            requestPDU.DataRepresentation.ByteOrder                   = ByteOrder.LittleEndian;
            requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
            requestPDU.OpNum          = (ushort)ServerServiceOpName.NetrShareEnum;
            requestPDU.Data           = shareEnumRequest.GetBytes();
            requestPDU.AllocationHint = (uint)requestPDU.Data.Length;
            byte[] input = requestPDU.GetBytes();
            byte[] output;
            int    maxOutputLength = maxTransmitFragmentSize;

            status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, maxOutputLength);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                return(null);
            }
            ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;

            if (responsePDU == null)
            {
                status = NTStatus.STATUS_NOT_SUPPORTED;
                return(null);
            }

            byte[] responseData = responsePDU.Data;
            while ((responsePDU.Flags & PacketFlags.LastFragment) == 0)
            {
                status = namedPipeShare.ReadFile(out output, pipeHandle, 0, maxOutputLength);
                if (status != NTStatus.STATUS_SUCCESS)
                {
                    return(null);
                }
                responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;
                if (responsePDU == null)
                {
                    status = NTStatus.STATUS_NOT_SUPPORTED;
                    return(null);
                }
                responseData = ByteUtils.Concatenate(responseData, responsePDU.Data);
            }
            namedPipeShare.CloseFile(pipeHandle);
            NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responseData);
            ShareInfo1Container   shareInfo1        = shareEnumResponse.InfoStruct.Info as ShareInfo1Container;

            if (shareInfo1 == null || shareInfo1.Entries == null)
            {
                if (shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED)
                {
                    status = NTStatus.STATUS_ACCESS_DENIED;
                }
                else
                {
                    status = NTStatus.STATUS_NOT_SUPPORTED;
                }
                return(null);
            }

            List <string> result = new List <string>();

            foreach (ShareInfo1Entry entry in shareInfo1.Entries)
            {
                if (!shareType.HasValue || shareType.Value == entry.ShareType.ShareType)
                {
                    result.Add(entry.NetName.Value);
                }
            }
            return(result);
        }
예제 #16
0
 public PduReceivedEventArgs(RequestPDU request)
 {
     vRequest = request;
 }
예제 #17
0
 public ResponsePDU WaitResponse(RequestPDU pdu)
 {
     return(WaitResponse(pdu, vDefaultResponseTimeout));
 }
예제 #18
0
 public IAsyncResult BeginSendPdu(RequestPDU pdu, int timeout, AsyncCallback callback, object @object)
 {
     return(vCallback.BeginInvoke(pdu, timeout, callback, @object));
 }
예제 #19
0
        public static List <string> ListShares(INTFileStore namedPipeShare, ShareType?shareType, out NTStatus status)
        {
            object     pipeHandle;
            FileStatus fileStatus;

            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);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                return(null);
            }
            BindPDU bindPDU = new BindPDU();

            bindPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
            bindPDU.DataRepresentation.CharacterFormat             = CharacterFormat.ASCII;
            bindPDU.DataRepresentation.ByteOrder                   = ByteOrder.LittleEndian;
            bindPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
            bindPDU.MaxTransmitFragmentSize = 5680;
            bindPDU.MaxReceiveFragmentSize  = 5680;

            ContextElement serverServiceContext = new ContextElement();

            serverServiceContext.AbstractSyntax = new SyntaxID(ServerService.ServiceInterfaceGuid, ServerService.ServiceVersion);
            serverServiceContext.TransferSyntaxList.Add(new SyntaxID(RemoteServiceHelper.NDRTransferSyntaxIdentifier, RemoteServiceHelper.NDRTransferSyntaxVersion));

            bindPDU.ContextList.Add(serverServiceContext);

            byte[] input = bindPDU.GetBytes();
            byte[] output;
            status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, 4096);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                return(null);
            }
            BindAckPDU bindAckPDU = RPCPDU.GetPDU(output, 0) as BindAckPDU;

            if (bindAckPDU == null)
            {
                status = NTStatus.STATUS_NOT_SUPPORTED;
                return(null);
            }

            NetrShareEnumRequest shareEnumRequest = new NetrShareEnumRequest();

            shareEnumRequest.InfoStruct            = new ShareEnum();
            shareEnumRequest.InfoStruct.Level      = 1;
            shareEnumRequest.InfoStruct.Info       = new ShareInfo1Container();
            shareEnumRequest.PreferedMaximumLength = UInt32.MaxValue;
            shareEnumRequest.ServerName            = "*";
            RequestPDU requestPDU = new RequestPDU();

            requestPDU.Flags = PacketFlags.FirstFragment | PacketFlags.LastFragment;
            requestPDU.DataRepresentation.CharacterFormat             = CharacterFormat.ASCII;
            requestPDU.DataRepresentation.ByteOrder                   = ByteOrder.LittleEndian;
            requestPDU.DataRepresentation.FloatingPointRepresentation = FloatingPointRepresentation.IEEE;
            requestPDU.OpNum          = (ushort)ServerServiceOpName.NetrShareEnum;
            requestPDU.Data           = shareEnumRequest.GetBytes();
            requestPDU.AllocationHint = (uint)requestPDU.Data.Length;
            input = requestPDU.GetBytes();
            int maxOutputLength = bindAckPDU.MaxTransmitFragmentSize;

            status = namedPipeShare.DeviceIOControl(pipeHandle, (uint)IoControlCode.FSCTL_PIPE_TRANSCEIVE, input, out output, maxOutputLength);
            if (status != NTStatus.STATUS_SUCCESS)
            {
                return(null);
            }
            ResponsePDU responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;

            if (responsePDU == null)
            {
                status = NTStatus.STATUS_NOT_SUPPORTED;
                return(null);
            }

            byte[] responseData = responsePDU.Data;
            while ((responsePDU.Flags & PacketFlags.LastFragment) == 0)
            {
                status = namedPipeShare.ReadFile(out output, pipeHandle, 0, maxOutputLength);
                if (status != NTStatus.STATUS_SUCCESS)
                {
                    return(null);
                }
                responsePDU = RPCPDU.GetPDU(output, 0) as ResponsePDU;
                if (responsePDU == null)
                {
                    status = NTStatus.STATUS_NOT_SUPPORTED;
                    return(null);
                }
                responseData = ByteUtils.Concatenate(responseData, responsePDU.Data);
            }
            NetrShareEnumResponse shareEnumResponse = new NetrShareEnumResponse(responseData);
            ShareInfo1Container   shareInfo1        = shareEnumResponse.InfoStruct.Info as ShareInfo1Container;

            if (shareInfo1 == null || shareInfo1.Entries == null)
            {
                if (shareEnumResponse.Result == Win32Error.ERROR_ACCESS_DENIED)
                {
                    status = NTStatus.STATUS_ACCESS_DENIED;
                }
                else
                {
                    status = NTStatus.STATUS_NOT_SUPPORTED;
                }
                return(null);
            }

            List <string> result = new List <string>();

            foreach (ShareInfo1Entry entry in shareInfo1.Entries)
            {
                if (!shareType.HasValue || shareType.Value == entry.ShareType.ShareType)
                {
                    result.Add(entry.NetName.Value);
                }
            }
            return(result);
        }