Windows2003-3790/sdktools/debuggers/sds/sdp.cpp
2020-09-30 16:53:55 +02:00

378 lines
7.2 KiB
C++

#include <windows.h>
#include <stdio.h>
#include <direct.h>
#include <assert.h>
#include <tchar.h>
#include <dbghelp.h>
#include <strsafe.h>
#include <str.h>
typedef enum {
cmdIni,
cmdInfo,
cmdClient,
cmdHave,
cmdSync,
cmdMax
};
typedef BOOL (*CMDPROC)(TCHAR *dir);
typedef struct _CMD {
TCHAR *sz;
CMDPROC cmdproc;
PENUMDIRTREE_CALLBACK enumdirproc;
} CMD, *PCMD;
BOOL ini(TCHAR *path);
BOOL info(TCHAR *dir);
BOOL client(TCHAR *dir);
BOOL have(TCHAR *dir);
BOOL sync(TCHAR *dir);
BOOL CALLBACK cbIni(LPCSTR filepath, void *data);
BOOL CALLBACK cbInfo(LPCSTR filepath, void *data);
BOOL CALLBACK cbClient(LPCSTR filepath, void *data);
BOOL CALLBACK cbHave(LPCSTR filepath, void *data);
BOOL CALLBACK cbSync(LPCSTR filepath, void *data);
CMD gcmds[cmdMax] =
{
{TEXT("ini"), ini, cbIni},
{TEXT("info"), info, cbInfo},
{TEXT("client"), client, cbClient},
{TEXT("have"), have, cbHave},
{TEXT("sync"), sync, cbSync},
};
bool grecursive = false;
int gcmd;
TCHAR gdir[SZ_SIZE];
bool init()
{
grecursive = false;
gcmd = cmdMax;
_tgetcwd(gdir, SZ_SIZE);
return true;
}
bool parsecmd(int argc, TCHAR *argv[])
{
int i;
for (i = 1; i < argc; i++)
{
if (!_tcscmp(argv[i], TEXT("...")))
{
grecursive = true;
}
else if (!_tcsicmp(argv[i], TEXT("ini")))
{
gcmd = cmdIni;
}
else if (!_tcsicmp(argv[i], TEXT("info")))
{
gcmd = cmdInfo;
}
else if (!_tcsicmp(argv[i], TEXT("client")))
{
gcmd = cmdClient;
}
else if (!_tcsicmp(argv[i], TEXT("have")))
{
gcmd = cmdHave;
}
else if (!_tcsicmp(argv[i], TEXT("sync")))
{
gcmd = cmdSync;
}
else
{
_tprintf(TEXT("SDP: \"%s\" is an unrecognized parameter.\n"), argv[i]);
return false;
}
}
return true;
}
BOOL
dumpfile(
const TCHAR *path
)
{
BOOL rc;
HANDLE hf;
DWORD size;
DWORD cb;
LPSTR p;
char buf[SZ_SIZE];
assert(path && *path);
fflush(stdout);
rc = FALSE;
hf = CreateFile(path,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hf == INVALID_HANDLE_VALUE)
return FALSE;
// test validity of file pointer
size = GetFileSize(hf, NULL);
if (!size || size > SZ_SIZE)
goto cleanup;
// read it
ZeroMemory(buf, SZ_SIZE * sizeof(buf[0]));
if (!ReadFile(hf, buf, size, &cb, 0))
goto cleanup;
if (cb != size)
goto cleanup;
rc = TRUE;
printf("%s\n", buf);
cleanup:
// done
if (hf)
CloseHandle(hf);
fflush(stdout);
return rc;
}
BOOL ini(TCHAR *path)
{
TCHAR file[SZ_SIZE];
StringCchCopy(file, DIMA(file), path);
if (!_tcsstr(file, TEXT("sd.ini")))
{
EnsureTrailingBackslash(file);
StringCchCat(file, DIMA(file), TEXT("sd.ini"));
}
_tprintf(TEXT("------- SDP INI: %s -------\n"), path);
dumpfile(file);
return false;
}
BOOL CALLBACK cbIni(LPCSTR filepath, void *data)
{
TCHAR sz[SZ_SIZE];
TCHAR path[SZ_SIZE];
ansi2tchar(filepath, sz, SZ_SIZE);
getpath(sz, path, DIMA(path));
return ini(path);
}
BOOL process(TCHAR *dir, TCHAR *cmd)
{
BOOL rc;
DWORD err;
STARTUPINFO si;
PROCESS_INFORMATION pi;
TCHAR sz[SZ_SIZE];
StringCchCopy(sz, DIMA(sz), cmd);
fflush(stdout);
GetStartupInfo(&si);
ZeroMemory(&pi, sizeof(pi));
rc = CreateProcess(NULL, // LPCWSTR lpszImageName,
sz, // LPCWSTR lpszCmdLine,
NULL, // LPSECURITY_ATTRIBUTES lpsaProcess,
NULL, // LPSECURITY_ATTRIBUTES lpsaThread,
true, // BOOL fInheritHandles,
0, // DWORD dwCreationFlags,
NULL, // LPVOID lpvEnvironment,
dir, // LPWSTR lpszCurDir,
&si, // LPSTARTUPINFOW lpsiStartInfo,
&pi // LPPROCESS_INFORMATION lppiProcInfo
);
if (!rc || !pi.hProcess)
{
err = GetLastError();
goto cleanup;
}
// Wait for command to complete ... Give it 20 minutes
err = WaitForSingleObject(pi.hProcess, 1200000);
if (err != WAIT_OBJECT_0)
{
rc = false;
goto cleanup;
}
// Get the process exit code
GetExitCodeProcess(pi.hProcess, &err);
rc = (err == ERROR_SUCCESS) ? true : false;
cleanup:
if (pi.hProcess)
CloseHandle(pi.hProcess);
fflush(stdout);
return rc;
}
BOOL info(TCHAR *dir)
{
_tprintf(TEXT("------- SDP INFO: %s -------\n"), dir);
return process(dir, TEXT("sd.exe info"));
}
BOOL CALLBACK cbInfo(LPCSTR filepath, void *data)
{
TCHAR sz[SZ_SIZE];
TCHAR path[SZ_SIZE];
ansi2tchar(filepath, sz, SZ_SIZE);
getpath(sz, path, DIMA(path));
info(path);
return false;
}
BOOL client(TCHAR *dir)
{
_tprintf(TEXT("------- SDP CLIENT: %s -------\n"), dir);
if (!process(dir, TEXT("sd.exe info")))
return false;
return process(dir, TEXT("sd.exe client -o"));
}
BOOL CALLBACK cbClient(LPCSTR filepath, void *data)
{
TCHAR sz[SZ_SIZE];
TCHAR path[SZ_SIZE];
ansi2tchar(filepath, sz, SZ_SIZE);
getpath(sz, path, DIMA(path));
// ini(sz);
client(path);
return false;
}
BOOL have(TCHAR *dir)
{
_tprintf(TEXT("------- SDP HAVE: %s -------\n"), dir);
return process(dir, TEXT("sd.exe have"));
}
BOOL CALLBACK cbHave(LPCSTR filepath, void *data)
{
TCHAR sz[SZ_SIZE];
TCHAR path[SZ_SIZE];
ansi2tchar(filepath, sz, SZ_SIZE);
getpath(sz, path, DIMA(path));
have(path);
return false;
}
BOOL sync(TCHAR *dir)
{
return process(dir, TEXT("sd.exe sync"));
}
BOOL CALLBACK cbSync(LPCSTR filepath, void *data)
{
TCHAR sz[SZ_SIZE];
TCHAR path[SZ_SIZE];
ansi2tchar(filepath, sz, SZ_SIZE);
getpath(sz, path, DIMA(path));
sync(path);
fflush(stdout);
return false;
}
bool cmd()
{
char sz[SZ_SIZE];
if (gcmd == cmdMax)
return false;
if (grecursive)
{
tchar2ansi(gdir, sz, SZ_SIZE);
EnumDirTree(INVALID_HANDLE_VALUE, sz, "sd.ini", NULL, gcmds[gcmd].enumdirproc, NULL);
return true;
}
gcmds[gcmd].cmdproc(gdir);
return true;
}
extern "C" int __cdecl _tmain(int argc, _TCHAR **argv, _TCHAR **envp)
{
if (!init())
return -1;
if (!parsecmd(argc, argv))
return -1;
if (!cmd())
return -1;
return 0;
}