📄 mdd.c
字号:
TerminateChannel(pPortObj);
}
DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: return pPortObj=%Xh\r\n"),pPortObj));
return pPortObj;
}
// ****************************************************************
//
// @doc EXTERNAL
//
// @func BOOL | LPT_Close | close the parallel device.
//
// @parm DWORD | pHead | Context pointer returned from LPT_Open
//
// @rdesc TRUE if success; FALSE if failure
//
// @remark This routine is called by the device manager to close the device.
//
//
//
BOOL
LPT_Close(PPortInformation pOpenHead)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_Close: entry\r\n")));
return TRUE;
}
/*
@doc EXTERNAL
@func BOOL | LPT_Deinit | De-initialize parallel port.
@parm DWORD | pSerialHead | Context pointer returned from LPT_Init
*
@rdesc None.
*/
BOOL
LPT_Deinit(PPortInformation pPortObj)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_Deinit: entry\r\n")));
if (pPortObj) {
if (pPortObj->pDeviceID.pdeviceID) {
LocalFree(pPortObj->pDeviceID.pdeviceID);
}
LocalFree(pPortObj);
}
return TRUE;
}
/*
@doc EXTERNAL
@func ULONG | LPT_Read | Allows application to receive characters from
* parallel port. This routine sets the buffer and bufferlength to be used
* by the reading thread. It also enables reception and controlling when
* to return to the user. It writes to the referent of the fourth argument
* the number of bytes transacted. It returns the status of the call.
*
* Exported to users.
@rdesc This routine returns: -1 if error, or number of bytes read.
*/
ULONG
LPT_Read(
PPortInformation pPortObj, //@parm [IN] HANDLE returned by LPT_Open
PUCHAR pTargetBuffer, //@parm [IN,OUT] Pointer to valid memory.
ULONG BufferLength //@parm [IN] Size in bytes of pTargetBuffer.
)
{
ULONG BytesRead = 0;
DEBUGMSG(ZONE_IO,(TEXT("LPT_Read: entry\r\n")));
return BytesRead;
}
/*
@doc EXTERNAL
@func ULONG | LPT_Write | Allows application to transmit bytes to the parallel port. Exported to users.
*
@rdesc It returns the number of bytes written or -1 if error.
*
*
*/
ULONG
LPT_Write(PPortInformation pPortObj, /*@parm [IN] HANDLE returned by LPT_Open.*/
PUCHAR pSourceBytes, /*@parm [IN] Pointer to bytes to be written.*/
ULONG NumberOfBytes /*@parm [IN] Number of bytes to be written. */
)
{
ULONG TotalWritten;
ULONG ulTimeout;
ULONG ulStartTime;
ULONG ulEndTime;
ULONG uStatusPort, uDataPort;
DEBUGMSG(ZONE_IO,(TEXT("LPT_Write: entry\r\n")));
// Initialize the LPT Port variables
uDataPort = pPortObj->ulBase;
/****************************************************************************
* Modification done by Maneesh Gupta
*
* modifying register access with the help of dwPrinterRegMultiplier
****************************************************************************/
uStatusPort = uDataPort + 1 * dwPrinterRegMultiplier;
/****************************************************************************
* End of Modification done by Maneesh Gupta
****************************************************************************/
TotalWritten= NumberOfBytes; // set total written to requested
// setup transfer size
pPortObj->pPortData.QOutCount = NumberOfBytes;
// if no timeout specified
/****************************************************************************
* Modification done by Maneesh Gupta
*
* modifying register access with the help of dwPrinterRegMultiplier
****************************************************************************/
if (!pPortObj->CommTimeouts.WriteTotalTimeoutMultiplier &&
/****************************************************************************
* End of Modification done by Maneesh Gupta
****************************************************************************/
!pPortObj->CommTimeouts.WriteTotalTimeoutConstant) {
do { // start writing until completion
while (pPortObj->pPortData.QOutCount && CheckPrinterStatus (pPortObj, uStatusPort))
{
OutByte(uDataPort, *pSourceBytes++);
pPortObj->pPortData.QOutCount --;
}
} while (pPortObj->pPortData.QOutCount);
} else {
// compute timeout
/****************************************************************************
* Modification done by Maneesh Gupta
*
* modifying register access with the help of dwPrinterRegMultiplier
****************************************************************************/
ulTimeout= NumberOfBytes*pPortObj->CommTimeouts.WriteTotalTimeoutMultiplier+
/****************************************************************************
* End of Modification done by Maneesh Gupta
****************************************************************************/
pPortObj->CommTimeouts.WriteTotalTimeoutConstant;
ulStartTime=GetTickCount(); // get starting time
do {
while (pPortObj->pPortData.QOutCount && CheckPrinterStatus (pPortObj, uStatusPort))
{
OutByte(uDataPort, *pSourceBytes++);
pPortObj->pPortData.QOutCount --;
}
ulEndTime=GetTickCount(); // get elapsed time
// if timeout or all written, exit
} while (pPortObj->pPortData.QOutCount && ulEndTime-ulStartTime < ulTimeout);
// return bytes actuall written
TotalWritten-=pPortObj->pPortData.QOutCount;
}
if (TotalWritten != NumberOfBytes)
DEBUGMSG(ZONE_ERROR,(TEXT("LPT_Write: Timeout after %u of %u written.\r\n"),TotalWritten,NumberOfBytes));
return TotalWritten;
}
ULONG
LPT_Seek(
PPortInformation pPortObj,
LONG Position,
DWORD Type
)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_Seek: entry\r\n")));
return (ULONG)-1;
}
/*
@doc EXTERNAL
@func BOOL | LPT_PowerUp | Turn power on to parallel device
* Exported to users.
@rdesc This routine returns a status of 1 if unsuccessful and 0 otherwise.
*/
BOOL
LPT_PowerUp(
PPortInformation pPortObj /*@parm Handle to device. */
)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_PowerUp: entry\r\n")));
return 1;
}
/*
@doc EXTERNAL
@func BOOL | LPT_PowerDown | Turns off power to parallel device.
* Exported to users.
@rdesc This routine returns a status of 1 if unsuccessful and 0 otherwise.
*/
BOOL
LPT_PowerDown(
PPortInformation pPortObj /*@parm Handle to device. */
)
{
DEBUGMSG(ZONE_IO,(TEXT("LPT_PowerDown: entry\r\n")));
return 1;
}
/* ****************************************************************
*
* Win32 Comm Api Support follows.
*
* @doc EXTERNAL
*/
// ****************************************************************
//
// @func BOOL | LPT_IOControl | Device IO control routine
// @parm DWORD | dwOpenData | value returned from COM_Open call
// @parm DWORD | dwCode | io control code to be performed
// @parm PBYTE | pBufIn | input data to the device
// @parm DWORD | dwLenIn | number of bytes being passed in
// @parm PBYTE | pBufOut | output data from the device
// @parm DWORD | dwLenOut |maximum number of bytes to receive from device
// @parm PDWORD | pdwActualOut | actual number of bytes received from device
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// @remark Routine exported by a device driver. "PAR" is the string
// passed in as lpszType in RegisterDevice
BOOL
LPT_IOControl(PPortInformation pPortObj,
DWORD dwCode, PBYTE pBufIn,
DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut,
PDWORD pdwActualOut)
{
BOOL RetVal = TRUE; // Initialize to success
unsigned int ulStartTime;
unsigned int ulTimeout;
DWORD dwRet;
WORD wTemp;
DEBUGMSG(ZONE_IO,(TEXT("LPT_IOControl: entry code=%u\r\n"),dwCode));
switch (dwCode) {
case IOCTL_PARALLEL_SET_TIMEOUTS:
// if input buffer too small
if (dwLenIn < sizeof(COMMTIMEOUTS))
return FALSE; // return error
// copy timeouts into port info struct
memcpy(&pPortObj->CommTimeouts,pBufIn,sizeof(COMMTIMEOUTS));
break;
case IOCTL_PARALLEL_GET_TIMEOUTS:
// if output buffer too small
if ((unsigned int)dwLenOut < (unsigned int)sizeof(COMMTIMEOUTS))
{
*pdwActualOut=0; // return error
return FALSE;
}
// copy current timeouts to output
memcpy(pBufOut,&pPortObj->CommTimeouts,sizeof(COMMTIMEOUTS));
// return timeout size
*pdwActualOut= sizeof(COMMTIMEOUTS);
break;
case IOCTL_PARALLEL_GETDEVICEID:
// compute timeout
ulTimeout= pPortObj->CommTimeouts.WriteTotalTimeoutConstant;
ulStartTime=GetTickCount();
do {
dwRet=0;
// Change to proper mode. We always read the device id in nibble mode.
TerminateChannel(pPortObj);
if (Nibble_Connect(pPortObj, NIBBLE_MODE | PN_REQ_DEVID) != PD_SUCCESS)
{
DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] Nibble_Connect fail\r\n")));
continue;
}
// Try for up to T(l) to get DataAvail
// Some slow devices might require this
/****************************************************************************
* Modification done by Maneesh Gupta
*
* modifying register access with the help of dwPrinterRegMultiplier
****************************************************************************/
if (!CheckPort(pPortObj->ulBase + 1 * dwPrinterRegMultiplier, 0x08, 0x00, P1284_TL_MS))
/****************************************************************************
* End of Modification done by Maneesh Gupta
****************************************************************************/
{
DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] Couldn't Read ID!\r\n")));
TerminateChannel(pPortObj);
continue;
}
// Read ID length.
if (!NibbleRead(pPortObj->ulBase, (LPSTR)&wTemp, 2, &dwRet))
{
DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] Couldn't read size bytes.\r\n")));
TerminateChannel(pPortObj);
continue;
}
// Determine the size of the ID string
if ((wTemp = swapbyte(wTemp)) <= 2)
{
TerminateChannel(pPortObj);
continue;
}
DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] ID string length + 2=%u\r\n"),wTemp));
// Adjust of the two size bytes
wTemp -= 2;
if (dwLenOut < wTemp)
wTemp = (WORD)dwLenOut-1;
// Read the remainder of the id string
NibbleRead ( pPortObj->ulBase, pBufOut, (DWORD)wTemp, &dwRet);
TerminateChannel(pPortObj);
pBufOut[dwRet]='\0';
*pdwActualOut= dwRet;
if (!dwRet)
Sleep(1000);
} while (!dwRet && (unsigned int)GetTickCount()-ulStartTime < ulTimeout);
DEBUGMSG(ZONE_IO,(TEXT("[LPT_IOControl GetDeviceID] dwRet %d timeout %d\r\n"),
dwRet, (unsigned int)GetTickCount()-ulStartTime > ulTimeout));
if (!dwRet && ((unsigned int)GetTickCount()-ulStartTime > ulTimeout))
RetVal= FALSE;
break;
case IOCTL_PARALLEL_WRITE:
LPT_Write(pPortObj, pBufIn, dwLenIn);
break;
case IOCTL_PARALLEL_GET_ECP_CHANNEL32:
// if output buffer too small
if ((unsigned int)dwLenOut < 4)
{
*pdwActualOut=0; // return error
return FALSE;
}
*pdwActualOut=Get_DJ400_Dev_Status(pPortObj->ulBase, pBufOut);
NegotiateChannel(pPortObj,FALSE);
if (pPortObj->bCurrentMode == NIBBLE_MODE)
{
DEBUGMSG(ZONE_IO,(TEXT("[LPT_Open]: In NIBBLE_MODE calling TerminateChannel...\r\n")));
// If we are in nibble mode return to the forward direction
TerminateChannel(pPortObj);
}
break;
case IOCTL_PARALLEL_STATUS:
// if output buffer too small
if ((unsigned int)dwLenOut < 4)
{
*pdwActualOut=0; // return error
return FALSE;
}
// copy current status to output
memcpy(pBufOut,&pPortObj->pPortData.dwCommError,4);
*pdwActualOut= 4;
break;
}
return RetVal;
}
/****************************************************************************
* Modification done by Maneesh Gupta
*
* Function: VirtualAddress
* Input: unsigned StartAddress
* unsigned Length
* Output: Success: Pointer to start of Virtual Address Space allocated.
* Failure: NULL
* Synopsis: This routine maps "Length" bytes of physical memory starting
* at "StartAddress" into the Virtual Address Space and returns
* a pointer to the start of this Virtual Address Space.
******************************************************************************/
unsigned VirtualAddress(unsigned StartAddress, unsigned Length)
{
unsigned *VirtAddr;
DEBUGMSG(1, (TEXT("+VirtualAddress(0x%x, 0x%x): "), StartAddress, Length));
VirtAddr = VirtualAlloc(0, Length, MEM_RESERVE, PAGE_NOACCESS);
DEBUGMSG(1, (TEXT("Got VirtAddr = 0x%x\r\n"), VirtAddr));
if ( VirtAddr == NULL ) {
ERRORMSG(1, (TEXT("DD2: MapAddress: VirtualAlloc failed for %d bytes!\r\n"), Length));
return FALSE;
}
else {
if ( !VirtualCopy((PVOID)VirtAddr, (PVOID)StartAddress,
Length, PAGE_READWRITE|PAGE_NOCACHE) ) {
ERRORMSG(1, (TEXT("DD2: MapAddress: VirtualCopy failed for Physical Address 0x%08x!\r\n"), StartAddress));
return FALSE;
}
}
return (unsigned)VirtAddr;
}
/****************************************************************************
* End of Modification done by Maneesh Gupta
****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -