263 lines
8.4 KiB
C++
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);
|
|
}
|