Exemplo n.º 1
0
void CResourceCompilerHelper::GetEditorExecutable(SettingsManagerHelpers::CWCharBuffer wbuffer)
{
	if (wbuffer.getSizeInElements() <= 0)
	{
		return;
	}

	g_pSettingsManager->GetRootPathUtf16(wbuffer);

	SettingsManagerHelpers::CFixedString<wchar_t, 1024> editorExe;
	editorExe = wbuffer.getPtr();

	if (editorExe.length() <= 0)
	{
		MessageBoxA(NULL, "Can't Find the Editor.\nPlease, setup correct CryENGINE root path in the engine settings dialog", "Error", MB_ICONERROR | MB_OK);
		ResourceCompilerUI(0);
		g_pSettingsManager->GetRootPathUtf16(wbuffer);
		editorExe = wbuffer.getPtr();

		if (editorExe.length() <= 0)
		{
			wbuffer[0] = 0;
			return;
		}
	}

	g_pSettingsManager->GetValueByRef("EDT_Prefer32Bit", wbuffer);
	if (wcscmp(wbuffer.getPtr(), L"true") == 0)
	{
		editorExe.appendAscii("/Bin32/Editor.exe");
	}
	else
	{
		editorExe.appendAscii("/Bin64/Editor.exe");
	}

	const size_t sizeToCopy = (editorExe.length() + 1) * sizeof(wbuffer[0]);
	if (sizeToCopy > wbuffer.getSizeInBytes())
	{
		wbuffer[0] = 0;
	}
	else
	{
		memcpy(wbuffer.getPtr(), editorExe.c_str(), sizeToCopy);
	}
}
Exemplo n.º 2
0
bool CResourceCompilerHelper::InvokeResourceCompiler( const char *szSrcFile, const bool bWindow ) const
{
	bool bRet = true;

	// make command for execution

	wchar_t wMasterCDDir[512];
	GetCurrentDirectoryW(512,wMasterCDDir);

	SettingsManagerHelpers::CFixedString<wchar_t, 512> wRemoteCmdLine;
	SettingsManagerHelpers::CFixedString<wchar_t, 512> wDir;

	wRemoteCmdLine.appendAscii("Bin32/rc/");
	wRemoteCmdLine.appendAscii(RC_EXECUTABLE);
	wRemoteCmdLine.appendAscii(" \"");
	wRemoteCmdLine.append(wMasterCDDir);
	wRemoteCmdLine.appendAscii("\\");
	wRemoteCmdLine.appendAscii(szSrcFile);
	wRemoteCmdLine.appendAscii("\" /userdialog=0");

	wDir.append(wMasterCDDir);
	wDir.appendAscii("\\Bin32\\rc");

	STARTUPINFOW si;
	ZeroMemory( &si, sizeof(si) );
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	si.dwFlags = STARTF_USEPOSITION;

	PROCESS_INFORMATION pi;
	ZeroMemory( &pi, sizeof(pi) );

	if (!CreateProcessW( 
		NULL,     // No module name (use command line). 
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line. 
		NULL,     // Process handle not inheritable. 
		NULL,     // Thread handle not inheritable. 
		FALSE,    // Set handle inheritance to FALSE. 
		bWindow?0:CREATE_NO_WINDOW,	// creation flags. 
		NULL,     // Use parent's environment block. 
		wDir.c_str(),  // Set starting directory. 
		&si,      // Pointer to STARTUPINFO structure.
		&pi))     // Pointer to PROCESS_INFORMATION structure.
	{
		bRet = false;
	}

	// Wait until child process exits.
	WaitForSingleObject( pi.hProcess, INFINITE );

	// Close process and thread handles. 
	CloseHandle( pi.hProcess );
	CloseHandle( pi.hThread );

	return bRet;
}
ERcExitCode CResourceCompilerHelper::InvokeResourceCompiler(const char* szSrcFilePath, const char* szDstFilePath, const bool bUserDialog) 
{
	const char* szAdjustedFilename = szSrcFilePath;
#if defined(USE_GAMESTREAM)
	char szFullSrcPathBuf[ICryPak::g_nMaxPath];
	if (gEnv && gEnv->pGameStream)
	{
		szAdjustedFilename = gEnv->pCryPak->AdjustFileName(szSrcFilePath, szFullSrcPathBuf, ICryPak::FLAGS_RESOLVE_TO_CACHE);
	}
#endif

	ERcExitCode eRet = eRcExitCode_Pending;

	// make command for execution
	wchar_t szProjectDir[512];
	GetCurrentDirectoryW(sizeof(szProjectDir) / sizeof(szProjectDir[0]), szProjectDir);

	SettingsManagerHelpers::CFixedString<wchar_t, 512> wRemoteCmdLine;
	SettingsManagerHelpers::CFixedString<wchar_t, 512> wDir;
	CSettingsManagerTools smTools = CSettingsManagerTools();

	const char* const szRcParentDir =
		(smTools.Is64bitWindows() && (DirectoryExists(L"Bin64/rc") || !DirectoryExists(L"Bin32/rc")))
		? "Bin64" 
		: "Bin32";

	wchar_t szRegSettingsBuffer[1024];
	smTools.GetEngineSettingsManager()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(szRegSettingsBuffer, sizeof(szRegSettingsBuffer)));

	wRemoteCmdLine.appendAscii(szRcParentDir);
	wRemoteCmdLine.appendAscii("/rc/");
	wRemoteCmdLine.appendAscii(RC_EXECUTABLE);
	wRemoteCmdLine.appendAscii(" \"");
	wRemoteCmdLine.append(szProjectDir);
	wRemoteCmdLine.appendAscii("\\");
	wRemoteCmdLine.appendAscii(szAdjustedFilename);
	wRemoteCmdLine.appendAscii("\" /userdialog=0 ");
	wRemoteCmdLine.append(szRegSettingsBuffer);

	// make it write to a filename of our choice
	char szDstFilename[512];
	char szDstPath[512];

	RemovePath(szDstFilePath, szDstFilename, 512);
	RemoveFilename(szDstFilePath, szDstPath, 512);

	wRemoteCmdLine.appendAscii(" /overwritefilename=\"");
	wRemoteCmdLine.appendAscii(szDstFilename);
	wRemoteCmdLine.appendAscii("\"");
	wRemoteCmdLine.appendAscii(" /targetroot=\"");
	wRemoteCmdLine.append(szProjectDir);
	wRemoteCmdLine.appendAscii("\\");
	wRemoteCmdLine.appendAscii(szDstPath);
	wRemoteCmdLine.appendAscii("\"");

	wDir.append(szProjectDir);
	wDir.appendAscii("\\");
	wDir.appendAscii(szRcParentDir);
	wDir.appendAscii("\\rc");

	STARTUPINFOW si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	si.dwFlags = STARTF_USEPOSITION;

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

