Click here to Skip to main content
15,884,933 members
Articles / Web Development / HTML

A Comprehensive CE Class Library to Replace ATL and MFC

Rate me:
Please Sign up or sign in to vote.
4.48/5 (14 votes)
4 Oct 2000CPOL 278.5K   998   70  
A collection of classes for CE that do not use ATL or MFC, plus an FTP client, database viewer, and sample application that solves beam deflection equations.
#include "stdafx.h"
#include "CeRes.h"

#define UNUSED(var)		var


BOOL CeVersionInfo::Load(LPBYTE pDataIn)
{
	memset(&m_fileInfo, 0, sizeof m_fileInfo);

	BYTE* pData = pDataIn;

	WORD wLength = (*((WORD*)pData));		pData += sizeof WORD;
	WORD wValueLength = (*((WORD*)pData));	pData += sizeof WORD;
	WORD wType = (*((WORD*)pData));			pData += sizeof WORD;

	if (0 != wcsncmp((wchar_t*) pData, OLESTR("VS_VERSION_INFO"), 15))
	{
		OutputDebugString(_T("Invalid KEY expected VS_VERSION_INFO\n"));
		return FALSE;
	}

	// skip over the key and it's null terminator
	pData += (15+1) * sizeof (wchar_t);

	// put back on a DWORD boundry,
	// this is PADDING1
	pData += (pData-pDataIn) % sizeof DWORD;

	// this value is optional, it is only present if
	// wValueLength is non-zero
	if (wValueLength != 0)
	{
		// get the structure
		CopyMemory(&m_fileInfo, pData, sizeof m_fileInfo);
		
		if (0xfeef04bd != m_fileInfo.dwSignature)
			// not a valid VS_FIXEDFILEINFO structure...
			return FALSE;

		// put back on a DWORD boundry, this is only required
		// if there is a VALUE,
		// this is PADDING2
		pData += sizeof m_fileInfo;

		// force to DWORD boundry
		pData += (pData-pDataIn) % sizeof DWORD;

		// Trace the fileInfo
		/*
		TRACE("dwStrucVersion:     %08x\n", m_fileInfo.dwStrucVersion);
		TRACE("dwFileVersionMS:    %08x\n", m_fileInfo.dwFileVersionMS);
		TRACE("dwFileVersionLS:    %08x\n", m_fileInfo.dwFileVersionLS);
		TRACE("dwProductVersionMS: %08x\n", m_fileInfo.dwProductVersionMS);
		TRACE("dwProductVersionLS: %08x\n", m_fileInfo.dwProductVersionLS); 
		TRACE("dwFileFlagsMask:    %08x\n", m_fileInfo.dwFileFlagsMask);
		TRACE("dwFileFlags:        %08x\n", m_fileInfo.dwFileFlags);
		TRACE("dwFileOS:           %08x\n", m_fileInfo.dwFileOS); 
		TRACE("dwFileType:         %08x\n", m_fileInfo.dwFileType);
		TRACE("dwFileSubtype:      %08x\n", m_fileInfo.dwFileSubtype);
		TRACE("dwFileDateMS:       %08x\n", m_fileInfo.dwFileDateMS); 
		TRACE("dwFileDateLS:       %08x\n", m_fileInfo.dwFileDateLS); 
		*/
	}

	memset(&m_vfi, 0, sizeof m_vfi);
	memset(&m_sfi, 0, sizeof m_sfi);

	// rip through the children, these are either StringFileInfo or VersionFileInfo
	while (pDataIn + wLength > pData)
	{
		BYTE* pDataInfoStart = pData;

		WORD  wChildLength = (*((WORD*)pData));			pData += sizeof WORD;
		WORD  wChildValueLength = (*((WORD*)pData));	pData += sizeof WORD;
		WORD  wChildType = (*((WORD*)pData));			pData += sizeof WORD;

		if (0 == wcsncmp((wchar_t*) pData, OLESTR("VarFileInfo"), 11))
		{
//			OutputDebugString(_T("VarFileInfo Structure\n"));
			pData += 12 * sizeof(wchar_t);
			pData += (pData-pDataIn) % sizeof DWORD;

			WORD  wVerLength = (*((WORD*)pData));		pData += sizeof WORD;
			WORD  wVerValueLength = (*((WORD*)pData));	pData += sizeof WORD;
			WORD  wVerType = (*((WORD*)pData));			pData += sizeof WORD;

			wchar_t szKey[64];
			for (int ii = 0;   ; pData += sizeof(wchar_t), ii++)
			{
				szKey[ii] = *((wchar_t*) pData);
				if (szKey[ii] == 0)
					break;
			}

			pData += (pData-pDataIn) % sizeof DWORD;
			for (ii = 0; ii < wVerValueLength; ii++)
			{
				m_vfi.m_var[m_vfi.m_wCnt].m_dwValue[ii] = ((WORD*)pData)[ii];
				// print each word
				//TRACE(_T("%04hx"), m_vfi.m_var[ii].m_dwValue);
			}

			m_vfi.m_var[m_vfi.m_wCnt].m_wCnt = ii;
			m_vfi.m_wCnt++;
		}
		else if (0 == wcsncmp((wchar_t*) pData, OLESTR("StringFileInfo"), 14))
		{
//			OutputDebugString(_T("StringFileInfo Structure\n"));
			pData += 15 * sizeof(wchar_t);
			pData += (pData-pDataIn) % sizeof DWORD;

			// Start of a string table...
			BYTE* pStringTableStart = pData;

			WORD  wStrTabLength = (*((WORD*)pData));		pData += sizeof WORD;
			WORD  wStrTabValueLength = (*((WORD*)pData));	pData += sizeof WORD;
			WORD  wStrTabType = (*((WORD*)pData));			pData += sizeof WORD;

			wchar_t szLang[9];
			// extract the language information
			for (int ii = 0;  ; pData += sizeof(wchar_t), ii++)
			{
				szLang[ii] = *((wchar_t*) pData);
				if (szLang[ii] == 0)
				{
					pData += sizeof(wchar_t);
					break;
				}
			}

			m_sfi.m_st[m_sfi.m_wCnt].m_dwKey = wcstol(szLang, NULL, 16);
			wcscmp(m_sfi.m_st[m_sfi.m_wCnt].m_wszKey, szLang);

			// align on DWORD
			pData += (pData-pDataIn) % sizeof DWORD;

			// extract the String children
			while (pStringTableStart + wStrTabLength > pData)
			{
				BYTE* pStringStart = pData;
				WORD  wStrLength = (*((WORD*)pData));		pData += sizeof WORD;
				WORD  wStrValueLength = (*((WORD*)pData));	pData += sizeof WORD;
				WORD  wStrType = (*((WORD*)pData));			pData += sizeof WORD;

				wchar_t szDesc[64];
				for (int jj=0; ; pData += sizeof(wchar_t), jj++)
				{
					szDesc[jj] = *((wchar_t*) pData);
					if (szDesc[jj] == 0)
					{
						// skip past the null terminator
						pData += sizeof(wchar_t);
						break;
					}
				}
				//CString strDesc(szDesc);

				pData += (pData-pDataIn) % sizeof DWORD;

				wchar_t szString[256];
				if (wStrValueLength != 0)
				{
					if (0 == *((wchar_t*) pData))
						pData += sizeof DWORD;

					for (jj=0; ; pData += sizeof(wchar_t), jj++)
					{
						szString[jj] = *((wchar_t*) pData);
						if (szString[jj] == 0)
							break;
					}
				}
				else
					szString[0] = 0;

				if (!wcscmp(szDesc, OLESTR("CompanyName")))
					wcscpy(m_wszCompanyName, szString);
				else if (!wcscmp(szDesc, OLESTR("FileDescription")))
					wcscpy(m_wszFileDescription, szString);
				else if (!wcscmp(szDesc, OLESTR("FileVersion")))
					wcscpy(m_wszFileVersion, szString);
				else if (!wcscmp(szDesc, OLESTR("InternalName")))
					wcscpy(m_wszInternalName, szString);
				else if (!wcscmp(szDesc, OLESTR("OriginalFilename")))
					wcscpy(m_wszOriginalFilename, szString);
				else if (!wcscmp(szDesc, OLESTR("ProductName")))
					wcscpy(m_wszProductName, szString);
				else if (!wcscmp(szDesc, OLESTR("ProductVersion")))
					wcscpy(m_wszProductVerion, szString);
				else if (!wcscmp(szDesc, OLESTR("LegalCopyright")))
					wcscpy(m_wszFileCopyright, szString);
				

				//CString strString(szString);
				//OutputDebugStringW(szDesc);
				//OutputDebugStringW(L" - ");
				//OutputDebugStringW(szString);
				//OutputDebugStringW(L"\n");

				wcscpy(m_sfi.m_st[m_sfi.m_wCnt].m_sp[m_sfi.m_st[m_sfi.m_wCnt].m_wCnt].m_wszKey, szDesc);
				wcscpy(m_sfi.m_st[m_sfi.m_wCnt].m_sp[m_sfi.m_st[m_sfi.m_wCnt].m_wCnt].m_wszValue, szString);
				m_sfi.m_st[m_sfi.m_wCnt].m_wCnt++;

				pData = pStringStart + wStrLength;
				pData += (pData-pDataIn) % sizeof DWORD;
			}

			m_sfi.m_st[m_sfi.m_wCnt].m_wCnt++;
			m_sfi.m_wCnt++;
		}
		else
		{
			OutputDebugString(_T("Corrupt VS_VERSION_INFO...\n"));
		}

		// on to the next child
		pData = pDataInfoStart + wChildLength;
		pData += (pData-pDataIn) % sizeof(DWORD);
	}

	return TRUE;
}

