ALERT!
Click here to register with a few steps and explore all our cool stuff we have to offer!
Home
Upgrade
Credits
Help
Search
Awards
Achievements
 9574

XBDM source code, PART ONE no header file unfortunately

by quadrant2005 - 05-01-2020 - 03:22 AM
#1
As the title reads this is the source code of XBDM.XEX that everyone makes use of to use there mods, unfortunately its missing the header file but could be used as a primer by someone so wanted to share this...

Code:
/*
Copyright (c) 2013 Nathan LeRoux

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.
*/

#include "dmincludes.h"

DMCONN rgdmc[CONNECTION_MAX];
SOCKET sockServ, sockName;

const char rgchHex[] = "0123456789ABCDEF";
char *rgszDumpMode[] = { "smart", "enabled", "disabled" };

/* BEGIN MICROSOFT CODE */

int SgnCompareRgch(const char *sz1, const char *sz2, int cch)
{
    while(cch-- && *sz1) {
        char ch1 = *sz1++;
        char ch2 = *sz2++;
        if(ch1 >= 'a' && ch2 <= 'z')
            ch1 -= 32;
        if(ch2 >= 'a' && ch2 <= 'z')
            ch2 -= 32;
        if(ch1 != ch2)
            return ch1 - ch2;
    }
    if(*sz1)
        return *sz1;
    return cch < 0 ? 0 : -*sz2;
}

BOOL FEqualRgch(const char *sz1, const char *sz2, int cch)
{
    return SgnCompareRgch(sz1, sz2, cch) == 0;
}

DWORD DwHexFromSz(LPCSTR sz, LPCSTR *szOut)
{
    DWORD dw = 0;

    for(;;) {
        if(*sz >= '0' && *sz <= '9')
            dw = dw * 16 + (*sz - '0');
        else if(*sz >= 'A' && *sz <= 'F')
            dw = dw * 16 + (*sz - 'A' + 10);
        else if(*sz >= 'a' && *sz <= 'f')
            dw = dw * 16 + (*sz - 'a' + 10);
        else
            break;
        ++sz;
    }
    if(szOut)
        *szOut = sz;
    return dw;
}

DWORD DwFromSz(LPCSTR sz, int *pcchUsed)
{
    DWORD dw = 0;
    LPCSTR szStart = sz;

    /* Process decimal, octal, or hex */
    if(*sz == '0') {
        ++sz;
        if(*sz == 'x')
            dw = DwHexFromSz(++sz, &sz);
        else
            while(*sz >= '0' && *sz <= '7')
                dw = dw * 8 + (*sz++ - '0');
    } else
        while(*sz >= '0' && *sz <= '9')
            dw = dw * 10 + (*sz++ - '0');
    if(pcchUsed)
        *pcchUsed = sz - szStart;
    return dw;
}

__inline BOOL FIsSpace(char ch)
{
    return ch == ' ' || ch == '\015' || ch == 0;
}

const char *PchGetParam(LPCSTR szCmd, LPCSTR szKey, BOOL fNeedValue)
{
    const char *pchTok;
    int cchTok;
    BOOL fQuote = FALSE;

    /* Skip the command */
    for(pchTok = szCmd; !FIsSpace(*pchTok); ++pchTok);

    while(*pchTok) {
        /* Skip leading spaces */
        while(*pchTok && FIsSpace(*pchTok))
            ++pchTok;
        if(!*pchTok)
            return NULL;
        for(cchTok = 0; !FIsSpace(pchTok[cchTok]); ++cchTok) {
            if(pchTok[cchTok] == '=') {
                if(FEqualRgch(szKey, pchTok, cchTok))
                    return pchTok + cchTok + 1; /* Skip the '=' */
                break;
            }
        }
        /* If we didn't see the '=' we need to check anyway */
        if(!fNeedValue && pchTok[cchTok] != '=' && FEqualRgch(szKey, pchTok,
                cchTok))
            return pchTok + cchTok;
        /* No match, so we need to skip past the value */
        pchTok += cchTok;
        while(*pchTok && (!FIsSpace(*pchTok) || fQuote))
            if(*pchTok++ == '"')
                fQuote = !fQuote;
    }
    return NULL;
}

void GetParam(LPCSTR szLine, LPSTR szBuf, int cchBuf)
{
    int cch = 0;
    BOOL fQuote = FALSE;

    while(cch < cchBuf-1 && *szLine && (!FIsSpace(*szLine) || fQuote)) {
        if(*szLine == '"') {
            if(fQuote && szLine[1] == '"') {
                /* Double quote inside a string gets copied as a single
                * quote */
                szBuf[cch++] = '"';
                szLine += 2;
            } else {
                fQuote = !fQuote;
                ++szLine;
            }
        } else
            szBuf[cch++] = *szLine++;
    }
    szBuf[cch] = 0;
}

BOOL FGetSzParam(LPCSTR szLine, LPCSTR szKey, LPSTR szBuf, int cchBuf)
{
    LPCSTR pch = PchGetParam(szLine, szKey, TRUE);
    if(!pch)
        return FALSE;
    GetParam(pch, szBuf, cchBuf);
    return TRUE;
}

BOOL FGetDwParam(LPCSTR szLine, LPCSTR szKey, DWORD *pdw)
{
    int cch;
    char sz[32];
    LPCSTR pch = PchGetParam(szLine, szKey, TRUE);
    if(!pch)
        return FALSE;
    GetParam(pch, sz, sizeof sz);
    *pdw = DwFromSz(sz, &cch);
    return FIsSpace(sz[cch]);
}

/* END MICROSOFT CODE */

BOOL FGetVectorParam(LPCSTR szLine, LPCSTR szKey, float *pvr)
{
char sz[63];
int j = 0, i;

LPCSTR pch = PchGetParam(szLine, szKey, TRUE);
if(!pch)
return FALSE;
GetParam(pch, sz, sizeof sz);

for(i = 0;i < 4;i++)
{
((DWORD*)pvr)[i] = DwFromSz(sz + j, NULL);

do{ j++; } while(sz[j] != ',');

if(i < 3 && (sz[j] != ',') && !FIsSpace(sz[j]))
return FALSE;

j++;
}

return TRUE;
}

