📄 minidriv.c
字号:
/****************************************************************************
* *
* 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 (C) 1993-95 Microsoft Corporation. All Rights Reserved. *
* Machine G5410 *
****************************************************************************/
#define PRINTDRIVER
#define BUILDDLL
#define MAXDELAY 30
#define SP_OK 1
#define MAXBYTES 384
#define STARTLINE 2
#define PRT_MODE 0
#define UART_BAUD 9600
/*;0:300DPI B4; 1:300DPI A3
;2:400DPI B4; 3:400DPI A3
;4:600DPI B4; 5:600DPI A3
*/
#include "print.h"
#include "gdidefs.inc"
#include "bitmap.h"
#include "mdevice.h"
#include "unidrv.h"
#include <stdio.h>
WORD nCopy=1;
short OutOnePage(LPEXTPDEV lpXPDV);
extern char *rgchModuleName; // global module name
char szSection[8] = "BITMAP,";
short OutOnePage(LPEXTPDEV lpXPDV)
{
WORD i, wWidthBytes,dwLine;
BYTE _huge *p;
signed char ch,c;
BYTE name[128];
WORD iDs;
BYTE far *ptmp;
dwLine=(WORD)(lpXPDV->dwTotalScans); //总的行数
wWidthBytes = (WORD)(lpXPDV->dwTotalScanBytes / lpXPDV->dwTotalScans); //一行字节数
if ((lpXPDV->hDIBFile = OpenFile(lpXPDV->szDIBFile,
(LPOFSTRUCT)&lpXPDV->of,OF_CREATE | OF_WRITE | OF_READ)) < 0)
return SP_ERROR;
ptmp = (BYTE far *)lpXPDV->lpTmpBuf;
*ptmp++ = MAXBYTES >> 8; //MSB; //最大物理宽度(2字节)
*ptmp++ = MAXBYTES % 256; //LSB;
*ptmp++ = STARTLINE >> 8; //空白行数(2字节);
*ptmp++ = STARTLINE % 256;
*ptmp++ = PRT_MODE; //打印模式(1字节);
*ptmp++ = MAXDELAY; //最大打印时间(1字节);
*ptmp++ = (unsigned char)(wWidthBytes >> 8);//MSB; //每行字节数(2字节);
*ptmp++ = (unsigned char)(wWidthBytes % 256);//LSB;
*ptmp++ = (unsigned char)((lpXPDV->dwTotalScanBytes) >> 24); //MSB;//总的打印字节数(4字节);
*ptmp++ = (unsigned char)((lpXPDV->dwTotalScanBytes) >> 16);
*ptmp++ = (unsigned char)((lpXPDV->dwTotalScanBytes) >> 8);
*ptmp++ = (unsigned char)((lpXPDV->dwTotalScanBytes) % 256);//LSB;
*ptmp++ = (unsigned char)(UART_BAUD >> 8); //波特率(2字节)
*ptmp++ = (unsigned char)(UART_BAUD % 256); //Maxium UART BAUD is 65535;(2 bytes)
*ptmp++ = 33;//Number of UART init command; //串口初始化命令个数;
*ptmp++ = 0x83;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x18;
*ptmp++ = 1;
*ptmp++ = (unsigned char)(0x80 + (nCopy%10));
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1a;
*ptmp++ = 1;
*ptmp++ = (unsigned char)(0x90 + (nCopy/10%10));
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1a;
*ptmp++ = 1;
*ptmp++ = (unsigned char)(0xa0 + (nCopy/100%10));
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1a;
*ptmp++ = 1;
*ptmp++ = (unsigned char)(0xb0 + (nCopy/1000));
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1a;
*ptmp++ = 1;
*ptmp++ = 0x8e;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1f;
*ptmp++ = 1;
*ptmp++ = 0xc1;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1f;
*ptmp++ = 1;
*ptmp++ = 0x85;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1f;
*ptmp++ = 1;
*ptmp++ = 0xc1;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1f;
*ptmp++ = 1;
*ptmp++ = 0x83;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1f;
*ptmp++ = 1;
*ptmp++ = 0xc2;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x1f;
*ptmp++ = 1;
*ptmp++ = 0x80;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x14;
*ptmp++ = 1;
*ptmp++ = 0xa0;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x5;
*ptmp++ = 1;
*ptmp++ = 0x81;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0xf;
*ptmp++ = 1;
*ptmp++ = 0x81;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x11;
*ptmp++ = 1;
*ptmp++ = 0x83;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
*ptmp++ = 0x13;
*ptmp++ = 1;
*ptmp++ = 0xb;
*ptmp++ = 1;
/*
*ptmp++ = 5;//Number of UART init command; //串口初始化命令个数;
i++;
*ptmp++ = 0xa0; //串口初始化命令;
i++;
*ptmp++ = 0; //Without response by UART; //是否需要回应标志;
i++;
*ptmp++ = 0x14;
i++;
*ptmp++ = 1; //Need response flag;
i++;
*ptmp++ = 0x0b;
i++;
*ptmp++ = 1;
i++;
*ptmp++ = 0x88;
i++;
*ptmp++ = 0;
i++;
*ptmp++ = 0x5;
i++;
*ptmp++ = 0;
i++; */
_lwrite(lpXPDV->hDIBFile, lpXPDV->lpTmpBuf, 128); //write parameter(total 128 bytes);
ptmp = (BYTE far *)lpXPDV->lpTmpBuf;
p=lpXPDV->lpScanBuf;
for (i=0; i < dwLine; i++)
{
ptmp = (BYTE far *)lpXPDV->lpTmpBuf; //add by zwh on 10-13-2005
for (iDs=0; iDs<wWidthBytes;)
{
ch=*p++;
if( ch >= 0 && (int)ch <= 127)
{
iDs +=(int)ch+1;
for (; ch > -1; ch--)
*ptmp++=*p++; //copy printer data to my buffer;
//outp(dport,*p);
}
else
if ( ch < 0 && ch>=-127 )
{
iDs +=1-(int)ch;
c=*p++;
for( ; ch<1 ; ch++)
*ptmp++=c; //copy printer data to my buffer;
}
else
{
lpXPDV->func=100;
return SP_ERROR;
}
}
_lwrite(lpXPDV->hDIBFile, lpXPDV->lpTmpBuf, wWidthBytes); //write a line print data to file;
}
_lclose(lpXPDV->hDIBFile);
GetSystemDirectory(name,sizeof(name)); // c:\windows\system\zdhinit.exe;
lstrcat(name,"\\zdhinit.exe");
if (WinExec(name,SW_SHOW) < 32)
{
MessageBox(NULL,"找不到 zdhinit.exe 文件,请重新安装驱动程序!",
"CopyPrinter Driver",
MB_ICONSTOP | MB_OK | MB_SYSTEMMODAL);
return SP_ERROR;
}
return SP_OK;
}
short Alloc(LPEXTPDEV lpXPDV)
{
WORD wBytes=0,Mod;
WORD wWidthBytes;
wWidthBytes = (WORD)(lpXPDV->dwTotalScanBytes / lpXPDV->dwTotalScans);
if (Mod=(WORD)(lpXPDV->dwTotalScans%32))
{
Mod=32-Mod;
wBytes=Mod*wWidthBytes;
if ((lpXPDV->dwTotalScanBytes + wBytes) > lpXPDV->dwScanBufSize)
{
HANDLE hTemp;
lpXPDV->dwScanBufSize = lpXPDV->dwTotalScanBytes+wBytes;
hTemp = GlobalReAlloc(lpXPDV->hScanBuf, lpXPDV->dwScanBufSize,
GMEM_MOVEABLE | GMEM_ZEROINIT);
// if realloc fails, call ABORTDOC to clean up scan buf
if (!hTemp) {
MessageBox(NULL,"Memory not enough, quit some\napplication and try again.",
"CopyPrinter Driver",
MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL);
lpXPDV->func=100;
return SP_ERROR;
}
else
{
lpXPDV->hScanBuf = hTemp;
lpXPDV->lpScanBuf = (char _huge *)GlobalLock(lpXPDV->hScanBuf);
lpXPDV->lpScanBuf += lpXPDV->dwTotalScanBytes;
}
}
lpXPDV->dwTotalScans +=Mod;
for (Mod=0; Mod < wBytes; Mod++)
*lpXPDV->lpScanBuf++ = (BYTE)0xff;
lpXPDV->dwTotalScanBytes +=wBytes;
}
return SP_OK;
}
void utoa(DWORD dValue, LPSTR p)
{
DWORD dtmp=0xf0000000;
int i;
for (i=7; i>=0; i--) {
p[7-i]=(char)((dValue & dtmp)>>(4*i));
if (p[7-i]<10)
p[7-i] +='0';
else
p[7-i] = (char)(p[7-i]-10+'A');
dtmp=dtmp>>4;
}
p[8]=0;
}
short ReLoad(LPEXTPDEV lpXPDV)
{
BYTE _huge *p;
_llseek(lpXPDV->hDIBFile, 0, 0);
if (lpXPDV->hScanBuf) {
GlobalUnlock(lpXPDV->hScanBuf);
GlobalFree(lpXPDV->hScanBuf);
if (!(lpXPDV->hScanBuf = GlobalAlloc(GPTR,lpXPDV->dwTotalCmp)))
return SP_ERROR;
lpXPDV->lpScanBuf = (BYTE _huge *)GlobalLock(lpXPDV->hScanBuf);
}
p=(BYTE _huge *)lpXPDV->lpScanBuf;
for (; QueryAbort(lpXPDV->hAppDC,0); p+=0x8000)
if (_lread(lpXPDV->hDIBFile, p, 0x8000) < 0x8000)
break;
_lclose(lpXPDV->hDIBFile);
lpXPDV->hDIBFile = OpenFile((LPSTR)lpXPDV->szDIBFile,
(LPOFSTRUCT)&lpXPDV->of,
OF_DELETE);
return SP_OK;
}
short WriteTmpFile(LPEXTPDEV lpXPDV)
{
WORD i, j, wWidthBytes;
BYTE ch,ch1;
BYTE _huge *p;
BYTE far *dwLine;
WORD newWidth,lenCmp;
DWORD dwBytes;
if (Alloc(lpXPDV)!=SP_OK)
return SP_ERROR;
if (lpXPDV->func<105 || (lpXPDV->iPageNum%2)) {
if ((lpXPDV->hDIBFile = OpenFile(lpXPDV->szDIBFile,
(LPOFSTRUCT)&lpXPDV->of,OF_CREATE | OF_WRITE | OF_READ)) < 0)
return SP_ERROR;
}
wWidthBytes = (WORD)(lpXPDV->dwTotalScanBytes / lpXPDV->dwTotalScans);
p=(BYTE _huge *)(lpXPDV->lpScanBuf)-lpXPDV->dwTotalScanBytes;
newWidth=(WORD)(lpXPDV->dwTotalScans/8);
dwLine=(BYTE far *)lpXPDV->lpTmpBuf;
for (i=0; i<wWidthBytes*8; i++) {
ch1=(BYTE)(((BYTE)0x80)>>(i & 7));
dwBytes=(DWORD)i>>3;
for (j=0; j<newWidth; j++)
dwLine[j]=0;
for (j=0; j<(WORD)lpXPDV->dwTotalScans; j++) {
ch=*(p+dwBytes);
if (!(ch & ch1))
dwLine[j>>3] |= (((BYTE)0x80)>>(j & 7));
dwBytes +=wWidthBytes;
}
lenCmp = cmp(lpXPDV,newWidth);
_lwrite(lpXPDV->hDIBFile, dwLine+LINEBYTES, lenCmp);
lpXPDV->dwTotalCmp +=lenCmp;
}
lpXPDV->dwTotalScans=wWidthBytes*8;
return SP_OK;
}
void ErrorExit(LPEXTPDEV lpXPDV)
{
if (lpXPDV->hScanBuf)
{
GlobalUnlock(lpXPDV->hScanBuf);
GlobalFree(lpXPDV->hScanBuf);
lpXPDV->hScanBuf = NULL;
}
if (lpXPDV->hTmpBuf)
{
GlobalUnlock(lpXPDV->hTmpBuf);
GlobalFree(lpXPDV->hTmpBuf);
lpXPDV->hTmpBuf = NULL;
}
}
#ifndef NOCONTROL
short WINAPI Control(lpdv, function, lpInData, lpOutData)
LPDV lpdv;
WORD function;
LPSTR lpInData;
LPSTR lpOutData;
{
LPEXTPDEV lpXPDV;
short sRet,nRet;
static DWORD dwTotalScans;
static DWORD dwTotalScanBytes;
// get pointer to our private data stored in UNIDRV's PDEVICE
lpXPDV = ((LPEXTPDEV)lpdv->lpMd);
switch (function)
{
case SETPRINTERDC:
// save app's DC for QueryAbort() calls
if (lpXPDV)
lpXPDV->hAppDC = *(HANDLE FAR *)lpInData;
break;
case NEXTBAND:
{
if (lpXPDV->func==100)
return SP_USERABORT;
// call UNIDRV.DLL's NEXTBAND to see if we're at end of page
sRet = UniControl(lpdv, function, lpInData, lpOutData);
// check for end of page (ie, empty rectangle) or failure
if ((!IsRectEmpty((LPRECT)lpOutData)) || (sRet <= 0))
return sRet;
// increment page number
lpXPDV->iPageNum++;
if (lpXPDV->func==103)
lpXPDV->lpScanBuf -= lpXPDV->dwTotalCmp;
if (lpXPDV->func==104)
{
// open file and store name and file handle in private PDEVICE
if (WriteTmpFile(lpXPDV)!=SP_OK)
{
ErrorExit(lpXPDV);
return SP_ERROR;
}
if (Reload(lpXPDV)!=SP_OK)
{
ErrorExit(lpXPDV);
return SP_ERROR;
}
}
if (lpXPDV->func==105)
{
if (WriteTmpFile(lpXPDV)!=SP_OK)
{
ErrorExit(lpXPDV);
return SP_ERROR;
}
if (lpXPDV->iPageNum%2)
{
dwTotalScanBytes=lpXPDV->dwTotalScanBytes;
dwTotalScans=lpXPDV->dwTotalScans;
lpXPDV->lpScanBuf -=dwTotalScanBytes;
}
else
{
if (Reload(lpXPDV)!=SP_OK)
{
ErrorExit(lpXPDV);
return SP_ERROR;
}
lpXPDV->dwTotalScanBytes +=lpXPDV->dwTotalScanBytes;
lpXPDV->dwTotalScans +=lpXPDV->dwTotalScans;
}
}
if (lpXPDV->func<105 || !(lpXPDV->iPageNum%2))
{
if ((nRet=OutOnePage(lpXPDV))!=SP_OK)
{
ErrorExit(lpXPDV);
return nRet;
}
GlobalUnlock(lpXPDV->hScanBuf);
GlobalFree(lpXPDV->hScanBuf);
lpXPDV->hScanBuf = NULL;
if (lpXPDV->func==103)
{
if (!(lpXPDV->hScanBuf = GlobalAlloc(GPTR, BUF_CHUNK)))
return SP_ERROR;
}
else if (!(lpXPDV->hScanBuf = GlobalAlloc(GHND, BUF_CHUNK)))
return SP_ERROR;
lpXPDV->lpScanBuf = (char _huge *)GlobalLock(lpXPDV->hScanBuf);
lpXPDV->dwScanBufSize = BUF_CHUNK;
lpXPDV->dwTotalCmp = 0;
}
// clean up page stuff
// initialize job variables
lpXPDV->dwTotalScans =
lpXPDV->dwTotalScanBytes = 0;
return (sRet);
}
case STARTDOC:
{
HANDLE hInst;
DOCINFO di;
//Get Video Board Address & Check Online status
//if ((sRet=GetPortAddr(lpXPDV))!=SP_OK)
//return sRet;
// get minidriver instance handle
hInst = GetModuleHandle((LPSTR)rgchModuleName);
if (!(DialogBoxParam(hInst, "FILEDLG", NULL, FileDlgProc, (LPARAM)lpXPDV)))
return SP_USERABORT;
GetWindowsDirectory(lpXPDV->szDIBFile,sizeof(lpXPDV->szDIBFile));
lstrcat(lpXPDV->szDIBFile,"\\~ZDHMAP~.BMP");
// alloc page scan buffer
if (lpXPDV->func==103)
{
if (!(lpXPDV->hScanBuf = GlobalAlloc(GPTR, BUF_CHUNK)))
{
return SP_ERROR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -