Click here to Skip to main content
15,896,606 members
Articles / Programming Languages / C#

The NAR loader - single file .NET deployment

Rate me:
Please Sign up or sign in to vote.
4.51/5 (23 votes)
27 Oct 2006GPL34 min read 104.7K   455   36  
JAR archives for .NET = NAR archives.
#include "stdafx.h"
#include <atlbase.h>

#include "Tools.h"
#include "PasswordDlg.h"
#include "CLRIdentityManager.h"

HINSTANCE NARInstance;
BOOL isDebug = FALSE;
BOOL isSFX = FALSE;
BOOL isSFXCreation = FALSE;

INT ErrorExit(HRESULT hr, PCHAR Message, ...)
{
	CString w(" ", 1024);
	CString msg;

	if (Message) 
	{
		va_list vl;
		va_start(vl, Message);
		vsprintf_s(w.GetBuffer(), w.GetLength(), Message, vl);
		w.ReleaseBuffer();
		va_end(vl);
	}
	w.Replace("\n", "\n\t");

	if (hr != 0) 
	{
		if (w.GetLength())
			msg.Format("Error:\t%s\n\t0x%x %s\n", w, hr, _com_error(hr).ErrorMessage());
		else
			msg.Format("Error:\t0x%x %s\n", hr, _com_error(hr).ErrorMessage());
	}
	else
	{
		if (w.GetLength())
			msg.Format("Error:\t%s\n", w);
	}

	if (isDebug) 
	{
		printf(msg);
	}
	else
		MessageBox(NULL, msg, "Error", MB_ICONERROR | MB_OK);

	return 1;
}


VOID DebugOut(LPCTSTR Message, ...)
{
	CString w(" ", 1024);

	if (isDebug)
	{
		if (Message) 
		{
			va_list vl;
			va_start(vl, Message);
			vsprintf_s(w.GetBuffer(), w.GetLength(), Message, vl);
			w.ReleaseBuffer();
			va_end(vl);
		}

		if (w.GetLength())
			printf(w);
		
		//MessageBox(NULL, w, "Debug", MB_ICONINFORMATION | MB_OK);
		//getchar();
	}
}

VOID GetLastErrorMessage(DWORD dwErr, CString& msg)
{
    try
    {
        LPVOID lpMsgBuf;

        DWORD dwError   =  dwErr ? dwErr : GetLastError();

        DWORD dwFlags   =  FORMAT_MESSAGE_ALLOCATE_BUFFER    |
                           FORMAT_MESSAGE_FROM_SYSTEM        |
                           FORMAT_MESSAGE_IGNORE_INSERTS;

        DWORD dwLang    =  MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT);

        DWORD dwBytes   =  FormatMessage(dwFlags,NULL,dwError,dwLang,
                             (LPTSTR) &lpMsgBuf, 0, NULL);

        if (dwBytes == 0) {
            msg = CString("Unknown");
        }

        CString sMessage((char*)lpMsgBuf);
        LocalFree(lpMsgBuf);
		msg = sMessage;
    }

    catch (...)
    {
        msg = CString("Unknown");
    }
}

VOID Pause()
{
	printf("Press Enter to continue.\n");
	getchar();
}

VOID GetArrayFromData(const char *Data, long Len, SAFEARRAY **psa)
{
   void *pData;

   *psa = SafeArrayCreateVector(VT_UI1, 0, Len);
   SafeArrayAccessData(*psa, (void **)&pData);
   memcpy(pData, Data, Len);
   SafeArrayUnaccessData(*psa);
} 

