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.

1441 lines
26 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. comoem.cpp
  5. Abstract:
  6. Windows NT Universal Printer Driver OEM Plug-in Sample
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. Created it.
  11. --*/
  12. #include "pdev.h"
  13. #include "name.h"
  14. #include "code.c"
  15. #include <initguid.h>
  16. #include <prcomoem.h>
  17. #include <assert.h>
  18. #include "comoem.h"
  19. ///////////////////////////////////////////////////////////
  20. //
  21. // Globals
  22. //
  23. static HANDLE ghInstance = NULL ;
  24. static long g_cComponents = 0 ;
  25. static long g_cServerLocks = 0 ;
  26. ///////////////////////////////////////////////////////////
  27. //
  28. // Export functions
  29. //
  30. BOOL APIENTRY
  31. DllMain(
  32. HANDLE hInst,
  33. DWORD dwReason,
  34. void* lpReserved)
  35. /*++
  36. Routine Description:
  37. Dll entry point for initializatoin.
  38. Arguments:
  39. hInst - Dll instance handle
  40. wReason - The reason DllMain was called.
  41. Initialization or termination, for a process or a thread.
  42. lpreserved - Reserved for the system's use
  43. Return Value:
  44. TRUE if successful, FALSE if there is an error
  45. Note:
  46. --*/
  47. {
  48. switch(dwReason)
  49. {
  50. case DLL_PROCESS_ATTACH:
  51. DebugMsg(DLLTEXT("DLLMain: Process attach.\r\n"));
  52. //
  53. // Save DLL instance for use later.
  54. //
  55. ghInstance = hInst;
  56. break;
  57. case DLL_THREAD_ATTACH:
  58. DebugMsg(DLLTEXT("DLLMain: Thread attach.\r\n"));
  59. break;
  60. case DLL_PROCESS_DETACH:
  61. DebugMsg(DLLTEXT("DLLMain: Process detach.\r\n"));
  62. break;
  63. case DLL_THREAD_DETACH:
  64. DebugMsg(DLLTEXT("DLLMain: Thread detach.\r\n"));
  65. break;
  66. }
  67. return TRUE;
  68. }
  69. STDAPI
  70. DllCanUnloadNow()
  71. /*++
  72. Routine Description:
  73. Function to return the status that this dll can be unloaded.
  74. Arguments:
  75. Return Value:
  76. S_OK if it's ok to unload it, S_FALSE if it is used.
  77. Note:
  78. --*/
  79. {
  80. if ((g_cComponents == 0) && (g_cServerLocks == 0))
  81. {
  82. return S_OK ;
  83. }
  84. else
  85. {
  86. return S_FALSE ;
  87. }
  88. }
  89. STDAPI
  90. DllGetClassObject(
  91. const CLSID& clsid,
  92. const IID& iid,
  93. void** ppv)
  94. /*++
  95. Routine Description:
  96. Function to return class factory object
  97. Arguments:
  98. clsid - CLSID for the class object
  99. iid - Reference to the identifier of the interface that communic
  100. ppv - Indirect pointer to the communicating interface
  101. Note:
  102. --*/
  103. {
  104. DebugMsg(DLLTEXT("DllGetClassObject:\tCreate class factory.")) ;
  105. //
  106. // Can we create this component?
  107. //
  108. if (clsid != CLSID_OEMRENDER)
  109. {
  110. return CLASS_E_CLASSNOTAVAILABLE ;
  111. }
  112. //
  113. // Create class factory.
  114. //
  115. IOemCF* pClassFactory = new IOemCF ; // Reference count set to 1
  116. // in constructor
  117. if (pClassFactory == NULL)
  118. {
  119. return E_OUTOFMEMORY ;
  120. }
  121. //
  122. // Get requested interface.
  123. //
  124. HRESULT hr = pClassFactory->QueryInterface(iid, ppv) ;
  125. pClassFactory->Release() ;
  126. return hr ;
  127. }
  128. ////////////////////////////////////////////////////////////////////////////////
  129. //
  130. // Interface Oem CallBack (IPrintOemUNI) body
  131. //
  132. STDMETHODIMP
  133. IOemCB::QueryInterface(
  134. const IID& iid,
  135. void** ppv)
  136. /*++
  137. Routine Description:
  138. IUnknow QueryInterface
  139. Arguments:
  140. iid - Reference to the identifier of the interface that communic
  141. ppv - Indirect pointer to the communicating interface
  142. Note:
  143. --*/
  144. {
  145. DebugMsg(DLLTEXT("IOemCB: QueryInterface entry\n"));
  146. if (iid == IID_IUnknown)
  147. {
  148. *ppv = static_cast<IUnknown*>(this);
  149. DebugMsg(DLLTEXT("IOemCB:Return pointer to IUnknown.\n")) ;
  150. }
  151. else if (iid == IID_IPrintOemUni)
  152. {
  153. *ppv = static_cast<IPrintOemUni*>(this) ;
  154. DebugMsg(DLLTEXT("IOemCB:Return pointer to IPrintOemUni.\n")) ;
  155. }
  156. else
  157. {
  158. *ppv = NULL ;
  159. DebugMsg(DLLTEXT("IOemCB:Return NULL.\n")) ;
  160. return E_NOINTERFACE ;
  161. }
  162. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  163. return S_OK ;
  164. }
  165. STDMETHODIMP_(ULONG)
  166. IOemCB::AddRef()
  167. /*++
  168. Routine Description:
  169. IUnknow AddRef interface
  170. Arguments:
  171. Increment a reference count
  172. Return Value:
  173. Reference count
  174. Note:
  175. --*/
  176. {
  177. DebugMsg(DLLTEXT("IOemCB::AddRef() entry.\r\n"));
  178. return InterlockedIncrement(&m_cRef) ;
  179. }
  180. STDMETHODIMP_(ULONG)
  181. IOemCB::Release()
  182. /*++
  183. Routine Description:
  184. IUnknown Release interface
  185. Arguments:
  186. Decrement a reference count
  187. Return Value:
  188. Reference count
  189. Note:
  190. --*/
  191. {
  192. DebugMsg(DLLTEXT("IOemCB::Release() entry.\r\n"));
  193. if (InterlockedDecrement(&m_cRef) == 0)
  194. {
  195. delete this ;
  196. return 0 ;
  197. }
  198. return m_cRef ;
  199. }
  200. STDMETHODIMP
  201. IOemCB::EnableDriver(
  202. DWORD dwDriverVersion,
  203. DWORD cbSize,
  204. PDRVENABLEDATA pded)
  205. /*++
  206. Routine Description:
  207. Arguments:
  208. Return Value:
  209. Note:
  210. --*/
  211. {
  212. DebugMsg(DLLTEXT("IOemCB::EnableDriver() entry.\r\n"));
  213. return E_NOTIMPL;
  214. }
  215. STDMETHODIMP
  216. IOemCB::DisableDriver(VOID)
  217. /*++
  218. Routine Description:
  219. IPrintOemUni DisableDriver interface
  220. Free all resources, and get prepared to be unloaded.
  221. Arguments:
  222. Return Value:
  223. Note:
  224. --*/
  225. {
  226. DebugMsg(DLLTEXT("IOemCB::DisaleDriver() entry.\r\n"));
  227. return E_NOTIMPL;
  228. }
  229. STDMETHODIMP
  230. IOemCB::PublishDriverInterface(
  231. IUnknown *pIUnknown)
  232. /*++
  233. Routine Description:
  234. IPrintOemUni PublishDriverInterface interface
  235. Arguments:
  236. Return Value:
  237. Note:
  238. --*/
  239. {
  240. DebugMsg(DLLTEXT("IOemCB::PublishDriverInterface() entry.\r\n"));
  241. // Need to store pointer to Driver Helper functions, if we already haven't.
  242. if (this->pOEMHelp == NULL)
  243. {
  244. HRESULT hResult;
  245. // Get Interface to Helper Functions.
  246. hResult = pIUnknown->QueryInterface(IID_IPrintOemDriverUni, (void** ) &(this->pOEMHelp));
  247. if(!SUCCEEDED(hResult))
  248. {
  249. // Make sure that interface pointer reflects interface query failure.
  250. this->pOEMHelp = NULL;
  251. return E_FAIL;
  252. }
  253. }
  254. return S_OK;
  255. }
  256. STDMETHODIMP
  257. IOemCB::EnablePDEV(
  258. PDEVOBJ pdevobj,
  259. PWSTR pPrinterName,
  260. ULONG cPatterns,
  261. HSURF *phsurfPatterns,
  262. ULONG cjGdiInfo,
  263. GDIINFO *pGdiInfo,
  264. ULONG cjDevInfo,
  265. DEVINFO *pDevInfo,
  266. DRVENABLEDATA *pded,
  267. OUT PDEVOEM *pDevOem)
  268. /*++
  269. Routine Description:
  270. IPrintOemUni EnablePDEV interface
  271. Construct its own PDEV. At this time, the driver also passes a function
  272. table which contains its own implementation of DDI entrypoints
  273. Arguments:
  274. pdevobj - pointer to a DEVOBJ structure. pdevobj->pdevOEM is undefined.
  275. pPrinterName - name of the current printer.
  276. Cpatterns -
  277. phsurfPatterns -
  278. cjGdiInfo - size of GDIINFO
  279. pGdiInfo - a pointer to GDIINFO
  280. cjDevInfo - size of DEVINFO
  281. pDevInfo - These parameters are identical to what39s passed into DrvEnablePDEV.
  282. pded: points to a function table which contains the system driver39s
  283. implementation of DDI entrypoints.
  284. Return Value:
  285. --*/
  286. {
  287. DebugMsg(DLLTEXT("IOemCB::EnablePDEV() entry.\r\n"));
  288. return E_NOTIMPL;
  289. }
  290. STDMETHODIMP
  291. IOemCB::ResetPDEV(
  292. PDEVOBJ pdevobjOld,
  293. PDEVOBJ pdevobjNew)
  294. /*++
  295. Routine Description:
  296. IPrintOemUni ResetPDEV interface
  297. OEMResetPDEV transfers the state of the driver from the old PDEVOBJ to the
  298. new PDEVOBJ when an application calls ResetDC.
  299. Arguments:
  300. pdevobjOld - pdevobj containing Old PDEV
  301. pdevobjNew - pdevobj containing New PDEV
  302. Return Value:
  303. Note:
  304. --*/
  305. {
  306. DebugMsg(DLLTEXT("IOemCB::ResetPDEV entry.\r\n"));
  307. return E_NOTIMPL;
  308. }
  309. STDMETHODIMP
  310. IOemCB::DisablePDEV(
  311. PDEVOBJ pdevobj)
  312. /*++
  313. Routine Description:
  314. IPrintOemUni DisablePDEV interface
  315. Free resources allocated for the PDEV.
  316. Arguments:
  317. pdevobj -
  318. Return Value:
  319. Note:
  320. --*/
  321. {
  322. DebugMsg(DLLTEXT("IOemCB::DisablePDEV() entry.\r\n"));
  323. return E_NOTIMPL;
  324. };
  325. STDMETHODIMP
  326. IOemCB::GetInfo (
  327. DWORD dwMode,
  328. PVOID pBuffer,
  329. DWORD cbSize,
  330. PDWORD pcbNeeded)
  331. /*++
  332. Routine Description:
  333. IPrintOemUni GetInfo interface
  334. Arguments:
  335. Return Value:
  336. Note:
  337. --*/
  338. {
  339. LPTSTR OEM_INFO[] = { __TEXT("Bad Index"),
  340. __TEXT("OEMGI_GETSIGNATURE"),
  341. __TEXT("OEMGI_GETINTERFACEVERSION"),
  342. __TEXT("OEMGI_GETVERSION"),
  343. };
  344. DebugMsg(DLLTEXT("IOemCB::GetInfo(%s) entry.\r\n"), OEM_INFO[dwMode]);
  345. //
  346. // Validate parameters.
  347. //
  348. if( ( (OEMGI_GETSIGNATURE != dwMode) &&
  349. (OEMGI_GETINTERFACEVERSION != dwMode) &&
  350. (OEMGI_GETVERSION != dwMode) ) ||
  351. (NULL == pcbNeeded)
  352. )
  353. {
  354. DebugMsg(ERRORTEXT("OEMGetInfo() ERROR_INVALID_PARAMETER.\r\n"));
  355. //
  356. // Did not write any bytes.
  357. //
  358. if(NULL != pcbNeeded)
  359. *pcbNeeded = 0;
  360. return E_FAIL;
  361. }
  362. //
  363. // Need/wrote 4 bytes.
  364. //
  365. *pcbNeeded = 4;
  366. //
  367. // Validate buffer size. Minimum size is four bytes.
  368. //
  369. if( (NULL == pBuffer) || (4 > cbSize) )
  370. {
  371. DebugMsg(ERRORTEXT("OEMGetInfo() ERROR_INSUFFICIENT_BUFFER.\r\n"));
  372. return E_FAIL;
  373. }
  374. //
  375. // Write information to buffer.
  376. //
  377. switch(dwMode)
  378. {
  379. case OEMGI_GETSIGNATURE:
  380. *(LPDWORD)pBuffer = OEM_SIGNATURE;
  381. break;
  382. case OEMGI_GETINTERFACEVERSION:
  383. *(LPDWORD)pBuffer = PRINTER_OEMINTF_VERSION;
  384. break;
  385. case OEMGI_GETVERSION:
  386. *(LPDWORD)pBuffer = OEM_VERSION;
  387. break;
  388. }
  389. return S_OK;
  390. }
  391. STDMETHODIMP
  392. IOemCB::GetImplementedMethod(
  393. PSTR pMethodName)
  394. /*++
  395. Routine Description:
  396. IPrintOemUni GetImplementedMethod interface
  397. Arguments:
  398. Return Value:
  399. Note:
  400. --*/
  401. {
  402. LONG lReturn;
  403. DebugMsg(DLLTEXT("IOemCB::GetImplementedMethod() entry.\r\n"));
  404. DebugMsg(DLLTEXT(" Function:%s:"),pMethodName);
  405. lReturn = FALSE;
  406. if (pMethodName != NULL)
  407. {
  408. switch (*pMethodName)
  409. {
  410. case (WCHAR)'F':
  411. if (!strcmp(pstrFilterGraphics, pMethodName))
  412. lReturn = TRUE;
  413. break;
  414. case (WCHAR)'G':
  415. if (!strcmp(pstrGetInfo, pMethodName))
  416. lReturn = TRUE;
  417. break;
  418. }
  419. }
  420. if (lReturn)
  421. {
  422. DebugMsg(__TEXT("Supported\r\n"));
  423. return S_OK;
  424. }
  425. else
  426. {
  427. DebugMsg(__TEXT("NOT supported\r\n"));
  428. return E_FAIL;
  429. }
  430. }
  431. STDMETHODIMP
  432. IOemCB::DevMode(
  433. DWORD dwMode,
  434. POEMDMPARAM pOemDMParam)
  435. /*++
  436. Routine Description:
  437. IPrintOemUni DevMode interface
  438. Arguments:
  439. Return Value:
  440. Note:
  441. --*/
  442. {
  443. DebugMsg(DLLTEXT("IOemCB::DevMode() entry.\r\n"));
  444. return E_NOTIMPL;
  445. }
  446. STDMETHODIMP
  447. IOemCB::CommandCallback(
  448. PDEVOBJ pdevobj,
  449. DWORD dwCallbackID,
  450. DWORD dwCount,
  451. PDWORD pdwParams,
  452. OUT INT *piResult)
  453. /*++
  454. Routine Description:
  455. IPrintOemUni CommandCallback interface
  456. Arguments:
  457. Return Value:
  458. Note:
  459. --*/
  460. {
  461. DebugMsg(DLLTEXT("IOemCB::CommandCallback() entry.\r\n"));
  462. DebugMsg(DLLTEXT(" dwCallbackID = %d\r\n"), dwCallbackID);
  463. DebugMsg(DLLTEXT(" dwCount = %d\r\n"), dwCount);
  464. return E_NOTIMPL;
  465. }
  466. STDMETHODIMP
  467. IOemCB::ImageProcessing(
  468. PDEVOBJ pdevobj,
  469. PBYTE pSrcBitmap,
  470. PBITMAPINFOHEADER pBitmapInfoHeader,
  471. PBYTE pColorTable,
  472. DWORD dwCallbackID,
  473. PIPPARAMS pIPParams,
  474. OUT PBYTE *ppbResult)
  475. /*++
  476. Routine Description:
  477. IPrintOemUni ImageProcessing interface
  478. Arguments:
  479. Return Value:
  480. Note:
  481. --*/
  482. {
  483. DebugMsg(DLLTEXT("IOemCB::ImageProcessing() entry.\r\n"));
  484. return E_NOTIMPL;
  485. }
  486. STDMETHODIMP
  487. IOemCB::FilterGraphics(
  488. PDEVOBJ pdevobj,
  489. PBYTE pBuf,
  490. DWORD dwLen)
  491. /*++
  492. Routine Description:
  493. IPrintOemUni FilterGraphics interface
  494. Arguments:
  495. Return Value:
  496. Note:
  497. --*/
  498. {
  499. DWORD dwResult;
  500. DebugMsg(DLLTEXT("IOemCB::FilterGraphis() entry.\r\n"));
  501. BYTE *lpSrc, *lpTgt;
  502. static BYTE localBuf[1300];
  503. int i,j, bytesRem, nBytes;
  504. static BYTE Blk1[256] = {0};
  505. static BYTE Blk4[256] = {0};
  506. static BYTE Blk2Byt1[256] = {0};
  507. static BYTE Blk2Byt2[256] = {0};
  508. static BYTE Blk3Byt1[256] = {0};
  509. static BYTE Blk3Byt2[256] = {0};
  510. static BYTE BindBlk2[4][16] = {0};
  511. static BYTE BindBlk3[16][4] = {0};
  512. if (!Blk1[1]) // need to initialize tables
  513. {
  514. for(i = 0 ; i < 256 ; i++)
  515. {
  516. BYTE rot;
  517. //First Block , one byte only 123456XX to 00654321
  518. rot = (BYTE)i;
  519. Blk1[i] = 0x10 & (rot <<=1);
  520. Blk1[i] |= 0x20 & (rot <<=2);
  521. rot = (BYTE)i;
  522. Blk1[i] |= 0x08 & (rot >>=1);
  523. Blk1[i] |= 0x04 & (rot >>=2);
  524. Blk1[i] |= 0x02 & (rot >>=2);
  525. Blk1[i] |= 0x01 & (rot >>=2);
  526. Blk1[i] = Blk1[i] + 0x3F;
  527. //Second Block first byte XXXXXX12 to 00000021
  528. Blk2Byt1[i] = 0x01 & (i >>1);
  529. Blk2Byt1[i] |= 0x02 & (i <<1); // i byte
  530. //Second Block second byte 3456XXXX to 00006543
  531. rot = (BYTE)i;
  532. Blk2Byt2[i] = 0x08 & (rot >>=1);
  533. Blk2Byt2[i] |= 0x04 & (rot >>=2);
  534. Blk2Byt2[i] |= 0x02 & (rot >>=2);
  535. Blk2Byt2[i] |= 0x01 & (rot >>=2); // j byte
  536. //Third Block First byte XXXX1234 to 00004321
  537. rot =(BYTE)i;
  538. Blk3Byt1[i] = 0x02 & (rot >>=1);
  539. Blk3Byt1[i] |= 0x01 & (rot >>=2);
  540. rot = (BYTE)i;
  541. Blk3Byt1[i] |= 0x04 & (rot <<=1);
  542. Blk3Byt1[i] |= 0x08 & (rot <<=2); //j byte
  543. //Third Block Second byte 56XXXXXX to 00000065
  544. rot = (BYTE)i;
  545. Blk3Byt2[i] = 0x02 & (rot >>=5);
  546. Blk3Byt2[i] |= 0x01 & (rot >>=2); //i byte
  547. //Fourth Block, only byte XX123456 to 00654321
  548. rot = (BYTE)i;
  549. Blk4[i] = 0x08 & (rot <<=1);
  550. Blk4[i] |= 0x10 & (rot <<=2);
  551. Blk4[i] |= 0x20 & (rot <<=2);
  552. rot = (BYTE)i;
  553. Blk4[i] |= 0x04 & (rot >>=1);
  554. Blk4[i] |= 0x02 & (rot >>=2);
  555. Blk4[i] |= 0x01 & (rot >>=2);
  556. Blk4[i] = Blk4[i] + 0x3F;
  557. }
  558. for(i = 0 ; i < 4 ; i++)
  559. for(j = 0 ; j < 16 ; j++)
  560. {
  561. // Bind 00000021 & 00006543 & add 3F
  562. BindBlk2[i][j] = ( (j<< 2 ) | i) + 0x3F;
  563. // Bind 00004321 & 00000065 & add 3F
  564. BindBlk3[j][i] = ( (i<< 4 ) | j) + 0x3F;
  565. }
  566. }
  567. bytesRem = dwLen;
  568. lpSrc = (PBYTE)pBuf;
  569. while(bytesRem > 0)
  570. {
  571. nBytes = (bytesRem > 3072) ? 3072 : bytesRem;
  572. bytesRem -= nBytes;
  573. lpTgt = localBuf;
  574. for(i = 0 ; i < nBytes / 3 ; i++)
  575. {
  576. *lpTgt++ = Blk1[*lpSrc];
  577. lpSrc +=3;
  578. }
  579. CompressIt(pdevobj, (PBYTE)localBuf, (int)(lpTgt - localBuf), pOEMHelp);
  580. }
  581. // End of block send graphics line feed & carriage return
  582. pOEMHelp->DrvWriteSpoolBuf(pdevobj, "\x2D\x24", 2, &dwResult);
  583. bytesRem = dwLen;
  584. lpSrc = (PBYTE)pBuf;
  585. while(bytesRem > 0)
  586. {
  587. nBytes = (bytesRem > 3072) ? 3072 : bytesRem;
  588. bytesRem -= nBytes;
  589. lpTgt = localBuf;
  590. for(i = 0 ; i < nBytes / 3 ; i++)
  591. {
  592. *lpTgt++ = BindBlk2[ Blk2Byt1[ *lpSrc] ][ Blk2Byt2[ *(lpSrc +1)] ];
  593. lpSrc +=3;
  594. }
  595. CompressIt(pdevobj, (PBYTE)localBuf, (int)(lpTgt - localBuf), pOEMHelp);
  596. }
  597. // End of block send graphics line feed & carriage return
  598. pOEMHelp->DrvWriteSpoolBuf(pdevobj, "\x2D\x24", 2, &dwResult);
  599. bytesRem = dwLen;
  600. lpSrc = (PBYTE)pBuf;
  601. while(bytesRem > 0)
  602. {
  603. nBytes = (bytesRem > 3072) ? 3072 : bytesRem;
  604. bytesRem -= nBytes;
  605. lpTgt = localBuf;
  606. for(i = 0 ; i < nBytes / 3 ; i++)
  607. {
  608. *lpTgt++ = BindBlk3[ Blk3Byt1[ *(lpSrc+1) ] ][ Blk3Byt2[ *(lpSrc +2)] ];
  609. lpSrc +=3;
  610. }
  611. CompressIt(pdevobj, (PBYTE)localBuf, (int)(lpTgt - localBuf), pOEMHelp);
  612. }
  613. // End of block send graphics line feed & carriage return
  614. pOEMHelp->DrvWriteSpoolBuf(pdevobj, "\x2D\x24", 2, &dwResult);
  615. bytesRem = dwLen;
  616. lpSrc = (PBYTE)pBuf;
  617. while(bytesRem > 0)
  618. {
  619. nBytes = (bytesRem > 3072) ? 3072 : bytesRem;
  620. bytesRem -= nBytes;
  621. lpTgt = localBuf;
  622. for(i = 0 ; i < nBytes / 3 ; i++)
  623. {
  624. *lpTgt++ = Blk4[ *(lpSrc+2) ];
  625. lpSrc += 3;
  626. }
  627. CompressIt(pdevobj, (PBYTE)localBuf, (int)(lpTgt - localBuf), pOEMHelp);
  628. }
  629. // End of final block send line feed & End Block command
  630. pOEMHelp->DrvWriteSpoolBuf(pdevobj, "\x2D\x9C", 2, &dwResult);
  631. return 100; /* Value not used AT PRESENT! */
  632. if (SUCCEEDED(FilterGraphics( pdevobj, pBuf, dwLen)))
  633. return S_OK;
  634. else
  635. return E_FAIL;
  636. }
  637. BOOL
  638. CompressIt(
  639. PDEVOBJ pdevobj,
  640. PBYTE ExpBuf,
  641. int ExpLen,
  642. IPrintOemDriverUni* pOEMHelp)
  643. {
  644. static BYTE CompBuf[1200]; //Max size before Compression is 1024
  645. BYTE *lpSrc, *lpTgt;
  646. int InCompMode =0, count=0,i,FormatLen;
  647. BYTE FormatBuf[10];
  648. BYTE *pFormat;
  649. lpSrc = ExpBuf;
  650. lpTgt = CompBuf;
  651. DWORD dwResult;
  652. for (i=0; i < ExpLen; i++,lpSrc++)
  653. {
  654. if ( *lpSrc != *(lpSrc +1))
  655. {
  656. if (!InCompMode)
  657. *lpTgt++ = *lpSrc;
  658. else
  659. {
  660. InCompMode = 0;
  661. //Send the repeat char sequence - !#X
  662. pFormat = FormatBuf;
  663. FormatLen = sprintf((char *)pFormat,"!%d%c",count,*lpSrc);
  664. pOEMHelp->DrvWriteSpoolBuf(pdevobj, FormatBuf,FormatLen,&dwResult);
  665. }
  666. }
  667. else
  668. {
  669. if (!InCompMode)
  670. {
  671. InCompMode =1;
  672. count =2;
  673. pOEMHelp->DrvWriteSpoolBuf(pdevobj, CompBuf, (DWORD)(lpTgt - CompBuf), &dwResult);
  674. lpTgt = CompBuf;
  675. }
  676. else
  677. count++;
  678. }
  679. }
  680. if (!InCompMode)
  681. pOEMHelp->DrvWriteSpoolBuf(pdevobj, CompBuf, (DWORD)(lpTgt - CompBuf), &dwResult);
  682. else
  683. {
  684. //Send the repeat char sequence - !#X
  685. pFormat = FormatBuf;
  686. FormatLen = sprintf((char *)pFormat,"!%d%c",count-1,*lpSrc);
  687. pOEMHelp->DrvWriteSpoolBuf(pdevobj, FormatBuf,FormatLen, &dwResult);
  688. }
  689. return TRUE;
  690. }
  691. IOemCB::~IOemCB()
  692. {
  693. // Make sure that driver's helper function interface is released.
  694. if(NULL != pOEMHelp)
  695. {
  696. pOEMHelp->Release();
  697. pOEMHelp = NULL;
  698. }
  699. // If this instance of the object is being deleted, then the reference
  700. // count should be zero.
  701. assert(0 == m_cRef);
  702. }
  703. STDMETHODIMP
  704. IOemCB::Compression(
  705. PDEVOBJ pdevobj,
  706. PBYTE pInBuf,
  707. PBYTE pOutBuf,
  708. DWORD dwInLen,
  709. DWORD dwOutLen,
  710. OUT INT *piResult)
  711. /*++
  712. Routine Description:
  713. IPrintOemUni Compression interface
  714. Arguments:
  715. Return Value:
  716. Note:
  717. --*/
  718. {
  719. DebugMsg(DLLTEXT("IOemCB::Compression() entry.\r\n"));
  720. return E_NOTIMPL;
  721. }
  722. STDMETHODIMP
  723. IOemCB::HalftonePattern(
  724. PDEVOBJ pdevobj,
  725. PBYTE pHTPattern,
  726. DWORD dwHTPatternX,
  727. DWORD dwHTPatternY,
  728. DWORD dwHTNumPatterns,
  729. DWORD dwCallbackID,
  730. PBYTE pResource,
  731. DWORD dwResourceSize)
  732. /*++
  733. Routine Description:
  734. IPrintOemUni HalftonePattern interface
  735. Arguments:
  736. Return Value:
  737. Note:
  738. --*/
  739. {
  740. DebugMsg(DLLTEXT("IOemCB::HalftonePattern() entry.\r\n"));
  741. return E_NOTIMPL;
  742. }
  743. STDMETHODIMP
  744. IOemCB::MemoryUsage(
  745. PDEVOBJ pdevobj,
  746. POEMMEMORYUSAGE pMemoryUsage)
  747. /*++
  748. Routine Description:
  749. IPrintOemUni MemoryUsage interface
  750. Arguments:
  751. Return Value:
  752. Note:
  753. --*/
  754. {
  755. DebugMsg(DLLTEXT("IOemCB::MemoryUsage() entry.\r\n"));
  756. return E_NOTIMPL;
  757. }
  758. STDMETHODIMP
  759. IOemCB::DownloadFontHeader(
  760. PDEVOBJ pdevobj,
  761. PUNIFONTOBJ pUFObj,
  762. OUT DWORD *pdwResult)
  763. /*++
  764. Routine Description:
  765. IPrintOemUni DownloadFontHeader interface
  766. Arguments:
  767. Return Value:
  768. Note:
  769. --*/
  770. {
  771. DebugMsg(DLLTEXT("IOemCB::DownloadFontHeader() entry.\r\n"));
  772. return E_NOTIMPL;
  773. }
  774. STDMETHODIMP
  775. IOemCB::DownloadCharGlyph(
  776. PDEVOBJ pdevobj,
  777. PUNIFONTOBJ pUFObj,
  778. HGLYPH hGlyph,
  779. PDWORD pdwWidth,
  780. OUT DWORD *pdwResult)
  781. /*++
  782. Routine Description:
  783. IPrintOemUni DownloadCharGlyph interface
  784. Arguments:
  785. Return Value:
  786. Note:
  787. --*/
  788. {
  789. DebugMsg(DLLTEXT("IOemCB::DownloadCharGlyph() entry.\r\n"));
  790. return E_NOTIMPL;
  791. }
  792. STDMETHODIMP
  793. IOemCB::TTDownloadMethod(
  794. PDEVOBJ pdevobj,
  795. PUNIFONTOBJ pUFObj,
  796. OUT DWORD *pdwResult)
  797. /*++
  798. Routine Description:
  799. IPrintOemUni TTDownloadMethod interface
  800. Arguments:
  801. Return Value:
  802. Note:
  803. --*/
  804. {
  805. DebugMsg(DLLTEXT("IOemCB::TTDownloadMethod() entry.\r\n"));
  806. return E_NOTIMPL;
  807. }
  808. STDMETHODIMP
  809. IOemCB::OutputCharStr(
  810. PDEVOBJ pdevobj,
  811. PUNIFONTOBJ pUFObj,
  812. DWORD dwType,
  813. DWORD dwCount,
  814. PVOID pGlyph)
  815. /*++
  816. Routine Description:
  817. IPrintOemUni OutputCharStr interface
  818. Arguments:
  819. Return Value:
  820. Note:
  821. --*/
  822. {
  823. DebugMsg(DLLTEXT("IOemCB::OutputCharStr() entry.\r\n"));
  824. return E_NOTIMPL;
  825. }
  826. STDMETHODIMP
  827. IOemCB::SendFontCmd(
  828. PDEVOBJ pdevobj,
  829. PUNIFONTOBJ pUFObj,
  830. PFINVOCATION pFInv)
  831. /*++
  832. Routine Description:
  833. IPrintOemUni SendFontCmd interface
  834. Arguments:
  835. Return Value:
  836. Note:
  837. --*/
  838. {
  839. DebugMsg(DLLTEXT("IOemCB::SendFontCmd() entry.\r\n"));
  840. return E_NOTIMPL;
  841. }
  842. STDMETHODIMP
  843. IOemCB::DriverDMS(
  844. PVOID pDevObj,
  845. PVOID pBuffer,
  846. DWORD cbSize,
  847. PDWORD pcbNeeded)
  848. /*++
  849. Routine Description:
  850. IPrintOemUni DriverDMS interface
  851. Arguments:
  852. Return Value:
  853. Note:
  854. --*/
  855. {
  856. DebugMsg(DLLTEXT("IOemCB::DriverDMS() entry.\r\n"));
  857. return E_NOTIMPL;
  858. }
  859. STDMETHODIMP
  860. IOemCB::TextOutAsBitmap(
  861. SURFOBJ *pso,
  862. STROBJ *pstro,
  863. FONTOBJ *pfo,
  864. CLIPOBJ *pco,
  865. RECTL *prclExtra,
  866. RECTL *prclOpaque,
  867. BRUSHOBJ *pboFore,
  868. BRUSHOBJ *pboOpaque,
  869. POINTL *pptlOrg,
  870. MIX mix)
  871. /*++
  872. Routine Description:
  873. IPrintOemUni TextOutAsBitmap interface
  874. Arguments:
  875. Return Value:
  876. Note:
  877. --*/
  878. {
  879. DebugMsg(DLLTEXT("IOemCB::TextOutAsBitmap() entry.\r\n"));
  880. return E_NOTIMPL;
  881. }
  882. STDMETHODIMP
  883. IOemCB::TTYGetInfo(
  884. PDEVOBJ pdevobj,
  885. DWORD dwInfoIndex,
  886. PVOID pOutputBuf,
  887. DWORD dwSize,
  888. DWORD *pcbcNeeded)
  889. /*++
  890. Routine Description:
  891. IPrintOemUni TTYGetInfo interface
  892. Arguments:
  893. Return Value:
  894. Note:
  895. --*/
  896. {
  897. DebugMsg(DLLTEXT("IOemCB::TTYGetInfo() entry.\r\n"));
  898. return E_NOTIMPL;
  899. }
  900. ///////////////////////////////////////////////////////////
  901. //
  902. // Interface Oem Class factory body
  903. //
  904. STDMETHODIMP
  905. IOemCF::QueryInterface(
  906. const IID& iid,
  907. void** ppv)
  908. /*++
  909. Routine Description:
  910. Class Factory QueryInterface interface
  911. Arguments:
  912. Return Value:
  913. Note:
  914. --*/
  915. {
  916. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  917. {
  918. *ppv = static_cast<IOemCF*>(this) ;
  919. }
  920. else
  921. {
  922. *ppv = NULL ;
  923. return E_NOINTERFACE ;
  924. }
  925. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  926. return S_OK ;
  927. }
  928. STDMETHODIMP_(ULONG)
  929. IOemCF::AddRef()
  930. /*++
  931. Routine Description:
  932. IPrintOemUni AddRef interface
  933. Arguments:
  934. Return Value:
  935. Note:
  936. --*/
  937. {
  938. return InterlockedIncrement(&m_cRef) ;
  939. }
  940. STDMETHODIMP_(ULONG)
  941. IOemCF::Release()
  942. /*++
  943. Routine Description:
  944. IPrintOemUni Release interface
  945. Arguments:
  946. Return Value:
  947. Note:
  948. --*/
  949. {
  950. if (InterlockedDecrement(&m_cRef) == 0)
  951. {
  952. delete this ;
  953. return 0 ;
  954. }
  955. return m_cRef ;
  956. }
  957. STDMETHODIMP
  958. IOemCF::CreateInstance(
  959. IUnknown* pUnknownOuter,
  960. const IID& iid,
  961. void** ppv)
  962. /*++
  963. Routine Description:
  964. IPrintOemUni CreateInstance interface
  965. Arguments:
  966. Return Value:
  967. Note:
  968. --*/
  969. {
  970. DebugMsg(DLLTEXT("Class factory:\t\tCreate component.")) ;
  971. //
  972. // Cannot aggregate.
  973. //
  974. if (pUnknownOuter != NULL)
  975. {
  976. return CLASS_E_NOAGGREGATION ;
  977. }
  978. //
  979. // Create component.
  980. //
  981. IOemCB* pOemCB = new IOemCB ;
  982. if (pOemCB == NULL)
  983. {
  984. return E_OUTOFMEMORY ;
  985. }
  986. //
  987. // Get the requested interface.
  988. //
  989. HRESULT hr = pOemCB->QueryInterface(iid, ppv) ;
  990. //
  991. // Release the IUnknown pointer.
  992. // (If QueryInterface failed, component will delete itself.)
  993. //
  994. pOemCB->Release() ;
  995. return hr ;
  996. }
  997. STDMETHODIMP
  998. IOemCF::LockServer(
  999. BOOL bLock)
  1000. /*++
  1001. Routine Description:
  1002. Class Factory LockServer interface
  1003. Arguments:
  1004. Return Value:
  1005. Note:
  1006. --*/
  1007. {
  1008. if (bLock)
  1009. {
  1010. InterlockedIncrement(&g_cServerLocks) ;
  1011. }
  1012. else
  1013. {
  1014. InterlockedDecrement(&g_cServerLocks) ;
  1015. }
  1016. return S_OK ;
  1017. }