Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

185 lines
5.9 KiB

  1. /*
  2. * GETICON.CPP
  3. *
  4. * Functions to create DVASPECT_ICON metafile from filename or classname.
  5. *
  6. * OleMetafilePictFromIconAndLabel
  7. *
  8. * (c) Copyright Microsoft Corp. 1992-1993 All Rights Reserved
  9. */
  10. /*******
  11. *
  12. * ICON (DVASPECT_ICON) METAFILE FORMAT:
  13. *
  14. * The metafile generated with OleMetafilePictFromIconAndLabel contains
  15. * the following records which are used by the functions in DRAWICON.CPP
  16. * to draw the icon with and without the label and to extract the icon,
  17. * label, and icon source/index.
  18. *
  19. * SetWindowOrg
  20. * SetWindowExt
  21. * DrawIcon:
  22. * Inserts records of DIBBITBLT or DIBSTRETCHBLT, once for the
  23. * AND mask, one for the image bits.
  24. * Escape with the comment "IconOnly"
  25. * This indicates where to stop record enumeration to draw only
  26. * the icon.
  27. * SetTextColor
  28. * SetTextAlign
  29. * SetBkColor
  30. * CreateFont
  31. * SelectObject on the font.
  32. * ExtTextOut
  33. * One or more ExtTextOuts occur if the label is wrapped. The
  34. * text in these records is used to extract the label.
  35. * SelectObject on the old font.
  36. * DeleteObject on the font.
  37. * Escape with a comment that contains the path to the icon source.
  38. * Escape with a comment that is the ASCII of the icon index.
  39. *
  40. *******/
  41. #include "precomp.h"
  42. #include "common.h"
  43. #include <stdlib.h>
  44. #include <string.h>
  45. #include <ctype.h>
  46. #include <commdlg.h>
  47. #include <memory.h>
  48. #include <cderr.h>
  49. #include <reghelp.hxx>
  50. #include "utility.h"
  51. #include "strsafe.h"
  52. OLEDBGDATA
  53. static const TCHAR szSeparators[] = TEXT(" \t\\/!:");
  54. #define IS_SEPARATOR(c) ( (c) == ' ' || (c) == '\\' \
  55. || (c) == '/' || (c) == '\t' \
  56. || (c) == '!' || (c) == ':')
  57. #define IS_FILENAME_DELIM(c) ( (c) == '\\' || (c) == '/' || (c) == ':' )
  58. #define IS_SPACE(c) ( (c) == ' ' || (c) == '\t' || (c) == '\n' )
  59. /*
  60. * GetAssociatedExecutable
  61. *
  62. * Purpose: Finds the executable associated with the provided extension
  63. *
  64. * Parameters:
  65. * lpszExtension LPSTR points to the extension we're trying to find
  66. * an exe for. Does **NO** validation.
  67. *
  68. * lpszExecutable LPSTR points to where the exe name will be returned.
  69. * No validation here either - pass in 128 char buffer.
  70. *
  71. * Return:
  72. * BOOL TRUE if we found an exe, FALSE if we didn't.
  73. *
  74. * SECURITY BUG: DON'T TRUST THE RESULTS OF THIS FUNCTION! IF THE ASSOCIATED EXECUTABLE IS
  75. * "D:\Program Files\Foo.exe", this routine will return "D:\program". Currently this function is not used to actually
  76. * start an application, so it is not causing a security defect. It is a bug, however, and will be a security issue if
  77. * you do use the results to start the executable.
  78. */
  79. BOOL FAR PASCAL GetAssociatedExecutable(LPTSTR lpszExtension, LPTSTR lpszExecutable, UINT cchBuf)
  80. {
  81. BOOL fRet = FALSE;
  82. HKEY hKey = NULL;
  83. LRESULT lRet = OpenClassesRootKey(NULL, &hKey);
  84. if (ERROR_SUCCESS != lRet)
  85. {
  86. goto end;
  87. }
  88. LONG dw = OLEUI_CCHKEYMAX_SIZE;
  89. TCHAR szValue[OLEUI_CCHKEYMAX];
  90. lRet = RegQueryValue(hKey, lpszExtension, szValue, &dw); //ProgId
  91. if (ERROR_SUCCESS != lRet)
  92. {
  93. goto end;
  94. }
  95. // szValue now has ProgID
  96. TCHAR szKey[OLEUI_CCHKEYMAX];
  97. StringCchCopy(szKey, sizeof(szKey)/sizeof(szKey[0]), szValue);
  98. if (FAILED(StringCchCat(szKey, sizeof(szKey)/sizeof(szKey[0]), TEXT("\\Shell\\Open\\Command"))))
  99. {
  100. goto end;
  101. }
  102. dw = OLEUI_CCHKEYMAX_SIZE;
  103. lRet = RegQueryValue(hKey, szKey, szValue, &dw);
  104. if (ERROR_SUCCESS != lRet)
  105. {
  106. goto end;
  107. }
  108. // szValue now has an executable name in it. Let's null-terminate
  109. // at the first post-executable space (so we don't have cmd line
  110. // args.
  111. LPTSTR lpszTemp = szValue;
  112. while ('\0' != *lpszTemp && IS_SPACE(*lpszTemp))
  113. lpszTemp = CharNext(lpszTemp); // Strip off leading spaces
  114. LPTSTR lpszExe = lpszTemp;
  115. while ('\0' != *lpszTemp && !IS_SPACE(*lpszTemp))
  116. lpszTemp = CharNext(lpszTemp); // Step through exe name
  117. *lpszTemp = '\0'; // null terminate at first space (or at end).
  118. StringCchCopy(lpszExecutable, cchBuf, lpszExe);
  119. fRet = TRUE;
  120. end:
  121. if(hKey)
  122. {
  123. RegCloseKey(hKey);
  124. hKey = NULL;
  125. }
  126. return fRet;
  127. }
  128. /*
  129. * PointerToNthField
  130. *
  131. * Purpose:
  132. * Returns a pointer to the beginning of the nth field.
  133. * Assumes null-terminated string.
  134. *
  135. * Parameters:
  136. * lpszString string to parse
  137. * nField field to return starting index of.
  138. * chDelimiter char that delimits fields
  139. *
  140. * Return Value:
  141. * LPSTR pointer to beginning of nField field.
  142. * NOTE: If the null terminator is found
  143. * Before we find the Nth field, then
  144. * we return a pointer to the null terminator -
  145. * calling app should be sure to check for
  146. * this case.
  147. *
  148. */
  149. LPTSTR FAR PASCAL PointerToNthField(LPTSTR lpszString, int nField, TCHAR chDelimiter)
  150. {
  151. if (1 == nField)
  152. return lpszString;
  153. int cFieldFound = 1;
  154. LPTSTR lpField = lpszString;
  155. while (*lpField != '\0')
  156. {
  157. if (*lpField++ == chDelimiter)
  158. {
  159. cFieldFound++;
  160. if (nField == cFieldFound)
  161. return lpField;
  162. }
  163. }
  164. return lpField;
  165. }