|
|
#include "hdspPCH.h"
#include "resource.h"
#include "rescopy.h"
static char *g_szMonths[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
BOOL CALLBACK RezNamesCallback( HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LPARAM lParam ) { PResCallbackData pData = (PResCallbackData)lParam; DWORD cResourceBytes = 0; CHAR szDataPath[MAX_PATH]; HRSRC hrsrc = NULL; HGLOBAL hglbResource = NULL; LPVOID pDataFile = NULL; HANDLE hFileWrite = INVALID_HANDLE_VALUE; DWORD cBytesWritten = 0; BOOL fEndSlash = FALSE; LPCSTR pszEndSlash = NULL; PLyraExeHeader pHeader = NULL; LyraExeHeader HeaderComp; BOOL fPerformVersionCheck = TRUE; BOOL fOKToCopy = TRUE; UINT idxMonth = 0;
if( NULL == pData ) { return( FALSE ); }
pszEndSlash = pData->pszDirectory; while( pszEndSlash && *pszEndSlash ) { fEndSlash = ( *pszEndSlash == '\\' ); pszEndSlash = CharNextA(pszEndSlash); }
if( 0 > _snprintf( szDataPath, sizeof(szDataPath)/sizeof(szDataPath[0]), fEndSlash ? "%s%s" : "%s\\%s", pData->pszDirectory, lpszName ) ) { pData->hr = E_OUTOFMEMORY; return( FALSE ); }
hrsrc = FindResourceA( hModule, lpszName, lpszType ); if( NULL == hrsrc ) { pData->hr = HRESULT_FROM_WIN32( GetLastError() ); return( FALSE ); }
cResourceBytes = SizeofResource( hModule, hrsrc ); if( 0 == cResourceBytes ) { pData->hr = E_UNEXPECTED; return( FALSE ); }
hglbResource = LoadResource(hModule, hrsrc ); if( NULL == hrsrc ) { pData->hr = HRESULT_FROM_WIN32( GetLastError() ); return( FALSE ); }
//
// Note: Win32 Claims that you do NOT have to Free/Unlock resource after calling lock
//
pDataFile = LockResource( hglbResource ); if( NULL == pDataFile ) { pData->hr = HRESULT_FROM_WIN32( GetLastError() ); return( FALSE ); }
pszEndSlash = strrchr( lpszName, '.' );
if( NULL != pszEndSlash && 0 == stricmp(pszEndSlash, ".exe") && cResourceBytes > sizeof(LyraExeHeader) ) { pHeader = (PLyraExeHeader)pDataFile;
//
// If our files don't have "LYRA" in them, then there is no
// version check to perform (ughhhh!!!)
//
if( strncmp((char *)pHeader->szLyra, "LYRA", sizeof(pHeader->szLyra) ) ) { fPerformVersionCheck = FALSE; } } else { fPerformVersionCheck = FALSE; }
hFileWrite = CreateFileA( szDataPath, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( INVALID_HANDLE_VALUE == hFileWrite ) { pData->hr = HRESULT_FROM_WIN32( GetLastError() ); return( FALSE ); }
if( fPerformVersionCheck ) { if( !ReadFile( hFileWrite, &HeaderComp, sizeof(HeaderComp), &cBytesWritten, NULL ) ) { fPerformVersionCheck = FALSE; }
//
// Make sure we got the number of bytes we need for our version header,
// if not, then just copy the file!
//
if( cBytesWritten != sizeof(HeaderComp) ) { fPerformVersionCheck = FALSE; } }
if( fPerformVersionCheck ) {
//
// If we ARE going to perform a version check, then this MUST be set to false intially because
// if we fail on the version check, we DONT want to copy the file!
//
fOKToCopy = FALSE;
//
// At this point, we know we have version stuff in our .exe in our resource,
// and we know that we have 36 bytes of what "should" be a header, now
// compare them, if they don't match, it's okay to copy
//
if( strncmp( (char *)pHeader->szLyra, (char *)HeaderComp.szLyra, sizeof(HeaderComp.szLyra) ) ) { fOKToCopy = TRUE; } else { //
// Okay, we have version information, check the revision number
//
if( pHeader->szRevision[0] >= HeaderComp.szRevision[0] ) { if( pHeader->szRevision[0] == HeaderComp.szRevision[0] ) { if( pHeader->szRevision[2] >= HeaderComp.szRevision[2] ) { if( pHeader->szRevision[2] > HeaderComp.szRevision[2] ) { fOKToCopy = TRUE; } else { SYSTEMTIME sysTimeFile; SYSTEMTIME sysTimeResource; FILETIME ftFile; FILETIME ftRes;
ZeroMemory( &sysTimeFile, sizeof(sysTimeFile) ); ZeroMemory( &sysTimeResource, sizeof(sysTimeResource) );
for( idxMonth = 0; idxMonth < 12; idxMonth++ ) { if( !_strnicmp( (char*)pHeader->szMonth, g_szMonths[idxMonth], sizeof(pHeader->szMonth) ) ) { sysTimeResource.wMonth = idxMonth + 1; }
if( !_strnicmp( (char*)HeaderComp.szMonth, g_szMonths[idxMonth], sizeof(HeaderComp.szMonth) ) ) { sysTimeFile.wMonth = idxMonth + 1; } }
sysTimeResource.wDay = ( pHeader->szDay[0] - '0' ) * 10 + ( pHeader->szDay[1] - '0' ); sysTimeFile.wDay = ( HeaderComp.szDay[0] - '0' ) * 10 + ( HeaderComp.szDay[1] - '0' );
sysTimeResource.wYear= ( pHeader->szYear[0] - '0' ) * 1000 + ( pHeader->szYear[1] - '0' ) * 100 + ( pHeader->szYear[2] - '0' ) * 10 + ( pHeader->szYear[3] - '0' );
sysTimeFile.wYear= ( HeaderComp.szYear[0] - '0' ) * 1000 + ( HeaderComp.szYear[1] - '0' ) * 100 + ( HeaderComp.szYear[2] - '0' ) * 10 + ( HeaderComp.szYear[3] - '0' );
sysTimeResource.wHour = ( pHeader->szTime[0] - '0' ) * 10 + ( pHeader->szTime[1] - '0' ); sysTimeFile.wHour = ( HeaderComp.szTime[0] - '0' ) * 10 + ( HeaderComp.szTime[1] - '0' );
sysTimeResource.wMinute = ( pHeader->szTime[0] - '0' ) * 10 + ( pHeader->szTime[1] - '0' ); sysTimeFile.wMinute = ( HeaderComp.szTime[3] - '0' ) * 10 + ( HeaderComp.szTime[4] - '0' );
SystemTimeToFileTime( &sysTimeResource, &ftRes ); SystemTimeToFileTime( &sysTimeFile, &ftFile );
fOKToCopy = ( CompareFileTime( &ftRes, &ftFile ) > 0 ); } } } else { fOKToCopy = TRUE; } } } }
if( fOKToCopy ) { SetFilePointer( hFileWrite, 0, NULL, FILE_BEGIN ); SetEndOfFile( hFileWrite );
if( !WriteFile( hFileWrite, pDataFile, cResourceBytes, &cBytesWritten, NULL ) ) { pData->hr = HRESULT_FROM_WIN32( GetLastError() ); } }
CloseHandle( hFileWrite ); return( TRUE ); }
HRESULT CopyFileResToDirectory( HINSTANCE hInstance, LPCSTR pszDestDir ) { HRESULT hr = S_OK; RezCallbackData data; DWORD dwAttributes; CHAR szCreatePath[MAX_PATH]; LPCSTR pszCreateDir = NULL;
if( NULL == hInstance || NULL == pszDestDir ) { return( E_INVALIDARG ); }
dwAttributes = GetFileAttributesA( pszDestDir ); if( -1 != dwAttributes && (!(FILE_ATTRIBUTE_DIRECTORY & dwAttributes )) ) { return( E_INVALIDARG ); } if( -1 == dwAttributes ) { pszCreateDir = pszDestDir;
while( *pszCreateDir && SUCCEEDED( hr ) ) { if( *pszCreateDir == '\\' ) { if( ( (LPBYTE)pszCreateDir - (LPBYTE)pszDestDir ) > sizeof(szCreatePath) ) { hr = E_INVALIDARG; continue; } else { pszCreateDir = CharNextA( pszCreateDir );
memcpy( szCreatePath, pszDestDir, (LPBYTE)pszCreateDir-(LPBYTE)pszDestDir ); ((LPBYTE)szCreatePath)[ (LPBYTE)pszCreateDir - (LPBYTE)pszDestDir] = '\0';
if( strlen(szCreatePath) != 3 && // 3 indicates the drive path
!CreateDirectoryA( szCreatePath, NULL ) ) { hr = HRESULT_FROM_WIN32( GetLastError() );
if( HRESULT_FROM_WIN32( ERROR_ALREADY_EXISTS ) == hr ) { hr = S_OK; } } continue; } }
pszCreateDir = CharNextA( pszCreateDir ); }
if( SUCCEEDED( hr ) ) { if( strlen(pszDestDir) != 3 && // 3 indicates the drive path
!CreateDirectoryA( pszDestDir, NULL ) ) { hr = HRESULT_FROM_WIN32( GetLastError() );
if( HRESULT_FROM_WIN32( ERROR_ALREADY_EXISTS ) == hr ) { hr = S_OK; } } } }
#ifdef LYRA_HANDLES_HIDDEN
if( SUCCEEDED( hr ) ) { dwAttributes = GetFileAttributesA( pszDestDir );
if( (DWORD)-1 != dwAttributes ) { SetFileAttributesA( pszDestDir, dwAttributes | FILE_ATTRIBUTE_HIDDEN ); } } #endif
if( SUCCEEDED( hr ) ) { data.pszDirectory = pszDestDir;
if( !EnumResourceNamesA( hInstance, "File", (ENUMRESNAMEPROC)RezNamesCallback, (LPARAM) &data) ) { hr = HRESULT_FROM_WIN32( GetLastError() ); } }
if( SUCCEEDED( hr ) ) { hr = data.hr; }
return( hr ); }
|