HRESULT STDMETHODCALLTYPE CDriveContextMenu::InvokeCommand(/* [in] */ __in CMINVOKECOMMANDINFO *pici)
{
	WINCDEMU_LOG_LINE(L"CDriveContextMenu::InvokeCommand()");

	if (!pici)
		return E_NOTIMPL;

	extern HINSTANCE g_hModule;
	TCHAR tszPath[MAX_PATH];
	GetModuleFileName(g_hModule, tszPath, _countof(tszPath));
	BazisLib::String path = String::sFormat(L"%s\\%s", BazisLib::Path::GetDirectoryName(BazisLib::Path::GetDirectoryName(String(tszPath))).c_str(), VMNT_EXE_W);

	switch ((int)pici->lpVerb)
	{
	case IDM_CREATEISO:
		ShellExecute(pici->hwnd, _T("open"), path.c_str(), String::sFormat(L"/createiso %s", m_FileName.c_str()).c_str(), NULL, pici->nShow);
		break;
	case IDM_CHANGEIMAGE:
		ShellExecute(pici->hwnd, _T("open"), path.c_str(), String::sFormat(L"/remount:%c", m_FileName[0]).c_str(), NULL, pici->nShow);
		break;
	case IDM_BUILDISO:
		ShellExecute(pici->hwnd, _T("open"), path.c_str(), String::sFormat(L"/isofromfolder \"%s\"", m_FileName.c_str()).c_str(), NULL, pici->nShow);
		break;
	default:
		return E_FAIL;
	}

	return S_OK;
}
Пример #2
0
bool LocalizableStringManager::ProduceHeaderFile( const BazisLib::String &fp )
{
	File file(fp, FileModes::CreateOrTruncateRW);
	if (!file.Valid())
	{
		_tprintf(_T("ERROR: cannot open %s for writing\n"), fp.c_str());
		return false;
	}
	file.WriteLine(DynamicStringA("#pragma once\r\n//Generated by BazisLib STRGEN.EXE, http://bazislib.sysprogs.org/\r\n\r\n#include<bzshlp/Win32/i18n.h>\r\n#ifndef BAZISLIB_FIRST_LOCALIZABLE_STRING_ID\r\n#define BAZISLIB_FIRST_LOCALIZABLE_STRING_ID 0x1000\r\n#endif\r\n"));
	unsigned id = 0;
	DynamicStringA definitionLine;

	unsigned maxIdLen = 0;

	for each(const std::map<BazisLib::String, StringRecord>::value_type &pair in m_Strings)
		if (pair.first.length() > maxIdLen)
			maxIdLen = pair.first.length();

	DynamicStringA maxSpacing;
	maxSpacing.insert(0, maxIdLen, ' ');

	for each(const std::map<BazisLib::String, StringRecord>::value_type &pair in m_Strings)
	{
		const char *pSpacing = maxSpacing.c_str() + pair.first.length();
		definitionLine.Format("#define %s  %s(BAZISLIB_FIRST_LOCALIZABLE_STRING_ID + 0x%04X)", StringToANSIString(pair.first).c_str(), pSpacing, id++);
		file.WriteLine(definitionLine);
	}

	definitionLine.Format("\r\n#define BAZISLIB_LAST_LOCALIZABLE_STRING_ID \t(BAZISLIB_FIRST_LOCALIZABLE_STRING_ID + 0x%04X)", id - 1);
	file.WriteLine(definitionLine);

	return true;
}
Пример #3
0
void DeleteFiles(BazisLib::String path)
{
	TCHAR tsz[MAX_PATH] = {0,};
	GetModuleFileName(GetModuleHandle(NULL), tsz, sizeof(tsz)/sizeof(tsz[0]));
	TCHAR *p = _tcsrchr(tsz, '\\');
	if (!p)
		return;
	p[0] = 0;
	if (path.empty())
		path = tsz;

	RemoveTreeRecursive((Path::Combine(path, _T("x86"))).c_str());
	RemoveTreeRecursive((Path::Combine(path, _T("x64"))).c_str());
	RemoveTreeRecursive((Path::Combine(path, _T("langfiles"))).c_str());
	File::Delete(Path::Combine(path, _T("vmnt.exe")));
	File::Delete(Path::Combine(path, _T("vmnt64.exe")));
	File::Delete(Path::Combine(path, _T("batchmnt.exe")));
	File::Delete(Path::Combine(path, _T("batchmnt64.exe")));
	File::Delete(Path::Combine(path, _T("BazisVirtualCD.inf")));
	File::Delete(Path::Combine(path, _T("VirtDiskBus.inf")));
	File::Delete(Path::Combine(path, _T("BazisVirtualCDBus.inf")));
	File::Delete(Path::Combine(path, _T("BazisVirtualCD.cat")));
	File::Delete(Path::Combine(path, _T("VirtDiskBus.cat")));
	File::Delete(Path::Combine(path, _T("BazisVirtualCDBus.cat")));
	File::Delete(Path::Combine(path, _T("uninstall.exe")));
	File::Delete(Path::Combine(path, _T("uninstall64.exe")));
	Directory::Remove(path);
	p[0] = '\\';
	MoveFileEx(tsz, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
}
Пример #4
0
HRESULT StartRevertingCurrentVMToLastSnapshot()
{
	TCHAR tszDll[MAX_PATH];
	GetModuleFileName(g_hThisDll, tszDll, _countof(tszDll));

	BazisLib::String machineID = VBoxCmdLineToMachineID(GetCommandLineW()); 

	BazisLib::Win32::Process process(BazisLib::String::sFormat(L"rundll32 \"%s\",VMSnapshotRevertingEntry --startvm %s", tszDll, machineID.c_str()).c_str(), (WORD)SW_SHOW);
	return S_OK;
}
Пример #5
0
unsigned SessionNameFromVMCmdLineW(const RemoteProcessInfo &info, wchar_t *pName, size_t MaxNameLength)
{
	int argc = 0;
	LPWSTR *pArgs = CommandLineToArgvW(info.CommandLine.c_str(), &argc);
	if (!pArgs)
		return 0;

	BazisLib::String exeName;

	if (argc && pArgs[0])
		exeName = pArgs[0];

	LocalFree(pArgs);
	pArgs = NULL;

	if (wcsstr(exeName.c_str(), L"vmware-vmx.exe") || wcsstr(exeName.c_str(), L"vmware-vmx-debug.exe") || wcsstr(exeName.c_str(), L"vmware-vmx-stats.exe"))
		return SessionNameFromVMWareCmdLineW(info.CommandLine.c_str(), pName, MaxNameLength);
	else if (wcsstr(exeName.c_str(), L"VirtualBox.exe"))
		return VBoxCmdLineToVMNameW(info, pName, MaxNameLength);
	else
		return 0;
}
Пример #6
0
BazisLib::String LocalizableStringManager::FormatStringASCString( const BazisLib::TempString &str )
{
	BazisLib::String result;
	result.reserve(str.length());
	for (size_t i = 0; i < str.length(); i++)
	{
		if (str[i] == '\\')
			result.append(_T("\\\\"));
		else if (str[i] == '\'')
			result.append(_T("\\\'"));
		else if (str[i] == '\"')
			result.append(_T("\\\""));
		else if (str[i] == '\t')
			result.append(_T("\\\t"));
		else if (str[i] == '\r')
			result.append(_T("\\\r"));
		else if (str[i] == '\n')
			result.append(_T("\\\n"));
		else
			result.append(1, str[i]);
	}
	return result;
}
Пример #7
0
bool LocalizableStringManager::ProduceIDTableFile( const BazisLib::String &fp, const String &HeaderFileName )
{
	File file(fp, FileModes::CreateOrTruncateRW);
	if (!file.Valid())
	{
		_tprintf(_T("ERROR: cannot open %s for writing\n"), fp.c_str());
		return false;
	}
	DynamicStringA definitionLine;

	file.WriteLine(DynamicStringA("#include \"stdafx.h\"\r\n#include <bzshlp/Win32/i18n.h>"));
	definitionLine.Format("#include \"%s\"", StringToANSIString(HeaderFileName).c_str());
	file.WriteLine(definitionLine);
	file.WriteLine(DynamicStringA("//Generated by BazisLib STRGEN.EXE, http://bazislib.sysprogs.org/\r\n"));
	file.WriteLine(DynamicStringA("BazisLib::StringIDRecord g_StringIDs[] = {"));
	unsigned id = 0;

	unsigned maxIdLen = 0;

	for each(const std::map<BazisLib::String, StringRecord>::value_type &pair in m_Strings)
		if (pair.first.length() > maxIdLen)
			maxIdLen = pair.first.length();

	DynamicStringA maxSpacing;
	maxSpacing.insert(0, maxIdLen, ' ');

	for each(const std::map<BazisLib::String, StringRecord>::value_type &pair in m_Strings)
	{
		const char *pSpacing = maxSpacing.c_str() + pair.first.length();
		definitionLine.Format("\t{%s%s, _T(\"%s\")},", StringToANSIString(pair.first).c_str(), pSpacing, StringToANSIString(pair.first).c_str());
		file.WriteLine(definitionLine);
	}

	file.WriteLine(DynamicStringA("\t{0, NULL},\r\n};"));

	return true;
}
Пример #8
0
bool LocalizableStringManager::ProduceLanguageFile( const BazisLib::String &fp )
{
	File file(fp, FileModes::CreateOrTruncateRW);
	if (!file.Valid())
	{
		_tprintf(_T("ERROR: cannot open %s for writing\n"), fp.c_str());
		return false;
	}
#ifdef UNICODE
	unsigned short unicodeHeader = 0xFEFF;
	file.Write(&unicodeHeader, sizeof(unicodeHeader));
#endif
	//1033 == MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
	file.WriteLine(DynamicString(_T("; Generated by BazisLib STRGEN.EXE, http://bazislib.sysprogs.org/\r\n; Syntax: <ID> <spaces or tabs> <value>\r\n; <value> should be in C/C++ format (\\r, \\n, \\t, \\\", etc.) \r\n; Strings starting with '; ' will be ignored\r\n; WARNING! This file should always be UNICODE!\r\n")));
	file.WriteLine(DynamicString(_T("[settings]\r\nLanguage       English\r\nLANGID         1033\r\nLanguageEng    English\r\nTranslator     SysProgs\r\nE-Mail         [email protected]\r\n"))); 
	file.WriteLine(DynamicString(_T("[strings]"))); 

	unsigned maxIdLen = 0;

	for each(const std::map<BazisLib::String, StringRecord>::value_type &pair in m_Strings)
		if (pair.first.length() > maxIdLen)
			maxIdLen = pair.first.length();

	DynamicString definitionLine;
	DynamicString maxSpacing;
	maxSpacing.insert(0, maxIdLen, ' ');

	for each(const std::map<BazisLib::String, StringRecord>::value_type &pair in m_Strings)
	{
		const TCHAR *pSpacing = maxSpacing.c_str() + pair.first.length();
		definitionLine.Format(_T("%s%s   %s"), pair.first.c_str(), pSpacing, pair.second.Value.c_str());
		file.WriteLine(definitionLine);
	}

	return true;
}
Пример #9
0
int AppMain()
{
	int argc;
	LPCWSTR lpCmdLine = GetCommandLineW();
	LPWSTR *ppArgv = CommandLineToArgvW(lpCmdLine, &argc);
	LPCWSTR lpDiskPath = NULL;
	bool ShowSettingsDialog = false, ForceMountOptions = false, AdminModeOnNetworkShare = false;
	bool bDisableUAC = false;
	char DriveLetterToRemount = 0;
	BazisLib::String tmpString;

	for (int i = 1; i < argc; i++)
	{
		if (ppArgv[i][0] != '/')
		{
			if (!lpDiskPath)
				lpDiskPath = ppArgv[i];
		}
		else
		{
			if (!_wcsicmp(ppArgv[i], L"/settings"))
				ShowSettingsDialog = true;
			else if (!_wcsicmp(ppArgv[i], L"/ltrselect"))
				ForceMountOptions = true;
			else if (!_wcsicmp(ppArgv[i], L"/uac_on_network_share"))
				AdminModeOnNetworkShare = true;
			else if (!_wcsicmp(ppArgv[i], L"/uacdisable"))
				bDisableUAC = true;
			else if (!_wcsicmp(ppArgv[i], L"/createiso") || !_wcsicmp(ppArgv[i], L"/isofromfolder"))
			{
				if (argc < (i + 2))
				{
					MessageBox(HWND_DESKTOP, _TR(IDS_BADCMDLINE, "Invalid command line!"), NULL, MB_ICONERROR);
					return 1;
				}
				ActionStatus st;
				if (!_wcsicmp(ppArgv[i], L"/isofromfolder"))
				{
					wchar_t *pwszFolder = ppArgv[i + 1];
					if (pwszFolder[0] && pwszFolder[wcslen(pwszFolder) - 1] == '\"')
						pwszFolder[wcslen(pwszFolder) - 1] = '\\';

					st = BuildISOFromFolder(pwszFolder);
				}
				else
					st = CreateISOFile(ppArgv[i + 1]);

				if (!st.Successful() && st.GetErrorCode() != OperationAborted)
					MessageBox(HWND_DESKTOP, st.GetMostInformativeText().c_str(), NULL, MB_ICONERROR);
				return !st.Successful();
			}
			else if (!_wcsnicmp(ppArgv[i], L"/remount:", 9))
				DriveLetterToRemount = (char)ppArgv[i][9];
		}
	}

	if (bDisableUAC)
	{
		RegistryKey driverParametersKey(HKEY_LOCAL_MACHINE, _T("SYSTEM\\CurrentControlSet\\Services\\BazisVirtualCDBus\\Parameters"));
		int prevVal = driverParametersKey[_T("GrantAccessToEveryone")];
		int newVal = 1;
		driverParametersKey[_T("GrantAccessToEveryone")] = newVal;

		if (prevVal != newVal)
			VirtualCDClient::RestartDriver();

		return 0;
	}

	if (GetKeyState(VK_SHIFT) & (1 << 31))
		ForceMountOptions = true;

	if (!lpDiskPath && DriveLetterToRemount)
	{
		const TCHAR *pwszFilter = _TR(IDS_ISOFILTER, "ISO images (*.iso)|*.iso|All files (*.*)|*.*");
		TCHAR tszFilter[128] = { 0, };
		_tcsncpy(tszFilter, pwszFilter, _countof(tszFilter) - 1);
		for (size_t i = 0; i < _countof(tszFilter); i++)
		if (tszFilter[i] == '|')
			tszFilter[i] = '\0';

		CFileDialog dlg(true, _T("iso"), NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, tszFilter);
		dlg.m_ofn.lpstrTitle = _TR(IDS_MOUNTIMAGE, "Mount a disc image");

		if (dlg.DoModal() != IDOK)
			return 1;

		tmpString.assign(dlg.m_szFileName);
		lpDiskPath = tmpString.c_str();
	}

	if ((argc < 2) || !ppArgv || !lpDiskPath || ShowSettingsDialog)
	{
		return ::ShowSettingsDialog();
	}

	MMCProfile detectedProfile = mpInvalid;
	bool bFileOnNetworkShare = false;

	{
		TCHAR tszFullPath[MAX_PATH] = {0,};
		GetFullPathName(lpDiskPath, __countof(tszFullPath), tszFullPath, NULL);
		TCHAR tszRoot[4] = {tszFullPath[0], ':', '\\', 0};
		if (GetDriveType(tszRoot) == DRIVE_REMOTE)
			bFileOnNetworkShare = true;

		ImageFormatDatabase imageFormatDB;
		ManagedPointer<AIParsedCDImage> pImage = imageFormatDB.OpenCDImage(ManagedPointer<AIFile>(new ACFile(tszFullPath, FileModes::OpenReadOnly.ShareAll())), tszFullPath);
		if (!pImage)
		{
			if (AdminModeOnNetworkShare)
				MessageBox(HWND_DESKTOP, _TR(IDS_UACNETWORKWARNING, "Cannot open image file. To mount images from network drives, go to WinCDEmu settings and allow mounting drives without administrator privileges."), NULL, MB_ICONERROR);
			else
				MessageBox(HWND_DESKTOP, _TR(ISD_CORRUPTIMAGE, "Unknown or corrupt image file!"), NULL, MB_ICONERROR);
			return 1;
		}
		if (pImage->GetTrackCount() != 1)
			detectedProfile = mpCdrom;
		else
		{
			UDFAnalysisResult result = AnalyzeUDFImage(pImage);
			if (!result.isUDF)
				detectedProfile = mpInvalid;
			else if (result.foundBDMV)
				detectedProfile = mpBDRSequentialWritable;
			else if (result.foundVIDEO_TS)
				detectedProfile = mpDvdRecordable;
		}

		/*if ((detectedProfile == mpCdrom) || (detectedProfile == mpInvalid))
		{
			if (pImage->GetSectorCount() >= ((10LL * 1024LL * 1024LL * 1024LL / 2048)))
				detectedProfile = mpBDRSequentialWritable;
			else if (pImage->GetSectorCount() >= ((1LL * 1024LL * 1024LL * 1024LL / 2048)))
				detectedProfile = mpDvdRecordable;
		}*/
	}

	wchar_t wszKernelPath[512];
	if (!VirtualCDClient::Win32FileNameToKernelFileName(lpDiskPath, wszKernelPath, __countof(wszKernelPath)))
	{
		MessageBox(HWND_DESKTOP, _TR(IDS_BADIMGFN, "Invalid image file name!"), NULL, MB_ICONERROR);
		return 1;
	}

	bool bDiskConnected = false;
	ActionStatus status;

	{
		VirtualCDClient clt(&status);
		if (!clt.Valid())
		{
			if (status.GetErrorCode() == BazisLib::AccessDenied)
			{
				if (bFileOnNetworkShare)
					return (int)CUACInvokerDialog((String(GetCommandLine()) + L" /uac_on_network_share").c_str()).DoModal();
				else
					return (int)CUACInvokerDialog(GetCommandLine()).DoModal();
			}

			MessageBox(HWND_DESKTOP, _TR(IDS_NOBUS, "Cannot connect to BazisVirtualCD.sys!"), NULL, MB_ICONERROR);
			return 1;
		}


		bDiskConnected = clt.IsDiskConnected(wszKernelPath);
	}

	if (DriveLetterToRemount != 0)
	{
		if (bDiskConnected)
		{
			MessageBox(HWND_DESKTOP, String::sFormat(_TR(IDS_ALREADYMOUNTED, "%s is already mounted."), lpDiskPath).c_str(), NULL, MB_ICONERROR);
			status = MAKE_STATUS(OperationAborted);
		}
		else
			status = VirtualCDClient::MountImageOnExistingDrive(wszKernelPath, DriveLetterToRemount);
	}
	else if (!bDiskConnected)
	{
		RegistryParams params;

		char driveLetter = 0;
		bool disableAutorun = false, persistent = false;
		if ((params.DriveLetterPolicy == drvlAskEveryTime) || ForceMountOptions)
		{
			CLetterSelectionDialog dlg(ForceMountOptions, detectedProfile);
			if (dlg.DoModal() != IDOK)
				return 3;
			driveLetter = dlg.GetDriveLetter();
			disableAutorun = dlg.IsAutorunDisabled();
			persistent = dlg.IsPersistent();
			detectedProfile = dlg.GetMMCProfile();

#ifdef WINCDEMU_DEBUG_LOGGING_SUPPORT
			if (dlg.IsDebugLoggingEnabled())
			{
				FilePath fpDir = FilePath::GetSpecialDirectoryLocation(SpecialDirFromCSIDL(CSIDL_APPDATA)).PlusPath(L"WinCDEmu.debug");
				bool cancel = false;
				if (!Directory::Exists(fpDir))
					cancel = MessageBox(0, String::sFormat(L"WinCDEmu will create a directory for debugging log files (%s). If you encounter problems using WinCDEmu, please submit the most recent log file to [email protected]. Continue?", fpDir.c_str()).c_str() , L"Information", MB_OKCANCEL | MB_ICONINFORMATION) != IDOK;
				if (!cancel)
				{
					CreateDirectory(fpDir.c_str(), NULL);
					wchar_t wszKernelDirPath[512];
					if (VirtualCDClient::Win32FileNameToKernelFileName(fpDir.c_str(), wszKernelDirPath, __countof(wszKernelDirPath)))
						VirtualCDClient().SetDebugLogDirectory(wszKernelDirPath);
				}
			}
			else
				VirtualCDClient().SetDebugLogDirectory(NULL);
#endif
		}
		else
		{
			disableAutorun = params.DisableAutorun;
			persistent = params.PersistentDefault;
			if (detectedProfile == mpInvalid)
				detectedProfile = (MMCProfile)params.DefaultMMCProfile;
			if (params.DriveLetterPolicy == drvlStartingFromGiven)
			{
				DWORD dwMask = GetLogicalDrives();
				unsigned char ch = 'A' + params.StartingDriveLetterIndex;
				for (unsigned i = (1 << (ch - 'A')); ch <= 'Z'; ch++, i <<= 1)
					if (!(dwMask & i))
					{
						driveLetter = ch;
						break;
					}

			}
		}
		status = VirtualCDClient().ConnectDisk(wszKernelPath, driveLetter, 0, disableAutorun, persistent, AutorunErrorHandler, detectedProfile);
	}
	else
		status = VirtualCDClient().DisconnectDisk(wszKernelPath);

	if (!status.Successful())
	{
		if (status.GetErrorCode() != OperationAborted)
			MessageBox(HWND_DESKTOP, status.GetMostInformativeText().c_str(), NULL, MB_ICONERROR);
		return 1;
	}
	return 0;
}
Пример #10
0
static HRESULT DoRevertVMToSnapshot()
{
	BazisLib::String rawMachineID = VBoxCmdLineToMachineID(GetCommandLineW());
	if (rawMachineID.empty())
		return E_FAIL;

	CComBSTR machineID = rawMachineID.c_str();

	CComPtr<IVirtualBox> pVirtualBox;
	HRESULT hR = pVirtualBox.CoCreateInstance(CLSID_VirtualBox, NULL, CLSCTX_LOCAL_SERVER);
	if (!SUCCEEDED(hR))
		return hR;

	CComPtr<IMachine> pMachine;
	hR = pVirtualBox->FindMachine(machineID, &pMachine);
	if (!SUCCEEDED(hR))
		return hR;

	CComPtr<ISession> pSession;
	hR = pSession.CoCreateInstance(CLSID_Session, NULL, CLSCTX_INPROC_SERVER);
	if (!SUCCEEDED(hR))
		return hR;

	hR = pMachine->LockMachine(pSession, LockType_Shared);
	if (!SUCCEEDED(hR))
	{
		if (hR == E_FAIL)
			MessageBox(HWND_DESKTOP, L"Cannot connect to VirtualBox. Ensure that both VirtualBox and Visual Studio are running from the same user account, either both elevated (UAC), or both not.", L"Error", MB_ICONERROR);
		return hR;
	}

	CComPtr<IConsole> pConsole;
	hR = pSession->get_Console(&pConsole);
	if (!SUCCEEDED(hR))
		return hR;

	CComPtr<ISnapshot> pSnapshot;
	hR = pMachine->get_CurrentSnapshot(&pSnapshot);
	if (!SUCCEEDED(hR))
	{
		pSession->UnlockMachine();
		return hR;
	}

	CComBSTR snapshotID;
	hR = pSnapshot->get_Id(&snapshotID);
	if (!SUCCEEDED(hR))
		return hR;

	CComPtr<IProgress> pProgress;
	hR = pConsole->PowerDown(&pProgress);
	if (!SUCCEEDED(hR))
		return hR;

	hR = WaitForCompletion(pProgress);
	if (!SUCCEEDED(hR))
		return hR;

	pProgress = NULL;
	pSession->UnlockMachine();

	BazisLib::DateTime dtStart = BazisLib::DateTime::Now();
	
	for (;;)
	{
		hR = pMachine->LockMachine(pSession, LockType_Shared);
		if (!SUCCEEDED(hR) && (dtStart.MillisecondsElapsed() >= 10000))
			return hR;
		if (SUCCEEDED(hR))
			break;
		Sleep(100);
	}

	pConsole = NULL;
	hR = pSession->get_Console(&pConsole);
	if (!SUCCEEDED(hR))
		return hR;

	hR = pConsole->RestoreSnapshot(pSnapshot, &pProgress);
	if (!SUCCEEDED(hR))
		return hR;

	hR = WaitForCompletion(pProgress);
	if (!SUCCEEDED(hR))
		return hR;
	
	pSession->UnlockMachine();

	CComBSTR sessionType = L"gui";
	pProgress = NULL;

	hR = pMachine->LaunchVMProcess(pSession, sessionType, NULL, &pProgress);
	if (!SUCCEEDED(hR))
		return hR;

	hR = WaitForCompletion(pProgress);
	if (!SUCCEEDED(hR))
		return hR;

	pSession->UnlockMachine();


	pProgress = NULL;

	return S_OK;
}
Пример #11
0
bool LocalizableStringManager::ParseSourceFile( const BazisLib::String &fp )
{
	ManagedPointer<TextANSIFileReader> pRdr = new TextANSIFileReader(new ACFile(fp, FileModes::OpenReadOnly));
	if (!pRdr->Valid())
	{
		_tprintf(_T("ERROR: cannot open %s\n"), fp.c_str());
		return false;
	}
	_tprintf(_T("  %s\n"), Path::GetFileName(fp).c_str());

	bool insideCCommentBlock = false;
	bool insideStringConstant = false;

	unsigned lineNum = 0;

	DynamicString currentDialogID;

	while (!pRdr->IsEOF())
	{
		size_t LocalizationTokenStart = -1;
		enum
		{
			ltUnknown = 0,
			ltTR,
			ltDIALOG,
			ltDLGITEM,
		} localizationTokenType;

		lineNum++;
		DynamicStringA line = pRdr->ReadLine();

		if (line[0] == '#')
			break;
			
		unsigned backslashCount = 0;
		char prevChar = 0, ch = 0;

		size_t lastStringStart = -1, lastStringLen = 0;

		for (size_t i = 0; i < line.length(); i++, prevChar = ch)
		{
			//Even amount of backslashes followed by quotation mark toggles string constant flag (outside comment block)
			//The "/*" and "*/" sequences outside string block change the comment flag.
			//The "//" sequence skips everything till the end of the string
			//At the end of each line inside the string block there should be a backslash
			ch = line[i];

			bool isLastChar = (i == (line.length() - 1));

			if (insideCCommentBlock)
			{
				if ((ch == '/') && (prevChar == '*'))
					insideCCommentBlock = false;
			}
			else	//Outside comment block - detect string literals
			{
				if (ch == '\\')
					backslashCount++;
				else 
				{
					if (((ch == '\"') || (ch == '\'')) && !(backslashCount % 2))
					{
						if (!insideStringConstant)
							lastStringStart = i + 1, lastStringLen = 0;
						else
							lastStringLen = i - lastStringStart;

						insideStringConstant = !insideStringConstant;
					}
					backslashCount = 0;
				}

				if (!insideStringConstant)	//Outside comment and string blocks - check for comment start
				{
					if ((ch == '*') && (prevChar == '/'))
						insideCCommentBlock = true;
					if ((ch == '/') && (prevChar == '/'))
						break;
				}
				else	//Inside string block
				{
					if (isLastChar && (ch != '\\'))
					{
						_tprintf(_T("%s(%d) : error: Unterminated string"), GetFullPath(fp).c_str(), lineNum);
						return false;
					}
				}
			}

			//Here, both insideCCommentBlock and insideStringConstant reflect the real file context. So, let's find "_TR()" and LOCALIZE_DIALOG()/LOCALIZE_DLGITEM()
			if (!insideCCommentBlock && !insideStringConstant)
			{
				if (!IsValidCTokenChar(prevChar))
				{
					size_t newTokenStart = -1;
					size_t remaining = line.length() - i;
					if ((remaining > 4) && (line.substr(i, 3) == "_TR") && !IsValidCTokenChar(line[i + 3]))
						newTokenStart = i + 3, localizationTokenType = ltTR;
					else if ((remaining > 16) && (line.substr(i, 15) == "LOCALIZE_DIALOG") && !IsValidCTokenChar(line[i + 15]))
						newTokenStart = i + 15, localizationTokenType = ltDIALOG;
					else if ((remaining > 17) && (line.substr(i, 16) == "LOCALIZE_DLGITEM") && !IsValidCTokenChar(line[i + 16]))
						newTokenStart = i + 16, localizationTokenType = ltDLGITEM;

					if (newTokenStart != -1)
					{
						if (LocalizationTokenStart != -1)
						{
							_tprintf(_T("%s(%d) : error: Localization token used recursively"), GetFullPath(fp).c_str(), lineNum);
							return false;
						}
						LocalizationTokenStart = newTokenStart;
						
						lastStringStart = -1;
						lastStringLen = 0;
					}

				}
				if (ch == '}')
					currentDialogID.clear();

				if ((ch == ')') && (LocalizationTokenStart != -1))
				{
					size_t tokenParamsStart = line.find_first_not_of(" \t()", LocalizationTokenStart);
					TempStringA tokenParams = line.substr(tokenParamsStart, i - LocalizationTokenStart);
					if (tokenParams.empty())
					{
						_tprintf(_T("%s(%d) : error: Empty localization macro"), GetFullPath(fp).c_str(), lineNum);
						return false;
					}
					if (localizationTokenType == ltTR)
					{
						if ((lastStringStart == -1) || !lastStringLen)
						{
							_tprintf(_T("%s(%d) : error: Invalid _TR() statement - default string not found"), GetFullPath(fp).c_str(), lineNum);
							return false;
						}
						DynamicString lastString = ANSIStringToString(line.substr(lastStringStart, lastStringLen));

						size_t idEnd = tokenParams.find_first_of(" ,");
						DynamicString id = ANSIStringToString(tokenParams.substr(0, (idEnd == -1) ? 0 : idEnd));
						if (id.empty())
						{
							_tprintf(_T("%s(%d) : error: Invalid _TR() statement - cannot determine string ID"), GetFullPath(fp).c_str(), lineNum);
							return false;
						}

						const DynamicString &existingValue = m_Strings[id].Value;
						if (!existingValue.empty() && (existingValue != lastString))
							_tprintf(_T("%s(%d) : warning: %s redefined with different value\n"), GetFullPath(fp).c_str(), lineNum, id.c_str());

						m_Strings[id].Value = lastString;
					}
					else
					{
						_FixedSetOfCharsSplitString<2, TempStringA> params(tokenParams, ", \t");
						if (params.count() < 2)
						{
							_tprintf(_T("%s(%d) : error: Invalid LOCALIZE_xxx() statement - less than 2 arguments\n"), GetFullPath(fp).c_str(), lineNum);
							return false;
						}

						DynamicString stringId = ANSIStringToString(params[0]);
						if (stringId.empty())
						{
							_tprintf(_T("%s(%d) : error: Invalid LOCALIZE_xxx() statement - empty string ID\n"), GetFullPath(fp).c_str(), lineNum);
							return false;
						}

						if (localizationTokenType == ltDIALOG)
						{
							DynamicString dlgID = ANSIStringToString(params[1]);
							if (m_Dialogs.find(dlgID) == m_Dialogs.end())
							{
								_tprintf(_T("%s(%d) : error: Cannot find dialog %s\n"), GetFullPath(fp).c_str(), lineNum, dlgID.c_str());
								return false;
							}
							m_Dialogs[dlgID].Localized = true;
							m_Dialogs[dlgID].LocalizationFileAndLine.Format(_T("%s(%d)"), GetFullPath(fp).c_str(), lineNum);
							m_Strings[stringId].Value = m_Dialogs[dlgID].Caption;
							currentDialogID = dlgID;
						}
						else if (localizationTokenType == ltDLGITEM)
						{
							if (currentDialogID.empty())
							{
								_tprintf(_T("%s(%d) : error: LOCALIZE_DLGITEM() used outside LOCALIZE_DIALOG() block\n"), GetFullPath(fp).c_str(), lineNum);
								return false;
							}
							DynamicString itemID = ANSIStringToString(params[1]);
							std::map<BazisLib::String, DialogMember>::iterator it = m_Dialogs[currentDialogID].DialogMembers.find(itemID);
							if ((stringId == _T("0")) || !stringId.icompare(_T("NULL")))
							{
								it->second.Skipped = true;
								continue;
							}
							if (it == m_Dialogs[currentDialogID].DialogMembers.end())
							{
								_tprintf(_T("%s(%d) : error: %s is not defined in %s\n"), GetFullPath(fp).c_str(), lineNum, itemID.c_str(), currentDialogID.c_str());
								return false;
							}
							m_Strings[stringId].Value = it->second.Name;
							it->second.Localized = true;
						}

					}
					LocalizationTokenStart = -1;
				}
			}
		}

	}
	return true;
}
Пример #12
0
bool LocalizableStringManager::ParseResourceFile( const BazisLib::String &fp )
{
	ManagedPointer<TextANSIFileReader> pRdr = new TextANSIFileReader(new ACFile(fp, FileModes::OpenReadOnly));
	if (!pRdr->Valid())
	{
		_tprintf(_T("ERROR: cannot open %s\n"), fp.c_str());
		return false;
	}
	_tprintf(_T("  %s\n"), DynamicString(Path::GetFileName((fp))).c_str());

	DynamicString dialogName;
	bool insideDialogDescription = false;
	size_t spacingBeforeDlgitem = -1;

	unsigned lineNum = 0;

	while (!pRdr->IsEOF())
	{
		lineNum++;
		DynamicStringA line = pRdr->ReadLine();
		_FixedCharacterSplitString<2, TempStringA> tokens(line, ' ');
		if (!tokens.count())
			continue;
		if (!tokens[0].icompare("BEGIN"))
			insideDialogDescription = true;
		else if (!tokens[0].icompare("END"))
			dialogName.clear(), insideDialogDescription = false;
		else if (!tokens[1].icompare("DIALOGEX"))
		{
			dialogName = ANSIStringToString(tokens[0]), insideDialogDescription = false;
			m_Dialogs[dialogName].FileAndLine.Format(_T("%s(%d)"), GetFullPath(fp).c_str(), lineNum);
		}
		else if (!line.substr(0, 8).icompare("CAPTION ") && !dialogName.empty() && !insideDialogDescription)
		{
			TempStringA dlgCaption = line.substr(9);
			size_t lastQuote = dlgCaption.find_last_of('\"');
			if (lastQuote != -1)
				dlgCaption = dlgCaption.substr(0, lastQuote);

			DynamicString translatedCaption = ANSIStringToString(dlgCaption);
			for (size_t idx = 0; idx < (translatedCaption.length() - 1); idx++)
			{
				if ((translatedCaption[idx] == '\"') && (translatedCaption[idx + 1] == '\"'))
					translatedCaption.erase(idx, 1);
			}
			m_Dialogs[dialogName].Caption = FormatStringASCString(translatedCaption);
		}
		else if (insideDialogDescription && !dialogName.empty())
		{
			if (spacingBeforeDlgitem == -1)
				spacingBeforeDlgitem = line.find_first_not_of(" \t");
			if (spacingBeforeDlgitem == -1)
				continue;

			if ((line.length() <= spacingBeforeDlgitem) || (line[spacingBeforeDlgitem] == ' ') || (line[spacingBeforeDlgitem] == '\t'))
				continue;

			_FixedSetOfCharsSplitString<1, TempStringA> tokens2(line.substr(spacingBeforeDlgitem), " \t");
			if (tokens2.count() < 1)
				continue;

			if (!tokens2[0].length())
				continue;

			size_t nameStart = tokens2.GetRemainderOffset();
			if (nameStart == -1)
				continue;

			nameStart = line.find_first_not_of(" \t", nameStart + spacingBeforeDlgitem);

			if ((nameStart == -1) || (line[nameStart] != '\"'))
				continue;

			nameStart++;

			char prevChar = 0;
			size_t nameEnd;
			for (nameEnd = nameStart; nameEnd < line.length(); nameEnd++)
			{
				if (line[nameEnd] == '\"')
				{
					if (((nameEnd + 1) < line.length()) && (line[nameEnd + 1] == '\"'))
					{
						nameEnd++;
						continue;
					}
					else
						break;
				}
			}

			DynamicStringA itemText = line.substr(nameStart, nameEnd - nameStart);

			for (size_t idx = 0; (idx + 1) < itemText.length(); idx++)
			{
				if ((itemText[idx] == '\"') && (itemText[idx + 1] == '\"'))
					itemText.erase(idx, 1);
			}


			size_t IDOffset = line.find_first_not_of(" \t,", nameEnd + 1);
			if (IDOffset == -1)
				continue;
			size_t IDEnd = line.find_first_of(" \t,", IDOffset);

			TempStringA itemID = line.substr(IDOffset, (IDEnd == -1) ? -1 : IDEnd - IDOffset);

			m_Dialogs[dialogName].DialogMembers[ANSIStringToString(itemID)].Name = FormatStringASCString(ANSIStringToString(itemText));
			
		}
	}
	return true;
}