CeVersionInfo::CeVersionInfo()
{
	memset(&m_fileInfo, 0, sizeof m_fileInfo);

	*m_wszCompanyName = 0;
	*m_wszFileDescription = 0;
	*m_wszFileVersion = 0;
	*m_wszInternalName = 0;
	*m_wszOriginalFilename = 0;
	*m_wszProductName = 0;
	*m_wszProductVerion = 0;
}


CeResource::CeResource(HINSTANCE hInst)
{
	m_hInst = hInst;
	m_hResFile = NULL;
	m_bUpdating = false;
}

CeResource::CeResource(LPCTSTR lpsz)
{
	Load(lpsz);

	m_hResFile = NULL;
	m_bUpdating = false;
}

CeResource::~CeResource()
{
#ifndef _WIN32_WCE
	if (m_hResFile && m_bUpdating)
		// default while in edit if not explictly updated
		// we abandon changes
		EndUpdate(TRUE);
#endif
	if (m_hInst)
	{
		::FreeLibrary(m_hInst);
		m_hInst = NULL;
	}
}

#ifndef _WIN32_WCE

// Methods for modifiy resources
bool CeResource::BeginUpdate(LPCTSTR szExe, BOOL bDeleteExistingResources/*=FALSE*/)
{
	m_hResFile = BeginUpdateResource(szExe, bDeleteExistingResources);
	if (m_hResFile)
		m_bUpdating = true;
	return (NULL != m_hResFile);
}

