* got rid of SHGetFileInfo usage - vastly improves startup time and memory usage

* cache PhGetSystemDirectory() string

git-svn-id: svn://svn.code.sf.net/p/processhacker/code@3716 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
wj32
2010-10-02 11:27:47 +00:00
parent f165e2824d
commit f9b1ecc972
8 changed files with 161 additions and 86 deletions
+1
View File
@@ -2,6 +2,7 @@ Process Hacker
2.7
* NEW/IMPROVED:
* Vastly improved startup time, and lower memory usage
* FIXED:
* ToolStatus layout problems
+1 -3
View File
@@ -12,7 +12,7 @@
#include <circbuf.h>
#include <phnet.h>
#include <providers.h>
#include "resource.h"
#include "../resource.h"
#define KPH_ERROR_MESSAGE (L"KProcessHacker does not support your operating system " \
L"or could not be loaded. Make sure Process Hacker is running " \
@@ -267,8 +267,6 @@ VOID PhUpdateProcessNode(
VOID PhTickProcessNodes();
HICON PhGetStockAppIcon();
PHAPPAPI
PPH_PROCESS_ITEM PhGetSelectedProcessItem();
+19 -22
View File
@@ -33,10 +33,6 @@
#include <iphlpapi.h>
#include <wtsapi32.h>
typedef BOOL (WINAPI *_FileIconInit)(
__in BOOL RestoreCache
);
typedef HRESULT (WINAPI *_LoadIconMetric)(
__in HINSTANCE hinst,
__in PCWSTR pszName,
@@ -272,22 +268,6 @@ BOOLEAN PhMainWndInitialization(
{
PH_RECTANGLE windowRectangle;
// Initialize the system image lists.
{
HMODULE shell32;
_FileIconInit fileIconInit;
shell32 = LoadLibrary(L"shell32.dll");
if (shell32)
{
fileIconInit = (_FileIconInit)GetProcAddress(shell32, (PSTR)660);
if (fileIconInit)
fileIconInit(FALSE);
}
}
if (PhGetIntegerSetting(L"FirstRun"))
{
PPH_STRING autoDbghelpPath;
@@ -2495,9 +2475,23 @@ VOID PhpAddIconProcesses(
// Menu icons only work properly on Vista and above.
if (WindowsVersion >= WINDOWS_VISTA)
iconBitmap = PhIconToBitmap(processItem->SmallIcon ? processItem->SmallIcon : PhGetStockAppIcon(), 16, 16);
{
if (processItem->SmallIcon)
{
iconBitmap = PhIconToBitmap(processItem->SmallIcon, 16, 16);
}
else
{
HICON icon;
PhGetStockApplicationIcon(&icon, NULL);
iconBitmap = PhIconToBitmap(icon, 16, 16);
}
}
else
{
iconBitmap = NULL;
}
subMenu->Bitmap = iconBitmap;
Bitmaps[i] = iconBitmap;
@@ -4321,8 +4315,11 @@ VOID PhMainWndOnNetworkItemAdded(
if (!NetworkImageListWrapper.Handle)
{
HICON icon;
PhGetStockApplicationIcon(&icon, NULL);
PhInitializeImageListWrapper(&NetworkImageListWrapper, 16, 16, ILC_COLOR32 | ILC_MASK);
PhImageListWrapperAddIcon(&NetworkImageListWrapper, PhGetStockAppIcon());
PhImageListWrapperAddIcon(&NetworkImageListWrapper, icon);
ListView_SetImageList(NetworkListViewHandle, NetworkImageListWrapper.Handle, LVSIL_SMALL);
}
+23 -41
View File
@@ -582,26 +582,16 @@ VOID PhpProcessQueryStage1(
if (processItem->FileName)
{
// Small icon, large icon.
if (ExtractIconEx(
processItem->FileName->Buffer,
0,
&Data->LargeIcon,
&Data->SmallIcon,
1
) == 0)
{
SHFILEINFO fileInfo;
if (SHGetFileInfo(
processItem->FileName->Buffer,
0,
&fileInfo,
sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_SMALLICON
))
Data->SmallIcon = fileInfo.hIcon;
if (SHGetFileInfo(
processItem->FileName->Buffer,
0,
&fileInfo,
sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_LARGEICON
))
Data->LargeIcon = fileInfo.hIcon;
Data->LargeIcon = NULL;
Data->SmallIcon = NULL;
}
// Version info.
@@ -610,30 +600,22 @@ VOID PhpProcessQueryStage1(
// Use the default EXE icon if we didn't get the file's icon.
{
SHFILEINFO fileInfo;
if (!Data->SmallIcon)
if (!Data->SmallIcon || !Data->LargeIcon)
{
if (SHGetFileInfo(
L".exe",
FILE_ATTRIBUTE_NORMAL,
&fileInfo,
sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_SMALLICON | SHGFI_USEFILEATTRIBUTES
))
Data->SmallIcon = fileInfo.hIcon;
}
if (Data->SmallIcon)
{
DestroyIcon(Data->SmallIcon);
Data->SmallIcon = NULL;
}
else if (Data->LargeIcon)
{
DestroyIcon(Data->LargeIcon);
Data->LargeIcon = NULL;
}
if (!Data->LargeIcon)
{
if (SHGetFileInfo(
L".exe",
FILE_ATTRIBUTE_NORMAL,
&fileInfo,
sizeof(SHFILEINFO),
SHGFI_ICON | SHGFI_LARGEICON | SHGFI_USEFILEATTRIBUTES
))
Data->LargeIcon = fileInfo.hIcon;
PhGetStockApplicationIcon(&Data->SmallIcon, &Data->LargeIcon);
Data->SmallIcon = DuplicateIcon(NULL, Data->SmallIcon);
Data->LargeIcon = DuplicateIcon(NULL, Data->LargeIcon);
}
}
+1 -20
View File
@@ -463,25 +463,6 @@ VOID PhTickProcessNodes()
}
}
HICON PhGetStockAppIcon()
{
if (!StockAppIcon)
{
SHFILEINFO fileInfo = { 0 };
SHGetFileInfo(
L".exe",
FILE_ATTRIBUTE_NORMAL,
&fileInfo,
sizeof(SHFILEINFO),
SHGFI_USEFILEATTRIBUTES | SHGFI_ICON | SHGFI_SMALLICON
);
StockAppIcon = fileInfo.hIcon;
}
return StockAppIcon;
}
VOID PhpUpdateProcessNodeWsCounters(
__inout PPH_PROCESS_NODE ProcessNode
)
@@ -1480,7 +1461,7 @@ BOOLEAN NTAPI PhpProcessTreeListCallback(
}
else
{
getNodeIcon->Icon = PhGetStockAppIcon();
PhGetStockApplicationIcon(&getNodeIcon->Icon, NULL);
}
getNodeIcon->Flags = TLC_CACHE;
+87
View File
@@ -774,6 +774,65 @@ VOID PhImageListWrapperRemove(
PhAddItemList(Wrapper->FreeList, (PVOID)Index);
}
VOID PhGetStockApplicationIcon(
__out_opt HICON *SmallIcon,
__out_opt HICON *LargeIcon
)
{
static PH_INITONCE initOnce = PH_INITONCE_INIT;
static HICON smallIcon = NULL;
static HICON largeIcon = NULL;
// This no longer uses SHGetFileInfo because it is *very* slow and causes
// many other DLLs to be loaded, increasing memory usage.
if (PhBeginInitOnce(&initOnce))
{
PPH_STRING systemDirectory;
PPH_STRING dllFileName;
// user32,0 (Vista and above) or shell32,2 (XP) contains the default application icon.
if (systemDirectory = PhGetSystemDirectory())
{
PH_STRINGREF dllBaseName;
ULONG index;
// TODO: Find a better solution.
if (WindowsVersion >= WINDOWS_VISTA)
{
PhInitializeStringRef(&dllBaseName, L"\\user32.dll");
index = 0;
}
else
{
PhInitializeStringRef(&dllBaseName, L"\\shell32.dll");
index = 2;
}
dllFileName = PhConcatStringRef2(&systemDirectory->sr, &dllBaseName);
PhDereferenceObject(systemDirectory);
ExtractIconEx(dllFileName->Buffer, index, &largeIcon, &smallIcon, 1);
PhDereferenceObject(dllFileName);
}
// Fallback icons - this is bad, because the icon isn't scaled correctly.
if (!smallIcon)
smallIcon = LoadIcon(NULL, IDI_APPLICATION);
if (!largeIcon)
largeIcon = LoadIcon(NULL, IDI_APPLICATION);
PhEndInitOnce(&initOnce);
}
if (SmallIcon)
*SmallIcon = smallIcon;
if (LargeIcon)
*LargeIcon = largeIcon;
}
HICON PhGetFileShellIcon(
__in_opt PWSTR FileName,
__in_opt PWSTR DefaultExtension,
@@ -784,6 +843,34 @@ HICON PhGetFileShellIcon(
ULONG iconFlag;
HICON icon;
if (DefaultExtension && PhEqualStringZ(DefaultExtension, L".exe", TRUE))
{
// Special case for executable files (see above for reasoning).
icon = NULL;
if (FileName)
{
ExtractIconEx(
FileName,
0,
LargeIcon ? &icon : NULL,
!LargeIcon ? &icon : NULL,
1
);
}
if (!icon)
{
PhGetStockApplicationIcon(
!LargeIcon ? &icon : NULL,
LargeIcon ? &icon : NULL
);
}
return icon;
}
iconFlag = LargeIcon ? SHGFI_LARGEICON : SHGFI_SMALLICON;
icon = NULL;
+6
View File
@@ -443,6 +443,12 @@ VOID PhImageListWrapperRemove(
__in INT Index
);
PHLIBAPI
VOID PhGetStockApplicationIcon(
__out_opt HICON *SmallIcon,
__out_opt HICON *LargeIcon
);
PHLIBAPI
HICON PhGetFileShellIcon(
__in_opt PWSTR FileName,
+23
View File
@@ -1706,10 +1706,22 @@ PPH_STRING PhGetBaseName(
PPH_STRING PhGetSystemDirectory()
{
static PPH_STRING cachedSystemDirectory = NULL;
PPH_STRING systemDirectory;
ULONG bufferSize;
ULONG returnLength;
// Use the cached value if possible.
systemDirectory = cachedSystemDirectory;
if (systemDirectory)
{
PhReferenceObject(systemDirectory);
return systemDirectory;
}
bufferSize = 0x40;
systemDirectory = PhCreateStringEx(NULL, bufferSize * 2);
@@ -1732,6 +1744,17 @@ PPH_STRING PhGetSystemDirectory()
PhTrimToNullTerminatorString(systemDirectory);
// Try to cache the value.
if (_InterlockedCompareExchangePointer(
&cachedSystemDirectory,
systemDirectory,
NULL
) == NULL)
{
// Success, add one more reference for the cache.
PhReferenceObject(systemDirectory);
}
return systemDirectory;
}