|
|
// conexec.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "process.h" // for CreateProcess? //for _spawnv //windows.h" // for CreateThread()
#include "mscoree.h"
#import <mscorlib.tlb> raw_interfaces_only high_property_prefixes("_get","_put","_putref")
using namespace ComRuntimeLibrary; #import <asmexec.tlb>
// !! required !!
#include "Debug/asmexec.tlh"
using namespace asmexec ; //ComHost;
/*#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif*/
//#using <mscorlib.dll>
//{5F078073-5DCE-36EF-8A36-C03C30980216}
extern const GUID __declspec(selectany) CLSID_AsmExecute = { 0x5f078073, 0x5dce, 0x36ef, { 0x8a, 0x36, 0xc0, 0x3c, 0x30, 0x98, 0x02, 0x16 } };
//{229C7FE0-4744-30C8-81F4-BB0541469CA9}
extern const GUID __declspec(selectany) IID__AsmExecute = { 0x229c7fe0, 0x4744, 0x30c8, { 0x81, 0xf4, 0xbb, 0x05, 0x41, 0x46, 0x9c, 0xa9 } };
//class _AsmExecute;
HRESULT _hr; _AsmExecute* _pAsmExecute;
bool init() { bool ret = true;
//
// Initialize COM
//
_hr = ::CoInitialize(NULL); if(FAILED(_hr)) { printf("COM CoInitialize failed...\n"); ret = false; goto exit; }
printf("COM CoInitialize succeed\n");
exit: return ret; }
bool final() { if(SUCCEEDED(_hr)) { ::CoUninitialize(); printf("COM CoUninitialize called\n"); }
return true; }
int main(int argc, char* argv[]) { int ret = -1; HRESULT hr;
_hr = E_FAIL; _pAsmExecute = NULL; printf("CONsoleEXEC\n"); if (argc < 3) { printf("syntax: Codebase [+]Flag [Zone] [uniqueId Site]\n + - spawn a new process\n default - execute in this process\n"); goto exit; } else { for (int i = 1; i < argc; i++) { switch(i) { case 1: printf(" Codebase- %s", argv[i]); break; case 2: printf(" Flag- %s", argv[i]); break; case 3: printf(" Zone- %s", argv[i]); break; case 4: printf(" uniqueId- %s", argv[i]); break; case 5: printf(" Site- %s", argv[i]); break; default: break; } } printf("\n"); }
if (!init()) { goto exit; }
if (*argv[2] == '+') { // spawn a new process
// printf("Spawnv...\n" );
printf("CreateProcess...\n");
/* // a hack to remove the flag in the spawn process... BUGBUG? use sprintf and _spawnl?
*argv[2] = ' '; passing the original argv does not work if it originally contains a quoted path, eg. "c:\program files\a.exe"
background: argv[0] is the path to the running program itself note: if you type> prog "ar g1" arg2 this becomes argv[0] = "prog", argv[1] = "ar g1", arg2 = "arg2" if you type> "De ug\prog" "ar g1" this becomes argv[0] = "De ug\prog", argv[1] = "ar g1" however, spawn will only take non-quoted path (even if there are spaces in it) for the program path but the spawned conexec choks on the space inside argv[0] (program path) and instead for it this becomes argv[0] = "De", argv[1] = " ug\prog", argv[2] = "ar g1" - and thus crashes badly Therefore, keep the original argv[0] for spawn program path, but add quotes when pass as arguments*/
/* char buf0[1025];
char* ptr; char buf1[1025]; char buf2[1025]; // _spawn limits to 1024+'\0' for total of argv
_snprintf(buf0, 1025, "\"%s\"", argv[0]); _snprintf(buf1, 1025, "\"%s\"", argv[1]); _snprintf(buf2, 1025, "%s", argv[2]+1); // error checking?
// BUGBUG? free?
ptr = argv[0]; argv[0] = buf0; argv[1] = buf1; argv[2] = buf2;
// _P_OVERLAY? _P_WAIT?
if (_spawnv(_P_NOWAIT, ptr, argv) == -1) { printf("Spawnv failed. errno = %x\n", errno); goto exit; }
// how to start in a new console??
printf("Spawnv succeed. This process will terminate\n" ); ret = 0; goto exit;*/
STARTUPINFO si; PROCESS_INFORMATION pi;
ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) );
// char szAppName[1025];
char szCmdLine[1025]; int len = 0;
/* if ((len = _snprintf(szAppName, 1025, "\"%s\"", argv[0])) <= 0)
{ printf("Application name too long > 1024\n"); goto exit; }
strcpy(szCmdLine, szAppName);
printf("\n\n%d\n", len); szCmdLine[len] = ' '; szCmdLine[len+1] = '0'; szCmdLine[len+2] = '\0';*/ for (int i = 0; i < argc; i++) { // a small hack: "conexec.exe" "asm.exe" 0<-- 2 spaces before "0"
// for this for-loop to work w/o another condition for i=0
if ((len += _snprintf(szCmdLine+len, 1025-len, (i <= 1 ? "\"%s\" " : " %s"), (i == 2 ? argv[i] + 1 : argv[i]))) >= 1025) { printf("Command line too long > 1024\n"); goto exit; } }
// Start the child process.
if( !CreateProcess( NULL, // Use command line instead to avoid ambigous naming and allow the use of quotes.//szAppName, //argv[0], // Myself. This CANNOT have quotes
szCmdLine, // Command line.
NULL, // Process handle not inheritable. security??
NULL, // Thread handle not inheritable. security??
FALSE, // Set handle inheritance to FALSE.
CREATE_NEW_CONSOLE, //DETACHED_PROCESS, // No access to current console.
NULL, // Use parent's environment block.
NULL, // Use parent's starting directory. ??
&si, // Pointer to STARTUPINFO structure.
&pi ) // Pointer to PROCESS_INFORMATION structure.
) { printf("CreateProcess failed. Error code = %x\n", GetLastError()); goto exit; }
// Wait until child process exits.
// WaitForSingleObject( pi.hProcess, INFINITE );
// Close process and thread handles.
CloseHandle( pi.hProcess ); CloseHandle( pi.hThread );
printf("CreateProcess succeed. This process will terminate\n" ); ret = 0; goto exit; }
// return data...?
hr = CoCreateInstance(CLSID_AsmExecute, NULL,CLSCTX_INPROC_SERVER,IID__AsmExecute,(void**)&_pAsmExecute); if (FAILED(hr)) { printf("AsmExecute CoCreateInstance failed...\n"); goto exit; }
printf("AsmExecute CoCreateInstance succeed.\n");
printf("Calling AsmExecute.Execute()...\n"); try { if (argc == 3) { // use _bstr_t?
hr = _pAsmExecute->Execute(argv[1], argv[2]); } else if (argc == 4) { hr = _pAsmExecute->Execute_2(argv[1], argv[2], argv[3]); } else if (argc == 6) //BUGBUG > args?
{ hr = _pAsmExecute->Execute_3(argv[1], argv[2], argv[3], argv[4], argv[5]); } } catch (_com_error &e) { // _com_issue_errorex throws _com_error
printf("... AsmExecute Execute failed; Code = %08lx\n", e.Error()); printf(" Code meaning = %s\n", (char*) e.ErrorMessage()); printf(" Source = %s\n", (char*) e.Source()); printf(" Description = %s\n", (char*) e.Description());
goto exit; }
if (FAILED(hr)) { // !! should never be here !!
printf("... AsmExecute Execute failed; hr = %x\n", hr); goto exit; }
printf("... AsmExecute Execute succeed.\n"); ret = 0; exit: if (_pAsmExecute != NULL) { _pAsmExecute->Release(); _pAsmExecute = NULL; } // BUGBUG: relesase domains?
final(); return ret; }
|