ReactOS 0.4.15-dev-7704-gc07eb9f
shlextdbg.cpp File Reference
#include <windows.h>
#include <shlobj.h>
#include <atlbase.h>
#include <atlcom.h>
#include <atlstr.h>
#include <atlsimpcoll.h>
#include <conio.h>
#include <shellutils.h>
Include dependency graph for shlextdbg.cpp:

Go to the source code of this file.

Enumerations

enum  WaitType { Wait_None , Wait_Infinite , Wait_OpenWindows , Wait_Input }
 

Functions

HRESULT CreateIDataObject (CComHeapPtr< ITEMIDLIST > &pidl, CComPtr< IDataObject > &dataObject, PCWSTR FileName)
 
HRESULT LoadAndInitialize (REFIID riid, LPVOID *ppv)
 
BOOL CALLBACK EnumWindowsProc (HWND hwnd, LPARAM lParam)
 
void WaitWindows ()
 
static BOOL CALLBACK cb_AddPage (HPROPSHEETPAGE page, LPARAM lParam)
 
static bool isCmdWithArg (int argc, WCHAR **argv, int &n, PCWSTR check, PCWSTR &arg)
 
static bool isCmd (int argc, WCHAR **argv, int n, PCWSTR check)
 
static void PrintHelp (PCWSTR ExtraLine)
 
int wmain (int argc, WCHAR **argv)
 

Variables

CLSID g_CLSID = { 0 }
 
CStringW g_DLL
 
CStringW g_ShellExtInit
 
bool g_bIShellPropSheetExt = false
 
CStringA g_ContextMenu
 
WaitType g_Wait = Wait_None
 
CSimpleArray< HWNDg_Windows
 
HWND g_ConsoleWindow
 
CSimpleArray< HPROPSHEETPAGEg_Pages
 

Enumeration Type Documentation

◆ WaitType

Enumerator
Wait_None 
Wait_Infinite 
Wait_OpenWindows 
Wait_Input 

Definition at line 17 of file shlextdbg.cpp.

18{
23};
@ Wait_OpenWindows
Definition: shlextdbg.cpp:21
@ Wait_Input
Definition: shlextdbg.cpp:22
@ Wait_Infinite
Definition: shlextdbg.cpp:20
@ Wait_None
Definition: shlextdbg.cpp:19

Function Documentation

◆ cb_AddPage()

static BOOL CALLBACK cb_AddPage ( HPROPSHEETPAGE  page,
LPARAM  lParam 
)
static

Definition at line 160 of file shlextdbg.cpp.

161{
162 g_Pages.Add(page);
163 if (lParam != (LPARAM)&g_Pages)
164 {
165 wprintf(L"Propsheet failed to pass lParam, got: 0x%Ix\n", lParam);
166 }
167 return TRUE;
168}
LPARAM lParam
Definition: combotst.c:139
#define TRUE
Definition: types.h:120
#define L(x)
Definition: ntvdm.h:50
CSimpleArray< HPROPSHEETPAGE > g_Pages
Definition: shlextdbg.cpp:159
Definition: module.h:576
#define wprintf(...)
Definition: whoami.c:18
LONG_PTR LPARAM
Definition: windef.h:208

Referenced by wmain().

◆ CreateIDataObject()

HRESULT CreateIDataObject ( CComHeapPtr< ITEMIDLIST > &  pidl,
CComPtr< IDataObject > &  dataObject,
PCWSTR  FileName 
)

Definition at line 32 of file shlextdbg.cpp.

