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.
1006 lines
31 KiB
1006 lines
31 KiB
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
|
|
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
|
|
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
|
|
// PARTICULAR PURPOSE.
|
|
//
|
|
// Copyright 1997 - 2003 Microsoft Corporation. All Rights Reserved.
|
|
//
|
|
// FILE: OEMUI.cpp
|
|
//
|
|
//
|
|
// PURPOSE: Main file for OEM UI test module.
|
|
//
|
|
//
|
|
// Functions:
|
|
//
|
|
//
|
|
//
|
|
//
|
|
// PLATFORMS: Windows 2000, Windows XP, Windows Server 2003
|
|
//
|
|
//
|
|
|
|
#include "precomp.h"
|
|
#include "resource.h"
|
|
#include "debug.h"
|
|
#include "oemui.h"
|
|
|
|
// StrSafe.h needs to be included last
|
|
// to disallow bad string functions.
|
|
#include <STRSAFE.H>
|
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
// INTERNAL MACROS and DEFINES
|
|
////////////////////////////////////////////////////////
|
|
|
|
typedef struct _tagCBUserData
|
|
{
|
|
HANDLE hComPropSheet;
|
|
HANDLE hPropPage;
|
|
POEMUIPSPARAM pOEMUIParam;
|
|
PFNCOMPROPSHEET pfnComPropSheet;
|
|
|
|
} CBUSERDATA, *PCBUSERDATA;
|
|
|
|
|
|
////////////////////////////////////////////////////////
|
|
// INTERNAL PROTOTYPES
|
|
////////////////////////////////////////////////////////
|
|
|
|
static HRESULT hrDocumentPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam);
|
|
static HRESULT hrPrinterPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam);
|
|
LONG APIENTRY OEMPrinterUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam);
|
|
LONG APIENTRY OEMDocUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam);
|
|
LONG APIENTRY OEMDocUICallBack2(PCPSUICBPARAM pCallbackParam);
|
|
INT_PTR CALLBACK DevicePropPageProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam);
|
|
static BOOL AddCustomUIHelp (HANDLE hPrinter, HANDLE hHeap, HANDLE hModule, POPTITEM pOptItem, DWORD HelpIndex, DWORD HelpFile);
|
|
static POIEXT CreateOIExt(HANDLE hHeap);
|
|
static POPTITEM CreateOptItems(HANDLE hHeap, DWORD dwOptItems);
|
|
static void InitOptItems(POPTITEM pOptItems, DWORD dwOptItems);
|
|
static POPTTYPE CreateOptType(HANDLE hHeap, WORD wOptParams);
|
|
static PTSTR GetHelpFile (HANDLE hPrinter, HANDLE hHeap, HANDLE hModule, UINT uResource);
|
|
static PTSTR GetStringResource(HANDLE hHeap, HANDLE hModule, UINT uResource);
|
|
LPBYTE WrapGetPrinterDriver (HANDLE hHeap, HANDLE hPrinter, DWORD dwLevel);
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initializes OptItems to display OEM device or document property UI.
|
|
// Called via IOemUI::CommonUIProp
|
|
//
|
|
HRESULT hrOEMPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
|
|
{
|
|
HRESULT hResult = S_OK;
|
|
|
|
|
|
VERBOSE(DLLTEXT("hrOEMPropertyPage(%d) entry.\r\n"), dwMode);
|
|
|
|
// Validate parameters.
|
|
if( (OEMCUIP_DOCPROP != dwMode)
|
|
&&
|
|
(OEMCUIP_PRNPROP != dwMode)
|
|
)
|
|
{
|
|
ERR(ERRORTEXT("hrOEMPropertyPage() ERROR_INVALID_PARAMETER.\r\n"));
|
|
VERBOSE(DLLTEXT("\tdwMode = %d, pOEMUIParam = %#lx.\r\n"), dwMode, pOEMUIParam);
|
|
|
|
// Return invalid parameter error.
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return E_FAIL;
|
|
}
|
|
|
|
switch(dwMode)
|
|
{
|
|
case OEMCUIP_DOCPROP:
|
|
hResult = hrDocumentPropertyPage(dwMode, pOEMUIParam);
|
|
break;
|
|
|
|
case OEMCUIP_PRNPROP:
|
|
hResult = hrPrinterPropertyPage(dwMode, pOEMUIParam);
|
|
break;
|
|
|
|
default:
|
|
// Should never reach this!
|
|
ERR(ERRORTEXT("hrOEMPropertyPage() Invalid dwMode, %d"), dwMode);
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
hResult = E_FAIL;
|
|
break;
|
|
}
|
|
|
|
return hResult;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initializes OptItems to display OEM document property UI.
|
|
//
|
|
static HRESULT hrDocumentPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
|
|
{
|
|
if(NULL == pOEMUIParam->pOEMOptItems)
|
|
{
|
|
// Fill in the number of OptItems to create for OEM document property UI.
|
|
pOEMUIParam->cOEMOptItems = 1;
|
|
|
|
VERBOSE(DLLTEXT("hrDocumentPropertyPage() requesting %d number of items.\r\n"), pOEMUIParam->cOEMOptItems);
|
|
}
|
|
else
|
|
{
|
|
POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
|
|
|
|
|
|
VERBOSE(DLLTEXT("hrDocumentPropertyPage() fill out %d items.\r\n"), pOEMUIParam->cOEMOptItems);
|
|
|
|
// Init UI Callback reference.
|
|
pOEMUIParam->OEMCUIPCallback = OEMDocUICallBack;
|
|
|
|
// Init OEMOptItmes.
|
|
InitOptItems(pOEMUIParam->pOEMOptItems, pOEMUIParam->cOEMOptItems);
|
|
|
|
// Fill out tree view items.
|
|
|
|
// New section.
|
|
pOEMUIParam->pOEMOptItems[0].Level = 1;
|
|
pOEMUIParam->pOEMOptItems[0].Flags = OPTIF_COLLAPSE;
|
|
pOEMUIParam->pOEMOptItems[0].pName = GetStringResource(pOEMUIParam->hOEMHeap, pOEMUIParam->hModule, IDS_ADV_SECTION);
|
|
pOEMUIParam->pOEMOptItems[0].Sel = pOEMDev->dwAdvancedData;
|
|
|
|
pOEMUIParam->pOEMOptItems[0].pOptType= CreateOptType(pOEMUIParam->hOEMHeap, 2);
|
|
|
|
//
|
|
//Setup the Optional Item
|
|
//
|
|
pOEMUIParam->pOEMOptItems[0].pOptType->Type = TVOT_UDARROW;
|
|
pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].IconID = 0;
|
|
pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].lParam = 100;
|
|
|
|
|
|
//
|
|
//Allows You to apply Customised help to this Control.
|
|
//
|
|
//Notes:
|
|
// You must use a fully qualified path for pHelpFile
|
|
// OPTITEM Flags member must have OPTIF_HAS_POIEXT flag set. This indicates that the data in OIEXT is valid.
|
|
// OPTITEM is allocated on the Heap see (AddCustomUIHelp, GetHelpFile, CreateOIExt)
|
|
//
|
|
AddCustomUIHelp (pOEMUIParam->hPrinter,
|
|
pOEMUIParam->hOEMHeap,
|
|
pOEMUIParam->hModule,
|
|
&(pOEMUIParam->pOEMOptItems[0]),
|
|
CUSDRV_HELPTOPIC_2, IDS_HELPFILE);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initializes OptItems to display OEM printer property UI.
|
|
//
|
|
static HRESULT hrPrinterPropertyPage(DWORD dwMode, POEMCUIPPARAM pOEMUIParam)
|
|
{
|
|
if(NULL == pOEMUIParam->pOEMOptItems)
|
|
{
|
|
// Fill in the number of OptItems to create for OEM printer property UI.
|
|
pOEMUIParam->cOEMOptItems = 1;
|
|
|
|
VERBOSE(DLLTEXT("hrPrinterPropertyPage() requesting %d number of items.\r\n"), pOEMUIParam->cOEMOptItems);
|
|
}
|
|
else
|
|
{
|
|
//
|
|
//This is the second time we are called Now setup the optional items.
|
|
//
|
|
DWORD dwError;
|
|
DWORD dwDeviceValue;
|
|
DWORD dwType;
|
|
DWORD dwNeeded;
|
|
|
|
|
|
VERBOSE(DLLTEXT("hrPrinterPropertyPage() fill out %d items.\r\n"), pOEMUIParam->cOEMOptItems);
|
|
|
|
// Get device settings value from printer.
|
|
dwError = GetPrinterData(pOEMUIParam->hPrinter, OEMUI_VALUE, &dwType, (PBYTE) &dwDeviceValue,
|
|
sizeof(dwDeviceValue), &dwNeeded);
|
|
if( (ERROR_SUCCESS != dwError)
|
|
||
|
|
(dwDeviceValue > 100)
|
|
)
|
|
{
|
|
// Failed to get the device value or value is invalid, just use the default.
|
|
dwDeviceValue = 0;
|
|
}
|
|
|
|
// Init UI Callback reference.
|
|
pOEMUIParam->OEMCUIPCallback = OEMPrinterUICallBack;
|
|
|
|
// Init OEMOptItmes.
|
|
InitOptItems(pOEMUIParam->pOEMOptItems, pOEMUIParam->cOEMOptItems);
|
|
|
|
// Fill out tree view items.
|
|
|
|
// New section.
|
|
pOEMUIParam->pOEMOptItems[0].Level = 1;
|
|
pOEMUIParam->pOEMOptItems[0].Flags = OPTIF_COLLAPSE;
|
|
pOEMUIParam->pOEMOptItems[0].pName = GetStringResource(pOEMUIParam->hOEMHeap, pOEMUIParam->hModule, IDS_DEV_SECTION);
|
|
pOEMUIParam->pOEMOptItems[0].Sel = dwDeviceValue;
|
|
|
|
pOEMUIParam->pOEMOptItems[0].pOptType = CreateOptType(pOEMUIParam->hOEMHeap, 2);
|
|
|
|
//
|
|
//Setup the Optional Item
|
|
//
|
|
pOEMUIParam->pOEMOptItems[0].pOptType->Type = TVOT_UDARROW;
|
|
pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].IconID = 0;
|
|
pOEMUIParam->pOEMOptItems[0].pOptType->pOptParam[1].lParam = 100;
|
|
|
|
//
|
|
//Allows You to apply Customised help to this Control
|
|
//
|
|
AddCustomUIHelp (pOEMUIParam->hPrinter,
|
|
pOEMUIParam->hOEMHeap,
|
|
pOEMUIParam->hModule,
|
|
&(pOEMUIParam->pOEMOptItems[0]),
|
|
CUSDRV_HELPTOPIC_1,
|
|
IDS_HELPFILE);
|
|
}
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Adds property page to Document property sheet. Called via IOemUI::DocumentPropertySheets
|
|
//
|
|
HRESULT hrOEMDocumentPropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam,
|
|
IPrintOemDriverUI* pOEMHelp)
|
|
{
|
|
LONG_PTR lResult;
|
|
|
|
|
|
VERBOSE(DLLTEXT("OEMDocumentPropertySheets() entry.\r\n"));
|
|
|
|
// Validate parameters.
|
|
if( (NULL == pPSUIInfo)
|
|
||
|
|
(PROPSHEETUI_INFO_VERSION != pPSUIInfo->Version)
|
|
)
|
|
{
|
|
ERR(ERRORTEXT("OEMDocumentPropertySheets() ERROR_INVALID_PARAMETER.\r\n"));
|
|
|
|
// Return invalid parameter error.
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return E_FAIL;
|
|
}
|
|
|
|
// Do action.
|
|
switch(pPSUIInfo->Reason)
|
|
{
|
|
case PROPSHEETUI_REASON_INIT:
|
|
{
|
|
DWORD dwSheets = 0;
|
|
PCBUSERDATA pUserData;
|
|
POEMUIPSPARAM pOEMUIParam = (POEMUIPSPARAM) pPSUIInfo->lParamInit;
|
|
HANDLE hHeap = pOEMUIParam->hOEMHeap;
|
|
HANDLE hModule = pOEMUIParam->hModule;
|
|
POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
|
|
COMPROPSHEETUI Sheet;
|
|
|
|
|
|
// Init property page.
|
|
memset(&Sheet, 0, sizeof(COMPROPSHEETUI));
|
|
Sheet.cbSize = sizeof(COMPROPSHEETUI);
|
|
Sheet.Flags = CPSUIF_UPDATE_PERMISSION;
|
|
Sheet.hInstCaller = ghInstance;
|
|
Sheet.pCallerName = GetStringResource(hHeap, ghInstance, IDS_NAME);
|
|
Sheet.pHelpFile = NULL;
|
|
Sheet.pfnCallBack = OEMDocUICallBack2;
|
|
Sheet.pDlgPage = CPSUI_PDLGPAGE_TREEVIEWONLY;
|
|
Sheet.cOptItem = 1;
|
|
Sheet.IconID = IDI_CPSUI_PRINTER;
|
|
Sheet.pOptItemName = GetStringResource(hHeap, ghInstance, IDS_SECTION);
|
|
Sheet.CallerVersion = 0x100;
|
|
Sheet.OptItemVersion = 0x100;
|
|
|
|
// Init user data.
|
|
pUserData = (PCBUSERDATA) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(CBUSERDATA));
|
|
pUserData->hComPropSheet = pPSUIInfo->hComPropSheet;
|
|
pUserData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
|
|
pUserData->pOEMUIParam = pOEMUIParam;
|
|
Sheet.UserData = (ULONG_PTR) pUserData;
|
|
|
|
// Create OptItems for page.
|
|
Sheet.pOptItem = CreateOptItems(hHeap, Sheet.cOptItem);
|
|
|
|
// Initialize OptItems
|
|
Sheet.pOptItem[0].Level = 1;
|
|
Sheet.pOptItem[0].Flags = OPTIF_COLLAPSE;
|
|
Sheet.pOptItem[0].pName = GetStringResource(hHeap, ghInstance, IDS_SECTION);
|
|
Sheet.pOptItem[0].Sel = pOEMDev->dwDriverData;
|
|
|
|
Sheet.pOptItem[0].pOptType = CreateOptType(hHeap, 2);
|
|
|
|
//
|
|
//Set the UI prop of this OPTYPE item.
|
|
//
|
|
Sheet.pOptItem[0].pOptType->Type = TVOT_UDARROW;
|
|
Sheet.pOptItem[0].pOptType->pOptParam[1].IconID = 0;
|
|
Sheet.pOptItem[0].pOptType->pOptParam[1].lParam = 100;
|
|
|
|
//
|
|
//Allows You to apply Customised help to this Control.
|
|
//See Function : AddCustomUIHelp, For more details on implamentation.
|
|
//
|
|
AddCustomUIHelp (pOEMUIParam->hPrinter,
|
|
hHeap,
|
|
hModule,
|
|
&(Sheet.pOptItem[0]),
|
|
CUSDRV_HELPTOPIC_1,
|
|
IDS_HELPFILE);
|
|
|
|
// Adds the property sheets.
|
|
lResult = pPSUIInfo->pfnComPropSheet(pPSUIInfo->hComPropSheet, CPSFUNC_ADD_PCOMPROPSHEETUI,
|
|
(LPARAM)&Sheet, (LPARAM)&dwSheets);
|
|
}
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_GET_INFO_HEADER:
|
|
{
|
|
PPROPSHEETUI_INFO_HEADER pHeader = (PPROPSHEETUI_INFO_HEADER) lParam;
|
|
|
|
pHeader->pTitle = (LPTSTR)PROP_TITLE;
|
|
lResult = TRUE;
|
|
}
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_GET_ICON:
|
|
// No icon
|
|
lResult = 0;
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_SET_RESULT:
|
|
{
|
|
PSETRESULT_INFO pInfo = (PSETRESULT_INFO) lParam;
|
|
|
|
lResult = pInfo->Result;
|
|
}
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_DESTROY:
|
|
lResult = TRUE;
|
|
break;
|
|
}
|
|
|
|
pPSUIInfo->Result = lResult;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Adds property page to printer property sheet. Called via IOemUI::DevicePropertySheets
|
|
//
|
|
HRESULT hrOEMDevicePropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam)
|
|
{
|
|
LONG_PTR lResult;
|
|
|
|
|
|
VERBOSE(DLLTEXT("hrOEMDevicePropertySheets(%#x, %#x) entry\r\n"), pPSUIInfo, lParam);
|
|
|
|
// Validate parameters.
|
|
if( (NULL == pPSUIInfo)
|
|
||
|
|
(PROPSHEETUI_INFO_VERSION != pPSUIInfo->Version)
|
|
)
|
|
{
|
|
ERR(ERRORTEXT("hrOEMDevicePropertySheets() ERROR_INVALID_PARAMETER.\r\n"));
|
|
|
|
// Return invalid parameter error.
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
return E_FAIL;
|
|
}
|
|
|
|
Dump(pPSUIInfo);
|
|
|
|
// Do action.
|
|
switch(pPSUIInfo->Reason)
|
|
{
|
|
case PROPSHEETUI_REASON_INIT:
|
|
{
|
|
PROPSHEETPAGE Page;
|
|
|
|
// Init property page.
|
|
memset(&Page, 0, sizeof(PROPSHEETPAGE));
|
|
Page.dwSize = sizeof(PROPSHEETPAGE);
|
|
Page.dwFlags = PSP_DEFAULT;
|
|
Page.hInstance = ghInstance;
|
|
Page.pszTemplate = MAKEINTRESOURCE(IDD_DEVICE_PROPPAGE);
|
|
Page.pfnDlgProc = DevicePropPageProc;
|
|
|
|
// Add property sheets.
|
|
lResult = pPSUIInfo->pfnComPropSheet(pPSUIInfo->hComPropSheet, CPSFUNC_ADD_PROPSHEETPAGE, (LPARAM)&Page, 0);
|
|
|
|
VERBOSE(DLLTEXT("hrOEMDevicePropertySheets() pfnComPropSheet returned %d.\r\n"), lResult);
|
|
}
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_GET_INFO_HEADER:
|
|
{
|
|
PPROPSHEETUI_INFO_HEADER pHeader = (PPROPSHEETUI_INFO_HEADER) lParam;
|
|
|
|
pHeader->pTitle = (LPTSTR)PROP_TITLE;
|
|
lResult = TRUE;
|
|
}
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_GET_ICON:
|
|
// No icon
|
|
lResult = 0;
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_SET_RESULT:
|
|
{
|
|
PSETRESULT_INFO pInfo = (PSETRESULT_INFO) lParam;
|
|
|
|
lResult = pInfo->Result;
|
|
}
|
|
break;
|
|
|
|
case PROPSHEETUI_REASON_DESTROY:
|
|
lResult = TRUE;
|
|
break;
|
|
}
|
|
|
|
pPSUIInfo->Result = lResult;
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OptItems call back for OEM printer property UI.
|
|
//
|
|
LONG APIENTRY OEMPrinterUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam)
|
|
{
|
|
LONG lReturn = CPSUICB_ACTION_NONE;
|
|
POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
|
|
|
|
|
|
VERBOSE(DLLTEXT("OEMPrinterUICallBack() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
|
|
|
|
switch(pCallbackParam->Reason)
|
|
{
|
|
case CPSUICB_REASON_APPLYNOW:
|
|
{
|
|
DWORD dwDriverValue = pOEMUIParam->pOEMOptItems[0].Sel;
|
|
|
|
// Store OptItems state in printer data.
|
|
SetPrinterData(pOEMUIParam->hPrinter, OEMUI_VALUE, REG_DWORD, (PBYTE) &dwDriverValue, sizeof(DWORD));
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return lReturn;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Call back for OEM device property UI.
|
|
//
|
|
INT_PTR CALLBACK DevicePropPageProc(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (uiMsg)
|
|
{
|
|
case WM_COMMAND:
|
|
switch(HIWORD(wParam))
|
|
{
|
|
case BN_CLICKED:
|
|
switch(LOWORD(wParam))
|
|
{
|
|
case IDC_CALIBRATE:
|
|
// Just display a message that the printer is calibrated,
|
|
// since we don't acutally calibrate anything.
|
|
{
|
|
TCHAR szName[MAX_PATH];
|
|
TCHAR szCalibrated[MAX_PATH];
|
|
|
|
|
|
LoadString(ghInstance, IDS_NAME, szName, sizeof(szName)/sizeof(szName[0]));
|
|
LoadString(ghInstance, IDS_CALIBRATED, szCalibrated, sizeof(szCalibrated)/sizeof(szCalibrated[0]));
|
|
MessageBox(hDlg, szCalibrated, szName, MB_OK);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
|
|
case WM_NOTIFY:
|
|
{
|
|
switch (((LPNMHDR)lParam)->code) // type of notification message
|
|
{
|
|
case PSN_SETACTIVE:
|
|
break;
|
|
|
|
case PSN_KILLACTIVE:
|
|
break;
|
|
|
|
case PSN_APPLY:
|
|
break;
|
|
|
|
case PSN_RESET:
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OptItems call back for OEM document property UI.
|
|
//
|
|
LONG APIENTRY OEMDocUICallBack(PCPSUICBPARAM pCallbackParam, POEMCUIPPARAM pOEMUIParam)
|
|
{
|
|
LONG lReturn = CPSUICB_ACTION_NONE;
|
|
POEMDEV pOEMDev = (POEMDEV) pOEMUIParam->pOEMDM;
|
|
|
|
|
|
VERBOSE(DLLTEXT("OEMDocUICallBack() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
|
|
|
|
switch(pCallbackParam->Reason)
|
|
{
|
|
case CPSUICB_REASON_APPLYNOW:
|
|
// Store OptItems state in DEVMODE.
|
|
pOEMDev->dwAdvancedData = pOEMUIParam->pOEMOptItems[0].Sel;
|
|
break;
|
|
|
|
case CPSUICB_REASON_KILLACTIVE:
|
|
pOEMDev->dwAdvancedData = pOEMUIParam->pOEMOptItems[0].Sel;
|
|
break;
|
|
|
|
case CPSUICB_REASON_SETACTIVE:
|
|
if(pOEMUIParam->pOEMOptItems[0].Sel != pOEMDev->dwAdvancedData)
|
|
{
|
|
pOEMUIParam->pOEMOptItems[0].Sel = pOEMDev->dwAdvancedData;
|
|
pOEMUIParam->pOEMOptItems[0].Flags |= OPTIF_CHANGED;
|
|
lReturn = CPSUICB_ACTION_OPTIF_CHANGED;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return lReturn;
|
|
}
|
|
|
|
|
|
LONG APIENTRY OEMDocUICallBack2(PCPSUICBPARAM pCallbackParam)
|
|
{
|
|
LONG lReturn = CPSUICB_ACTION_NONE;
|
|
PCBUSERDATA pUserData = (PCBUSERDATA) pCallbackParam->UserData;
|
|
POEMDEV pOEMDev = (POEMDEV) pUserData->pOEMUIParam->pOEMDM;
|
|
|
|
|
|
VERBOSE(DLLTEXT("OEMDocUICallBack2() entry, Reason is %d.\r\n"), pCallbackParam->Reason);
|
|
|
|
switch(pCallbackParam->Reason)
|
|
{
|
|
case CPSUICB_REASON_APPLYNOW:
|
|
pOEMDev->dwDriverData = pCallbackParam->pOptItem[0].Sel;
|
|
pUserData->pfnComPropSheet(pUserData->hComPropSheet, CPSFUNC_SET_RESULT,
|
|
(LPARAM)pUserData->hPropPage,
|
|
(LPARAM)CPSUI_OK);
|
|
break;
|
|
|
|
case CPSUICB_REASON_KILLACTIVE:
|
|
pOEMDev->dwDriverData = pCallbackParam->pOptItem[0].Sel;
|
|
break;
|
|
|
|
case CPSUICB_REASON_SETACTIVE:
|
|
if(pCallbackParam->pOptItem[0].Sel != pOEMDev->dwDriverData)
|
|
{
|
|
pCallbackParam->pOptItem[0].Sel = pOEMDev->dwDriverData;
|
|
pCallbackParam->pOptItem[0].Flags |= OPTIF_CHANGED;
|
|
lReturn = CPSUICB_ACTION_OPTIF_CHANGED;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return lReturn;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Creates and Initializes OptItems.
|
|
//
|
|
static POPTITEM CreateOptItems(HANDLE hHeap, DWORD dwOptItems)
|
|
{
|
|
POPTITEM pOptItems = NULL;
|
|
|
|
|
|
// Allocate memory for OptItems;
|
|
pOptItems = (POPTITEM) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(OPTITEM) * dwOptItems);
|
|
if(NULL != pOptItems)
|
|
{
|
|
InitOptItems(pOptItems, dwOptItems);
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("CreateOptItems() failed to allocate memory for OPTITEMs!\r\n"));
|
|
}
|
|
|
|
return pOptItems;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Initializes OptItems.
|
|
//
|
|
static void InitOptItems(POPTITEM pOptItems, DWORD dwOptItems)
|
|
{
|
|
VERBOSE(DLLTEXT("InitOptItems() entry.\r\n"));
|
|
|
|
// Zero out memory.
|
|
memset(pOptItems, 0, sizeof(OPTITEM) * dwOptItems);
|
|
|
|
// Set each OptItem's size, and Public DM ID.
|
|
for(DWORD dwCount = 0; dwCount < dwOptItems; dwCount++)
|
|
{
|
|
pOptItems[dwCount].cbSize = sizeof(OPTITEM);
|
|
pOptItems[dwCount].DMPubID = DMPUB_NONE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Adds Custom help top a OPTTYPE UI item.
|
|
//
|
|
// Note :
|
|
// The OPTITEM member HelpIndex must be set the the correct HELP ID number.
|
|
// HelpIndex is the index that you assigned in the hlp file to this item of help.
|
|
// The OPTITEM, pOIExt member must point to a valid OIEXT structure.
|
|
// The phelpfile is member of OIEXT must have the fully qualified path to the driver file.
|
|
//
|
|
//
|
|
// It is also possible to overide common help items in UNIDRIVE via the HelpIndex in the GPD.
|
|
// For further information on using HelpIndex in the GPD see the relavent section in the DDK
|
|
// It is not possible to custimse help however via the PPD. The OPTITEM must be modified in the OEM Plugin.
|
|
//
|
|
static BOOL AddCustomUIHelp (HANDLE hPrinter, HANDLE hHeap, HANDLE hModule,
|
|
POPTITEM pOptItem, DWORD HelpIndex, DWORD HelpFile)
|
|
{
|
|
|
|
VERBOSE(DLLTEXT("AddCustomUIHelp() entry.\r\n"));
|
|
POIEXT pOIExt = NULL;
|
|
|
|
//
|
|
//Allocate a new OIEXT structure on the heap
|
|
//
|
|
if (pOptItem->pOIExt == NULL)
|
|
{
|
|
pOptItem->pOIExt = CreateOIExt(hHeap);
|
|
}
|
|
|
|
if ( pOptItem->pOIExt == NULL )
|
|
{
|
|
ERR(ERRORTEXT("AddCustomUIHelp() Error Allocation Failed.\r\n"));
|
|
return FALSE;
|
|
}
|
|
|
|
pOIExt = pOptItem->pOIExt;
|
|
|
|
//
|
|
//Set to the full absolute path of the driver file.
|
|
//(It should be in the Printer Driver Directrory in most cases)
|
|
//This String needs to be allocated on the heap (The Driver will clean it up).
|
|
//
|
|
pOIExt->pHelpFile = GetHelpFile (hPrinter, hHeap, hModule, HelpFile);
|
|
|
|
//
|
|
//Set to show tha there is a valid OIEXT structure and data
|
|
//
|
|
pOptItem->Flags |= OPTIF_HAS_POIEXT;
|
|
|
|
//
|
|
//This needs to be set if you have ansi strings in your help file. (NOTE!)
|
|
//
|
|
//pOiExt->Flags |= OIEXTF_ANSI_STRING;
|
|
|
|
//
|
|
//Add the help this the index in the .hlp file.
|
|
//
|
|
pOptItem->HelpIndex = HelpIndex;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Allocates and initializes OIEXT for OptItem.
|
|
//
|
|
static POIEXT CreateOIExt(HANDLE hHeap)
|
|
{
|
|
|
|
POIEXT pOiExt = NULL;
|
|
|
|
VERBOSE(DLLTEXT("CreateOIExt() entry.\r\n"));
|
|
|
|
// Allocate memory from the heap for the OPTTYPE; the driver will take care of clean up.
|
|
pOiExt = (POIEXT) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(OIEXT));
|
|
if(NULL != pOiExt)
|
|
{
|
|
//
|
|
// Initialize OPTTYPE. (These members are setup by AddCustomUIHelp)
|
|
//
|
|
pOiExt->cbSize = sizeof(OIEXT);
|
|
pOiExt->Flags = 0;
|
|
pOiExt->hInstCaller = NULL;
|
|
pOiExt->pHelpFile = NULL;
|
|
}
|
|
|
|
return pOiExt;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Allocates and initializes OptType for OptItem.
|
|
//
|
|
static POPTTYPE CreateOptType(HANDLE hHeap, WORD wOptParams)
|
|
{
|
|
POPTTYPE pOptType = NULL;
|
|
|
|
|
|
VERBOSE(DLLTEXT("CreateOptType() entry.\r\n"));
|
|
|
|
// Allocate memory from the heap for the OPTTYPE; the driver will take care of clean up.
|
|
pOptType = (POPTTYPE) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(OPTTYPE));
|
|
if(NULL != pOptType)
|
|
{
|
|
// Initialize OPTTYPE.
|
|
pOptType->cbSize = sizeof(OPTTYPE);
|
|
pOptType->Count = wOptParams;
|
|
|
|
// Allocate memory from the heap for the OPTPARAMs for the OPTTYPE.
|
|
pOptType->pOptParam = (POPTPARAM) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, wOptParams * sizeof(OPTPARAM));
|
|
if(NULL != pOptType->pOptParam)
|
|
{
|
|
// Initialize the OPTPARAMs.
|
|
for(WORD wCount = 0; wCount < wOptParams; wCount++)
|
|
{
|
|
pOptType->pOptParam[wCount].cbSize = sizeof(OPTPARAM);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("CreateOptType() failed to allocated memory for OPTPARAMs!\r\n"));
|
|
|
|
// Free allocated memory and return NULL.
|
|
HeapFree(hHeap, 0, pOptType);
|
|
pOptType = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("CreateOptType() failed to allocated memory for OPTTYPE!\r\n"));
|
|
}
|
|
|
|
return pOptType;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Allocates space on the heap and gets the help file name from the resource file.
|
|
// Note you need to allocate this on the heap so that it stays allocated as long as the driver UI is loaded.
|
|
// The OPTITEM->pOIExt ref this data.
|
|
//
|
|
static PTSTR GetHelpFile (HANDLE hPrinter, HANDLE hHeap, HANDLE hModule, UINT uResource)
|
|
{
|
|
|
|
DWORD nResult = 0;
|
|
DWORD dwSize = MAX_PATH;
|
|
PTSTR pszString = NULL;
|
|
PTSTR pszTemp = NULL;
|
|
PDRIVER_INFO_2 pDriverInfo = NULL;
|
|
|
|
VERBOSE(DLLTEXT("GetHelpFile (%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
|
|
|
|
//
|
|
// Allocate buffer for string resource from heap;
|
|
//
|
|
pszTemp = (PTSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(TCHAR));
|
|
pDriverInfo = (PDRIVER_INFO_2)WrapGetPrinterDriver (hHeap, hPrinter, 2);
|
|
|
|
//
|
|
//Get the Full Driver Dir from pDriverPath it must include the \version\
|
|
//
|
|
if(NULL != pszTemp && pDriverInfo && pDriverInfo->pDriverPath)
|
|
{
|
|
HRESULT hCopy;
|
|
|
|
hCopy = StringCchCopy(pszTemp, dwSize, pDriverInfo->pDriverPath);
|
|
if(FAILED(hCopy))
|
|
{
|
|
ERR(ERRORTEXT("StringCchCopy() failed to copy driver path to temp buffer!\r\n"));
|
|
}
|
|
pszString = _tcsrchr (pszTemp, _T('\\') ) + 1;
|
|
}
|
|
|
|
//
|
|
//The Help file is installed with the driver in the version drictory.
|
|
//
|
|
if(NULL != pszString)
|
|
{
|
|
//
|
|
//The Buffer size is in characters for the unicode version of LoadString
|
|
//
|
|
nResult = LoadString((HMODULE)hModule, uResource, pszString, (dwSize - _tcslen(pszTemp)) );
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
|
|
}
|
|
|
|
if(nResult > 0)
|
|
{
|
|
//
|
|
//Reallocate this so that we don't waist space on the heap (free any non used heap in MAX_PATH)
|
|
//
|
|
pszString = (PTSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszTemp, (_tcslen(pszTemp) + 1) * sizeof(TCHAR));
|
|
if(NULL == pszString)
|
|
{
|
|
pszTemp = pszString;
|
|
ERR(ERRORTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
|
|
ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
|
|
pszString = NULL;
|
|
}
|
|
|
|
//
|
|
//Clean up the Driverinfo that was allocated. It is not needed. (Always free this it is only temp data)
|
|
//
|
|
if (pDriverInfo)
|
|
{
|
|
HeapFree(hHeap, 0, pDriverInfo);
|
|
}
|
|
|
|
return pszString;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Retrieves pointer to a String resource.
|
|
//
|
|
static PTSTR GetStringResource(HANDLE hHeap, HANDLE hModule, UINT uResource)
|
|
{
|
|
int nResult;
|
|
DWORD dwSize = MAX_PATH;
|
|
PTSTR pszString = NULL;
|
|
|
|
|
|
VERBOSE(DLLTEXT("GetStringResource(%#x, %#x, %d) entered.\r\n"), hHeap, hModule, uResource);
|
|
|
|
// Allocate buffer for string resource from heap; let the driver clean it up.
|
|
pszString = (PTSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwSize * sizeof(TCHAR));
|
|
if(NULL != pszString)
|
|
{
|
|
// Load string resource; resize after loading so as not to waste memory.
|
|
nResult = LoadString((HMODULE)hModule, uResource, pszString, dwSize);
|
|
if(nResult > 0)
|
|
{
|
|
PTSTR pszTemp;
|
|
|
|
|
|
VERBOSE(DLLTEXT("LoadString() returned %d!\r\n"), nResult);
|
|
VERBOSE(DLLTEXT("String load was \"%s\".\r\n"), pszString);
|
|
|
|
pszTemp = (PTSTR) HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, pszString, (nResult + 1) * sizeof(TCHAR));
|
|
if(NULL != pszTemp)
|
|
{
|
|
pszString = pszTemp;
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("GetStringResource() HeapReAlloc() of string retrieved failed! (Last Error was %d)\r\n"), GetLastError());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("LoadString() returned %d! (Last Error was %d)\r\n"), nResult, GetLastError());
|
|
ERR(ERRORTEXT("GetStringResource() failed to load string resource %d!\r\n"), uResource);
|
|
|
|
pszString = NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ERR(ERRORTEXT("GetStringResource() failed to allocate string buffer!\r\n"));
|
|
}
|
|
|
|
return pszString;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Wrapper to help retrive the PrinterDriverInfo,
|
|
// Note the MEM is orphaned by this call on success
|
|
//
|
|
|
|
LPBYTE WrapGetPrinterDriver (HANDLE hHeap, HANDLE hPrinter, DWORD dwLevel)
|
|
{
|
|
//
|
|
//Get the PrinterINFO so that we know where the driver help file is.
|
|
//
|
|
BOOL bGet = TRUE;
|
|
DWORD dwSize = 0;
|
|
DWORD dwNeeded = 0;
|
|
DWORD dwError = ERROR_SUCCESS;
|
|
DWORD dwLoop = 0;
|
|
LPBYTE pBuffer = NULL;
|
|
|
|
do
|
|
{
|
|
if(!bGet && (dwError == ERROR_INSUFFICIENT_BUFFER ) )
|
|
{
|
|
dwSize = dwNeeded;
|
|
|
|
if (pBuffer)
|
|
{
|
|
PBYTE pTemp;
|
|
|
|
|
|
pTemp = (LPBYTE)HeapReAlloc (hHeap, HEAP_ZERO_MEMORY, (LPVOID)pBuffer, dwSize);
|
|
if(NULL != pTemp)
|
|
{
|
|
pBuffer = pTemp;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pBuffer = (LPBYTE)HeapAlloc (hHeap, HEAP_ZERO_MEMORY, dwSize);
|
|
}
|
|
}
|
|
|
|
bGet = GetPrinterDriver(hPrinter, NULL, dwLevel, pBuffer, dwSize, &dwNeeded);
|
|
dwError = GetLastError();
|
|
|
|
} while (!bGet && (dwLoop++ < 4));
|
|
|
|
if(!bGet)
|
|
{
|
|
if (pBuffer)
|
|
{
|
|
HeapFree(hHeap, 0, pBuffer);
|
|
pBuffer = NULL;
|
|
}
|
|
ERR(ERRORTEXT("GetPrinterDriver(%p, %d, %p, %d) failed with error %d."),
|
|
hPrinter, dwLevel, pBuffer, dwError);
|
|
}
|
|
|
|
return pBuffer;
|
|
}
|