Index: src/chext/ShellExtControl.cpp =================================================================== diff -u -rd3f78bbf9677c239814dae1041f24f0bbc821db9 -rd0fdcc905035e648382256101a3d99f429af6d56 --- src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision d3f78bbf9677c239814dae1041f24f0bbc821db9) +++ src/chext/ShellExtControl.cpp (.../ShellExtControl.cpp) (revision d0fdcc905035e648382256101a3d99f429af6d56) @@ -18,13 +18,108 @@ ***************************************************************************/ #include "stdafx.h" #include "chext.h" +#include #include "ShellExtControl.h" #include "../common/version.h" -STDMETHODIMP CShellExtControl::GetVersion(LONG* plVersion) +CShellExtControl::CShellExtControl() : + m_pShellExtData(NULL), + m_hMemory(NULL), + m_hMutex(NULL) { - if(!plVersion) + // create protection mutex + m_hMutex = ::CreateMutex(NULL, FALSE, _T("CHShellExtControlDataMutex")); + if(!m_hMutex) + return; + + DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); + if(dwRes != WAIT_OBJECT_0) + return; + + // memory mapped file + m_hMemory = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(SHELLEXT_DATA), _T("CHShellExtControlData")); // name of map object + if(!m_hMemory) + { + ReleaseMutex(m_hMutex); + CloseHandle(m_hMutex); + return; + } + + DWORD dwLastError = GetLastError(); + m_pShellExtData = (SHELLEXT_DATA*)MapViewOfFile(m_hMemory, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); + if(!m_pShellExtData) + { + ReleaseMutex(m_hMutex); + CloseHandle(m_hMutex); + CloseHandle(m_hMemory); + m_hMemory = NULL; + return; + } + + if(dwLastError != ERROR_ALREADY_EXISTS) + { + m_pShellExtData->m_lFlags = 0; + m_pShellExtData->m_lID = GetTickCount(); + } + + ReleaseMutex(m_hMutex); +} + +CShellExtControl::~CShellExtControl() +{ + if(m_pShellExtData) + { + UnmapViewOfFile((LPVOID)m_pShellExtData); + + // Close the process's handle to the file-mapping object. + CloseHandle(m_hMemory); + } + + if(m_hMutex) + CloseHandle(m_hMutex); +} + +STDMETHODIMP CShellExtControl::GetVersion(LONG* plVersion, BSTR* pbstrVersion) +{ + if(!plVersion || !pbstrVersion || (*pbstrVersion)) return E_INVALIDARG; + (*plVersion) = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4; + _bstr_t strVer(SHELLEXT_PRODUCT_FULL_VERSION); + pbstrVersion = strVer.GetAddress(); + return S_OK; } + +STDMETHODIMP CShellExtControl::SetFlags(LONG lFlags, LONG lMask) +{ + if(!m_hMutex || !m_pShellExtData) + return E_FAIL; + + DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); + if(dwRes != WAIT_OBJECT_0) + return E_FAIL; + m_pShellExtData->m_lFlags = (m_pShellExtData->m_lFlags & ~lMask) | (lFlags & lMask); + + ReleaseMutex(m_hMutex); + + return S_OK; +} + +STDMETHODIMP CShellExtControl::GetFlags(LONG* plFlags) +{ + if(!m_hMutex || !m_pShellExtData) + return E_FAIL; + if(!plFlags) + return E_INVALIDARG; + + DWORD dwRes = WaitForSingleObject(m_hMutex, 10000); + if(dwRes != WAIT_OBJECT_0) + return E_FAIL; + + (*plFlags) = m_pShellExtData->m_lFlags; + + ReleaseMutex(m_hMutex); + + return S_OK; +}