BOOL FGetQwordParam(LPCSTR szLine, LPCSTR szKey, ULARGE_INTEGER *plu)
{
    int cch;
    char sz[32];
    LPCSTR pch;

    pch = PchGetParam(szLine, szKey, TRUE);
    if(!pch)
        return FALSE;
    GetParam(pch, sz, sizeof sz - 1);
    sz[sizeof sz - 1] = 0;

    /* Verify the 0q prefix */
    if(sz[0] != '0' || sz[1] != 'q')
        return FALSE;
    /* Make sure we have a bunch of hex characters */
    for(cch = 2; cch < sizeof sz && !FIsSpace(sz[cch]); ++cch) {
        if(!(sz[cch] >= '0' && sz[cch] <= '9' ||
                sz[cch] >= 'A' && sz[cch] <= 'F' ||
                sz[cch] >= 'a' && sz[cch] <= 'f'))
            return FALSE;
    }
    cch -= 2;
    if(cch <= 0)
        return FALSE;

    /* Move the text out to the end of the string and fill the preceding
    * characters with zeroes */
    memmove(&sz[sizeof sz - 1 - cch], &sz[2], cch);
    memset(sz, '0', sizeof sz - 1 - cch);

    /* Now parse out the two dwords */
    plu->LowPart = DwHexFromSz(&sz[sizeof sz - 9], NULL);
    sz[sizeof sz - 9] = 0;
    plu->HighPart = DwHexFromSz(&sz[sizeof sz - 17], NULL);
    return TRUE;
}

BOOL FGetNamedDwParam(LPCSTR szLine, LPCSTR szKey, DWORD *pdw, LPSTR szResp)
{
    if(!FGetDwParam(szLine, szKey, pdw)) {
        RtlSprintf(szResp, "missing %s", szKey);
        return FALSE;
    }
    return TRUE;
}

ULONG UlAddrFromSz(LPCSTR sz)
{
    ULONG ul;
    int ib;
    int ich;

    for(ib = 0; ib < 4; ++ib) {
        BYTE b = 0;

        for(ich = 0; ich < 3; ++ich) {
            if(sz[ich] < '0' || sz[ich] > '9')
                break;
            b = 10 * b + (sz[ich] - '0');
        }
        if(ich == 0 || sz[ich] != (ib == 3 ? 0 : '.'))
            return 0;
        sz += ich + 1;
        ((BYTE *)&ul)[ib ^ 3] = b;
    }
    return ul;
}

void GetFileAttrSz(LPSTR sz, ULONG dwAttributes, PLARGE_INTEGER pliChange,
    PLARGE_INTEGER pliCreate, PLARGE_INTEGER pliSize)
{
    RtlSprintf(sz, "sizehi=0x%x sizelo=0x%x createhi=0x%08x createlo=0x%08x "
        "changehi=0x%08x changelo=0x%08x%s%s%s", pliSize->HighPart,
        pliSize->LowPart, pliCreate->HighPart, pliCreate->LowPart,
        pliChange->HighPart, pliChange->LowPart,
        dwAttributes & FILE_ATTRIBUTE_DIRECTORY ? " directory" : "",
        dwAttributes & FILE_ATTRIBUTE_READONLY ? " readonly" : "",
        dwAttributes & FILE_ATTRIBUTE_HIDDEN ? " hidden" : "");
}

VOID FStopServ()
{
int i;

closesocket(sockServ);
closesocket(sockName);

for(i = 0;i < CONNECTION_MAX;i++)
if(rgdmc[i].bActive)
closesocket(rgdmc[i].s);
}

int FSend(SOCKET s, LPCSTR fmt, ...)
{
char buf[0x200];

va_list list;
va_start(list, fmt);
RtlVsnprintf(buf, sizeof(buf), fmt, list);
va_end(list);

return send(s, buf, strlen(buf), 0);
}

int FSendLine(SOCKET s, LPCSTR fmt, ...)
{
char buf[0x202];
int i;

va_list list;
va_start(list, fmt);
i = RtlVsnprintf(buf, sizeof(buf) - 2, fmt, list);
va_end(list);

strcat(buf, "\r\n");

return send(s, buf, i + 2, 0);
}

LPCSTR SzStdResponse(HRESULT hr)
{
    LPCSTR pszResp;

    switch(hr) {
case XBDM_LINE_TOO_LONG:
pszResp = "line too long";
break;
    case XBDM_NOSUCHFILE:
        pszResp = "file not found";
        break;
    case XBDM_NOMODULE:
        pszResp = "no such module";
        break;
    case XBDM_MEMUNMAPPED:
        pszResp = "memory not mapped";
        break;
    case XBDM_NOTHREAD:
        pszResp = "no such thread";
        break;
    case XBDM_INVALIDCMD:
        pszResp = "unknown command";
        break;
    case XBDM_NOTSTOPPED:
        pszResp = "not stopped";
        break;
case XBDM_ALREADYSTOPPED:
pszResp = "already stopped";
break;
    case XBDM_MUSTCOPY:
        pszResp = "file must be copied";
        break;
    case XBDM_ALREADYEXISTS:
        pszResp = "file already exists";
        break;
    case XBDM_DIRNOTEMPTY:
        pszResp = "directory not empty";
        break;
    case XBDM_BADFILENAME:
        pszResp = "filename is invalid";
        break;
    case XBDM_CANNOTCREATE:
        pszResp = "file cannot be created";
        break;
    case XBDM_DEVICEFULL:
        pszResp = "no room on device";
        break;
    case XBDM_MULTIRESPONSE:
        pszResp = "multiline response follows";
        break;
    case XBDM_BINRESPONSE:
        pszResp = "binary response follows";
        break;
    case XBDM_READYFORBIN:
        pszResp = "send binary data";
        break;
    case XBDM_CANNOTACCESS:
        pszResp = "access denied";
        break;
    case XBDM_NOTDEBUGGABLE:
        pszResp = "not debuggable";
        break;
    case XBDM_BADCOUNTTYPE:
        pszResp = "type invalid";
        break;
    case XBDM_COUNTUNAVAILABLE:
        pszResp = "data not available";
        break;
    case XBDM_NOTLOCKED:
        pszResp = "box is not locked";
        break;
    case XBDM_KEYXCHG:
        pszResp = "key exchange required";
        break;
    case XBDM_MUSTBEDEDICATED:
        pszResp = "dedicated connection required";
        break;
    case E_OUTOFMEMORY:
        pszResp = "out of memory";
        break;
    case E_UNEXPECTED:
        pszResp = "unexpected error";
        break;
    case E_INVALIDARG:
        pszResp = "bad parameter";
        break;
    case XBDM_NOERR:
        pszResp = "OK";
        break;
    default:
        pszResp = "";
        break;
    }
    return pszResp;
}

int SendHrSzResp(SOCKET s, HRESULT hr, LPCSTR szResp, LPSTR szBuf)
{
    /* Make sure we have an error code we like */
    if(((hr >> 16) & 0x7fff) != FACILITY_XBDM) {
        hr = SUCCEEDED(hr) ? XBDM_NOERR : XBDM_UNDEFINED;
        if(!szResp)
            szResp = SzStdResponse(E_UNEXPECTED);
    } else if((hr & 0xffff) > 0xff)
        hr = XBDM_UNDEFINED;

    if(FAILED(hr))
        szBuf[0] = '4';
    else
        szBuf[0] = '2';
    szBuf[1] = (char) ('0' + (hr & 0xffff) / 10);  // overflow?
    szBuf[2] = (char) ('0' + (hr & 0xffff) % 10);
    szBuf[3] = '-';
    szBuf[4] = ' ';
    if(szResp != szBuf) {
        if(szResp)
            strcpy(szBuf + 5, szResp);
        else
            szBuf[5] = 0;
    }
    return FSendLine(s, "%s", szBuf);
}

