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.

558 lines
13 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. return hrOEMPropertyPage(dwMode, pOemCUIPParam);
  177. }
  178. //
  179. //Adds a New page to the device Documment property sheet.
  180. //
  181. HRESULT __stdcall IOemUI::DocumentPropertySheets(
  182. PPROPSHEETUI_INFO pPSUIInfo,
  183. LPARAM lParam)
  184. {
  185. VERBOSE(DLLTEXT("IOemUI:DocumentPropertySheets entry.\r\n"));
  186. return hrOEMDocumentPropertySheets(pPSUIInfo, lParam, m_pOEMHelp);
  187. }
  188. //
  189. //Adds a New page to the device printer property page.
  190. //
  191. HRESULT __stdcall IOemUI::DevicePropertySheets(
  192. PPROPSHEETUI_INFO pPSUIInfo,
  193. LPARAM lParam)
  194. {
  195. VERBOSE(DLLTEXT("IOemUI:DevicePropertySheets entry.\r\n"));
  196. return hrOEMDevicePropertySheets(pPSUIInfo, lParam);
  197. }
  198. //
  199. //Allows the UI plugin to spec Customized device capabilaties (TODO)
  200. //
  201. HRESULT __stdcall IOemUI::DeviceCapabilities(
  202. POEMUIOBJ poemuiobj,
  203. HANDLE hPrinter,
  204. PWSTR pDeviceName,
  205. WORD wCapability,
  206. PVOID pOutput,
  207. PDEVMODE pPublicDM,
  208. PVOID pOEMDM,
  209. DWORD dwOld,
  210. DWORD *dwResult)
  211. {
  212. VERBOSE(DLLTEXT("IOemUI:DeviceCapabilities entry.\r\n"));
  213. return E_NOTIMPL;
  214. }
  215. //
  216. //Allows the UI plugin to help determine if a print Job is printable.
  217. //
  218. HRESULT __stdcall IOemUI::DevQueryPrintEx(
  219. POEMUIOBJ poemuiobj,
  220. PDEVQUERYPRINT_INFO pDQPInfo,
  221. PDEVMODE pPublicDM,
  222. PVOID pOEMDM)
  223. {
  224. VERBOSE(DLLTEXT("IOemUI:DevQueryPrintEx entry.\r\n"));
  225. return E_NOTIMPL;
  226. }
  227. //
  228. //Allows the UI Plugin to upgrade its dev options stored in the registry.
  229. //
  230. HRESULT __stdcall IOemUI::UpgradePrinter(
  231. DWORD dwLevel,
  232. PBYTE pDriverUpgradeInfo)
  233. {
  234. VERBOSE(DLLTEXT("IOemUI:UpgradePrinter entry.\r\n"));
  235. return E_NOTIMPL;
  236. }
  237. HRESULT __stdcall IOemUI::PrinterEvent(
  238. PWSTR pPrinterName,
  239. INT iDriverEvent,
  240. DWORD dwFlags,
  241. LPARAM lParam)
  242. {
  243. VERBOSE(DLLTEXT("IOemUI:PrinterEvent entry.\r\n"));
  244. return E_NOTIMPL;
  245. }
  246. HRESULT __stdcall IOemUI::DriverEvent(
  247. DWORD dwDriverEvent,
  248. DWORD dwLevel,
  249. LPBYTE pDriverInfo,
  250. LPARAM lParam)
  251. {
  252. VERBOSE(DLLTEXT("IOemUI:DriverEvent entry.\r\n"));
  253. return E_NOTIMPL;
  254. };
  255. #define PROFILE_NAME L"OEMPROFILE.icm\0"
  256. HRESULT __stdcall IOemUI::QueryColorProfile(
  257. HANDLE hPrinter,
  258. POEMUIOBJ poemuiobj,
  259. PDEVMODE pPublicDM,
  260. PVOID pOEMDM,
  261. ULONG ulQueryMode,
  262. VOID *pvProfileData,
  263. ULONG *pcbProfileData,
  264. FLONG *pflProfileData)
  265. {
  266. HRESULT Result = E_FAIL;
  267. VERBOSE(DLLTEXT("IOemUI:QueryColorProfile entry.\r\n"));
  268. if(QCP_DEVICEPROFILE == ulQueryMode)
  269. {
  270. if(NULL == pvProfileData)
  271. {
  272. *pcbProfileData = sizeof(PROFILE_NAME);
  273. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  274. }
  275. else
  276. {
  277. if(*pcbProfileData < sizeof(PROFILE_NAME))
  278. {
  279. *pcbProfileData = sizeof(PROFILE_NAME);
  280. SetLastError(ERROR_INSUFFICIENT_BUFFER);
  281. }
  282. else
  283. {
  284. Result = StringCbCopy((LPWSTR)pvProfileData, *pcbProfileData, PROFILE_NAME);
  285. *pcbProfileData = sizeof(PROFILE_NAME);
  286. *pflProfileData = QCP_PROFILEDISK;
  287. if(FAILED(Result))
  288. {
  289. SetLastError(Result);
  290. }
  291. }
  292. }
  293. }
  294. return Result;
  295. };
  296. HRESULT __stdcall IOemUI::FontInstallerDlgProc(
  297. HWND hWnd,
  298. UINT usMsg,
  299. WPARAM wParam,
  300. LPARAM lParam)
  301. {
  302. VERBOSE(DLLTEXT("IOemUI:FontInstallerDlgProc entry.\r\n"));
  303. return E_NOTIMPL;
  304. };
  305. HRESULT __stdcall IOemUI::UpdateExternalFonts(
  306. HANDLE hPrinter,
  307. HANDLE hHeap,
  308. PWSTR pwstrCartridges)
  309. {
  310. VERBOSE(DLLTEXT("IOemUI:UpdateExternalFonts entry.\r\n"));
  311. return E_NOTIMPL;
  312. }
  313. ////////////////////////////////////////////////////////////////////////////////
  314. //
  315. // oem class factory
  316. //
  317. class IOemCF : public IClassFactory
  318. {
  319. public:
  320. // *** IUnknown methods ***
  321. STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR* ppvObj);
  322. STDMETHOD_(ULONG,AddRef) (THIS);
  323. STDMETHOD_(ULONG,Release) (THIS);
  324. // *** IClassFactory methods ***
  325. STDMETHOD(CreateInstance) (THIS_
  326. LPUNKNOWN pUnkOuter,
  327. REFIID riid,
  328. LPVOID FAR* ppvObject);
  329. STDMETHOD(LockServer) (THIS_ BOOL bLock);
  330. // Constructor
  331. IOemCF(): m_cRef(1) { };
  332. ~IOemCF() { };
  333. protected:
  334. LONG m_cRef;
  335. };
  336. ///////////////////////////////////////////////////////////
  337. //
  338. // Class factory body
  339. //
  340. HRESULT __stdcall IOemCF::QueryInterface(const IID& iid, void** ppv)
  341. {
  342. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  343. {
  344. *ppv = static_cast<IOemCF*>(this) ;
  345. }
  346. else
  347. {
  348. *ppv = NULL ;
  349. return E_NOINTERFACE ;
  350. }
  351. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  352. return S_OK ;
  353. }
  354. ULONG __stdcall IOemCF::AddRef()
  355. {
  356. return InterlockedIncrement(&m_cRef) ;
  357. }
  358. ULONG __stdcall IOemCF::Release()
  359. {
  360. ASSERT( 0 != m_cRef);
  361. ULONG cRef = InterlockedDecrement(&m_cRef);
  362. if (0 == cRef)
  363. {
  364. delete this;
  365. }
  366. return cRef;
  367. }
  368. // IClassFactory implementation
  369. HRESULT __stdcall IOemCF::CreateInstance(IUnknown* pUnknownOuter,
  370. const IID& iid,
  371. void** ppv)
  372. {
  373. //DbgPrint(DLLTEXT("Class factory:\t\tCreate component.")) ;
  374. // Cannot aggregate.
  375. if (pUnknownOuter != NULL)
  376. {
  377. return CLASS_E_NOAGGREGATION ;
  378. }
  379. // Create component.
  380. IOemUI* pOemCB = new IOemUI ;
  381. if (pOemCB == NULL)
  382. {
  383. return E_OUTOFMEMORY ;
  384. }
  385. // Get the requested interface.
  386. HRESULT hr = pOemCB->QueryInterface(iid, ppv) ;
  387. // Release the IUnknown pointer.
  388. // (If QueryInterface failed, component will delete itself.)
  389. pOemCB->Release() ;
  390. return hr ;
  391. }
  392. // LockServer
  393. HRESULT __stdcall IOemCF::LockServer(BOOL bLock)
  394. {
  395. if (bLock)
  396. {
  397. InterlockedIncrement(&g_cServerLocks) ;
  398. }
  399. else
  400. {
  401. InterlockedDecrement(&g_cServerLocks) ;
  402. }
  403. return S_OK ;
  404. }
  405. ///////////////////////////////////////////////////////////
  406. //
  407. // Exported functions
  408. //
  409. // Can DLL unload now?
  410. //
  411. STDAPI DllCanUnloadNow()
  412. {
  413. //
  414. // To avoid leaving OEM DLL still in memory when Unidrv or Pscript drivers
  415. // are unloaded, Unidrv and Pscript driver ignore the return value of
  416. // DllCanUnloadNow of the OEM DLL, and always call FreeLibrary on the OEMDLL.
  417. //
  418. // If OEM DLL spins off a working thread that also uses the OEM DLL, the
  419. // thread needs to call LoadLibrary and FreeLibraryAndExitThread, otherwise
  420. // it may crash after Unidrv or Pscript calls FreeLibrary.
  421. //
  422. if ((g_cComponents == 0) && (g_cServerLocks == 0))
  423. {
  424. return S_OK ;
  425. }
  426. else
  427. {
  428. return S_FALSE;
  429. }
  430. }
  431. //
  432. // Get class factory
  433. //
  434. STDAPI DllGetClassObject(const CLSID& clsid,
  435. const IID& iid,
  436. void** ppv)
  437. {
  438. VERBOSE(DLLTEXT("DllGetClassObject:Create class factory.\r\n"));
  439. // Can we create this component?
  440. if (clsid != CLSID_OEMUI)
  441. {
  442. return CLASS_E_CLASSNOTAVAILABLE ;
  443. }
  444. // Create class factory.
  445. IOemCF* pFontCF = new IOemCF ; // Reference count set to 1
  446. // in constructor
  447. if (pFontCF == NULL)
  448. {
  449. return E_OUTOFMEMORY ;
  450. }
  451. // Get requested interface.
  452. HRESULT hr = pFontCF->QueryInterface(iid, ppv) ;
  453. pFontCF->Release() ;
  454. return hr ;
  455. }