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.

393 lines
10 KiB

  1. /*
  2. * Microsoft Confidential
  3. * Copyright (C) Microsoft Corporation 1991
  4. * All Rights Reserved.
  5. *
  6. *
  7. * PIFLIB.C
  8. * User interface routines for PIFMGR.DLL
  9. *
  10. * History:
  11. * Created 31-Jul-1992 3:30pm by Jeff Parsons
  12. */
  13. #include "shellprv.h"
  14. #pragma hdrstop
  15. #ifdef _X86_
  16. #define LIB_SIG 0x504A
  17. #define LIB_DEFER LOADPROPLIB_DEFER
  18. typedef struct LIBLINK { /* ll */
  19. struct LIBLINK *pllNext; //
  20. struct LIBLINK *pllPrev; //
  21. int iSig; // liblink signature
  22. int flLib; // proplink flags (LIB_*)
  23. HINSTANCE hDLL; // if NULL, then load has been deferred
  24. TCHAR achDLL[80]; // name of DLL
  25. } LIBLINK;
  26. typedef LIBLINK *PLIBLINK;
  27. #define SHEET_SIG 0x504A
  28. typedef struct SHEETLINK { /* sl */
  29. struct SHEETLINK *pslNext;
  30. struct SHEETLINK *pslPrev;
  31. int iSig;
  32. int iType;
  33. PROPSHEETPAGE psi;
  34. } SHEETLINK;
  35. typedef SHEETLINK *PSHEETLINK;
  36. UINT cEdits; // number of edit sessions in progress
  37. PLIBLINK pllHead; // pointer to first lib link
  38. HANDLE offHighestLibLink; // highest offset of a lib link thus far recorded
  39. PSHEETLINK pslHead; // pointer to first sheet link
  40. UINT cSheetLinks; // number of sheet links
  41. HANDLE offHighestSheetLink; // highest offset of a sheet link thus far recorded
  42. struct { // built-in property sheet info
  43. LPCTSTR lpTemplateName;
  44. DLGPROC lpfnDlgProc;
  45. int iType;
  46. } const aPSInfo[] = {
  47. { MAKEINTRESOURCE(IDD_PROGRAM), DlgPrgProc, SHEETTYPE_SIMPLE},
  48. { MAKEINTRESOURCE(IDD_FONT), DlgFntProc, SHEETTYPE_SIMPLE},
  49. { MAKEINTRESOURCE(IDD_MEMORY), DlgMemProc, SHEETTYPE_SIMPLE},
  50. { MAKEINTRESOURCE(IDD_SCREEN), DlgVidProc, SHEETTYPE_SIMPLE},
  51. { MAKEINTRESOURCE(IDD_MISC), DlgMscProc, SHEETTYPE_SIMPLE},
  52. };
  53. /** EnumPropertyLibs - enumerate property libraries
  54. *
  55. * INPUT
  56. * iLib == 0 to begin enumeration, or result of previous call
  57. * lphDLL -> where to store handle (NULL if don't care)
  58. * lpszDLL -> where to store name of library (NULL if don't care)
  59. * cchszDLL == size of space (in chars) to store name
  60. *
  61. * OUTPUT
  62. * lphDLL and lpszDLL filled in as appropriate, 0 if no more libs (or error)
  63. */
  64. HANDLE WINAPI EnumPropertyLibs(HANDLE iLib, LPHANDLE lphDLL, LPTSTR lpszDLL, int cchszDLL)
  65. {
  66. register PLIBLINK pll;
  67. FunctionName(EnumPropertyLibs);
  68. if (!iLib)
  69. pll = pllHead;
  70. else
  71. pll = ((PLIBLINK)iLib)->pllNext;
  72. // Validate the handle
  73. if (!pll)
  74. return 0;
  75. if ((HANDLE) pll > offHighestLibLink)
  76. return 0;
  77. if (pll->iSig != LIB_SIG)
  78. return 0;
  79. if (lphDLL)
  80. *lphDLL = pll->hDLL;
  81. if (lpszDLL)
  82. StringCchCopy(lpszDLL, min(cchszDLL, ARRAYSIZE(pll->achDLL)), pll->achDLL);
  83. return pll;
  84. }
  85. /** LoadPropertySheets - load property sheets
  86. *
  87. * INPUT
  88. * hProps = property handle
  89. * flags = 0 (reserved)
  90. *
  91. * OUTPUT
  92. * # of sheets loaded, 0 if error
  93. */
  94. int WINAPI LoadPropertySheets(HANDLE hProps, int flags)
  95. {
  96. register PLIBLINK pll;
  97. FunctionName(LoadPropertySheets);
  98. // If this is the first edit session, do global init now
  99. if (cEdits++ == 0)
  100. if (!LoadGlobalEditData())
  101. return 0;
  102. pll = NULL;
  103. while (NULL != (pll = (PLIBLINK)EnumPropertyLibs(pll, NULL, NULL, 0))) {
  104. if (!pll->hDLL && (pll->flLib & LIB_DEFER)) {
  105. pll->hDLL = LoadLibrary(pll->achDLL);
  106. // If the load failed, to us that simply means those sheets
  107. // will not be available; the particular error is not interesting,
  108. // so nullify the handle
  109. if (pll->hDLL < (HINSTANCE)HINSTANCE_ERROR)
  110. pll->hDLL = NULL;
  111. }
  112. }
  113. return cSheetLinks + ARRAYSIZE(aPSInfo);
  114. }
  115. /** EnumPropertySheets - enumerate property sheets
  116. *
  117. * INPUT
  118. * hProps == property handle
  119. * iType == sheet type (see SHEETTYPE_* constants)
  120. * iSheet == 0 to begin enumeration, or result of previous call
  121. * lppsi -> property sheet info structure to be filled in
  122. *
  123. * OUTPUT
  124. * lppsi filled in as appropriate, 0 if no more sheets (or error)
  125. */
  126. INT_PTR WINAPI EnumPropertySheets(HANDLE hProps, int iType, INT_PTR iSheet, LPPROPSHEETPAGE lppsp)
  127. {
  128. register PSHEETLINK psl;
  129. FunctionName(EnumPropertySheets);
  130. while (iSheet < ARRAYSIZE(aPSInfo)) {
  131. if (aPSInfo[iSheet].iType <= iType) {
  132. if (lppsp) {
  133. lppsp->dwSize = SIZEOF(PROPSHEETPAGE);
  134. lppsp->dwFlags = PSP_DEFAULT;
  135. lppsp->hInstance = HINST_THISDLL;
  136. lppsp->pszTemplate = aPSInfo[iSheet].lpTemplateName;
  137. lppsp->pfnDlgProc = aPSInfo[iSheet].lpfnDlgProc;
  138. // lppsp->pszTitle = NULL;
  139. lppsp->lParam = (LONG_PTR)hProps;
  140. }
  141. return ++iSheet;
  142. }
  143. ++iSheet;
  144. }
  145. if (iSheet == ARRAYSIZE(aPSInfo))
  146. psl = pslHead;
  147. else
  148. psl = ((PSHEETLINK)iSheet)->pslNext;
  149. // Validate the handle
  150. while (psl && (HANDLE) psl <= offHighestSheetLink && psl->iSig == SHEET_SIG) {
  151. if (psl->iType <= iType) {
  152. *lppsp = psl->psi;
  153. lppsp->lParam = (LONG_PTR)hProps;
  154. return (INT_PTR) psl;
  155. }
  156. psl = psl->pslNext;
  157. }
  158. return 0; // no more matching sheets
  159. }
  160. /** FreePropertySheets - free property sheets
  161. *
  162. * INPUT
  163. * hProps = property handle
  164. * flags = 0 (reserved)
  165. *
  166. * OUTPUT
  167. * Nothing
  168. */
  169. HANDLE WINAPI FreePropertySheets(HANDLE hProps, int flags)
  170. {
  171. register PLIBLINK pll;
  172. FunctionName(FreePropertySheets);
  173. pll = NULL;
  174. while (NULL != (pll = (PLIBLINK)EnumPropertyLibs(pll, NULL, NULL, 0))) {
  175. if (pll->hDLL && (pll->flLib & LIB_DEFER)) {
  176. FreeLibrary(pll->hDLL);
  177. pll->hDLL = NULL;
  178. }
  179. }
  180. // If this is the last edit session, do global un-init now
  181. if (--cEdits == 0)
  182. FreeGlobalEditData();
  183. return 0;
  184. }
  185. /** InitRealModeFlag - Initialize PROP_REALMODE
  186. *
  187. * INPUT
  188. * ppl = properties
  189. *
  190. * OUTPUT
  191. * ppl->flProp PROP_REALMODE bit set if sheet is for real-mode app,
  192. * else clear.
  193. */
  194. void InitRealModeFlag(PPROPLINK ppl)
  195. {
  196. PROPPRG prg;
  197. if (!PifMgr_GetProperties(ppl, MAKELP(0,GROUP_PRG),
  198. &prg, SIZEOF(prg), GETPROPS_NONE)) {
  199. return; /* Weird */
  200. }
  201. if (prg.flPrgInit & PRGINIT_REALMODE) {
  202. ppl->flProp |= PROP_REALMODE;
  203. } else {
  204. ppl->flProp &= ~PROP_REALMODE;
  205. }
  206. }
  207. BOOL LoadGlobalEditData()
  208. {
  209. FunctionName(LoadGlobalEditData);
  210. if (!LoadGlobalFontEditData())
  211. return FALSE;
  212. return TRUE;
  213. }
  214. void FreeGlobalEditData()
  215. {
  216. FunctionName(FreeGlobalEditData);
  217. FreeGlobalFontEditData();
  218. }
  219. UINT CALLBACK PifPropPageRelease(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE lppsp)
  220. {
  221. FunctionName(PifPropPageRelease);
  222. if (uMsg == PSPCB_RELEASE) {
  223. PPROPLINK ppl = (PPROPLINK)(INT_PTR)lppsp->lParam;
  224. if ((--ppl->iSheetUsage) == 0) {
  225. FreePropertySheets(ppl, 0);
  226. PifMgr_CloseProperties(ppl, CLOSEPROPS_NONE);
  227. }
  228. }
  229. return 1;
  230. }
  231. #define MZMAGIC ((WORD)'M'+((WORD)'Z'<<8))
  232. //
  233. // call SHELL.DLL to get the EXE type.
  234. //
  235. BOOL IsWinExe(LPCTSTR lpszFile)
  236. {
  237. DWORD dw = (DWORD) SHGetFileInfo(lpszFile, 0, NULL, 0, SHGFI_EXETYPE);
  238. return dw && LOWORD(dw) != MZMAGIC;
  239. }
  240. BOOL WINAPI PifPropGetPages(LPVOID lpv,
  241. LPFNADDPROPSHEETPAGE lpfnAddPage,
  242. LPARAM lParam)
  243. {
  244. #define hDrop (HDROP)lpv
  245. PPROPLINK ppl;
  246. PROPSHEETPAGE psp;
  247. int iType, cSheets;
  248. INT_PTR iSheet;
  249. HPROPSHEETPAGE hpage;
  250. TCHAR szFileName[MAXPATHNAME];
  251. FunctionName(PifPropGetPages);
  252. // only process things if hDrop contains only one file
  253. if (DragQueryFile(hDrop, (UINT)-1, NULL, 0) != 1)
  254. {
  255. return TRUE;
  256. }
  257. // get the name of the file
  258. DragQueryFile(hDrop, 0, szFileName, ARRAYSIZE(szFileName));
  259. if (GetFileAttributes( szFileName) & FILE_ATTRIBUTE_OFFLINE)
  260. {
  261. return FALSE;
  262. }
  263. // if this is a windows app, don't do no properties
  264. if (IsWinExe(szFileName))
  265. return TRUE;
  266. // if we can't get a property handle, don't do no properties either
  267. if (!(ppl = (PPROPLINK)PifMgr_OpenProperties(szFileName, NULL, 0, OPENPROPS_NONE)))
  268. return TRUE;
  269. InitRealModeFlag(ppl);
  270. if (!(cSheets = LoadPropertySheets(ppl, 0)))
  271. goto CloseProps;
  272. // Since the user wishes to *explicitly* change settings for this app
  273. // we make sure that the DONTWRITE flag isn't going to get in his way...
  274. ppl->flProp &= ~PROP_DONTWRITE;
  275. iSheet = cSheets = 0;
  276. iType = (GetKeyState(VK_CONTROL) >= 0? SHEETTYPE_SIMPLE : SHEETTYPE_ADVANCED);
  277. while (TRUE) {
  278. if (!(iSheet = EnumPropertySheets(ppl, iType, iSheet, &psp))) {
  279. // done with enumeration
  280. break;
  281. }
  282. psp.dwFlags |= PSP_USECALLBACK;
  283. psp.pfnCallback = PifPropPageRelease;
  284. psp.pcRefParent = 0;
  285. hpage = CreatePropertySheetPage(&psp);
  286. if (hpage)
  287. {
  288. // the PROPLINK is now being used by this property sheet as well
  289. if (lpfnAddPage(hpage, lParam))
  290. {
  291. ppl->iSheetUsage++;
  292. cSheets++;
  293. }
  294. else
  295. {
  296. PifPropPageRelease(NULL, PSPCB_RELEASE, &psp);
  297. }
  298. }
  299. }
  300. if (!cSheets) {
  301. FreePropertySheets(ppl, 0);
  302. CloseProps:
  303. PifMgr_CloseProperties(ppl, CLOSEPROPS_NONE);
  304. }
  305. return TRUE;
  306. }
  307. #undef hDrop
  308. #endif