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.
 
 
 
 
 
 

394 lines
10 KiB

/*
* Microsoft Confidential
* Copyright (C) Microsoft Corporation 1991
* All Rights Reserved.
*
*
* PIFLIB.C
* User interface routines for PIFMGR.DLL
*
* History:
* Created 31-Jul-1992 3:30pm by Jeff Parsons
*/
#include "shellprv.h"
#pragma hdrstop
#ifdef _X86_
#define LIB_SIG 0x504A
#define LIB_DEFER LOADPROPLIB_DEFER
typedef struct LIBLINK { /* ll */
struct LIBLINK *pllNext; //
struct LIBLINK *pllPrev; //
int iSig; // liblink signature
int flLib; // proplink flags (LIB_*)
HINSTANCE hDLL; // if NULL, then load has been deferred
TCHAR achDLL[80]; // name of DLL
} LIBLINK;
typedef LIBLINK *PLIBLINK;
#define SHEET_SIG 0x504A
typedef struct SHEETLINK { /* sl */
struct SHEETLINK *pslNext;
struct SHEETLINK *pslPrev;
int iSig;
int iType;
PROPSHEETPAGE psi;
} SHEETLINK;
typedef SHEETLINK *PSHEETLINK;
UINT cEdits; // number of edit sessions in progress
PLIBLINK pllHead; // pointer to first lib link
HANDLE offHighestLibLink; // highest offset of a lib link thus far recorded
PSHEETLINK pslHead; // pointer to first sheet link
UINT cSheetLinks; // number of sheet links
HANDLE offHighestSheetLink; // highest offset of a sheet link thus far recorded
struct { // built-in property sheet info
LPCTSTR lpTemplateName;
DLGPROC lpfnDlgProc;
int iType;
} const aPSInfo[] = {
{ MAKEINTRESOURCE(IDD_PROGRAM), DlgPrgProc, SHEETTYPE_SIMPLE},
{ MAKEINTRESOURCE(IDD_FONT), DlgFntProc, SHEETTYPE_SIMPLE},
{ MAKEINTRESOURCE(IDD_MEMORY), DlgMemProc, SHEETTYPE_SIMPLE},
{ MAKEINTRESOURCE(IDD_SCREEN), DlgVidProc, SHEETTYPE_SIMPLE},
{ MAKEINTRESOURCE(IDD_MISC), DlgMscProc, SHEETTYPE_SIMPLE},
};
/** EnumPropertyLibs - enumerate property libraries
*
* INPUT
* iLib == 0 to begin enumeration, or result of previous call
* lphDLL -> where to store handle (NULL if don't care)
* lpszDLL -> where to store name of library (NULL if don't care)
* cchszDLL == size of space (in chars) to store name
*
* OUTPUT
* lphDLL and lpszDLL filled in as appropriate, 0 if no more libs (or error)
*/
HANDLE WINAPI EnumPropertyLibs(HANDLE iLib, LPHANDLE lphDLL, LPTSTR lpszDLL, int cchszDLL)
{
register PLIBLINK pll;
FunctionName(EnumPropertyLibs);
if (!iLib)
pll = pllHead;
else
pll = ((PLIBLINK)iLib)->pllNext;
// Validate the handle
if (!pll)
return 0;
if ((HANDLE) pll > offHighestLibLink)
return 0;
if (pll->iSig != LIB_SIG)
return 0;
if (lphDLL)
*lphDLL = pll->hDLL;
if (lpszDLL)
StringCchCopy(lpszDLL, min(cchszDLL, ARRAYSIZE(pll->achDLL)), pll->achDLL);
return pll;
}
/** LoadPropertySheets - load property sheets
*
* INPUT
* hProps = property handle
* flags = 0 (reserved)
*
* OUTPUT
* # of sheets loaded, 0 if error
*/
int WINAPI LoadPropertySheets(HANDLE hProps, int flags)
{
register PLIBLINK pll;
FunctionName(LoadPropertySheets);
// If this is the first edit session, do global init now
if (cEdits++ == 0)
if (!LoadGlobalEditData())
return 0;
pll = NULL;
while (NULL != (pll = (PLIBLINK)EnumPropertyLibs(pll, NULL, NULL, 0))) {
if (!pll->hDLL && (pll->flLib & LIB_DEFER)) {
pll->hDLL = LoadLibrary(pll->achDLL);
// If the load failed, to us that simply means those sheets
// will not be available; the particular error is not interesting,
// so nullify the handle
if (pll->hDLL < (HINSTANCE)HINSTANCE_ERROR)
pll->hDLL = NULL;
}
}
return cSheetLinks + ARRAYSIZE(aPSInfo);
}
/** EnumPropertySheets - enumerate property sheets
*
* INPUT
* hProps == property handle
* iType == sheet type (see SHEETTYPE_* constants)
* iSheet == 0 to begin enumeration, or result of previous call
* lppsi -> property sheet info structure to be filled in
*
* OUTPUT
* lppsi filled in as appropriate, 0 if no more sheets (or error)
*/
INT_PTR WINAPI EnumPropertySheets(HANDLE hProps, int iType, INT_PTR iSheet, LPPROPSHEETPAGE lppsp)
{
register PSHEETLINK psl;
FunctionName(EnumPropertySheets);
while (iSheet < ARRAYSIZE(aPSInfo)) {
if (aPSInfo[iSheet].iType <= iType) {
if (lppsp) {
lppsp->dwSize = SIZEOF(PROPSHEETPAGE);
lppsp->dwFlags = PSP_DEFAULT;
lppsp->hInstance = HINST_THISDLL;
lppsp->pszTemplate = aPSInfo[iSheet].lpTemplateName;
lppsp->pfnDlgProc = aPSInfo[iSheet].lpfnDlgProc;
// lppsp->pszTitle = NULL;
lppsp->lParam = (LONG_PTR)hProps;
}
return ++iSheet;
}
++iSheet;
}
if (iSheet == ARRAYSIZE(aPSInfo))
psl = pslHead;
else
psl = ((PSHEETLINK)iSheet)->pslNext;
// Validate the handle
while (psl && (HANDLE) psl <= offHighestSheetLink && psl->iSig == SHEET_SIG) {
if (psl->iType <= iType) {
*lppsp = psl->psi;
lppsp->lParam = (LONG_PTR)hProps;
return (INT_PTR) psl;
}
psl = psl->pslNext;
}
return 0; // no more matching sheets
}
/** FreePropertySheets - free property sheets
*
* INPUT
* hProps = property handle
* flags = 0 (reserved)
*
* OUTPUT
* Nothing
*/
HANDLE WINAPI FreePropertySheets(HANDLE hProps, int flags)
{
register PLIBLINK pll;
FunctionName(FreePropertySheets);
pll = NULL;
while (NULL != (pll = (PLIBLINK)EnumPropertyLibs(pll, NULL, NULL, 0))) {
if (pll->hDLL && (pll->flLib & LIB_DEFER)) {
FreeLibrary(pll->hDLL);
pll->hDLL = NULL;
}
}
// If this is the last edit session, do global un-init now
if (--cEdits == 0)
FreeGlobalEditData();
return 0;
}
/** InitRealModeFlag - Initialize PROP_REALMODE
*
* INPUT
* ppl = properties
*
* OUTPUT
* ppl->flProp PROP_REALMODE bit set if sheet is for real-mode app,
* else clear.
*/
void InitRealModeFlag(PPROPLINK ppl)
{
PROPPRG prg;
if (!PifMgr_GetProperties(ppl, MAKELP(0,GROUP_PRG),
&prg, SIZEOF(prg), GETPROPS_NONE)) {
return; /* Weird */
}
if (prg.flPrgInit & PRGINIT_REALMODE) {
ppl->flProp |= PROP_REALMODE;
} else {
ppl->flProp &= ~PROP_REALMODE;
}
}
BOOL LoadGlobalEditData()
{
FunctionName(LoadGlobalEditData);
if (!LoadGlobalFontEditData())
return FALSE;
return TRUE;
}
void FreeGlobalEditData()
{
FunctionName(FreeGlobalEditData);
FreeGlobalFontEditData();
}
UINT CALLBACK PifPropPageRelease(HWND hwnd, UINT uMsg, LPPROPSHEETPAGE lppsp)
{
FunctionName(PifPropPageRelease);
if (uMsg == PSPCB_RELEASE) {
PPROPLINK ppl = (PPROPLINK)(INT_PTR)lppsp->lParam;
if ((--ppl->iSheetUsage) == 0) {
FreePropertySheets(ppl, 0);
PifMgr_CloseProperties(ppl, CLOSEPROPS_NONE);
}
}
return 1;
}
#define MZMAGIC ((WORD)'M'+((WORD)'Z'<<8))
//
// call SHELL.DLL to get the EXE type.
//
BOOL IsWinExe(LPCTSTR lpszFile)
{
DWORD dw = (DWORD) SHGetFileInfo(lpszFile, 0, NULL, 0, SHGFI_EXETYPE);
return dw && LOWORD(dw) != MZMAGIC;
}
BOOL WINAPI PifPropGetPages(LPVOID lpv,
LPFNADDPROPSHEETPAGE lpfnAddPage,
LPARAM lParam)
{
#define hDrop (HDROP)lpv
PPROPLINK ppl;
PROPSHEETPAGE psp;
int iType, cSheets;
INT_PTR iSheet;
HPROPSHEETPAGE hpage;
TCHAR szFileName[MAXPATHNAME];
FunctionName(PifPropGetPages);
// only process things if hDrop contains only one file
if (DragQueryFile(hDrop, (UINT)-1, NULL, 0) != 1)
{
return TRUE;
}
// get the name of the file
DragQueryFile(hDrop, 0, szFileName, ARRAYSIZE(szFileName));
if (GetFileAttributes( szFileName) & FILE_ATTRIBUTE_OFFLINE)
{
return FALSE;
}
// if this is a windows app, don't do no properties
if (IsWinExe(szFileName))
return TRUE;
// if we can't get a property handle, don't do no properties either
if (!(ppl = (PPROPLINK)PifMgr_OpenProperties(szFileName, NULL, 0, OPENPROPS_NONE)))
return TRUE;
InitRealModeFlag(ppl);
if (!(cSheets = LoadPropertySheets(ppl, 0)))
goto CloseProps;
// Since the user wishes to *explicitly* change settings for this app
// we make sure that the DONTWRITE flag isn't going to get in his way...
ppl->flProp &= ~PROP_DONTWRITE;
iSheet = cSheets = 0;
iType = (GetKeyState(VK_CONTROL) >= 0? SHEETTYPE_SIMPLE : SHEETTYPE_ADVANCED);
while (TRUE) {
if (!(iSheet = EnumPropertySheets(ppl, iType, iSheet, &psp))) {
// done with enumeration
break;
}
psp.dwFlags |= PSP_USECALLBACK;
psp.pfnCallback = PifPropPageRelease;
psp.pcRefParent = 0;
hpage = CreatePropertySheetPage(&psp);
if (hpage)
{
// the PROPLINK is now being used by this property sheet as well
if (lpfnAddPage(hpage, lParam))
{
ppl->iSheetUsage++;
cSheets++;
}
else
{
PifPropPageRelease(NULL, PSPCB_RELEASE, &psp);
}
}
}
if (!cSheets) {
FreePropertySheets(ppl, 0);
CloseProps:
PifMgr_CloseProperties(ppl, CLOSEPROPS_NONE);
}
return TRUE;
}
#undef hDrop
#endif