AssemblyNameEx SplitAssemblyName(LPCTSTR AssemblyName)
{
	/*
    *) simple name
    *) version number
    *) cryptographic key pair
    *) supported culture
	*/

	AssemblyNameEx an;
	an.Raw = NULL;
	an.Version.Raw = NULL;
	DestroyAssemblyName(&an);
	an.Raw = _strdup(AssemblyName);

	int i = 0;
	BOOL f = TRUE;
	PCHAR p = NULL;

	if (an.Raw)
	{
		for (p = an.Raw; *p; p++)
		{
			if (f)
			{
				if (!strchr(" ,", *p))
				{
					f = FALSE;

					if ( !_strnicmp("Version=", p, 8) )
						an.Version.Raw = p + 8;
					else
					if ( !_strnicmp("Culture=", p, 8) )
						an.Culture = p + 8;
					else
					if ( !_strnicmp("PublicKeyToken=", p, 15) )
						an.Key = p + 15;
					else
					if ( !_strnicmp("ProcessorArchitecture=", p, 22) )
						an.Architecture = p + 22;
					else
						an.FriendlyName = (an.FriendlyName) ? an.FriendlyName : p;
				}
			}
			else
			{
				if ( (f = (BOOL)strchr(" ,", *p) ) )
				{
					*p = '\0';
					if (an.FriendlyName && strchr(an.FriendlyName, '='))
						an.FriendlyName = NULL;
				}
			}
		}
		an.FriendlyName = (!an.FriendlyName) ? p : an.FriendlyName;
		an.Version = SplitAssemblyVersion(an.Version.Raw);
		an.Culture = (!an.Culture) ? p : an.Culture;
		an.Key = (!an.Key) ? p : an.Key;
		an.Architecture = (!an.Architecture) ? p : an.Architecture;
	}
	return an;
}

VOID AssemblyNameToString(AssemblyNameEx *AssemblyName, LPTSTR Buffer, DWORD BufferSize, BOOL Short, BOOL Full)
{
	if (AssemblyName && Buffer)
	{
		CHAR Version[32];
		AssemblyVersionToString(&AssemblyName->Version, Version, sizeof(Version));

		if (Short)
			_snprintf_s(Buffer, BufferSize, _TRUNCATE, "%s, V=%s, C=%s, P=%s%s%s",
				AssemblyName->FriendlyName, 
				Version, 
				(AssemblyName->Culture && *AssemblyName->Culture) ? AssemblyName->Culture : "neutral", 
				(AssemblyName->Key && AssemblyName->Key) ? AssemblyName->Key : "neutral",
				(AssemblyName->Architecture && *AssemblyName->Architecture && Full) ? ", A=" : "",
				(AssemblyName->Architecture && *AssemblyName->Architecture && Full) ? AssemblyName->Architecture : ""
				);
		else
			_snprintf_s(Buffer, BufferSize, _TRUNCATE, "%s, Version=%s, Culture=%s, PublicKeyToken=%s%s%s",
				AssemblyName->FriendlyName, 
				Version, 
				(AssemblyName->Culture && *AssemblyName->Culture) ? AssemblyName->Culture : "neutral", 
				(AssemblyName->Key && *AssemblyName->Key) ? AssemblyName->Key : "null",
				(AssemblyName->Architecture && *AssemblyName->Architecture && Full) ? ", ProcessorArchitecture=" : "",
				(AssemblyName->Architecture && *AssemblyName->Architecture && Full) ? AssemblyName->Architecture : ""
				);
	}
}

VOID DestroyAssemblyName(AssemblyNameEx *an)
{
	if (an)
	{
		if (an->Raw)
			free(an->Raw);

		an->Raw = NULL;
		an->FriendlyName = NULL;
		an->Culture = NULL;
		an->Key = NULL;
		an->Architecture = NULL;

		DestroyAssemblyVersion(&(an->Version));
	}
}

AssemblyVersionEx SplitAssemblyVersion(LPCTSTR Version)
{
	AssemblyVersionEx av;
	av.Raw = NULL;
	DestroyAssemblyVersion(&av);
	av.Raw = _strdup(Version);

	int i = 0;
	BOOL f = TRUE;
	PCHAR p = NULL;
	PCHAR px[5] = {"0", "0", "0", "0", "0"};

	if (av.Raw)
	{
		for (p = av.Raw; *p; p++)
		{
			if (f)
			{
				if (!strchr(" .,", *p))
				{
					f = FALSE;
					px[i++] = p;
					if (i > 4)
						break;
				}
			}
			else
			{
				if ( (f = (BOOL)strchr(" .,", *p) ) )
					*p = '\0';
			}
		}
		av.Major = atoi(px[0]);
		av.Minor = atoi(px[1]);
		av.Build = atoi(px[2]);
		av.Revision = atoi(px[3]);
	}
	return av;
}

