windows-nt/Source/XPSP1/NT/shell/ext/dsui/dsuiext/icon.cpp
2020-09-26 16:20:57 +08:00

263 lines
8.4 KiB
C++

#include "pch.h"
#pragma hdrstop
/*-----------------------------------------------------------------------------
/ Misc data
/----------------------------------------------------------------------------*/
//
// mapping of class to resource ID's
//
typedef struct
{
LPCWSTR pObjectClass;
INT iResource;
} CLASSTORESOURCE, * LPCLASSTORESOURCE;
CLASSTORESOURCE normalIcons[] =
{
L"builtInDomain", IDI_BUILTINDOMAIN,
L"computer", IDI_COMPUTER,
L"configuration", IDI_CONFIGURATION,
L"rpcContainer", IDI_CONFIGURATION,
L"contact", IDI_CONTACT,
L"container", IDI_CONTAINER,
L"domainDNS", IDI_DOMAINDNS,
L"domainPolicy", IDI_DOMAINPOLICY,
L"group", IDI_GROUP,
L"localGroup", IDI_GROUP,
L"localPolicy", IDI_LOCALPOLICY,
L"nTDSConnection", IDI_NTDSCONNECTION,
L"nTDSDSA", IDI_NTDSDSA,
L"nTDSSettings", IDI_NTDSSETTINGS,
L"organizationalPerson", IDI_ORGANIZATIONALPERSON,
L"organizationalUnit", IDI_ORGANIZATIONALUNIT,
L"person", IDI_PERSON,
L"printQueue", IDI_PRINTQUEUE,
L"remoteMailRecipient", IDI_REMOTEMAILRECIPIENT,
L"server", IDI_SERVER,
L"serverConnection", IDI_SERVERCONNECTION,
L"site", IDI_SITE,
L"sitesContainer", IDI_SITESCONTAINER,
L"storage", IDI_STORAGE,
L"subnet", IDI_SUBNET,
L"subnetContainer", IDI_CONTAINER,
L"user", IDI_USER,
L"volume", IDI_VOLUME,
L"workStationAccount", IDI_WORKSTATIONACCOUNT,
// added daviddv (05jun98) for jonn
L"licensingSiteSettings", IDI_LICENSING,
L"nTDSSiteSettings", IDI_NTDSSITESETTINGS,
L"siteLink", IDI_SITELINK,
L"siteLinkBridge", IDI_SITELINK,
// added daviddv (19jun98) for jonn
L"nTFRSSettings", IDI_NTFRS,
L"nTFRSReplicaSet", IDI_NTFRS,
L"nTFRSSubscriptions", IDI_NTFRS,
L"nTFRSSubscriber", IDI_NTFRS,
L"nTFRSMember", IDI_NTFRS,
// added daviddv (23jun98) for ericb
L"foreignSecurityPrincipal", IDI_FPO,
// added daviddv (29oct98) for jonn
L"interSiteTransport", IDI_CONTAINER,
L"interSiteTransportContainer", IDI_CONTAINER,
L"serversContainer", IDI_CONTAINER,
// added jeffjon (30nov2000) for jccannon
L"inetOrgPerson", IDI_USER,
NULL, NULL,
};
CLASSTORESOURCE openIcons[] =
{
L"container", IDI_CONTAINER_OPEN,
L"subnetContainer", IDI_CONTAINER_OPEN,
L"interSiteTransport", IDI_CONTAINER_OPEN,
L"interSiteTransportContainer", IDI_CONTAINER_OPEN,
L"serversContainer", IDI_CONTAINER_OPEN,
NULL, NULL,
};
CLASSTORESOURCE disabledIcons[] =
{
L"user", IDI_USER_DISABLED,
L"computer", IDI_COMPUTER_DISABLED,
// added jeffjon (15dec2000) for jccannon
L"inetOrgPerson", IDI_USER_DISABLED,
NULL, NULL,
};
//
// mapping of states to icon tables
//
LPCLASSTORESOURCE state_to_icons[] =
{
normalIcons, // DSGIF_ISNORMAL
openIcons, // DSGIF_ISOPEN
disabledIcons, // DSGIF_ISDISABLED
};
//
// Look up a locally stored icon given its class and state.
//
BOOL _GetIconForState(LPWSTR pObjectClass, INT iState, INT* pindex)
{
BOOL fFound = FALSE;
INT i;
USES_CONVERSION;
TraceEnter(TRACE_ICON, "_GetIconForState");
Trace(TEXT("Find icon for class: %s, state: %d"), W2T(pObjectClass), iState);
if ( iState < ARRAYSIZE(state_to_icons) )
{
LPCLASSTORESOURCE pTable = state_to_icons[iState];
for ( i = 0 ; !fFound && pTable[i].pObjectClass ; i++ )
{
if ( !StrCmpIW(pTable[i].pObjectClass, pObjectClass) )
{
Trace(TEXT("Found icon at index %d"), i);
*pindex = -pTable[i].iResource;
fFound = TRUE;
}
}
}
TraceLeaveValue(fFound);
}
/*-----------------------------------------------------------------------------
/ _GetIconLocation
/ ----------------
/ Given a cache record for the icon, attempt to fetch the icon location from
/ it.
/
/ In:
/ pCacheEntry -> locked cacherecord
/ dwFlags = flags indicating which icon is required
/ pBuffer -> buffer that receives the name
/ cchBuffer = maximum size of the name buffer
/ piIndex = receives the resource ID of the loaded resource
/
/ Out:
/ HRESULT
/----------------------------------------------------------------------------*/
HRESULT _GetModuleLocation(LPWSTR pBuffer, INT cchBuffer)
{
HRESULT hr = S_OK;
TraceEnter(TRACE_ICON,"_GetModuleLocation");
#if UNICODE
if ( !GetModuleFileName(GLOBAL_HINSTANCE, pBuffer, cchBuffer) )
ExitGracefully(hr, E_FAIL, "Failed to get module location");
#else
TCHAR szBuffer[MAX_PATH];
if ( !GetModuleFileName(GLOBAL_HINSTANCE, szBuffer, ARRAYSIZE(szBuffer)) )
ExitGracefully(hr, E_FAIL, "Failed to get module location");
MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, pBuffer, cchBuffer);
#endif
exit_gracefully:
TraceLeaveResult(hr);
}
HRESULT _GetIconLocation(LPCLASSCACHEENTRY pCacheEntry, DWORD dwFlags, LPWSTR pBuffer, INT cchBuffer, INT* piIndex)
{
HRESULT hr;
INT iState = dwFlags & DSGIF_ISMASK;
USES_CONVERSION;
TraceEnter(TRACE_ICON, "_GetIconLocation");
if ( !pBuffer || !piIndex || (iState >= ARRAYSIZE(pCacheEntry->pIconName)) )
ExitGracefully(hr, E_INVALIDARG, "No class, buffer or index pointer specified")
// before we get too involved in looking at the cache records lets see if we have
// one already, if not then bail out now.
if ( !pCacheEntry )
ExitGracefully(hr, S_FALSE, "No cache record, returning S_FALSE");
// look up the class in the cache, if that works try and get the icon string
// for the given index, if that yeilds a NULL then try normal. Once we
// have a string pointer then lets copy that and parse out the resource ID.
if ( (pCacheEntry->dwCached & CLASSCACHE_ICONS) &&
(pCacheEntry->pIconName[iState] || pCacheEntry->pIconName[DSGIF_ISNORMAL]) )
{
TraceMsg("Reading icon name from the display specifier strings");
if ( !pCacheEntry->pIconName[iState] )
iState = DSGIF_ISNORMAL;
StrCpyNW(pBuffer, pCacheEntry->pIconName[iState], cchBuffer);
*piIndex = PathParseIconLocationW(pBuffer);
}
else
{
TraceMsg("Attempting to find icon in our fixed resource table");
if ( _GetIconForState(pCacheEntry->pObjectClass, iState, piIndex) ||
_GetIconForState(pCacheEntry->pObjectClass, DSGIF_ISNORMAL, piIndex) )
{
hr = _GetModuleLocation(pBuffer, cchBuffer);
FailGracefully(hr, "Failed to get the module location for dsuiext");
}
else
{
ExitGracefully(hr, S_FALSE, "Failed to find icon bound resources");
}
}
Trace(TEXT("Location: %s, Index: %d"), W2T(pBuffer), *piIndex);
hr = S_OK;
exit_gracefully:
//
// if we failed to look up the icon location, and the caller requested the
// default document icon then lets return the shell def document image
//
if ( (hr == S_FALSE) )
{
if ( dwFlags & DSGIF_DEFAULTISCONTAINER )
{
hr = E_FAIL;
if ( _GetIconForState(L"container", iState, piIndex) ||
_GetIconForState(L"container", DSGIF_ISNORMAL, piIndex) )
{
hr = _GetModuleLocation(pBuffer, cchBuffer);
}
else if ( dwFlags & DSGIF_GETDEFAULTICON )
{
StrCpyNW(pBuffer, L"shell32.dll", cchBuffer);
*piIndex = -1;
}
if ( FAILED(hr) )
{
dwFlags &= ~DSGIF_DEFAULTISCONTAINER;
ExitGracefully(hr, S_FALSE, "Failed to look up icon as container");
}
}
hr = S_OK; // its OK, we have a location now.
}
TraceLeaveResult(hr);
}