///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Author: Luuk Weltevreden
// Date: 23-07-2004
//
// Modified a lot by Elm� (http://kickme.to/elmue)
// Date: 01-08-2006
//
// Filename: ExtractResourceT.hpp
//
// - CExtractResourceT<T>
// - CExtractResource
//
// Purpose: This template extracts files from cabinet files stored as a Win32 Resource.
//
#pragma once
#include "ExtractMemoryT.hpp"
#pragma warning(disable: 4996)
template <class T> class CExtractResourceT : public CExtractMemoryT<T>
{
public:
// Copy the content of the cabinet in the resources onto disk
// You can set s8_Module = 0 if the cabinet is in the file which created the process
// Otherwise s8_Module must be the filename (without path) of the DLL which contains the CAB resource
// To test this function with the file Test.cab included in this project
// set s8_Module = "Cablib.dll" and uResourceID = ID_CAB_TEST and s8_ResourceTypeName = "CABFILE"
// because the file CabLib.rc contains:
// ID_CAB_TEST CABFILE "Res\\Test.cab"
BOOL ExtractResource(char* s8_Module, UINT uResourceID, UINT uResourceTypeID, LPCSTR szTarget, void * pParam = NULL)
{ return ExtractResource(s8_Module, MAKEINTRESOURCEA(uResourceID), MAKEINTRESOURCEA(uResourceTypeID), szTarget, pParam); }
BOOL ExtractResource(char* s8_Module, UINT uResourceID, LPCSTR s8_ResourceTypeName, LPCSTR szTarget, void * pParam = NULL)
{ return ExtractResource(s8_Module, MAKEINTRESOURCEA(uResourceID), s8_ResourceTypeName, szTarget, pParam); }
BOOL ExtractResource(char* s8_Module, LPCSTR s8_ResourceName, UINT uResourceTypeID, LPCSTR szTarget, void * pParam = NULL)
{ return ExtractResource(s8_Module, s8_ResourceName, MAKEINTRESOURCEA(uResourceTypeID), szTarget, pParam); }
BOOL ExtractResource(char* s8_Module, LPCSTR s8_ResourceName, LPCSTR s8_ResourceTypeName, LPCSTR szTarget, void * pParam = NULL)
{
GetModule() = GetModuleHandleA(s8_Module);
char s8_Cabinet[2000];
BuildFileName(s8_ResourceName, s8_ResourceTypeName, s8_Cabinet);
// Pass it on to the base class
return ExtractFile(s8_Cabinet, szTarget, pParam);
}
// Check if the cabinet in the resources is valid
// You can set s8_Module = 0 if the cabinet is in the file which created the process
// Otherwise s8_Module must be the filename (without path) of the DLL which contains the CAB resource
// To test this function with the file Test.cab included in this project
// set s8_Module = "Cablib.dll" and uResourceID = ID_CAB_TEST and s8_ResourceTypeName = "CABFILE"
// because the file CabLib.rc contains:
// ID_CAB_TEST CABFILE "Res\\Test.cab"
BOOL IsResourceCabinet(char* s8_Module, UINT uResourceID, UINT uResourceType, PFDICABINETINFO pfdici = NULL)
{ return IsResourceCabinet(s8_Module, MAKEINTRESOURCEA(uResourceID), MAKEINTRESOURCEA(uResourceTypeID), pfdici); }
BOOL IsResourceCabinet(char* s8_Module, UINT uResourceID, LPCSTR s8_ResourceTypeName, PFDICABINETINFO pfdici = NULL)
{ return IsResourceCabinet(s8_Module, MAKEINTRESOURCEA(uResourceID), s8_ResourceTypeName, pfdici); }
BOOL IsResourceCabinet(char* s8_Module, LPCSTR s8_ResourceName, UINT uResourceTypeID, PFDICABINETINFO pfdici = NULL)
{ return IsResourceCabinet(s8_Module, s8_ResourceName, MAKEINTRESOURCEA(uResourceTypeID), pfdici); }
BOOL IsResourceCabinet(char* s8_Module, LPCSTR s8_ResourceName, LPCSTR s8_ResourceTypeName, PFDICABINETINFO pfdici = NULL)
{
GetModule() = GetModuleHandleA(s8_Module);
char s8_Cabinet[2000];
BuildFileName(s8_ResourceName, s8_ResourceTypeName, s8_Cabinet);
// Pass it on to the base class
return IsCabinet(s8_Cabinet, pfdici);
}
protected:
// Create a file name for the CAB file which contains the resource name and resource type
// in the form "RESOURCETYPE\\RESOURCENAME"
void BuildFileName(LPCSTR s8_ResourceName, LPCSTR s8_ResourceTypeName, LPSTR lpszBuffer)
{
LPCSTR pszResName = s8_ResourceName;
LPCSTR pszResType = s8_ResourceTypeName;
char szTemp1[12] = {0};
char szTemp2[12] = {0};
if (IS_INTRESOURCE(s8_ResourceName))
{
itoa((int)(PtrToInt(s8_ResourceName)), szTemp1, 10);
memmove(szTemp1 + 1, szTemp1, strlen(szTemp1));
szTemp1[0] = '#';
pszResName = szTemp1;
}
if (IS_INTRESOURCE(s8_ResourceTypeName))
{
itoa((int)(PtrToInt(s8_ResourceTypeName)), szTemp2, 10);
memmove(szTemp2 + 1, szTemp2, strlen(szTemp2));
szTemp2[0] = '#';
pszResType = szTemp2;
}
sprintf(lpszBuffer, "%s\\%s", pszResType, pszResName);
}
static HMODULE& GetModule()
{
static HMODULE Mod = 0;
return Mod;
}
// This function opens the specified resource from the current module
// and returns a pointer to the resource memory block
static kMemory* OpenMem(const char* s8_File, int, int)
{
char s8_ResourceName[2000];
char s8_ResourceType[2000];
// Split the filename
char* s8_Slash = (char*) strrchr(s8_File, '\\');
if (!s8_Slash)
return (kMemory*) -1;
// Copy the resource name and type
strcpy(s8_ResourceName, s8_Slash+1);
strcpy(s8_ResourceType, s8_File);
s8_ResourceType[(int)(s8_Slash-s8_File)] = 0;
// Load the resource
HRSRC hResource = FindResourceA(GetModule(), s8_ResourceName, s8_ResourceType);
HGLOBAL hGlobal = LoadResource (GetModule(), hResource);
void* p_Addr = LockResource (hGlobal);
if (!p_Addr)
return (kMemory*) -1;
UINT Size = (UINT)SizeofResource(GetModule(), hResource);
return new kMemory(p_Addr, 0, Size);
}
// Copies a part of the CAB file's memory from the resource to the given buffer
static int ReadMem(kMemory* pk_Mem, void* buffer, UINT count)
{
// Reached the end of the resource
if (pk_Mem->s32_Pos >= pk_Mem->s32_Size)
return 0;
// Do not try to read behind the end of the resource
count = min((long)count, pk_Mem->s32_Size - pk_Mem->s32_Pos);
// Copy the memory in the buffer
memcpy(buffer, (char*)(pk_Mem->p_Addr) + pk_Mem->s32_Pos, count);
// Return the amount of bytes copied
return count;
}
// Declare this class as a friend so it can access the protected members.
friend class CExtractMemoryT<T>;
};
class CExtractResource : public CExtractResourceT<CExtractResource> { };