bool CeResource::EndUpdate(BOOL bDisardChanges/*=FALSE*/)
{
	BOOL bSuccess = EndUpdateResource(m_hResFile, bDisardChanges);
	m_bUpdating = false;
	m_hResFile = NULL;
	return (bSuccess != FALSE);
}

bool CeResource::Update(LPCTSTR lpType, LPCTSTR lpName, WORD wLanguage, LPVOID lpData, DWORD cbData)
{
	if (m_bUpdating)
		return false;

	return UpdateResource(m_hResFile, lpType, lpName, wLanguage, lpData, cbData); 
}

#endif // _WIN32_WCE


// Methods for retrieving resources
bool CeResource::Load(LPCTSTR lpLibFileName)
{
#ifdef LoadLibraryEx

	// open the data file so that we don't need to load all the
	// modules' dependecies
	Attach (::LoadLibraryEx(lpLibFileName, NULL, LOAD_LIBRARY_AS_DATAFILE|DONT_RESOLVE_DLL_REFERENCES));

#else // LoadLibraryEx

	Attach(::LoadLibrary(lpLibFileName));

#endif

	return (m_hInst != NULL);
}

HRSRC CeResource::FindResource(LPCTSTR lpName, LPCTSTR lpType, WORD wLanguage)
{
#ifndef _WIN32_WCE
	if (wLanguage)
		return ::FindResourceEx(m_hInst, lpName, lpType, wLanguage);
	else
#else
		UNUSED(wLanguage);
#endif
		return ::FindResource(m_hInst, lpName, lpType);
}

