ReactOS 0.4.16-dev-178-g8ba6102
shellutils.h
Go to the documentation of this file.
1/*
2 * Copyright 1999, 2000 Juergen Schmied
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#ifndef __ROS_SHELL_UTILS_H
20#define __ROS_SHELL_UTILS_H
21
22#ifdef __cplusplus
23extern "C" {
24#endif /* defined(__cplusplus) */
25
26inline ULONG
27Win32DbgPrint(const char *filename, int line, const char *lpFormat, ...)
28{
29 char szMsg[512];
30 char *szMsgStart;
31 const char *fname;
32 va_list vl;
33
34 fname = strrchr(filename, '\\');
35 if (fname == NULL)
36 {
37 fname = strrchr(filename, '/');
38 if (fname != NULL)
39 fname++;
40 }
41 else
42 fname++;
43
44 if (fname == NULL)
45 fname = filename;
46
47 szMsgStart = szMsg + sprintf(szMsg, "%s:%d: ", fname, line);
48
49 va_start(vl, lpFormat);
50 vsprintf(szMsgStart, lpFormat, vl);
51 va_end(vl);
52
53 OutputDebugStringA(szMsg);
54
55 /* Return STATUS_SUCCESS, since we are supposed to mimic DbgPrint */
56 return 0;
57}
58
59#define DbgPrint(fmt, ...) \
60 Win32DbgPrint(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
61
62#ifdef __cplusplus
63# define IID_PPV_ARG(Itype, ppType) IID_##Itype, reinterpret_cast<void**>((static_cast<Itype**>(ppType)))
64# define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, reinterpret_cast<void**>((static_cast<Itype**>(ppType)))
65#else
66# define IID_PPV_ARG(Itype, ppType) IID_##Itype, (void**)(ppType)
67# define IID_NULL_PPV_ARG(Itype, ppType) IID_##Itype, NULL, (void**)(ppType)
68#endif
69
71{
72 // HRESULT_FROM_WIN32 will evaluate its parameter twice, this function will not.
73 return HRESULT_FROM_WIN32(hr);
74}
75
76#if 1
77
78inline BOOL _ROS_FAILED_HELPER(HRESULT hr, const char* expr, const char* filename, int line)
79{
80 if (FAILED(hr))
81 {
82 Win32DbgPrint(filename, line, "Unexpected failure (%s)=%08x.\n", expr, hr);
83 return TRUE;
84 }
85 return FALSE;
86}
87
88#define FAILED_UNEXPECTEDLY(hr) _ROS_FAILED_HELPER((hr), #hr, __FILE__, __LINE__)
89#else
90#define FAILED_UNEXPECTEDLY(hr) FAILED(hr)
91#endif
92
93#ifdef __cplusplus
94} /* extern "C" */
95#endif /* defined(__cplusplus) */
96
97static inline UINT
99{
100 WCHAR buf[400];
101 UINT cch;
102
103 if (!IsWindowVisible(hwndOwner))
104 hwndOwner = NULL;
105 if (Error == ERROR_SUCCESS)
107
109 NULL, Error, 0, buf, _countof(buf), NULL);
110 if (!cch)
111 {
112 enum { user32_IDS_ERROR = 2 }; // IDS_ERROR from user32 resource.h ("Error" string)
113 cch = LoadStringW(LoadLibraryW(L"USER32"), user32_IDS_ERROR, buf, _countof(buf));
114 wsprintfW(buf + cch, L"\n\n%#x (%d)", Error, Error);
115 }
116 MessageBoxW(hwndOwner, buf, NULL, MB_OK | MB_ICONSTOP);
117 return Error;
118}
119#ifdef __cplusplus
120template<class H> static UINT
121SHELL_ErrorBox(H hwndOwner, UINT Error = GetLastError())
122{
123 return SHELL_ErrorBoxHelper(const_cast<HWND>(hwndOwner), Error);
124}
125#endif
126
127#ifdef __cplusplus
128template <typename T>
129class CComCreatorCentralInstance
130{
131private:
132 static IUnknown *s_pInstance;
133
134public:
135 static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv)
136 {
137 *ppv = NULL;
138 if (pv != NULL)
140 if (!s_pInstance)
141 {
142 PVOID pObj;
143 HRESULT hr;
145 if (FAILED(hr))
146 return hr;
147 if (InterlockedCompareExchangePointer((PVOID *)&s_pInstance, pObj, NULL))
148 static_cast<IUnknown *>(pObj)->Release();
149 }
150 return s_pInstance->QueryInterface(riid, ppv);
151 }
152 static void Term()
153 {
154 if (s_pInstance)
155 {
156 s_pInstance->Release();
157 s_pInstance = NULL;
158 }
159 }
160};
161
162template <typename T>
163IUnknown *CComCreatorCentralInstance<T>::s_pInstance = NULL;
164
165#define DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(x) \
166public: \
167 typedef CComCreatorCentralInstance< ATL::CComObject<x> > _CreatorClass;
168
169
170template <class Base>
171class CComDebugObject : public Base
172{
173public:
174 CComDebugObject(void * = NULL)
175 {
176#if DEBUG_CCOMOBJECT_CREATION
177 DbgPrint("%S, this=%08p\n", __FUNCTION__, static_cast<Base*>(this));
178#endif
179 _pAtlModule->Lock();
180 }
181
182 virtual ~CComDebugObject()
183 {
184 this->FinalRelease();
185 _pAtlModule->Unlock();
186 }
187
189 {
190 int rc = this->InternalAddRef();
191#if DEBUG_CCOMOBJECT_REFCOUNTING
192 DbgPrint("%s, RefCount is now %d(--)!\n", __FUNCTION__, rc);
193#endif
194 return rc;
195 }
196
198 {
199 int rc = this->InternalRelease();
200
201#if DEBUG_CCOMOBJECT_REFCOUNTING
202 DbgPrint("%s, RefCount is now %d(--)!\n", __FUNCTION__, rc);
203#endif
204
205 if (rc == 0)
206 {
207#if DEBUG_CCOMOBJECT_DESTRUCTION
208 DbgPrint("%s, RefCount reached 0 Deleting!\n", __FUNCTION__);
209#endif
210 delete this;
211 }
212 return rc;
213 }
214
216 {
217 return this->_InternalQueryInterface(iid, ppvObject);
218 }
219
220 static HRESULT WINAPI CreateInstance(CComDebugObject<Base> **pp)
221 {
222 CComDebugObject<Base> *newInstance;
223 HRESULT hResult;
224
225 ATLASSERT(pp != NULL);
226 if (pp == NULL)
227 return E_POINTER;
228
229 hResult = E_OUTOFMEMORY;
230 newInstance = NULL;
231 ATLTRY(newInstance = new CComDebugObject<Base>());
232 if (newInstance != NULL)
233 {
234 newInstance->SetVoid(NULL);
235 newInstance->InternalFinalConstructAddRef();
236 hResult = newInstance->_AtlInitialConstruct();
237 if (SUCCEEDED(hResult))
238 hResult = newInstance->FinalConstruct();
239 if (SUCCEEDED(hResult))
240 hResult = newInstance->_AtlFinalConstruct();
241 newInstance->InternalFinalConstructRelease();
242 if (hResult != S_OK)
243 {
244 delete newInstance;
245 newInstance = NULL;
246 }
247 }
248 *pp = newInstance;
249 return hResult;
250 }
251};
252
253#ifdef DEBUG_CCOMOBJECT
254# define _CComObject CComDebugObject
255#else
256# define _CComObject CComObject
257#endif
258
259template<class T>
260ULONG ReleaseCComPtrExpectZeroHelper(const char *file, UINT line, CComPtr<T>& cptr, BOOL forceRelease = FALSE)
261{
262 ULONG r = 0;
263 if (cptr.p != NULL)
264 {
265 T *raw = cptr.Detach();
266 int nrc = r = raw->Release();
267 if (nrc > 0)
268 Win32DbgPrint(file, line, "WARNING: Unexpected RefCount > 0 (%d)\n", nrc);
269 while (nrc > 0 && forceRelease)
270 {
271 nrc = raw->Release();
272 }
273 }
274 return r;
275}
276#define ReleaseCComPtrExpectZero(...) ReleaseCComPtrExpectZeroHelper(__FILE__, __LINE__, __VA_ARGS__)
277
278template<class T, class R>
279HRESULT inline ShellDebugObjectCreator(REFIID riid, R ** ppv)
280{
281 CComPtr<T> obj;
282 HRESULT hResult;
283
284 if (ppv == NULL)
285 return E_POINTER;
286 *ppv = NULL;
287 ATLTRY(obj = new CComDebugObject<T>);
288 if (obj.p == NULL)
289 return E_OUTOFMEMORY;
290 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
291 if (FAILED(hResult))
292 return hResult;
293 return S_OK;
294}
295
296template<class T>
297HRESULT inline ShellObjectCreator(CComPtr<T> &objref)
298{
299 _CComObject<T> *pobj;
300 HRESULT hResult = _CComObject<T>::CreateInstance(&pobj);
301 objref = pobj; // AddRef() gets called here
302 if (FAILED(hResult))
303 return hResult;
304 return S_OK;
305}
306
307template<class T>
308HRESULT inline ShellObjectCreator(REFIID riid, void ** ppv)
309{
310 _CComObject<T> *pobj;
311 HRESULT hResult;
312
313 hResult = _CComObject<T>::CreateInstance(&pobj);
314 if (FAILED(hResult))
315 return hResult;
316
317 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
318
319 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
320
321 pobj->Release(); /* In case of failure the object will be released */
322
323 return hResult;
324}
325
326template<class T>
327HRESULT inline ShellObjectCreatorInit(REFIID riid, void ** ppv)
328{
329 _CComObject<T> *pobj;
330 HRESULT hResult;
331
332 hResult = _CComObject<T>::CreateInstance(&pobj);
333 if (FAILED(hResult))
334 return hResult;
335
336 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
337
338 hResult = pobj->Initialize();
339
340 if (SUCCEEDED(hResult))
341 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
342
343 pobj->Release(); /* In case of failure the object will be released */
344
345 return hResult;
346}
347
348template<class T, class T1>
349HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, void ** ppv)
350{
351 _CComObject<T> *pobj;
352 HRESULT hResult;
353
354 hResult = _CComObject<T>::CreateInstance(&pobj);
355 if (FAILED(hResult))
356 return hResult;
357
358 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
359
360 hResult = pobj->Initialize(initArg1);
361
362 if (SUCCEEDED(hResult))
363 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
364
365 pobj->Release(); /* In case of failure the object will be released */
366
367 return hResult;
368}
369
370template<class T, class T1, class T2>
371HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, void ** ppv)
372{
373 _CComObject<T> *pobj;
374 HRESULT hResult;
375
376 hResult = _CComObject<T>::CreateInstance(&pobj);
377 if (FAILED(hResult))
378 return hResult;
379
380 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
381
382 hResult = pobj->Initialize(initArg1, initArg2);
383
384 if (SUCCEEDED(hResult))
385 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
386
387 pobj->Release(); /* In case of failure the object will be released */
388
389 return hResult;
390}
391
392template<class T, class T1, class T2, class T3>
393HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REFIID riid, void ** ppv)
394{
395 _CComObject<T> *pobj;
396 HRESULT hResult;
397
398 hResult = _CComObject<T>::CreateInstance(&pobj);
399 if (FAILED(hResult))
400 return hResult;
401
402 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
403
404 hResult = pobj->Initialize(initArg1, initArg2, initArg3);
405
406 if (SUCCEEDED(hResult))
407 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
408
409 pobj->Release(); /* In case of failure the object will be released */
410
411 return hResult;
412}
413
414template<class T, class T1, class T2, class T3, class T4>
415HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, REFIID riid, void ** ppv)
416{
417 _CComObject<T> *pobj;
418 HRESULT hResult;
419
420 hResult = _CComObject<T>::CreateInstance(&pobj);
421 if (FAILED(hResult))
422 return hResult;
423
424 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
425
426 hResult = pobj->Initialize(initArg1, initArg2, initArg3, initArg4);
427
428 if (SUCCEEDED(hResult))
429 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
430
431 pobj->Release(); /* In case of failure the object will be released */
432
433 return hResult;
434}
435
436template<class T, class T1, class T2, class T3, class T4, class T5>
437HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, T5 initArg5, REFIID riid, void ** ppv)
438{
439 _CComObject<T> *pobj;
440 HRESULT hResult;
441
442 hResult = _CComObject<T>::CreateInstance(&pobj);
443 if (FAILED(hResult))
444 return hResult;
445
446 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
447
448 hResult = pobj->Initialize(initArg1, initArg2, initArg3, initArg4, initArg5);
449
450 if (SUCCEEDED(hResult))
451 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
452
453 pobj->Release(); /* In case of failure the object will be released */
454
455 return hResult;
456}
457
458template<class P, class R> static HRESULT SHILClone(P pidl, R *ppOut)
459{
460 R r = *ppOut = (R)ILClone((PIDLIST_RELATIVE)pidl);
461 return r ? S_OK : E_OUTOFMEMORY;
462}
463
464template<class B, class R> static HRESULT SHILCombine(B base, PCUIDLIST_RELATIVE sub, R *ppOut)
465{
466 R r = *ppOut = (R)ILCombine((PCIDLIST_ABSOLUTE)base, sub);
467 return r ? S_OK : E_OUTOFMEMORY;
468}
469
470static inline bool StrIsNullOrEmpty(LPCSTR str) { return !str || !*str; }
471static inline bool StrIsNullOrEmpty(LPCWSTR str) { return !str || !*str; }
472
473HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCSTR pstrValue)
474{
475 pStrRet->uType = STRRET_CSTR;
476 strcpy(pStrRet->cStr, pstrValue);
477 return S_OK;
478}
479
480HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCWSTR pwstrValue)
481{
482 SIZE_T cchr = wcslen(pwstrValue);
483 LPWSTR buffer = static_cast<LPWSTR>(CoTaskMemAlloc((cchr + 1) * sizeof(WCHAR)));
484 if (buffer == NULL)
485 return E_OUTOFMEMORY;
486
487 pStrRet->uType = STRRET_WSTR;
488 pStrRet->pOleStr = buffer;
489 wcscpy(buffer, pwstrValue);
490 return S_OK;
491}
492
493HRESULT inline SHSetStrRet(LPSTRRET pStrRet, HINSTANCE hInstance, DWORD resId)
494{
496
497 if (!LoadStringW(hInstance, resId, Buffer, MAX_PATH))
498 return E_FAIL;
499
500 return SHSetStrRet(pStrRet, Buffer);
501}
502
503static inline void DbgDumpMenuInternal(HMENU hmenu, char* padding, int padlevel)
504{
505 WCHAR label[128];
506 int i;
508
509 padding[padlevel] = '.';
510 padding[padlevel + 1] = '.';
511 padding[padlevel + 2] = 0;
512
513 for (i = 0; i < count; i++)
514 {
515 MENUITEMINFOW mii = { 0 };
516
517 mii.cbSize = sizeof(mii);
519 mii.dwTypeData = label;
520 mii.cch = _countof(label);
521
522 GetMenuItemInfoW(hmenu, i, TRUE, &mii);
523
524 if (mii.fType & MFT_BITMAP)
525 DbgPrint("%s%2d - %08x: BITMAP %08p (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.hbmpItem, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
526 else if (mii.fType & MFT_SEPARATOR)
527 DbgPrint("%s%2d - %08x ---SEPARATOR---\n", padding, i, mii.wID);
528 else
529 DbgPrint("%s%2d - %08x: %S (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.dwTypeData, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
530
531 if (mii.hSubMenu)
532 DbgDumpMenuInternal(mii.hSubMenu, padding, padlevel + 2);
533
534 }
535
536 padding[padlevel] = 0;
537}
538
539static __inline void DbgDumpMenu(HMENU hmenu)
540{
541 char padding[128];
542 DbgDumpMenuInternal(hmenu, padding, 0);
543}
544
545
546static inline
547void DumpIdList(LPCITEMIDLIST pcidl)
548{
549 DbgPrint("Begin IDList Dump\n");
550
551 for (; pcidl != NULL; pcidl = ILGetNext(pcidl))
552 {
553 int i;
554 int cb = pcidl->mkid.cb;
555 BYTE * sh = (BYTE*) &(pcidl->mkid);
556 if (cb == 0) // ITEMIDLISTs are terminatedwith a null SHITEMID.
557 break;
558 DbgPrint("Begin SHITEMID (cb=%d)\n", cb);
559 if ((cb & 3) != 0)
560 DbgPrint(" - WARNING: cb is not a multiple of 4\n");
561 for (i = 0; (i + 4) <= cb; i += 4)
562 {
563 DbgPrint(" - abID[%08x]: %02x %02x %02x %02x\n",
564 i,
565 sh[i + 0],
566 sh[i + 1],
567 sh[i + 2],
568 sh[i + 3]);
569 }
570 if (i < cb)
571 {
572 cb -= i;
573 if (cb == 3)
574 {
575 DbgPrint(" - abID[%08x]: %02x %02x %02x --\n",
576 i,
577 sh[i + 0],
578 sh[i + 1],
579 sh[i + 2]);
580 }
581 else if (cb == 2)
582 {
583 DbgPrint(" - abID[%08x]: %02x %02x -- --\n",
584 i,
585 sh[i + 0],
586 sh[i + 1]);
587 }
588 else if (cb == 1)
589 {
590 DbgPrint(" - abID[%08x]: %02x -- -- --\n",
591 i,
592 sh[i + 0]);
593 }
594 }
595 DbgPrint("End SHITEMID\n");
596 }
597 DbgPrint("End IDList Dump.\n");
598}
599
600struct CCoInit
601{
602 CCoInit()
603 {
605 }
606 ~CCoInit()
607 {
608 if (SUCCEEDED(hr))
609 {
611 }
612 }
613 HRESULT hr;
614};
615
616#endif /* __cplusplus */
617
618#define S_LESSTHAN 0xffff
619#define S_EQUAL S_OK
620#define S_GREATERTHAN S_FALSE
621#define MAKE_COMPARE_HRESULT(x) ((x)>0 ? S_GREATERTHAN : ((x)<0 ? S_LESSTHAN : S_EQUAL))
622
623#define SEE_CMIC_COMMON_BASICFLAGS (SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_UNICODE | \
624 SEE_MASK_NO_CONSOLE | SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_SEPVDM | \
625 SEE_MASK_FLAG_LOG_USAGE | SEE_MASK_NOZONECHECKS)
626#define SEE_CMIC_COMMON_FLAGS (SEE_CMIC_COMMON_BASICFLAGS | SEE_MASK_HOTKEY | SEE_MASK_ICON | \
627 SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE)
628
629static inline BOOL ILIsSingle(LPCITEMIDLIST pidl)
630{
631 return pidl == ILFindLastID(pidl);
632}
633
635{
636 return (PCUIDLIST_ABSOLUTE)(((LPBYTE)pida) + (pida)->aoffset[0]);
637}
638
640{
641 return (PCUIDLIST_RELATIVE)(((LPBYTE)pida) + (pida)->aoffset[i + 1]);
642}
643
644
645#ifdef __cplusplus
646
647#if defined(CMIC_MASK_UNICODE) && defined(SEE_MASK_UNICODE)
648static inline bool IsUnicode(const CMINVOKECOMMANDINFOEX &ici)
649{
650 const UINT minsize = FIELD_OFFSET(CMINVOKECOMMANDINFOEX, ptInvoke);
651 return (ici.fMask & CMIC_MASK_UNICODE) && ici.cbSize >= minsize;
652}
653
654static inline bool IsUnicode(const CMINVOKECOMMANDINFO &ici)
655{
656 return IsUnicode(*(CMINVOKECOMMANDINFOEX*)&ici);
657}
658#endif // CMIC_MASK_UNICODE
659
660DECLSPEC_SELECTANY CLIPFORMAT g_cfHIDA = NULL;
661DECLSPEC_SELECTANY CLIPFORMAT g_cfShellIdListOffsets = NULL;
662
663// Allow to use the HIDA from an IDataObject without copying it
664struct CDataObjectHIDA
665{
666private:
667 STGMEDIUM m_medium;
668 CIDA* m_cida;
669 HRESULT m_hr;
670
671public:
672 explicit CDataObjectHIDA(IDataObject* pDataObject)
673 : m_cida(nullptr)
674 {
675 m_hr = CreateCIDA(pDataObject, &m_cida, m_medium);
676 }
677
678 ~CDataObjectHIDA()
679 {
680 DestroyCIDA(m_cida, m_medium);
681 }
682
683 static void DestroyCIDA(CIDA *pcida, STGMEDIUM &medium)
684 {
685 if (pcida)
686 ::GlobalUnlock(medium.hGlobal);
687 ReleaseStgMedium(&medium);
688 }
689
690 static HRESULT CreateCIDA(IDataObject* pDataObject, CIDA **ppcida, STGMEDIUM &medium)
691 {
692 *ppcida = NULL;
693 medium.pUnkForRelease = NULL;
694 if (g_cfHIDA == NULL)
695 g_cfHIDA = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
696
697 FORMATETC fmt = { g_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
698 HRESULT hr = pDataObject->GetData(&fmt, &medium);
699 if (SUCCEEDED(hr))
700 {
701 *ppcida = (CIDA*)::GlobalLock(medium.hGlobal);
702 if (*ppcida)
703 return S_OK;
704 ReleaseStgMedium(&medium);
706 }
707 medium.tymed = TYMED_NULL;
708 return hr;
709 }
710
711 HRESULT hr() const
712 {
713 return m_hr;
714 }
715
716 operator bool() const
717 {
718 return m_cida != nullptr;
719 }
720
721 operator const CIDA* () const
722 {
723 return m_cida;
724 }
725
726 const CIDA* operator->() const
727 {
728 return m_cida;
729 }
730};
731
732inline
733HRESULT DataObject_GetData(IDataObject* pDataObject, CLIPFORMAT clipformat, PVOID pBuffer, SIZE_T dwBufferSize)
734{
735 FORMATETC fmt = { clipformat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
736 STGMEDIUM medium = { TYMED_NULL };
737
738 HRESULT hr = pDataObject->GetData(&fmt, &medium);
739 if (SUCCEEDED(hr))
740 {
741 LPVOID blob = GlobalLock(medium.hGlobal);
742 if (blob)
743 {
744 SIZE_T size = GlobalSize(medium.hGlobal);
745 if (size <= dwBufferSize)
746 {
748 hr = S_OK;
749 }
750 else
751 {
753 }
754 GlobalUnlock(medium.hGlobal);
755 }
756 else
757 {
759 }
760
761 ReleaseStgMedium(&medium);
762 }
763 return hr;
764}
765
766inline
767HRESULT DataObject_SetData(IDataObject* pDataObject, CLIPFORMAT clipformat, PVOID pBuffer, SIZE_T dwBufferSize)
768{
769 STGMEDIUM medium = { TYMED_HGLOBAL };
770
771 medium.hGlobal = GlobalAlloc(GHND, dwBufferSize);
772 if (!medium.hGlobal)
773 return E_OUTOFMEMORY;
774
776 LPVOID blob = GlobalLock(medium.hGlobal);
777 if (blob)
778 {
779 CopyMemory(blob, pBuffer, dwBufferSize);
780 GlobalUnlock(medium.hGlobal);
781
782 FORMATETC etc = { clipformat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
783 hr = pDataObject->SetData(&etc, &medium, TRUE);
784 }
785
786 if (FAILED(hr))
787 GlobalFree(medium.hGlobal);
788
789 return hr;
790}
791
792
793inline HRESULT
794DataObject_GetOffset(IDataObject *pDataObject, POINT *point)
795{
796 if (g_cfShellIdListOffsets == NULL)
797 {
798 g_cfShellIdListOffsets = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTOFFSETW);
799 }
800
801 point->x = point->y = 0;
802
803 return DataObject_GetData(pDataObject, g_cfShellIdListOffsets, point, sizeof(point[0]));
804}
805
806inline HRESULT
807DataObject_SetOffset(IDataObject* pDataObject, POINT* point)
808{
809 if (g_cfShellIdListOffsets == NULL)
810 {
811 g_cfShellIdListOffsets = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTOFFSETW);
812 }
813
814 return DataObject_SetData(pDataObject, g_cfShellIdListOffsets, point, sizeof(point[0]));
815}
816
817#endif // __cplusplus
818
819#ifdef __cplusplus
820struct SHELL_GetSettingImpl
821{
823 SHELL_GetSettingImpl(DWORD ssf) { SHGetSetSettings(&ss, ssf, FALSE); }
824 const SHELLSTATE* operator ->() { return &ss; }
825};
826#define SHELL_GetSetting(ssf, field) ( SHELL_GetSettingImpl(ssf)->field )
827#else
828#define SHELL_GetSetting(pss, ssf, field) ( SHGetSetSettings((pss), (ssf), FALSE), (pss)->field )
829#endif
830
831
832#endif /* __ROS_SHELL_UTILS_H */
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define ATLTRY(x)
Definition: atlcomcli.h:44
BOOL Error
Definition: chkdsk.c:66
#define STDMETHOD_(t, m)
Definition: basetyps.h:63
#define STDMETHOD(m)
Definition: basetyps.h:62
const GUID IID_IUnknown
_In_ BOOLEAN Release
Definition: cdrom.h:920
HINSTANCE hInstance
Definition: charmap.c:19
static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv)
Definition: atlcom.h:424
Definition: ehthrow.cxx:54
Definition: bufpool.h:45
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_FAIL
Definition: ddrawi.h:102
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define P(row, col)
#define MAX_PATH
Definition: compat.h:34
#define LoadLibraryW(x)
Definition: compat.h:747
static HRESULT WINAPI DataObject_GetData(LPDATAOBJECT iface, LPFORMATETC pformatetcIn, STGMEDIUM *pmedium)
Definition: view.c:175
static HRESULT WINAPI DataObject_SetData(LPDATAOBJECT iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
Definition: view.c:203
DWORD WINAPI FormatMessageW(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, __ms_va_list *args)
Definition: format_msg.c:583
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
HRESULT SHILClone(_In_opt_ LPCITEMIDLIST pidl, _Outptr_ LPITEMIDLIST *ppidl)
Definition: utils.cpp:13
#define __FUNCTION__
Definition: types.h:116
POINTL point
Definition: edittest.c:50
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define DbgPrint
Definition: hal.h:12
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
HGLOBAL NTAPI GlobalFree(HGLOBAL hMem)
Definition: heapmem.c:611
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
SIZE_T NTAPI GlobalSize(HGLOBAL hMem)
Definition: heapmem.c:1090
#define ss
Definition: i386-dis.c:441
LPVOID WINAPI CoTaskMemAlloc(SIZE_T size)
Definition: ifs.c:426
void WINAPI SHIM_OBJ_NAME() OutputDebugStringA(LPCSTR lpOutputString)
Definition: ignoredbgout.c:18
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
HRESULT SetData([in, unique] FORMATETC *pformatetc, [in, unique] STGMEDIUM *pmedium, [in] BOOL fRelease)
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
ULONG AddRef()
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
nsresult QueryInterface(nsIIDRef riid, void **result)
nsrefcnt Release()
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
const char * filename
Definition: ioapi.h:137
#define T
Definition: mbstring.h:31
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const WCHAR label[]
Definition: itemdlg.c:1546
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
#define H
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static HRESULT QueryInterface(REFIID, void **)
Definition: events.c:2587
static const DWORD padding[]
Definition: mciwnd.c:89
static ULONG WINAPI AddRef(IStream *iface)
Definition: clist.c:90
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
unsigned int UINT
Definition: ndis.h:50
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2451
#define bool
Definition: nsiface.idl:72
#define L(x)
Definition: ntvdm.h:50
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:718
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:872
#define DECLSPEC_SELECTANY
Definition: guiddef.h:40
#define REFIID
Definition: guiddef.h:118
PVOID pBuffer
const WCHAR * str
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
short sh
Definition: format.c:272
#define R(b, x)
Definition: sha2.c:134
VOID WINAPI SHGetSetSettings(LPSHELLSTATE lpss, DWORD dwMask, BOOL bSet)
Definition: shellord.c:225
ULONG Win32DbgPrint(const char *filename, int line, const char *lpFormat,...)
Definition: shellutils.h:27
#define DbgPrint(fmt,...)
Definition: shellutils.h:59
static PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const *pida, SIZE_T i)
Definition: shellutils.h:639
HRESULT HResultFromWin32(DWORD hr)
Definition: shellutils.h:70
static PCUIDLIST_ABSOLUTE HIDA_GetPIDLFolder(CIDA const *pida)
Definition: shellutils.h:634
static UINT SHELL_ErrorBoxHelper(HWND hwndOwner, UINT Error)
Definition: shellutils.h:98
static BOOL ILIsSingle(LPCITEMIDLIST pidl)
Definition: shellutils.h:629
BOOL _ROS_FAILED_HELPER(HRESULT hr, const char *expr, const char *filename, int line)
Definition: shellutils.h:78
HRESULT hr
Definition: shlfolder.c:183
static const WCHAR CFSTR_SHELLIDLISTOFFSETW[]
Definition: shlobj.h:508
static const WCHAR CFSTR_SHELLIDLISTW[]
Definition: shlobj.h:506
@ STRRET_CSTR
Definition: shtypes.idl:87
@ STRRET_WSTR
Definition: shtypes.idl:85
const ITEMIDLIST_ABSOLUTE UNALIGNED * PCUIDLIST_ABSOLUTE
Definition: shtypes.idl:63
const ITEMIDLIST_RELATIVE UNALIGNED * PCUIDLIST_RELATIVE
Definition: shtypes.idl:57
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
Definition: shlobj.h:572
LONG y
Definition: windef.h:330
LONG x
Definition: windef.h:329
char cStr[MAX_PATH]
Definition: shtypes.idl:98
UINT uType
Definition: shtypes.idl:93
LPWSTR pOleStr
Definition: shtypes.idl:96
Definition: image.c:134
Definition: query.h:86
Definition: fci.c:127
Definition: dsound.c:943
Definition: parser.c:49
LPWSTR dwTypeData
Definition: winuser.h:3272
LPCWSTR lpFormat
Definition: trayclock.cpp:32
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG
Definition: typedefs.h:59
static HMENU hmenu
Definition: win.c:66
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:420
#define CopyMemory
Definition: winbase.h:1710
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:423
#define GHND
Definition: winbase.h:297
_In_ void _In_ PCCERT_CONTEXT _In_opt_ LPFILETIME _In_ DWORD _In_ DWORD _Outptr_opt_ void ** ppvObject
Definition: wincrypt.h:6082
#define WINAPI
Definition: msvc.h:6
#define STG_E_INVALIDHANDLE
Definition: winerror.h:2569
#define CLASS_E_NOAGGREGATION
Definition: winerror.h:2662
#define E_UNEXPECTED
Definition: winerror.h:2456
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define E_POINTER
Definition: winerror.h:2365
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
#define MIIM_STRING
Definition: winuser.h:730
#define MIIM_ID
Definition: winuser.h:725
int WINAPI GetMenuItemCount(_In_opt_ HMENU)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPIV wsprintfW(_Out_ LPWSTR, _In_ _Printf_format_string_ LPCWSTR,...)
#define MIIM_FTYPE
Definition: winuser.h:732
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
#define MFT_SEPARATOR
Definition: winuser.h:747
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
#define MIIM_STATE
Definition: winuser.h:724
#define MIIM_SUBMENU
Definition: winuser.h:726
#define MFT_BITMAP
Definition: winuser.h:741
#define MB_OK
Definition: winuser.h:793
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define MB_ICONSTOP
Definition: winuser.h:806
BOOL WINAPI IsWindowVisible(_In_ HWND)
const char * LPCSTR
Definition: xmlstorage.h:183
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193