?? lpt.c
字號:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
/*++
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.
Module Name:
lpt.c
Abstract:
LPT_Xxx Streams interface for USB Print Client Driver.
Functions:
Notes:
--*/
#include "usbprn.h"
const TCHAR g_sPortsKey[] = TEXT("Printers\\Ports");
BOOL
RegisterLPTName(
LPTSTR ActivePath,
LPTSTR PortName
);
BOOL
DeregisterLPTName(
LPTSTR PortName
);
BOOL
RegisterPrinterSettings(
PUSBPRN_CONTEXT pUsbPrn
);
BOOL
DeregisterPrinterSettings(
PUSBPRN_CONTEXT pUsbPrn
);
PUSBPRN_CONTEXT
GetContextFromReg(
LPTSTR ActivePath
);
DWORD
LPT_ReadComplete(
PVOID Context
);
DWORD
LPT_WriteComplete(
PVOID Context
);
/*++
Called by Device Manager to initialize the streams interface in response to ActivateDevice.
We passed ActivateDevice a pointer to our device context, but must read it out of the registry as "ClientInfo".
Returns context used in XXX_Open, XXX_PowerDown, XXX_PowerUp, and XXX_Deinit
--*/
PUSBPRN_CONTEXT
LPT_Init(
PVOID Context
)
{
LPTSTR ActivePath = (LPTSTR)Context; // HKLM\Drivers\Active\xx
PUSBPRN_CONTEXT pUsbPrn = NULL;
BOOL bRc = FALSE;
DEBUGMSG(ZONE_LPT_INIT, (TEXT(">LPT_Init(%p)\n"), Context));
//
// get our Context
//
pUsbPrn = GetContextFromReg( ActivePath );
//
// Register our file device (LPT) name
//
if ( VALID_CONTEXT( pUsbPrn ) ) {
EnterCriticalSection(&pUsbPrn->Lock);
do {
if ( pUsbPrn->ActivePath ) {
DEBUGMSG(ZONE_ERR, (TEXT("Existing ActivePath: %s\n"), pUsbPrn->ActivePath));
TEST_TRAP();
break;
}
pUsbPrn->ActivePath = ActivePath;
memset( pUsbPrn->PortName, 0, sizeof(pUsbPrn->PortName));
bRc = RegisterLPTName( ActivePath,
pUsbPrn->PortName );
if ( !bRc ) {
DEBUGMSG(ZONE_ERR, (TEXT("RegisterLPTName Failed\n")));
break;
}
bRc = RegisterPrinterSettings( pUsbPrn );
if ( !bRc ) {
DEBUGMSG(ZONE_ERR, (TEXT("RegisterPrinterSettings Failed\n")));
break;
}
} while (0);
LeaveCriticalSection(&pUsbPrn->Lock);
}
DEBUGMSG(ZONE_LPT_INIT, (TEXT("<LPT_Init:0x%x\n"), pUsbPrn ));
return (bRc ? pUsbPrn : NULL);
}
BOOL
LPT_Deinit(
PUSBPRN_CONTEXT pUsbPrn
)
{
BOOL bRc = FALSE;
DEBUGMSG(ZONE_LPT_INIT, (TEXT(">LPT_Deinit\n")));
if ( VALID_CONTEXT( pUsbPrn ) ) {
EnterCriticalSection( &pUsbPrn->Lock );
#if DEBUG
if (pUsbPrn->Flags.Open) {
DEBUGMSG(ZONE_ERR, (TEXT("LPT_Deinit on Open Device!\n")));
TEST_TRAP();
}
#endif
bRc = DeregisterLPTName( pUsbPrn->PortName );
if ( !bRc ) {
DEBUGMSG(ZONE_ERR, (TEXT("DeregisterLPTName Failed\n")));
}
memset( pUsbPrn->PortName, 0, sizeof(pUsbPrn->PortName));
bRc = DeregisterPrinterSettings( pUsbPrn );
if ( !bRc ) {
DEBUGMSG(ZONE_ERR, (TEXT("DeregisterPrinterSettings Failed\n")));
}
LeaveCriticalSection(&pUsbPrn->Lock);
}
DEBUGMSG(ZONE_LPT_INIT, (TEXT("<LPT_Deinit:%d\n"), bRc));
return bRc;
}
//
// Returns open context to be used in the
// XXX_Read, XXX_Write, XXX_Seek, and XXX_IOControl functions.
// If the device cannot be opened, this function returns NULL.
//
PUSBPRN_CONTEXT
LPT_Open(
PUSBPRN_CONTEXT Context, // context returned by LPT_Init.
DWORD AccessCode, // @parm access code
DWORD ShareMode // @parm share mode
)
{
PUSBPRN_CONTEXT pUsbPrn = Context;
BOOL bRc = TRUE;
UNREFERENCED_PARAMETER(ShareMode);
UNREFERENCED_PARAMETER(AccessCode);
DEBUGMSG(ZONE_LPT_INIT,(TEXT(">LPT_Open(0x%x, 0x%x, 0x%x)\n"),pUsbPrn, AccessCode, ShareMode));
if ( VALID_CONTEXT( pUsbPrn ) ) {
EnterCriticalSection(&pUsbPrn->Lock);
if ( !pUsbPrn->Flags.Open &&
!pUsbPrn->Flags.UnloadPending ) {
pUsbPrn->Flags.Open = TRUE;
ResetEvent( pUsbPrn->hCloseEvent ); // non-signaled
} else {
DEBUGMSG( ZONE_ERR,(TEXT("LPT_Open: ERROR_ACCESS_DENIED\n")));
SetLastError(ERROR_ACCESS_DENIED);
bRc = FALSE;
}
LeaveCriticalSection(&pUsbPrn->Lock);
} else {
DEBUGMSG( ZONE_ERR,(TEXT("LPT_Open: ERROR_FILE_NOT_FOUND\n")));
SetLastError(ERROR_FILE_NOT_FOUND);
bRc = FALSE;
}
DEBUGMSG(ZONE_LPT_INIT,(TEXT("<LPT_Open:%d\n"), bRc ));
return (bRc ? pUsbPrn : NULL);
}
BOOL
LPT_Close(
PUSBPRN_CONTEXT Context
)
{
PUSBPRN_CONTEXT pUsbPrn = Context;
DEBUGMSG(ZONE_LPT_INIT,(TEXT("LPT_Close(0x%x)\n"),pUsbPrn));
if ( VALID_CONTEXT( pUsbPrn ) ) {
EnterCriticalSection(&pUsbPrn->Lock);
pUsbPrn->Flags.Open = FALSE;
LeaveCriticalSection(&pUsbPrn->Lock);
//
// Note: any waiters are run as soon as we signal this event
//
return SetEvent( pUsbPrn->hCloseEvent );
} else {
DEBUGMSG( ZONE_ERR,(TEXT("LPT_Close: ERROR_INVALID_HANDLE\n")));
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
}
#define MAX_USBTRANSFER_SIZE 0x1000 // 4k
//
// Printers are sequential byte processing devices,
// so no need for anything fancy
//
ULONG
LPT_Write(
PUSBPRN_CONTEXT pUsbPrn,
PUCHAR pBuffer,
ULONG BufferLength
)
{
DWORD dwTimeout;
DWORD dwTransferSize;
DWORD dwBytesTransferred ;
DWORD dwTatalTransferred = 0 ;
DWORD dwErr = ERROR_SUCCESS;
DWORD dwUsbErr = USB_NO_ERROR;
DEBUGMSG(ZONE_LPT_WRITE,(TEXT(">LPT_Write(0x%x, %d)\n"),pBuffer, BufferLength));
if ( ACCEPT_IO( pUsbPrn ) ) {
while ( pBuffer && BufferLength) {
dwTransferSize=min(BufferLength,MAX_USBTRANSFER_SIZE);
dwTimeout = dwTransferSize * pUsbPrn->Timeouts.WriteTotalTimeoutMultiplier +
pUsbPrn->Timeouts.WriteTotalTimeoutConstant;
if (!dwTimeout) {
dwTimeout = INFINITE;
}
DEBUGMSG(ZONE_LPT_WRITE, (TEXT("LPT_Write timeout due in %d msec\n"), dwTimeout));
EnterCriticalSection( &pUsbPrn->Lock );
dwBytesTransferred = 0 ;
dwErr = IssueBulkTransfer( pUsbPrn->UsbFuncs,
pUsbPrn->BulkOut.hPipe,
DefaultTransferComplete, // Callback
pUsbPrn->BulkOut.hEvent, // Context
(USB_OUT_TRANSFER /*| USB_SHORT_TRANSFER_OK*/), // Flags
pBuffer, 0,
dwTransferSize,
&dwBytesTransferred,
dwTimeout,
&dwUsbErr );
if ( ERROR_SUCCESS != dwErr || USB_NO_ERROR != dwUsbErr) {
DEBUGMSG( ZONE_ERR, (TEXT("IssueBulkTransfer error:%d, 0x%x\n"), dwErr, dwUsbErr));
IoErrorHandler( pUsbPrn, pUsbPrn->BulkOut.hPipe, pUsbPrn->BulkOut.bIndex, dwUsbErr);
LeaveCriticalSection( &pUsbPrn->Lock );
break;
}
else {
LeaveCriticalSection( &pUsbPrn->Lock );
pBuffer +=dwTransferSize;
BufferLength -=dwTransferSize;
dwTatalTransferred +=dwTransferSize;
}
};
} else {
DEBUGMSG( ZONE_ERR,(TEXT("LPT_Write: ERROR_INVALID_HANDLE\n")));
dwTatalTransferred=(DWORD)-1;
SetLastError(ERROR_INVALID_HANDLE);
}
DEBUGMSG(ZONE_LPT_WRITE,(TEXT("<LPT_Write:%d\n"), dwTatalTransferred ));
return dwTatalTransferred;
}
ULONG
LPT_Read(
PUSBPRN_CONTEXT pUsbPrn,
PUCHAR pBuffer,
ULONG BufferLength
)
{
DWORD dwTimeout;
DWORD dwBytesTransferred = 0;
DWORD dwErr = ERROR_SUCCESS;
DWORD dwUsbErr = USB_NO_ERROR;
DEBUGMSG(ZONE_LPT_READ,(TEXT(">LPT_Read(0x%x, %d)\n"),pBuffer, BufferLength));
if ( ACCEPT_IO( pUsbPrn ) ) {
if ( pBuffer && BufferLength ) {
EnterCriticalSection( &pUsbPrn->Lock );
dwTimeout = BufferLength * pUsbPrn->Timeouts.ReadTotalTimeoutMultiplier +
pUsbPrn->Timeouts.ReadTotalTimeoutConstant;
if (!dwTimeout) {
dwTimeout = INFINITE;
}
DEBUGMSG(ZONE_LPT_READ, (TEXT("LPT_Read timeout due in %d msec\n"), dwTimeout));
dwErr = IssueBulkTransfer( pUsbPrn->UsbFuncs,
pUsbPrn->BulkIn.hPipe,
DefaultTransferComplete, // Callback
pUsbPrn->BulkIn.hEvent, // Context
(USB_IN_TRANSFER | USB_SHORT_TRANSFER_OK), // Flags
pBuffer, 0,
BufferLength,
&dwBytesTransferred,
dwTimeout,
&dwUsbErr );
if ( ERROR_SUCCESS != dwErr || USB_NO_ERROR != dwUsbErr) {
DEBUGMSG( ZONE_ERR, (TEXT("IssueBulkTransfer error:%d, 0x%x\n"), dwErr, dwUsbErr));
IoErrorHandler( pUsbPrn, pUsbPrn->BulkOut.hPipe, pUsbPrn->BulkOut.bIndex, dwUsbErr);
}
LeaveCriticalSection( &pUsbPrn->Lock );
} else {
DEBUGMSG( ZONE_ERR,(TEXT("LPT_Read: ERROR_INVALID_PARAMETER\n")));
SetLastError(ERROR_INVALID_PARAMETER );
}
} else {
DEBUGMSG( ZONE_ERR,(TEXT("LPT_Read: ERROR_INVALID_HANDLE\n")));
SetLastError(ERROR_INVALID_HANDLE);
}
DEBUGMSG(ZONE_LPT_READ,(TEXT("<LPT_Read:%d\n"), dwBytesTransferred));
return dwBytesTransferred;
}
BOOL
LPT_IOControl(
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -