1
1
// EsteidShlExt.cpp : Implementation of CEsteidShlExt
2
2
// http://msdn.microsoft.com/en-us/library/bb757020.aspx
3
3
4
- #include " stdafx.h"
5
4
#include " EsteidShlExt.h"
5
+ #include " resource.h"
6
+
7
+ #include < shellapi.h>
8
+ #include < shlwapi.h>
9
+ #include < uxtheme.h>
10
+
11
+ extern HINSTANCE instanceHandle;
6
12
7
13
typedef DWORD ARGB;
8
14
9
- bool HasAlpha (ARGB *pargb, SIZE &sizeImage, int cxRow)
15
+ bool HasAlpha (ARGB *pargb, const SIZE &sizeImage, int cxRow)
10
16
{
11
17
ULONG cxDelta = cxRow - sizeImage.cx ;
12
18
for (ULONG y = sizeImage.cy ; y; --y)
@@ -23,31 +29,16 @@ bool HasAlpha(ARGB *pargb, SIZE &sizeImage, int cxRow)
23
29
24
30
BITMAPINFO InitBitmapInfo (const SIZE &sizeImage)
25
31
{
26
- BITMAPINFO pbmi = {};
27
- pbmi.bmiHeader .biSize = sizeof (BITMAPINFOHEADER);
32
+ BITMAPINFO pbmi{{sizeof (BITMAPINFOHEADER)}};
28
33
pbmi.bmiHeader .biPlanes = 1 ;
29
34
pbmi.bmiHeader .biCompression = BI_RGB;
30
-
31
35
pbmi.bmiHeader .biWidth = sizeImage.cx ;
32
36
pbmi.bmiHeader .biHeight = sizeImage.cy ;
33
37
pbmi.bmiHeader .biBitCount = 32 ;
34
38
return pbmi;
35
39
}
36
40
37
- HBITMAP Create32BitHBITMAP (HDC hdc, const SIZE &sizeImage, void **ppvBits)
38
- {
39
- BITMAPINFO bmi = InitBitmapInfo (sizeImage);
40
- if (HDC hdcUsed = hdc ? hdc : GetDC (nullptr ))
41
- {
42
- HBITMAP phBmp = CreateDIBSection (hdcUsed, &bmi, DIB_RGB_COLORS, ppvBits, nullptr , 0 );
43
- if (hdc != hdcUsed)
44
- ReleaseDC (NULL , hdcUsed);
45
- return phBmp;
46
- }
47
- return nullptr ;
48
- }
49
-
50
- HRESULT ConvertToPARGB32 (HDC hdc, ARGB *pargb, HBITMAP hbmp, SIZE &sizeImage, int cxRow)
41
+ HRESULT ConvertToPARGB32 (HDC hdc, ARGB *pargb, HBITMAP hbmp, const SIZE &sizeImage, int cxRow)
51
42
{
52
43
BITMAPINFO bmi = InitBitmapInfo (sizeImage);
53
44
HRESULT hr = E_OUTOFMEMORY;
@@ -77,7 +68,7 @@ HRESULT ConvertToPARGB32(HDC hdc, ARGB *pargb, HBITMAP hbmp, SIZE &sizeImage, in
77
68
return hr;
78
69
}
79
70
80
- HRESULT ConvertBufferToPARGB32 (HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon, SIZE &sizeIcon)
71
+ HRESULT ConvertBufferToPARGB32 (HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon, const SIZE &sizeIcon)
81
72
{
82
73
RGBQUAD *prgbQuad;
83
74
int cxRow = 0 ;
@@ -102,18 +93,24 @@ HRESULT ConvertBufferToPARGB32(HPAINTBUFFER hPaintBuffer, HDC hdc, HICON hicon,
102
93
103
94
CEsteidShlExt::CEsteidShlExt ()
104
95
{
105
- SIZE sizeIcon = { GetSystemMetrics (SM_CXSMICON), GetSystemMetrics (SM_CYSMICON) };
106
- if (HICON hIcon = (HICON)LoadImage (_AtlBaseModule. GetModuleInstance () , MAKEINTRESOURCE (IDB_DIGIDOCICO), IMAGE_ICON, sizeIcon.cx , sizeIcon.cy , LR_DEFAULTCOLOR|LR_CREATEDIBSECTION))
96
+ const SIZE sizeIcon { GetSystemMetrics (SM_CXSMICON), GetSystemMetrics (SM_CYSMICON) };
97
+ if (HICON hIcon = (HICON)LoadImage (instanceHandle , MAKEINTRESOURCE (IDB_DIGIDOCICO), IMAGE_ICON, sizeIcon.cx , sizeIcon.cy , LR_DEFAULTCOLOR|LR_CREATEDIBSECTION))
107
98
{
108
- if (HDC hdcDest = CreateCompatibleDC (nullptr )) {
109
- if ((m_DigidocBmp = Create32BitHBITMAP (hdcDest, sizeIcon, nullptr ))) {
110
- if (HBITMAP hbmpOld = (HBITMAP)SelectObject (hdcDest, m_DigidocBmp)) {
99
+ if (HDC hdcDest = CreateCompatibleDC (nullptr ))
100
+ {
101
+ BITMAPINFO bmi = InitBitmapInfo (sizeIcon);
102
+ if ((m_DigidocBmp = CreateDIBSection (hdcDest, &bmi, DIB_RGB_COLORS, nullptr , nullptr , 0 )))
103
+ {
104
+ if (HBITMAP hbmpOld = (HBITMAP)SelectObject (hdcDest, m_DigidocBmp))
105
+ {
111
106
RECT rcIcon = { 0 , 0 , sizeIcon.cx , sizeIcon.cy };
112
107
BLENDFUNCTION bfAlpha = { AC_SRC_OVER, 0 , 255 , AC_SRC_ALPHA };
113
108
BP_PAINTPARAMS paintParams = { sizeof (paintParams), BPPF_ERASE, nullptr , &bfAlpha };
114
109
HDC hdcBuffer;
115
- if (HPAINTBUFFER hPaintBuffer = BeginBufferedPaint (hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer)) {
116
- if (DrawIconEx (hdcBuffer, 0 , 0 , hIcon, sizeIcon.cx , sizeIcon.cy , 0 , nullptr , DI_NORMAL)) {
110
+ if (HPAINTBUFFER hPaintBuffer = BeginBufferedPaint (hdcDest, &rcIcon, BPBF_DIB, &paintParams, &hdcBuffer))
111
+ {
112
+ if (DrawIconEx (hdcBuffer, 0 , 0 , hIcon, sizeIcon.cx , sizeIcon.cy , 0 , nullptr , DI_NORMAL))
113
+ {
117
114
// If icon did not have an alpha channel, we need to convert buffer to PARGB.
118
115
ConvertBufferToPARGB32 (hPaintBuffer, hdcDest, hIcon, sizeIcon);
119
116
}
@@ -136,13 +133,12 @@ CEsteidShlExt::~CEsteidShlExt()
136
133
STDMETHODIMP CEsteidShlExt::Initialize (
137
134
LPCITEMIDLIST /* pidlFolder */ , LPDATAOBJECT pDataObj, HKEY /* hProgID */ )
138
135
{
139
- FORMATETC fmt = { CF_HDROP, nullptr , DVASPECT_CONTENT, -1 , TYMED_HGLOBAL };
140
- STGMEDIUM stg = { TYMED_HGLOBAL };
136
+ FORMATETC fmt{ CF_HDROP, nullptr , DVASPECT_CONTENT, -1 , TYMED_HGLOBAL };
137
+ STGMEDIUM stg{ TYMED_HGLOBAL };
141
138
m_Files.clear ();
142
139
143
140
// Look for CF_HDROP data in the data object.
144
141
if (FAILED (pDataObj->GetData (&fmt, &stg))) {
145
- // Nope! Return an "invalid argument" error back to Explorer.
146
142
return E_INVALIDARG;
147
143
}
148
144
@@ -153,36 +149,21 @@ STDMETHODIMP CEsteidShlExt::Initialize(
153
149
return E_INVALIDARG;
154
150
}
155
151
156
- // Sanity check - make sure there is at least one filename.
157
- UINT nFiles = DragQueryFile (hDrop, 0xFFFFFFFF , nullptr , 0 );
158
- if (nFiles == 0 ) {
159
- GlobalUnlock (stg.hGlobal );
160
- ReleaseStgMedium (&stg);
161
- return E_INVALIDARG;
162
- }
163
-
164
- for (UINT i = 0 ; i < nFiles; i++) {
152
+ for (UINT i = 0 , nFiles = DragQueryFile (hDrop, 0xFFFFFFFF , nullptr , 0 ); i < nFiles; i++) {
165
153
// Get path length in chars
166
154
UINT len = DragQueryFile (hDrop, i, nullptr , 0 );
167
155
if (len == 0 || len >= MAX_PATH)
168
156
continue ;
169
157
170
158
// Get the name of the file
171
- TCHAR szFile[MAX_PATH];
172
- if (DragQueryFile (hDrop, i, szFile, len+1 ) == 0 )
173
- continue ;
174
-
175
- tstring str = tstring (szFile);
176
- if (str.empty ())
177
- continue ;
178
-
179
- m_Files.push_back (str);
159
+ auto &szFile = m_Files.emplace_back (len, 0 );
160
+ if (DragQueryFile (hDrop, i, szFile.data (), len + 1 ) != len)
161
+ m_Files.pop_back ();
180
162
}
181
163
182
164
GlobalUnlock (stg.hGlobal );
183
165
ReleaseStgMedium (&stg);
184
166
185
- // Don't show menu if no items were found
186
167
return m_Files.empty () ? E_INVALIDARG : S_OK;
187
168
}
188
169
@@ -194,17 +175,17 @@ STDMETHODIMP CEsteidShlExt::QueryContextMenu(
194
175
if (uFlags & CMF_DEFAULTONLY)
195
176
return MAKE_HRESULT (SEVERITY_SUCCESS, FACILITY_NULL, 0 );
196
177
197
- PCTCH sign = _T ( " Sign digitally" ) ;
198
- PCTCH encrypt = _T ( " Encrypt" ) ;
178
+ LPCWSTR sign = L " Sign digitally" ;
179
+ LPCWSTR encrypt = L " Encrypt" ;
199
180
switch (PRIMARYLANGID (GetUserDefaultUILanguage ()))
200
181
{
201
182
case LANG_ESTONIAN:
202
- sign = _T ( " Allkirjasta digitaalselt" ) ;
203
- encrypt = _T ( " Krüpteeri" ) ;
183
+ sign = L " Allkirjasta digitaalselt" ;
184
+ encrypt = L " Krüpteeri" ;
204
185
break ;
205
186
case LANG_RUSSIAN:
206
- sign = _T ( " Подписать дигитально" ) ;
207
- encrypt = _T ( " Зашифровать" ) ;
187
+ sign = L " Подписать дигитально" ;
188
+ encrypt = L " Зашифровать" ;
208
189
break ;
209
190
default : break ;
210
191
}
@@ -222,24 +203,26 @@ STDMETHODIMP CEsteidShlExt::QueryContextMenu(
222
203
STDMETHODIMP CEsteidShlExt::GetCommandString (
223
204
UINT_PTR idCmd, UINT uFlags, UINT * /* pwReserved */ , LPSTR pszName, UINT cchMax)
224
205
{
225
- USES_CONVERSION;
226
-
227
206
// Check idCmd, it must be 0 or 1 since we have only two menu items.
228
207
if (idCmd > MENU_ENCRYPT)
229
208
return E_INVALIDARG;
230
209
231
210
// If Explorer is asking for a help string, copy our string into the
232
211
// supplied buffer.
233
212
if (uFlags & GCS_HELPTEXT) {
234
- LPCTSTR szText = idCmd == MENU_SIGN ? _T (" Allkirjasta valitud failid digitaalselt" ) : _T (" Krüpteeri valitud failid" );
235
-
236
213
if (uFlags & GCS_UNICODE) {
214
+ LPCWSTR szText = idCmd == MENU_SIGN
215
+ ? L" Allkirjasta valitud failid digitaalselt"
216
+ : L" Krüpteeri valitud failid" ;
237
217
// We need to cast pszName to a Unicode string, and then use the
238
218
// Unicode string copy API.
239
- lstrcpynW (LPWSTR (pszName), T2CW ( szText) , int (cchMax));
219
+ lstrcpynW (LPWSTR (pszName), szText, int (cchMax));
240
220
} else {
221
+ LPCSTR szText = idCmd == MENU_SIGN
222
+ ? " Allkirjasta valitud failid digitaalselt"
223
+ : " Krüpteeri valitud failid" ;
241
224
// Use the ANSI string copy API to return the help string.
242
- lstrcpynA (pszName, T2CA ( szText) , int (cchMax));
225
+ lstrcpynA (pszName, szText, int (cchMax));
243
226
}
244
227
245
228
return S_OK;
@@ -248,59 +231,47 @@ STDMETHODIMP CEsteidShlExt::GetCommandString(
248
231
return E_INVALIDARG;
249
232
}
250
233
251
- bool WINAPI CEsteidShlExt::FindRegistryInstallPath (tstring* path)
234
+ bool WINAPI CEsteidShlExt::FindRegistryInstallPath (std::wstring & path)
252
235
{
253
- static PCTCH IDCARD_REGKEY = _T (" SOFTWARE\\ RIA\\ Open-EID" );
254
- static PCTCH IDCARD_REGVALUE = _T (" Installed" );
255
- HKEY hkey;
256
- DWORD dwSize = MAX_PATH * sizeof (TCHAR);
257
- TCHAR szInstalldir[MAX_PATH];
258
- LSTATUS dwRet = RegOpenKeyEx (HKEY_LOCAL_MACHINE, IDCARD_REGKEY, 0 , KEY_QUERY_VALUE, &hkey);
259
- if (dwRet == ERROR_SUCCESS) {
260
- dwRet = RegQueryValueEx (hkey, IDCARD_REGVALUE, nullptr , nullptr , LPBYTE (szInstalldir), &dwSize);
261
- RegCloseKey (hkey);
262
- *path = tstring (szInstalldir);
263
- return true ;
264
- }
265
- dwRet = RegOpenKeyEx (HKEY_CURRENT_USER, IDCARD_REGKEY, 0 , KEY_QUERY_VALUE, &hkey);
266
- if (dwRet == ERROR_SUCCESS) {
267
- RegCloseKey (hkey);
268
- *path = tstring (szInstalldir);
269
- return true ;
270
- }
271
- return false ;
236
+ HKEY hkey{};
237
+ if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, L" SOFTWARE\\ RIA\\ Open-EID" , 0 , KEY_QUERY_VALUE, &hkey) != ERROR_SUCCESS)
238
+ return false ;
239
+ DWORD dwSize = path.size () * sizeof (TCHAR);
240
+ bool result = true ;
241
+ if (RegQueryValueEx (hkey, L" Installed" , nullptr , nullptr , LPBYTE (path.data ()), &dwSize) == ERROR_SUCCESS)
242
+ path.resize (dwSize / sizeof (TCHAR) - 1 ); // size includes any terminating null
243
+ else
244
+ result = false ;
245
+ RegCloseKey (hkey);
246
+ return result;
272
247
}
273
248
274
249
STDMETHODIMP CEsteidShlExt::ExecuteDigidocclient (LPCMINVOKECOMMANDINFO /* pCmdInfo */ , bool crypto)
275
250
{
276
251
if (m_Files.empty ())
277
252
return E_INVALIDARG;
278
253
279
- tstring path (MAX_PATH, 0 );
280
- tstring command (MAX_PATH, 0 );
254
+ std::wstring path (MAX_PATH, 0 );
281
255
282
256
// Read the location of the installation from registry
283
- if (!FindRegistryInstallPath (&path)) {
284
- // .. and fall back to directory where shellext resides if not found from registry
285
- GetModuleFileName (_AtlBaseModule.m_hInst , &path[0 ], MAX_PATH);
286
- path.resize (path.find_last_of (_T (' \\ ' )) + 1 );
287
- }
288
-
289
- command = path + _T (" qdigidoc4.exe" );
290
- if (PathFileExists (command.c_str ()) != 1 ) {
291
- // Replace "c:\Program Files\" with "c:\Program Files (x86)\"
292
- command.insert (16 , _T (" (x86)" ));
257
+ if (!FindRegistryInstallPath (path)) {
258
+ // .. and fall back to directory where shellext resides if not found from registry
259
+ GetModuleFileName (instanceHandle, path.data (), path.size ());
260
+ path.resize (path.find_last_of (L' \\ ' ) + 1 );
293
261
}
294
262
263
+ path += L" qdigidoc4.exe" ;
295
264
// Construct command line arguments to pass to qdigidocclient.exe
296
- tstring parameters = crypto ? _T (" \" -crypto\" " ) : _T (" \" -sign\" " );
297
- for (const tstring &file: m_Files)
298
- parameters += _T (" \" " ) + file + _T (" \" " );
299
-
300
- SHELLEXECUTEINFO seInfo = { sizeof (SHELLEXECUTEINFO) };
301
- seInfo.lpFile = command.c_str ();
302
- seInfo.lpParameters = parameters.c_str ();
303
- seInfo.nShow = SW_SHOW;
265
+ std::wstring parameters = crypto ? L" \" -crypto\" " : L" \" -sign\" " ;
266
+ for (const auto &file: m_Files)
267
+ parameters += L" \" " + file + L" \" " ;
268
+
269
+ SHELLEXECUTEINFO seInfo{
270
+ .cbSize = sizeof (SHELLEXECUTEINFO),
271
+ .lpFile = path.c_str (),
272
+ .lpParameters = parameters.c_str (),
273
+ .nShow = SW_SHOW
274
+ };
304
275
return ShellExecuteEx (&seInfo) ? S_OK : S_FALSE;
305
276
}
306
277
0 commit comments