Windows-Server-2003/com/ole2ui32/geticon.cpp

186 lines
5.7 KiB
C++

/*
* GETICON.CPP
*
* Functions to create DVASPECT_ICON metafile from filename or classname.
*
* OleMetafilePictFromIconAndLabel
*
* (c) Copyright Microsoft Corp. 1992-1993 All Rights Reserved
*/
/*******
*
* ICON (DVASPECT_ICON) METAFILE FORMAT:
*
* The metafile generated with OleMetafilePictFromIconAndLabel contains
* the following records which are used by the functions in DRAWICON.CPP
* to draw the icon with and without the label and to extract the icon,
* label, and icon source/index.
*
* SetWindowOrg
* SetWindowExt
* DrawIcon:
* Inserts records of DIBBITBLT or DIBSTRETCHBLT, once for the
* AND mask, one for the image bits.
* Escape with the comment "IconOnly"
* This indicates where to stop record enumeration to draw only
* the icon.
* SetTextColor
* SetTextAlign
* SetBkColor
* CreateFont
* SelectObject on the font.
* ExtTextOut
* One or more ExtTextOuts occur if the label is wrapped. The
* text in these records is used to extract the label.
* SelectObject on the old font.
* DeleteObject on the font.
* Escape with a comment that contains the path to the icon source.
* Escape with a comment that is the ASCII of the icon index.
*
*******/
#include "precomp.h"
#include "common.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <commdlg.h>
#include <memory.h>
#include <cderr.h>
#include <reghelp.hxx>
#include "utility.h"
#include "strsafe.h"
OLEDBGDATA
static const TCHAR szSeparators[] = TEXT(" \t\\/!:");
#define IS_SEPARATOR(c) ( (c) == ' ' || (c) == '\\' \
|| (c) == '/' || (c) == '\t' \
|| (c) == '!' || (c) == ':')
#define IS_FILENAME_DELIM(c) ( (c) == '\\' || (c) == '/' || (c) == ':' )
#define IS_SPACE(c) ( (c) == ' ' || (c) == '\t' || (c) == '\n' )
/*
* GetAssociatedExecutable
*
* Purpose: Finds the executable associated with the provided extension
*
* Parameters:
* lpszExtension LPSTR points to the extension we're trying to find
* an exe for. Does **NO** validation.
*
* lpszExecutable LPSTR points to where the exe name will be returned.
* No validation here either - pass in 128 char buffer.
*
* Return:
* BOOL TRUE if we found an exe, FALSE if we didn't.
*
* SECURITY BUG: DON'T TRUST THE RESULTS OF THIS FUNCTION! IF THE ASSOCIATED EXECUTABLE IS
* "D:\Program Files\Foo.exe", this routine will return "D:\program". Currently this function is not used to actually
* start an application, so it is not causing a security defect. It is a bug, however, and will be a security issue if
* you do use the results to start the executable.
*/
BOOL FAR PASCAL GetAssociatedExecutable(LPTSTR lpszExtension, LPTSTR lpszExecutable, UINT cchBuf)
{
BOOL fRet = FALSE;
HKEY hKey = NULL;
LRESULT lRet = OpenClassesRootKey(NULL, &hKey);
if (ERROR_SUCCESS != lRet)
{
goto end;
}
LONG dw = OLEUI_CCHKEYMAX_SIZE;
TCHAR szValue[OLEUI_CCHKEYMAX];
lRet = RegQueryValue(hKey, lpszExtension, szValue, &dw); //ProgId
if (ERROR_SUCCESS != lRet)
{
goto end;
}
// szValue now has ProgID
TCHAR szKey[OLEUI_CCHKEYMAX];
StringCchCopy(szKey, sizeof(szKey)/sizeof(szKey[0]), szValue);
if (FAILED(StringCchCat(szKey, sizeof(szKey)/sizeof(szKey[0]), TEXT("\\Shell\\Open\\Command"))))
{
goto end;
}
dw = OLEUI_CCHKEYMAX_SIZE;
lRet = RegQueryValue(hKey, szKey, szValue, &dw);
if (ERROR_SUCCESS != lRet)
{
goto end;
}
// szValue now has an executable name in it. Let's null-terminate
// at the first post-executable space (so we don't have cmd line
// args.
LPTSTR lpszTemp = szValue;
while ('\0' != *lpszTemp && IS_SPACE(*lpszTemp))
lpszTemp = CharNext(lpszTemp); // Strip off leading spaces
LPTSTR lpszExe = lpszTemp;
while ('\0' != *lpszTemp && !IS_SPACE(*lpszTemp))
lpszTemp = CharNext(lpszTemp); // Step through exe name
*lpszTemp = '\0'; // null terminate at first space (or at end).
StringCchCopy(lpszExecutable, cchBuf, lpszExe);
fRet = TRUE;
end:
if(hKey)
{
RegCloseKey(hKey);
hKey = NULL;
}
return fRet;
}
/*
* PointerToNthField
*
* Purpose:
* Returns a pointer to the beginning of the nth field.
* Assumes null-terminated string.
*
* Parameters:
* lpszString string to parse
* nField field to return starting index of.
* chDelimiter char that delimits fields
*
* Return Value:
* LPSTR pointer to beginning of nField field.
* NOTE: If the null terminator is found
* Before we find the Nth field, then
* we return a pointer to the null terminator -
* calling app should be sure to check for
* this case.
*
*/
LPTSTR FAR PASCAL PointerToNthField(LPTSTR lpszString, int nField, TCHAR chDelimiter)
{
if (1 == nField)
return lpszString;
int cFieldFound = 1;
LPTSTR lpField = lpszString;
while (*lpField != '\0')
{
if (*lpField++ == chDelimiter)
{
cFieldFound++;
if (nField == cFieldFound)
return lpField;
}
}
return lpField;
}