392 lines
10 KiB
C
392 lines
10 KiB
C
/*++
|
|
|
|
Copyright (c) 1992-1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
prnt_lm.c
|
|
|
|
Abstract:
|
|
|
|
This file contains the routines which actually call Lan Manager and
|
|
retrieve the contents of the print queue table, including cacheing.
|
|
|
|
Environment:
|
|
|
|
User Mode - Win32
|
|
|
|
Revision History:
|
|
|
|
10-May-1996 DonRyan
|
|
Removed banner from Technology Dynamics, Inc.
|
|
|
|
--*/
|
|
|
|
//--------------------------- WINDOWS DEPENDENCIES --------------------------
|
|
|
|
//--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
|
|
|
|
#ifdef WIN32
|
|
#include <windows.h>
|
|
#include <winspool.h>
|
|
#endif
|
|
|
|
#include <tchar.h>
|
|
#include <string.h>
|
|
#include <search.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
//--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
|
|
|
|
|
|
#include "mib.h"
|
|
#include "mibfuncs.h"
|
|
#include "prnt_tbl.h"
|
|
#include "lmcache.h"
|
|
|
|
//--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
|
|
|
|
//--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
|
|
|
|
//--------------------------- PRIVATE CONSTANTS -----------------------------
|
|
|
|
#define SafeBufferFree(x) if(NULL != x) NetApiBufferFree( x )
|
|
#define SafeFree(x) if(NULL != x) SnmpUtilMemFree( x )
|
|
|
|
//--------------------------- PRIVATE STRUCTS -------------------------------
|
|
|
|
//--------------------------- PRIVATE VARIABLES -----------------------------
|
|
|
|
//--------------------------- PRIVATE PROTOTYPES ----------------------------
|
|
|
|
//--------------------------- PRIVATE PROCEDURES ----------------------------
|
|
|
|
|
|
int __cdecl prnt_entry_cmp(
|
|
IN const PRINTQ_ENTRY *A,
|
|
IN const PRINTQ_ENTRY *B
|
|
) ;
|
|
|
|
void build_prnt_entry_oids( );
|
|
|
|
//--------------------------- PUBLIC PROCEDURES -----------------------------
|
|
|
|
|
|
//
|
|
// MIB_prnt_lmget
|
|
// Retrieve print queue table information from Lan Manager.
|
|
// If not cached, sort it and then
|
|
// cache it.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// None.
|
|
//
|
|
SNMPAPI MIB_prntq_lmget(
|
|
)
|
|
|
|
{
|
|
|
|
DWORD entriesread = 0; // init number of table entries read
|
|
DWORD bytesNeeded = 0; // init size needed
|
|
DWORD dwLastError = ERROR_SUCCESS; // init last error to no error
|
|
LPBYTE bufptr;
|
|
unsigned lmCode;
|
|
unsigned i;
|
|
PRINTER_INFO_2 *DataTable;
|
|
PRINTQ_ENTRY *MIB_PrintQTableElement ;
|
|
int First_of_this_block;
|
|
time_t curr_time ;
|
|
BOOL result;
|
|
SNMPAPI nResult = SNMPAPI_NOERROR;
|
|
|
|
|
|
time(&curr_time); // get the time
|
|
|
|
//
|
|
//
|
|
// If cached, return piece of info.
|
|
//
|
|
//
|
|
|
|
if((NULL != cache_table[C_PRNT_TABLE].bufptr) &&
|
|
(curr_time <
|
|
(cache_table[C_PRNT_TABLE].acquisition_time
|
|
+ cache_expire[C_PRNT_TABLE] ) ) )
|
|
{ // it has NOT expired!
|
|
|
|
goto Exit ; // the global table is valid
|
|
|
|
}
|
|
|
|
//
|
|
// remember to free the existing data
|
|
//
|
|
|
|
MIB_PrintQTableElement = MIB_PrintQTable.Table ;
|
|
|
|
// iterate over the whole table
|
|
for(i=0; i<MIB_PrintQTable.Len ;i++)
|
|
{
|
|
// free any alloc'ed elements of the structure
|
|
SnmpUtilOidFree(&(MIB_PrintQTableElement->Oid));
|
|
SafeFree(MIB_PrintQTableElement->svPrintQName.stream);
|
|
|
|
MIB_PrintQTableElement ++ ; // increment table entry
|
|
}
|
|
SafeFree(MIB_PrintQTable.Table) ; // free the base Table
|
|
MIB_PrintQTable.Table = NULL ; // just for safety
|
|
MIB_PrintQTable.Len = 0 ; // just for safety
|
|
|
|
|
|
//
|
|
//
|
|
// Do network call to gather information and put it in a nice array
|
|
//
|
|
//
|
|
|
|
// call it with zero length buffer to get the size
|
|
//
|
|
result = EnumPrinters(
|
|
PRINTER_ENUM_SHARED |
|
|
PRINTER_ENUM_LOCAL, // what type to enum
|
|
NULL, // local server
|
|
2, // level
|
|
NULL, // where to put it
|
|
0, // max of above
|
|
&bytesNeeded, // additional bytes req'd
|
|
&entriesread ); // how many we got this time
|
|
|
|
if (result)
|
|
{
|
|
// When there is no table entries from spooler *and* spooler is
|
|
// running, we'll be here.
|
|
SNMPDBG((
|
|
SNMP_LOG_TRACE,
|
|
"SNMP: LMMIB2: EnumPrinters returns TRUE, bytesNeeded=0x%08lx\n",
|
|
bytesNeeded
|
|
));
|
|
|
|
goto Exit; // get out with 0 entries in the table
|
|
}
|
|
// Assert: result == FALSE
|
|
dwLastError = GetLastError(); // save last error
|
|
|
|
SNMPDBG((
|
|
SNMP_LOG_TRACE,
|
|
"SNMP: LMMIB2: EnumPrinters returns FALSE, bytesNeeded=0x%08lx, dwLastError=0x%08lx\n",
|
|
bytesNeeded, dwLastError
|
|
));
|
|
|
|
if (ERROR_INSUFFICIENT_BUFFER != dwLastError)
|
|
{
|
|
//
|
|
// EnumPrinters Failed and the last error is not
|
|
// ERROR_INSUFFICIENT_BUFFER, we'll bail out with 0 entries in the
|
|
// table.
|
|
// For example, if spooler service was down, we will be here.
|
|
//
|
|
SNMPDBG((
|
|
SNMP_LOG_TRACE,
|
|
"SNMP: LMMIB2: EnumPrinters failed, lasterror != ERROR_INSUFFICIENT_BUFFER, bytesNeeded=%d\n",
|
|
bytesNeeded
|
|
));
|
|
|
|
goto Exit; // get out with 0 entries in the table, so getnext will work
|
|
}
|
|
// Assert: dwLastError == ERROR_INSUFFICIENT_BUFFER
|
|
|
|
bufptr = SnmpUtilMemAlloc(bytesNeeded); // SnmpUtilMemAlloc the buffer
|
|
if(NULL==bufptr)
|
|
{
|
|
nResult = SNMPAPI_ERROR;
|
|
goto Exit ; // can't allocate memory, error out
|
|
}
|
|
|
|
|
|
// then read the rest of it
|
|
// call it again
|
|
result = EnumPrinters(
|
|
PRINTER_ENUM_SHARED |
|
|
PRINTER_ENUM_LOCAL, // what type to enum
|
|
NULL, // local server
|
|
2, // level
|
|
bufptr, // where to put it
|
|
bytesNeeded, // max of above
|
|
&bytesNeeded, // additional bytes req'd
|
|
&entriesread ); // how many we got this time
|
|
|
|
|
|
if (!result) {
|
|
// Signal error
|
|
SafeFree( bufptr );
|
|
nResult = SNMPAPI_ERROR;
|
|
goto Exit;
|
|
}
|
|
|
|
|
|
DataTable = (PRINTER_INFO_2 *) bufptr ;
|
|
|
|
|
|
if(0 == MIB_PrintQTable.Len) { // 1st time, alloc the whole table
|
|
// alloc the table space
|
|
MIB_PrintQTable.Table = SnmpUtilMemAlloc(entriesread *
|
|
sizeof(PRINTQ_ENTRY) );
|
|
// prefix bug 445181
|
|
if (MIB_PrintQTable.Table == NULL) {
|
|
// free the table
|
|
SafeFree( bufptr ) ;
|
|
// Signal error
|
|
nResult = SNMPAPI_ERROR;
|
|
goto Exit;
|
|
}
|
|
}
|
|
|
|
MIB_PrintQTableElement = MIB_PrintQTable.Table ;
|
|
|
|
for(i=0; i<entriesread; i++) { // once for each entry in the buffer
|
|
|
|
// increment the entry number
|
|
|
|
MIB_PrintQTable.Len ++;
|
|
|
|
// Stuff the data into each item in the table
|
|
|
|
// client name
|
|
MIB_PrintQTableElement->svPrintQName.dynamic = TRUE;
|
|
|
|
#ifdef UNICODE
|
|
if (SnmpUtilUnicodeToUTF8(
|
|
&MIB_PrintQTableElement->svPrintQName.stream,
|
|
DataTable->pPrinterName,
|
|
TRUE))
|
|
{
|
|
MIB_PrintQTableElement->svPrintQName.stream = NULL;
|
|
MIB_PrintQTableElement->svPrintQName.length = 0;
|
|
}
|
|
else
|
|
{
|
|
MIB_PrintQTableElement->svPrintQName.length =
|
|
strlen (MIB_PrintQTableElement->svPrintQName.stream);
|
|
}
|
|
#else
|
|
MIB_PrintQTableElement->svPrintQName.stream = SnmpUtilMemAlloc (
|
|
strlen( DataTable->pPrinterName ) + 1 ) ;
|
|
MIB_PrintQTableElement->svPrintQName.length =
|
|
strlen( DataTable->pPrinterName ) ;
|
|
|
|
memcpy( MIB_PrintQTableElement->svPrintQName.stream,
|
|
DataTable->pPrinterName,
|
|
strlen( DataTable->pPrinterName ) ) ;
|
|
#endif
|
|
|
|
// number of connections
|
|
MIB_PrintQTableElement->svPrintQNumJobs =
|
|
DataTable->cJobs;
|
|
|
|
|
|
MIB_PrintQTableElement ++ ; // and table entry
|
|
|
|
DataTable ++ ; // advance pointer to next sess entry in buffer
|
|
|
|
} // for each entry in the data table
|
|
|
|
// free all of the printer enum data
|
|
if(NULL!=bufptr) // free the table
|
|
SnmpUtilMemFree( bufptr ) ;
|
|
|
|
|
|
|
|
|
|
// iterate over the table populating the Oid field
|
|
build_prnt_entry_oids();
|
|
|
|
// Sort the table information using MSC QuickSort routine
|
|
qsort( &MIB_PrintQTable.Table[0], MIB_PrintQTable.Len,
|
|
sizeof(PRINTQ_ENTRY), prnt_entry_cmp );
|
|
|
|
//
|
|
//
|
|
// Cache table
|
|
//
|
|
//
|
|
|
|
if(0 != MIB_PrintQTable.Len) {
|
|
|
|
cache_table[C_PRNT_TABLE].acquisition_time = curr_time ;
|
|
|
|
cache_table[C_PRNT_TABLE].bufptr = bufptr ;
|
|
}
|
|
|
|
//
|
|
//
|
|
// Return piece of information requested in global table
|
|
//
|
|
//
|
|
|
|
Exit:
|
|
return nResult;
|
|
} // MIB_prnt_get
|
|
|
|
//
|
|
// MIB_prnt_cmp
|
|
// Routine for sorting the session table.
|
|
//
|
|
// Notes:
|
|
//
|
|
// Return Codes:
|
|
// SNMPAPI_NOERROR
|
|
// SNMPAPI_ERROR
|
|
//
|
|
// Error Codes:
|
|
// None.
|
|
//
|
|
int __cdecl prnt_entry_cmp(
|
|
IN const PRINTQ_ENTRY *A,
|
|
IN const PRINTQ_ENTRY *B
|
|
)
|
|
|
|
{
|
|
// Compare the OID's
|
|
return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
|
|
(AsnObjectIdentifier *)&B->Oid );
|
|
} // MIB_prnt_cmp
|
|
|
|
|
|
//
|
|
// None.
|
|
//
|
|
void build_prnt_entry_oids(
|
|
)
|
|
|
|
{
|
|
AsnOctetString OSA ;
|
|
PRINTQ_ENTRY *PrintQEntry ;
|
|
unsigned i;
|
|
|
|
// start pointer at 1st guy in the table
|
|
PrintQEntry = MIB_PrintQTable.Table ;
|
|
|
|
// now iterate over the table, creating an oid for each entry
|
|
for( i=0; i<MIB_PrintQTable.Len ; i++) {
|
|
// for each entry in the session table
|
|
|
|
OSA.stream = PrintQEntry->svPrintQName.stream ;
|
|
OSA.length = PrintQEntry->svPrintQName.length ;
|
|
OSA.dynamic = TRUE;
|
|
|
|
// Make the entry's OID from string index
|
|
MakeOidFromStr( &OSA, &PrintQEntry->Oid );
|
|
|
|
PrintQEntry++; // point to the next guy in the table
|
|
|
|
} // for
|
|
|
|
} // build_prnt_entry_oids
|
|
//-------------------------------- END --------------------------------------
|