VOID DoReadWrite(PDMCONN pdmc, BOOL bCanRead)
{
int i, j;
DWORD dw;
char sz[0x200];
char resp[0x200];
HRESULT hr;

if(!pdmc->bConversation)
{
// We are not currently in a handling function

// Check for shutdown
if(pdmc->bShutdown)
{
if(!pdmc->bKeepAlive)
closesocket(pdmc->s);

ZeroMemory(pdmc, sizeof(DMCONN));

return;
}

// First, scan the buffer to search for newlines
for(dw = 0;dw < pdmc->dwRecv && (pdmc->szRecv[dw] != '\n');dw++);

// If i == pdmc->dwRecv then there are no commands in the buffer
if(dw == pdmc->dwRecv)
{
// Recieve into the buffer
if(bCanRead)
{
i = recv(pdmc->s, (char*)pdmc->szRecv + pdmc->dwRecv, sizeof(pdmc->szRecv) - pdmc->dwRecv, 0);
if(i <= 0)
{
pdmc->bShutdown = TRUE;
return;
}

pdmc->dwRecv += i;
}
}

// Scan the buffer for a newline
for(dw = 0;dw < pdmc->dwRecv && (pdmc->szRecv[dw] != '\n');dw++);

if(dw != pdmc->dwRecv)
{
// We found a command
if(pdmc->bTooLong)
{
SendHrSzResp(pdmc->s, XBDM_LINE_TOO_LONG, "", sz);
pdmc->bTooLong = FALSE;
pdmc->dwRecv = 0;

return;
}

// Find the command name
for(i = 0;(pdmc->szRecv[i]) && (pdmc->szRecv[i] != '\r') && (pdmc->szRecv[i] != '\n') && (pdmc->szRecv[i] != ' ');i++)
sz[i] = pdmc->szRecv[i];
sz[i] = 0;

// Now we just walk the list with our super inefficient algo of BRUTE FORCE SEARCHING
for(j = 0;j < cchcmd && stricmp(sz, rgbcmd[j].szName);j++);

if(j == cchcmd) // Command not found
{
SendHrSzResp(pdmc->s, XBDM_INVALIDCMD, SzStdResponse(XBDM_INVALIDCMD), sz);

memcpy(sz, pdmc->szRecv, dw - 1);
sz[dw - 1] = 0;

DbgPrint("[xbdm] unknown command \"%s\"\n", sz);
}
else if((rgbcmd[j].dwPriv & pdmc->dwPriv) != rgbcmd[j].dwPriv)
{
// Not enough permissions
SendHrSzResp(pdmc->s, XBDM_CANNOTACCESS, SzStdResponse(XBDM_CANNOTACCESS), sz);
}
else
{
// Command foundzorz

// Copy the whole string over
for(i = 0;(pdmc->szRecv[i] != '\r') && (pdmc->szRecv[i] != '\n');i++)
sz[i] = pdmc->szRecv[i];

sz[i] = 0;
resp[0] = 0;

// Setup some final state information
pdmc->dmcc.Buffer = NULL;
pdmc->dmcc.BufferSize = 0;
pdmc->dmcc.BytesRemaining = 0;
pdmc->dmcc.CustomData = &pdmc->dmcd;
pdmc->dmcc.DataSize = -1;
pdmc->dmcc.HandlingFunction = NULL;

pdmc->hr = hr = rgbcmd[j].pdmcp(sz, resp, sizeof(resp), &pdmc->dmcc);

if(hr == XBDM_MULTIRESPONSE
|| hr == XBDM_BINRESPONSE
|| hr == XBDM_READYFORBIN)
pdmc->bConversation = TRUE;

if(!pdmc->bKeepAlive)
{
if(resp[0])
{
if(SendHrSzResp(pdmc->s, hr, resp, sz) <= 0)
pdmc->bShutdown = TRUE;
}
else if(SendHrSzResp(pdmc->s, hr, SzStdResponse(hr), sz) <= 0)
pdmc->bShutdown = TRUE;
}
}

// Fetch the index of the \n
for(i = 0;pdmc->szRecv[i] != '\n';i++);

// Move the memory
memmove(pdmc->szRecv, pdmc->szRecv + (i + 1), sizeof(pdmc->szRecv) - (i + 1));

// Adjust the vars
pdmc->dwRecv -= i + 1;
}
else if(pdmc->dwRecv == sizeof(pdmc->szRecv))
pdmc->bTooLong = TRUE; // Overflow....

// On overflow, just ignore the rest of the data until newline
if(pdmc->bTooLong)
pdmc->dwRecv = 0;
}
else
{
// We are currently in a handling function

ASSERT(pdmc->dmcc.HandlingFunction);

if(pdmc->dmcc.Buffer == NULL)
{
pdmc->dmcc.Buffer = pdmc->szBuf;
pdmc->dmcc.BufferSize = sizeof(pdmc->szBuf);
}

// Check for shutdown
if(pdmc->bShutdown)
{
if(pdmc->hr == XBDM_READYFORBIN)
{
// Multiline responses are free to continue, but they wont go anywhere
pdmc->dmcc.DataSize = 0;
pdmc->bConversation = FALSE;
}
}

if(pdmc->hr == XBDM_READYFORBIN)
{
if(bCanRead)
{
if(!pdmc->bShutdown)
{
i = recv(pdmc->s, (char*)pdmc->dmcc.Buffer,
pdmc->dmcc.BytesRemaining > pdmc->dmcc.BufferSize ? pdmc->dmcc.BufferSize : pdmc->dmcc.BytesRemaining,
0);

if(i <= 0)
{
pdmc->dmcc.DataSize = 0;
pdmc->bShutdown = TRUE;
}
else
pdmc->dmcc.DataSize = i;
}

hr = pdmc->dmcc.HandlingFunction(&pdmc->dmcc, resp, sizeof(resp));

if(!pdmc->bShutdown)
{
if(pdmc->dmcc.BytesRemaining == 0)
{
if(hr == XBDM_MULTIRESPONSE
|| hr == XBDM_BINRESPONSE
|| hr == XBDM_READYFORBIN)
{
pdmc->hr = hr;
pdmc->bConversation = TRUE;
pdmc->dmcc.DataSize = 0;
}
else
{
pdmc->bConversation = FALSE;
pdmc->dmcc.HandlingFunction = NULL;
}

SendHrSzResp(pdmc->s, hr, SzStdResponse(hr), sz);
}
}

if(pdmc->bShutdown)
pdmc->bConversation = FALSE;
}
}
else
{
if(pdmc->bShutdown || pdmc->dmcc.DataSize == 0 || pdmc->dmcc.DataSize == -1)
{
// Multiline/binary
pdmc->dmcc.DataSize = -1;
#ifdef _DEBUG
hr = pdmc->dmcc.HandlingFunction(&pdmc->dmcc, NULL, 0x100); // This way i can catch those annoying errors
#else
hr = pdmc->dmcc.HandlingFunction(&pdmc->dmcc, NULL, 0);
#endif

pdmc->Buffer = pdmc->dmcc.Buffer;
}

if(pdmc->bShutdown)
{
if(FAILED(hr)
|| hr == XBDM_MULTIRESPONSE
|| hr == XBDM_BINRESPONSE
|| hr == XBDM_READYFORBIN) // Just let them keep talking
pdmc->bConversation = FALSE;
}
else
{
if(hr == XBDM_ENDOFLIST
|| hr == XBDM_MULTIRESPONSE
|| hr == XBDM_BINRESPONSE
|| hr == XBDM_READYFORBIN)
{
if(pdmc->hr == XBDM_MULTIRESPONSE)
FSend(pdmc->s, ".\r\n");

pdmc->bConversation = FALSE;

if(hr == XBDM_MULTIRESPONSE
|| hr == XBDM_BINRESPONSE
|| hr == XBDM_READYFORBIN)
{
pdmc->hr = hr;
pdmc->bConversation = TRUE;
}
else
pdmc->dmcc.HandlingFunction = NULL;
}
else if(NT_SUCCESS(hr))
{
if(pdmc->dmcc.DataSize == -1)
{
// Null terminated string with a newline
if(FSend(pdmc->s, "%s\r\n", pdmc->dmcc.Buffer) <= 0)
pdmc->bShutdown = TRUE;
}
else if(pdmc->dmcc.DataSize != 0)
{
// Binary data
if((i = send(pdmc->s, (char*)pdmc->Buffer, pdmc->dmcc.DataSize, 0)) <= 0)
pdmc->bShutdown = TRUE;

pdmc->dmcc.DataSize -= i;
pdmc->Buffer = (PVOID)((DWORD)pdmc->Buffer + i);
}
}
else
{
if(pdmc->dmcc.DataSize == -1)
FSend(pdmc->s, "%s\r\n", pdmc->dmcc.Buffer);

// Forcefully terminate the connection
pdmc->bShutdown = TRUE;
pdmc->bConversation = FALSE;
}
}
}
}
}

