2 * Helper functions for debugging
4 * Copyright 1998, 2002 Juergen Schmied
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
29 #include "wine/debug.h"
32 #include "shell32_main.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(pidl);
38 LPITEMIDLIST _dbg_ILGetNext(LPCITEMIDLIST pidl)
47 return (LPITEMIDLIST) (((LPBYTE)pidl)+len);
54 BOOL _dbg_ILIsDesktop(LPCITEMIDLIST pidl)
56 return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
60 LPPIDLDATA _dbg_ILGetDataPointer(LPCITEMIDLIST pidl)
62 if(pidl && pidl->mkid.cb != 0x00)
63 return (LPPIDLDATA)pidl->mkid.abID;
68 LPSTR _dbg_ILGetTextPointer(LPCITEMIDLIST pidl)
70 LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
85 return pdata->u.drive.szDriveName;
92 return pdata->u.file.szNames;
99 return pdata->u.network.szNames;
106 LPWSTR _dbg_ILGetTextPointerW(LPCITEMIDLIST pidl)
108 LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
123 /* return (LPSTR)&(pdata->u.drive.szDriveName);*/
131 /* return (LPSTR)&(pdata->u.file.szNames); */
139 /* return (LPSTR)&(pdata->u.network.szNames); */
143 return (LPWSTR)pdata->u.file.szNames;
151 LPSTR _dbg_ILGetSTextPointer(LPCITEMIDLIST pidl)
153 LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
163 return pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1;
166 return pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1;
173 LPWSTR _dbg_ILGetSTextPointerW(LPCITEMIDLIST pidl)
175 LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);
185 /*return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1); */
189 /* return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1); */
193 return (LPWSTR)(pdata->u.file.szNames + lstrlenW ((LPWSTR)pdata->u.file.szNames) + 1);
201 IID* _dbg_ILGetGUIDPointer(LPCITEMIDLIST pidl)
203 LPPIDLDATA pdata =_ILGetDataPointer(pidl);
212 return &(pdata->u.guid.guid);
219 void _dbg_ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
230 if (_dbg_ILIsDesktop(pidl))
233 if (szOut) lstrcpynA(szOut, "Desktop", uOutSize);
235 else if (( szSrc = _dbg_ILGetTextPointer(pidl) ))
238 if (szOut) lstrcpynA(szOut, szSrc, uOutSize);
240 else if (( szSrcW = _dbg_ILGetTextPointerW(pidl) ))
243 /* unicode filesystem */
244 WideCharToMultiByte(CP_ACP,0,szSrcW, -1, tmp, MAX_PATH, NULL, NULL);
245 if (szOut) lstrcpynA(szOut, tmp, uOutSize);
247 else if (( riid = _dbg_ILGetGUIDPointer(pidl) ))
250 sprintf( szOut, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
251 riid->Data1, riid->Data2, riid->Data3,
252 riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
253 riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
260 void pdump (LPCITEMIDLIST pidl)
262 LPCITEMIDLIST pidltemp = pidl;
264 if (!TRACE_ON(pidl)) return;
268 MESSAGE ("-------- pidl=NULL (Desktop)\n");
272 MESSAGE ("-------- pidl=%p\n", pidl);
273 if (pidltemp->mkid.cb)
277 if (_ILIsUnicode(pidltemp))
280 LPPIDLDATA pData = _dbg_ILGetDataPointer(pidltemp);
281 DWORD type = pData ? pData->type : 0;
282 LPWSTR szLongName = _dbg_ILGetTextPointerW(pidltemp);
283 LPWSTR szShortName = _dbg_ILGetSTextPointerW(pidltemp);
284 char szName[MAX_PATH];
286 _dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH);
287 if ( pData && (PT_FOLDER == type || PT_VALUE == type) )
288 dwAttrib = pData->u.file.uFileAttribs;
290 MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n",
291 pidltemp, pidltemp->mkid.cb, type, dwAttrib,
292 debugstr_a(szName), debugstr_w(szLongName), debugstr_w(szShortName));
297 LPPIDLDATA pData = _dbg_ILGetDataPointer(pidltemp);
298 DWORD type = pData ? pData->type : 0;
299 LPSTR szLongName = _dbg_ILGetTextPointer(pidltemp);
300 LPSTR szShortName = _dbg_ILGetSTextPointer(pidltemp);
301 char szName[MAX_PATH];
303 _dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH);
304 if ( pData && (PT_FOLDER == type || PT_VALUE == type) )
305 dwAttrib = pData->u.file.uFileAttribs;
307 MESSAGE ("[%p] size=%04u type=%x attr=0x%08x name=%s (%s,%s)\n",
308 pidltemp, pidltemp->mkid.cb, type, dwAttrib,
309 debugstr_a(szName), debugstr_a(szLongName), debugstr_a(szShortName));
312 pidltemp = _dbg_ILGetNext(pidltemp);
314 } while (pidltemp && pidltemp->mkid.cb);
318 MESSAGE ("empty pidl (Desktop)\n");
324 static void dump_pidl_hex( LPCITEMIDLIST pidl )
326 const unsigned char *p = (const unsigned char *)pidl;
327 const int max_bytes = 0x80;
328 #define max_line 0x10
329 char szHex[max_line*3+1], szAscii[max_line+1];
337 sprintf( &szHex[ (i%max_line)*3 ], "%02X ", p[i] );
338 szAscii[ (i%max_line) ] = isprint( p[i] ) ? p[i] : '.';
340 /* print out at the end of each line and when we're finished */
341 if( i!=(n-1) && (i%max_line) != (max_line-1) )
343 szAscii[ (i%max_line)+1 ] = 0;
344 ERR("%-*s %s\n", max_line*3, szHex, szAscii );
348 BOOL pcheck( LPCITEMIDLIST pidl )
351 LPCITEMIDLIST pidltemp = pidl;
353 while( pidltemp && pidltemp->mkid.cb )
355 type = _dbg_ILGetDataPointer(pidltemp)->type;
379 ERR("unknown IDLIST %p [%p] size=%u type=%x\n",
380 pidl, pidltemp, pidltemp->mkid.cb,type );
381 dump_pidl_hex( pidltemp );
384 pidltemp = _dbg_ILGetNext(pidltemp);
389 static const struct {
392 } InterfaceDesc[] = {
393 {&IID_IUnknown, "IID_IUnknown"},
394 {&IID_IClassFactory, "IID_IClassFactory"},
395 {&IID_IShellView, "IID_IShellView"},
396 {&IID_IOleCommandTarget, "IID_IOleCommandTarget"},
397 {&IID_IDropTarget, "IID_IDropTarget"},
398 {&IID_IDropSource, "IID_IDropSource"},
399 {&IID_IViewObject, "IID_IViewObject"},
400 {&IID_IContextMenu, "IID_IContextMenu"},
401 {&IID_IShellExtInit, "IID_IShellExtInit"},
402 {&IID_IShellFolder, "IID_IShellFolder"},
403 {&IID_IShellFolder2, "IID_IShellFolder2"},
404 {&IID_IPersist, "IID_IPersist"},
405 {&IID_IPersistFolder, "IID_IPersistFolder"},
406 {&IID_IPersistFolder2, "IID_IPersistFolder2"},
407 {&IID_IPersistFolder3, "IID_IPersistFolder3"},
408 {&IID_IExtractIconA, "IID_IExtractIconA"},
409 {&IID_IExtractIconW, "IID_IExtractIconW"},
410 {&IID_IDataObject, "IID_IDataObject"},
411 {&IID_IAutoComplete, "IID_IAutoComplete"},
412 {&IID_IAutoComplete2, "IID_IAutoComplete2"},
413 {&IID_IShellLinkA, "IID_IShellLinkA"},
414 {&IID_IShellLinkW, "IID_IShellLinkW"},
417 const char * shdebugstr_guid( const struct _GUID *id )
420 const char* name = NULL;
423 if (!id) return "(null)";
425 for (i = 0; InterfaceDesc[i].riid && !name; i++) {
426 if (IsEqualIID(InterfaceDesc[i].riid, id)) name = InterfaceDesc[i].name;
429 if (HCR_GetClassNameA(id, clsidbuf, 100))
433 return wine_dbg_sprintf( "%s (%s)", debugstr_guid(id), name ? name : "unknown" );