|
|
#include "precomp.h"
#pragma hdrstop
#include "shguidp.h"
#include "..\..\shell32\pidl.h"
#include "..\..\shell32\shitemid.h"
// We never want assertions since we are the debugger extension!
#undef DBG
#undef DEBUG
#include "..\..\lib\idhidden.cpp"
extern "C" { #include <stdexts.h>
};
UNALIGNED WCHAR * ua_lstrcpyW(UNALIGNED WCHAR * dst, UINT cchDest, UNALIGNED const WCHAR * src) { UNALIGNED WCHAR * cp = dst;
if (cchDest == 0) return dst;
while( cchDest ) { WCHAR ch = *src++;
*cp++ = ch;
if (ch == TEXT('\0')) { break; } --cchDest; }
if (cchDest == 0) { --cp; *cp = TEXT('\0'); }
return( dst ); }
///////////////////////////////////////////////////////////////////////////////
// Pidl Cracking function //
// //
// returns fSuccess //
// //
// History: //
// 11/4/97 Created by cdturner //
// //
///////////////////////////////////////////////////////////////////////////////
// NOTE: the options are autovalidate before they are passed to us
typedef enum _PidlTypes { PIDL_UNKNOWN, PIDL_ROOT, PIDL_FILESYS, PIDL_DRIVES, PIDL_NET, PIDL_INTERNET, PIDL_FAVORITES } PIDLTYPE;
#define PIDL_BUFFER_SIZE 400
class CPidlBreaker { public: CPidlBreaker( LPVOID pArg ); ~CPidlBreaker( );
void SetVerbose() {_fVerbose = TRUE;};
VOID SetType( PIDLTYPE eType ); BOOL FillBuffer( DWORD cbSize, BOOL fAppend ); VOID ResetBuffer( void );
WORD FetchWord(); DWORD FetchDWORD(); LPBYTE GetBuffer( int iPos = 0);
PIDLTYPE CrackType( BYTE bType ); void PrintType( PIDLTYPE eType ); BOOL PrintPidl(); BOOL PrintRootPidl(); BOOL PrintDrivePidl(); BOOL PrintFileSysPidl(); BOOL PrintInternetPidl(); BOOL PrintNetworkPidl();
BOOL GetSHIDFlags( BYTE bFlags, CHAR * pszBuffer, DWORD cchSize );
void CLSIDToString( CHAR * pszBuffer, DWORD cchSize, REFCLSID rclsid );
BOOL GetCLSIDText( const CHAR * pszCLSID, CHAR * pszBuffer, DWORD cbSize ); private: PIDLTYPE _eType; LPVOID _pArg; BYTE _rgBuffer[PIDL_BUFFER_SIZE]; int _iCurrent; int _iMax; BOOL _fVerbose;
// used to display slashes right when we are not in verbose mode...
BOOL _fSlash; };
extern "C" BOOL Ipidl( DWORD dwOpts, LPVOID pArg ) { PIDLTYPE eType = PIDL_UNKNOWN;
CPidlBreaker Breaker( pArg ); if ( dwOpts & OFLAG(r)) { Breaker.SetType( PIDL_ROOT ); } else if ( dwOpts & OFLAG(f)) { Breaker.SetType( PIDL_FILESYS ); }
if (dwOpts & OFLAG(v)) { Breaker.SetVerbose(); }
BOOL bRes = FALSE; __try { bRes = Breaker.PrintPidl(); } __except( EXCEPTION_EXECUTE_HANDLER ) { Print( "Exception caught in !pidl\n"); }
if ( !(dwOpts & OFLAG(v)) ) Print( "\n" ); return bRes; }
VOID CPidlBreaker::SetType( PIDLTYPE eType ) { _eType = eType; }
CPidlBreaker::CPidlBreaker( LPVOID pArg ) { _pArg = pArg; _iCurrent = 0; _iMax = 0; _eType = PIDL_UNKNOWN; _fVerbose = FALSE; _fSlash = FALSE; }
CPidlBreaker::~CPidlBreaker( ) { }
BOOL CPidlBreaker::FillBuffer( DWORD cbSize, BOOL fAppend ) { if ( !fAppend ) { _iCurrent = 0; _iMax = 0; }
int iStart = fAppend ? _iMax : 0;
if ( cbSize + iStart > PIDL_BUFFER_SIZE ) { return FALSE; }
#ifdef DEBUG
char szBuffer[50]; StringCchPrintf( szBuffer, ARRAYSIZE(szBuffer), "****Moving %d from %8X\n", cbSize, _pArg ); Print( szBuffer ); #endif
if ( tryMoveBlock( _rgBuffer + iStart, _pArg, cbSize )) {
#ifdef DEBUG
for ( int iByte = 0; iByte < (int) cbSize; iByte ++ ) { StringCchPrintf( szBuffer, ARRAYSIZE(szBuffer), "Byte %2x\n", _rgBuffer[iByte + iStart] ); Print( szBuffer ); } #endif
_pArg = (LPBYTE) _pArg + cbSize; _iMax += cbSize;
return TRUE; } else { return FALSE; } }
WORD CPidlBreaker::FetchWord() { // assume that the buffer has been filled...
if ( _iCurrent + 1 >= _iMax ) { return 0; } WORD wRet = MAKEWORD( _rgBuffer[_iCurrent], _rgBuffer[_iCurrent + 1]); _iCurrent += 2;
#ifdef DEBUG
char szBuffer[200]; StringCchPrintf( szBuffer, ARRAYSIZE(szBuffer), "FetchWord() == %4X\n", wRet ); Print( szBuffer ); #endif
return wRet; }
DWORD CPidlBreaker::FetchDWORD() { // assume that the buffer has been filled...
if ( _iCurrent + 3 >= _iMax ) { return 0; } DWORD dwRet = MAKELONG( MAKEWORD( _rgBuffer[_iCurrent], _rgBuffer[_iCurrent + 1]), MAKEWORD( _rgBuffer[_iCurrent + 2], _rgBuffer[_iCurrent + 3] )); _iCurrent += 4;
#ifdef DEBUG
char szBuffer[200]; StringCchPrintf(( szBuffer, ARRAYSIZE(szBuffer), "FetchDWord() == %8X\n", dwRet ); Print( szBuffer ); #endif
return dwRet; }
LPBYTE CPidlBreaker::GetBuffer(int iPos) { return _rgBuffer + _iCurrent + iPos; }
VOID CPidlBreaker::ResetBuffer( ) { _iCurrent = 0; _iMax = 0; }
BOOL CPidlBreaker::PrintRootPidl() { CHAR szBuffer[200]; if ( !FillBuffer( sizeof( WORD ), FALSE )) { Print( "ERROR Unable to get the pidl size\n"); return FALSE; }
// get the size of the first chunk
WORD wSize = FetchWord();
// root pidls always have the size field as 14
if ( wSize != sizeof( IDREGITEM )) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Pidl Size %d seems bogus for a regitem\n", wSize ); Print( szBuffer ); return FALSE; } else { if ( !FillBuffer( wSize - sizeof(WORD) , TRUE )) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Error: unable to access the data for the pidl of size %d\n", wSize ); Print( szBuffer ); return FALSE; }
LPBYTE pBuf = GetBuffer(- ((int) sizeof(WORD))); char szBuffer2[200];
if ( pBuf[2] != SHID_ROOT_REGITEM ) { Print( "Pidl has incorrect flags, should have SHID_ROOT_REGITEM\n"); } // now map it to a Root structure
LPIDREGITEM pRegItem = (LPIDREGITEM) pBuf;
GetSHIDFlags( pRegItem->bFlags, szBuffer2, ARRAYSIZE( szBuffer2 )); Print( "RegItem Pidl:\n");
if ( _fVerbose ) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " bFlags = %d (%s)\n", pRegItem->bFlags, szBuffer2 ); Print( szBuffer ); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " bOrder = %d\n", pRegItem->bOrder ); Print( szBuffer ); } CHAR szCLSID[40]; CLSIDToString( szCLSID, ARRAYSIZE( szCLSID ), pRegItem->clsid );
StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " CLSID = %s ", szCLSID ); Print( szBuffer );
if ( GetCLSIDText( szCLSID, szBuffer2 + 1, ARRAYSIZE( szBuffer2 ) -2)) { szBuffer2[0] = '('; StringCchCatA( szBuffer2, ARRAYSIZE(szBuffer2), ")\n" ); Print( szBuffer2 ); }
if ( _fVerbose ) Print( "\n" ); ResetBuffer(); if ( pRegItem->clsid == CLSID_ShellNetwork ) { PrintNetworkPidl(); } else if ( pRegItem->clsid == CLSID_ShellInetRoot ) { // internet root
PrintInternetPidl(); } else if ( pRegItem->clsid == CLSID_ShellDrives ) { // file system pidls ...
PrintDrivePidl(); } else { // unknown pidl type ....
Print( "unknown pidl type, can't crack any further\n"); } }
return TRUE; }
void _SprintDosDateTime(LPSTR szBuffer, LPCSTR pszType, WORD wDate, WORD wTime) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " date/time %s = 0x%04x/%04x = %04d/%02d/%02d %02d:%02d:%02d\n", pszType, wDate, wTime, ((wDate & 0xFE00) >> 9)+1980, (wDate & 0x01E0) >> 5, (wDate & 0x001F) >> 0, (wTime & 0xF800) >> 11, (wTime & 0x07E0) >> 5, (wTime & 0x001F) << 1 ); }
BOOL CPidlBreaker::PrintFileSysPidl() { CHAR szBuffer[200]; CHAR szBuffer2[200]; if ( !FillBuffer( sizeof( WORD ), FALSE )) { Print( "ERROR Unable to get the pidl size\n"); return FALSE; } // get the size of the first chunk
WORD wSize = FetchWord();
if ( wSize == 0 ) { // end of the pidl chain....
return TRUE; } if ( !FillBuffer( wSize - sizeof(WORD) , TRUE )) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Error: unable to access the data for the pidl of size %d\n", wSize ); Print( szBuffer ); return FALSE; }
LPBYTE pBuf = GetBuffer(- ((int)sizeof(WORD)));
if (( pBuf[2] & SHID_FS ) != SHID_FS ) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Error, Unknown Pidl flag, use !db %8X\n", (DWORD_PTR) _pArg - wSize); Print( szBuffer ); return FALSE; } if ((( pBuf[2] & SHID_FS_UNICODE ) == SHID_FS_UNICODE ) && wSize > sizeof( IDFOLDER ) ) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Error, size to big for a UNICODE FileSys Pidl, use !db %8X\n", (DWORD_PTR) _pArg - wSize); Print( szBuffer ); return FALSE; } if ((( pBuf[2] & SHID_FS_UNICODE) != SHID_FS_UNICODE ) && wSize > sizeof( IDFOLDER )) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Error, size to big for a ANSI FileSys Pidl, use !db %8X\n", (DWORD_PTR) _pArg - wSize); Print( szBuffer ); return FALSE; }
if ( _fVerbose ) Print("FileSystem pidl:\n"); LPIDFOLDER pItem = (LPIDFOLDER) pBuf;
if ( _fVerbose ) { GetSHIDFlags( pItem->bFlags, szBuffer2, ARRAYSIZE( szBuffer2)); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " bFlags = %d (%s)\n", pItem->bFlags, szBuffer2 ); Print( szBuffer );
StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " dwSize = %d,\tattrs = 0x%X\n", pItem->dwSize, pItem->wAttrs ); Print( szBuffer );
_SprintDosDateTime(szBuffer, "modified", pItem->dateModified, pItem->timeModified); Print( szBuffer ); }
BOOL fPathShown = FALSE;
PIDFOLDEREX pidlx = (PIDFOLDEREX)ILFindHiddenIDOn((LPITEMIDLIST)pBuf, IDLHID_IDFOLDEREX, FALSE); if (pidlx && pidlx->hid.cb >= sizeof(IDFOLDEREX)) { LPBYTE pbMax = pBuf + wSize;
if (_fVerbose) { _SprintDosDateTime(szBuffer, "created", pidlx->dsCreate.wDate, pidlx->dsCreate.wTime); Print(szBuffer);
_SprintDosDateTime(szBuffer, "accessed", pidlx->dsAccess.wDate, pidlx->dsAccess.wTime); Print(szBuffer);
if (pidlx->offResourceA) { LPSTR pszResourceA = (LPSTR)pidlx + pidlx->offResourceA; if ((LPBYTE)pszResourceA < pbMax) { Print(" MUI = "); Print(pszResourceA); Print("\n"); } } }
// Do a "cheap" UnicodeToAnsi because
//
// 1. There's really no point in getting it right, since there
// is no guarantee that the debugger is running the same
// codepage as the app, and...
// 2. The string is unaligned so we have to walk it manually anyway.
//
if (pidlx->offNameW) { LPBYTE pbName = (LPBYTE)pidlx + pidlx->offNameW; int i = 0; while (pbName < pbMax && *pbName && i < ARRAYSIZE(szBuffer2) - 1) { szBuffer2[i++] = *pbName; pbName += 2; } szBuffer2[i] = TEXT('\0'); }
if (_fVerbose) { Print(" NameW = "); Print(szBuffer2); Print("\n"); } else { fPathShown = TRUE; if ( !_fSlash ) Print( "\\" );
Print( szBuffer2 ); }
}
if (( pItem->bFlags & SHID_FS_UNICODE ) == SHID_FS_UNICODE ) { WCHAR szTemp[MAX_PATH];
ua_lstrcpyW( szTemp, ARRAYSIZE(szTemp), (LPCWSTR)pItem->cFileName ); WideCharToMultiByte( CP_ACP, 0, szTemp, -1, szBuffer2, ARRAYSIZE( szBuffer2 ) * sizeof(CHAR), 0 ,0 );
if ( _fVerbose ) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " cFileName = %s\n", szBuffer2 ); Print( szBuffer ); } else if (!fPathShown) { fPathShown = TRUE; if ( !_fSlash ) Print( "\\" );
Print( szBuffer2 ); } } else { // assume to be ansi ...
if ( _fVerbose ) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " cFileName = %s\n", pItem->cFileName); Print( szBuffer ); } else if (!fPathShown) { fPathShown = TRUE; if ( !_fSlash ) Print( "\\" );
Print( pItem->cFileName ); }
if ( _fVerbose ) { int cLen = lstrlenA( pItem->cFileName); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " cAltName = %s\n", pItem->cFileName + cLen + 1); Print( szBuffer ); } }
if ( pItem->bFlags & SHID_JUNCTION ) { // it is a junction point, so the CLASSID is tagged on the end
/*[TODO]*/ }
_fSlash = FALSE; ResetBuffer(); PrintFileSysPidl(); return TRUE; }
BOOL CPidlBreaker::PrintPidl() { if ( _eType == PIDL_UNKNOWN ) { LPVOID pPrevArg = _pArg; // check the 3rd byte in, it might be a SHID value...
if ( !FillBuffer(3, FALSE )) { Print( "Unable to access the memory\n"); return FALSE; }
LPBYTE pBuf = GetBuffer();
_eType = CrackType( pBuf[2] );
ResetBuffer(); _pArg = pPrevArg; }
PrintType( _eType ); return TRUE; }
BOOL CPidlBreaker::PrintInternetPidl() { return TRUE; }
BOOL CPidlBreaker::PrintNetworkPidl() { return TRUE; }
BOOL CPidlBreaker::PrintDrivePidl() { CHAR szBuffer[200]; CHAR szBuffer2[200]; if ( !FillBuffer( sizeof( WORD ), FALSE )) { Print( "ERROR Unable to get the pidl size\n"); return FALSE; } // get the size of the first chunk
WORD wSize = FetchWord();
if ( wSize == 0 ) { return TRUE; } if ( !FillBuffer( wSize - sizeof(WORD) , TRUE )) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Error: unable to access the data for the pidl of size %d\n", wSize ); Print( szBuffer ); return FALSE; }
LPBYTE pBuf = GetBuffer(- ((int)sizeof(WORD))); // need to check to see if it is an IDDrive structure or a regitem ....
if ( wSize == sizeof( IDDRIVE ) || wSize == FIELD_OFFSET(IDDRIVE, clsid) ) { // must be a drive structure....
if ( _fVerbose ) Print( "(My Computer) Drives Pidl:\n"); else Print( "Path = ");
LPIDDRIVE pDriveItem = (LPIDDRIVE) pBuf;
if ( _fVerbose ) { GetSHIDFlags( pDriveItem->bFlags, szBuffer2, ARRAYSIZE( szBuffer2 )); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " bFlags = %d (%s)\n", pDriveItem->bFlags, szBuffer2 ); Print( szBuffer ); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " cName = %s\n", pDriveItem->cName ); Print( szBuffer ); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " qwSize = 0x%lX\tqwFree = 0x%lX\n", pDriveItem->qwSize, pDriveItem->qwFree ); Print( szBuffer ); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " wSig = 0x%X\n\n", pDriveItem->wSig); Print( szBuffer ); if ( wSize == sizeof( IDDRIVE ) ) { CHAR szCLSID[40]; CLSIDToString( szCLSID, ARRAYSIZE( szCLSID ), pDriveItem->clsid ); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " CLSID = %s ", szCLSID ); Print( szBuffer ); } } else Print( pDriveItem->cName );
// coming from a drive, we already have a slash at the start
_fSlash = TRUE; // assume the next pidl is a standard file-sys one...
PrintFileSysPidl(); } else if ( wSize == sizeof( IDREGITEM )) { // must be a reg item like control panel or printers...
Print( "Drives (My Computer) RegItem Pidl\n"); if ( pBuf[2] != SHID_COMPUTER_REGITEM ) { Print( "Pidl has incorrect flags, should have SHID_ROOT_REGITEM\n"); } // now map it to a Root structure
LPIDREGITEM pRegItem = (LPIDREGITEM) pBuf;
GetSHIDFlags( pRegItem->bFlags, szBuffer2, ARRAYSIZE( szBuffer2 )); Print( "RegItem Pidl:\n");
if ( _fVerbose ) { StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " bFlags = %d (%s)\n", pRegItem->bFlags, szBuffer2 ); Print( szBuffer ); StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " bOrder = %d\n", pRegItem->bOrder ); Print( szBuffer ); } CHAR szCLSID[40]; CLSIDToString( szCLSID, ARRAYSIZE( szCLSID ), pRegItem->clsid );
StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), " CLSID = %s ", szCLSID ); Print( szBuffer );
if ( GetCLSIDText( szCLSID, szBuffer2 + 1, ARRAYSIZE( szBuffer2 ) -2)) { szBuffer2[0] = '('; StringCchCatA( szBuffer2, ARRAYSIZE(szBuffer2), ")\n" ); Print( szBuffer2 ); }
ResetBuffer();
LPVOID _pPrevArg = _pArg; if ( !FillBuffer( sizeof( WORD ), FALSE )) { Print( "Error unable to access next pidl section\n"); } if ( FetchWord() != 0 ) { // unknown hierarchy pidl type
StringCchPrintfA( szBuffer, ARRAYSIZE(szBuffer), "Unknown Pidl Type contents, use !db %8X\n", (DWORD_PTR) _pPrevArg ); }
_pArg = _pPrevArg; } else { Print( "Unknown Drives pidl type\n"); return FALSE; }
return TRUE; }
PIDLTYPE CPidlBreaker::CrackType( BYTE bType ) { PIDLTYPE eType = PIDL_UNKNOWN; switch( bType & 0xf0 ) { case SHID_ROOT: eType = PIDL_ROOT; break; case SHID_COMPUTER: eType = PIDL_DRIVES; break; case SHID_FS: eType = PIDL_FILESYS; break; case SHID_NET: eType = PIDL_NET; break; case 0x60: // SHID_INTERNET
eType = PIDL_INTERNET; break; } return eType; }
void CPidlBreaker::PrintType( PIDLTYPE eType ) { switch( eType ) { case PIDL_ROOT: PrintRootPidl(); break;
case PIDL_FILESYS: PrintFileSysPidl(); break;
case PIDL_DRIVES: PrintDrivePidl(); break; case PIDL_NET: case PIDL_INTERNET: default: Print( "Unknown Pidl Type\n"); break; } }
typedef struct _tagSHIDs { BYTE bFlag; LPCSTR pszText; } SHIDFLAGS;
SHIDFLAGS g_argSHID[] = { {SHID_ROOT, "SHID_ROOT" }, {SHID_ROOT_REGITEM, "SHID_ROOT_REGITEM"}, {SHID_COMPUTER, "SHID_COMPUTER"}, {SHID_COMPUTER_1, "SHID_COMPUTER_1"}, {SHID_COMPUTER_REMOVABLE, "SHID_COMPUTER_REMOVABLE"}, {SHID_COMPUTER_FIXED, "SHID_COMPUTER_FIXED"}, {SHID_COMPUTER_REMOTE, "SHID_COMPUTER_REMOTE"}, {SHID_COMPUTER_CDROM, "SHID_COMPUTER_CDROM"}, {SHID_COMPUTER_RAMDISK, "SHID_COMPUTER_RAMDISK"}, {SHID_COMPUTER_7, "SHID_COMPUTER_7"}, {SHID_COMPUTER_DRIVE525, "SHID_COMPUTER_DRIVE525"}, {SHID_COMPUTER_DRIVE35, "SHID_COMPUTER_DRIVE35"}, {SHID_COMPUTER_NETDRIVE, "SHID_COMPUTER_NETDRIVE"}, {SHID_COMPUTER_NETUNAVAIL, "SHID_COMPUTER_NETUNAVAIL"}, {SHID_COMPUTER_C, "SHID_COMPUTER_C"}, {SHID_COMPUTER_D, "SHID_COMPUTER_D"}, {SHID_COMPUTER_REGITEM, "SHID_COMPUTER_REGITEM"}, {SHID_COMPUTER_MISC, "SHID_COMPUTER_MISC"}, {SHID_FS, "SHID_FS"}, {SHID_FS_TYPEMASK, "SHID_FS_TYPEMASK"}, {SHID_FS_DIRECTORY, "SHID_FS_DIRECTORY"}, {SHID_FS_FILE, "SHID_FS_FILE"}, {SHID_FS_UNICODE, "SHID_FS_UNICODE"}, {SHID_FS_DIRUNICODE, "SHID_FS_DIRUNICODE"}, {SHID_FS_FILEUNICODE, "SHID_FS_FILEUNICODE"}, {SHID_NET, "SHID_NET"}, {SHID_NET_DOMAIN, "SHID_NET_DOMAIN"}, {SHID_NET_SERVER, "SHID_NET_SERVER"}, {SHID_NET_SHARE, "SHID_NET_SHARE"}, {SHID_NET_FILE, "SHID_NET_FILE"}, {SHID_NET_GROUP, "SHID_NET_GROUP"}, {SHID_NET_NETWORK, "SHID_NET_NETWORK"}, {SHID_NET_RESTOFNET, "SHID_NET_RESTOFNET"}, {SHID_NET_SHAREADMIN, "SHID_NET_SHAREADMIN"}, {SHID_NET_DIRECTORY, "SHID_NET_DIRECTORY"}, {SHID_NET_TREE, "SHID_NET_TREE"}, {SHID_NET_REGITEM, "SHID_NET_REGITEM"}, {SHID_NET_PRINTER, "SHID_NET_PRINTER"} };
BOOL CPidlBreaker::GetSHIDFlags( BYTE bFlags, CHAR * pszBuffer, DWORD cchSize ) { LPCSTR pszText = NULL; for ( int iFlag = 0; iFlag < ARRAYSIZE( g_argSHID ); iFlag ++ ) { if ( g_argSHID[iFlag].bFlag == ( bFlags & SHID_TYPEMASK )) { pszText = g_argSHID[iFlag].pszText; break; } }
if ( pszText == NULL ) { StringCchPrintfA( pszBuffer, cchSize, "unknown SHID value %2X", bFlags ); return FALSE; } else { StringCchCopyA( pszBuffer, cchSize, pszText ); } if (bFlags & SHID_JUNCTION) { StringCchCatA(pszBuffer, cchSize, " | SHID_JUNCTION"); } return TRUE; }
void CPidlBreaker::CLSIDToString( CHAR * pszBuffer, DWORD cchSize, REFCLSID rclsid ) { WCHAR szBuffer[40];
StringFromGUID2( rclsid, szBuffer, ARRAYSIZE( szBuffer )); WideCharToMultiByte( CP_ACP, 0, szBuffer, -1, pszBuffer, cchSize, 0, 0 ); }
//
// Some CLSIDs have "known" names which are used if there is no custom name
// in the registry.
//
typedef struct KNOWNCLSIDS { LPCSTR pszCLSID; LPCSTR pszName; } KNOWNCLSIDS;
const KNOWNCLSIDS c_kcKnown[] = { { "{20D04FE0-3AEA-1069-A2D8-08002B30309D}", "My Computer" }, { "{21EC2020-3AEA-1069-A2DD-08002B30309D}", "Control Panel" }, { "{645FF040-5081-101B-9F08-00AA002F954E}", "Recycle Bin" }, { "{450D8FBA-AD25-11D0-98A8-0800361B1103}", "My Documents" }, { "{871C5380-42A0-1069-A2EA-08002B30309D}", "The Internet" }, };
BOOL CPidlBreaker::GetCLSIDText( const CHAR * pszCLSID, CHAR * pszBuffer, DWORD cbSize ) { int i; for (i = 0; i < ARRAYSIZE(c_kcKnown); i++) { if (lstrcmpiA(c_kcKnown[i].pszCLSID, pszCLSID) == 0) { StringCbCopyA(pszBuffer, cbSize, c_kcKnown[i].pszName); return TRUE; } }
HKEY hKey; LONG lRes = RegOpenKeyExA( HKEY_CLASSES_ROOT, "CLSID", 0, KEY_READ, &hKey ); if ( ERROR_SUCCESS == lRes ) { LONG lSize = cbSize; lRes = RegQueryValueA( hKey, pszCLSID, pszBuffer, &lSize ); RegCloseKey(hKey); return ( ERROR_SUCCESS == lRes ); } return FALSE; }
|