33{
35 if (!SUCCEEDED(hr))
36 {
37 wprintf(L"Failed to create pidl from '%s': 0x%x\n", FileName, hr);
38 return hr;
39 }
40
41 CComPtr<IShellFolder> shellFolder;
42 PCUITEMID_CHILD childs;
43 hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &shellFolder), &childs);
44 if (!SUCCEEDED(hr))
45 {
46 wprintf(L"Failed to bind to parent: 0x%x\n", hr);
47 return hr;
48 }
49 hr = shellFolder->GetUIObjectOf(NULL, 1, &childs, IID_IDataObject, NULL, (PVOID*)&dataObject);
50 if (!SUCCEEDED(hr))
51 {
52 wprintf(L"Failed to query IDataObject: 0x%x\n", hr);
53 }
54 return hr;
55}
#define NULL
Definition: types.h:112
#define SUCCEEDED(hr)
Definition: intsafe.h:50
const GUID IID_IDataObject
HRESULT WINAPI SHParseDisplayName(LPCWSTR pszName, IBindCtx *pbc, LPITEMIDLIST *ppidl, SFGAOF sfgaoIn, SFGAOF *psfgaoOut)
Definition: pidl.c:1396
HRESULT WINAPI SHBindToParent(LPCITEMIDLIST pidl, REFIID riid, LPVOID *ppv, LPCITEMIDLIST *ppidlLast)
Definition: pidl.c:1352
HRESULT hr
Definition: shlfolder.c:183
const ITEMID_CHILD UNALIGNED * PCUITEMID_CHILD
Definition: shtypes.idl:70
#define IID_PPV_ARG(Itype, ppType)

Referenced by LoadAndInitialize().

◆ EnumWindowsProc()

BOOL CALLBACK EnumWindowsProc ( HWND  hwnd,
LPARAM  lParam 
)

Definition at line 127 of file shlextdbg.cpp.

128{
129 if (hwnd != g_ConsoleWindow)
130 {
131 DWORD pid = 0;
133 if (pid == GetCurrentProcessId())
134 {
135 g_Windows.Add(hwnd);
136 }
137 }
138 return TRUE;
139}
unsigned long DWORD
Definition: ntddk_ex.h:95
CSimpleArray< HWND > g_Windows
Definition: shlextdbg.cpp:125
HWND g_ConsoleWindow
Definition: shlextdbg.cpp:126
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, PDWORD lpdwProcessId)
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
_In_ ULONG_PTR _In_ ULONG _Out_ ULONG_PTR * pid
Definition: winddi.h:3837

Referenced by WaitWindows().

◆ isCmd()

static bool isCmd ( int  argc,
WCHAR **  argv,
int  n,
PCWSTR  check 
)
static

Definition at line 194 of file shlextdbg.cpp.

195{
196 return !wcsicmp(argv[n] + 1, check);
197}
#define wcsicmp
Definition: compat.h:15
#define check(expected, result)
Definition: dplayx.c:32
GLdouble n
Definition: glext.h:7729
#define argv
Definition: mplay32.c:18

Referenced by wmain().

◆ isCmdWithArg()

static bool isCmdWithArg ( int  argc,
WCHAR **  argv,
int n,
PCWSTR  check,
PCWSTR arg 
)
static

Definition at line 170 of file shlextdbg.cpp.

171{
172 arg = NULL;
173 size_t len = wcslen(check);
174 if (!_wcsnicmp(argv[n] + 1, check, len))
175 {
176 PCWSTR cmd = argv[n] + len + 1;
177 if (*cmd == ':' || *cmd == '=')
178 {
179 arg = cmd + 1;
180 return true;
181 }
182 if (n + 1 < argc)
183 {
184 arg = argv[n+1];
185 n++;
186 return true;
187 }
188 wprintf(L"Command %s has no required argument!\n", check);
189 return false;
190 }
191 return false;
192}
static int argc
Definition: ServiceArgs.c:12
GLenum GLsizei len
Definition: glext.h:6722
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
Definition: ftp_var.h:139
const uint16_t * PCWSTR
Definition: typedefs.h:57

Referenced by wmain().

◆ LoadAndInitialize()

HRESULT LoadAndInitialize ( REFIID  riid,
LPVOID ppv 
)

Definition at line 57 of file shlextdbg.cpp.