HRSRC CeResource::FindResource(UINT nName, LPCTSTR lpType, WORD wLanguage)
{
#ifndef _WIN32_WCE
	if (wLanguage)
		return ::FindResourceEx(m_hInst, MAKEINTRESOURCE(nName), lpType, wLanguage);
	else
#else
		UNUSED(wLanguage);
#endif
		return ::FindResource(m_hInst, MAKEINTRESOURCE(nName), lpType);
}

LPVOID CeResource::LoadResource(HRSRC hRsrc, DWORD& dwSize)
{
	LPVOID pData = NULL;
	dwSize = ::SizeofResource(m_hInst, hRsrc);

	HGLOBAL hMem = ::LoadResource(m_hInst, hRsrc);
	if (hMem)
		pData = ::LockResource(hMem);

	return pData;
}
// Methods for enumerating resources

#ifndef _WIN32_WCE

/*static*/
BOOL CALLBACK CeResource::EnumResTypeProc( HINSTANCE hModule, LPTSTR lpszType, LONG lParam)
{
	//CWordArray* parTypes = (CWordArray*) lParam;
	SCallbackArray* parTypes = (SCallbackArray*) lParam;
	
	// test of string type
	if (((DWORD) lpszType) & 0xffff0000)
	{
		// string...
		//TRACE("Unknown Type: %s\n", lpszType);
		return TRUE;
	}
	
	parTypes->rgwRes[parTypes->wCnt++] = (WORD) lpszType;

	//parTypes->Add((WORD) lpszType);
	//TRACE("ResType: %d\n", (DWORD) lpszType);
	
	return TRUE;
}

void CeResource::EnumTypes(SCallbackArray& arTypes)
{
	EnumResourceTypes(m_hInst, (ENUMRESTYPEPROC) EnumResTypeProc, (LONG) &arTypes);
}

/*static*/
BOOL CALLBACK CeResource::EnumResNameProc(HANDLE hModule, LPCTSTR lpszType, LPTSTR lpszName, LONG lParam)
{
	SCallbackArray* parTypes = (SCallbackArray*) lParam;
	
	// test of string type
	if (((DWORD) lpszName) & 0xffff0000)
	{
		// string...
		//TRACE("Unknown String Res: %s\n", lpszType);
		return TRUE;
	}
	
	parTypes->rgwRes[parTypes->wCnt++] = (WORD) lpszName;

	//TRACE("ResName: %d\n", (DWORD) lpszName);
	return TRUE;
}

void CeResource::EnumResources(SCallbackArray* par, WORD wType)
{
	EnumResourceNames(m_hInst, (LPCTSTR) wType, (ENUMRESNAMEPROC)EnumResNameProc, (LONG) par);
}

#endif // _WIN32_WCE

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions