예제 #1
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);
        }
예제 #2
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*/ }
            }
        }
예제 #3
0
        /// <summary>
        /// Sends message to a remote SMMP server
        /// </summary>
        /// <param name="message">A message to send</param>
        /// <param name="timeOut">A value in miliseconds after which the send operation times out</param>
        public void SendMessage(ShortMessage message, int timeOut)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            //Check if connection is open
            if (vState != SmppConnectionState.Connected)
            {
                throw new SmppClientException("Sending message operation failed because the SmppClient is not connected");
            }

            string messageId = null;

            foreach (SendSmPDU pdu in message.GetMessagePDUs(vProperties.DefaultEncoding))
            {
                ResponsePDU resp = vTrans.SendPdu(pdu, timeOut);
                if (resp.Header.ErrorCode != SmppErrorCode.ESME_ROK)
                {
                    throw new SmppException(resp.Header.ErrorCode);
                }
                var submitSmResp = resp as SubmitSmResp;
                if (submitSmResp != null)
                {
                    messageId = ((SubmitSmResp)resp).MessageID;
                }
                message.ReceiptedMessageId = messageId;
                RaiseMessageSentEvent(message);
            }
        }
예제 #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
        /// <summary>
        /// Sends message to a remote SMPP server
        /// </summary>
        /// <param name="message">A message to send</param>
        /// <param name="timeOut">A value in miliseconds after which the send operation times out</param>
        public void SendMessage(ShortMessage message, int timeOut)
        {
            if (message == null)
            {
                throw new ArgumentNullException("message");
            }

            //Check if connection is open
            if (vState != SmppConnectionState.Connected)
            {
                throw new SmppClientException("Sending message operation failed because the SmppClient is not connected");
            }

            string messageId = null;

            foreach (SendSmPDU pdu in message.GetMessagePDUs(vProperties.DefaultEncoding, vSmppEncodingService))
            {
                if (_Log.IsDebugEnabled)
                {
                    _Log.DebugFormat("SendMessage SendSmPDU: {0}", LoggingExtensions.DumpString(pdu, vSmppEncodingService));
                }
                ResponsePDU resp         = SendPdu(pdu, timeOut);
                var         submitSmResp = resp as SubmitSmResp;
                if (submitSmResp != null)
                {
                    if (_Log.IsDebugEnabled)
                    {
                        _Log.DebugFormat("SendMessage Response: {0}", LoggingExtensions.DumpString(resp, vSmppEncodingService));
                    }
                    messageId = ((SubmitSmResp)resp).MessageID;
                }
                message.ReceiptedMessageId = messageId;
                RaiseMessageSentEvent(message);
            }
        }
예제 #6
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);
        }
예제 #7
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);
        }
예제 #8
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);
        }
예제 #9
0
 private ResponsePDU FetchResponse(uint sequenceNumber)
 {
     vResponseEvent.WaitOne();
     try
     {
         for (int index = 0; index < vResponseQueue.Count; ++index)
         {
             ResponsePDU pdu = vResponseQueue[index];
             if (pdu.Header.SequenceNumber == sequenceNumber)
             {
                 vResponseQueue.RemoveAt(index);
                 return(pdu);
             }
         }
         return(null);
     }
     finally { vResponseEvent.Set(); }
 }
예제 #10
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*/ }
        }
예제 #11
0
 public void Handle(ResponsePDU pdu)
 {
     AddResponse(pdu);
     vWaitingEvent.WaitOne();
     try
     {
         uint           sequenceNumber = pdu.Header.SequenceNumber;
         PDUWaitContext waitContext;
         if (vWaitingQueue.TryGetValue(sequenceNumber, out waitContext))
         {
             waitContext.AlertResponseReceived();
             if (waitContext.TimedOut)
             {
                 FetchResponse(sequenceNumber);
             }
         }
     }
     finally { vWaitingEvent.Set(); }
 }
예제 #12
0
 public void Handle(ResponsePDU pdu)
 {
     AddResponse(pdu);
     vWaitingEvent.WaitOne();
     try
     {
         uint sequenceNumber = pdu.Header.SequenceNumber;
         for (int index = 0; index < vWaitingQueue.Count; ++index)
         {
             PDUWaitContext waitContext = vWaitingQueue[index];
             if (waitContext.SequenceNumber == sequenceNumber)
             {
                 vWaitingQueue.RemoveAt(index);
                 waitContext.AlertResponseReceived();
                 if (waitContext.TimedOut)
                 {
                     FetchResponse(sequenceNumber);
                 }
                 return;
             }
         }
     }
     finally { vWaitingEvent.Set(); }
 }
예제 #13
0
 private void AddResponse(ResponsePDU pdu)
 {
     vResponseEvent.WaitOne();
     try { vResponseQueue[pdu.Header.SequenceNumber] = pdu; }
     finally { vResponseEvent.Set(); }
 }
예제 #14
0
 private void AddResponse(ResponsePDU pdu)
 {
     vResponseEvent.WaitOne();
     try { vResponseQueue.Add(pdu); }
     finally { vResponseEvent.Set(); }
 }
예제 #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 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);
        }