58{
59 CComPtr<IShellExtInit> spShellExtInit;
60 HRESULT hr;
61 if (g_DLL.IsEmpty())
62 {
63 hr = CoCreateInstance(g_CLSID, NULL, CLSCTX_ALL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
64 if (!SUCCEEDED(hr))
65 {
66 WCHAR Buffer[100];
68 wprintf(L"Failed to Create %s:IShellExtInit: 0x%x\n", Buffer, hr);
69 return hr;
70 }
71 }
72 else
73 {
74 typedef HRESULT (STDAPICALLTYPE *tDllGetClassObject)(REFCLSID rclsid, REFIID riid, LPVOID *ppv);
76 if (!mod)
77 {
78 wprintf(L"Failed to Load %s:(0x%x)\n", g_DLL.GetString(), GetLastError());
79 return E_FAIL;
80 }
81 tDllGetClassObject DllGet = (tDllGetClassObject)GetProcAddress(mod, "DllGetClassObject");
82 if (!DllGet)
83 {
84 wprintf(L"%s does not export DllGetClassObject\n", g_DLL.GetString());
85 return E_FAIL;
86 }
87 CComPtr<IClassFactory> spClassFactory;
88 hr = DllGet(g_CLSID, IID_PPV_ARG(IClassFactory, &spClassFactory));
89 if (!SUCCEEDED(hr))
90 {
91 wprintf(L"Failed to create IClassFactory: 0x%x\n", hr);
92 return hr;
93 }
94 hr = spClassFactory->CreateInstance(NULL, IID_PPV_ARG(IShellExtInit, &spShellExtInit));
95 if (!SUCCEEDED(hr))
96 {
97 wprintf(L"Failed to Request IShellExtInit from IClassFactory: 0x%x\n", hr);
98 return hr;
99 }
100 }
101
102 CComPtr<IDataObject> spDataObject;
104 hr = CreateIDataObject(pidl, spDataObject, g_ShellExtInit.GetString());
105 if (!SUCCEEDED(hr))
106 return hr;
107
108 hr = spShellExtInit->Initialize(pidl, spDataObject, NULL);
109 if (!SUCCEEDED(hr))
110 {
111 wprintf(L"IShellExtInit->Initialize failed: 0x%x\n", hr);
112 return hr;
113 }
114 hr = spShellExtInit->QueryInterface(riid, ppv);
115 if (!SUCCEEDED(hr))
116 {
117 WCHAR Buffer[100];
119 wprintf(L"Failed to query %s from IShellExtInit: 0x%x\n", Buffer, hr);
120 }
121 return hr;
122}
bool IsEmpty() const noexcept
Definition: atlsimpstr.h:389
PXSTR GetString() noexcept
Definition: atlsimpstr.h:367
Definition: bufpool.h:45
#define E_FAIL
Definition: ddrawi.h:102
#define GetProcAddress(x, y)
Definition: compat.h:753
#define LoadLibraryW(x)
Definition: compat.h:747
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
#define STDAPICALLTYPE
Definition: guid.c:3
static int mod
Definition: i386-dis.c:1288
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
CLSID g_CLSID
Definition: shlextdbg.cpp:25
CStringW g_ShellExtInit
Definition: shlextdbg.cpp:27
HRESULT CreateIDataObject(CComHeapPtr< ITEMIDLIST > &pidl, CComPtr< IDataObject > &dataObject, PCWSTR FileName)
Definition: shlextdbg.cpp:32
CStringW g_DLL
Definition: shlextdbg.cpp:26
#define _countof(array)
Definition: sndvol32.h:68
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by wmain().

◆ PrintHelp()

static void PrintHelp ( PCWSTR  ExtraLine)
static

Definition at line 199 of file shlextdbg.cpp.

200{
201 if (ExtraLine)
202 wprintf(L"%s\n", ExtraLine);
203
204 wprintf(L"shlextdbg /clsid={clsid} [/dll=dllname] /IShellExtInit=filename |shlextype| |waitoptions|\n");
205 wprintf(L" {clsid}: The CLSID or ProgID of the object to create\n");
206 wprintf(L" dll: Optional dllname to create the object from, instead of CoCreateInstance\n");
207 wprintf(L" filename: The filename to pass to IShellExtInit->Initialze\n");
208 wprintf(L" shlextype: The type of shell extention to run:\n");
209 wprintf(L" /IShellPropSheetExt to create a property sheet\n");
210 wprintf(L" /IContextMenu=verb to activate the specified verb\n");
211 wprintf(L" waitoptions: Specify how to wait:\n");
212 wprintf(L" /infinite: Keep on waiting infinitely\n");
213 wprintf(L" /openwindows: Wait for all windows from the current application to close\n");
214 wprintf(L" /input: Wait for input\n");
215 wprintf(L"\n");
216}

◆ WaitWindows()

void WaitWindows ( )

Definition at line 141 of file shlextdbg.cpp.

142{
143 /* Give the windows some time to spawn */
144 Sleep(2000);
146 while (true)
147 {
148 g_Windows.RemoveAll();
150 if (g_Windows.GetSize() == 0)
151 break;
152 Sleep(500);
153 }
154 wprintf(L"All windows closed (ignoring console window)\n");
155}
HWND WINAPI DECLSPEC_HOTPATCH GetConsoleWindow(VOID)
Definition: console.c:2729
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
Definition: shlextdbg.cpp:127
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
BOOL WINAPI EnumWindows(_In_ WNDENUMPROC lpEnumFunc, _In_ LPARAM lParam)

Referenced by wmain().

◆ wmain()

int wmain ( int  argc,
WCHAR **  argv 
)

Definition at line 227 of file shlextdbg.cpp.

228{
229 bool failArgs = false;
230 for (int n = 1; n < argc; ++n)
231 {
232 WCHAR* cmd = argv[n];
233 if (cmd[0] == '-' || cmd[0] == '/')
234 {
235 PCWSTR arg;
236 if (isCmdWithArg(argc, argv, n, L"clsid", arg))
237 {
239 if (!SUCCEEDED(hr))
240 {
241 wprintf(L"Failed to convert %s to CLSID\n", arg);
242 failArgs = true;
243 }
244 }
245 else if (isCmdWithArg(argc, argv, n, L"dll", arg))
246 {
247 g_DLL = arg;
248 }
249 else if (isCmdWithArg(argc, argv, n, L"IShellExtInit", arg))
250 {
252 }
253 else if (isCmd(argc, argv, n, L"IShellPropSheetExt"))
254 {
256 }
257 else if (isCmdWithArg(argc, argv, n, L"IContextMenu", arg))
258 {
260 }
261 else if (isCmd(argc, argv, n, L"infinite"))
262 {
264 }
265 else if (isCmd(argc, argv, n, L"openwindows"))
266 {
268 }
269 else if (isCmd(argc, argv, n, L"input"))
270 {
272 }
273 else
274 {
275 wprintf(L"Unknown argument: %s\n", cmd);
276 failArgs = true;
277 }
278 }
279 }
280
281 if (failArgs)
282 {
284 return E_INVALIDARG;
285 }
286
287
288 CLSID EmptyCLSID = { 0 };
289 if (EmptyCLSID == g_CLSID)
290 {
291 PrintHelp(L"No CLSID specified");
292 return E_INVALIDARG;
293 }
294
296 {
297 PrintHelp(L"No filename specified");
298 return E_INVALIDARG;
299 }
300
304
305 HRESULT hr;
307 {
310 if (!SUCCEEDED(hr))
311 return hr;
312
313 hr = spSheetExt->AddPages(cb_AddPage, (LPARAM)&g_Pages);
314 if (!SUCCEEDED(hr))
315 {
316 wprintf(L"IShellPropSheetExt->AddPages failed: 0x%x\n", hr);
317 return hr;
318 }
319
320 USHORT ActivePage = HRESULT_CODE(hr);
321 PROPSHEETHEADERW psh = { 0 };
322
323 psh.dwSize = sizeof(psh);
325 psh.pszCaption = L"shlextdbg";
326 psh.phpage = g_Pages.GetData();
327 psh.nPages = g_Pages.GetSize();
328 psh.nStartPage = ActivePage ? (ActivePage-1) : 0;
329 hr = PropertySheetW(&psh);
330
331 wprintf(L"PropertySheetW returned: 0x%x\n", hr);
332 }
333 if (!g_ContextMenu.IsEmpty())
334 {
335 CComPtr<IContextMenu> spContextMenu;
336 hr = LoadAndInitialize(IID_PPV_ARG(IContextMenu, &spContextMenu));
337 if (!SUCCEEDED(hr))
338 return hr;
339
340 CMINVOKECOMMANDINFO cm = { sizeof(cm), 0 };
341 cm.lpVerb = g_ContextMenu.GetString();
342 cm.nShow = SW_SHOW;
343 hr = spContextMenu->InvokeCommand(&cm);
344
345 if (!SUCCEEDED(hr))
346 {
347 wprintf(L"IContextMenu->InvokeCommand failed: 0x%x\n", hr);
348 return hr;
349 }
350 wprintf(L"IContextMenu->InvokeCommand returned: 0x%x\n", hr);
351 }
352
353 switch (g_Wait)
354 {
355 case Wait_None:
356 break;
357 case Wait_Infinite:
358 while (true) {
359 Sleep(1000);
360 }
361 break;
362 case Wait_OpenWindows:
363 WaitWindows();
364 break;
365 case Wait_Input:
366 wprintf(L"Press any key to continue...\n");
367 _getch();
368 break;
369
370 }
371 return 0;
372}
BOOL WINAPI InitCommonControlsEx(const INITCOMMONCONTROLSEX *lpInitCtrls)
Definition: commctrl.c:893
#define E_INVALIDARG
Definition: ddrawi.h:101
INT_PTR WINAPI PropertySheetW(LPCPROPSHEETHEADERW lppsh)
Definition: propsheet.c:2913
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
void PrintHelp()
Definition: appwiz.c:21
unsigned short USHORT
Definition: pedump.c:61
#define PSH_PROPTITLE
Definition: prsht.h:40
#define ICC_STANDARD_CLASSES
Definition: commctrl.h:73
#define ICC_LINK_CLASS
Definition: commctrl.h:74
int _getch()
Definition: getch.c:16
CStringA g_ContextMenu
Definition: shlextdbg.cpp:29
static BOOL CALLBACK cb_AddPage(HPROPSHEETPAGE page, LPARAM lParam)
Definition: shlextdbg.cpp:160
WaitType g_Wait
Definition: shlextdbg.cpp:30
static bool isCmdWithArg(int argc, WCHAR **argv, int &n, PCWSTR check, PCWSTR &arg)
Definition: shlextdbg.cpp:170
static bool isCmd(int argc, WCHAR **argv, int n, PCWSTR check)
Definition: shlextdbg.cpp:194
HRESULT LoadAndInitialize(REFIID riid, LPVOID *ppv)
Definition: shlextdbg.cpp:57
bool g_bIShellPropSheetExt
Definition: shlextdbg.cpp:28
void WaitWindows()
Definition: shlextdbg.cpp:141
DWORD dwSize
Definition: prsht.h:293
DWORD dwFlags
Definition: prsht.h:294
HPROPSHEETPAGE * phpage
Definition: prsht.h:309
UINT nStartPage
Definition: prsht.h:304
LPCWSTR pszCaption
Definition: prsht.h:301
void * arg
Definition: msvc.h:10
#define HRESULT_CODE(hr)
Definition: winerror.h:76
#define SW_SHOW
Definition: winuser.h:774

Variable Documentation

◆ g_bIShellPropSheetExt

bool g_bIShellPropSheetExt = false

Definition at line 28 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_CLSID

CLSID g_CLSID = { 0 }

Definition at line 25 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_ConsoleWindow

HWND g_ConsoleWindow

Definition at line 126 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().

◆ g_ContextMenu

CStringA g_ContextMenu

Definition at line 29 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_DLL

CStringW g_DLL

Definition at line 26 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_Pages

Definition at line 159 of file shlextdbg.cpp.

Referenced by cb_AddPage(), and wmain().

◆ g_ShellExtInit

CStringW g_ShellExtInit

Definition at line 27 of file shlextdbg.cpp.

Referenced by LoadAndInitialize(), and wmain().

◆ g_Wait

WaitType g_Wait = Wait_None

Definition at line 30 of file shlextdbg.cpp.

Referenced by wmain().

◆ g_Windows

CSimpleArray<HWND> g_Windows

Definition at line 125 of file shlextdbg.cpp.

Referenced by EnumWindowsProc(), and WaitWindows().