VOID AssemblyVersionToString(AssemblyVersionEx *AssemblyVersion, LPTSTR Buffer, DWORD BufferSize)
{
	if (AssemblyVersion && Buffer)
	{
		_snprintf_s(Buffer, BufferSize, _TRUNCATE, "%d.%d.%d.%d", 
			AssemblyVersion->Major, AssemblyVersion->Minor, AssemblyVersion->Revision, AssemblyVersion->Build);
	}
}

VOID DestroyAssemblyVersion(AssemblyVersionEx *av)
{
	if (av)
	{
		if (av->Raw)
			free(av->Raw);

		av->Major = 0;
		av->Minor = 0;
		av->Build = 0;
		av->Revision = 0;
	}
}

BOOL GetResourceAssembly(INT ResourceID, SAFEARRAY **pSA)
{
	HRSRC hRC = FindResource(NULL, MAKEINTRESOURCE(ResourceID), "BINARY");
	if (!hRC)
		return FALSE;

	HGLOBAL hRes = LoadResource(NULL, hRC);
	if (!hRes)
		return FALSE;

	DWORD dwSize = SizeofResource(NULL, hRC);
	if (!dwSize)
		return FALSE;

	LPVOID lpAsm = LockResource(hRes);
	if (!lpAsm)
		return FALSE;

	if ((*pSA = SafeArrayCreateVector(VT_UI1, 0, dwSize)))
	{
		LPVOID pBuf = NULL;

		if(FAILED(SafeArrayAccessData(*pSA, &pBuf)))
			return FALSE;
		else
		{
			memcpy(pBuf, lpAsm, dwSize);		
			SafeArrayUnaccessData(*pSA);
			UnlockResource(hRes);
			return TRUE;
		}
	}

	UnlockResource(hRes);
	return FALSE;
}

HRESULT GetResourceAssemblyAsStream(const int ResourceID, IStream **Stream, UINT64 *UniqueID, LPWSTR *Identity)
{
	HRSRC hRC = FindResource(NULL, MAKEINTRESOURCE(ResourceID), "BINARY");
	if (!hRC)
		return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

	HGLOBAL hRes = LoadResource(NULL, hRC);
	if (!hRes)
		return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

	DWORD dwSize = SizeofResource(NULL, hRC);
	if (!dwSize)
		return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

	LPVOID lpAsm = LockResource(hRes);
	if (!lpAsm)
		return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

	HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, Stream);
	if (SUCCEEDED(hr))
	{
		LARGE_INTEGER StreamStart = {0};

		hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);
		hr = (*Stream)->Write(lpAsm, dwSize, NULL);
		assertHR(hr, "GetResourceAssemblyAsStream, Stream->Write");

		hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);

		UnlockResource(hRes);

		if (UniqueID)
			*UniqueID = ResourceID;

		if (Identity)
		{
			CCLRIdentityManager *pIdentityClass = new CCLRIdentityManager();
			ICLRAssemblyIdentityManager *pIdentityInterface = pIdentityClass->GetCLRIdentityManager();

			dwSize = 0;
			hr = pIdentityInterface->GetBindingIdentityFromStream(*Stream, 0, NULL, &dwSize);

			*Identity = (wchar_t *)malloc(dwSize * sizeof(wchar_t));

			hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);
			hr = pIdentityInterface->GetBindingIdentityFromStream(*Stream, 0, *Identity, &dwSize);
			assertHR(hr, "GetBindingIdentityFromStream-2");

			hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);

			pIdentityInterface->Release();
			delete pIdentityClass;
		}

		return S_OK;
	}
	assertHR(hr, "GetResourceAssemblyAsStream, CreateStreamOnHGlobal");
	return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}

