icon.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 9k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "pch.h"
  2. #pragma hdrstop
  3. /*-----------------------------------------------------------------------------
  4. / Misc data
  5. /----------------------------------------------------------------------------*/
  6. //
  7. // mapping of class to resource ID's
  8. //
  9. typedef struct
  10. {
  11.     LPCWSTR pObjectClass;
  12.     INT iResource;
  13. } CLASSTORESOURCE, * LPCLASSTORESOURCE;
  14. CLASSTORESOURCE normalIcons[] =
  15. {
  16.     L"builtInDomain",               IDI_BUILTINDOMAIN,
  17.     L"computer",                    IDI_COMPUTER,
  18.     L"configuration",               IDI_CONFIGURATION,
  19.     L"rpcContainer",                IDI_CONFIGURATION,
  20.     L"contact",                     IDI_CONTACT,
  21.     L"container",                   IDI_CONTAINER,
  22.     L"domainDNS",                   IDI_DOMAINDNS,
  23.     L"domainPolicy",                IDI_DOMAINPOLICY,
  24.     L"group",                       IDI_GROUP,
  25.     L"localGroup",                  IDI_GROUP,
  26.     L"localPolicy",                 IDI_LOCALPOLICY,
  27.     L"nTDSConnection",              IDI_NTDSCONNECTION,
  28.     L"nTDSDSA",                     IDI_NTDSDSA,
  29.     L"nTDSSettings",                IDI_NTDSSETTINGS,
  30.     L"organizationalPerson",        IDI_ORGANIZATIONALPERSON,
  31.     L"organizationalUnit",          IDI_ORGANIZATIONALUNIT,
  32.     L"person",                      IDI_PERSON,
  33.     L"printQueue",                  IDI_PRINTQUEUE,
  34.     L"remoteMailRecipient",         IDI_REMOTEMAILRECIPIENT,
  35.     L"server",                      IDI_SERVER,
  36.     L"serverConnection",            IDI_SERVERCONNECTION,
  37.     L"site",                        IDI_SITE,
  38.     L"sitesContainer",              IDI_SITESCONTAINER,
  39.     L"storage",                     IDI_STORAGE,
  40.     L"subnet",                      IDI_SUBNET,
  41.     L"subnetContainer",             IDI_CONTAINER,
  42.     L"user",                        IDI_USER,
  43.     L"volume",                      IDI_VOLUME,
  44.     L"workStationAccount",          IDI_WORKSTATIONACCOUNT,
  45. // added daviddv (05jun98) for jonn
  46.     L"licensingSiteSettings",       IDI_LICENSING,
  47.     L"nTDSSiteSettings",            IDI_NTDSSITESETTINGS,
  48.     L"siteLink",                    IDI_SITELINK,
  49.     L"siteLinkBridge",              IDI_SITELINK,
  50. // added daviddv (19jun98) for jonn
  51.     L"nTFRSSettings",               IDI_NTFRS,    
  52.     L"nTFRSReplicaSet",             IDI_NTFRS,
  53.     L"nTFRSSubscriptions",          IDI_NTFRS,
  54.     L"nTFRSSubscriber",             IDI_NTFRS,
  55.     L"nTFRSMember",                 IDI_NTFRS,
  56. // added daviddv (23jun98) for ericb
  57.     L"foreignSecurityPrincipal",    IDI_USER,
  58. // added daviddv (29oct98) for jonn
  59.     L"interSiteTransport",          IDI_CONTAINER,
  60.     L"interSiteTransportContainer", IDI_CONTAINER, 
  61.     L"serversContainer",            IDI_CONTAINER,
  62.     NULL, NULL,
  63. };
  64. CLASSTORESOURCE openIcons[] =
  65. {
  66.     L"container",                   IDI_CONTAINER_OPEN,
  67.     L"subnetContainer",             IDI_CONTAINER_OPEN,
  68.     L"interSiteTransport",          IDI_CONTAINER_OPEN,
  69.     L"interSiteTransportContainer", IDI_CONTAINER_OPEN, 
  70.     L"serversContainer",            IDI_CONTAINER_OPEN,
  71.     NULL, NULL,
  72. };
  73. CLASSTORESOURCE disabledIcons[] =
  74. {
  75.     L"user",                        IDI_USER_DISABLED,
  76.     L"computer",                    IDI_COMPUTER_DISABLED,
  77.     NULL, NULL,
  78. };
  79. //
  80. // mapping of states to icon tables
  81. //
  82. LPCLASSTORESOURCE state_to_icons[] =
  83. {
  84.     normalIcons,            // DSGIF_ISNORMAL
  85.     openIcons,              // DSGIF_ISOPEN
  86.     disabledIcons,          // DSGIF_ISDISABLED
  87. };
  88. //
  89. // Look up a locally stored icon given its class and state.
  90. //
  91. BOOL _GetIconForState(LPWSTR pObjectClass, INT iState, INT* pindex)
  92. {
  93.     BOOL fFound = FALSE;
  94.     INT i;
  95.     USES_CONVERSION;
  96.     TraceEnter(TRACE_ICON, "_GetIconForState");
  97.     Trace(TEXT("Find icon for class: %s, state: %d"), W2T(pObjectClass), iState);
  98.     if ( iState < ARRAYSIZE(state_to_icons) )
  99.     {
  100.         LPCLASSTORESOURCE pTable = state_to_icons[iState];
  101.         
  102.         for ( i = 0 ; !fFound && pTable[i].pObjectClass ; i++ )
  103.         {
  104.             if ( !StrCmpIW(pTable[i].pObjectClass, pObjectClass) )
  105.             {
  106.                 Trace(TEXT("Found icon at index %d"), i);
  107.                 *pindex = -pTable[i].iResource;
  108.                 fFound = TRUE;
  109.             }
  110.         }        
  111.     }        
  112.     TraceLeaveValue(fFound);
  113. }
  114. #if DOWNLEVEL_SHELL
  115. //
  116. // Win9x user doesn't support PrivateExtractIcons, therefore we use shell32's ExtractIconEx
  117. // with suitable parameter munging.
  118. //
  119. UINT _MyExtractIcons(LPCWSTR szFileName, int nIconIndex, int cxIcon, int cyIcon, 
  120.                                             HICON *phicon, UINT *piconid, UINT nIcons, UINT flags)
  121. {  
  122.     UINT ures = 0;   
  123.     HICON *phLargeIcon = (GetSystemMetrics(SM_CXICON) == cxIcon) ? phicon:NULL;
  124.     HICON *phSmallIcon = (GetSystemMetrics(SM_CXICON) != cxIcon) ? phicon:NULL;
  125.     USES_CONVERSION;
  126.     TraceEnter(TRACE_ICON, "_MyExtractIcons");
  127.     ures = ExtractIconEx(W2CT(szFileName), nIconIndex, phLargeIcon, phSmallIcon, 1);
  128.     Trace(TEXT("ures is %d from ExtractIcons"), ures);
  129.     TraceLeaveValue(ures);
  130. }
  131. #endif
  132. /*-----------------------------------------------------------------------------
  133. / _GetIconLocation
  134. / ----------------
  135. /   Given a cache record for the icon, attempt to fetch the icon location from
  136. /    it.
  137. /
  138. / In:
  139. /   pCacheEntry -> locked cacherecord
  140. /   dwFlags = flags indicating which icon is required
  141. /   pBuffer -> buffer that receives the name
  142. /   cchBuffer = maximum size of the name buffer
  143. /   piIndex = receives the resource ID of the loaded resource
  144. /
  145. / Out:
  146. /   HRESULT
  147. /----------------------------------------------------------------------------*/
  148. HRESULT _GetModuleLocation(LPWSTR pBuffer, INT cchBuffer)
  149. {
  150.     HRESULT hr = S_OK;
  151.     TraceEnter(TRACE_ICON,"_GetModuleLocation");
  152. #if UNICODE
  153.     if ( !GetModuleFileName(GLOBAL_HINSTANCE, pBuffer, cchBuffer) )
  154.         ExitGracefully(hr, E_FAIL, "Failed to get module location");
  155. #else
  156.     TCHAR szBuffer[MAX_PATH];
  157.     if ( !GetModuleFileName(GLOBAL_HINSTANCE, szBuffer, ARRAYSIZE(szBuffer)) )
  158.         ExitGracefully(hr, E_FAIL, "Failed to get module location");
  159.     MultiByteToWideChar(CP_ACP, 0, szBuffer, -1, pBuffer, cchBuffer);
  160. #endif        
  161. exit_gracefully:
  162.     TraceLeaveResult(hr);
  163. }
  164. HRESULT _GetIconLocation(LPCLASSCACHEENTRY pCacheEntry, DWORD dwFlags, LPWSTR pBuffer, INT cchBuffer, INT* piIndex)
  165. {
  166.     HRESULT hr;
  167.     INT iState = dwFlags & DSGIF_ISMASK;
  168.     USES_CONVERSION;
  169.     TraceEnter(TRACE_ICON, "_GetIconLocation");
  170.     if ( !pBuffer || !piIndex || (iState >= ARRAYSIZE(pCacheEntry->pIconName)) )
  171.         ExitGracefully(hr, E_INVALIDARG, "No class, buffer or index pointer specified")
  172.     // before we get too involved in looking at the cache records lets see if we have
  173.     // one already, if not then bail out now.
  174.     if ( !pCacheEntry )
  175.         ExitGracefully(hr, S_FALSE, "No cache record, returning S_FALSE");
  176.     // look up the class in the cache, if that works try and get the icon string
  177.     // for the given index, if that yeilds a NULL then try normal.  Once we
  178.     // have a string pointer then lets copy that and parse out the resource ID.
  179.     if ( (pCacheEntry->dwCached & CLASSCACHE_ICONS) &&
  180.            (pCacheEntry->pIconName[iState] || pCacheEntry->pIconName[DSGIF_ISNORMAL]) )
  181.     {
  182.         TraceMsg("Reading icon name from the display specifier strings");
  183.         if ( !pCacheEntry->pIconName[iState] )
  184.             iState = DSGIF_ISNORMAL;
  185.         StrCpyNW(pBuffer, pCacheEntry->pIconName[iState], cchBuffer);
  186.         *piIndex = PathParseIconLocationW(pBuffer);
  187.     }
  188.     else
  189.     {
  190.         TraceMsg("Attempting to find icon in our fixed resource table");
  191.         if ( _GetIconForState(pCacheEntry->pObjectClass, iState, piIndex) ||
  192.                 _GetIconForState(pCacheEntry->pObjectClass, DSGIF_ISNORMAL, piIndex) )
  193.         {
  194.             hr = _GetModuleLocation(pBuffer, cchBuffer);
  195.             FailGracefully(hr, "Failed to get the module location for dsuiext");
  196.         }
  197.         else
  198.         {
  199.             ExitGracefully(hr, S_FALSE, "Failed to find icon bound resources");
  200.         }
  201.     }
  202.     Trace(TEXT("Location: %s, Index: %d"), W2T(pBuffer), *piIndex);
  203.     hr = S_OK;
  204. exit_gracefully:
  205.     //
  206.     // if we failed to look up the icon location, and the caller requested the 
  207.     // default document icon then lets return the shell def document image
  208.     //
  209.     if ( (hr == S_FALSE) )      
  210.     {
  211.         if ( dwFlags & DSGIF_DEFAULTISCONTAINER )
  212.         {
  213.             hr = E_FAIL;
  214.             if ( _GetIconForState(L"container", iState, piIndex) ||
  215.                     _GetIconForState(L"container", DSGIF_ISNORMAL, piIndex) )
  216.             {
  217.                 hr = _GetModuleLocation(pBuffer, cchBuffer);
  218.             }
  219.             else if ( dwFlags & DSGIF_GETDEFAULTICON )
  220.             {
  221.                 StrCpyNW(pBuffer, L"shell32.dll", cchBuffer);
  222.                 *piIndex = -1;
  223.             }
  224.             if ( FAILED(hr) )
  225.             {
  226.                 dwFlags &= ~DSGIF_DEFAULTISCONTAINER;
  227.                 ExitGracefully(hr, S_FALSE, "Failed to look up icon as container");
  228.             }
  229.         }
  230.         hr = S_OK;                  // its OK, we have a location now.
  231.     }
  232.     TraceLeaveResult(hr);
  233. }