debughlp.c 7.96 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
/*
 * Helper functions for debugging
 *
 * Copyright 1998, 2002 Juergen Schmied
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pidl.h"
#include "shlguid.h"
#include "wine/debug.h"
#include "debughlp.h"
29 30
#include "docobj.h"
#include "shell32_main.h"
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136


WINE_DEFAULT_DEBUG_CHANNEL(pidl);

LPITEMIDLIST  _dbg_ILGetNext(LPITEMIDLIST pidl)
{
	WORD len;

	if(pidl)
	{
	  len =  pidl->mkid.cb;
	  if (len)
	  {
	    pidl = (LPITEMIDLIST) (((LPBYTE)pidl)+len);
	    return pidl;
	  }
	}
	return NULL;
}

BOOL _dbg_ILIsDesktop(LPCITEMIDLIST pidl)
{
	return ( !pidl || (pidl && pidl->mkid.cb == 0x00) );
}

LPPIDLDATA _dbg_ILGetDataPointer(LPITEMIDLIST pidl)
{
	if(pidl && pidl->mkid.cb != 0x00)
	  return (LPPIDLDATA) &(pidl->mkid.abID);
	return NULL;
}

LPSTR _dbg_ILGetTextPointer(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_MYCOMP:
	    case PT_SPECIAL:
	      return NULL;

	    case PT_DRIVE:
	    case PT_DRIVE1:
	    case PT_DRIVE2:
	    case PT_DRIVE3:
	      return (LPSTR)&(pdata->u.drive.szDriveName);

	    case PT_FOLDER:
	    case PT_FOLDER1:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_IESPECIAL2:
	      return (LPSTR)&(pdata->u.file.szNames);

	    case PT_WORKGRP:
	    case PT_COMP:
	    case PT_NETWORK:
	    case PT_SHARE:
	      return (LPSTR)&(pdata->u.network.szNames);
	  }
	}
	return NULL;
}

LPSTR _dbg_ILGetSTextPointer(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_dbg_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_FOLDER:
	    case PT_VALUE:
	    case PT_IESPECIAL1:
	    case PT_IESPECIAL2:
	      return (LPSTR)(pdata->u.file.szNames + strlen (pdata->u.file.szNames) + 1);

	    case PT_WORKGRP:
	      return (LPSTR)(pdata->u.network.szNames + strlen (pdata->u.network.szNames) + 1);
	  }
	}
	return NULL;
}

REFIID _dbg_ILGetGUIDPointer(LPCITEMIDLIST pidl)
{
	LPPIDLDATA pdata =_ILGetDataPointer(pidl);

	if (pdata)
	{
	  switch (pdata->type)
	  {
	    case PT_SPECIAL:
	    case PT_MYCOMP:
	      return (REFIID) &(pdata->u.mycomp.guid);
	  }
	}
	return NULL;
}

DWORD _dbg_ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR szOut, UINT uOutSize)
{
137
	DWORD		dwReturn=0;
138 139 140
	LPSTR		szSrc;
	GUID const * 	riid;
	char szTemp[MAX_PATH];
141

142 143 144 145 146
	if (!pidl) return 0;

	if (szOut)
	  *szOut = 0;

147
	if (_dbg_ILIsDesktop(pidl))
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
	{
	 /* desktop */
	  if (szOut) strncpy(szOut, "Desktop", uOutSize);
	  dwReturn = strlen ("Desktop");
	}
	else if (( szSrc = _dbg_ILGetTextPointer(pidl) ))
	{
	  /* filesystem */
	  if (szOut) strncpy(szOut, szSrc, uOutSize);
	  dwReturn = strlen(szSrc);
	}
	else if (( riid = _dbg_ILGetGUIDPointer(pidl) ))
	{
	  if (szOut)
            sprintf( szOut, "{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
                 riid->Data1, riid->Data2, riid->Data3,
                 riid->Data4[0], riid->Data4[1], riid->Data4[2], riid->Data4[3],
                 riid->Data4[4], riid->Data4[5], riid->Data4[6], riid->Data4[7] );
	  dwReturn = strlen (szTemp);
	}
	return dwReturn;
}