HRESULT GetFileAssemblyAsStream(const PCHAR FileName, IStream **Stream, UINT64 *UniqueID, LPWSTR *Identity)
{
	// Make sure we can open the file
	HANDLE hFile = CreateFile(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if (hFile == INVALID_HANDLE_VALUE)
		return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

	printf("Creating Stream for Assembly in file: %s\n", FileName);

	// Get the file size so we know how many bytes to write to the OLE Structured Storage File
	DWORD dwSize = GetFileSize(hFile, NULL);

	// Map the file into memory
	HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, dwSize, NULL);
	PVOID pFile = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);

	HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, Stream);
	if (SUCCEEDED(hr))
	{
		LARGE_INTEGER StreamStart = {0};

		hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);
		hr = (*Stream)->Write(pFile, dwSize, NULL);
		assertHR(hr, "GetResourceAssemblyAsStream, Stream->Write");

		hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);

		if (UniqueID)
			*UniqueID = 7546734; //TODO: Change this - just a test

		if (Identity)
		{
			CCLRIdentityManager *pIdentityClass = new CCLRIdentityManager();
			ICLRAssemblyIdentityManager *pIdentityInterface = pIdentityClass->GetCLRIdentityManager();

			dwSize = 0;
			hr = pIdentityInterface->GetBindingIdentityFromStream(*Stream, 0, NULL, &dwSize);

			*Identity = (wchar_t *)malloc(dwSize * sizeof(wchar_t));

			hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);
			hr = pIdentityInterface->GetBindingIdentityFromStream(*Stream, 0, *Identity, &dwSize);
			assertHR(hr, "GetBindingIdentityFromStream-2");

			hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);

			pIdentityInterface->Release();
			delete pIdentityClass;
		}

		UnmapViewOfFile(pFile);
		CloseHandle(hFileMapping);
		CloseHandle(hFile);

		return S_OK;
	}
	assertHR(hr, "GetResourceAssemblyAsStream, CreateStreamOnHGlobal");
	return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}

HRESULT GetArchiveAssemblyAsStream(zipFile Archive, LPCTSTR Password, const PCHAR AssemblyFileName, IStream **Stream, UINT64 *UniqueID, LPWSTR *Identity)
{
	ULONG dwSize = 0;
	ULONG lPosition = 0;
	PCHAR lpAsm;
	
	if ( GetZIPFileContent(Archive, Password, AssemblyFileName, &lpAsm, &dwSize, &lPosition, TRUE) )
		return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);

	HRESULT hr = CreateStreamOnHGlobal(NULL, TRUE, Stream);
	if (SUCCEEDED(hr))
	{
		LARGE_INTEGER StreamStart = {0};

		hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);
		hr = (*Stream)->Write(lpAsm, dwSize, NULL);
		assertHR(hr, "GetArchiveAssemblyAsStream, Stream->Write");

		hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);

		if (UniqueID)
			*UniqueID = lPosition;

		if (Identity)
		{
			CCLRIdentityManager *pIdentityClass = new CCLRIdentityManager();
			ICLRAssemblyIdentityManager *pIdentityInterface = pIdentityClass->GetCLRIdentityManager();

			dwSize = 0;
			hr = pIdentityInterface->GetBindingIdentityFromStream(*Stream, 0, NULL, &dwSize);

			*Identity = (wchar_t *)malloc(dwSize * sizeof(wchar_t));

			hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);
			hr = pIdentityInterface->GetBindingIdentityFromStream(*Stream, 0, *Identity, &dwSize);
			assertHR(hr, "GetBindingIdentityFromStream-2");

			hr = (*Stream)->Seek(StreamStart, STREAM_SEEK_SET, NULL);

			pIdentityInterface->Release();
			delete pIdentityClass;
		}

		return S_OK;
	}
	assertHR(hr, "GetArchiveAssemblyAsStream, CreateStreamOnHGlobal");
	return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
}

