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.

566 lines
14 KiB

  1. /*++
  2. Copyright (c) 1996-2003 Microsoft Corporation
  3. Module Name:
  4. comoem.cpp
  5. Abstract:
  6. Implementation of OEMGetInfo and OEMDevMode.
  7. Shared by all Unidrv OEM test dll's.
  8. Environment:
  9. Windows 2000, Windows XP, Windows Server 2003
  10. Revision History:
  11. Created it.
  12. --*/
  13. #include "precomp.h"
  14. #include <INITGUID.H>
  15. #include <PRCOMOEM.H>
  16. #include "oemui.h"
  17. #include "debug.h"
  18. #include "intrface.h"
  19. // StrSafe.h needs to be included last
  20. // to disallow bad string functions.
  21. #include <STRSAFE.H>
  22. ////////////////////////////////////////////////////////
  23. // Internal Globals
  24. ////////////////////////////////////////////////////////
  25. static long g_cComponents = 0 ; // Count of active components
  26. static long g_cServerLocks = 0 ; // Count of locks
  27. ////////////////////////////////////////////////////////////////////////////////
  28. //
  29. // IOemUI body
  30. //
  31. IOemUI::~IOemUI()
  32. {
  33. // Make sure that helper interface is released.
  34. if(NULL != m_pOEMHelp)
  35. {
  36. m_pOEMHelp->Release();
  37. m_pOEMHelp = NULL;
  38. }
  39. // If this instance of the object is being deleted, then the reference
  40. // count should be zero.
  41. assert(0 == m_cRef);
  42. }
  43. HRESULT __stdcall IOemUI::QueryInterface(const IID& iid, void** ppv)
  44. {
  45. VERBOSE(DLLTEXT("IOemUI:QueryInterface entry.\r\n\r\n"));
  46. if (iid == IID_IUnknown)
  47. {
  48. *ppv = static_cast<IUnknown*>(this);
  49. VERBOSE(DLLTEXT("IOemUI:Return pointer to IUnknown.\r\n\r\n"));
  50. }
  51. else if (iid == IID_IPrintOemUI)
  52. {
  53. *ppv = static_cast<IPrintOemUI*>(this) ;
  54. VERBOSE(DLLTEXT("IOemUI:Return pointer to IPrintOemUI.\r\n"));
  55. }
  56. else
  57. {
  58. *ppv = NULL ;
  59. VERBOSE(DLLTEXT("IOemUI:No Interface. Return NULL.\r\n"));
  60. return E_NOINTERFACE ;
  61. }
  62. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  63. return S_OK ;
  64. }
  65. ULONG __stdcall IOemUI::AddRef()
  66. {
  67. VERBOSE(DLLTEXT("IOemUI:AddRef entry.\r\n"));
  68. return InterlockedIncrement(&m_cRef) ;
  69. }
  70. ULONG __stdcall IOemUI::Release()
  71. {
  72. VERBOSE(DLLTEXT("IOemUI:Release entry.\r\n"));
  73. ASSERT( 0 != m_cRef);
  74. ULONG cRef = InterlockedDecrement(&m_cRef);
  75. if (0 == cRef)
  76. {
  77. delete this;
  78. }
  79. return cRef;
  80. }
  81. //
  82. //(Implamentation is required) Supplies a pointer to UNIDRIVE /PScript IPrintOemDriverUI
  83. //
  84. HRESULT __stdcall IOemUI::PublishDriverInterface(
  85. IUnknown *pIUnknown)
  86. {
  87. VERBOSE(DLLTEXT("IOemUI:PublishDriverInterface entry.\r\n"));
  88. // Need to store pointer to Driver Helper functions, if we already haven't.
  89. if (m_pOEMHelp == NULL)
  90. {
  91. HRESULT hResult;
  92. // Get Interface to Helper Functions.
  93. hResult = pIUnknown->QueryInterface(IID_IPrintOemDriverUI, (void** ) &(m_pOEMHelp));
  94. if(!SUCCEEDED(hResult))
  95. {
  96. // Make sure that interface pointer reflects interface query failure.
  97. m_pOEMHelp = NULL;
  98. return E_FAIL;
  99. }
  100. }
  101. return S_OK;
  102. }
  103. //
  104. //(Implamentation is required) Returns the UI Plugin's identification information
  105. //
  106. HRESULT __stdcall IOemUI::GetInfo(
  107. DWORD dwMode,
  108. PVOID pBuffer,
  109. DWORD cbSize,
  110. PDWORD pcbNeeded)
  111. {
  112. VERBOSE(DLLTEXT("IOemUI::GetInfo(%d) entry.\r\r\n"), dwMode);
  113. // Validate parameters.
  114. if( (NULL == pcbNeeded)
  115. ||
  116. ( (OEMGI_GETSIGNATURE != dwMode)
  117. &&
  118. (OEMGI_GETVERSION != dwMode)
  119. &&
  120. (OEMGI_GETPUBLISHERINFO != dwMode)
  121. )
  122. )
  123. {
  124. WARNING(DLLTEXT("IOemUI::GetInfo() exit pcbNeeded is NULL! ERROR_INVALID_PARAMETER\r\r\n"));
  125. SetLastError(ERROR_INVALID_PARAMETER);
  126. return E_FAIL;
  127. }
  128. // Set expected buffer size and number of bytes written.
  129. *pcbNeeded = sizeof(DWORD);
  130. // Check buffer size is sufficient.
  131. if((cbSize < *pcbNeeded) || (NULL == pBuffer))
  132. {
  133. WARNING(DLLTEXT("IOemUI::GetInfo() exit insufficient buffer!\r\r\n"));
  134. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  135. return E_FAIL;
  136. }
  137. switch(dwMode)
  138. {
  139. // OEM DLL Signature
  140. case OEMGI_GETSIGNATURE:
  141. *(PDWORD)pBuffer = OEM_SIGNATURE;
  142. break;
  143. // OEM DLL version
  144. case OEMGI_GETVERSION:
  145. *(PDWORD)pBuffer = OEM_VERSION;
  146. break;
  147. // dwMode not supported.
  148. default:
  149. // Set written bytes to zero since nothing was written.
  150. WARNING(DLLTEXT("IOemUI::GetInfo() exit mode not supported.\r\r\n"));
  151. *pcbNeeded = 0;
  152. SetLastError(ERROR_NOT_SUPPORTED);
  153. return E_FAIL;
  154. }
  155. VERBOSE(DLLTEXT("IOemUI::GetInfo() exit S_OK, (*pBuffer is %#x).\r\r\n"), *(PDWORD)pBuffer);
  156. return S_OK;
  157. }
  158. //
  159. //Performs operation on UI Plugins Private DevMode Members.
  160. //
  161. HRESULT __stdcall IOemUI::DevMode(
  162. DWORD dwMode,
  163. POEMDMPARAM pOemDMParam)
  164. {
  165. VERBOSE(DLLTEXT("IOemUI:DevMode(%d, %#x) entry.\r\n"), dwMode, pOemDMParam);
  166. return hrOEMDevMode(dwMode, pOemDMParam);
  167. }
  168. //
  169. //Allows UI Plugin to Modifiy Existing printer porp sheet and document property sheet page..
  170. //
  171. HRESULT __stdcall IOemUI::CommonUIProp(
  172. DWORD dwMode,
  173. POEMCUIPPARAM pOemCUIPParam)
  174. {
  175. VERBOSE(DLLTEXT("IOemUI:CommonUIProp entry.\r\n"));
  176. //
  177. //We want to keep this pointer so the we can modifie the data and OPTITEMS from the OEM plugin page.
  178. //
  179. m_OemSheetData.pOEMCUIParam = pOemCUIPParam;
  180. return hrOEMPropertyPage(dwMode, pOemCUIPParam);
  181. }
  182. //
  183. //Adds a New page to the device Documment property sheet.
  184. //
  185. HRESULT __stdcall IOemUI::DocumentPropertySheets(
  186. PPROPSHEETUI_INFO pPSUIInfo,
  187. LPARAM lParam)
  188. {
  189. VERBOSE(DLLTEXT("IOemUI:DocumentPropertySheets entry.\r\n"));
  190. return hrOEMDocumentPropertySheets(pPSUIInfo, lParam, m_pOEMHelp);
  191. }
  192. //
  193. //Adds a New page to the device printer property page.
  194. //
  195. HRESULT __stdcall IOemUI::DevicePropertySheets(
  196. PPROPSHEETUI_INFO pPSUIInfo,
  197. LPARAM lParam)
  198. {
  199. VERBOSE(DLLTEXT("IOemUI:DevicePropertySheets entry.\r\n"));
  200. //
  201. //Store the This pointer in the OEMSHEETDATA
  202. //
  203. m_OemSheetData.pOEMHelp = m_pOEMHelp;
  204. return hrOEMDevicePropertySheets(pPSUIInfo, lParam, &(m_OemSheetData));
  205. }
  206. //
  207. //Allows the UI plugin to spec Customized device capabilaties (TODO)
  208. //
  209. HRESULT __stdcall IOemUI::DeviceCapabilities(
  210. POEMUIOBJ poemuiobj,
  211. HANDLE hPrinter,
  212. PWSTR pDeviceName,
  213. WORD wCapability,
  214. PVOID pOutput,
  215. PDEVMODE pPublicDM,
  216. PVOID pOEMDM,
  217. DWORD dwOld,
  218. DWORD *dwResult)
  219. {
  220. VERBOSE(DLLTEXT("IOemUI:DeviceCapabilities entry.\r\n"));
  221. return E_NOTIMPL;
  222. }
  223. //
  224. //Allows the UI plugin to help determine if a print Job is printable.
  225. //
  226. HRESULT __stdcall IOemUI::DevQueryPrintEx(
  227. POEMUIOBJ poemuiobj,
  228. PDEVQUERYPRINT_INFO pDQPInfo,
  229. PDEVMODE pPublicDM,
  230. PVOID pOEMDM)
  231. {
  232. VERBOSE(DLLTEXT("IOemUI:DevQueryPrintEx entry.\r\n"));
  233. return E_NOTIMPL;
  234. }
  235. //
  236. //Allows the UI Plugin to upgrade its dev options stored in the registry.
  237. //
  238. HRESULT __stdcall IOemUI::UpgradePrinter(
  239. DWORD dwLevel,
  240. PBYTE pDriverUpgradeInfo)
  241. {
  242. VERBOSE(DLLTEXT("IOemUI:UpgradePrinter entry.\r\n"));
  243. return E_NOTIMPL;
  244. }
  245. HRESULT __stdcall IOemUI::PrinterEvent(
  246. PWSTR pPrinterName,
  247. INT iDriverEvent,
  248. DWORD dwFlags,
  249. LPARAM lParam)
  250. {
  251. VERBOSE(DLLTEXT("IOemUI:PrinterEvent entry.\r\n"));
  252. return E_NOTIMPL;
  253. }
  254. HRESULT __stdcall IOemUI::DriverEvent(
  255. DWORD dwDriverEvent,
  256. DWORD dwLevel,
  257. LPBYTE pDriverInfo,
  258. LPARAM lParam)
  259. {
  260. VERBOSE(DLLTEXT("IOemUI:DriverEvent entry.\r\n"));
  261. return E_NOTIMPL;
  262. };
  263. #define PROFILE_NAME L"OEMPROFILE.icm\0"
  264. HRESULT __stdcall IOemUI::QueryColorProfile(
  265. HANDLE hPrinter,
  266. POEMUIOBJ poemuiobj,
  267. PDEVMODE pPublicDM,
  268. PVOID pOEMDM,
  269. ULONG ulQueryMode,
  270. VOID *pvProfileData,
  271. ULONG *pcbProfileData,
  272. FLONG *pflProfileData)
  273. {
  274. HRESULT Result = E_FAIL;
  275. VERBOSE(DLLTEXT("IOemUI:QueryColorProfile entry.\r\n"));
  276. if(QCP_DEVICEPROFILE == ulQueryMode)
  277. {
  278. if(NULL == pvProfileData)
  279. {
  280. *pcbProfileData = sizeof(PROFILE_NAME);
  281. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  282. }
  283. else
  284. {
  285. if(*pcbProfileData < sizeof(PROFILE_NAME))
  286. {
  287. *pcbProfileData = sizeof(PROFILE_NAME);
  288. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  289. }
  290. else
  291. {
  292. Result = StringCbCopy((LPWSTR)pvProfileData, *pcbProfileData, PROFILE_NAME);
  293. *pcbProfileData = sizeof(PROFILE_NAME);
  294. *pflProfileData = QCP_PROFILEDISK;
  295. if(FAILED(Result))
  296. {
  297. SetLastError(Result);
  298. }
  299. }
  300. }
  301. }
  302. return Result;
  303. };
  304. HRESULT __stdcall IOemUI::FontInstallerDlgProc(
  305. HWND hWnd,
  306. UINT usMsg,
  307. WPARAM wParam,
  308. LPARAM lParam)
  309. {
  310. VERBOSE(DLLTEXT("IOemUI:FontInstallerDlgProc entry.\r\n"));
  311. return E_NOTIMPL;
  312. };
  313. HRESULT __stdcall IOemUI::UpdateExternalFonts(
  314. HANDLE hPrinter,
  315. HANDLE hHeap,
  316. PWSTR pwstrCartridges)
  317. {
  318. VERBOSE(DLLTEXT("IOemUI:UpdateExternalFonts entry.\r\n"));
  319. return E_NOTIMPL;
  320. }
  321. ////////////////////////////////////////////////////////////////////////////////
  322. //
  323. // oem class factory
  324. //
  325. class IOemCF : public IClassFactory
  326. {
  327. public:
  328. // *** IUnknown methods ***
  329. STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj);
  330. STDMETHOD_(ULONG,AddRef) (THIS);
  331. STDMETHOD_(ULONG,Release) (THIS);
  332. // *** IClassFactory methods ***
  333. STDMETHOD(CreateInstance) (THIS_
  334. LPUNKNOWN pUnkOuter,
  335. REFIID riid,
  336. LPVOID FAR* ppvObject);
  337. STDMETHOD(LockServer) (THIS_ BOOL bLock);
  338. // Constructor
  339. IOemCF(): m_cRef(1) { };
  340. ~IOemCF() { };
  341. protected:
  342. LONG m_cRef;
  343. };
  344. ///////////////////////////////////////////////////////////
  345. //
  346. // Class factory body
  347. //
  348. HRESULT __stdcall IOemCF::QueryInterface(const IID& iid, void** ppv)
  349. {
  350. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  351. {
  352. *ppv = static_cast<IOemCF*>(this) ;
  353. }
  354. else
  355. {
  356. *ppv = NULL ;
  357. return E_NOINTERFACE ;
  358. }
  359. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  360. return S_OK ;
  361. }
  362. ULONG __stdcall IOemCF::AddRef()
  363. {
  364. return InterlockedIncrement(&m_cRef) ;
  365. }
  366. ULONG __stdcall IOemCF::Release()
  367. {
  368. ASSERT( 0 != m_cRef);
  369. ULONG cRef = InterlockedDecrement(&m_cRef);
  370. if (0 == cRef)
  371. {
  372. delete this;
  373. }
  374. return cRef;
  375. }
  376. // IClassFactory implementation
  377. HRESULT __stdcall IOemCF::CreateInstance(IUnknown* pUnknownOuter,
  378. const IID& iid,
  379. void** ppv)
  380. {
  381. //DbgPrint(DLLTEXT("Class factory:\t\tCreate component.")) ;
  382. // Cannot aggregate.
  383. if (pUnknownOuter != NULL)
  384. {
  385. return CLASS_E_NOAGGREGATION ;
  386. }
  387. // Create component.
  388. IOemUI* pOemCB = new IOemUI ;
  389. if (pOemCB == NULL)
  390. {
  391. return E_OUTOFMEMORY ;
  392. }
  393. // Get the requested interface.
  394. HRESULT hr = pOemCB->QueryInterface(iid, ppv) ;
  395. // Release the IUnknown pointer.
  396. // (If QueryInterface failed, component will delete itself.)
  397. pOemCB->Release() ;
  398. return hr ;
  399. }
  400. // LockServer
  401. HRESULT __stdcall IOemCF::LockServer(BOOL bLock)
  402. {
  403. if (bLock)
  404. {
  405. InterlockedIncrement(&g_cServerLocks) ;
  406. }
  407. else
  408. {
  409. InterlockedDecrement(&g_cServerLocks) ;
  410. }
  411. return S_OK ;
  412. }
  413. ///////////////////////////////////////////////////////////
  414. //
  415. // Exported functions
  416. //
  417. // Can DLL unload now?
  418. //
  419. STDAPI DllCanUnloadNow()
  420. {
  421. //
  422. // To avoid leaving OEM DLL still in memory when Unidrv or Pscript drivers
  423. // are unloaded, Unidrv and Pscript driver ignore the return value of
  424. // DllCanUnloadNow of the OEM DLL, and always call FreeLibrary on the OEMDLL.
  425. //
  426. // If OEM DLL spins off a working thread that also uses the OEM DLL, the
  427. // thread needs to call LoadLibrary and FreeLibraryAndExitThread, otherwise
  428. // it may crash after Unidrv or Pscript calls FreeLibrary.
  429. //
  430. if ((g_cComponents == 0) && (g_cServerLocks == 0))
  431. {
  432. return S_OK ;
  433. }
  434. else
  435. {
  436. return S_FALSE;
  437. }
  438. }
  439. //
  440. // Get class factory
  441. //
  442. STDAPI DllGetClassObject(const CLSID& clsid,
  443. const IID& iid,
  444. void** ppv)
  445. {
  446. VERBOSE(DLLTEXT("DllGetClassObject:Create class factory.\r\n"));
  447. // Can we create this component?
  448. if (clsid != CLSID_OEMUI)
  449. {
  450. return CLASS_E_CLASSNOTAVAILABLE ;
  451. }
  452. // Create class factory.
  453. IOemCF* pFontCF = new IOemCF ; // Reference count set to 1
  454. // in constructor
  455. if (pFontCF == NULL)
  456. {
  457. return E_OUTOFMEMORY ;
  458. }
  459. // Get requested interface.
  460. HRESULT hr = pFontCF->QueryInterface(iid, ppv) ;
  461. pFontCF->Release() ;
  462. return hr ;
  463. }