mirror of
https://github.com/ReneLergner/WPinternals.git
synced 2026-06-14 03:16:40 +10:00
348 lines
15 KiB
C#
348 lines
15 KiB
C#
// Copyright (c) 2018, Rene Lergner - wpinternals.net - @Heathcliff74xda
|
|
//
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
// to deal in the Software without restriction, including without limitation
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
//
|
|
// The above copyright notice and this permission notice shall be included in
|
|
// all copies or substantial portions of the Software.
|
|
//
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
using MadWizard.WinUSBNet;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
|
|
namespace WPinternals
|
|
{
|
|
internal class NokiaPhoneModel: IDisposable
|
|
{
|
|
protected bool Disposed = false;
|
|
private USBDevice Device = null;
|
|
private int MessageId = 0;
|
|
private object UsbLock = new object();
|
|
|
|
public NokiaPhoneModel(string DevicePath)
|
|
{
|
|
// Mass Storage device is not WinUSB
|
|
try
|
|
{
|
|
Device = new USBDevice(DevicePath);
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private JToken ExecuteJsonMethodAsJsonToken(string JsonMethod, Dictionary<string, object> Params, string ResultElement)
|
|
{
|
|
byte[] Buffer;
|
|
int Length;
|
|
|
|
lock (UsbLock)
|
|
{
|
|
string jsonrpc = "2.0";
|
|
int id = MessageId++;
|
|
string method = JsonMethod;
|
|
Dictionary<string, object> @params = new Dictionary<string, object>();
|
|
if (Params != null)
|
|
{
|
|
foreach (KeyValuePair<string, object> Param in Params)
|
|
{
|
|
if (Param.Value is byte[])
|
|
@params.Add(Param.Key, ((byte[])Param.Value).Select(b => (int)b).ToArray()); // convert to int-array
|
|
else
|
|
@params.Add(Param.Key, Param.Value);
|
|
}
|
|
}
|
|
@params.Add("MessageVersion", 0);
|
|
string Request = JsonConvert.SerializeObject(new { jsonrpc, id, method, @params });
|
|
Device.OutputPipe.Write(System.Text.Encoding.ASCII.GetBytes(Request));
|
|
|
|
Buffer = new byte[0x10000];
|
|
Length = Device.InputPipe.Read(Buffer);
|
|
}
|
|
|
|
Newtonsoft.Json.Linq.JObject ResultMessage = Newtonsoft.Json.Linq.JObject.Parse(System.Text.ASCIIEncoding.ASCII.GetString(Buffer, 0, Length));
|
|
|
|
JToken ResultToken = ResultMessage.Root.SelectToken("result");
|
|
if ((ResultToken == null) || (ResultElement == null)) return null;
|
|
return ResultToken.SelectToken(ResultElement);
|
|
}
|
|
|
|
public void ExecuteJsonMethod(string JsonMethod, Dictionary<string, object> Params)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, Params, null);
|
|
}
|
|
|
|
public string ExecuteJsonMethodAsString(string JsonMethod, Dictionary<string, object> Params, string ResultElement)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, Params, ResultElement);
|
|
if (Token == null) return null;
|
|
return Token.Value<string>();
|
|
}
|
|
|
|
public string ExecuteJsonMethodAsString(string JsonMethod, string ResultElement)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, null, ResultElement);
|
|
if (Token == null) return null;
|
|
return Token.Value<string>();
|
|
}
|
|
|
|
public int ExecuteJsonMethodAsInteger(string JsonMethod, Dictionary<string, object> Params, string ResultElement)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, Params, ResultElement);
|
|
if (Token == null) return 0;
|
|
return Token.Value<int>();
|
|
}
|
|
|
|
public int ExecuteJsonMethodAsInteger(string JsonMethod, string ResultElement)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, null, ResultElement);
|
|
if (Token == null) return 0;
|
|
return Token.Value<int>();
|
|
}
|
|
|
|
public byte[] ExecuteJsonMethodAsBytes(string JsonMethod, Dictionary<string, object> Params, string ResultElement)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, Params, ResultElement);
|
|
if (Token == null) return null;
|
|
return Token.Values<byte>().ToArray();
|
|
}
|
|
|
|
public byte[] ExecuteJsonMethodAsBytes(string JsonMethod, string ResultElement)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, null, ResultElement);
|
|
if (Token == null) return null;
|
|
return Token.Values<byte>().ToArray();
|
|
}
|
|
|
|
public bool? ExecuteJsonMethodAsBoolean(string JsonMethod, string ResultElement)
|
|
{
|
|
JToken Token = ExecuteJsonMethodAsJsonToken(JsonMethod, null, ResultElement);
|
|
if (Token == null) return null;
|
|
return Token.Value<bool>();
|
|
}
|
|
|
|
public void ExecuteJsonMethodAsync(string JsonMethod, Dictionary<string, object> Params)
|
|
{
|
|
lock (UsbLock)
|
|
{
|
|
string jsonrpc = "2.0";
|
|
int id = MessageId++;
|
|
string method = JsonMethod;
|
|
Dictionary<string, object> @params = new Dictionary<string, object>();
|
|
if (Params != null)
|
|
{
|
|
foreach (KeyValuePair<string, object> Param in Params)
|
|
{
|
|
if (Param.Value is byte[])
|
|
@params.Add(Param.Key, ((byte[])Param.Value).Select(b => (int)b).ToArray()); // convert to int-array
|
|
else
|
|
@params.Add(Param.Key, Param.Value);
|
|
}
|
|
}
|
|
@params.Add("MessageVersion", 0);
|
|
string Request = JsonConvert.SerializeObject(new { jsonrpc, id, method, @params });
|
|
|
|
byte[] OutBuffer = System.Text.Encoding.ASCII.GetBytes(Request);
|
|
Device.OutputPipe.BeginWrite(OutBuffer, 0, OutBuffer.Length, (AsyncResultWrite) =>
|
|
{
|
|
Device.OutputPipe.EndWrite(AsyncResultWrite);
|
|
}, null);
|
|
}
|
|
}
|
|
|
|
public void ExecuteJsonMethodAsync(string JsonMethod)
|
|
{
|
|
ExecuteJsonMethod(JsonMethod, null);
|
|
}
|
|
|
|
public delegate void JsonMethodCallbackString(object State, string Result);
|
|
|
|
public void ExecuteJsonMethodAsStringAsync(string JsonMethod, Dictionary<string, object> Params, string ResultElement, object State, JsonMethodCallbackString Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, Params, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Value<string>()); });
|
|
}
|
|
|
|
public void ExecuteJsonMethodAsStringAsync(string JsonMethod, string ResultElement, object State, JsonMethodCallbackString Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, null, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Value<string>()); });
|
|
}
|
|
|
|
public delegate void JsonMethodCallbackBoolean(object State, bool Result);
|
|
|
|
public void ExecuteJsonMethodAsBooleanAsync(string JsonMethod, Dictionary<string, object> Params, string ResultElement, object State, JsonMethodCallbackBoolean Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, Params, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Value<bool>()); });
|
|
}
|
|
|
|
public void ExecuteJsonMethodAsBooleanAsync(string JsonMethod, string ResultElement, object State, JsonMethodCallbackBoolean Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, null, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Value<bool>()); });
|
|
}
|
|
|
|
public delegate void JsonMethodCallbackBytes(object State, byte[] Result);
|
|
|
|
public void ExecuteJsonMethodAsBytesAsync(string JsonMethod, Dictionary<string, object> Params, string ResultElement, object State, JsonMethodCallbackBytes Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, Params, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Values<byte>().ToArray()); });
|
|
}
|
|
|
|
public void ExecuteJsonMethodAsBytesAsync(string JsonMethod, string ResultElement, object State, JsonMethodCallbackBytes Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, null, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Values<byte>().ToArray()); });
|
|
}
|
|
|
|
public delegate void JsonMethodCallbackInteger(object State, int Result);
|
|
|
|
public void ExecuteJsonMethodAsIntegerAsync(string JsonMethod, Dictionary<string, object> Params, string ResultElement, object State, JsonMethodCallbackInteger Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, Params, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Value<int>()); });
|
|
}
|
|
|
|
public void ExecuteJsonMethodAsIntegerAsync(string JsonMethod, string ResultElement, object State, JsonMethodCallbackInteger Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, null, ResultElement, State, (ReturnState, Token) => { Callback(ReturnState, Token.Value<int>()); });
|
|
}
|
|
|
|
public delegate void JsonMethodCallbackToken(object State, JToken Result);
|
|
|
|
public void ExecuteJsonMethodAsTokenAsync(string JsonMethod, Dictionary<string, object> Params, string ResultElement, object State, JsonMethodCallbackToken Callback)
|
|
{
|
|
byte[] Buffer;
|
|
int Length;
|
|
|
|
lock (UsbLock)
|
|
{
|
|
string jsonrpc = "2.0";
|
|
int id = MessageId++;
|
|
string method = JsonMethod;
|
|
Dictionary<string, object> @params = new Dictionary<string, object>();
|
|
if (Params != null)
|
|
{
|
|
foreach (KeyValuePair<string, object> Param in Params)
|
|
{
|
|
if (Param.Value is byte[])
|
|
@params.Add(Param.Key, ((byte[])Param.Value).Select(b => (int)b).ToArray()); // convert to int-array
|
|
else
|
|
@params.Add(Param.Key, Param.Value);
|
|
}
|
|
}
|
|
@params.Add("MessageVersion", 0);
|
|
string Request = JsonConvert.SerializeObject(new { jsonrpc, id, method, @params });
|
|
|
|
byte[] OutBuffer = System.Text.Encoding.ASCII.GetBytes(Request);
|
|
Device.OutputPipe.BeginWrite(OutBuffer, 0, OutBuffer.Length, (AsyncResultWrite) =>
|
|
{
|
|
Device.OutputPipe.EndWrite(AsyncResultWrite);
|
|
Buffer = new byte[0x10000];
|
|
Device.InputPipe.BeginRead(Buffer, 0, 0x10000, (AsyncResultRead) =>
|
|
{
|
|
Length = Device.InputPipe.EndRead(AsyncResultRead);
|
|
|
|
Newtonsoft.Json.Linq.JObject ResultMessage = Newtonsoft.Json.Linq.JObject.Parse(System.Text.ASCIIEncoding.ASCII.GetString(Buffer, 0, Length));
|
|
|
|
JToken ResultToken = ResultMessage.Root.SelectToken("result");
|
|
if ((ResultToken == null) || (ResultElement == null)) Callback(AsyncResultRead.AsyncState, null);
|
|
Callback(AsyncResultRead.AsyncState, ResultToken.SelectToken(ResultElement));
|
|
}, AsyncResultWrite.AsyncState);
|
|
}, State);
|
|
}
|
|
}
|
|
|
|
public void ExecuteJsonMethodAsTokenAsync(string JsonMethod, string ResultElement, object State, JsonMethodCallbackToken Callback)
|
|
{
|
|
ExecuteJsonMethodAsTokenAsync(JsonMethod, null, ResultElement, State, Callback);
|
|
}
|
|
|
|
public byte[] ExecuteRawMethod(byte[] RawMethod)
|
|
{
|
|
return ExecuteRawMethod(RawMethod, RawMethod.Length);
|
|
}
|
|
|
|
public byte[] ExecuteRawMethod(byte[] RawMethod, int Length)
|
|
{
|
|
byte[] Buffer = new byte[0x8000]; // Should be at least 0x4408 for receiving the GPT packet.
|
|
byte[] Result = null;
|
|
lock (UsbLock)
|
|
{
|
|
Device.OutputPipe.Write(RawMethod, 0, Length);
|
|
try
|
|
{
|
|
int OutputLength = Device.InputPipe.Read(Buffer);
|
|
Result = new byte[OutputLength];
|
|
System.Buffer.BlockCopy(Buffer, 0, Result, 0, OutputLength);
|
|
}
|
|
catch { } // Reboot command looses connection
|
|
}
|
|
return Result;
|
|
}
|
|
|
|
public void ExecuteRawVoidMethod(byte[] RawMethod)
|
|
{
|
|
ExecuteRawVoidMethod(RawMethod, RawMethod.Length);
|
|
}
|
|
|
|
public void ExecuteRawVoidMethod(byte[] RawMethod, int Length)
|
|
{
|
|
lock (UsbLock)
|
|
{
|
|
Device.OutputPipe.Write(RawMethod, 0, Length);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disposes the UsbDevice including all unmanaged WinUSB handles. This function
|
|
/// should be called when the UsbDevice object is no longer in use, otherwise
|
|
/// unmanaged handles will remain open until the garbage collector finalizes the
|
|
/// object.
|
|
/// </summary>
|
|
public void Dispose()
|
|
{
|
|
Dispose(true);
|
|
GC.SuppressFinalize(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Finalizer for the UsbDevice. Disposes all unmanaged handles.
|
|
/// </summary>
|
|
~NokiaPhoneModel()
|
|
{
|
|
Dispose(false);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Disposes the object
|
|
/// </summary>
|
|
/// <param name="disposing">Indicates wether Dispose was called manually (true) or by
|
|
/// the garbage collector (false) via the destructor.</param>
|
|
protected virtual void Dispose(bool disposing)
|
|
{
|
|
if (Disposed)
|
|
return;
|
|
|
|
if (disposing)
|
|
{
|
|
if (Device != null)
|
|
Device.Dispose();
|
|
}
|
|
|
|
// Clean unmanaged resources here.
|
|
// (none currently)
|
|
|
|
Disposed = true;
|
|
}
|
|
}
|
|
}
|