PCHAR ProbeArchive(zipFile Archive, AssemblyNameEx *AssemblyName, CStringArray &privatePath, CStringArray &Extensions)
{
	unz_file_info *FileInfo = NULL;
	CString Extension;
	CString CulturePath;
	CString ProbePath;
	CString FullPath;
	long size = -1;

	if (AssemblyName->Culture && *AssemblyName->Culture)
		if (_strnicmp("neutral", AssemblyName->Culture, 7))
		{
			CulturePath = AssemblyName->Culture;
			CulturePath.Append("\\");
		}

	for (int i = 0; i <= Extensions.GetUpperBound(); i++)
	{
		Extension = Extensions[i];

		int u = privatePath.GetUpperBound();
		for (int j = -1; j <= u; j++)
		{
			if ( j < 0 )
				ProbePath = "";
			else
				ProbePath = privatePath[j] + "\\";

			if ( size < 0 )
			{
				FullPath.Format("%s%s%s%s", 
					CulturePath, ProbePath, AssemblyName->FriendlyName, Extension);
				if (FileInfo = LocateFileInZIPArchive(Archive, FullPath))
				{
					size = FileInfo->uncompressed_size;
					free(FileInfo);
				}
			}

			if ( size < 0 )
			{
				FullPath.Format("%s%s%s\\%s%s", 
					CulturePath, ProbePath, AssemblyName->FriendlyName, AssemblyName->FriendlyName, Extension);
				if (FileInfo = LocateFileInZIPArchive(Archive, FullPath))
				{
					size = FileInfo->uncompressed_size;
					free(FileInfo);
				}
			}

			if( size >= 0 )
				break;
		}
	}

	if ( size >= 0 )
		return _strdup(FullPath);
	else
		return NULL;
}

BOOL LoadResourceAssembly(CComPtr<_AppDomain> AppDomain, INT ResourceID, _Assembly **Assembly)
{
	HRESULT hr;
	SAFEARRAY *pSA;

	GetResourceAssembly(ResourceID, &pSA);
	if(pSA)
	{
		hr = AppDomain->Load_3(pSA, Assembly);
		SafeArrayDestroy(pSA);
		pSA = NULL;
		if (FAILED(hr))
			return false;
		return true;
	}
	return false;
}

BOOL RegisterFileExtension(LPCTSTR Extension, LPCTSTR ProgID, LPCTSTR Handler, LPCTSTR AdditionalParams)
{
	HKEY _key = NULL;
	CHAR w[MAX_PATH + 1];
	CHAR _Extension[MAX_PATH + 1];
	PCHAR _NativeHandler = NULL;

	// ensure that the given extension starts with a dot
	if (*Extension != '.')
		sprintf_s(_Extension, MAX_PATH + 1, ".%s", Extension);
	else
		sprintf_s(_Extension, MAX_PATH + 1, "%s", Extension);

	// create the .extension key in HK_ROOT
	if (RegCreateKey(HKEY_CLASSES_ROOT, _Extension, &_key) == ERROR_SUCCESS) 
	{   
        if (RegSetValue(_key, NULL, REG_SZ, ProgID, strlen(ProgID)) == ERROR_SUCCESS) 
		{
			RegCloseKey(_key);
			_key = NULL;

			// create the ProgID key in HK_ROOT
			sprintf_s(w, MAX_PATH + 1, "%s\\Shell\\Open\\Command", ProgID);
			if (RegCreateKey(HKEY_CLASSES_ROOT, w, &_key) == ERROR_SUCCESS) 
			{
				sprintf_s(w, MAX_PATH + 1, "\"%s\" %s \"%%1\" %%*", Handler, ((AdditionalParams) ? AdditionalParams : ""));
				if (RegSetValue(_key, NULL, REG_SZ, w, strlen(w)) == ERROR_SUCCESS) 
				{
					RegCloseKey(_key);
					_key = NULL;

					return TRUE;
				}
			}
		}

		if (_key)
			RegCloseKey(_key);
	}
	return FALSE;
}