void pdump (LPCITEMIDLIST pidl)
{
	LPITEMIDLIST pidltemp = pidl;

	if (!TRACE_ON(pidl)) return;

	if (! pidltemp)
	{
	  MESSAGE ("-------- pidl=NULL (Desktop)\n");
	}
	else
	{
	  MESSAGE ("-------- pidl=%p\n", pidl);
	  if (pidltemp->mkid.cb)
188
	  {
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
	    do
	    {
	      DWORD dwAttrib = 0;
	      LPPIDLDATA pData   = _dbg_ILGetDataPointer(pidltemp);
	      DWORD type         = pData->type;
	      LPSTR szLongName   = _dbg_ILGetTextPointer(pidltemp);
	      LPSTR szShortName  = _dbg_ILGetSTextPointer(pidltemp);
	      char szName[MAX_PATH];

	      _dbg_ILSimpleGetText(pidltemp, szName, MAX_PATH);
	      if( PT_FOLDER == type)
	        dwAttrib = pData->u.folder.uFileAttribs;
	      else if( PT_VALUE == type)
	        dwAttrib = pData->u.file.uFileAttribs;

204
	      MESSAGE ("[%p] size=%04u type=%lx attr=0x%08lx name=\"%s\" (%s,%s)\n",
205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
	               pidltemp, pidltemp->mkid.cb,type,dwAttrib,szName,debugstr_a(szLongName), debugstr_a(szShortName));

	      pidltemp = _dbg_ILGetNext(pidltemp);

	    } while (pidltemp->mkid.cb);
	  }
	  else
	  {
	    MESSAGE ("empty pidl (Desktop)\n");
	  }
	  pcheck(pidl);
	}
}
#define BYTES_PRINTED 32
BOOL pcheck (LPCITEMIDLIST pidl)
{
        DWORD type, ret=TRUE;
        LPITEMIDLIST pidltemp = pidl;

        if (pidltemp && pidltemp->mkid.cb)
        { do
          { type   = _dbg_ILGetDataPointer(pidltemp)->type;
            switch (type)
	    { case PT_DESKTOP:
	      case PT_MYCOMP:
	      case PT_SPECIAL:
	      case PT_DRIVE:
	      case PT_DRIVE1:
	      case PT_DRIVE2:
	      case PT_DRIVE3:
	      case PT_FOLDER:
	      case PT_VALUE:
	      case PT_FOLDER1:
	      case PT_WORKGRP:
	      case PT_COMP:
	      case PT_NETWORK:
	      case PT_IESPECIAL1:
	      case PT_IESPECIAL2:
	      case PT_SHARE:
		break;
	      default:
	      {
		char szTemp[BYTES_PRINTED*4 + 1];
		int i;
		unsigned char c;

		memset(szTemp, ' ', BYTES_PRINTED*4 + 1);
		for ( i = 0; (i<pidltemp->mkid.cb) && (i<BYTES_PRINTED); i++)
		{
		  c = ((unsigned char *)pidltemp)[i];

		  szTemp[i*3+0] = ((c>>4)>9)? (c>>4)+55 : (c>>4)+48;
		  szTemp[i*3+1] = ((0x0F&c)>9)? (0x0F&c)+55 : (0x0F&c)+48;
		  szTemp[i*3+2] = ' ';
		  szTemp[i+BYTES_PRINTED*3]  =  (c>=0x20 && c <=0x80) ? c : '.';
		}
		szTemp[BYTES_PRINTED*4] = 0x00;
262
		ERR("unknown IDLIST %p [%p] size=%u type=%lx\n%s\n",pidl, pidltemp, pidltemp->mkid.cb,type, szTemp);
263 264 265 266 267 268 269 270
		ret = FALSE;
	      }
	    }
	    pidltemp = _dbg_ILGetNext(pidltemp);
	  } while (pidltemp->mkid.cb);
	}
	return ret;
}
271

272 273 274
static char shdebugstr_buf1[100];
static char shdebugstr_buf2[100];
static char * shdebugstr_buf = shdebugstr_buf1;
275 276 277 278 279 280

static struct {
	REFIID	riid;
	char 	*name;
} InterfaceDesc[] = {
	{&IID_IUnknown,			"IID_IUnknown"},
281
	{&IID_IClassFactory,		"IID_IClassFactory"},
282 283 284 285 286 287 288 289 290 291 292 293 294 295
	{&IID_IShellView,		"IID_IShellView"},
	{&IID_IOleCommandTarget,	"IID_IOleCommandTarget"},
	{&IID_IDropTarget,		"IID_IDropTarget"},
	{&IID_IDropSource,		"IID_IDropSource"},
	{&IID_IViewObject,		"IID_IViewObject"},
	{&IID_IContextMenu,		"IID_IContextMenu"},
	{&IID_IShellExtInit,		"IID_IShellExtInit"},
	{&IID_IShellFolder,		"IID_IShellFolder"},
	{&IID_IShellFolder2,		"IID_IShellFolder2"},
	{&IID_IPersist,			"IID_IPersist"},
	{&IID_IPersistFolder,		"IID_IPersistFolder"},
	{&IID_IPersistFolder2,		"IID_IPersistFolder2"},
	{&IID_IPersistFolder3,		"IID_IPersistFolder3"},
	{&IID_IExtractIconA,		"IID_IExtractIconA"},
296
	{&IID_IExtractIconW,		"IID_IExtractIconW"},
297 298 299 300 301 302 303 304 305
	{&IID_IDataObject,		"IID_IDataObject"},
	{NULL,NULL}};

const char * shdebugstr_guid( const struct _GUID *id )
{
	int i;
	char* name = NULL;
	char clsidbuf[100];

306 307
	shdebugstr_buf = (shdebugstr_buf == shdebugstr_buf1) ? shdebugstr_buf2 : shdebugstr_buf1;

308 309 310 311 312 313 314
	if (!id) {
	  strcpy (shdebugstr_buf, "(null)");
	} else {
	    for (i=0;InterfaceDesc[i].riid && !name;i++) {
	        if (IsEqualIID(InterfaceDesc[i].riid, id)) name = InterfaceDesc[i].name;
	    }
	    if (!name) {
315
		if (HCR_GetClassNameA(id, clsidbuf, 100))
316 317 318 319 320 321 322 323 324 325
		    name = clsidbuf;
	    }

	    sprintf( shdebugstr_buf, "\n\t{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x} (%s)",
                 id->Data1, id->Data2, id->Data3,
                 id->Data4[0], id->Data4[1], id->Data4[2], id->Data4[3],
                 id->Data4[4], id->Data4[5], id->Data4[6], id->Data4[7], name ? name : "unknown" );
	}
	return shdebugstr_buf;
}