XbdmWrapper.ps1

$cp = New-Object CodeDom.Compiler.CompilerParameters 
$cp.CompilerOptions = "/unsafe"

Add-Type -CompilerParameters $cp @'
using System;
using System.IO;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Text;
 
namespace XBDM
{
    [StructLayout(LayoutKind.Sequential)]
    public struct LARGE_INTEGER
    {
        public UInt32 LowPart;
        public long HighPart;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct DM_VERSION_INFO
    {
        public ushort Major;
        public ushort Minor;
        public ushort Build;
        public ushort QFE;
    }
     
    [StructLayout(LayoutKind.Sequential)]
    public struct DM_COUNTDATA
    {
        public UInt64 CountValue;
        public UInt64 RateValue;
        public uint CountType;
    }
     
    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DM_CONTEXT {
 
        //
        // The flags values within this flag control the contents of
        // a CONTEXT record.
        //
        // If the context record is used as an input parameter, then
        // for each portion of the context record controlled by a flag
        // whose value is set, it is assumed that that portion of the
        // context record contains valid context. If the context record
        // is being used to modify a thread's context, then only that
        // portion of the threads context will be modified.
        //
        // If the context record is used as an IN OUT parameter to capture
        // the context of a thread, then only those portions of the thread's
        // context corresponding to set flags will be returned.
        //
        // The context record is never used as an OUT only parameter.
        //
 
        uint ContextFlags;
 
        //
        // This section is specified/returned if the ContextFlags word contains
        // the flag CONTEXT_CONTROL.
        //
 
        uint Msr; // Machine status register
        uint Iar; // Instruction address register
        uint Lr; // Link register
        UInt64 Ctr; // Count register
 
        //
        // This section is specified/returned if the ContextFlags word contains
        // the flag CONTEXT_INTEGER.
        //
 
        UInt64 Gpr0; // General registers 0..31
        UInt64 Gpr1;
        UInt64 Gpr2;
        UInt64 Gpr3;
        UInt64 Gpr4;
        UInt64 Gpr5;
        UInt64 Gpr6;
        UInt64 Gpr7;
        UInt64 Gpr8;
        UInt64 Gpr9;
        UInt64 Gpr10;
        UInt64 Gpr11;
        UInt64 Gpr12;
        UInt64 Gpr13;
        UInt64 Gpr14;
        UInt64 Gpr15;
        UInt64 Gpr16;
        UInt64 Gpr17;
        UInt64 Gpr18;
        UInt64 Gpr19;
        UInt64 Gpr20;
        UInt64 Gpr21;
        UInt64 Gpr22;
        UInt64 Gpr23;
        UInt64 Gpr24;
        UInt64 Gpr25;
        UInt64 Gpr26;
        UInt64 Gpr27;
        UInt64 Gpr28;
        UInt64 Gpr29;
        UInt64 Gpr30;
        UInt64 Gpr31;
 
        uint Cr; // Condition register
        uint Xer; // Fixed point exception register
 
        //
        // This section is specified/returned if the ContextFlags word contains
        // the flag CONTEXT_FLOATING_POINT.
        //
 
        double Fpscr; // Floating point status/control reg
        double Fpr0; // Floating registers 0..31
        double Fpr1;
        double Fpr2;
        double Fpr3;
        double Fpr4;
        double Fpr5;
        double Fpr6;
        double Fpr7;
        double Fpr8;
        double Fpr9;
        double Fpr10;
        double Fpr11;
        double Fpr12;
        double Fpr13;
        double Fpr14;
        double Fpr15;
        double Fpr16;
        double Fpr17;
        double Fpr18;
        double Fpr19;
        double Fpr20;
        double Fpr21;
        double Fpr22;
        double Fpr23;
        double Fpr24;
        double Fpr25;
        double Fpr26;
        double Fpr27;
        double Fpr28;
        double Fpr29;
        double Fpr30;
        double Fpr31;
 
        uint UserModeControl; // User mode control state
        uint Fill;
 
        //
        // This section is specified/returned if the ContextFlags word contains
        // the flag CONTEXT_VECTOR.
        //
 
        fixed float Vscr[4]; // Vector status/control register
        fixed float Vr0[4]; // Vector registers 0..127
        fixed float Vr1[4];
        fixed float Vr2[4];
        fixed float Vr3[4];
        fixed float Vr4[4];
        fixed float Vr5[4];
        fixed float Vr6[4];
        fixed float Vr7[4];
        fixed float Vr8[4];
        fixed float Vr9[4];
        fixed float Vr10[4];
        fixed float Vr11[4];
        fixed float Vr12[4];
        fixed float Vr13[4];
        fixed float Vr14[4];
        fixed float Vr15[4];
        fixed float Vr16[4];
        fixed float Vr17[4];
        fixed float Vr18[4];
        fixed float Vr19[4];
        fixed float Vr20[4];
        fixed float Vr21[4];
        fixed float Vr22[4];
        fixed float Vr23[4];
        fixed float Vr24[4];
        fixed float Vr25[4];
        fixed float Vr26[4];
        fixed float Vr27[4];
        fixed float Vr28[4];
        fixed float Vr29[4];
        fixed float Vr30[4];
        fixed float Vr31[4];
        fixed float Vr32[4];
        fixed float Vr33[4];
        fixed float Vr34[4];
        fixed float Vr35[4];
        fixed float Vr36[4];
        fixed float Vr37[4];
        fixed float Vr38[4];
        fixed float Vr39[4];
        fixed float Vr40[4];
        fixed float Vr41[4];
        fixed float Vr42[4];
        fixed float Vr43[4];
        fixed float Vr44[4];
        fixed float Vr45[4];
        fixed float Vr46[4];
        fixed float Vr47[4];
        fixed float Vr48[4];
        fixed float Vr49[4];
        fixed float Vr50[4];
        fixed float Vr51[4];
        fixed float Vr52[4];
        fixed float Vr53[4];
        fixed float Vr54[4];
        fixed float Vr55[4];
        fixed float Vr56[4];
        fixed float Vr57[4];
        fixed float Vr58[4];
        fixed float Vr59[4];
        fixed float Vr60[4];
        fixed float Vr61[4];
        fixed float Vr62[4];
        fixed float Vr63[4];
        fixed float Vr64[4];
        fixed float Vr65[4];
        fixed float Vr66[4];
        fixed float Vr67[4];
        fixed float Vr68[4];
        fixed float Vr69[4];
        fixed float Vr70[4];
        fixed float Vr71[4];
        fixed float Vr72[4];
        fixed float Vr73[4];
        fixed float Vr74[4];
        fixed float Vr75[4];
        fixed float Vr76[4];
        fixed float Vr77[4];
        fixed float Vr78[4];
        fixed float Vr79[4];
        fixed float Vr80[4];
        fixed float Vr81[4];
        fixed float Vr82[4];
        fixed float Vr83[4];
        fixed float Vr84[4];
        fixed float Vr85[4];
        fixed float Vr86[4];
        fixed float Vr87[4];
        fixed float Vr88[4];
        fixed float Vr89[4];
        fixed float Vr90[4];
        fixed float Vr91[4];
        fixed float Vr92[4];
        fixed float Vr93[4];
        fixed float Vr94[4];
        fixed float Vr95[4];
        fixed float Vr96[4];
        fixed float Vr97[4];
        fixed float Vr98[4];
        fixed float Vr99[4];
        fixed float Vr100[4];
        fixed float Vr101[4];
        fixed float Vr102[4];
        fixed float Vr103[4];
        fixed float Vr104[4];
        fixed float Vr105[4];
        fixed float Vr106[4];
        fixed float Vr107[4];
        fixed float Vr108[4];
        fixed float Vr109[4];
        fixed float Vr110[4];
        fixed float Vr111[4];
        fixed float Vr112[4];
        fixed float Vr113[4];
        fixed float Vr114[4];
        fixed float Vr115[4];
        fixed float Vr116[4];
        fixed float Vr117[4];
        fixed float Vr118[4];
        fixed float Vr119[4];
        fixed float Vr120[4];
        fixed float Vr121[4];
        fixed float Vr122[4];
        fixed float Vr123[4];
        fixed float Vr124[4];
        fixed float Vr125[4];
        fixed float Vr126[4];
        fixed float Vr127[4];
    }
     
