DWORD WatchPrintProc(LPVOID lpdata)
{
PPRINTER_NOTIFY_INFO pNotification = NULL;
WORD JobFields[] =
{
JOB_NOTIFY_FIELD_PRINTER_NAME,
JOB_NOTIFY_FIELD_MACHINE_NAME,
JOB_NOTIFY_FIELD_PORT_NAME,
JOB_NOTIFY_FIELD_USER_NAME,
JOB_NOTIFY_FIELD_NOTIFY_NAME,
JOB_NOTIFY_FIELD_DATATYPE,
JOB_NOTIFY_FIELD_PRINT_PROCESSOR,
JOB_NOTIFY_FIELD_PARAMETERS,
JOB_NOTIFY_FIELD_DRIVER_NAME,
JOB_NOTIFY_FIELD_DEVMODE,
JOB_NOTIFY_FIELD_STATUS,
JOB_NOTIFY_FIELD_STATUS_STRING,
JOB_NOTIFY_FIELD_DOCUMENT,
JOB_NOTIFY_FIELD_PRIORITY,
JOB_NOTIFY_FIELD_POSITION,
JOB_NOTIFY_FIELD_SUBMITTED,
JOB_NOTIFY_FIELD_START_TIME,
JOB_NOTIFY_FIELD_UNTIL_TIME,
JOB_NOTIFY_FIELD_TIME,
JOB_NOTIFY_FIELD_TOTAL_PAGES,
JOB_NOTIFY_FIELD_PAGES_PRINTED,
JOB_NOTIFY_FIELD_TOTAL_BYTES,
JOB_NOTIFY_FIELD_BYTES_PRINTED
};
PRINTER_NOTIFY_OPTIONS_TYPE Notifications[1] =
{
{
JOB_NOTIFY_TYPE,
0,
0,
0,
sizeof(JobFields) / sizeof(JobFields[0]),
JobFields
},
};
PRINTER_NOTIFY_OPTIONS NotificationOptions =
{
2,
PRINTER_NOTIFY_OPTIONS_REFRESH,
sizeof(Notifications) / sizeof(Notifications[0]),
Notifications
};
LPSTR pszTitle = NULL ;
LPSTR pszName = NULL ;
LPSTR pszShareName = NULL ;
int * pCmdtCode = NULL ;
switch( (int)lpdata )
{
case 0 :
pszTitle = g_WatchPrint.szTitle1 ;
pszName = g_WatchPrint.szName1 ;
pszShareName = g_WatchPrint.szShare1 ;
pCmdtCode = &g_WatchPrint.nCmdtCode1 ;
break ;
case 1 :
pszTitle = g_WatchPrint.szTitle2 ;
pszName = g_WatchPrint.szName2 ;
pszShareName = g_WatchPrint.szShare2 ;
pCmdtCode = &g_WatchPrint.nCmdtCode2 ;
break ;
default :
return 0 ;
}
if( !pszTitle || !pszShareName || !pCmdtCode || !pszName )
return 0 ;
if( !strlen( pszTitle ) )
return 0;
std::map<int,int> MapId ;
HANDLE hPrinter = NULL;
while(TRUE){
DWORD dwNeeded = NULL,
dwReturned = NULL;
// CString strPrinter = "HP LaserJet P2035";
// CString strPrinter = "PC01에서 자동 EPSON Stylus Photo R210 Series";
// CString strPrinter = g_WatchPrint.szPrintName1 ;
CString strPrinter;
EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 1, NULL, 0, &dwNeeded, &dwReturned) ;
if( dwNeeded <= 0 ){
CDebug::dprintf( "Failed EnumPrinters\n" ) ;
return 0 ;
}
// CDebug::dprintf( "EnumPrinter( %d , %d )\n" , dwNeeded , dwReturned ) ;
LPBYTE lpBuffer = new BYTE[dwNeeded];
EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, NULL, 1, lpBuffer, dwNeeded, &dwNeeded, &dwReturned);
CDebug::dprintf( "EnumPrinter( %d , %d )\n" , dwNeeded , dwReturned ) ;
PPRINTER_INFO_1 p1 = (PPRINTER_INFO_1) lpBuffer;
for (DWORD x = 0; x < dwReturned; x++)
{
// CDebug::dprintf("EnumPrinter(%d) (%s-%s)\n", dwReturned , p1->pName , g_WatchPrint.szTitle1) ;
//
// 공유된 프린터 라면 공유 이름으로 프린터를 찾는다.
if( strlen( pszShareName )){
OpenPrinter((LPTSTR) (LPCTSTR) p1->pName, &hPrinter, NULL);
if( !hPrinter )
continue ;
BOOL IsFind = FALSE ;
DWORD dwNeeded = ::DocumentProperties(NULL, hPrinter, (LPTSTR) (LPCTSTR) p1->pName, NULL, NULL, 0) ;
::GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
PRINTER_INFO_2 *pi2 = (PRINTER_INFO_2 *)::GlobalAlloc(GPTR,dwNeeded);
GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
CDebug::dprintf( "Printer - DriverName=%s - %s , ShareName=%s - %s \n" , pi2->pDriverName , pszName , pi2->pShareName , pszShareName ) ;
if( strcmp( pi2->pDriverName , pszName ) == 0 && strcmp( pi2->pShareName , pszShareName ) == 0 ){
IsFind = TRUE ;
strPrinter = p1->pName ;
}
::GlobalFree(pi2) ;
if( IsFind )
break ;
ClosePrinter( hPrinter ) ;
}
else if( strstr( p1->pName , pszTitle ) ){ // 공유된 프린터가 아니라면( 네트웍프린터 ) 프린터 타이틀로 프린터를 찾는다.
strPrinter = p1->pName ;
OpenPrinter((LPTSTR) (LPCTSTR) strPrinter, &hPrinter, NULL);
break ;
}
p1++;
}
delete lpBuffer;
if( strPrinter.IsEmpty() )
return 0;
// HANDLE hPrinter;
// OpenPrinter((LPTSTR) (LPCTSTR) strPrinter, &hPrinter, NULL);
if( !hPrinter )
return 0;
// get a handle to a printer change notification object.
HANDLE hChange = FindFirstPrinterChangeNotification(hPrinter,
PRINTER_CHANGE_ALL,
0,
&NotificationOptions);
DWORD dwChange;
HANDLE aHandles[2];
aHandles[0] = hChange;
::GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
PRINTER_INFO_2 *pi2 = (PRINTER_INFO_2 *)::GlobalAlloc(GPTR,dwNeeded);
::GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
if( /*strncmp( pi2->pPortName , "\\\\" , strlen( "\\\\" ) ) == 0 || strncmp( pi2->pPortName , "IP" , strlen( "IP" ) ) == 0 ||*/ ( pi2->pServerName && strlen(pi2->pServerName) ) ){
CDebug::dprintf("==========================================================\n");
CDebug::dprintf("It is Not Local Printer1(%s) \n", strPrinter );
CDebug::dprintf("==========================================================\n");
FindClosePrinterChangeNotification(hChange);
hChange = INVALID_HANDLE_VALUE;
ClosePrinter( hPrinter );
hPrinter = NULL ;
return 0;
}
// Office 레지 등록 (워드 카피수 오류 수정)
CRegistry reg;
if (reg.Open(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Office\\11.0\\Word\\Options", KEY_ALL_ACCESS)){ // 2003
DWORD dwReadData = 0 ;
reg.ReadDWORD("ForceSetCopyCount" , dwReadData ) ;
if( dwReadData != 1 )
reg.WriteDWORD("ForceSetCopyCount",1) ;
reg.Close() ;
}
if (reg.Open(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Office\\12.0\\Word\\Options", KEY_ALL_ACCESS)){ // 2007
DWORD dwReadData = 0 ;
reg.ReadDWORD("ForceSetCopyCount" , dwReadData ) ;
if( dwReadData != 1 )
reg.WriteDWORD("ForceSetCopyCount",1) ;
reg.Close() ;
}
if (reg.Open(HKEY_CURRENT_USER, "SOFTWARE\\Microsoft\\Office\\14.0\\Word\\Options", KEY_ALL_ACCESS)){ //2010
DWORD dwReadData = 0 ;
reg.ReadDWORD("ForceSetCopyCount" , dwReadData ) ;
if( dwReadData != 1 )
reg.WriteDWORD("ForceSetCopyCount",1) ;
reg.Close() ;
}
CDebug::dprintf("==========================================================\n");
CDebug::dprintf("WatchPrint1 - Build(06-09) - (%s) \n", strPrinter );
CDebug::dprintf("==========================================================\n");
MapId.clear() ;
while (hChange != INVALID_HANDLE_VALUE)
{
// sleep until a printer change notification wakes this thread or the
// event becomes set indicating it's time for the thread to end.
WaitForMultipleObjects(2, aHandles, FALSE, INFINITE);
if (WaitForSingleObject(hChange, 0U) == WAIT_OBJECT_0)
{
FindNextPrinterChangeNotification(hChange, &dwChange, &NotificationOptions, (LPVOID *) &pNotification);
if (pNotification != NULL)
{
// if a notification overflow occurred,
if (pNotification->Flags & PRINTER_NOTIFY_INFO_DISCARDED)
{
DWORD dwOldFlags = NotificationOptions.Flags;
// we must refresh to continue
NotificationOptions.Flags = PRINTER_NOTIFY_OPTIONS_REFRESH;
FreePrinterNotifyInfo(pNotification);
FindNextPrinterChangeNotification(hChange, &dwChange, &NotificationOptions, (LPVOID *) &pNotification);
NotificationOptions.Flags = dwOldFlags;
}
// int nbeganTime = 0 ;
int nStatus = NULL;
int nCopies = 0 ;
int nCopies1 = 0 ;
int nId = 0 ;
// BOOL IsLocal = FALSE ;
// CDebug::dprintf("WatchPrint1 - Notifi (%d) \n", pNotification->Count );
// iterate through each notification
int nTotalPages = 0 ;
int nTotalPages1 = 0 ;
BOOL bNewDataID = FALSE ;
char szComName[40] = {0,} ;
for (DWORD x = 0; x < pNotification->Count; x++)
{
ASSERT(pNotification->aData[x].Type == JOB_NOTIFY_TYPE);
if( pNotification->aData[x].Id ){
nId = pNotification->aData[x].Id ;
if (pNotification->aData[x].Field == JOB_NOTIFY_FIELD_TOTAL_PAGES){
nTotalPages1 = pNotification->aData[x].NotifyData.adwData[0];
// CDebug::dprintf("JOB_NOTIFY_FIELD_TOTAL_PAGES(%d) \n", nTotalPages1 );
}else if (pNotification->aData[x].Field == JOB_NOTIFY_FIELD_STATUS){
TRACE( "JOB_NOTIFY_FIELD_STATUS ( %d )\n" , pNotification->aData[x].NotifyData.adwData[0] ) ;
/*if( pNotification->aData[x].NotifyData.adwData[0] == JOB_STATUS_PRINTED ){
}
else*/ if( nStatus != JOB_STATUS_PRINTED || nStatus != JOB_STATUS_PRINTING ){
nStatus = pNotification->aData[x].NotifyData.adwData[0];
if( nStatus == JOB_STATUS_PRINTING || nStatus == JOB_STATUS_PRINTED ){
if( MapId.find( nId ) == MapId.end() ){
if( nCopies == 0 ){
/* for( int i = 0 ; i < 6 ; i++ ){
CSpoolReader reader( strPrinter , nId ) ;
nCopies = reader.GetCopies() ;
if( nCopies > 0 )
break ;
Sleep( 400 ) ;
}*/
JOB_INFO_2 *pd_JobInfo = NULL;
DWORD dwNeed = NULL ;
DWORD dwJobId = NULL ;
DWORD dwRet = NULL ;
if( GetJob( hPrinter,nId , 2, NULL , NULL, &dwNeeded) ){
pd_JobInfo = (JOB_INFO_2 *)malloc(dwNeeded);
if( GetJob( hPrinter, nId, 2, (LPBYTE)pd_JobInfo , dwNeeded , &dwRet) ){
nTotalPages = pd_JobInfo->PagesPrinted + pd_JobInfo->TotalPages ;
if( nCopies < 1 ){
DEVMODE *pDevMode = pd_JobInfo->pDevMode;
nCopies = pDevMode->dmCopies ;
}
}
free(pd_JobInfo) ;
}
}
CDebug::dprintf( "Printer page copies (%d)\n" , nCopies ) ;
bNewDataID = TRUE ;
}
}
}
}
else if (pNotification->aData[x].Field == JOB_NOTIFY_FIELD_DEVMODE){
DEVMODE DMode ;
memcpy( &DMode, (void*)pNotification->aData[x].NotifyData.adwData[1], sizeof DMode ) ;
nCopies1 = DMode.dmCopies ; // 인쇄 매수
CDebug::dprintf( "Printer page copies1 (%d)\n" , nCopies ) ;
}
else if ( pNotification->aData[x].Field == JOB_NOTIFY_FIELD_MACHINE_NAME ){
LPSTR pszSendComName = (LPSTR)pNotification->aData[x].NotifyData.Data.pBuf ;
if( pszSendComName[0] == '\\' && pszSendComName[1] == '\\' )
STRnCPY( szComName , &pszSendComName[2] ) ;
else
STRnCPY( szComName , pszSendComName ) ;
/* char szComName[MAX_PATH] ;
DWORD dwSize = MAX_PATH ;
GetComputerName( szComName , &dwSize ) ;
TCHAR szIP[100] = {0,} ;
DWORD dwip = GetHostIPAddr();
CFNUtil fn;
STRnCPY(szIP, fn.LipToSip(dwip, TRUE));
// 자기 자신이 보낸게 아니라면 무시한다.
// 보낸곳이 로컬이라면 저장 과금 한다. ( "\\kky"로 시작 한다면 "\\" 빼주고 비교 한다. )
if( pszSendComName[0] == '\\' && pszSendComName[1] == '\\' ){
if( strcmp( &pszSendComName[2] , szComName ) == 0 ) // 컴 이름
IsLocal = TRUE ;
else if( strcmp( &pszSendComName[2] , szIP ) == 0 ) // ip 체크
IsLocal = TRUE ;
}
else{
if( strcmp( pszSendComName , szComName ) == 0 ) // 컴 이름
IsLocal = TRUE ;
else if( strcmp( pszSendComName , szIP ) == 0 ) // ip 체크
IsLocal = TRUE ;
}
*/
}
// CDebug::dprintf("Notification->Count(%d , %d) \n", nId , x );
if( nStatus == JOB_STATUS_PRINTED || nStatus == JOB_STATUS_PRINTING){
if( nCopies < 1 && nCopies1 > 0 )
nCopies = nCopies1 ;
if( nTotalPages < 1 && nTotalPages1 > 0 )
nTotalPages = nTotalPages1 ;
CDebug::dprintf("JOB_STATUS_PRINTING - Pages(%d) - Copies(%d) \n", nTotalPages , nCopies );
nTotalPages *= nCopies ;
if( nTotalPages > 0 ){
// if( MapId.find( pNotification->aData[x].Id ) == MapId.end() ){
if( bNewDataID ){
MapId.insert( std::make_pair(pNotification->aData[x].Id ,pNotification->aData[x].Id ) ) ;
// if( IsLocal ){
// CString sLog ;
// sLog.Format( "BillingPrint - Printer(%s) - Pages(%d) - Cmdt(%d) - ComName(%s)\n", pszName , nTotalPages , *pCmdtCode , szComName ) ;
// CDebug::dprintf("BillingPrint - Pages(%d) - Cmdt(%d) - ComName(%s)\n", nTotalPages , *pCmdtCode , szComName );
// UM_WRITE_ERROR_LOG(sLog);
if( nTotalPages > 0 && *pCmdtCode > 0 && strlen( szComName ) ){
// 서버로 출력되었다고 보낸다.
_ReqBillingPrint pkt; ZERO_MEM(pkt);
INIT_TCP_CHNL_BOOL(BILLING_R_, cmdReqBillingPrint);
pkt.nTotalPages = nTotalPages ;
pkt.nCmdtCode = *pCmdtCode ;
STRnCPY( pkt.szComName , szComName ) ;
BOOL result = TcpClt.SendPacket(&pkt, sizeof(pkt));
}
// }
}
/* if( nStatus == JOB_STATUS_PRINTED ){
::GetPrinter(hPrinter, 2, 0, 0, &dwNeeded);
PRINTER_INFO_2 *pi2 = (PRINTER_INFO_2 *)::GlobalAlloc(GPTR,dwNeeded);
GetPrinter(hPrinter, 2, (LPBYTE)pi2, dwNeeded, &dwNeeded);
// 인쇄된 프린터 보관 이라면 취소를 날려 출력로그를 없앤다.
if( (pi2->Attributes&PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS)==PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS ){
CDebug::dprintf("JOB_STATUS_PRINTED\n" );
// 프린트 된것은 취소를 날려 출력로그를 없앤다.
JOB_INFO_2 *pd_JobInfo = NULL;
DWORD dwNeed = NULL ;
DWORD dwJobId = NULL ;
DWORD dwRet = NULL ;
GetJob( hPrinter,pNotification->aData[x].Id , 2, (LPBYTE)pd_JobInfo , NULL, &dwNeeded);
pd_JobInfo = (JOB_INFO_2 *)malloc(dwNeeded);
GetJob( hPrinter, pNotification->aData[x].Id, 2, (LPBYTE)pd_JobInfo , dwNeeded , &dwRet);
SetJob( hPrinter , pNotification->aData[x].Id , 2 , (LPBYTE)pd_JobInfo , JOB_CONTROL_CANCEL ) ;
free(pd_JobInfo) ;
}
::GlobalFree(pi2) ;
}*/
nStatus = NULL ;
}
}
}
}
}
FreePrinterNotifyInfo(pNotification);
pNotification = NULL;
}
//
// 요금 부과할 프린터를 바꾸었다면 기존 셋팅을 초기화 하고 다시 셋팅 하여야 한다.
if( !strlen( pszTitle ) || !strstr( strPrinter , pszTitle ) || *pCmdtCode < 1 || m_bWatchPrintProcQuit ){
FindClosePrinterChangeNotification(hChange);
hChange = INVALID_HANDLE_VALUE;
ClosePrinter( hPrinter );
hPrinter = NULL ;
break ;
}
::Sleep(5) ;
} // while
if( !strlen( pszTitle ) || *pCmdtCode < 1 || m_bWatchPrintProcQuit )
break ;
Sleep( 1000 * 5 ) ;
}// while
return 0;
}
댓글 없음:
댓글 쓰기