#if defined(DEBUG) && !defined(NDEBUG) && defined(_RENDERER)
	extern ILog *iLog;

	char tmp1[512];
	char tmp2[512];
	SettingsManagerHelpers::CCharBuffer dst1(tmp1, 512); SettingsManagerHelpers::ConvertUtf16ToUtf8(wDir.c_str(), dst1);
	SettingsManagerHelpers::CCharBuffer dst2(tmp2, 512); SettingsManagerHelpers::ConvertUtf16ToUtf8(wRemoteCmdLine.c_str(), dst2);

	iLog->Log("Debug: RC: dir \"%s\", cmd \"%s\"\n", tmp1, tmp2);
#endif

	if (!CreateProcessW( 
		NULL,     // No module name (use command line). 
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line. 
		NULL,     // Process handle not inheritable. 
		NULL,     // Thread handle not inheritable. 
		FALSE,    // Set handle inheritance to FALSE. 
		BELOW_NORMAL_PRIORITY_CLASS + (bUserDialog ? 0 : CREATE_NO_WINDOW),	// creation flags. 
		NULL,     // Use parent's environment block. 
		wDir.c_str(),  // Set starting directory. 
		&si,      // Pointer to STARTUPINFO structure.
		&pi))     // Pointer to PROCESS_INFORMATION structure.
	{
		eRet = eRcExitCode_FatalError;
	}
	else
	{
		// Wait until child process exits.
		WaitForSingleObject(pi.hProcess, INFINITE);

		DWORD exitCode;
		if (GetExitCodeProcess(pi.hProcess, &exitCode) == 0)
		{
			eRet = eRcExitCode_Error;
		}
		else
		{
			eRet = (ERcExitCode)exitCode;
		}
	}

	// Close process and thread handles. 
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	return eRet;
}
void* CResourceCompilerHelper::AsyncCallResourceCompiler(
	const char* szFileName, 
	const char* szAdditionalSettings, 
	bool bMayShowWindow, 
	CResourceCompilerHelper::ERcExePath rcExePath, 
	bool bSilent,
	bool bNoUserDialog,
	const wchar_t* szWorkingDirectory,
	const wchar_t* szRootPath)
{
	// make command for execution
	SettingsManagerHelpers::CFixedString<wchar_t, MAX_PATH * 3> wRemoteCmdLine;
	CSettingsManagerTools smTools = CSettingsManagerTools();

	if (!szAdditionalSettings)
	{
		szAdditionalSettings = "";
	}

	wchar_t szRcDirectory[512];
	{
		wchar_t pathBuffer[512];
		switch (rcExePath)
		{
		case eRcExePath_registry:
			smTools.GetRootPathUtf16(true, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_settingsManager:
			smTools.GetRootPathUtf16(false, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_currentFolder:
			wcscpy(pathBuffer, L".");
			break;
		case eRcExePath_customPath:
			wcscpy(pathBuffer, szRootPath);
			break;
		default:
			return NULL;
		}

		if (!pathBuffer[0])
		{
			wcscpy(pathBuffer, L".");
		}

		if (smTools.Is64bitWindows() && (DirectoryExists(pathBuffer, L"/Bin64/rc") || !DirectoryExists(pathBuffer, L"/Bin32/rc")))
		{
			swprintf_s(szRcDirectory, L"%s/Bin64/rc", pathBuffer);
		}
		else
		{
			swprintf_s(szRcDirectory, L"%s/Bin32/rc", pathBuffer);
		}
	}

	wchar_t szRegSettingsBuffer[1024];
	smTools.GetEngineSettingsManager()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(szRegSettingsBuffer, sizeof(szRegSettingsBuffer)));

	wRemoteCmdLine.appendAscii("\"");
	wRemoteCmdLine.append(szRcDirectory);
	wRemoteCmdLine.appendAscii("/");
	wRemoteCmdLine.appendAscii(RC_EXECUTABLE);	
	wRemoteCmdLine.appendAscii("\"");

	if (!szFileName)
	{
		wRemoteCmdLine.appendAscii(" /userdialog=0 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
		wRemoteCmdLine.appendAscii(" ");
		wRemoteCmdLine.append(szRegSettingsBuffer);
	}
	else
	{
		wRemoteCmdLine.appendAscii(" \"");
		wRemoteCmdLine.appendAscii(szFileName);
		wRemoteCmdLine.appendAscii("\"");
		wRemoteCmdLine.appendAscii(bNoUserDialog ? " /userdialog=0 " : " /userdialog=1 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
		wRemoteCmdLine.appendAscii(" ");
		wRemoteCmdLine.append(szRegSettingsBuffer);
	}

	STARTUPINFOW si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	si.dwFlags = STARTF_USEPOSITION;

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	bool bShowWindow;
	if (bMayShowWindow)
	{
		wchar_t buffer[20];
		smTools.GetEngineSettingsManager()->GetValueByRef("ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)));
		bShowWindow = (wcscmp(buffer, L"true") == 0);
	}
	else
	{
		bShowWindow = false;
	}

	const wchar_t* const szStartingDirectory = szWorkingDirectory ? szWorkingDirectory : szRcDirectory;

	if (!CreateProcessW(
		NULL,                   // No module name (use command line).
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line.
		NULL,                   // Process handle not inheritable.
		NULL,                   // Thread handle not inheritable.
		TRUE,                   // Set handle inheritance to TRUE.
		bShowWindow ? 0 : CREATE_NO_WINDOW, // creation flags.
		NULL,                   // Use parent's environment block.
		szStartingDirectory,    // Set starting directory.
		&si,                    // Pointer to STARTUPINFO structure.
		&pi))                   // Pointer to PROCESS_INFORMATION structure.
	{
		if (!bSilent)
		{
			ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szStartingDirectory);
		}
		return NULL;
	}

	return pi.hProcess;
}
CResourceCompilerHelper::ERcCallResult CResourceCompilerHelper::CallResourceCompiler(
	const char* szFileName, 
	const char* szAdditionalSettings, 
	IResourceCompilerListener* listener, 
	bool bMayShowWindow, 
	CResourceCompilerHelper::ERcExePath rcExePath, 
	bool bSilent,
	bool bNoUserDialog,
	const wchar_t* szWorkingDirectory,
	const wchar_t* szRootPath)
{
	// make command for execution
	SettingsManagerHelpers::CFixedString<wchar_t, MAX_PATH * 3> wRemoteCmdLine;
	CSettingsManagerTools smTools = CSettingsManagerTools();

	if (!szAdditionalSettings)
	{
		szAdditionalSettings = "";
	}

	wchar_t szRcDirectory[512];
	{
		wchar_t pathBuffer[512];
		switch (rcExePath)
		{
		case eRcExePath_registry:
			smTools.GetRootPathUtf16(true, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_settingsManager:
			smTools.GetRootPathUtf16(false, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_currentFolder:
			wcscpy(pathBuffer, L".");
			break;
		case eRcExePath_customPath:
			wcscpy(pathBuffer, szRootPath);
			break;
		default:
			return eRcCallResult_notFound;
		}

		if (!pathBuffer[0])
		{
			wcscpy(pathBuffer, L".");
		}

		if (smTools.Is64bitWindows() && (DirectoryExists(pathBuffer, L"/Bin64/rc") || !DirectoryExists(pathBuffer, L"/Bin32/rc")))
		{
			swprintf_s(szRcDirectory, L"%s/Bin64/rc", pathBuffer);
		}
		else
		{
			swprintf_s(szRcDirectory, L"%s/Bin32/rc", pathBuffer);
		}
	}

	wchar_t szRegSettingsBuffer[1024];
	smTools.GetEngineSettingsManager()->GetValueByRef("RC_Parameters", SettingsManagerHelpers::CWCharBuffer(szRegSettingsBuffer, sizeof(szRegSettingsBuffer)));

	wRemoteCmdLine.appendAscii("\"");
	wRemoteCmdLine.append(szRcDirectory);
	wRemoteCmdLine.appendAscii("/");
	wRemoteCmdLine.appendAscii(RC_EXECUTABLE);	
	wRemoteCmdLine.appendAscii("\"");

	if (!szFileName)
	{
		wRemoteCmdLine.appendAscii(" /userdialog=0 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
		wRemoteCmdLine.appendAscii(" ");
		wRemoteCmdLine.append(szRegSettingsBuffer);
	}
	else
	{
		wRemoteCmdLine.appendAscii(" \"");
		wRemoteCmdLine.appendAscii(szFileName);
		wRemoteCmdLine.appendAscii("\"");
		wRemoteCmdLine.appendAscii(bNoUserDialog ? " /userdialog=0 " : " /userdialog=1 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
		wRemoteCmdLine.appendAscii(" ");
		wRemoteCmdLine.append(szRegSettingsBuffer);
	}

	// Create a pipe to read the stdout of the RC.
	SECURITY_ATTRIBUTES saAttr;
	HANDLE hChildStdOutRd, hChildStdOutWr;
	HANDLE hChildStdInRd, hChildStdInWr;
	if (listener)
	{
		ZeroMemory(&saAttr, sizeof(saAttr));
		saAttr.bInheritHandle = TRUE;
		saAttr.lpSecurityDescriptor = 0;
		CreatePipe(&hChildStdOutRd, &hChildStdOutWr, &saAttr, 0);
		SetHandleInformation(hChildStdOutRd, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN
		CreatePipe(&hChildStdInRd, &hChildStdInWr, &saAttr, 0);
		SetHandleInformation(hChildStdInWr, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN
	}

	STARTUPINFOW si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	if (listener)
	{
		si.hStdError = hChildStdOutWr;
		si.hStdOutput = hChildStdOutWr;
		si.hStdInput = hChildStdInRd;
		si.dwFlags = STARTF_USEPOSITION | STARTF_USESTDHANDLES;
	}
	else
	{
		si.dwFlags = STARTF_USEPOSITION;
	}

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	bool bShowWindow;
	if (bMayShowWindow)
	{
		wchar_t buffer[20];
		smTools.GetEngineSettingsManager()->GetValueByRef("ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)));
		bShowWindow = (wcscmp(buffer, L"true") == 0);
	}
	else
	{
		bShowWindow = false;
	}

	const wchar_t* const szStartingDirectory = szWorkingDirectory ? szWorkingDirectory : szRcDirectory;

	if (!CreateProcessW(
		NULL,                   // No module name (use command line).
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line.
		NULL,                   // Process handle not inheritable.
		NULL,                   // Thread handle not inheritable.
		TRUE,                   // Set handle inheritance to TRUE.
		bShowWindow ? 0 : CREATE_NO_WINDOW, // creation flags.
		NULL,                   // Use parent's environment block.
		szStartingDirectory,    // Set starting directory.
		&si,                    // Pointer to STARTUPINFO structure.
		&pi))                   // Pointer to PROCESS_INFORMATION structure.
	{
		// The following  code block is commented out instead of being deleted 
		// because it's good to have at hand for a debugging session.







		if (!bSilent)
		{
			ShowMessageBoxRcNotFound(wRemoteCmdLine.c_str(), szStartingDirectory);
		}

		return eRcCallResult_notFound;
	}

	bool bFailedToReadOutput = false;

	if (listener)
	{
		// Close the pipe that writes to the child process, since we don't actually have any input for it.
		CloseHandle(hChildStdInWr);

		// Read all the output from the child process.
		CloseHandle(hChildStdOutWr);
		ResourceCompilerLineHandler lineHandler(listener);
		LineStreamBuffer lineBuffer(&lineHandler, &ResourceCompilerLineHandler::HandleLine);
		for (;;)
		{
			char buffer[2048];
			DWORD bytesRead;
			if (!ReadFile(hChildStdOutRd, buffer, sizeof(buffer), &bytesRead, NULL) || (bytesRead == 0))
			{
				break;
			}
			lineBuffer.HandleText(buffer, bytesRead);
		} 

		bFailedToReadOutput = lineBuffer.IsTruncated();
	}

	// Wait until child process exits.
	WaitForSingleObject(pi.hProcess, INFINITE);

	DWORD exitCode = eRcExitCode_Error;
	if (bFailedToReadOutput || GetExitCodeProcess(pi.hProcess, &exitCode) == 0)
	{
		exitCode = eRcExitCode_Error;
	}

	// Close process and thread handles. 
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	switch (exitCode)
	{
	case eRcExitCode_Success:
	case eRcExitCode_UserFixing:
		return eRcCallResult_success;
	case eRcExitCode_Crash:
		return eRcCallResult_crash;
	default:
		return eRcCallResult_error;
	}
}
Exemplo n.º 6
0
void* CResourceCompilerHelper::AsyncCallResourceCompiler(
	const char* szFileName, 
	const char* szAdditionalSettings, 
	bool bMayShowWindow, 
	CResourceCompilerHelper::ERcExePath rcExePath, 
	bool bSilent,
	bool bNoUserDialog,
	const wchar_t* szWorkingDirectory,
	const wchar_t* szRootPath)
{
	// make command for execution
	SettingsManagerHelpers::CFixedString<wchar_t, MAX_PATH*3> wRemoteCmdLine;

	if (!szAdditionalSettings)
	{
		szAdditionalSettings = "";
	}

	wchar_t szRemoteDirectory[512];
	{
		wchar_t pathBuffer[512];
		switch (rcExePath)
		{
		case eRcExePath_registry:
			GetRootPathUtf16(true, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_settingsManager:
			GetRootPathUtf16(false, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_currentFolder:
			wcscpy(pathBuffer, L".");
			break;
		case eRcExePath_customPath:
			wcscpy(pathBuffer, szRootPath);
			break;
		default:
			return NULL;
		}

		if (!pathBuffer[0])
		{
			wcscpy(pathBuffer, L".");
		}

		swprintf_s(szRemoteDirectory, L"%s/Bin32/rc", pathBuffer);
	}

	if (!szFileName)
	{
		wRemoteCmdLine.appendAscii("\"");
		wRemoteCmdLine.append(szRemoteDirectory);
		wRemoteCmdLine.appendAscii("/rc.exe\" /userdialog=0 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
	}
	else
	{
		wRemoteCmdLine.appendAscii("\"");
		wRemoteCmdLine.append(szRemoteDirectory);
		wRemoteCmdLine.appendAscii("/rc.exe\" \"");
		wRemoteCmdLine.appendAscii(szFileName);
		wRemoteCmdLine.appendAscii("\" ");
		wRemoteCmdLine.appendAscii(bNoUserDialog ? "/userdialog=0 " : "/userdialog=1 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
	}

	STARTUPINFOW si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	si.dwFlags = STARTF_USEPOSITION;

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	bool bShowWindow = false;
	{
		wchar_t buffer[20];
		g_pSettingsManager->GetValueByRef("ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)));
		bShowWindow = (wcscmp(buffer, L"true") == 0);
	}

	if (!CreateProcessW(
		NULL,                   // No module name (use command line).
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line.
		NULL,                   // Process handle not inheritable.
		NULL,                   // Thread handle not inheritable.
		TRUE,                   // Set handle inheritance to TRUE.
		(bMayShowWindow && bShowWindow) ? 0  : CREATE_NO_WINDOW, // creation flags.
		NULL,                   // Use parent's environment block.
		szWorkingDirectory?szWorkingDirectory:szRemoteDirectory,  // Set starting directory.
		&si,                    // Pointer to STARTUPINFO structure.
		&pi ))                  // Pointer to PROCESS_INFORMATION structure.
	{
		if (!bSilent)
		{
			MessageBoxA(0, "ResourceCompiler was not found.\n\nPlease verify CryENGINE RootPath.", "Error", MB_ICONERROR|MB_OK);
		}

		return NULL;
	}

	return pi.hProcess;
}
Exemplo n.º 7
0
CResourceCompilerHelper::ERcCallResult CResourceCompilerHelper::CallResourceCompiler(
	const char* szFileName, 
	const char* szAdditionalSettings, 
	IResourceCompilerListener* listener, 
	bool bMayShowWindow, 
	CResourceCompilerHelper::ERcExePath rcExePath, 
	bool bSilent,
	bool bNoUserDialog,
	const wchar_t* szWorkingDirectory,
	const wchar_t* szRootPath)
{
	// make command for execution
	SettingsManagerHelpers::CFixedString<wchar_t, MAX_PATH*3> wRemoteCmdLine;

	if (!szAdditionalSettings)
	{
		szAdditionalSettings = "";
	}

	wchar_t szRemoteDirectory[512];
	{
		wchar_t pathBuffer[512];
		switch (rcExePath)
		{
		case eRcExePath_registry:
			GetRootPathUtf16(true, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_settingsManager:
			GetRootPathUtf16(false, SettingsManagerHelpers::CWCharBuffer(pathBuffer, sizeof(pathBuffer)));
			break;
		case eRcExePath_currentFolder:
			wcscpy(pathBuffer, L".");
			break;
		case eRcExePath_customPath:
			wcscpy(pathBuffer, szRootPath);
			break;
		default:
			return eRcCallResult_notFound;
		}

		if (!pathBuffer[0])
		{
			wcscpy(pathBuffer, L".");
		}

		swprintf_s(szRemoteDirectory, L"%s/Bin32/rc", pathBuffer);
	}

	if (!szFileName)
	{
		wRemoteCmdLine.appendAscii("\"");
		wRemoteCmdLine.append(szRemoteDirectory);
		wRemoteCmdLine.appendAscii("/rc.exe\" /userdialog=0 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
	}
	else
	{
		wRemoteCmdLine.appendAscii("\"");
		wRemoteCmdLine.append(szRemoteDirectory);
		wRemoteCmdLine.appendAscii("/rc.exe\" \"");
		wRemoteCmdLine.appendAscii(szFileName);
		wRemoteCmdLine.appendAscii("\" ");
		wRemoteCmdLine.appendAscii(bNoUserDialog ? "/userdialog=0 " : "/userdialog=1 ");
		wRemoteCmdLine.appendAscii(szAdditionalSettings);
	}

	// Create a pipe to read the stdout of the RC.
	SECURITY_ATTRIBUTES saAttr;
	::memset(&saAttr, 0, sizeof(saAttr));
	saAttr.bInheritHandle = TRUE;
	saAttr.lpSecurityDescriptor = 0;
	HANDLE hChildStdOutRd, hChildStdOutWr;
	CreatePipe(&hChildStdOutRd, &hChildStdOutWr, &saAttr, 0);
	SetHandleInformation(hChildStdOutRd, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN
	HANDLE hChildStdInRd, hChildStdInWr;
	CreatePipe(&hChildStdInRd, &hChildStdInWr, &saAttr, 0);
	SetHandleInformation(hChildStdInWr, HANDLE_FLAG_INHERIT, 0); // Need to do this according to MSDN

	STARTUPINFOW si;
	ZeroMemory(&si, sizeof(si));
	si.cb = sizeof(si);
	si.dwX = 100;
	si.dwY = 100;
	si.hStdError = hChildStdOutWr;
	si.hStdOutput = hChildStdOutWr;
	si.hStdInput = hChildStdInRd;
	si.dwFlags = STARTF_USEPOSITION | STARTF_USESTDHANDLES;

	PROCESS_INFORMATION pi;
	ZeroMemory(&pi, sizeof(pi));

	bool bShowWindow = false;
	{
		wchar_t buffer[20];
		g_pSettingsManager->GetValueByRef("ShowWindow", SettingsManagerHelpers::CWCharBuffer(buffer, sizeof(buffer)));
		bShowWindow = (wcscmp(buffer, L"true") == 0);
	}

	if (!CreateProcessW(
		NULL,                   // No module name (use command line).
		const_cast<wchar_t*>(wRemoteCmdLine.c_str()), // Command line.
		NULL,                   // Process handle not inheritable.
		NULL,                   // Thread handle not inheritable.
		TRUE,                   // Set handle inheritance to TRUE.
		(bMayShowWindow && bShowWindow) ? 0  : CREATE_NO_WINDOW, // creation flags.
		NULL,                   // Use parent's environment block.
		szWorkingDirectory?szWorkingDirectory:szRemoteDirectory,  // Set starting directory.
		&si,                    // Pointer to STARTUPINFO structure.
		&pi ))                  // Pointer to PROCESS_INFORMATION structure.
	{
		/*
		This code block is commented out instead of being deleted because it's
		good to have at hand for a debugging session.

		const size_t charsInMessageBuffer = 32768;   // msdn about FormatMessage(): "The output buffer cannot be larger than 64K bytes."
		wchar_t szMessageBuffer[charsInMessageBuffer] = L"";   
		FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), 0, szMessageBuffer, charsInMessageBuffer, NULL);
		GetCurrentDirectoryW(charsInMessageBuffer, szMessageBuffer);
		*/

		if (!bSilent)
		{
			MessageBoxA(0, "ResourceCompiler was not found.\n\nPlease verify CryENGINE RootPath.", "Error", MB_ICONERROR|MB_OK);
		}

		return eRcCallResult_notFound;
	}

	// Close the pipe that writes to the child process, since we don't actually have any input for it.
	CloseHandle(hChildStdInWr);

	// Read all the output from the child process.
	CloseHandle(hChildStdOutWr);
	ResourceCompilerLineHandler lineHandler(listener);
	LineStreamBuffer lineBuffer(&lineHandler, &ResourceCompilerLineHandler::HandleLine);
	for (;;)
	{
		char buffer[2048];
		DWORD bytesRead;
		if (!ReadFile(hChildStdOutRd, buffer, sizeof(buffer), &bytesRead, NULL) || (bytesRead == 0))
		{
			break;
		}
		lineBuffer.HandleText(buffer, bytesRead);
	} 

	// Wait until child process exits.
	WaitForSingleObject(pi.hProcess, INFINITE);

	bool ok = true;
	DWORD exitCode = 1;
	{
		if ((GetExitCodeProcess(pi.hProcess, &exitCode) == 0) || (exitCode != 0))
		{
			ok = false;
		}	
	}

	// Close process and thread handles. 
	CloseHandle(pi.hProcess);
	CloseHandle(pi.hThread);

	if (exitCode == eRcExitCode_Crash)
	{
		return eRcCallResult_crash;
	}

	if (lineBuffer.IsTruncated())
	{
		return eRcCallResult_error;
	}

	return ok ? eRcCallResult_success : eRcCallResult_error;
}