VOID AnswerName(SOCKET s)
{
struct {
BYTE bRequest;
BYTE cchName;
char szName[256];
} nm;

SOCKADDR_IN sin;
int cbAddr = sizeof(sin);
int cbPkt;

cbPkt = recvfrom(s, (char*)&nm, sizeof(nm), 0, (SOCKADDR*)&sin, &cbAddr);
switch(nm.bRequest)
{
case 1:
case 3:
if(nm.bRequest == 1)
{
nm.bRequest = 0;

if(cbPkt < 2 || cbPkt < (2 + nm.cchName))
break;

if(!nm.cchName || strcmpi(nm.szName, g_dmGlobals.rgchDbgName))
break;
}

nm.bRequest = 2;
break;
default:
nm.bRequest = 0;
break;
}

if(nm.bRequest)
sendto(s, (char*)&nm, cbPkt, 0, (SOCKADDR*)&sin, cbAddr);
}

ULONG __stdcall ServerThread(LPVOID lpParam)
{
SOCKET sock;
BOOL bReuse;
SOCKADDR_IN sin;
FD_SET readfds, writefds;
struct timeval timeout;
XNADDR xna;
DMTD *pdmtd;
int i;

KeSetBasePriorityThread(PsGetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
pdmtd = DmGetCurrentDmtd();

pdmtd->DebugFlags |= DMFLAG_DEBUGTHREAD;

VSetThreadName(-1, "Debugger Command Thread");

ZeroMemory(rgdmc, sizeof(rgdmc));

do
{
// Well, this IS the server thread, so if we can't start a server then screw you
Sleep(5000);
sockServ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
} while(sockServ == INVALID_SOCKET);

bReuse = TRUE;
if(setsockopt(sockServ, SOL_SOCKET, SO_DECRYPTSOCK, (char*)&bReuse, sizeof(bReuse)))
{
DbgPrint("[xbdm] failed %i\n", WSAGetLastError());
DebugBreak();
}
if(setsockopt(sockServ, SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(bReuse)))
{
DbgPrint("[xbdm] failed %i\n", WSAGetLastError());
DebugBreak();
}

sin.sin_family = AF_INET;
sin.sin_port = 730;
sin.sin_addr.s_addr = INADDR_ANY;
if(bind(sockServ, (SOCKADDR*)&sin, sizeof(sin))
|| listen(sockServ, 8))
{
DbgPrint("[xbdm] failed %i\n", WSAGetLastError());
DebugBreak();
goto abortsocket;
}

sockName = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(setsockopt(sockName, SOL_SOCKET, SO_DECRYPTSOCK, (char*)&bReuse, sizeof(bReuse)))
{
DbgPrint("[xbdm] failed %i\n", WSAGetLastError());
DebugBreak();
}
if(setsockopt(sockName, SOL_SOCKET, SO_REUSEADDR, (char*)&bReuse, sizeof(bReuse)))
{
DbgPrint("[xbdm] failed %i\n", WSAGetLastError());
DebugBreak();
}
if(setsockopt(sockName, SOL_SOCKET, SO_BROADCAST, (char*)&bReuse, sizeof(bReuse)))
{
DbgPrint("[xbdm] failed %i\n", WSAGetLastError());
DebugBreak();
}
if(bind(sockName, (SOCKADDR*)&sin, sizeof(sin)))
{
DbgPrint("[xbdm] failed %i\n", WSAGetLastError());
DebugBreak();
}

DbgPrint("[xbdm] server started\n");

for(;;)
{
readfds.fd_count = 0;
writefds.fd_count = 0;

FD_SET(sockServ, &readfds);
FD_SET(sockName, &readfds);

for(i = 0;i < CONNECTION_MAX;i++)
{
if(rgdmc[i].bActive)
FD_SET(rgdmc[i].s, &readfds);
}

timeout.tv_sec = 0;
timeout.tv_usec = 0;

if(g_dmGlobals.bDirty)
{
FWriteGlobals();

g_dmGlobals.bDirty = FALSE;
}

if(!g_dmGlobals.bHasIp)
{
i = XNetGetTitleXnAddr(&xna);
if(i != XNET_GET_XNADDR_PENDING)
{
DbgPrint("[xbdm] IP Address Acquired [%i.%i.%i.%i] (0x%08x)\n",
xna.ina.S_un.S_un_b.s_b1, xna.ina.S_un.S_un_b.s_b2,
xna.ina.S_un.S_un_b.s_b3, xna.ina.S_un.S_un_b.s_b4,
i);

g_dmGlobals.bHasIp = TRUE;
}
}

// Yield to others (its the right thing to do)
Sleep(0);

ProcessQueuedNotifications();

select(0, &readfds, &writefds, NULL, &timeout);

if(FD_ISSET(sockName, &readfds))
AnswerName(sockName);

if(FD_ISSET(sockServ, &readfds))
{
i = sizeof(sin);
sock = accept(sockServ, (SOCKADDR*)&sin, &i);

for(i = 0;i < CONNECTION_MAX;i++)
{
if(!rgdmc[i].bActive)
{
rgdmc[i].bActive = TRUE;
rgdmc[i].s = sock;
memcpy(&rgdmc[i].sin, &sin, sizeof(sin));
break;
}
}

if(i == CONNECTION_MAX)
{
// No more connection slots
FSendLine(sock, "401- max number of connections exceeded");
closesocket(sock);
}
else
{
// Some quick init

// Give all permssions, as we dont have locking yet
rgdmc[i].dwPriv = DMPL_PRIV_READ | DMPL_PRIV_WRITE | DMPL_PRIV_CONFIGURE | DMPL_PRIV_CONTROL;

// Only give hypervisor access if its enabled
if(g_dmGlobals.bHypervisorEnabled)
rgdmc[i].dwPriv |= DMPL_PRIV_HVX_MASK;

// Say hello!
FSendLine(rgdmc[i].s, "201- connected");
}
}

for(i = 0;i < CONNECTION_MAX;i++)
{
if(rgdmc[i].bActive)
DoReadWrite(&rgdmc[i], FD_ISSET(rgdmc[i].s, &readfds));
}
}

abortsocket:
closesocket(sockServ);

DebugBreak();
return 0;
}

DMHRAPI HrGetAltAddr(LPCSTR szCommand, LPSTR szResponse,
    DWORD cchResponse, PDM_CMDCONT pdmcc)
{
XNADDR xna;
DWORD dw;

if(!pdmcc)
return E_FAIL;

dw = XNetGetTitleXnAddr(&xna);

if(dw == XNET_GET_XNADDR_PENDING || dw == XNET_GET_XNADDR_NONE)
return E_FAIL;

RtlSnprintf(szResponse, cchResponse, "addr=0x%08x", xna.ina.s_addr);

return XBDM_NOERR;
}

DMHRAPI HrEndConversation(LPCSTR szCommand, LPSTR szResponse,
    DWORD cchResponse, PDM_CMDCONT pdmcc)
{
PDMCONN pdmc;

if(!pdmcc)
return E_FAIL;

// Snag the structure
pdmc = CONTAINING_RECORD(pdmcc, DMCONN, dmcc);

// Say goodbye
strcpy(szResponse, "bye");

// Signal shutdown
pdmc->bShutdown = TRUE;

return XBDM_NOERR;
}

DMHRAPI HrMagicReboot(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
PDMCONN pdmc;

char szTmp[MAX_PATH];
char szLaunchPath[MAX_PATH];
char szMountPath[MAX_PATH];
char szCmdLine[MAX_PATH];

DWORD dwMask = 0;
HRESULT hr = XBDM_NOERR;

szCmdLine[0] = 0;
szMountPath[0] = 0;
szLaunchPath[0] = 0;

if(PchGetParam(szCommand, "wait", FALSE))
dwMask = DMBOOT_WAIT;
else if(PchGetParam(szCommand, "stop", FALSE))
dwMask = DMBOOT_STOP;
if(PchGetParam(szCommand, "cold", FALSE))
dwMask |= DMBOOT_COLD;

// TODO: if(stopped and exception) flag |= cold
if(FGetSzParam(szCommand, "title", szTmp, sizeof(szTmp)))
{
if(szTmp[0] == '\\')
strcpy_s(szLaunchPath, sizeof(szLaunchPath), szTmp);
else if(FAILED(FFileNameToObName(szTmp, szLaunchPath, sizeof(szLaunchPath))))
hr = XBDM_NOSUCHFILE;
}
if(FGetSzParam(szCommand, "directory", szTmp, sizeof(szTmp)))
{
if(szTmp[0] == '\\')
strcpy_s(szMountPath, sizeof(szMountPath), szTmp);
else if(FAILED(FFileNameToObName(szTmp, szMountPath, sizeof(szMountPath))))
hr = XBDM_NOSUCHFILE;
}

FGetSzParam(szCommand, "cmdline", szCmdLine, sizeof(szCmdLine));

if(NT_SUCCESS(hr))
{
if(dwMask & DMBOOT_COLD)
{
pdmc = CONTAINING_RECORD(pdmcc, DMCONN, dmcc);
FSendLine(pdmc->s, "200- OK");

Sleep(200);
FStopServ();
}

DmRebootEx(dwMask, szLaunchPath, szMountPath, szCmdLine);
}

return XBDM_NOERR;
}

DMHRAPI HrGetConsoleFeatures(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
if(!pdmcc)
return E_FAIL;

strcpy_s(szResponse, cchResponse, "DEBUGGING");

if(g_dmGlobals.dwConsoleColor & CONSOLE_COLOR_FLAG_BLUE)
strcat_s(szResponse, cchResponse, " 1GB_RAM");

return XBDM_NOERR;
}

DMHRAPI HrGetConsoleType(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
if(!pdmcc)
return E_FAIL;

if(g_dmGlobals.dwConsoleColor & CONSOLE_COLOR_FLAG_BLACK)
strcpy_s(szResponse, cchResponse, "devkit");
else if(g_dmGlobals.dwConsoleColor & CONSOLE_COLOR_FLAG_WHITE)
strcpy_s(szResponse, cchResponse, "testkit");
else
strcpy_s(szResponse, cchResponse, "reviewerkit");


return XBDM_NOERR;
}

DMHRAPI HrDbgName(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
char sz[256];

if(FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy_s(g_dmGlobals.rgchDbgName, 256, sz);
g_dmGlobals.bDirty = TRUE;

return XBDM_NOERR;
}

strcpy_s(szResponse, cchResponse, g_dmGlobals.rgchDbgName);
return XBDM_NOERR;
}

DMHRAPI HrDrivemap(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
if(PchGetParam(szCommand, "internal", FALSE))
g_dmGlobals.bDriveMap = TRUE;
else
g_dmGlobals.bDriveMap = FALSE;

g_dmGlobals.bDirty = TRUE;

return XBDM_NOERR;
}

DMHRAPI HrReportHelpInfo(PDM_CMDCONT pdmcc, LPSTR szResponse, DWORD cchResponse)
{
if((int)pdmcd->cch >= cchcmd)
return XBDM_ENDOFLIST;

strcpy_s((char*)pdmcc->Buffer, pdmcc->BufferSize, rgbcmd[pdmcd->cch].szName);
pdmcd->cch++;

return XBDM_NOERR;
}

DMHRAPI HrHelp(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
if(!pdmcc)
return E_FAIL;

pdmcc->HandlingFunction = HrReportHelpInfo;
pdmcc->BufferSize = 1;
pdmcd->cch = 0;

strcpy_s(szResponse, cchResponse, "command names follow");

return XBDM_MULTIRESPONSE;
}

DMHRAPI HrReboot(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
if(!pdmcc)
return E_FAIL;

FStopServ();

HalReturnToFirmware(6);
return XBDM_NOERR;
}

DMHRAPI HrSetSystemTime(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
ULARGE_INTEGER lu, luUnused;

if(!pdmcc)
return E_FAIL;

if(!FGetDwParam(szCommand, "clockhi", &lu.HighPart) || !FGetDwParam(szCommand, "clocklo", &lu.LowPart))
return XBDM_CLOCKNOTSET;

NtSetSystemTime(&lu, &luUnused);
XnpNoteSystemTime();

g_dmGlobals.fClockSet = TRUE;

return XBDM_NOERR;
}

DMHRAPI HrGetSystemTime(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
ULARGE_INTEGER lu;

if(!pdmcc)
return E_FAIL;

if(!g_dmGlobals.fClockSet)
return XBDM_CLOCKNOTSET;

KeQuerySystemTime(&lu);

RtlSnprintf(szResponse, cchResponse, "high=0x%x low=0x%x", lu.HighPart, lu.LowPart);

return XBDM_NOERR;
}

DMHRAPI HrShutdown(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
if(!pdmcc)
return E_FAIL;

FStopServ();

HalReturnToFirmware(5);
return XBDM_NOERR;
}

DMHRAPI HrSpew(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
DbgPrint("SPEW: %s\n", szCommand);
return XBDM_NOERR;
}

DMHRAPI HrReportXbeInfo(PDM_CMDCONT pdmcc, LPSTR szResponse, DWORD cchResponse)
{
PDM_XBE pdxbe = (PDM_XBE)pdmcc->CustomData;
int i;

if(pdmcc->BytesRemaining == 3)
{
DmFreePool(pdmcc->CustomData);
return XBDM_ENDOFLIST;
}
else if(pdmcc->BytesRemaining == 2)
{
i = strlen(pdxbe->LaunchPath);

pdxbe->LaunchPath[i++] = '"';
pdxbe->LaunchPath[i + 1] = 0;
memmove(pdxbe->LaunchPath + 6, pdxbe->LaunchPath, i++);
memcpy(pdxbe->LaunchPath, "name=\"", 6);

pdmcc->Buffer = pdxbe->LaunchPath;
pdmcc->BytesRemaining++;
}
else if(pdmcc->BytesRemaining == 1)
{
RtlSnprintf((char*)pdmcc->Buffer, pdmcc->BufferSize, "timestamp=0x%08x checksum=0x%08x", pdxbe->TimeStamp, pdxbe->CheckSum);

pdmcc->BytesRemaining++;
}

return XBDM_NOERR;
}

DMHRAPI HrGetXbeInfo(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
PDM_XBE pdxbe;
DWORD dwFlags = 0;
char sz[0x200];
LPCSTR szName;
HRESULT hr;

if(!pdmcc)
return E_FAIL;

if(PchGetParam(szCommand, "running", FALSE))
szName = NULL;
else if(FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
szName = sz;

if(PchGetParam(szCommand, "ondiskonly", FALSE))
dwFlags = DM_XBEONDISKONLY;
}
else
{
strcpy_s(szResponse, cchResponse, "missing name");
return E_FAIL;
}

pdxbe = (PDM_XBE)DmAllocatePoolWithTag(sizeof(DM_XBE), 'Xbdm');
pdmcc->CustomData = pdxbe;

if(!pdxbe)
return E_OUTOFMEMORY;

hr = DmGetXbeInfoEx(szName, pdxbe, dwFlags);

if(NT_SUCCESS(hr))
{
pdmcc->HandlingFunction = HrReportXbeInfo;
pdmcc->BytesRemaining = 1;

hr = XBDM_MULTIRESPONSE;
}
else
DmFreePool(pdxbe);

return hr;
}

DMHRAPI HrReportDriveList(PDM_CMDCONT pdmcc, LPSTR szResponse, DWORD cchResponse)
{
CHAR sz[MAX_PATH];
NTSTATUS st;
ANSI_STRING as;
OBJECT_ATTRIBUTES oa;
BOOL bExists = FALSE;
OBJECT_DIRECTORY_INFORMATION odi;
HANDLE h;
int i;

start:
if(pdmcd->cch == 0)
{
// List from our interal list

i = Drives[pdmcd->DriveList.CurrentDrive].Visibility;

// Check verbosity
if(i != 0 && !(i == 1 && !g_dmGlobals.bDriveMap))
{
// Get name
strcpy(sz, Drives[pdmcd->DriveList.CurrentDrive].DriveName);
i = strlen(sz);
strcat(sz, ":\\");

st = FCreateFile(&h, SYNCHRONIZE, sz, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
if(NT_SUCCESS(st))
{
sz[i] = 0;
bExists = TRUE;
NtClose(h);
}
}

pdmcd->DriveList.CurrentDrive++;

if(pdmcd->DriveList.CurrentDrive >= cchDrives)
{
// Move on to the actual object enumeration
pdmcd->cch = 1;

RtlInitAnsiString(&as, "\\??");
oa.Attributes = OBJ_CASE_INSENSITIVE;
oa.ObjectName = &as;
oa.RootDirectory = NULL;

pdmcd->DriveList.CurrentDrive = 0;

st = NtOpenDirectoryObject(&pdmcd->h, &oa);

if(FAILED(st))
{
pdmcd->h = INVALID_HANDLE_VALUE;
pdmcd->cch = 2;
}
}
}
else if(pdmcd->cch == 1)
{
// List the objects
st = NtQueryDirectoryObject(pdmcd->h, &odi, sizeof(odi), (pdmcd->DriveList.CurrentDrive == 0), (PULONG)&pdmcd->DriveList.CurrentDrive, NULL);
if(NT_SUCCESS(st))
{
// Attempt to open the device that we found
memcpy(sz, odi.Name.Buffer, odi.Name.Length);

// But first, check the drive list
sz[odi.Name.Length - 1] = 0;
for(i = 0;i < cchDrives;i++)
{
if(!strcmpi(Drives[i].DriveName, sz))
{
bExists = TRUE;
break;
}
}

if(bExists)
bExists = FALSE;
else
{
strcat(sz, ":\\");

st = FCreateFile(&h, SYNCHRONIZE, sz, NULL, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
FILE_OPEN, FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
if(NT_SUCCESS(st))
{
NtClose(h);
sz[odi.Name.Length - 1] = 0;
bExists = TRUE;
}
}
}
else
{
NtClose(pdmcd->h);
pdmcd->cch = 2;
}
}
else
return XBDM_ENDOFLIST;

if(bExists)
RtlSnprintf((char*)pdmcc->Buffer, pdmcc->BufferSize, "drivename=\"%s\"", sz);
else
goto start;

return XBDM_NOERR;
}

DMHRAPI HrGetDriveList(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
if(!pdmcc)
return E_FAIL;

pdmcd->cch = 0;
pdmcd->DriveList.CurrentDrive = 0;
pdmcd->h = INVALID_HANDLE_VALUE;

pdmcc->BytesRemaining = 1;
pdmcc->HandlingFunction = HrReportDriveList;

return XBDM_MULTIRESPONSE;
}

DMHRAPI HrReportDriveFreeSpace(PDM_CMDCONT pdmcc, LPSTR szResponse, DWORD cchResponse)
{
FILE_FS_SIZE_INFORMATION fsi;
IO_STATUS_BLOCK iosb;
DWORD dwBPU;
ULARGE_INTEGER ulFree, ulTotal;
NTSTATUS st;

if(pdmcd->cch)
return XBDM_ENDOFLIST;

pdmcd->cch = 1;

st = NtQueryVolumeInformationFile(pdmcd->h, &iosb, &fsi, sizeof(fsi), FileFsSizeInformation);

if(FAILED(st))
{
RtlSnprintf((char*)pdmcc->Buffer, pdmcc->BufferSize, "unknown error (%d)", st);
return E_FAIL;
}

dwBPU = fsi.SectorsPerAllocationUnit * fsi.BytesPerSector;

ulFree.QuadPart = fsi.AvailableAllocationUnits.QuadPart * dwBPU;
ulTotal.QuadPart = fsi.TotalAllocationUnits.QuadPart * dwBPU;

RtlSnprintf((char*)pdmcc->Buffer, pdmcc->BufferSize, "freetocallerlo=0x%08x freetocallerhi=0x%08x totalbyteslo=0x%08x totalbyteshi=0x%08x totalfreebyteslo=0x%08x totalfreebyteshi=0x%08x",
ulFree.LowPart, ulFree.HighPart, ulTotal.LowPart, ulTotal.HighPart, ulFree.LowPart, ulFree.HighPart);

return XBDM_NOERR;
}

DMHRAPI HrGetDriveFreeSpace(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
NTSTATUS st;
char sz[MAX_PATH];

if(!pdmcc)
return E_FAIL;

if(!FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy(szResponse, "missing name");
return E_FAIL;
}

st = FCreateFile(&pdmcd->h, FILE_READ_ATTRIBUTES, sz, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

if(FAILED(st))
return XBDM_CANNOTACCESS;

pdmcd->cch = 0;
pdmcc->HandlingFunction = HrReportDriveFreeSpace;

return XBDM_MULTIRESPONSE;
}

DMHRAPI HrReportDirList(PDM_CMDCONT pdmcc, LPSTR szResponse, DWORD cchResponse)
{
NTSTATUS st;
IO_STATUS_BLOCK iosb;
FILE_DIRECTORY_INFORMATION fna;
HRESULT hr = XBDM_NOERR;

ZeroMemory(&fna, sizeof(fna));
st = NtQueryDirectoryFile(pdmcd->h, NULL, NULL, NULL, &iosb,
&fna, sizeof(fna), NULL, NULL);

if(NT_SUCCESS(st))
{
RtlSnprintf((char*)pdmcc->Buffer, pdmcc->BufferSize, "name=\"%s\" ", fna.FileName);
GetFileAttrSz((char*)pdmcc->Buffer + strlen((char*)pdmcc->Buffer), fna.FileAttributes,
&fna.LastWriteTime, &fna.CreationTime, &fna.EndOfFile);
}
else
{
NtClose(pdmcd->h);
hr = XBDM_ENDOFLIST;
}

return hr;
}

DMHRAPI HrGetDirList(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
NTSTATUS st;
CHAR sz[MAX_PATH];

if(!pdmcc)
return E_FAIL;

if(!FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy(szResponse, "missing name");
return E_FAIL;
}

pdmcc->BytesRemaining = 1;
pdmcc->HandlingFunction = HrReportDirList;

st = FCreateFile(&pdmcd->h, FILE_LIST_DIRECTORY | SYNCHRONIZE, sz, NULL, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);

return NT_SUCCESS(st) ? XBDM_MULTIRESPONSE : XBDM_CANNOTACCESS;
}

DMHRAPI HrDvdEject(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
DWORD dwEject = 1;

if(!pdmcc)
return E_FAIL;

FGetDwParam(szCommand, "eject", &dwEject);

HalOpenCloseODDTray(dwEject);

return XBDM_NOERR;
}

DMHRAPI HrDelete(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
FILE_DISPOSITION_INFORMATION fdi;
IO_STATUS_BLOCK iosb;
char sz[MAX_PATH];
NTSTATUS st;
HANDLE h;
BOOL b;

if(!pdmcc)
return E_FAIL;

if(!FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy_s(szResponse, cchResponse, "missing name");
return E_FAIL;
}

b = (BOOL)PchGetParam(szCommand, "dir", FALSE);

st = FCreateFile(&h, DELETE | SYNCHRONIZE, sz, NULL, 0, 0,
FILE_OPEN, (b ? FILE_DIRECTORY_FILE : FILE_NON_DIRECTORY_FILE)
| FILE_SYNCHRONOUS_IO_NONALERT);

if(FAILED(st))
return XBDM_CANNOTACCESS;

ZeroMemory(&fdi, sizeof(fdi));
fdi.DeleteFile = TRUE;

st = NtSetInformationFile(h, &iosb, &fdi, sizeof(fdi), FileDispositionInformation);
NtClose(h);

if(FAILED(st))
return XBDM_CANNOTACCESS;

return XBDM_NOERR;
}

DMHRAPI HrCreateDirectory(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
char sz[MAX_PATH];
NTSTATUS st;
HANDLE h;

if(!pdmcc)
return E_FAIL;

if(!FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy_s(szResponse, cchResponse, "missing name");
return E_FAIL;
}

st = FCreateFile(&h, FILE_LIST_DIRECTORY | SYNCHRONIZE, sz,
NULL, FILE_ATTRIBUTE_NORMAL, 0, FILE_CREATE, FILE_DIRECTORY_FILE |
FILE_SYNCHRONOUS_IO_NONALERT);

if(FAILED(st))
{
if(st == STATUS_OBJECT_NAME_COLLISION)
return XBDM_ALREADYEXISTS;
return XBDM_CANNOTCREATE;
}

NtClose(h);
return XBDM_NOERR;
}

DMHRAPI HrRenameFile(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
char sz[MAX_PATH];
char szNew[MAX_PATH];
IO_STATUS_BLOCK iosb;
NTSTATUS st;
HANDLE h;
FILE_RENAME_INFORMATION fri;

if(!pdmcc)
return E_FAIL;

if(!FGetSzParam(szCommand, "newname", sz, sizeof(sz)))
{
strcpy_s(szResponse, cchResponse, "missing newname");
return E_FAIL;
}
if(FAILED(FFileNameToObName(sz, szNew, sizeof(szNew))))
{
strcpy_s(szResponse, cchResponse, "new name does not exist");
return XBDM_NOSUCHFILE;
}
if(!FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy_s(szResponse, cchResponse, "missing name");
return E_FAIL;
}

st = FCreateFile(&h, GENERIC_WRITE | SYNCHRONIZE, sz, NULL, 0, 0,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT);

if(FAILED(st))
return XBDM_CANNOTACCESS;

ZeroMemory(&fri, sizeof(fri));

RtlInitAnsiString(&fri.FileName, szNew);
fri.ReplaceIfExists = FALSE;
fri.RootDirectory = NULL;

st = NtSetInformationFile(h, &iosb, &fri, sizeof(fri), FileRenameInformation);
NtClose(h);

if(st == STATUS_NOT_SAME_DEVICE)
return XBDM_MUSTCOPY;

if(FAILED(st))
return XBDM_CANNOTCREATE;

return XBDM_NOERR;
}

DMHRAPI HrReportFileAttributes(PDM_CMDCONT pdmcc, LPSTR szResponse, DWORD cchResponse)
{
if(pdmcd->cch)
return XBDM_ENDOFLIST;

pdmcd->cch = 1;

GetFileAttrSz((LPSTR)pdmcc->Buffer, pdmcd->fni.fni.FileAttributes,
&pdmcd->fni.fni.LastWriteTime, &pdmcd->fni.fni.CreationTime,
&pdmcd->fni.fni.EndOfFile);

return XBDM_NOERR;
}

DMHRAPI HrGetFileAttr(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
char sz[MAX_PATH];
char osz[MAX_PATH];
ANSI_STRING as;
NTSTATUS st;
OBJECT_ATTRIBUTES oa;

if(!pdmcc)
return E_FAIL;

if(!FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy_s(szResponse, cchResponse, "missing name");
return E_FAIL;
}

if(FAILED(FFileNameToObName(sz, osz, sizeof(osz))))
return XBDM_NOSUCHFILE;

RtlInitAnsiString(&as, osz);
oa.Attributes = OBJ_CASE_INSENSITIVE;
oa.RootDirectory = NULL;
oa.ObjectName = &as;

pdmcc->HandlingFunction = HrReportFileAttributes;
pdmcc->BytesRemaining = 1;
pdmcd->cch = 0;

st = NtQueryFullAttributesFile(&oa, &pdmcd->fni.fni);
return NT_SUCCESS(st) ? XBDM_MULTIRESPONSE : XBDM_NOSUCHFILE;
}

DMHRAPI HrSetFileAttr(LPCSTR szCommand, LPSTR szResponse,
DWORD cchResponse, PDM_CMDCONT pdmcc)
{
NTSTATUS st;
HANDLE h;
IO_STATUS_BLOCK iosb;
char sz[MAX_PATH];
FILE_NETWORK_OPEN_INFORMATION fna;
FILE_BASIC_INFORMATION fba;
DWORD dwAttrMask = 0;
DWORD dwAttrNew = 0;
DWORD dwT = 0;

if(!pdmcc)
return E_FAIL;

if(!FGetSzParam(szCommand, "name", sz, sizeof(sz)))
{
strcpy_s(szResponse, cchResponse, "missing name");
return E_FAIL;
}

st = FCreateFile(&h, SYNCHRONIZE, sz, NULL, 0,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
FILE_SYNCHRONOUS_IO_NONALERT);

if(FAILED(st))
return XBDM_CANNOTACCESS;

st = NtQueryInformationFile(h, &iosb, &fna, sizeof(fna), FileNetworkOpenInformation);

if(FAILED(st))
{
NtClose(h);
return XBDM_CANNOTACCESS;
}

ZeroMemory(&fba, sizeof(fba));
if(FGetDwParam(szCommand, "readonly", &dwT))
{
dwAttrMask |= FILE_ATTRIBUTE_READONLY;
if(dwT)
dwAttrNew |= FILE_ATTRIBUTE_READONLY;
}
if(FGetDwParam(szCommand, "hidden", &dwT))
{
dwAttrMask |= FILE_ATTRIBUTE_HIDDEN;
if(dwT)
dwAttrNew |= FILE_ATTRIBUTE_HIDDEN;
}

FGetDwParam(szCommand, "createhi", (DWORD*)&fba.CreationTime.HighPart);
FGetDwParam(szCommand, "createlo", (DWORD*)&fba.ChangeTime.LowPart);
FGetDwParam(szCommand, "changehi", (DWORD*)&fba.LastWriteTime.HighPart);
FGetDwParam(szCommand, "changelo", (DWORD*)&fba.LastWriteTime.LowPart);

fba.FileAttributes = fna.FileAttributes ^ ((fna.FileAttributes ^ dwAttrNew) & dwAttrMask);

if(!fba.FileAttributes)
fba.FileAttributes = FILE_ATTRIBUTE_NORMAL;

st = NtSetInformationFile(h, &iosb, &fba, sizeof(fba), FileBasicInformation);

NtClose(h);

return NT_SUCCESS(st) ? XBDM_NOERR : XBDM_CANNOTACCESS;
}

DMHRAPI HrReportMemoryEx(PDM_CMDCONT pdmcc, LPSTR szResponse, DWORD cchResponse)
{
DWORD chars, addr, read = 0;
BYTE mem;

if(!pdmcd->cch)
{
pdmcc->BytesRemaining = 0;
DmFreePool(pdmcc->Buffer);

return XBDM_ENDOFLIST;
}

chars = pdmcd->cch;
if(chars > 0x400)
{
chars = 0x400;
((PBYTE)pdmcc->Buffer)[1] = 0x00;
}
else
((PBYTE)pdmcc->Buffer)[1] = 0x80;

((PBYTE)pdmcc->Buffer)[0] = 0;

for(addr = pdmcd->mem.Address;addr < pdmcd->mem.Address + chars;addr++)
{
if(FGetMemory(addr, &mem))
{
((PBYTE)pdmcc->Buffer)[addr - pdmcd->mem.Address + 2] = mem;
read++;
}
else
{
pdmcd->cch = 0;
((PBYTE)pdmcc->Buffer)[1] = 0x80;
break;
}
}

*(PWORD)pdmcc->Buffer |= _byteswap_ushort((WORD)read);

if(pdmcd->cch)
pdmcd->cch -= read;

pdmcd->mem.Address += read;

pdmcc->BytesRemaining = 1;
pdmcc->DataSize = read + 2;

return XBDM_NOERR;
}

Please moderator delete this duplicate post thank you..
Reply
#2
lol ooooooooooooooooooooooooooooooooooooof
This account is currently banned
Ban reason: leeching and spamming
Reply
#3
okay then lol jo
Reply

Users browsing: 1 Guest(s)