/// <summary> /// Creates and connects a new pass-through socket, from the host to a port on the device. /// </summary> /// <param name="endpoint"></param> /// <param name="device">the device to connect to. Can be null in which case the connection will be /// to the first available device.</param> /// <param name="pid">the process pid to connect to.</param> /// <returns>The Socket</returns> public Socket CreatePassThroughConnection(IPEndPoint endpoint, Device device, int pid) { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { socket.Connect(endpoint); socket.NoDelay = true; // if the device is not -1, then we first tell adb we're looking to // talk to a specific device SetDevice(socket, device); byte[] req = CreateJdwpForwardRequest(pid); // Log.hexDump(req); if (!Write(socket, req)) { throw new AdbException("failed submitting request to ADB"); //$NON-NLS-1$ } AdbResponse resp = ReadAdbResponse(socket, false /* readDiagString */); if (!resp.Okay) { throw new AdbException("connection request rejected: " + resp.Message); //$NON-NLS-1$ } } catch (AdbException ioe) { socket.Close( ); throw ioe; } return(socket); }
/// <summary> /// Opens this connection. /// </summary> /// <returns></returns> public bool Open( ) { if (IsOpen) { return(true); } try { Channel = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); Channel.Connect(this.Address); Channel.Blocking = true; // target a specific device AdbHelper.Instance.SetDevice(Channel, Device); byte[] request = AdbHelper.Instance.FormAdbRequest("sync:"); AdbHelper.Instance.Write(Channel, request, -1, DdmPreferences.Timeout); AdbResponse resp = AdbHelper.Instance.ReadAdbResponse(Channel, false /* readDiagString */); if (!resp.IOSuccess || !resp.Okay) { Log.w("ddms:syncservice", "Got timeout or unhappy response from ADB sync req: {0}", resp.Message); Channel.Close( ); Channel = null; return(false); } } catch (IOException) { Close( ); throw; } return(true); }
/// <summary> /// Opens the specified address on the device on the specified port. /// </summary> /// <param name="address">The address.</param> /// <param name="device">The device.</param> /// <param name="port">The port.</param> /// <returns></returns> public Socket Open(IPAddress address, IDevice device, int port) { Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { s.Connect(address, port); s.Blocking = true; s.NoDelay = false; SetDevice(s, device); byte[] req = CreateAdbForwardRequest(null, port); if (!Write(s, req)) { throw new AdbException("failed submitting request to ADB"); } AdbResponse resp = ReadAdbResponse(s, false); if (!resp.Okay) { throw new AdbException("connection request rejected"); } s.Blocking = true; } catch (AdbException) { s.Close( ); throw; } return(s); }
/// <summary> /// Creates the reverse forward. /// </summary> /// <param name="adbSockAddr">The adb sock addr.</param> /// <param name="device">The device.</param> /// <param name="remotePort">The remote port.</param> /// <param name="localPort">The local port.</param> /// <returns></returns> /// <exception cref="Managed.Adb.Exceptions.AdbException"> /// failed to submit the forward command. /// or /// Device rejected command: + resp.Message /// </exception> public bool CreateReverseForward(IPEndPoint adbSockAddr, Device device, int remotePort, int localPort) { Socket adbChan = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { adbChan.Connect(adbSockAddr); adbChan.Blocking = true; // if the device is not -1, then we first tell adb we're looking to talk // to a specific device SetDevice(adbChan, device); byte[] request = FormAdbRequest(String.Format("reverse:forward:tcp:{0};tcp:{1}", //$NON-NLS-1$ remotePort, localPort)); if (!Write(adbChan, request)) { throw new AdbException("failed to submit the reverse forward command."); } AdbResponse resp = ReadAdbResponse(adbChan, false /* readDiagString */); if (!resp.IOSuccess || !resp.Okay) { throw new AdbException("Device rejected command: " + resp.Message); } } finally { if (adbChan != null) { adbChan.Close( ); } } return(true); }
/// <summary> /// Sets the device. /// </summary> /// <param name="adbChan">The adb chan.</param> /// <param name="device">The device.</param> public void SetDevice(Socket adbChan, IDevice device) { // if the device is not null, then we first tell adb we're looking to talk // to a specific device if (device != null) { String msg = "host:transport:" + device.SerialNumber; byte[] device_query = FormAdbRequest(msg); if (!Write(adbChan, device_query)) { throw new AdbException("failed submitting device (" + device + ") request to ADB"); } AdbResponse resp = ReadAdbResponse(adbChan, false /* readDiagString */); if (!resp.Okay) { if (String.Compare("device not found", resp.Message, true) == 0) { throw new DeviceNotFoundException(device.SerialNumber); } else { throw new AdbException("device (" + device + ") request rejected: " + resp.Message); } } } }
/// <summary> /// Sends the device monitoring request. /// </summary> /// <param name="socket">The socket.</param> /// <param name="device">The device.</param> /// <returns></returns> private bool SendDeviceMonitoringRequest(Socket socket, Device device) { AdbHelper.Instance.SetDevice(socket, device); byte[] request = AdbHelper.Instance.FormAdbRequest("track-jdwp"); if (!AdbHelper.Instance.Write(socket, request)) { Log.e(TAG, "Sending jdwp tracking request failed!"); socket.Close( ); throw new IOException( ); } AdbResponse resp = AdbHelper.Instance.ReadAdbResponse(socket, false /* readDiagString */); if (resp.IOSuccess == false) { Log.e(TAG, "Failed to read the adb response!"); socket.Close( ); throw new IOException( ); } if (resp.Okay == false) { // request was refused by adb! Log.e(TAG, "adb refused request: " + resp.Message); } return(resp.Okay); }
/// <summary> /// Removes the forward. /// </summary> /// <param name="adbSockAddr">The adb sock addr.</param> /// <param name="device">The device.</param> /// <param name="localPort">The local port.</param> /// <param name="remotePort">The remote port.</param> /// <returns></returns> public bool RemoveForward(IPEndPoint adbSockAddr, Device device, int localPort, int remotePort) { Socket adbChan = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { adbChan.Connect(adbSockAddr); adbChan.Blocking = true; byte[] request = FormAdbRequest(String.Format("host-serial:{0}:killforward:tcp:{1};tcp:{2}", device.SerialNumber, localPort, remotePort)); if (!Write(adbChan, request)) { throw new AdbException("failed to submit the remove forward command."); } AdbResponse resp = ReadAdbResponse(adbChan, false /* readDiagString */); if (!resp.IOSuccess || !resp.Okay) { throw new AdbException("Device rejected command: " + resp.Message); } } finally { if (adbChan != null) { adbChan.Close( ); } } return(true); }
/// <summary> /// Sends the device list monitoring request. /// </summary> /// <returns></returns> private bool SendDeviceListMonitoringRequest( ) { byte[] request = AdbHelper.Instance.FormAdbRequest("host:track-devices"); if (AdbHelper.Instance.Write(MainAdbConnection, request) == false) { Log.e(TAG, "Sending Tracking request failed!"); MainAdbConnection.Close( ); throw new IOException("Sending Tracking request failed!"); } AdbResponse resp = AdbHelper.Instance.ReadAdbResponse(MainAdbConnection, false /* readDiagString */); if (!resp.IOSuccess) { Log.e(TAG, "Failed to read the adb response!"); MainAdbConnection.Close( ); throw new IOException("Failed to read the adb response!"); } if (!resp.Okay) { // request was refused by adb! Log.e(TAG, "adb refused request: {0}", resp.Message); } return(resp.Okay); }
/// <summary> /// Executes the raw socket command. /// </summary> /// <param name="address">The address.</param> /// <param name="device">The device.</param> /// <param name="command">The command. Should call FormAdbRequest on the string to create the byte array.</param> /// <returns></returns> /// <exception cref="Managed.Adb.Exceptions.AdbException"> /// Device is offline /// or /// failed to submit the command: {0}..With(command.GetString().Trim()) /// or /// Device rejected command: {0}.With(resp.Message) /// </exception> /// <exception cref="AdbException">Device is offline. /// or /// failed to submit the command: {0}.With(command) /// or /// Device rejected command: {0}.With(resp.Message)</exception> private Socket ExecuteRawSocketCommand(IPEndPoint address, Device device, byte[] command) { if (device != null && !device.IsOnline) { throw new AdbException("Device is offline"); } Socket adbChan = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); adbChan.Connect(address); adbChan.Blocking = true; if (device != null) { SetDevice(adbChan, device); } if (!Write(adbChan, command)) { throw new AdbException("failed to submit the command: {0}.".With(command.GetString().Trim())); } AdbResponse resp = ReadAdbResponse(adbChan, false /* readDiagString */); if (!resp.IOSuccess || !resp.Okay) { throw new AdbException("Device rejected command: {0}".With(resp.Message)); } return(adbChan); }
/// <summary> /// Reads the adb response. /// </summary> /// <param name="socket">The socket.</param> /// <param name="readDiagString">if set to <c>true</c> [read diag string].</param> /// <returns></returns> public AdbResponse ReadAdbResponse(Socket socket, bool readDiagString) { AdbResponse resp = new AdbResponse( ); byte[] reply = new byte[4]; if (!Read(socket, reply)) { return(resp); } resp.IOSuccess = true; if (IsOkay(reply)) { resp.Okay = true; } else { readDiagString = true; // look for a reason after the FAIL resp.Okay = false; } // not a loop -- use "while" so we can use "break" while (readDiagString) { // length string is in next 4 bytes byte[] lenBuf = new byte[4]; if (!Read(socket, lenBuf)) { Console.WriteLine("Expected diagnostic string not found"); break; } String lenStr = ReplyToString(lenBuf); int len; try { len = int.Parse(lenStr, System.Globalization.NumberStyles.HexNumber); } catch (FormatException) { Log.e(TAG, "Expected digits, got '{0}' : {1} {2} {3} {4}", lenBuf[0], lenBuf[1], lenBuf[2], lenBuf[3]); Log.e(TAG, "reply was {0}", ReplyToString(reply)); break; } byte[] msg = new byte[len]; if (!Read(socket, msg)) { Log.e(TAG, "Failed reading diagnostic string, len={0}", len); break; } resp.Message = ReplyToString(msg); Log.e(TAG, "Got reply '{0}', diag='{1}'", ReplyToString(reply), resp.Message); break; } return(resp); }
/// <summary> /// Gets the adb version. /// </summary> /// <param name="address">The address.</param> /// <returns></returns> public int GetAdbVersion(IPEndPoint address) { byte[] request = FormAdbRequest("host:version"); byte[] reply; Socket adbChan = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { adbChan.ReceiveTimeout = SOCKET_TIMEOUT; adbChan.SendTimeout = SOCKET_TIMEOUT; adbChan.Connect(address); adbChan.Blocking = true; if (!Write(adbChan, request)) { throw new IOException("failed asking for adb version"); } AdbResponse resp = ReadAdbResponse(adbChan, false /* readDiagstring */); if (!resp.IOSuccess || !resp.Okay) { Log.E(TAG, "Got timeout or unhappy response from ADB fb req: " + resp.Message); adbChan.Close(); return(-1); } reply = new byte[4]; if (!Read(adbChan, reply)) { Log.E(TAG, "error in getting data length"); adbChan.Close(); return(-1); } string lenHex = StringHelper.GetString(reply, AdbHelper.DEFAULT_ENCODING); int len = int.Parse(lenHex, System.Globalization.NumberStyles.HexNumber); // the protocol version. reply = new byte[len]; if (!Read(adbChan, reply)) { Log.E(TAG, "did not get the version info"); adbChan.Close(); return(-1); } string sReply = StringHelper.GetString(reply, AdbHelper.DEFAULT_ENCODING); return(int.Parse(sReply, System.Globalization.NumberStyles.HexNumber)); } catch (Exception ex) { Log.E(TAG, ex); throw; } }
/// <summary> /// Gets the devices that are available for communication. /// </summary> /// <param name="address">The address.</param> /// <returns></returns> public List <Device> GetDevices(IPEndPoint address) { byte[] request = FormAdbRequest("host:devices"); //$NON-NLS-1$ byte[] reply; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { socket.ReceiveTimeout = SOCKET_TIMEOUT; socket.SendTimeout = SOCKET_TIMEOUT; socket.Connect(address); socket.Blocking = true; if (!Write(socket, request)) { throw new AdbException("failed asking for devices"); } AdbResponse resp = ReadAdbResponse(socket, false /* readDiagstring */); if (!resp.IOSuccess || !resp.Okay) { Log.E(TAG, "Got timeout or unhappy response from ADB fb req: " + resp.Message); socket.Close(); return(null); } reply = new byte[4]; if (!Read(socket, reply)) { Log.E(TAG, "error in getting data length"); socket.Close(); return(null); } string lenHex = Encoding.Default.GetString(reply); int len = int.Parse(lenHex, System.Globalization.NumberStyles.HexNumber); reply = new byte[len]; if (!Read(socket, reply)) { Log.E(TAG, "error in getting data"); socket.Close(); return(null); } List <Device> s = new List <Device>(); string[] data = Encoding.Default.GetString(reply).Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries); foreach (var item in data) { s.Add(Device.CreateFromAdbData(item)); } return(s); } finally { socket.Close(); } }
/// <summary> /// Reads the adb response. /// </summary> /// <param name="socket">The socket.</param> /// <param name="readDiagString">if set to <c>true</c> [read diag string].</param> /// <returns></returns> public AdbResponse ReadAdbResponse(Socket socket, bool readDiagString) { AdbResponse resp = new AdbResponse(); byte[] reply = new byte[4]; if(!Read(socket, reply)) { return resp; } resp.IOSuccess = true; if(IsOkay(reply)) { resp.Okay = true; } else { readDiagString = true; // look for a reason after the FAIL resp.Okay = false; } // not a loop -- use "while" so we can use "break" while(readDiagString) { // length string is in next 4 bytes byte[] lenBuf = new byte[4]; if(!Read(socket, lenBuf)) { Log.w(TAG,"Expected diagnostic string not found"); break; } String lenStr = ReplyToString(lenBuf); int len; try { len = int.Parse(lenStr, System.Globalization.NumberStyles.HexNumber); } catch(FormatException) { Log.e(TAG, "Expected digits, got '{0}' : {1} {2} {3} {4}", lenBuf[0], lenBuf[1], lenBuf[2], lenBuf[3]); Log.e(TAG, "reply was {0}", ReplyToString(reply)); break; } byte[] msg = new byte[len]; if(!Read(socket, msg)) { Log.e(TAG, "Failed reading diagnostic string, len={0}", len); break; } resp.Message = ReplyToString(msg); Log.e(TAG, "Got reply '{0}', diag='{1}'", ReplyToString(reply), resp.Message); break; } return resp; }
/// <summary> /// Executes the remote command. /// </summary> /// <param name="endPoint">The end point.</param> /// <param name="command">The command.</param> /// <param name="device">The device.</param> /// <param name="rcvr">The RCVR.</param> /// <param name="maxTimeToOutputResponse">The max time to output response.</param> /// <exception cref="AdbException">failed submitting shell command</exception> /// <exception cref="System.OperationCanceledException"></exception> /// <exception cref="Managed.Adb.Exceptions.ShellCommandUnresponsiveException"></exception> /// <exception cref="System.IO.FileNotFoundException"></exception> /// <exception cref="UnknownOptionException"></exception> /// <exception cref="CommandAbortingException"></exception> /// <exception cref="PermissionDeniedException"></exception> public void ExecuteRemoteCommand(IPEndPoint endPoint, String command, Device device, IShellOutputReceiver rcvr, int maxTimeToOutputResponse) { Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (!device.IsOnline) { return; } try { socket.Connect(endPoint); socket.ReceiveTimeout = maxTimeToOutputResponse; socket.SendTimeout = maxTimeToOutputResponse; socket.Blocking = true; SetDevice(socket, device); byte[] request = FormAdbRequest("shell:" + command); if (!Write(socket, request)) { throw new AdbException("failed submitting shell command"); } AdbResponse resp = ReadAdbResponse(socket, false /* readDiagString */); if (!resp.IOSuccess || !resp.Okay) { throw new AdbException("sad result from adb: " + resp.Message); } byte[] data = new byte[16384]; int count = -1; while (count != 0) { if (rcvr != null && rcvr.IsCancelled) { Log.w(TAG, "execute: cancelled"); throw new OperationCanceledException( ); } count = socket.Receive(data); if (count == 0) { // we're at the end, we flush the output rcvr.Flush( ); Log.w(TAG, "execute '" + command + "' on '" + device + "' : EOF hit. Read: " + count); } else { string[] cmd = command.Trim( ).Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string sdata = data.GetString(0, count, AdbHelper.DEFAULT_ENCODING); var sdataTrimmed = sdata.Trim( ); if (sdataTrimmed.EndsWith(String.Format("{0}: not found", cmd[0]))) { Log.w(TAG, "The remote execution returned: '{0}: not found'", cmd[0]); throw new FileNotFoundException(string.Format("The remote execution returned: '{0}: not found'", cmd[0])); } if (sdataTrimmed.EndsWith("No such file or directory")) { Log.w(TAG, "The remote execution returned: {0}", sdataTrimmed); throw new FileNotFoundException(String.Format("The remote execution returned: {0}", sdataTrimmed)); } // for "unknown options" if (sdataTrimmed.Contains("Unknown option")) { Log.w(TAG, "The remote execution returned: {0}", sdataTrimmed); throw new UnknownOptionException(sdataTrimmed); } // for "aborting" commands if (sdataTrimmed.IsMatch("Aborting.$")) { Log.w(TAG, "The remote execution returned: {0}", sdataTrimmed); throw new CommandAbortingException(sdataTrimmed); } // for busybox applets // cmd: applet not found if (sdataTrimmed.IsMatch("applet not found$") && cmd.Length > 1) { Log.w(TAG, "The remote execution returned: '{0}'", sdataTrimmed); throw new FileNotFoundException(string.Format("The remote execution returned: '{0}'", sdataTrimmed)); } // checks if the permission to execute the command was denied. // workitem: 16822 if (sdataTrimmed.IsMatch("(permission|access) denied$")) { Log.w(TAG, "The remote execution returned: '{0}'", sdataTrimmed); throw new PermissionDeniedException(String.Format("The remote execution returned: '{0}'", sdataTrimmed)); } // Add the data to the receiver if (rcvr != null) { rcvr.AddOutput(data, 0, count); } } } } catch (SocketException s) { throw new ShellCommandUnresponsiveException( ); } finally { if (socket != null) { socket.Close( ); } rcvr.Flush( ); } }
/// <summary> /// Gets the frame buffer from the specified end point. /// </summary> /// <param name="adbSockAddr">The adb sock addr.</param> /// <param name="device">The device.</param> /// <returns></returns> public RawImage GetFrameBuffer(IPEndPoint adbSockAddr, IDevice device) { RawImage imageParams = new RawImage( ); byte[] request = FormAdbRequest("framebuffer:"); //$NON-NLS-1$ byte[] nudge = { 0 }; byte[] reply; Socket adbChan = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { adbChan.Connect(adbSockAddr); adbChan.Blocking = true; // if the device is not -1, then we first tell adb we're looking to talk // to a specific device SetDevice(adbChan, device); if (!Write(adbChan, request)) { throw new AdbException("failed asking for frame buffer"); } AdbResponse resp = ReadAdbResponse(adbChan, false /* readDiagString */); if (!resp.IOSuccess || !resp.Okay) { Log.w(TAG, "Got timeout or unhappy response from ADB fb req: " + resp.Message); adbChan.Close( ); return(null); } // first the protocol version. reply = new byte[4]; if (!Read(adbChan, reply)) { Log.w(TAG, "got partial reply from ADB fb:"); adbChan.Close( ); return(null); } BinaryReader buf; int version = 0; using (MemoryStream ms = new MemoryStream(reply)) { buf = new BinaryReader(ms); version = buf.ReadInt16( ); } // get the header size (this is a count of int) int headerSize = RawImage.GetHeaderSize(version); // read the header reply = new byte[headerSize * 4]; if (!Read(adbChan, reply)) { Log.w(TAG, "got partial reply from ADB fb:"); adbChan.Close( ); return(null); } using (MemoryStream ms = new MemoryStream(reply)) { buf = new BinaryReader(ms); // fill the RawImage with the header if (imageParams.ReadHeader(version, buf) == false) { Log.w(TAG, "Unsupported protocol: " + version); return(null); } } Log.d(TAG, "image params: bpp=" + imageParams.Bpp + ", size=" + imageParams.Size + ", width=" + imageParams.Width + ", height=" + imageParams.Height); if (!Write(adbChan, nudge)) { throw new AdbException("failed nudging"); } reply = new byte[imageParams.Size]; if (!Read(adbChan, reply)) { Log.w(TAG, "got truncated reply from ADB fb data"); adbChan.Close( ); return(null); } imageParams.Data = reply; } finally { if (adbChan != null) { adbChan.Close( ); } } return(imageParams); }
public void RunCatLog(IPEndPoint address, IDevice device, string filePath, LogReceiver receiver) { if (device.IsOnline && (receiver != null)) { int num = 0x1400; Action action = null; Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, new LingerOption(true, 0)); socket.ReceiveTimeout = -1; socket.ReceiveBufferSize = num + 1; socket.Blocking = true; socket.Connect(AndroidDebugBridge.SocketAddress); if (action == null) { action = delegate { if (socket != null) { socket.Close(); } }; } receiver.CancelAction = action; this.SetDevice(socket, device); //byte[] data = Instance.FormAdbRequest(string.Format("shell:cat {0}", filePath)); byte[] data = Instance.FormAdbRequest(string.Format("log:{0}", filePath)); if (!this.Write(socket, data)) { throw new AdbException("failed submitting shell command"); } AdbResponse response = Instance.ReadAdbResponse(socket, false); if (!response.IOSuccess || !response.Okay) { throw new AdbException("sad result from adb: " + response.Message); } byte[] buffer = new byte[num + 1]; byte num2 = 0; while ((device.IsOnline && (receiver != null)) && !receiver.IsCancelled) { int num3 = socket.Receive(buffer); if (num3 > 0) { using (MemoryStream stream = new MemoryStream()) { for (int i = 0; i < num3; i++) { if ((((num3 > (i + 1)) && (buffer[i] == 13)) && (buffer[i + 1] == 10)) || ((num2 == 13) && (buffer[i] == 10))) { stream.WriteByte(10); i++; } else { stream.WriteByte(buffer[i]); } if (i == (num3 - 1)) { num2 = buffer[i]; } } receiver.ParseNewData(stream.ToArray(), 0, (int)stream.Length); //continue; } } } } catch (SocketException exception) { if (exception.SocketErrorCode != SocketError.ConnectionAborted) { Log.e("Socket error while receiving response", exception); } } finally { if (socket != null) { socket.Dispose(); } } } }
/// <summary> /// Executes a shell command on the remote device /// </summary> /// <param name="endPoint">The socket end point</param> /// <param name="command">The command to execute</param> /// <param name="device">The device to execute on</param> /// <param name="rcvr">The shell output receiver</param> /// <exception cref="FileNotFoundException">Throws if the result is 'command': not found</exception> /// <exception cref="IOException">Throws if there is a problem reading / writing to the socket</exception> /// <exception cref="OperationCanceledException">Throws if the execution was canceled</exception> /// <exception cref="EndOfStreamException">Throws if the Socket.Receice ever returns -1</exception> public void ExecuteRemoteCommand(IPEndPoint endPoint, string command, Device device, IShellOutputReceiver rcvr) { Log.I(TAG, "executing '" + command + "' on '" + device + "'."); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); if (!device.IsOnline) { return; } try { socket.ReceiveTimeout = SOCKET_TIMEOUT; socket.SendTimeout = SOCKET_TIMEOUT; socket.Connect(endPoint); socket.Blocking = true; SetDevice(socket, device); byte[] request = FormAdbRequest("shell:" + command); if (!Write(socket, request)) { throw new AdbException("failed submitting shell command"); } AdbResponse resp = ReadAdbResponse(socket, false /* readDiagstring */); if (!resp.IOSuccess || !resp.Okay) { throw new AdbException("sad result from adb: " + resp.Message); } byte[] data = new byte[16384]; int count = -1; socket.ReceiveTimeout = SOCKET_TIMEOUT_SHELLCOMMAND; while (count != 0) { if (rcvr != null && rcvr.IsCancelled) { Log.W(TAG, "execute: cancelled"); throw new OperationCanceledException(); } count = socket.Receive(data); if (count < 0) { // we're at the end, we flush the output rcvr.Flush(); Log.W(TAG, "execute '" + command + "' on '" + device + "' : EOF hit. Read: " + count); throw new EndOfStreamException(); } else if (count == 0) { // do nothing } else { string[] cmd = command.Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); string sdata = StringHelper.GetString(data, 0, count, AdbHelper.DEFAULT_ENCODING); var sdataTrimmed = sdata.Trim(); if (sdataTrimmed.EndsWith(string.Format("{0}: not found", cmd[0]))) { Log.W("AdbHelper", "The remote execution returned: '{0}: not found'", cmd[0]); throw new FileNotFoundException(string.Format("The remote execution returned: '{0}: not found'", cmd[0])); } if (sdataTrimmed.EndsWith("No such file or directory")) { Log.W("AdbHelper", "The remote execution returned: {0}", sdataTrimmed); throw new FileNotFoundException(string.Format("The remote execution returned: {0}", sdataTrimmed)); } // for busybox applets // cmd: applet not found if (cmd.Length > 1 && sdataTrimmed.EndsWith(string.Format("{0}: applet not found", cmd[1]))) { Log.W("AdbHelper", "The remote execution returned: '{0}'", sdataTrimmed); throw new FileNotFoundException(string.Format("The remote execution returned: '{0}'", sdataTrimmed)); } // checks if the permission to execute the command was denied. // workitem: 16822 if (sdataTrimmed.EndsWith(string.Format("{0}: permission denied", cmd[0])) || sdataTrimmed.EndsWith(string.Format("{0}: access denied", cmd[0]))) { Log.W("AdbHelper", "The remote execution returned: '{0}'", sdataTrimmed); throw new PermissionDeniedException(string.Format("The remote execution returned: '{0}'", sdataTrimmed)); } // Add the data to the receiver if (rcvr != null) { rcvr.AddOutput(data, 0, count); } } } } /*catch ( Exception e ) { * Log.e ( "AdbHelper", e ); * throw; * }*/ finally { if (socket != null) { socket.Close(); } rcvr.Flush(); } }