VOID UnRegisterFileExtension(LPCTSTR Extension)
{
	HKEY _key = NULL;
	CHAR _Extension[MAX_PATH + 1];
	PCHAR _NativeHandler = NULL;
	CHAR _ProgID[MAX_PATH + 1];

	// ensure that the given extension starts with a dot
	if (*Extension != '.')
		sprintf_s(_Extension, MAX_PATH + 1, ".%s", Extension);
	else
		sprintf_s(_Extension, MAX_PATH + 1, "%s", Extension);

	// get existing ProgID for the .nar extension and
	// delete the .nar extension
	if (RegOpenKeyEx(HKEY_CLASSES_ROOT, _Extension, 0, KEY_READ, &_key) == ERROR_SUCCESS) 
	{   
		DWORD _size = sizeof(_ProgID);
        if (RegQueryValueEx(_key, NULL, NULL, NULL, (unsigned char *)&_ProgID[0], &_size) == ERROR_SUCCESS) 
		{
			RegCloseKey(_key);
			_key = NULL;

			RegDeleteTree(HKEY_CLASSES_ROOT, _ProgID);
		}

		if (_key)
			RegCloseKey(_key);

		RegDeleteTree(HKEY_CLASSES_ROOT, _Extension);
	}
}

LONG RegDeleteTree(HKEY hKey, LPCTSTR lpSubKey)
{
	LONG _result;
	DWORD _index;
	DWORD _wsize;
	HKEY _key = NULL;
	CHAR w[256];

	if ((_result = RegOpenKeyEx(hKey, lpSubKey, 0, KEY_ALL_ACCESS, &_key)) == ERROR_SUCCESS) 
	{   
		_index = 0;
		_wsize = sizeof(w);
		while ((_result = RegEnumKeyEx(_key, _index, w, &_wsize, NULL, NULL, NULL, NULL)) == ERROR_SUCCESS) 
		{
			RegDeleteTree(_key, w);
			_wsize = sizeof(w);
		}
		RegCloseKey(_key);
		_result = RegDeleteKey(hKey, lpSubKey);
	}
	return _result;
}

BOOL FrameworkBasePath(PCHAR BasePath, DWORD *BasePathSize) 
{
	BOOL _result = FALSE;
	CHAR _rootPath[] = ("SOFTWARE\\Microsoft\\.NETFramework");
	HKEY _key = NULL;

	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _rootPath, 0, KEY_READ, &_key) == ERROR_SUCCESS) 
	{   
		DWORD _size = *BasePathSize;
        if (RegQueryValueEx(_key, "InstallRoot", NULL, NULL, (UCHAR *)BasePath, &_size) == ERROR_SUCCESS) 
		{
				_result = (_size <= *BasePathSize);
				*BasePathSize = _size;
		}
		RegCloseKey(_key);
	}
	return _result;
}

BOOL FrameworkVersion(DWORD *Major, DWORD *Minor, DWORD *Patch) 
{
	BOOL _result = FALSE;
	WCHAR _tmp[MAX_PATH + 1];
	DWORD _tmp_len = 0;

	if SUCCEEDED(GetCORVersion(_tmp, MAX_PATH, &_tmp_len)) 
	{
		_result = TRUE;
		swscanf_s(_tmp, L"v%d.%d.%d", Major, Minor, Patch);
	}
	return _result;
}

unz_file_info *LocateFileInZIPArchive(zipFile Archive, LPCTSTR FileName)
{
	unz_file_info *FileInfo = NULL;

	if ( (FileInfo = (unz_file_info *)malloc(sizeof(unz_file_info))) )
	{
		if (unzLocateFile(Archive, FileName, 2) == UNZ_OK) 
			if (unzGetCurrentFileInfo(Archive, FileInfo, NULL, 0, NULL, 0, NULL, 0) == UNZ_OK)
				return FileInfo;

		free(FileInfo);
		FileInfo = NULL;
	}

	return NULL;
}

