//*************************************************************************** //* Copyright (c) Microsoft Corporation 1995. All rights reserved. * //*************************************************************************** //* * //* UPDFILE.C * //* * //*************************************************************************** //*************************************************************************** //* INCLUDE FILES * //*************************************************************************** #include //#include #include #include "resource.h" #include "updfile.h" #include "updres.h" //*************************************************************************** //* GLOBAL VARIABLES * //*************************************************************************** //*************************************************************************** //* * //* NAME: main * //* * //* SYNOPSIS: Main entry point for the program. * //* * //* REQUIRES: * //* * //* RETURNS: int: Always 0 * //* * //*************************************************************************** INT _cdecl main( INT argc, CHAR *argv[] ) { // ARGV[1] == Name of package // ARGV[2] == Name of file to add to package HANDLE hUpdateRes = NULL; HANDLE hFile = INVALID_HANDLE_VALUE; DWORD dwFileSize = 0; PSTR pszFileContents = NULL; DWORD dwBytes; HMODULE hModule; TCHAR szResName[20]; DWORD dwResNum; TCHAR szFileToAdd[MAX_PATH]; PSTR pszFileToAddFilename = NULL; TCHAR szPackage[MAX_PATH]; PSTR pszPackageFilename = NULL; DWORD dwHeaderSize = 0; PSTR pszTemp = NULL; DWORD dwReturnCode = 0; PDWORD pdwTemp = NULL; static const TCHAR c_szResNameTemplate[] = "UPDFILE%lu"; if ( argc != 3 ) { MsgBox( IDS_ERR_INVALID_ARGS ); dwReturnCode = 1; goto done; } dwFileSize = GetFullPathName( argv[1], sizeof(szPackage), szPackage, &pszPackageFilename ); if ( (dwFileSize+1) > sizeof(szPackage) || dwFileSize == 0 ) { MsgBox1Param( IDS_ERR_GET_FULL_PATH, argv[1] ); dwReturnCode = 1; goto done; } if ( ! FileExists( szPackage ) ) { MsgBox1Param( IDS_ERR_FILE_NOT_EXIST, argv[1] ); dwReturnCode = 1; goto done; } dwFileSize = GetFullPathName( argv[2], sizeof(szFileToAdd), szFileToAdd, &pszFileToAddFilename ); if ( (dwFileSize+1) > sizeof(szFileToAdd) || dwFileSize == 0 ) { MsgBox1Param( IDS_ERR_GET_FULL_PATH, argv[2] ); dwReturnCode = 1; goto done; } if ( ! FileExists( szFileToAdd ) ) { MsgBox1Param( IDS_ERR_FILE_NOT_EXIST, argv[2] ); dwReturnCode = 1; goto done; } // make sure the target file is not read-only file SetFileAttributes( szPackage, FILE_ATTRIBUTE_NORMAL ); hModule = LoadLibraryEx( szPackage, NULL, LOAD_LIBRARY_AS_DATAFILE | DONT_RESOLVE_DLL_REFERENCES ); if ( hModule == NULL ) { MsgBox1Param( IDS_ERR_LOAD_EXE, argv[1] ); dwReturnCode = 1; goto done; } for ( dwResNum = 0; ; dwResNum += 1 ) { wsprintf( szResName, c_szResNameTemplate, dwResNum ); if ( FindResource( hModule, szResName, RT_RCDATA ) == NULL ) { break; } } FreeLibrary( hModule ); hFile = CreateFile( szFileToAdd, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) { MsgBox1Param( IDS_ERR_OPEN_INPUT_FILE, argv[2] ); dwReturnCode = 1; goto done; } dwFileSize = GetFileSize( hFile, NULL ); dwHeaderSize = sizeof(DWORD) + sizeof(DWORD) + lstrlen(pszFileToAddFilename) + 1; // File Size + reserved DWORD + Filename\0 + File Contents pszFileContents = (PSTR) LocalAlloc( LPTR, dwHeaderSize + dwFileSize ); if ( ! pszFileContents ) { MsgBox( IDS_ERR_NO_MEMORY ); dwReturnCode = 1; goto done; } pdwTemp = (PDWORD) pszFileContents; *pdwTemp = dwFileSize; pdwTemp = (PDWORD) (pszFileContents + sizeof(DWORD)); *pdwTemp = MAXDWORD; pszTemp = pszFileContents + sizeof(DWORD) + sizeof(DWORD); lstrcpy( pszTemp, pszFileToAddFilename ); pszTemp = pszFileContents + dwHeaderSize; if ( ! ReadFile( hFile, pszTemp, dwFileSize, &dwBytes, NULL ) ) { MsgBox1Param( IDS_ERR_READ_INPUT_FILE, argv[2] ); dwReturnCode = 1; goto done; } CloseHandle( hFile ); hFile = INVALID_HANDLE_VALUE ; // Initialize the EXE file for resource editing hUpdateRes = LocalBeginUpdateResource( szPackage, FALSE ); if ( hUpdateRes == NULL ) { MsgBox1Param( IDS_ERR_BEGIN_UPD_RES, argv[1] ); dwReturnCode = 1; goto done; } if ( LocalUpdateResource( hUpdateRes, RT_RCDATA, szResName, MAKELANGID( LANG_ENGLISH, SUBLANG_ENGLISH_US ), pszFileContents, dwHeaderSize + dwFileSize ) == FALSE ) { MsgBox1Param( IDS_ERR_UPDATE_RES, argv[1] ); dwReturnCode = 1; goto done; } done: if ( hUpdateRes ) { // Write out modified EXE if success ((returncode = 0, means pass // in FALSE to update file (i.e., don't discard changes) if ( LocalEndUpdateResource( hUpdateRes, (dwReturnCode == 1) ) == FALSE ) { MsgBox1Param( IDS_ERR_END_UPD_RES, argv[1] ); dwReturnCode = 1; } } if ( pszFileContents ) { LocalFree( pszFileContents ); } if (hFile != INVALID_HANDLE_VALUE) { CloseHandle( hFile ) ; } if (dwReturnCode == 0) MsgBox2Param( IDS_SUCCESS, argv[2], argv[1] ); return dwReturnCode; } //*************************************************************************** //* * //* NAME: FileExists * //* * //* SYNOPSIS: Checks if a file exists. * //* * //* REQUIRES: pszFilename * //* * //* RETURNS: BOOL: TRUE if it exists, FALSE otherwise * //* * //*************************************************************************** BOOL FileExists( PCSTR pszFilename ) { HANDLE hFile; hFile = CreateFile( pszFilename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); if ( hFile == INVALID_HANDLE_VALUE ) { return( FALSE ); } CloseHandle( hFile ); return( TRUE ); } //*************************************************************************** //* * //* NAME: MsgBox2Param * //* * //* SYNOPSIS: Displays a message box with the specified string ID using * //* 2 string parameters. * //* * //* REQUIRES: hWnd: Parent window * //* nMsgID: String resource ID * //* szParam1: Parameter 1 (or NULL) * //* szParam2: Parameter 2 (or NULL) * //* uIcon: Icon to display (or 0) * //* uButtons: Buttons to display * //* * //* RETURNS: INT: ID of button pressed * //* * //* NOTES: Macros are provided for displaying 1 parameter or 0 * //* parameter message boxes. Also see ErrorMsg() macros. * //* * //*************************************************************************** VOID MsgBox2Param( UINT nMsgID, PCSTR c_pszParam1, PCSTR c_pszParam2 ) { TCHAR szMsgBuf[512]; PSTR pszMessage = NULL; static const TCHAR c_szError[] = "Unexpected Error. Could not load resource."; PSTR apszParams[2]; apszParams[0] = (PSTR) c_pszParam1; apszParams[1] = (PSTR) c_pszParam2; LoadSz( nMsgID, szMsgBuf, sizeof(szMsgBuf) ); if ( (*szMsgBuf) == '\0' ) { lstrcpy( szMsgBuf, c_szError ); } if ( FormatMessage( FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY | FORMAT_MESSAGE_ALLOCATE_BUFFER, szMsgBuf, 0, 0, (PSTR) (&pszMessage), 0, (va_list *)apszParams ) ) { printf( "\n%s\n\n", pszMessage ); LocalFree( pszMessage ); } } //*************************************************************************** //* * //* NAME: LoadSz * //* * //* SYNOPSIS: Loads specified string resource into buffer. * //* * //* REQUIRES: idString: * //* lpszBuf: * //* cbBuf: * //* * //* RETURNS: LPSTR: Pointer to the passed-in buffer. * //* * //* NOTES: If this function fails (most likely due to low memory), the * //* returned buffer will have a leading NULL so it is generally * //* safe to use this without checking for failure. * //* * //*************************************************************************** PSTR LoadSz( UINT idString, PSTR pszBuf, UINT cbBuf ) { // Clear the buffer and load the string if ( pszBuf ) { *pszBuf = '\0'; LoadString( NULL, idString, pszBuf, cbBuf ); } return pszBuf; }