    [StructLayout(LayoutKind.Sequential)]
    public struct DM_MEMORY_STATISTICS
    {
        public uint StructureSize;
        public uint TotalPages;
        public uint AvailablePages;
        public uint StackPages;
        public uint VirtualPageTablePages;
        public uint SystemPageTablePages;
        public uint PoolPages;
        public uint VirtualMappedPages;
        public uint ImagePages;
        public uint FileCachePages;
        public uint ContiguousPages;
        public uint DebuggerPages;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct DM_SYSTEM_INFO
    {
        public int SizeOfStruct;
        public DM_VERSION_INFO BaseKernelVersion;
        public DM_VERSION_INFO KernelVersion;
        public DM_VERSION_INFO XDKVersion;
        public ulong SystemInfoFlags;
    }
     
     
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public unsafe struct DM_THREADINFOEX
    {
        public UInt32 Size;
        public UInt32 SuspendCount;
        public UInt32 Priority;
        public void * TlsBase;
        public void * StartAddress;
        public void * StackBase;
        public void * StackLimit;
        public _FILETIME CreateTime;
        public UInt32 StackSlackSpace;
        public string ThreadName;
        public UInt32 ThreadNameLength;
        public byte CurrentProcessor;
    }
 
    [StructLayout(LayoutKind.Explicit, CharSet=CharSet.Ansi)]
    public unsafe struct DM_FILE_ATTRIBUTES
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256), FieldOffset(0)]
        public string Name;
 