INT GetZIPFileContent(zipFile Archive, LPCTSTR Password, LPCTSTR FileName, PCHAR *Buffer, PULONG Size, 
					  PULONG Position, BOOL AllowGUI)
{
	CString TempPassword;
	LONG s = 0, p = 0;
	INT rtc = UNZ_INTERNALERROR;
	unz_file_info *FileInfo = NULL;
	unz_file_pos fp;

	if ( (FileInfo = LocateFileInZIPArchive(Archive, FileName)) )
	{
		do
		{
			rtc = unzOpenCurrentFilePassword(Archive, Password);

			if (!Password && ((FileInfo->flag & 0x01) == 1))
				rtc = UNZ_BADPASSWORD;

			if (rtc == UNZ_OK)
			{
				if (Buffer)
				{
					s = FileInfo->uncompressed_size;

					if ((*Buffer = (PCHAR)malloc(s + 1)) != NULL )
					{
						memset(*Buffer, 0, s + 1);
						unzReadCurrentFile(Archive, *Buffer, s);

						unzGetFilePos(Archive, &fp);
						//p = fp.num_of_file;
						p = fp.pos_in_zip_directory;
					}

					rtc = unzCloseCurrentFile(Archive);
				}
			} 

			if (rtc == UNZ_BADPASSWORD && AllowGUI)
			{
				if (DisplayPasswordDlg(TempPassword))
				{
					Password = TempPassword;
					NARFilePassword = TempPassword;
				}
				else
				{
					NARFilePassword.Empty();
					AllowGUI = FALSE;
				}
			}

		} while (rtc == UNZ_BADPASSWORD && AllowGUI);
		free(FileInfo);
	}

	if (rtc != UNZ_OK)
	{
		if (Buffer)
			*Buffer = NULL;
		s = 0;
		p = 0;
	}

	if (Size != NULL)
		*Size = s;

	if (Position != NULL)
		*Position = p;

	return rtc;
}

BOOL ExtractFileFromZIP(zipFile Archive, LPCTSTR Password, LPCTSTR FileNameInArchive, LPCTSTR FileNameOnDisk)
{
	PCHAR lpBuf;
	DWORD dwSize;
	DWORD dwPos;

	if ( (GetZIPFileContent(Archive, Password, FileNameInArchive, &lpBuf, &dwSize, &dwPos, TRUE)) )
		return FALSE;

	HANDLE hFile = CreateFile(FileNameOnDisk,
					   GENERIC_WRITE,
					   0,
					   NULL,
					   CREATE_ALWAYS,
					   FILE_ATTRIBUTE_NORMAL,
					   NULL);
	if (hFile == INVALID_HANDLE_VALUE)
		return FALSE;

	DWORD dwBytesWritten;	
	if (!WriteFile(hFile, lpBuf, dwSize, &dwBytesWritten, NULL))
	{
		CloseHandle(hFile);
		return FALSE;
	}

	CloseHandle(hFile);
	return TRUE;
}

BOOL ExtractFileFromZIPEx(LPCTSTR ArchiveFileName, LPCTSTR Password, LPCTSTR FileNameInArchive, LPCTSTR FileNameOnDisk)
{
	BOOL rtc = FALSE;
	zipFile zf;

	if ((zf = unzOpen(ArchiveFileName)))
	{
		if (ExtractFileFromZIP(zf, Password, FileNameInArchive, FileNameOnDisk))
			rtc = TRUE;
		unzClose(zf);
	}
	return rtc;
}

BOOL ExtractFileFromZIP2Temp(zipFile Archive, LPCTSTR Password, LPCTSTR FileNameInArchive, LPTSTR Buffer, DWORD BufferSize)
{
	BOOL rtc = FALSE;

	CString TempFileName = _tempnam("c:\\tmp", "nar");
	if (ExtractFileFromZIP(Archive, Password, FileNameInArchive, TempFileName))
	{
		if (Buffer)
			strcpy_s(Buffer, BufferSize, TempFileName);
		rtc = TRUE;
	}
	return rtc;
}

BOOL ExtractFileFromZIP2TempEx(LPCTSTR ArchiveFileName, LPCTSTR Password, LPCTSTR FileNameInArchive, LPTSTR Buffer, DWORD BufferSize)
{
	BOOL rtc = FALSE;

	CString TempFileName = _tempnam("c:\\tmp", FileNameInArchive);
	if (ExtractFileFromZIPEx(ArchiveFileName, Password, FileNameInArchive, TempFileName))
	{
		if (Buffer)
			strcpy_s(Buffer, BufferSize, TempFileName);
		rtc = TRUE;
	}
	return rtc;
}

