Changeset 637


Ignore:
Timestamp:
11/30/08 07:43:40 (6 years ago)
Author:
lowjoel
Message:

I've rewrote the packaging code to support Authenticode signing; the setup files are stored as Resources instead of just appending to stream which will be corrupted by the Authenticode process.

Location:
branches/eraser6
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Eraser.sln

    r633 r637  
    55    ProjectSection(SolutionItems) = preProject 
    66        Strong Name.snk = Strong Name.snk 
    7         Version.cs = Version.cs 
    87    EndProjectSection 
    98EndProject 
  • branches/eraser6/Installer/Bootstrapper/Bootstrapper.cpp

    r588 r637  
    4545}; 
    4646 
     47const wchar_t *ResourceName = MAKEINTRESOURCE(101); 
     48 
    4749int Integrate(const std::wstring& destItem, const std::wstring& package) 
    4850{ 
    4951    //Open a handle to ourselves 
    50     Handle srcFile(CreateFileW(Application::Get().GetPath().c_str(), GENERIC_READ, 
    51         FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); 
    52     if (srcFile == INVALID_HANDLE_VALUE) 
    53         throw GetErrorMessage(GetLastError()); 
    54  
    55     //Copy ourselves, in essence. 
    56     Handle destFile(CreateFileW(destItem.c_str(), GENERIC_WRITE, 0, NULL, 
    57         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); 
    58     if (destFile == INVALID_HANDLE_VALUE) 
    59         throw GetErrorMessage(GetLastError()); 
    60  
    6152    DWORD lastOperation = 0; 
    62     char buffer[262144]; 
    63     while (ReadFile(srcFile, buffer, sizeof(buffer), &lastOperation, NULL) && lastOperation) 
    64         WriteFile(destFile, buffer, lastOperation, &lastOperation, NULL); 
    65  
    66     //Fill to the predetermined file position 
    67     int amountToWrite = DataOffset - GetFileSize(srcFile, NULL); 
    68     if (amountToWrite < 0) 
    69         throw std::wstring(L"The file size of the binary is larger than the data " 
    70             L"offset position; recompile the package, increasing DataOffset."); 
    71     ZeroMemory(buffer, sizeof(buffer)); 
    72     while (amountToWrite > 0) 
    73     { 
    74         WriteFile(destFile, buffer, std::min<unsigned>(amountToWrite, sizeof(buffer)), 
    75             &lastOperation, NULL); 
    76         amountToWrite -= lastOperation; 
    77     } 
    78  
    79     //Then copy the package 
     53    { 
     54        Handle srcFile(CreateFileW(Application::Get().GetPath().c_str(), GENERIC_READ, 
     55            FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); 
     56        if (srcFile == INVALID_HANDLE_VALUE) 
     57            throw GetErrorMessage(GetLastError()); 
     58 
     59        //Copy ourselves 
     60        Handle destFile(CreateFileW(destItem.c_str(), GENERIC_WRITE, 0, NULL, 
     61            CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); 
     62        if (destFile == INVALID_HANDLE_VALUE) 
     63            throw GetErrorMessage(GetLastError()); 
     64 
     65        char buffer[262144]; 
     66        while (ReadFile(srcFile, buffer, sizeof(buffer), &lastOperation, NULL) && lastOperation) 
     67            WriteFile(destFile, buffer, lastOperation, &lastOperation, NULL); 
     68    } 
     69 
     70    //Start updating the resource in the destination item 
     71    HANDLE resHandle(BeginUpdateResource(destItem.c_str(), false)); 
     72    if (resHandle == NULL) 
     73        throw GetErrorMessage(GetLastError()); 
     74 
     75    //Read the package into memory 
    8076    Handle packageFile(CreateFileW(package.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, 
    8177        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL)); 
    8278    if (packageFile == INVALID_HANDLE_VALUE) 
    8379        throw GetErrorMessage(GetLastError()); 
    84     int error; 
    85     SetLastError(0); 
    86     while (ReadFile(packageFile, buffer, sizeof(buffer), &lastOperation, NULL) && lastOperation) 
    87     { 
    88         WriteFile(destFile, buffer, lastOperation, &lastOperation, NULL); 
    89         error = GetLastError(); 
    90     } 
     80 
     81    unsigned long packageSize = GetFileSize(packageFile, NULL); 
     82    char* inputData = new char[packageSize]; 
     83    if (!ReadFile(packageFile, inputData, packageSize, &lastOperation, NULL) || lastOperation != packageSize) 
     84        throw GetErrorMessage(GetLastError()); 
     85 
     86    //Add the package to the application resource section 
     87    if (!UpdateResource(resHandle, RT_RCDATA, ResourceName, MAKELANGID(LANG_NEUTRAL, 
     88        SUBLANG_DEFAULT), inputData, packageSize)) 
     89    { 
     90        throw GetErrorMessage(GetLastError()); 
     91    } 
     92 
     93    //Complete the update 
     94    if (!EndUpdateResource(resHandle, false))  
     95        throw GetErrorMessage(GetLastError()); 
    9196    return 0; 
    9297} 
    9398 
    9499/// ISzInStream interface for extracting the archives. 
    95 struct LZFileStream 
     100struct LZMemStream 
    96101{ 
    97102public: 
    98103    /// Constructor. 
    99104    ///  
    100     /// \param[in] fileHandle A HANDLE to the file stream, returned by CreateFile. 
    101     LZFileStream(HANDLE fileHandle) 
    102     { 
    103         InStream.Read = LZFileStreamRead; 
    104         InStream.Seek = LzFileStreamSeek; 
    105         FileHandle = fileHandle; 
    106  
    107         FileRead = 0; 
    108         LARGE_INTEGER largeInt; 
    109         largeInt.QuadPart = 0; 
    110         if (!SetFilePointerEx(FileHandle, largeInt, &largeInt, FILE_CURRENT)) 
    111             throw GetErrorMessage(GetLastError()); 
    112         DataOffset = largeInt.QuadPart; 
    113  
    114         if (!GetFileSizeEx(fileHandle, &largeInt)) 
    115             throw GetErrorMessage(GetLastError()); 
    116         FileSize = largeInt.QuadPart - DataOffset; 
    117     } 
    118  
    119     ~LZFileStream() 
    120     { 
    121         CloseHandle(FileHandle); 
     105    /// \param[in] buffer The buffer containing the data to present as a stream. 
     106    /// \param[in] bufferSize The size of the buffer passed in. 
     107    /// \param[in] deleteOnDestroy True if the the buffer should be freed (using delete[]) 
     108    ///                            after the stream is destroyed. 
     109    LZMemStream(void* buffer, size_t bufferSize, bool deleteOnDestroy) 
     110    { 
     111        InStream.Read = LZMemStreamRead; 
     112        InStream.Seek = LzMemStreamSeek; 
     113 
     114        Buffer = static_cast<char*>(buffer); 
     115        BufferRead = 0; 
     116        BufferSize = bufferSize; 
     117 
     118        DeleteOnDestroy = deleteOnDestroy; 
     119        CurrentOffset = 0; 
     120    } 
     121 
     122    ~LZMemStream() 
     123    { 
     124        if (DeleteOnDestroy) 
     125            delete[] Buffer; 
    122126    } 
    123127 
     
    125129 
    126130private: 
    127     HANDLE FileHandle; 
    128     long long DataOffset; 
    129     long long FileRead; 
    130     long long FileSize; 
    131  
    132     static SZ_RESULT LZFileStreamRead(void* object, void** bufferPtr, size_t size, 
     131    bool DeleteOnDestroy; 
     132    char* Buffer; 
     133    size_t BufferRead; 
     134    size_t BufferSize; 
     135    size_t CurrentOffset; 
     136 
     137    static SZ_RESULT LZMemStreamRead(void* object, void** bufferPtr, size_t size, 
    133138        size_t* processedSize) 
    134139    { 
    135         LZFileStream* s = static_cast<LZFileStream*>(object); 
     140        LZMemStream* s = static_cast<LZMemStream*>(object); 
    136141 
    137142        //Since we can allocate as much as we want to allocate, take a decent amount 
    138143        //of memory and stop. 
    139144        size = std::min(1048576u * 4, size); 
    140         static char* buffer = NULL; 
    141         if (buffer) 
    142             delete[] buffer; 
    143         buffer = new char[size]; 
    144  
    145         DWORD readSize = 0; 
    146         if (ReadFile(s->FileHandle, buffer, size, &readSize, NULL) && readSize != 0) 
    147         { 
    148             *bufferPtr = buffer; 
    149             *processedSize = readSize; 
    150             s->FileRead += readSize; 
    151  
    152             MainWindow& mainWin = Application::Get().GetTopWindow(); 
    153             mainWin.SetProgress((float)((double)s->FileRead / s->FileSize)); 
    154         } 
    155  
     145        static char* dstBuffer = NULL; 
     146        if (dstBuffer) 
     147            delete[] dstBuffer; 
     148        dstBuffer = new char[size]; 
     149 
     150        //Copy the memory to the provided buffer. 
     151        memcpy(dstBuffer, s->Buffer + s->CurrentOffset, size); 
     152        *bufferPtr = dstBuffer; 
     153        *processedSize = size; 
     154        s->BufferRead += size; 
     155        s->CurrentOffset += size; 
     156 
     157        MainWindow& mainWin = Application::Get().GetTopWindow(); 
     158        mainWin.SetProgress((float)((double)s->FileRead / s->FileSize)); 
    156159        return SZ_OK; 
    157160    } 
    158161 
    159     static SZ_RESULT LzFileStreamSeek(void *object, CFileSize pos) 
    160     { 
    161         LZFileStream* s = static_cast<LZFileStream*>(object); 
    162  
    163         LARGE_INTEGER value; 
    164         value.QuadPart = pos + s->DataOffset; 
    165         if (!SetFilePointerEx(s->FileHandle, value, NULL, FILE_BEGIN) && 
    166             GetLastError() != NO_ERROR) 
     162    static SZ_RESULT LzMemStreamSeek(void *object, CFileSize pos) 
     163    { 
     164        LZMemStream* s = static_cast<LZMemStream*>(object); 
     165 
     166        if (pos > s->BufferSize) 
    167167            return SZE_FAIL; 
     168        s->CurrentOffset = pos; 
    168169        return SZ_OK; 
    169170    } 
     
    176177 
    177178    //Open the file 
    178 #if _DEBUG 
    179     HANDLE srcFile = CreateFileW((Application::Get().GetPath() + L".7z").c_str(), 
    180         GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    181     if (srcFile == INVALID_HANDLE_VALUE) 
    182         throw GetErrorMessage(GetLastError()); 
    183 #else 
    184     HANDLE srcFile = CreateFileW(Application::Get().GetPath().c_str(), GENERIC_READ, 
    185         FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 
    186     if (srcFile == INVALID_HANDLE_VALUE) 
    187         throw GetErrorMessage(GetLastError()); 
    188  
    189     //Seek to the 196th kb. 
    190     LARGE_INTEGER fPos; 
    191     fPos.QuadPart = DataOffset; 
    192  
    193     if (!SetFilePointerEx(srcFile, fPos, &fPos, FILE_BEGIN)) 
    194         throw GetErrorMessage(GetLastError()); 
    195 #endif 
     179    HMODULE currProcess = static_cast<HMODULE>(Application::Get().GetInstance()); 
     180    HANDLE hResource(FindResource(currProcess, ResourceName, RT_RCDATA)); 
     181    if (!hResource) 
     182        throw GetErrorMessage(GetLastError()); 
     183 
     184    HANDLE hResLoad(LoadResource(currProcess, static_cast<HRSRC>(static_cast<HANDLE>(hResource)))); 
     185    if (!hResLoad) 
     186        throw GetErrorMessage(GetLastError()); 
     187 
     188    //Lock the data into global memory. 
     189    unsigned long resourceSize = SizeofResource(currProcess, static_cast<HRSRC>( 
     190        static_cast<HANDLE>(hResource))); 
     191    void* resourceBuffer = LockResource(hResLoad); 
     192    if (!resourceBuffer) 
     193        throw GetErrorMessage(GetLastError()); 
    196194 
    197195    //7z archive database structure 
     
    205203 
    206204    //Initialize the CRC and database structures 
    207     LZFileStream stream(srcFile); 
     205    LZMemStream stream(resourceBuffer, resourceSize, false); 
    208206    CrcGenerateTable(); 
    209207    SzArDbExInit(&db); 
  • branches/eraser6/Installer/Bootstrapper/Bootstrapper.h

    r546 r637  
    119119    static Application& Get(); 
    120120 
     121    /// Gets the HINSTANCE variable for the current 
     122    HINSTANCE GetInstance(); 
     123 
    121124    /// Retrieves the path to the executable file. 
    122125    std::wstring GetPath(); 
  • branches/eraser6/Installer/Bootstrapper/Main.cpp

    r546 r637  
    179179} 
    180180 
     181HINSTANCE Application::GetInstance() 
     182{ 
     183    return ::hInstance; 
     184} 
     185 
    181186MainWindow& Application::GetTopWindow() 
    182187{ 
Note: See TracChangeset for help on using the changeset viewer.