        [FieldOffset(256)]
        public _FILETIME CreationTime;
 
        [FieldOffset(264)]
        public _FILETIME ChangeTime;
 
        [FieldOffset(272)]
        public UInt32 SizeHigh;
 
        [FieldOffset(276)]
        public UInt32 SizeLow;
 
        [FieldOffset(280)]
        public UInt32 Attributes;
    }
     
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public unsafe struct DM_XBE
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
        public string Name;
  
        public uint TimeStamp;
 
        public uint CheckSum;
 
        public uint StackSize;
    }
     
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public unsafe struct DM_DUMP_SETTINGS
    {
        public uint ReportingFlags;
         
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
        public string NetworkPath;
    }
 
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public unsafe struct DM_USER
    {
        [MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
        public string UserName;
 
        public uint Access;
    }
 
 
    [Flags]
    public enum XboxButton : ushort
    {
        None = 0,
        DPadUp = 0x0001,
        DPadDown = 0x0002,
        DPadLeft = 0x0004,
        DPadRight = 0x0008,
        Start = 0x0010,
        Back = 0x0020,
        LeftThumb = 0x0040,
        RightThumb = 0x0080,
        LeftBumper = 0x100,
        RightBumper = 0x200,
        A = 0x1000,
        B = 0x2000,
        X = 0x4000,
        Y = 0x8000,
        XBox= 0x400,
        Bind = 0x800
    }
 
     
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public unsafe struct DM_XINPUT_GAMEPAD
    {
        [MarshalAs(UnmanagedType.U2)]
        public XboxButton Button;
         
        [MarshalAs(UnmanagedType.U1)]
        public byte RightTrigger;
 
        [MarshalAs(UnmanagedType.U1)]
        public byte LeftTrigger;
         
        [MarshalAs(UnmanagedType.I2)]
        public short LeftThumbstickX;
         
        [MarshalAs(UnmanagedType.I2)]
        public short LeftThumbstickY;
         
        [MarshalAs(UnmanagedType.I2)]
        public short RightThumbstickX;
         
        [MarshalAs(UnmanagedType.I2)]
        public short RightThumbstickY;
    }
     
    [StructLayout(LayoutKind.Explicit)]
    public struct _FILETIME
    {
        [FieldOffset(0)] public UInt32 dwLowDateTime;
        [FieldOffset(4)] public UInt32 dwHighDateTime;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DM_BREAK
    {
        public void * Address;
        public uint ThreadID;
    }
     
    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DM_DATABREAK
    {
        public void * Address;
        public uint ThreadID;
        public uint BreakType;
        public void * DataAddress;
    }
     
    [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DM_EXCEPTION
    {
        public uint ThreadID;
        public uint Code;
        public void * Address;
        public uint Flags;
        public fixed uint Information[2];
    }
 
/* [StructLayout(LayoutKind.Sequential)]
    public unsafe struct DM_DEBUGSTRING
    {
        public uint ThreadID;
        public uint Length;
        public string UserName;
    }*/
     
    [StructLayout(LayoutKind.Explicit)]
    public unsafe struct DM_ISTHREADSTOPPED
    {
        [FieldOffset(0)] public uint NotifiedReason;
        [FieldOffset(4)] public DM_BREAK Break;
        [FieldOffset(4)] public DM_DATABREAK DataBreak;
        [FieldOffset(4)] public DM_EXCEPTION Exception;
        // [FieldOffset(4)] public DM_DEBUGSTRING DebugString;
    }
     
    /// <summary>
    /// Summary description for XBDMXboxObject.
    /// </summary>
    public class XBDMXboxObject
    {
        [DllImport("xbdm")] private static extern UInt32 DmMkdir(string Dir);
        [DllImport("xbdm")] public static extern UInt32 DmSendFileA(string Src, string Dst);
        [DllImport("xbdm")] public static extern int DmReceiveFileA(string localName, string remoteName);
        [DllImport("xbdm")] public static extern int DmGetThreadContext(uint ThreadId, ref DM_CONTEXT context);
        [DllImport("xbdm")] public static extern int DmSetThreadContext(uint ThreadId, ref DM_CONTEXT context);
        [DllImport("xbdm")] public static extern UInt32 DmDeleteFile(string Src, bool IsDir);
        [DllImport("xbdm")] public static extern UInt32 DmSetXboxName(string Name);
        [DllImport("xbdm")] public static extern UInt32 DmSetXboxNameNoRegister(string Name);
        [DllImport("xbdm")] public static extern UInt32 DmReboot(UInt32 Flags);
        [DllImport("xbdm")] public static extern UInt32 DmGo();
        [DllImport("xbdm")] static extern int DmGetDriveList(StringBuilder driveList,
            out uint drivecount);
        [DllImport("xbdm")] public static extern int DmQueryAllocationTypeName(ushort allocationType,
            StringBuilder name,
            uint nameSize);
        [DllImport("xbdm")] public static extern unsafe int DmInsertAllocationEntry(void * AllocPtr,
            uint AllocSize,
            ushort AllocType);
        [DllImport("xbdm")] static extern int DmQueryTitleMemoryStatistics(ref DM_MEMORY_STATISTICS stats);
         
        public static DM_MEMORY_STATISTICS GetTitleMemoryStatistics() {
            DM_MEMORY_STATISTICS returnValue = new DM_MEMORY_STATISTICS();
            DmQueryTitleMemoryStatistics(ref returnValue);
            return returnValue;
        }
         
        [DllImport("xbdm")] public static extern unsafe int DmSetMemory(void * xboxAddress,
            uint BytesToCopy,
            void * localAddress,
            out uint BytesCopied);
         
         
        [DllImport("xbdm")] static extern int DmRegisterAllocationType(string name,
            ref ushort allocationType);
             
        [DllImport("xbdm")] public static extern int DmGetSystemInfo(out DM_SYSTEM_INFO SystemInfo);
        [DllImport("xbdm")] public static extern int DmGetXbeInfoEx(string path, ref DM_XBE xEX, uint flags);
        [DllImport("xbdm")] public static extern UInt32 DmScreenShot(string FileName);
        [DllImport("xbdm")] public static extern int DmAutomationSetGamepadState(UInt32 User,
                                                            ref DM_XINPUT_GAMEPAD xGamePad);
        [DllImport("xbdm")] public static extern int DmGetThreadInfoEx(UInt32 ThreadID,
                                                            ref DM_THREADINFOEX xGamePad);
 
        [DllImport("xbdm")] public static extern int DmQueryMemoryStatistics(ref DM_MEMORY_STATISTICS memoryStats);
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmGetDiskFreeSpace(string DriveName,
                                                          LARGE_INTEGER * pBytesAvailToCaller,
                                                          LARGE_INTEGER * pTotalBytes,
                                                          LARGE_INTEGER * pFreeBytes);
         
        [DllImport("xbdm")] private static extern unsafe UInt32 DmWalkDir( UInt32 ** ppWalkDir,
                                                                           string Dir,
                                                                           ref DM_FILE_ATTRIBUTES pDmFileAttrib);
 
        [DllImport("xbdm")] public static extern unsafe UInt32 DmGetFileAttributes( string Src,
                                                                                     ref DM_FILE_ATTRIBUTES pFileAttrib);
 
        [DllImport("xbdm")] public static extern unsafe UInt32 DmSetDumpSettings( ref DM_DUMP_SETTINGS settings);
         
        [DllImport("xbdm")] public static extern unsafe UInt32 DmGetDumpSettings( ref DM_DUMP_SETTINGS settings);
 
        [DllImport("xbdm")] public static extern unsafe UInt32 DmSetFileAttributes( string Src,
                                                                                     ref DM_FILE_ATTRIBUTES pFileAttrib);
 
        [DllImport("xbdm")] public static extern unsafe UInt32 DmSetFileSize( string filename,
                                                                                     uint offset,
                                                                                     uint createDisposition);
 
        [DllImport("xbdm")] public static extern unsafe UInt32 DmCloseDir(UInt32 * pWalkDir);
        [DllImport("xbdm")] public static extern unsafe int DmIsBreakpoint(void * address, ref uint type);
        [DllImport("xbdm")] public static extern unsafe int DmSetBreakpoint(void * address);
        [DllImport("xbdm")] public static extern unsafe int DmSetDataBreakpoint(void * address,
            uint type,
            uint size);
        [DllImport("xbdm")] public static extern unsafe int DmCaptureStackBackTrace(ulong FramesToCapture,
            void * BackTrace);
        [DllImport("xbdm")] public static extern unsafe int DmGetMemory(void * ConsoleAddress,
            uint BytesToCopy,
            void * PCAddress,
            ref uint BytesCopied);
        [DllImport("xbdm")] public static extern unsafe int DmGetMemoryChecksum(void * ConsoleAddress,
            uint BytesToCopy,
            uint BlockSize,
            void * PCAddress,
            ref uint BytesCopied);
        [DllImport("xbdm")] public static extern unsafe int DmSetInitialBreakpoint();
        [DllImport("xbdm")] public static extern unsafe int DmSetConnectionTimeout(uint ConnectTimeout, uint ConversationTimeout);
        [DllImport("xbdm")] public static extern unsafe int DmUseSharedConnection(bool share);
        [DllImport("xbdm")] private static extern unsafe UInt32 DmOpenConnection( ref void * pConnection );
        [DllImport("xbdm")] private static extern unsafe int DmOpenSecureConnection( ref void * pConnection, string password);
        [DllImport("xbdm")] private static extern unsafe UInt32 DmCloseConnection( void * pConnection );
        [DllImport("xbdm")] private static extern unsafe UInt32 DmDedicateConnection( void * pConnection, string HandlerPrefix );
 
        public delegate uint NotificationProcessor( string message );
        [DllImport("xbdm")] private static extern unsafe UInt32 DmOpenNotificationSession( UInt32 Flags, ref void* ppSession );
        [DllImport("xbdm")] private static extern unsafe UInt32 DmRegisterNotificationProcessor( void* pSession, string prefix, NotificationProcessor callbackFn );
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmSendCommand( void * pConnection,
                                                                               string Command,
                                                                               StringBuilder Response,
                                                                               ref UInt32 ResponseSize );
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmSendBinary( void * pConnection,
                                                                              void * pData,
                                                                              UInt32 Size );
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmReceiveStatusResponse( void * pConnection,
                                                                                         StringBuilder Response,
                                                                                         ref UInt32 ResponseSize );
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmReceiveSocketLine( void * pConnection,
                                                                                     StringBuilder Response,
                                                                                     ref UInt32 ResponseSize );
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmSetTitle( string Dir,
                                                                            string Title,
                                                                            string CmdLine );
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmGetNameOfXbox( StringBuilder Name,
                                                                                 ref UInt32 Size,
                                                                                 UInt32 Resolvable );
 
        [DllImport("xbdm")] private static extern unsafe UInt32 DmGetXboxName( StringBuilder Name,
                                                                               ref UInt32 Size );
 
        [DllImport("Kernel32.dll")] public static extern UInt32 LoadLibrary( string libName );
 
        enum XBDMERR
        {
            NOERR = 0,
            ALREADYEXISTS = 10,
            DIRNOTEMPTY = 11,
            ENDOFLIST = 0x104,
            READYFORBINARY = 0x02da0004,
            MULTIRESPONSE = 0x02da0002,
        }
 
        enum XBDMREBOOT
        {
            DMBOOT_WAIT = 1,
            DMBOOT_WARM = 2,
            DMBOOT_NODEBUG = 4,
            DMBOOT_STOP = 8
        }
 
        private string name;
        public static unsafe void * pConnection = null;
        public static bool ecpConnected = false;
        private static string debugConsoleCommandPrefix = "Twek!";
        private static string debugNotificationCommandPrefix = "TwkN";
 
        private static bool libLoaded = false;
 
        public XBDMXboxObject()
        {
            if( !libLoaded )
            {
                // Add the Xenon path so I can find the xbdm.dll
                string xedkDir = Environment.GetEnvironmentVariable( "xedk" );
 
                // Build up a new path using std::string to handle memory management.
                string newPath = xedkDir + "\\bin\\win32\\xbdm.dll";
 
                LoadLibrary( newPath );
            }
 
            name = "";
        }
 
        public XBDMXboxObject( string XboxName, bool Register )
        {
            if( !libLoaded )
            {
                // Add the Xenon path so I can find the xbdm.dll
                string xedkDir = Environment.GetEnvironmentVariable( "xedk" );
 
                // Build up a new path using std::string to handle memory management.
                string newPath = xedkDir + "\\bin\\win32\\xbdm.dll";
 
                LoadLibrary( newPath );
            }
 
            name = XboxName;
            UInt32 Result = 0;
 
            if (Register)
                Result = DmSetXboxName(name);
            else
                Result = DmSetXboxNameNoRegister(name);
 
            /*
            if( ! SUCCEEDED( Result ) )
                mainView.ErrorMessage( "Could not set Xbox Name", "Error" );
                */
        }
 
        public void LoadLib( string libraryFile )
        {
            LoadLibrary( libraryFile );
        }
 
        public unsafe bool Connect()
        {
            UInt32 Result;
         
            StringBuilder XboxName = new StringBuilder( 256, 1024 );
            UInt32 NameLength = 256;
 
            Result = DmGetNameOfXbox( XboxName, ref NameLength, 1 );
 
            // Open our connection
            Result = DmOpenConnection( ref pConnection );
            if( ! SUCCEEDED( Result ) )
                return false;
         
            // Send initial connect command to the External Command Processor so it knows we're here
            {
                UInt32 ResponseLen = 256;
                StringBuilder Response = new StringBuilder( 256, 1024 );
         
                Result = DmSendCommand( pConnection, debugConsoleCommandPrefix + "__connect__", Response, ref ResponseLen );
                if( ResponseLen != 0 )
                    Console.Write( "Xenon: " + Response + "\n" );
 
                if( ! SUCCEEDED( Result ) )
                    return false;
 
                ecpConnected = true;
            }
         
            return true;
        }
 
        public unsafe bool ConnectRaw()
        {
            if( pConnection != null )
                return true;
            UInt32 Result = DmOpenConnection( ref pConnection );
            return SUCCEEDED( Result );
        }
 
        public unsafe bool ConnectDedicated()
        {
            UInt32 Result = DmOpenConnection( ref pConnection );
            if( ! SUCCEEDED( Result ) )
                return false;
            Result = DmDedicateConnection( pConnection, debugConsoleCommandPrefix.Substring( 0, 4 ) );
            if( ! SUCCEEDED( Result ) )
                return false;
            return true;
        }
 
        public unsafe bool SendCommand( string command )
        {
            UInt32 ResponseLen = 256;
            StringBuilder Response = new StringBuilder( 256, 1024 );
         
            UInt32 Result = DmSendCommand( pConnection, debugConsoleCommandPrefix + command, Response, ref ResponseLen );
            if( ResponseLen != 0 )
                Console.Write( "Xenon: " + Response + "\n" );
 
            if( ! SUCCEEDED( Result ) )
                return false;
 
            return true;
        }
 
        public unsafe string SendCommandWithResponse( string command )
        {
            UInt32 ResponseLen = 256;
            StringBuilder Response = new StringBuilder( 256, 1024 );
         
            UInt32 Result = DmSendCommand( pConnection, debugConsoleCommandPrefix + command, Response, ref ResponseLen );
            return Response.ToString();
        }
 
        public unsafe string SendCommandWithMultilineResponse( string command )
        {
            UInt32 ResponseLen = 256;
            StringBuilder Response = new StringBuilder( 256, 1024 );
         
            UInt32 Result = DmSendCommand( pConnection, debugConsoleCommandPrefix + command, Response, ref ResponseLen );
            if( Result != (uint)XBDMERR.MULTIRESPONSE )
                return Response.ToString();
 
            string result = "";
            while( true )
            {
                ResponseLen = 256;
                Response = new StringBuilder( 256, 1024 );
                UInt32 cmdresult = DmReceiveSocketLine( pConnection, Response, ref ResponseLen );
                if( !SUCCEEDED( cmdresult ) )
                    break;
                string r = Response.ToString();
                if( r == "." )
                    break;
                result += r + "\n";
            }
            return "200-" + result;
        }
 
        public unsafe string SendBinaryWithResponse( string command, byte[] data )
        {
            UInt32 Result = 0;
            UInt32 ResponseLen = 256;
            StringBuilder Response = new StringBuilder( 256, 1024 );
            Result = DmSendCommand( pConnection, debugConsoleCommandPrefix + command + " " + data.Length , Response, ref ResponseLen );
            if( Result != (uint)XBDMERR.READYFORBINARY )
                return Response.ToString();
 
            fixed( byte* pBytes = data )
            {
                Result = DmSendBinary( pConnection, (void*)pBytes, (UInt32)data.Length );
                if( SUCCEEDED( Result ) )
                {
                    Result = DmReceiveStatusResponse( pConnection, Response, ref ResponseLen );
                }
            }
            return Response.ToString();
        }
 
        public unsafe bool Disconnect()
        {
            if( ecpConnected || ( pConnection != null ) )
            {
                DmCloseConnection( pConnection );
                pConnection = null;
                ecpConnected = false;
            }
 
            return true;
        }
 
        public bool MakeDir( string dir )
        {
            string strDelim = "\\";
            char[] Delim = strDelim.ToCharArray();
            string[] split = null;
 
            if( dir[ dir.Length - 1 ] != Path.DirectorySeparatorChar )
                dir += Path.DirectorySeparatorChar;
 
            split = dir.Split( Delim );
 
            for( short i = 1; i < split.Length - 1; i++ )
            {
                split[0] += strDelim + split[i];
                UInt32 result = DmMkdir( split[0] );
                if( !SUCCEEDED( result ) && ( ( result & 0xffff ) != (uint)XBDMERR.ALREADYEXISTS ) )
                    return false;
            }
 
            return true;
        }
 
        public bool CopyFile( string Src, string Dst, bool ForceOverwrite )
        {
            DM_FILE_ATTRIBUTES FileAttr = new DM_FILE_ATTRIBUTES();
            UInt32 Result = 0;
 
            if( ForceOverwrite )
            {
                Result = DmGetFileAttributes( Dst, ref FileAttr );
                FileAttr.Attributes = (uint)FileAttributes.Normal;
                Result = DmSetFileAttributes( Dst, ref FileAttr );
            }
 
            Result = DmSendFileA( Src, Dst );
            if( ! SUCCEEDED( Result ) )
            {
                // See if creating the dest directory helps
                string destPath = Dst.Substring( 0, Dst.LastIndexOf( Path.DirectorySeparatorChar ) );
                MakeDir( destPath );
                Result = DmSendFileA( Src, Dst );
                if( ! SUCCEEDED( Result ) )
                    return false;
            }
 
            return true;
        }
 
        public long GetFileTime( string filename )
        {
            DM_FILE_ATTRIBUTES FileAttr = new DM_FILE_ATTRIBUTES();
            UInt32 Result = DmGetFileAttributes( filename, ref FileAttr );
            if( !SUCCEEDED( Result ) )
                return 0;
            return (long)FileAttr.CreationTime.dwHighDateTime << 32 | (long)FileAttr.CreationTime.dwLowDateTime;
        }
 
        public short CopyDirectory( string Src, string Dest )
        {
            string[] Files;
            short FilesCopied = 0;
            UInt32 result = 0;
 
            string strDelim = "\\";
            char[] Delim = strDelim.ToCharArray();
            string[] split = null;
 
            if( Dest[ Dest.Length - 1 ] != Path.DirectorySeparatorChar )
                Dest += Path.DirectorySeparatorChar;
 
            split = Dest.Split( Delim );
 
            for( short i = 1; i < split.Length - 1; i++ )
            {
                split[0] += strDelim + split[i];
                result = DmMkdir( split[0] );
                if( !SUCCEEDED( result ) && ( ( result & 0xffff ) != (uint)XBDMERR.ALREADYEXISTS ) )
                    return 0;
            }
 
            Files = Directory.GetFileSystemEntries( Src );
 
            foreach( string entry in Files )
            {
                // recursive copy for sub-directories, or just copy the file
                if( Directory.Exists( entry ) )
                {
                    FilesCopied += CopyDirectory( entry, Dest + Path.GetFileName( entry ) );
                }
                else
                {
                    if( CopyFile( entry, Dest + Path.GetFileName( entry ), true ) )
                        FilesCopied++;
                    else
                        return 0;
                }
            }
 
            return FilesCopied;
        }
 
        public unsafe long GetDiskFreeSpace()
        {
            UInt32 result;
            LARGE_INTEGER x,y,z;
 
            x = new LARGE_INTEGER();
            y = new LARGE_INTEGER();
            z = new LARGE_INTEGER();
            
            result = DmGetDiskFreeSpace("xe:\\", &x, &y, &z);
 
            if ((result & 0xffff) == (UInt32)XBDMERR.NOERR)
                return (long)x.LowPart;
            else
                return -1;
        }
 
        public void DeleteDirectory(string Src)
        {
            UInt32 result = 0;
 
            // todo: finish
            result = DmDeleteFile(Src, true);
        }
 
        public string Name
        {
            get
            {
                return name;
            }
            set
            {
                name = value;
                DmSetXboxNameNoRegister(name);
            }
        }
 
        public unsafe UInt32 GetDirSize(string Dir)
        {
            UInt32 DirSize = 0xffffffff;
            UInt32 * pWalkDir = null;
            DM_FILE_ATTRIBUTES FileAttr;
 
            FileAttr = new DM_FILE_ATTRIBUTES();
            if (!Dir.EndsWith("\\"))
                Dir += "\\";
 
            while (SUCCEEDED(DmWalkDir(&pWalkDir, Dir, ref FileAttr)))
            {
                if (FileAttr.Attributes == (UInt32)FileAttributes.Directory)
                    DirSize += GetDirSize(Dir + FileAttr.Name + "\\" );
                else if (FileAttr.Attributes == 0)//(UInt32)FileAttributes.Normal)
                    DirSize += FileAttr.SizeLow;
            }
 
            DmCloseDir(pWalkDir);
            return DirSize;
        }
      
        public unsafe bool DirExists( string Dir )
        {
            UInt32 * pWalkDir = null;
            DM_FILE_ATTRIBUTES FileAttr;
 
            FileAttr = new DM_FILE_ATTRIBUTES();
            if( ! Dir.EndsWith( "\\" ) )
                Dir += "\\";
 
            UInt32 result = DmWalkDir( &pWalkDir, Dir, ref FileAttr);
            if( (result & 0xffff) == (UInt32)XBDMERR.NOERR ||
                (result & 0xffff) == (UInt32)XBDMERR.ENDOFLIST )
            {
                DmCloseDir( pWalkDir );
                return true;
            }
 
            DmCloseDir( pWalkDir );
            return false;
        }
 
        public string GetXboxName()
        {
            StringBuilder XboxName = new StringBuilder( 256, 1024 );
            UInt32 NameLength = 256;
 
            if( !SUCCEEDED( DmGetXboxName( XboxName, ref NameLength ) ) )
                return "";
 
            return XboxName.ToString();
        }
 
        public void Reboot()
        {
            DmReboot(2);
        }
 
        public void Capture(string FileName)
        {
            DmScreenShot(FileName);
        }
 
        public bool RunTitle( string dir, string filename, string cmdLine )
        {
            UInt32 Result = DmReboot( (uint)XBDMREBOOT.DMBOOT_STOP | (uint)XBDMREBOOT.DMBOOT_WARM );
            if( ! SUCCEEDED( Result ) )
                return false;
 
            Result = DmSetTitle( dir, filename, cmdLine );
            if( ! SUCCEEDED( Result ) )
                return false;
 
            DmGo();
            return true;
        }
 
        public unsafe void RegisterNotificationProcessor( NotificationProcessor del )
        {
            void* pSession = null;
            UInt32 Result = DmOpenNotificationSession( 0, ref pSession );
            if( !SUCCEEDED( Result ) )
                return;
            Result = DmRegisterNotificationProcessor( pSession, debugNotificationCommandPrefix, del );
            if( !SUCCEEDED( Result ) )
                return;
        }
 
        public bool SUCCEEDED(UInt32 ReturnCode)
        {
            if ((ReturnCode & 0xffff) == (UInt32)XBDMERR.NOERR)
                return true;
            else
                return false;
        }
    }
}
'@