SharedMemory *StoreInSharedMemory(PCHAR Name, ULONG ContentLength, PVOID Content)
{
	SharedMemory *Memory = (SharedMemory *)malloc(sizeof(SharedMemory));
	if (Memory)
	{
		memset(Memory, 0, sizeof(SharedMemory));
		ContentLength = (ContentLength < 0) ? 0 : ContentLength;
		ContentLength = (ContentLength > (ULONG_MAX - (sizeof(DWORD) + 1)) ? ULONG_MAX - (sizeof(DWORD) + 1) : ContentLength);
		// 4 Byte ULONG = length of content in shared memory
		//                (this corresponds to an INT in the managed AppDomain manager!)
		// ? content 
		// 1 Byte terminating zero = (just to be sure)
		// +----+-- ... --+-+
		// + 4  | ?       |1|
		// +----+-- ... --+-+
		ULONG MemoryLength = sizeof(ULONG) + ContentLength + 1;

		Memory->Name = _strdup(Name);
		Memory->Handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, MemoryLength, Memory->Name);
		if (Memory->Handle != NULL && Memory->Handle != INVALID_HANDLE_VALUE)
		{
			Memory->Length = (PULONG)MapViewOfFile(Memory->Handle, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(ULONG));
			Memory->Content = (BYTE*)MapViewOfFile(Memory->Handle, FILE_MAP_ALL_ACCESS, 0, 0, MemoryLength);
			memset(Memory->Content, 0, MemoryLength);
			Memory->Content += sizeof(ULONG);
			*Memory->Length = ContentLength;
			memcpy(Memory->Content, Content, ContentLength);
		}
	}
	return Memory;
}

SharedMemory *StoreFileInSharedMemory(PCHAR Name, PCHAR FileName)
{
/*
	SharedMemory *sm = (SharedMemory *)malloc(sizeof(SharedMemory));
	if (sm)
	{
		memset(sm, 0, sizeof(SharedMemory));

		HANDLE hFile = CreateFile(FileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if (hFile != NULL && hFile != INVALID_HANDLE_VALUE)
		{
			DWORD dwSize = GetFileSize(hFile, NULL);
			INT l = (sizeof(INT) * 2) + dwSize;

			sm->Name = _strdup(Name);
			sm->Handle = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, l, sm->Name);
			PVOID pFile = MapViewOfFile(sm->Handle, FILE_MAP_ALL_ACCESS, 0, 0, l);
			memset(sm->Content, 0, l);
			*sm->Length = ContentLength;
			memcpy(sm->Content + (sizeof(INT) * 2), Content, ContentLength);

			UnmapViewOfFile(pFile);
			CloseHandle(hFileMapping);
			CloseHandle(hFile);
		}
	}
	return sm;
*/
	return NULL;
}

VOID CloseSharedMemory(SharedMemory *Memory)
{
	if (!Memory)
		return;

	if (Memory->Name)
		free(Memory->Name);

	if (Memory->Length)
		UnmapViewOfFile(Memory->Length);

	Memory->Content -= sizeof(DWORD);
	if (Memory->Content)
		UnmapViewOfFile(Memory->Content);

	if (Memory->Handle && Memory->Handle != INVALID_HANDLE_VALUE)
		CloseHandle(Memory->Handle);

	memset(Memory, 0, sizeof(SharedMemory));
}

HWND FindConsoleHandle()
 {
	static LPCTSTR temptitle = _T("{98C1C303-2A9E-11d4-9FF5-006067718D04}");
	TCHAR title[512];
	TCHAR me[64];
	wsprintf(me, _T("%s-%08x"), temptitle, GetCurrentProcessId());
	if(GetConsoleTitle(title, sizeof(title)/sizeof(TCHAR)) == 0)
		return NULL;
	SetConsoleTitle(me);
	HWND hWnd = FindWindow(NULL, me);
	SetConsoleTitle(title);
	return hWnd;
 }

INT GetEntropy(UCHAR buf[], UINT len)
{
	unsigned __int64 pentium_tsc[1];
	unsigned int i;

	QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc);
	for( i = 0; i < 8 && i < len; ++i )
		buf[i] = ((UCHAR *)pentium_tsc)[i];
	return i;
}

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 GNU General Public License (GPLv3)


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

Comments and Discussions