ReactOS 0.4.16-dev-974-g5022a45
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
26static inline 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
78static inline 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#else
126#define SHELL_ErrorBox SHELL_ErrorBoxHelper
127#endif
128
129#ifdef __cplusplus
130#ifdef DECLARE_CLASSFACTORY // ATL
131template <typename T>
132class CComCreatorCentralInstance
133{
134private:
135 static IUnknown *s_pInstance;
136
137public:
138 static HRESULT WINAPI CreateInstance(void *pv, REFIID riid, LPVOID *ppv)
139 {
140 *ppv = NULL;
141 if (pv != NULL)
143 if (!s_pInstance)
144 {
145 PVOID pObj;
146 HRESULT hr;
148 if (FAILED(hr))
149 return hr;
150 if (InterlockedCompareExchangePointer((PVOID *)&s_pInstance, pObj, NULL))
151 static_cast<IUnknown *>(pObj)->Release();
152 }
153 return s_pInstance->QueryInterface(riid, ppv);
154 }
155 static void Term()
156 {
157 if (s_pInstance)
158 {
159 s_pInstance->Release();
160 s_pInstance = NULL;
161 }
162 }
163};
164
165template <typename T>
166IUnknown *CComCreatorCentralInstance<T>::s_pInstance = NULL;
167
168#define DECLARE_CENTRAL_INSTANCE_NOT_AGGREGATABLE(x) \
169public: \
170 typedef CComCreatorCentralInstance< ATL::CComObject<x> > _CreatorClass;
171
172
173template <class Base>
174class CComDebugObject : public Base
175{
176public:
177 CComDebugObject(void * = NULL)
178 {
179#if DEBUG_CCOMOBJECT_CREATION
180 DbgPrint("%S, this=%08p\n", __FUNCTION__, static_cast<Base*>(this));
181#endif
182 _pAtlModule->Lock();
183 }
184
185 virtual ~CComDebugObject()
186 {
187 this->FinalRelease();
188 _pAtlModule->Unlock();
189 }
190
192 {
193 int rc = this->InternalAddRef();
194#if DEBUG_CCOMOBJECT_REFCOUNTING
195 DbgPrint("%s, RefCount is now %d(--)!\n", __FUNCTION__, rc);
196#endif
197 return rc;
198 }
199
201 {
202 int rc = this->InternalRelease();
203
204#if DEBUG_CCOMOBJECT_REFCOUNTING
205 DbgPrint("%s, RefCount is now %d(--)!\n", __FUNCTION__, rc);
206#endif
207
208 if (rc == 0)
209 {
210#if DEBUG_CCOMOBJECT_DESTRUCTION
211 DbgPrint("%s, RefCount reached 0 Deleting!\n", __FUNCTION__);
212#endif
213 delete this;
214 }
215 return rc;
216 }
217
219 {
220 return this->_InternalQueryInterface(iid, ppvObject);
221 }
222
223 static HRESULT WINAPI CreateInstance(CComDebugObject<Base> **pp)
224 {
225 CComDebugObject<Base> *newInstance;
226 HRESULT hResult;
227
228 ATLASSERT(pp != NULL);
229 if (pp == NULL)
230 return E_POINTER;
231
232 hResult = E_OUTOFMEMORY;
233 newInstance = NULL;
234 ATLTRY(newInstance = new CComDebugObject<Base>());
235 if (newInstance != NULL)
236 {
237 newInstance->SetVoid(NULL);
238 newInstance->InternalFinalConstructAddRef();
239 hResult = newInstance->_AtlInitialConstruct();
240 if (SUCCEEDED(hResult))
241 hResult = newInstance->FinalConstruct();
242 if (SUCCEEDED(hResult))
243 hResult = newInstance->_AtlFinalConstruct();
244 newInstance->InternalFinalConstructRelease();
245 if (hResult != S_OK)
246 {
247 delete newInstance;
248 newInstance = NULL;
249 }
250 }
251 *pp = newInstance;
252 return hResult;
253 }
254};
255
256#ifdef DEBUG_CCOMOBJECT
257# define _CComObject CComDebugObject
258#else
259# define _CComObject CComObject
260#endif
261
262template<class T>
263ULONG ReleaseCComPtrExpectZeroHelper(const char *file, UINT line, CComPtr<T>& cptr, BOOL forceRelease = FALSE)
264{
265 ULONG r = 0;
266 if (cptr.p != NULL)
267 {
268 T *raw = cptr.Detach();
269 int nrc = r = raw->Release();
270 if (nrc > 0)
271 Win32DbgPrint(file, line, "WARNING: Unexpected RefCount > 0 (%d)\n", nrc);
272 while (nrc > 0 && forceRelease)
273 {
274 nrc = raw->Release();
275 }
276 }
277 return r;
278}
279#define ReleaseCComPtrExpectZero(...) ReleaseCComPtrExpectZeroHelper(__FILE__, __LINE__, __VA_ARGS__)
280
281template<class T, class R>
282HRESULT inline ShellDebugObjectCreator(REFIID riid, R ** ppv)
283{
284 CComPtr<T> obj;
285 HRESULT hResult;
286
287 if (ppv == NULL)
288 return E_POINTER;
289 *ppv = NULL;
290 ATLTRY(obj = new CComDebugObject<T>);
291 if (obj.p == NULL)
292 return E_OUTOFMEMORY;
293 hResult = obj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
294 if (FAILED(hResult))
295 return hResult;
296 return S_OK;
297}
298
299template<class T>
300HRESULT inline ShellObjectCreator(CComPtr<T> &objref)
301{
302 _CComObject<T> *pobj;
303 HRESULT hResult = _CComObject<T>::CreateInstance(&pobj);
304 objref = pobj; // AddRef() gets called here
305 if (FAILED(hResult))
306 return hResult;
307 return S_OK;
308}
309
310template<class T>
311HRESULT inline ShellObjectCreator(REFIID riid, void ** ppv)
312{
313 _CComObject<T> *pobj;
314 HRESULT hResult;
315
316 hResult = _CComObject<T>::CreateInstance(&pobj);
317 if (FAILED(hResult))
318 return hResult;
319
320 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
321
322 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
323
324 pobj->Release(); /* In case of failure the object will be released */
325
326 return hResult;
327}
328
329template<class T>
330HRESULT inline ShellObjectCreatorInit(REFIID riid, void ** ppv)
331{
332 _CComObject<T> *pobj;
333 HRESULT hResult;
334
335 hResult = _CComObject<T>::CreateInstance(&pobj);
336 if (FAILED(hResult))
337 return hResult;
338
339 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
340
341 hResult = pobj->Initialize();
342
343 if (SUCCEEDED(hResult))
344 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
345
346 pobj->Release(); /* In case of failure the object will be released */
347
348 return hResult;
349}
350
351template<class T, class T1>
352HRESULT inline ShellObjectCreatorInit(T1 initArg1, REFIID riid, void ** ppv)
353{
354 _CComObject<T> *pobj;
355 HRESULT hResult;
356
357 hResult = _CComObject<T>::CreateInstance(&pobj);
358 if (FAILED(hResult))
359 return hResult;
360
361 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
362
363 hResult = pobj->Initialize(initArg1);
364
365 if (SUCCEEDED(hResult))
366 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
367
368 pobj->Release(); /* In case of failure the object will be released */
369
370 return hResult;
371}
372
373template<class T, class T1, class T2>
374HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, REFIID riid, void ** ppv)
375{
376 _CComObject<T> *pobj;
377 HRESULT hResult;
378
379 hResult = _CComObject<T>::CreateInstance(&pobj);
380 if (FAILED(hResult))
381 return hResult;
382
383 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
384
385 hResult = pobj->Initialize(initArg1, initArg2);
386
387 if (SUCCEEDED(hResult))
388 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
389
390 pobj->Release(); /* In case of failure the object will be released */
391
392 return hResult;
393}
394
395template<class T, class T1, class T2, class T3>
396HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, REFIID riid, void ** ppv)
397{
398 _CComObject<T> *pobj;
399 HRESULT hResult;
400
401 hResult = _CComObject<T>::CreateInstance(&pobj);
402 if (FAILED(hResult))
403 return hResult;
404
405 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
406
407 hResult = pobj->Initialize(initArg1, initArg2, initArg3);
408
409 if (SUCCEEDED(hResult))
410 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
411
412 pobj->Release(); /* In case of failure the object will be released */
413
414 return hResult;
415}
416
417template<class T, class T1, class T2, class T3, class T4>
418HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, REFIID riid, void ** ppv)
419{
420 _CComObject<T> *pobj;
421 HRESULT hResult;
422
423 hResult = _CComObject<T>::CreateInstance(&pobj);
424 if (FAILED(hResult))
425 return hResult;
426
427 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
428
429 hResult = pobj->Initialize(initArg1, initArg2, initArg3, initArg4);
430
431 if (SUCCEEDED(hResult))
432 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
433
434 pobj->Release(); /* In case of failure the object will be released */
435
436 return hResult;
437}
438
439template<class T, class T1, class T2, class T3, class T4, class T5>
440HRESULT inline ShellObjectCreatorInit(T1 initArg1, T2 initArg2, T3 initArg3, T4 initArg4, T5 initArg5, REFIID riid, void ** ppv)
441{
442 _CComObject<T> *pobj;
443 HRESULT hResult;
444
445 hResult = _CComObject<T>::CreateInstance(&pobj);
446 if (FAILED(hResult))
447 return hResult;
448
449 pobj->AddRef(); /* CreateInstance returns object with 0 ref count */
450
451 hResult = pobj->Initialize(initArg1, initArg2, initArg3, initArg4, initArg5);
452
453 if (SUCCEEDED(hResult))
454 hResult = pobj->QueryInterface(riid, reinterpret_cast<void **>(ppv));
455
456 pobj->Release(); /* In case of failure the object will be released */
457
458 return hResult;
459}
460#endif // DECLARE_CLASSFACTORY (ATL)
461
462template<class P, class R> static HRESULT SHILClone(P pidl, R *ppOut)
463{
464 R r = *ppOut = (R)ILClone((PIDLIST_RELATIVE)pidl);
465 return r ? S_OK : E_OUTOFMEMORY;
466}
467
468template<class B, class R> static HRESULT SHILCombine(B base, PCUIDLIST_RELATIVE sub, R *ppOut)
469{
470 R r = *ppOut = (R)ILCombine((PCIDLIST_ABSOLUTE)base, sub);
471 return r ? S_OK : E_OUTOFMEMORY;
472}
473
474static inline bool StrIsNullOrEmpty(LPCSTR str) { return !str || !*str; }
475static inline bool StrIsNullOrEmpty(LPCWSTR str) { return !str || !*str; }
476
477HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCSTR pstrValue)
478{
479 pStrRet->uType = STRRET_CSTR;
480 strcpy(pStrRet->cStr, pstrValue);
481 return S_OK;
482}
483
484HRESULT inline SHSetStrRet(LPSTRRET pStrRet, LPCWSTR pwstrValue)
485{
486 SIZE_T cchr = wcslen(pwstrValue);
487 LPWSTR buffer = static_cast<LPWSTR>(CoTaskMemAlloc((cchr + 1) * sizeof(WCHAR)));
488 if (buffer == NULL)
489 return E_OUTOFMEMORY;
490
491 pStrRet->uType = STRRET_WSTR;
492 pStrRet->pOleStr = buffer;
493 wcscpy(buffer, pwstrValue);
494 return S_OK;
495}
496
497HRESULT inline SHSetStrRet(LPSTRRET pStrRet, HINSTANCE hInstance, DWORD resId)
498{
500
501 if (!LoadStringW(hInstance, resId, Buffer, MAX_PATH))
502 return E_FAIL;
503
504 return SHSetStrRet(pStrRet, Buffer);
505}
506
507static inline void DbgDumpMenuInternal(HMENU hmenu, char* padding, int padlevel)
508{
509 WCHAR label[128];
510 int i;
512
513 padding[padlevel] = '.';
514 padding[padlevel + 1] = '.';
515 padding[padlevel + 2] = 0;
516
517 for (i = 0; i < count; i++)
518 {
519 MENUITEMINFOW mii = { 0 };
520
521 mii.cbSize = sizeof(mii);
523 mii.dwTypeData = label;
524 mii.cch = _countof(label);
525
526 GetMenuItemInfoW(hmenu, i, TRUE, &mii);
527
528 if (mii.fType & MFT_BITMAP)
529 DbgPrint("%s%2d - %08x: BITMAP %08p (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.hbmpItem, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
530 else if (mii.fType & MFT_SEPARATOR)
531 DbgPrint("%s%2d - %08x ---SEPARATOR---\n", padding, i, mii.wID);
532 else
533 DbgPrint("%s%2d - %08x: %S (state=%d, has submenu=%s)\n", padding, i, mii.wID, mii.dwTypeData, mii.fState, mii.hSubMenu ? "TRUE" : "FALSE");
534
535 if (mii.hSubMenu)
536 DbgDumpMenuInternal(mii.hSubMenu, padding, padlevel + 2);
537
538 }
539
540 padding[padlevel] = 0;
541}
542
543static __inline void DbgDumpMenu(HMENU hmenu)
544{
545 char padding[128];
546 DbgDumpMenuInternal(hmenu, padding, 0);
547}
548
549
550static inline
551void DumpIdList(LPCITEMIDLIST pcidl)
552{
553 DbgPrint("Begin IDList Dump\n");
554
555 for (; pcidl != NULL; pcidl = ILGetNext(pcidl))
556 {
557 int i;
558 int cb = pcidl->mkid.cb;
559 BYTE * sh = (BYTE*) &(pcidl->mkid);
560 if (cb == 0) // ITEMIDLISTs are terminatedwith a null SHITEMID.
561 break;
562 DbgPrint("Begin SHITEMID (cb=%d)\n", cb);
563 if ((cb & 3) != 0)
564 DbgPrint(" - WARNING: cb is not a multiple of 4\n");
565 for (i = 0; (i + 4) <= cb; i += 4)
566 {
567 DbgPrint(" - abID[%08x]: %02x %02x %02x %02x\n",
568 i,
569 sh[i + 0],
570 sh[i + 1],
571 sh[i + 2],
572 sh[i + 3]);
573 }
574 if (i < cb)
575 {
576 cb -= i;
577 if (cb == 3)
578 {
579 DbgPrint(" - abID[%08x]: %02x %02x %02x --\n",
580 i,
581 sh[i + 0],
582 sh[i + 1],
583 sh[i + 2]);
584 }
585 else if (cb == 2)
586 {
587 DbgPrint(" - abID[%08x]: %02x %02x -- --\n",
588 i,
589 sh[i + 0],
590 sh[i + 1]);
591 }
592 else if (cb == 1)
593 {
594 DbgPrint(" - abID[%08x]: %02x -- -- --\n",
595 i,
596 sh[i + 0]);
597 }
598 }
599 DbgPrint("End SHITEMID\n");
600 }
601 DbgPrint("End IDList Dump.\n");
602}
603
604template <HRESULT (WINAPI *InitFunc)(void*), void (WINAPI *UninitFunc)()>
605struct CCoInitBase
606{
607 HRESULT hr;
608 CCoInitBase() : hr(InitFunc(NULL)) { }
609 ~CCoInitBase()
610 {
611 if (SUCCEEDED(hr))
612 UninitFunc();
613 }
614};
615typedef CCoInitBase<CoInitialize, CoUninitialize> CCoInit;
616typedef CCoInitBase<OleInitialize, OleUninitialize> COleInit;
617
618#endif /* __cplusplus */
619
620#define S_LESSTHAN 0xffff
621#define S_EQUAL S_OK
622#define S_GREATERTHAN S_FALSE
623#define MAKE_COMPARE_HRESULT(x) ((x)>0 ? S_GREATERTHAN : ((x)<0 ? S_LESSTHAN : S_EQUAL))
624
625#define SEE_CMIC_COMMON_BASICFLAGS (SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_UNICODE | \
626 SEE_MASK_NO_CONSOLE | SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_SEPVDM | \
627 SEE_MASK_FLAG_LOG_USAGE | SEE_MASK_NOZONECHECKS)
628#define SEE_CMIC_COMMON_FLAGS (SEE_CMIC_COMMON_BASICFLAGS | SEE_MASK_HOTKEY | SEE_MASK_ICON | \
629 SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE)
630
631static inline BOOL ILIsSingle(LPCITEMIDLIST pidl)
632{
633 return pidl == ILFindLastID(pidl);
634}
635
637{
638 return (PCUIDLIST_ABSOLUTE)(((LPBYTE)pida) + (pida)->aoffset[0]);
639}
640
642{
643 return (PCUIDLIST_RELATIVE)(((LPBYTE)pida) + (pida)->aoffset[i + 1]);
644}
645
646
647#ifdef __cplusplus
648
649#if defined(CMIC_MASK_UNICODE) && defined(SEE_MASK_UNICODE)
650static inline bool IsUnicode(const CMINVOKECOMMANDINFOEX &ici)
651{
652 const UINT minsize = FIELD_OFFSET(CMINVOKECOMMANDINFOEX, ptInvoke);
653 return (ici.fMask & CMIC_MASK_UNICODE) && ici.cbSize >= minsize;
654}
655
656static inline bool IsUnicode(const CMINVOKECOMMANDINFO &ici)
657{
658 return IsUnicode(*(CMINVOKECOMMANDINFOEX*)&ici);
659}
660#endif // CMIC_MASK_UNICODE
661
662DECLSPEC_SELECTANY CLIPFORMAT g_cfHIDA = NULL;
663DECLSPEC_SELECTANY CLIPFORMAT g_cfShellIdListOffsets = NULL;
664
665// Allow to use the HIDA from an IDataObject without copying it
666struct CDataObjectHIDA
667{
668private:
669 STGMEDIUM m_medium;
670 CIDA* m_cida;
671 HRESULT m_hr;
672
673public:
674 explicit CDataObjectHIDA(IDataObject* pDataObject)
675 : m_cida(nullptr)
676 {
677 m_hr = CreateCIDA(pDataObject, &m_cida, m_medium);
678 }
679
680 ~CDataObjectHIDA()
681 {
682 DestroyCIDA(m_cida, m_medium);
683 }
684
685 static void DestroyCIDA(CIDA *pcida, STGMEDIUM &medium)
686 {
687 if (pcida)
688 ::GlobalUnlock(medium.hGlobal);
689 ReleaseStgMedium(&medium);
690 }
691
692 static HRESULT CreateCIDA(IDataObject* pDataObject, CIDA **ppcida, STGMEDIUM &medium)
693 {
694 *ppcida = NULL;
695 medium.pUnkForRelease = NULL;
696 if (g_cfHIDA == NULL)
697 g_cfHIDA = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
698
699 FORMATETC fmt = { g_cfHIDA, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
700 HRESULT hr = pDataObject->GetData(&fmt, &medium);
701 if (SUCCEEDED(hr))
702 {
703 *ppcida = (CIDA*)::GlobalLock(medium.hGlobal);
704 if (*ppcida)
705 return S_OK;
706 ReleaseStgMedium(&medium);
708 }
709 medium.tymed = TYMED_NULL;
710 return hr;
711 }
712
713 HRESULT hr() const
714 {
715 return m_hr;
716 }
717
718 operator bool() const
719 {
720 return m_cida != nullptr;
721 }
722
723 operator const CIDA* () const
724 {
725 return m_cida;
726 }
727
728 const CIDA* operator->() const
729 {
730 return m_cida;
731 }
732};
733
734inline
735HRESULT DataObject_GetData(IDataObject* pDataObject, CLIPFORMAT clipformat, PVOID pBuffer, SIZE_T dwBufferSize)
736{
737 FORMATETC fmt = { clipformat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
738 STGMEDIUM medium = { TYMED_NULL };
739
740 HRESULT hr = pDataObject->GetData(&fmt, &medium);
741 if (SUCCEEDED(hr))
742 {
743 LPVOID blob = GlobalLock(medium.hGlobal);
744 if (blob)
745 {
746 SIZE_T size = GlobalSize(medium.hGlobal);
747 if (size <= dwBufferSize)
748 {
750 hr = S_OK;
751 }
752 else
753 {
755 }
756 GlobalUnlock(medium.hGlobal);
757 }
758 else
759 {
761 }
762
763 ReleaseStgMedium(&medium);
764 }
765 return hr;
766}
767
768inline
769HRESULT DataObject_SetData(IDataObject* pDataObject, CLIPFORMAT clipformat, PVOID pBuffer, SIZE_T dwBufferSize)
770{
771 STGMEDIUM medium = { TYMED_HGLOBAL };
772
773 medium.hGlobal = GlobalAlloc(GHND, dwBufferSize);
774 if (!medium.hGlobal)
775 return E_OUTOFMEMORY;
776
778 LPVOID blob = GlobalLock(medium.hGlobal);
779 if (blob)
780 {
781 CopyMemory(blob, pBuffer, dwBufferSize);
782 GlobalUnlock(medium.hGlobal);
783
784 FORMATETC etc = { clipformat, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
785 hr = pDataObject->SetData(&etc, &medium, TRUE);
786 }
787
788 if (FAILED(hr))
789 GlobalFree(medium.hGlobal);
790
791 return hr;
792}
793
794
795inline HRESULT
796DataObject_GetOffset(IDataObject *pDataObject, POINT *point)
797{
798 if (g_cfShellIdListOffsets == NULL)
799 {
800 g_cfShellIdListOffsets = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTOFFSETW);
801 }
802
803 point->x = point->y = 0;
804
805 return DataObject_GetData(pDataObject, g_cfShellIdListOffsets, point, sizeof(point[0]));
806}
807
808inline HRESULT
809DataObject_SetOffset(IDataObject* pDataObject, POINT* point)
810{
811 if (g_cfShellIdListOffsets == NULL)
812 {
813 g_cfShellIdListOffsets = (CLIPFORMAT)RegisterClipboardFormatW(CFSTR_SHELLIDLISTOFFSETW);
814 }
815
816 return DataObject_SetData(pDataObject, g_cfShellIdListOffsets, point, sizeof(point[0]));
817}
818
819#endif // __cplusplus
820
821#ifdef __cplusplus
822struct SHELL_GetSettingImpl
823{
825 SHELL_GetSettingImpl(DWORD ssf) { SHGetSetSettings(&ss, ssf, FALSE); }
826 const SHELLSTATE* operator ->() { return &ss; }
827};
828#define SHELL_GetSetting(ssf, field) ( SHELL_GetSettingImpl(ssf)->field )
829#else
830#define SHELL_GetSetting(pss, ssf, field) ( SHGetSetSettings((pss), (ssf), FALSE), (pss)->field )
831#endif
832
833static inline void DumpIdListOneLine(LPCITEMIDLIST pidl)
834{
835 char buf[1024], *data, drive = 0;
836 for (UINT depth = 0, type; ; pidl = ILGetNext(pidl), ++depth)
837 {
838 if (!pidl || !pidl->mkid.cb)
839 {
840 if (!depth)
841 {
842 wsprintfA(buf, "%p [] (%s)\n", pidl, pidl ? "Empty/Desktop" : "NULL");
844 }
845 break;
846 }
847 else if (!depth)
848 {
849 wsprintfA(buf, "%p", pidl);
851 }
852 type = pidl->mkid.abID[0] & 0x7f;
853 data = (char*)&pidl->mkid.abID[0];
854 if (depth == 0 && type == 0x1f && pidl->mkid.cb == 20 && *(UINT*)(&data[2]) == 0x20D04FE0)
855 {
856 wsprintfA(buf, " [%.2x ThisPC?]", type); /* "?" because we did not check the full GUID */
857 }
858 else if (depth == 1 && type >= 0x20 && type < 0x30 && type != 0x2E && pidl->mkid.cb > 4)
859 {
860 drive = data[1];
861 wsprintfA(buf, " [%.2x %c: %ub]", type, drive, pidl->mkid.cb);
862 }
863 else if (depth >= 2 && drive && (type & 0x70) == 0x30) /* PT_FS */
864 {
865 if (type & 4)
866 wsprintfA(buf, " [%.2x FS %.256ls %ub]", type, data + 12, pidl->mkid.cb);
867 else
868 wsprintfA(buf, " [%.2x FS %.256hs %ub]", type, data + 12, pidl->mkid.cb);
869 }
870 else
871 {
872 wsprintfA(buf, " [%.2x ? %ub]", type, pidl->mkid.cb);
873 }
875 }
876 OutputDebugStringA("\n");
877}
878
879#endif /* __ROS_SHELL_UTILS_H */
#define ATLASSERT(x)
Definition: CComVariant.cpp:10
#define __inline
Definition: _wctype.cpp:15
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
wcscpy
#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
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
HRESULT SHILClone(_In_opt_ LPCITEMIDLIST pidl, _Outptr_ LPITEMIDLIST *ppidl)
Definition: utils.cpp:133
#define __FUNCTION__
Definition: types.h:116
POINTL point
Definition: edittest.c:50
return nullptr
Definition: expand.cpp:78
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
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
static CInternetFolder * CreateInstance(void)
Definition: inetfolder.c:330
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()
#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
if(dx< 0)
Definition: linetemp.h:194
#define HResultFromWin32
Definition: loader.cpp:14
#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
static HMENU hmenu
Definition: win.c:66
unsigned int UINT
Definition: ndis.h:50
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2478
#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:816
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:970
#define DECLSPEC_SELECTANY
Definition: guiddef.h:40
#define REFIID
Definition: guiddef.h:118
PVOID pBuffer
const WCHAR * str
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
strcpy
Definition: string.h:131
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
#define DbgPrint(fmt,...)
Definition: shellutils.h:59
static PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const *pida, SIZE_T i)
Definition: shellutils.h:641
static BOOL _ROS_FAILED_HELPER(HRESULT hr, const char *expr, const char *filename, int line)
Definition: shellutils.h:78
static PCUIDLIST_ABSOLUTE HIDA_GetPIDLFolder(CIDA const *pida)
Definition: shellutils.h:636
static ULONG Win32DbgPrint(const char *filename, int line, const char *lpFormat,...)
Definition: shellutils.h:27
static UINT SHELL_ErrorBoxHelper(HWND hwndOwner, UINT Error)
Definition: shellutils.h:98
static BOOL ILIsSingle(LPCITEMIDLIST pidl)
Definition: shellutils.h:631
static void DumpIdListOneLine(LPCITEMIDLIST pidl)
Definition: shellutils.h:833
#define SHELL_ErrorBox
Definition: shellutils.h:126
HRESULT hr
Definition: shlfolder.c:183
static const WCHAR CFSTR_SHELLIDLISTOFFSETW[]
Definition: shlobj.h:516
static const WCHAR CFSTR_SHELLIDLISTW[]
Definition: shlobj.h:514
@ 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:580
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:3280
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
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:446
#define CopyMemory
Definition: winbase.h:1741
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:449
#define GHND
Definition: winbase.h:323
_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:738
#define MIIM_ID
Definition: winuser.h:733
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:740
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
#define MFT_SEPARATOR
Definition: winuser.h:755
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
int WINAPIV wsprintfA(_Out_ LPSTR, _In_ _Printf_format_string_ LPCSTR,...)
#define MIIM_STATE
Definition: winuser.h:732
#define MIIM_SUBMENU
Definition: winuser.h:734
#define MFT_BITMAP
Definition: winuser.h:749
#define MB_OK
Definition: winuser.h:801
BOOL WINAPI GetMenuItemInfoW(_In_ HMENU, _In_ UINT, _In_ BOOL, _Inout_ LPMENUITEMINFOW)
#define MB_ICONSTOP
Definition: winuser.h:814
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