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(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 path2Create = new List(); 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 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); } } } } }