// test_service.cpp : Defines the entry point for the console application.
//

#include <afx.h>
#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdtctl.h>		// MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h>			// MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT

#include <winbase.h>

#include <iostream>
#include <stdio.h>

using namespace std;

#include "test_service.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

#include "cService.hpp"

class  cMyService : private TService {
 public:
   cMyService (char *arg);

 private:
   const char* GetName        (void){return "CGId";}
   void        ServiceProc    (void);
};

cMyService::cMyService (char *arg) {
if (arg != NULL) {
  unsigned short a = *((unsigned short*) arg);  

   if      (a == *((unsigned short*) "/i")) Install(), cout << _T("install service...") << endl << flush; 
   else if (a == *((unsigned short*) "/r")) Remove(), cout << _T("remove service...") << endl << flush;
   else if (a == *((unsigned short*) "/s")) Start(), cout << _T("start service...") << endl << flush;
   else if (a == *((unsigned short*) "/q")) Stop(), cout << _T("stop service...") << endl << flush;
   else if (a == *((unsigned short*) "/t")) ConsoleMode(), cout << _T("text mode...") << endl << flush;;
   }
else Execute();
}

size_t ExecuteProcess(CString FullPathToExe, CString Parameters, size_t SecondsToWait) 
{ 
    size_t iReturnVal = 0; 
    DWORD dwExitCode = 0; 
    CString sTempStr = ""; 

    /* - NOTE - You should check here to see if the exe even exists */ 

    /* Add a space to the beginning of the Parameters */ 
    if (Parameters.GetLength() != 0) 
    { 
        if (Parameters[0] != ' ') 
        { 
            Parameters = " " + Parameters; 
        } 
    } 

    /* The first parameter needs to be the exe itself */ 
    sTempStr = FullPathToExe; 
    //iPos = sTempStr.find_last_of("\\"); 
    //sTempStr.erase(0, iPos +1); 
    Parameters = sTempStr + Parameters; 

     /* CreateProcessW can modify Parameters thus we allocate needed memory */ 
    char * pwszParam = new char[Parameters.GetLength() + 1]; 
    if (pwszParam == 0) 
    { 
        return 1; 
    } 
    const char* pchrTemp = Parameters.GetBuffer(1024); 
    memcpy(pwszParam, pchrTemp, Parameters.GetLength()+1); 
	Parameters.ReleaseBuffer(0);

    /* CreateProcess API initialization */ 
    STARTUPINFO siStartupInfo; 
    PROCESS_INFORMATION piProcessInfo; 
    memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 
    memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 
    siStartupInfo.cb = sizeof(siStartupInfo); 

    if (CreateProcess(const_cast<LPCSTR>(FullPathToExe.GetBuffer(1024)), 
                            pwszParam, 0, 0, false, 
                            CREATE_DEFAULT_ERROR_MODE, 0, 0, 
                            &siStartupInfo, &piProcessInfo) != false) 
    { 
         /* Watch the process. */ 
        //dwExitCode = WaitForSingleObject(piProcessInfo.hProcess, SecondsToWait); 
    } 
    else 
    { 
        /* CreateProcess failed */ 
        iReturnVal = GetLastError(); 
    } 

	FullPathToExe.ReleaseBuffer(0);

    /* Free memory */ 
    delete[]pwszParam; 
    pwszParam = 0; 

    /* Release handles */ 
    CloseHandle(piProcessInfo.hProcess); 
    CloseHandle(piProcessInfo.hThread); 

    return iReturnVal; 
} 

extern "C" {
      typedef int (*pf_t)();
      extern pf_t get_proc_address(HINSTANCE hInst, const char * name);
}


void cMyService::ServiceProc (void) {
   //FILE * cmd = _popen("C:\\Development\\cgid\\cgid\\cgid.exe", "rw");
   //if(cmd != NULL) {
   //   int ch;
   //   ch = fgetc(cmd);
   //   while(!feof(cmd)) {
   //      ch = fgetc(cmd);
   //   }
   //   _pclose(cmd);
   //}
   //STARTUPINFO siStartupInfo; 
   //PROCESS_INFORMATION piProcessInfo; 
   //memset(&siStartupInfo, 0, sizeof(siStartupInfo)); 
   //memset(&piProcessInfo, 0, sizeof(piProcessInfo)); 
   //siStartupInfo.cb = sizeof(siStartupInfo);
   //CreateProcess("C:\\Development\\cgid\\cgid\\cgid.exe", 
   //              "", 0, 0, false, 
   //              CREATE_DEFAULT_ERROR_MODE, 0, 0, 
   //              &siStartupInfo, &piProcessInfo);
   SetCurrentDirectory("c:\\Development\\cgid\\cgid"); 
   ShellExecute(NULL, "open", "cgid.exe", NULL, NULL, SW_SHOWNORMAL);
   //ExecuteProcess("C:\\Development\\cgid\\cgid\\cgid.exe", "", INFINITE);
   //system("C:\\Development\\cgid\\cgid\\cgid.exe");
   //HINSTANCE hInstance = LoadLibrary("C:\\Development\\cgid\\cgid\\cgid.dll");
   //if(hInstance != NULL) {
   //   pf_t f = get_proc_address(hInstance, "server_main");
   //   if(f != NULL) {
   //      f();
   //   }
   //   CloseHandle(hInstance);
   //}

   
while (! Terminated()) {
   //Beep  (400,100);
   Sleep (5000);
   }
}

void main (int argc,char *argv[]) {
delete new cMyService(argv[1]);
}

/*
CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		cerr << _T("Fatal Error: MFC initialization failed") << endl;
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		CString strHello;
		strHello.LoadString(IDS_HELLO);
		cout << (LPCTSTR)strHello << endl;
	}

	return nRetCode;
}


*/