Changeset 759


Ignore:
Timestamp:
12/9/2008 8:40:30 AM (6 years ago)
Author:
lowjoel
Message:

-Replace the Eraser program entry points with those that retunr ints for statuses to be returned to the shell extension
-Create a default constructor for the Handle class to allow for the initialisation of NULL handles
-Factor out the string formatting code to the FormatString? function. Allows for reuse later on
-Replace all new[]'s and selete[]'s with std::vector as the buffer to prevent memory leaks
-Implemented error checking when the Eraser binary is called from the shell extension. If the process returns an error status, we must be sure to read the output pipe for the error and display it to the user.

Location:
branches/eraser6
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Eraser/Program.cs

    r756 r759  
    4141        /// </summary> 
    4242        [STAThread] 
    43         static void Main(string[] commandLine) 
     43        static int Main(string[] commandLine) 
    4444        { 
    4545            //Trivial case: no command parameters 
     
    5757                else 
    5858                { 
    59                     CommandMain(commandLine); 
     59                    return CommandMain(commandLine); 
    6060                } 
    6161            } 
     
    6363            //The other trivial case: definitely a console application. 
    6464            else 
    65                 CommandMain(commandLine); 
     65                return CommandMain(commandLine); 
     66 
     67            //No error. 
     68            return 0; 
    6669        } 
    6770 
     
    7073        /// </summary> 
    7174        /// <param name="commandLine">The command line parameters passed to Eraser.</param> 
    72         private static void CommandMain(string[] commandLine) 
     75        private static int CommandMain(string[] commandLine) 
    7376        { 
    7477            //True if the user specified a quiet command. 
     
    8285                using (ManagerLibrary library = new ManagerLibrary(new Settings())) 
    8386                    program.Run(); 
     87 
     88                return 1; 
    8489            } 
    8590            catch (Exception e) 
  • branches/eraser6/ShellExt/CtxMenu.cpp

    r755 r759  
    6464{ 
    6565public: 
     66    Handle() 
     67    { 
     68        Object = NULL; 
     69    } 
     70 
    6671    Handle(handleType handle) 
    6772    { 
     
    8287    handleType Object; 
    8388}; 
     89 
     90Handle<HANDLE>::~Handle() 
     91{ 
     92    CloseHandle(Object); 
     93} 
    8494 
    8595Handle<HKEY>::~Handle() 
     
    98108 
    99109        //Check if the shell extension has been disabled. 
    100         Handle<HKEY> eraserKey(NULL); 
     110        Handle<HKEY> eraserKey; 
    101111        LONG openKeyResult = RegOpenKeyEx(HKEY_CURRENT_USER, 
    102112            L"Software\\Eraser\\Eraser 6\\3460478d-ed1b-4ecc-96c9-2ca0e8500557\\", 0, 
     
    516526            if (!(pCmdInfo->fMask & CMIC_MASK_FLAG_NO_UI)) 
    517527            { 
    518                 std::wstring formatStrSrc(LoadString(IDS_ERROR_UNKNOWNACTION)); 
    519                 size_t bufferSize = formatStrSrc.length() + 1; 
    520                 wchar_t* formatStr = new wchar_t[bufferSize]; 
    521                 wcscpy_s(formatStr, bufferSize, formatStrSrc.c_str()); 
    522  
    523                 wchar_t* buffer = NULL; 
    524                 while (buffer == NULL) 
    525                 { 
    526                     buffer = new wchar_t[bufferSize *= 2]; 
    527                     int result = swprintf_s(buffer, bufferSize, formatStr, 
    528                         VerbMenuIndices[LOWORD(pCmdInfo->lpVerb)]); 
    529  
    530                     if (result == -1) 
    531                     { 
    532                         delete[] buffer; 
    533                         buffer = NULL; 
    534                     } 
    535                     else if (result > 0 && static_cast<unsigned>(result) < bufferSize) 
    536                     { 
    537                         break; 
    538                     } 
    539                 } 
    540                  
    541                 if (buffer != NULL) 
    542                 { 
    543                     MessageBox(pCmdInfo->hwnd, buffer, L"Eraser Shell Extension", MB_OK | MB_ICONERROR); 
    544                     delete[] buffer; 
    545                 } 
     528                MessageBox(pCmdInfo->hwnd, FormatString(LoadString(IDS_ERROR_UNKNOWNACTION), 
     529                    VerbMenuIndices[LOWORD(pCmdInfo->lpVerb)]).c_str(), 
     530                    LoadString(IDS_ERASERSHELLEXT).c_str(), MB_OK | MB_ICONERROR); 
    546531            } 
    547532        } 
     
    575560            startupInfo.dwFlags = STARTF_USESHOWWINDOW; 
    576561            startupInfo.wShowWindow = static_cast<WORD>(pCmdInfo->nShow); 
     562            startupInfo.hStdInput = startupInfo.hStdOutput = startupInfo.hStdError = 
     563                INVALID_HANDLE_VALUE; 
     564 
     565            //Create handles for output redirection 
     566            Handle<HANDLE> readPipe; 
     567            HANDLE writePipe; 
     568            SECURITY_ATTRIBUTES security; 
     569            ZeroMemory(&security, sizeof(security)); 
     570            security.nLength = sizeof(security); 
     571            security.lpSecurityDescriptor = NULL; 
     572            security.bInheritHandle = true; 
     573 
     574            if (CreatePipe(&static_cast<HANDLE&>(readPipe), &writePipe, &security, 0)) 
     575            { 
     576                startupInfo.dwFlags |= STARTF_USESTDHANDLES; 
     577                startupInfo.hStdOutput = startupInfo.hStdError = 
     578                    writePipe; 
     579            } 
     580 
    577581            PROCESS_INFORMATION processInfo; 
    578582            ZeroMemory(&processInfo, sizeof(processInfo)); 
     
    582586                         << L"\" -q " << commandLine; 
    583587            std::wstring cmdLine(finalCmdLine.str()); 
    584             wchar_t* buffer = new wchar_t[cmdLine.length() + 1]; 
    585             wcscpy_s(buffer, cmdLine.length() + 1, cmdLine.c_str()); 
    586  
    587             if (!CreateProcess(NULL, buffer, NULL, NULL, false, CREATE_NO_WINDOW, 
     588            std::vector<wchar_t> buffer(cmdLine.length() + 1); 
     589            wcscpy_s(&buffer.front(), cmdLine.length() + 1, cmdLine.c_str()); 
     590 
     591            if (!CreateProcess(NULL, &buffer.front(), NULL, NULL, true, CREATE_NO_WINDOW, 
    588592                NULL, NULL, &startupInfo, &processInfo)) 
    589593            { 
     
    591595                { 
    592596                    MessageBox(pCmdInfo->hwnd, LoadString(IDS_ERROR_CANNOTFINDERASER).c_str(), 
    593                         L"Eraser Shell Extension", MB_OK | MB_ICONERROR); 
     597                        LoadString(IDS_ERASERSHELLEXT).c_str(), MB_OK | MB_ICONERROR); 
    594598                } 
    595599 
    596                 delete[] buffer; 
    597600                return E_UNEXPECTED; 
    598601            } 
    599602 
    600             delete[] buffer; 
    601             CloseHandle(processInfo.hThread); 
    602             CloseHandle(processInfo.hProcess); 
     603            //Wait for the process to finish. 
     604            Handle<HANDLE> hProcess(processInfo.hProcess), 
     605                           hThread(processInfo.hThread); 
     606            CloseHandle(writePipe); 
     607            WaitForSingleObject(hProcess, static_cast<DWORD>(-1)); 
     608            DWORD exitCode = 0; 
     609             
     610            if (GetExitCodeProcess(processInfo.hProcess, &exitCode) && exitCode) 
     611            { 
     612                char buffer[8192]; 
     613                DWORD lastRead = 0; 
     614                std::wstring output; 
     615 
     616                while (ReadFile(readPipe, buffer, sizeof(buffer), &lastRead, NULL) && lastRead != 0) 
     617                { 
     618                    size_t lastConvert = 0; 
     619                    wchar_t wBuffer[8192]; 
     620                    if (!mbstowcs_s(&lastConvert, wBuffer, sizeof(wBuffer) / sizeof(wBuffer[0]), 
     621                        buffer, lastRead)) 
     622                    { 
     623                        output += std::wstring(wBuffer, lastConvert); 
     624                    } 
     625                } 
     626 
     627                //Show the error message. 
     628                MessageBox(pCmdInfo->hwnd, output.c_str(), LoadString(IDS_ERASERSHELLEXT).c_str(), 
     629                    MB_OK | MB_ICONERROR); 
     630            } 
    603631        } 
    604632 
     
    653681            return std::wstring(buffer, lastCount); 
    654682        return std::wstring(); 
     683    } 
     684 
     685    std::wstring CCtxMenu::FormatString(std::wstring formatString, ...) 
     686    { 
     687        std::vector<wchar_t> formatStr(formatString.length() + 1); 
     688        wcscpy_s(&formatStr.front(), formatStr.size(), formatString.c_str()); 
     689 
     690        std::vector<wchar_t> buffer(formatStr.size()); 
     691        for ( ; ; ) 
     692        { 
     693            buffer.resize(buffer.size() * 2); 
     694            va_list arguments; 
     695            va_start(arguments, formatString); 
     696            int result = vswprintf_s(&buffer.front(), buffer.size(), &formatStr.front(), 
     697                arguments); 
     698            va_end(arguments); 
     699 
     700            if (result > 0 && static_cast<unsigned>(result) < buffer.size()) 
     701            { 
     702                break; 
     703            } 
     704        } 
     705 
     706        //Return the result as a wstring 
     707        std::wstring result; 
     708        if (buffer.size() > 0) 
     709            result = &buffer.front(); 
     710        return result; 
    655711    } 
    656712 
  • branches/eraser6/ShellExt/CtxMenu.h

    r736 r759  
    8181 
    8282        static std::wstring LoadString(UINT stringID); 
     83        static std::wstring FormatString(std::wstring formatString, ...); 
    8384        static std::wstring GetHKeyPath(HKEY handle); 
    8485        static MENUITEMINFO* GetSeparator(); 
Note: See TracChangeset for help on using the changeset viewer.