524 lines
18 KiB
C#
524 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using XDevkit;
|
|
using System.IO;
|
|
using System.Windows.Forms;
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace ITFInstaller
|
|
{
|
|
public class x360FileProxy : FileProxy
|
|
{
|
|
internal XboxConsole x360;
|
|
XboxManager xbm;
|
|
|
|
public override string getName() { return "x360"; }
|
|
|
|
public enum X360_ERRORS : uint
|
|
{
|
|
XBDM_NOERR = 0x02DA0000,
|
|
XBDM_UNDEFINED = 0x82DA0000,
|
|
XBDM_MAXCONNECT = 0x82DA0001,
|
|
XBDM_NOSUCHFILE = 0x82DA0002,
|
|
XBDM_NOMODULE = 0x82DA0003,
|
|
XBDM_MEMUNMAPPED = 0x82DA0004,
|
|
XBDM_NOTHREAD = 0x82DA0005,
|
|
XBDM_CLOCKNOTSET = 0x82DA0006,
|
|
XBDM_INVALIDCMD = 0x82DA0007,
|
|
XBDM_NOTSTOPPED = 0x82DA0008,
|
|
XBDM_MUSTCOPY = 0x82DA0009,
|
|
XBDM_ALREADYEXISTS = 0x82DA000A,
|
|
XBDM_DIRNOTEMPTY = 0x82DA000B,
|
|
XBDM_BADFILENAME = 0x82DA000C,
|
|
XBDM_CANNOTCREATE = 0x82DA000D,
|
|
XBDM_CANNOTACCESS = 0x82DA000E,
|
|
XBDM_DEVICEFULL = 0x82DA000F,
|
|
XBDM_NOTDEBUGGABLE = 0x82DA0010,
|
|
XBDM_BADCOUNTTYPE = 0x82DA0011,
|
|
XBDM_COUNTUNAVAILABLE = 0x82DA0012,
|
|
XBDM_NOTLOCKED = 0x82DA0014,
|
|
XBDM_KEYXCHG = 0x82DA0015,
|
|
XBDM_MUSTBEDEDICATED = 0x82DA0016,
|
|
XBDM_INVALIDARG = 0x82DA0017,
|
|
XBDM_PROFILENOTSTARTED = 0x82DA0018,
|
|
XBDM_PROFILEALREADYSTARTED = 0x82DA0019,
|
|
XBDM_ALREADYSTOPPED = 0x82DA001A,
|
|
XBDM_FASTCAPNOTENABLED = 0x82DA001B,
|
|
XBDM_NOMEMORY = 0x82DA001C,
|
|
XBDM_TIMEOUT = 0x82DA001D,
|
|
XBDM_NOSUCHPATH = 0x82DA001E,
|
|
XBDM_INVALID_SCREEN_INPUT_FORMAT = 0x82DA001F,
|
|
XBDM_INVALID_SCREEN_OUTPUT_FORMAT = 0x82DA0020,
|
|
XBDM_CALLCAPNOTENABLED = 0x82DA0021,
|
|
XBDM_INVALIDCAPCFG = 0x82DA0022,
|
|
XBDM_CAPNOTENABLED = 0x82DA0023,
|
|
XBDM_TOOBIGJUMP = 0x82DA0024,
|
|
XBDM_FIELDNOTPRESENT = 0x82DA0025,
|
|
XBDM_OUTPUTBUFFERTOOSMALL = 0x82DA0026,
|
|
XBDM_PROFILEREBOOT = 0x82DA0027,
|
|
XBDM_PROFILENOTITLE = 0x82DA0028,
|
|
XBDM_INVALIDSTATE = 0x82DA0042,
|
|
XBDM_D3D_DEBUG_COMMAND_NOT_IMPLEMENTED = 0x82DA0050,
|
|
XBDM_D3D_INVALID_SURFACE = 0x82DA0051,
|
|
XBDM_CANNOTCONNECT = 0x82DA0100,
|
|
XBDM_CONNECTIONLOST = 0x82DA0101,
|
|
XBDM_FILEERROR = 0x82DA0103,
|
|
XBDM_ENDOFLIST = 0x82DA0104,
|
|
XBDM_BUFFER_TOO_SMALL = 0x82DA0105,
|
|
XBDM_NOTXBEFILE = 0x82DA0106,
|
|
XBDM_MEMSETINCOMPLETE = 0x82DA0107,
|
|
XBDM_NOXBOXNAME = 0x82DA0108,
|
|
XBDM_NOERRORSTRING = 0x82DA0109,
|
|
XBDM_INVALIDSTATUS = 0x82DA010A,
|
|
XBDM_TASK_PENDING = 0x82DA0150,
|
|
XBDM_CONNECTED = 0x02DA0001,
|
|
XBDM_MULTIRESPONSE = 0x02DA0002,
|
|
XBDM_BINRESPONSE = 0x02DA0003,
|
|
XBDM_READYFORBIN = 0x02DA0004,
|
|
XBDM_DEDICATED = 0x02DA0005,
|
|
XBDM_PROFILERESTARTED = 0x02DA0006,
|
|
XBDM_FASTCAPENABLED = 0x02DA0007
|
|
|
|
}
|
|
|
|
public x360FileProxy(string XboxNameOrIp)
|
|
{
|
|
xbm = new XboxManager();
|
|
if (String.IsNullOrEmpty(XboxNameOrIp))
|
|
XboxNameOrIp = xbm.DefaultConsole;
|
|
x360 = xbm.OpenConsole(XboxNameOrIp);
|
|
try
|
|
{
|
|
XboxConsoleType xct = x360.ConsoleType;
|
|
}
|
|
catch (COMException)
|
|
{
|
|
//throw new Exception(xbm.TranslateError(comE.ErrorCode),
|
|
// comE);
|
|
}
|
|
}
|
|
|
|
|
|
internal bool FilesHaveSameModTime(string srcPath,string destPath)
|
|
{
|
|
bool bSkipFile = false;
|
|
DateTime destTime = getLastWriteTime(destPath);
|
|
if (destTime == DateTime.MinValue)
|
|
return false;
|
|
|
|
DateTime srcTime = File.GetLastWriteTime(srcPath);
|
|
{
|
|
// Note for X360 Systems (taken from XDk documentation) :
|
|
// The FATX file system supports the file creation, last access, and last write time values.
|
|
// Not all file systems can record creation and last access time, and not all file systems
|
|
// record them in the same manner. For example, on FATX, create time, write time, and
|
|
// last access time all have a resolution of 2 seconds.
|
|
// Therefore, GetFileTime may not return the same file time information set using the SetFileTime
|
|
// function. FATX records times on disk using UTC rather than local file time.
|
|
|
|
TimeSpan ts = (destTime - srcTime);
|
|
double totalSeconds = Math.Abs(ts.TotalSeconds);
|
|
bSkipFile = (totalSeconds >= 0 && totalSeconds <= 2);
|
|
}
|
|
|
|
return bSkipFile;
|
|
}
|
|
|
|
public override bool CopyFile(string sourceFile, string destinationFile, ref DateTime dateTime)
|
|
{
|
|
//source always from PC
|
|
//destination always to x360
|
|
if (!File.Exists(sourceFile))
|
|
return false;
|
|
|
|
// if (filesHaveSameModTime(sourceFile, destinationFile))
|
|
// return false;
|
|
|
|
FileStream source = File.OpenRead(sourceFile);
|
|
uint srcSize = (uint)source.Length;
|
|
|
|
Array FileData = Array.CreateInstance(typeof(byte), srcSize);
|
|
byte[] bData = (byte[])FileData;
|
|
int nbDataRead = source.Read(bData, 0, (int)srcSize);
|
|
string directory = Path.GetDirectoryName(destinationFile);
|
|
CreateDirectory(directory);
|
|
|
|
CreateFile(destinationFile, srcSize);
|
|
WriteFile(destinationFile, 0, bData);
|
|
|
|
dateTime = File.GetLastWriteTime(sourceFile);
|
|
setLastWriteTime(destinationFile, dateTime);
|
|
|
|
source.Close();
|
|
source = null;
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
public bool FileExists(string FilePath)
|
|
{
|
|
bool retry = true;
|
|
while (retry)
|
|
{
|
|
try
|
|
{
|
|
IXboxFile xbFile = x360.GetFileObject(FilePath);
|
|
retry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_BADFILENAME
|
|
|| ErrorCode == X360_ERRORS.XBDM_NOSUCHFILE
|
|
|| ErrorCode == X360_ERRORS.XBDM_NOSUCHPATH)
|
|
{
|
|
return false;
|
|
}
|
|
else if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
retry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
public DateTime getLastWriteTime(string FilePath)
|
|
{
|
|
DateTime dt = DateTime.MinValue;
|
|
bool retry = true;
|
|
while (retry)
|
|
{
|
|
try
|
|
{
|
|
if (!FileExists(FilePath))
|
|
return dt;
|
|
|
|
IXboxFile xFile = x360.GetFileObject(FilePath);
|
|
|
|
dt = (DateTime) xFile.ChangeTime;
|
|
retry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
retry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
return dt;
|
|
}
|
|
public void setLastWriteTime(string filePath, DateTime datetime)
|
|
{
|
|
bool bRetry = true;
|
|
while (bRetry)
|
|
{
|
|
try
|
|
{
|
|
IXboxFile xbFile = x360.GetFileObject(filePath);
|
|
if (xbFile!= null)
|
|
xbFile.ChangeTime = datetime;
|
|
bRetry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
bRetry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public Array ReadFile(string sourceFile, long offset, uint size)
|
|
{
|
|
Array FileData = Array.CreateInstance(typeof(byte), size);
|
|
uint nbDataRead = 0;
|
|
|
|
bool bRetry = true;
|
|
while (bRetry)
|
|
{
|
|
try
|
|
{
|
|
x360.ReadFileBytes(sourceFile, (uint)offset, size, (byte[])FileData, out nbDataRead);
|
|
bRetry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
bRetry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
|
|
|
|
byte[] bArray = (byte[])FileData;
|
|
Array.Resize<byte>(ref bArray, (int)nbDataRead);
|
|
return bArray;
|
|
}
|
|
|
|
public override uint getFileSize(string filePath)
|
|
{
|
|
uint size = uint.MaxValue;
|
|
bool retry = true;
|
|
while (retry)
|
|
{
|
|
try
|
|
{
|
|
size = (uint)x360.GetFileObject(filePath).Size;
|
|
retry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
retry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
return size;
|
|
}
|
|
|
|
public override bool DirectoryExists(string DirectoryPath)
|
|
{
|
|
bool isDirectory = false;
|
|
bool retry = true;
|
|
while (retry)
|
|
{
|
|
try
|
|
{
|
|
IXboxFile xbFile = x360.GetFileObject(DirectoryPath);
|
|
isDirectory = xbFile.IsDirectory;
|
|
retry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_BADFILENAME
|
|
|| ErrorCode == X360_ERRORS.XBDM_NOSUCHFILE
|
|
|| ErrorCode == X360_ERRORS.XBDM_NOSUCHPATH)
|
|
{
|
|
return false;
|
|
}
|
|
else if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
retry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
public override void DeleteFile(string FilePath)
|
|
{
|
|
bool bRetry = true;
|
|
while (bRetry)
|
|
{
|
|
try
|
|
{
|
|
x360.DeleteFile(FilePath);
|
|
bRetry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
if (ErrorCode == X360_ERRORS.XBDM_NOSUCHFILE)
|
|
{
|
|
bRetry = false;
|
|
}
|
|
else
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
bRetry = true;
|
|
}
|
|
else
|
|
{
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override bool CreateDirectory(string DirectoryPath)
|
|
{
|
|
bool retry = true;
|
|
while (retry)
|
|
{
|
|
try
|
|
{
|
|
List<string> path2Create = new List<string>();
|
|
bool PathDoesNotExist = true;
|
|
string strPath2Check = DirectoryPath;
|
|
path2Create.Add(DirectoryPath);
|
|
while (PathDoesNotExist || String.IsNullOrEmpty(strPath2Check))
|
|
{
|
|
strPath2Check = strPath2Check.TrimEnd('\\');
|
|
strPath2Check = Path.GetDirectoryName(strPath2Check);
|
|
strPath2Check += "\\";
|
|
PathDoesNotExist = !DirectoryExists(strPath2Check);
|
|
if (PathDoesNotExist)
|
|
{
|
|
path2Create.Add(strPath2Check);
|
|
}
|
|
}
|
|
for (int i = path2Create.Count - 1; i >= 0; i--)
|
|
{
|
|
try
|
|
{
|
|
if (!DirectoryExists(path2Create[i]))
|
|
x360.MakeDirectory(path2Create[i]);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.ToString());
|
|
|
|
// X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
// if (ErrorCode != X360_ERRORS.XBDM_ALREADYEXISTS)
|
|
// throw comE;
|
|
}
|
|
}
|
|
retry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
retry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public void WriteFile(string destinationFile, long offset, Array FileData)
|
|
{
|
|
uint nbDataRead;
|
|
bool bRetry = true;
|
|
while (bRetry)
|
|
{
|
|
try
|
|
{
|
|
x360.WriteFileBytes(destinationFile, (uint)offset, (uint)FileData.LongLength, (byte[])FileData, out nbDataRead);
|
|
bRetry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
if (ErrorCode == X360_ERRORS.XBDM_CONNECTIONLOST)
|
|
{
|
|
bRetry = false;
|
|
}
|
|
else
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
bRetry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
public void DirectoryFiles(string directoryPath,ref List<string> files)
|
|
{
|
|
bool bRetry = true;
|
|
|
|
while (bRetry)
|
|
{
|
|
try
|
|
{
|
|
IXboxFiles filesResult = x360.DirectoryFiles(directoryPath);
|
|
|
|
foreach (IXboxFile file in filesResult)
|
|
{
|
|
if (!file.IsDirectory)
|
|
{
|
|
files.Add(file.Name);
|
|
}
|
|
else
|
|
{
|
|
DirectoryFiles(file.Name, ref files);
|
|
}
|
|
}
|
|
|
|
bRetry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
bRetry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void CreateFile(string filePath,uint MinLength)
|
|
{
|
|
bool bRetry = true;
|
|
|
|
while (bRetry)
|
|
{
|
|
try
|
|
{
|
|
x360.SetFileSize(filePath, MinLength, XboxCreateDisposition.CreateAlways);
|
|
bRetry = false;
|
|
}
|
|
catch (COMException comE)
|
|
{
|
|
X360_ERRORS ErrorCode = (X360_ERRORS)(uint)comE.ErrorCode;
|
|
|
|
if (ErrorCode == X360_ERRORS.XBDM_MAXCONNECT)
|
|
{
|
|
bRetry = true;
|
|
}
|
|
else
|
|
throw new Exception(xbm.TranslateError(comE.ErrorCode), comE);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|