You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
361 lines
12 KiB
361 lines
12 KiB
#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 );
|
|
}
|