// FcRunAsUser.cpp : AvP[Vp̃Gg |Cg̒`
//

#include "stdafx.h"


//------------------------------------------------------------------------------
//	萔`
//------------------------------------------------------------------------------
#define	MAX_CHAR	_MAX_PATH						// ő啶
#define	FCSRAS_INIFILE			"FcRunAsUser.INI"   // Nt@CۑINIt@C

///////////////////////////////////////////////////////////
// fobO֐î܂DbgPrint֓nj
///////////////////////////////////////////////////////////
VOID MyDbgPrint(LPCTSTR pszFormat, ...)
{
    va_list argList;
    va_start(argList, pszFormat);
    CCHAR szMsg[1024];
    vsprintf(szMsg, pszFormat, argList);
    va_end(argList);
    OutputDebugString(szMsg);
}


//------------------------------------------------------------------------------
//	֐`
//------------------------------------------------------------------------------
void FCRunProcess(LPSTR pSection, LPSTR lpCmdLine);

//------------------------------------------------------------------------------
//	ϐ`
//------------------------------------------------------------------------------
TCHAR szFcRunAsUserIniFile[_MAX_PATH];				// INIt@CFULLpX




int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow )
{
 	// TODO: ̈ʒuɃR[hLqĂB
	TCHAR szDirExe[_MAX_PATH];	// st@C̃pX
	DWORD dwChar;
	TCHAR *pDirExe;
	
	// st@C̃tpX擾B
	dwChar = GetModuleFileName( NULL, szDirExe , _MAX_PATH);	
	// st@C폜i납猟\܂Łj
	pDirExe  = &szDirExe[dwChar];			
	while (*pDirExe != '\\')
	{
		*pDirExe = NULL;
		pDirExe--;
	}
	// NvZXۑpINIt@C쐬
	sprintf(szFcRunAsUserIniFile,"%s%s",szDirExe,FCSRAS_INIFILE);	

	FCRunProcess("RUN_INFO", lpCmdLine);			

	return 0;
}

void FCRunProcess(LPSTR pSection, LPSTR lpCmdLine)
{
	TCHAR szProcessName[MAX_CHAR];
	TCHAR szWorkDir[MAX_CHAR];
	TCHAR szCommandLine[MAX_CHAR];
	static STARTUPINFO siStartInfo ;
	static PROCESS_INFORMATION piProcInfo ;
	BOOL	bRet;

	// ݒt@Cs擾
	GetPrivateProfileString(						// w肳ꂽZNV當擾
				pSection,							// ZNV
				"PROCESS",							// L[
				NULL,								// ftHg
				szProcessName,						// XgO
				sizeof(szProcessName),				// obt@TCY
				szFcRunAsUserIniFile);				// tpX 

	// ݒt@CƃtH_擾
	GetPrivateProfileString(						// w肳ꂽZNV當擾
				pSection,							// ZNV
				"WORKFOLDER",						// L[
				NULL,								// ftHg
				szWorkDir,							// XgO
				sizeof(szWorkDir),					// obt@TCY
				szFcRunAsUserIniFile);				// tpX 

	strcat (szProcessName," ");
	strcat (szProcessName, lpCmdLine);

    PWTS_SESSION_INFO pSessionInfo = 0;
    DWORD dwCount = 0;
    int dwSessionId = 0;

    // Get the list of all terminal sessions
    WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, &pSessionInfo, &dwCount);

    // look over obtained list in search of the active session
    for (DWORD i = 0; i < dwCount; ++i)
    {
        WTS_SESSION_INFO si = pSessionInfo[i];
        if (WTSActive == si.State)
        {
		// If the current session is active ? store its ID
            dwSessionId = si.SessionId;
            break;
        }
    }
	WTSFreeMemory(pSessionInfo);

    HANDLE currentToken = NULL;
    HANDLE primaryToken = NULL;

    // Get token of the logged in user by the active session ID
    bRet = WTSQueryUserToken(dwSessionId, &currentToken);
    if (bRet == false)
    {
		MyDbgPrint("WTSQueryUserToken false Err=%d", GetLastError() );
        return;
    }

    bRet = DuplicateTokenEx(currentToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, NULL, SecurityImpersonation, TokenPrimary, &primaryToken);
    if (bRet == false)
    {
		MyDbgPrint("DuplicateTokenEx false Err=%d", GetLastError() );
	    CloseHandle(currentToken);
        return;
    }
    CloseHandle(currentToken);

    // Start the process on behalf of the current user
	if (strlen(szWorkDir) == 0) {
		bRet = CreateProcessAsUser(primaryToken, NULL, szProcessName, NULL, NULL, FALSE,
					CREATE_NEW_PROCESS_GROUP, NULL, NULL, &siStartInfo, &piProcInfo);
	} else {
		strcpy(szCommandLine, szWorkDir);
		strcat(szCommandLine,"\\");
		strcat(szCommandLine, szProcessName);
		bRet = CreateProcessAsUser(primaryToken, NULL, szCommandLine, NULL, NULL, FALSE,
					CREATE_NEW_PROCESS_GROUP ,NULL, szWorkDir, &siStartInfo, &piProcInfo);
	}
	// vZX̎s
	if(bRet)
	{
		// svZX̃nhԂB
		CloseHandle(piProcInfo.hThread) ;
		CloseHandle(piProcInfo.hProcess) ;
	}
	else
	{
		MyDbgPrint("CreateProcessAsUser() ret=%d, Err=%d", bRet, GetLastError());
	}
    CloseHandle(primaryToken);

}