Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

417 lines
11 KiB

  1. /*++
  2. Copyright (c) 1992-1996 Microsoft Corporation
  3. Module Name:
  4. prnt_lm.c
  5. Abstract:
  6. This file contains the routines which actually call Lan Manager and
  7. retrieve the contents of the print queue table, including cacheing.
  8. Environment:
  9. User Mode - Win32
  10. Revision History:
  11. 10-May-1996 DonRyan
  12. Removed banner from Technology Dynamics, Inc.
  13. --*/
  14. //--------------------------- WINDOWS DEPENDENCIES --------------------------
  15. //--------------------------- STANDARD DEPENDENCIES -- #include<xxxxx.h> ----
  16. #ifdef WIN32
  17. #include <windows.h>
  18. #include <winspool.h>
  19. #endif
  20. #include <tchar.h>
  21. #include <string.h>
  22. #include <search.h>
  23. #include <stdlib.h>
  24. #include <time.h>
  25. //--------------------------- MODULE DEPENDENCIES -- #include"xxxxx.h" ------
  26. #include "mib.h"
  27. #include "mibfuncs.h"
  28. #include "prnt_tbl.h"
  29. #include "lmcache.h"
  30. //--------------------------- SELF-DEPENDENCY -- ONE #include"module.h" -----
  31. //--------------------------- PUBLIC VARIABLES --(same as in module.h file)--
  32. //--------------------------- PRIVATE CONSTANTS -----------------------------
  33. #define SafeBufferFree(x) if(NULL != x) NetApiBufferFree( x )
  34. #define SafeFree(x) if(NULL != x) SnmpUtilMemFree( x )
  35. //--------------------------- PRIVATE STRUCTS -------------------------------
  36. //--------------------------- PRIVATE VARIABLES -----------------------------
  37. //--------------------------- PRIVATE PROTOTYPES ----------------------------
  38. //--------------------------- PRIVATE PROCEDURES ----------------------------
  39. int __cdecl prnt_entry_cmp(
  40. IN const PRINTQ_ENTRY *A,
  41. IN const PRINTQ_ENTRY *B
  42. ) ;
  43. BOOL build_prnt_entry_oids( );
  44. void FreePrintQTable();
  45. //--------------------------- PUBLIC PROCEDURES -----------------------------
  46. //
  47. // MIB_prnt_lmget
  48. // Retrieve print queue table information from Lan Manager.
  49. // If not cached, sort it and then
  50. // cache it.
  51. //
  52. // Notes:
  53. //
  54. // Return Codes:
  55. // SNMPAPI_NOERROR
  56. // SNMPAPI_ERROR
  57. //
  58. // Error Codes:
  59. // None.
  60. //
  61. SNMPAPI MIB_prntq_lmget(
  62. )
  63. {
  64. DWORD entriesread = 0; // init number of table entries read
  65. DWORD bytesNeeded = 0; // init size needed
  66. DWORD dwLastError = ERROR_SUCCESS; // init last error to no error
  67. LPBYTE bufptr;
  68. unsigned lmCode;
  69. unsigned i;
  70. PRINTER_INFO_2 *DataTable;
  71. PRINTQ_ENTRY *MIB_PrintQTableElement ;
  72. int First_of_this_block;
  73. time_t curr_time ;
  74. BOOL result;
  75. SNMPAPI nResult = SNMPAPI_NOERROR;
  76. time(&curr_time); // get the time
  77. //
  78. //
  79. // If cached, return piece of info.
  80. //
  81. //
  82. if((NULL != cache_table[C_PRNT_TABLE].bufptr) &&
  83. (curr_time <
  84. (cache_table[C_PRNT_TABLE].acquisition_time
  85. + cache_expire[C_PRNT_TABLE] ) ) )
  86. { // it has NOT expired!
  87. goto Exit ; // the global table is valid
  88. }
  89. //
  90. // remember to free the existing data
  91. //
  92. FreePrintQTable();
  93. //
  94. //
  95. // Do network call to gather information and put it in a nice array
  96. //
  97. //
  98. // call it with zero length buffer to get the size
  99. //
  100. result = EnumPrinters(
  101. PRINTER_ENUM_SHARED |
  102. PRINTER_ENUM_LOCAL, // what type to enum
  103. NULL, // local server
  104. 2, // level
  105. NULL, // where to put it
  106. 0, // max of above
  107. &bytesNeeded, // additional bytes req'd
  108. &entriesread ); // how many we got this time
  109. if (result)
  110. {
  111. // When there is no table entries from spooler *and* spooler is
  112. // running, we'll be here.
  113. SNMPDBG((
  114. SNMP_LOG_TRACE,
  115. "SNMP: LMMIB2: EnumPrinters returns TRUE, bytesNeeded=0x%08lx\n",
  116. bytesNeeded
  117. ));
  118. goto Exit; // get out with 0 entries in the table
  119. }
  120. // Assert: result == FALSE
  121. dwLastError = GetLastError(); // save last error
  122. SNMPDBG((
  123. SNMP_LOG_TRACE,
  124. "SNMP: LMMIB2: EnumPrinters returns FALSE, bytesNeeded=0x%08lx, dwLastError=0x%08lx\n",
  125. bytesNeeded, dwLastError
  126. ));
  127. if (ERROR_INSUFFICIENT_BUFFER != dwLastError)
  128. {
  129. //
  130. // EnumPrinters Failed and the last error is not
  131. // ERROR_INSUFFICIENT_BUFFER, we'll bail out with 0 entries in the
  132. // table.
  133. // For example, if spooler service was down, we will be here.
  134. //
  135. SNMPDBG((
  136. SNMP_LOG_TRACE,
  137. "SNMP: LMMIB2: EnumPrinters failed, lasterror != ERROR_INSUFFICIENT_BUFFER, bytesNeeded=%d\n",
  138. bytesNeeded
  139. ));
  140. goto Exit; // get out with 0 entries in the table, so getnext will work
  141. }
  142. // Assert: dwLastError == ERROR_INSUFFICIENT_BUFFER
  143. bufptr = SnmpUtilMemAlloc(bytesNeeded); // SnmpUtilMemAlloc the buffer
  144. if(NULL==bufptr)
  145. {
  146. nResult = SNMPAPI_ERROR;
  147. goto Exit ; // can't allocate memory, error out
  148. }
  149. // then read the rest of it
  150. // call it again
  151. result = EnumPrinters(
  152. PRINTER_ENUM_SHARED |
  153. PRINTER_ENUM_LOCAL, // what type to enum
  154. NULL, // local server
  155. 2, // level
  156. bufptr, // where to put it
  157. bytesNeeded, // max of above
  158. &bytesNeeded, // additional bytes req'd
  159. &entriesread ); // how many we got this time
  160. if (!result) {
  161. // Signal error
  162. SafeFree( bufptr );
  163. nResult = SNMPAPI_ERROR;
  164. goto Exit;
  165. }
  166. DataTable = (PRINTER_INFO_2 *) bufptr ;
  167. if(0 == MIB_PrintQTable.Len) { // 1st time, alloc the whole table
  168. // alloc the table space
  169. MIB_PrintQTable.Table = SnmpUtilMemAlloc(entriesread *
  170. sizeof(PRINTQ_ENTRY) );
  171. // prefix bug 445181
  172. if (MIB_PrintQTable.Table == NULL) {
  173. // free the table
  174. SafeFree( bufptr ) ;
  175. // Signal error
  176. nResult = SNMPAPI_ERROR;
  177. goto Exit;
  178. }
  179. }
  180. MIB_PrintQTableElement = MIB_PrintQTable.Table ;
  181. for(i=0; i<entriesread; i++) { // once for each entry in the buffer
  182. // increment the entry number
  183. MIB_PrintQTable.Len ++;
  184. // Stuff the data into each item in the table
  185. // client name
  186. MIB_PrintQTableElement->svPrintQName.dynamic = TRUE;
  187. #ifdef UNICODE
  188. if (SnmpUtilUnicodeToUTF8(
  189. &MIB_PrintQTableElement->svPrintQName.stream,
  190. DataTable->pPrinterName,
  191. TRUE))
  192. {
  193. MIB_PrintQTableElement->svPrintQName.stream = NULL;
  194. MIB_PrintQTableElement->svPrintQName.length = 0;
  195. MIB_PrintQTableElement->svPrintQName.dynamic = FALSE;
  196. }
  197. else
  198. {
  199. MIB_PrintQTableElement->svPrintQName.length =
  200. strlen (MIB_PrintQTableElement->svPrintQName.stream);
  201. }
  202. #else
  203. MIB_PrintQTableElement->svPrintQName.stream = SnmpUtilMemAlloc (
  204. strlen( DataTable->pPrinterName ) + 1 ) ;
  205. MIB_PrintQTableElement->svPrintQName.length =
  206. strlen( DataTable->pPrinterName ) ;
  207. memcpy( MIB_PrintQTableElement->svPrintQName.stream,
  208. DataTable->pPrinterName,
  209. strlen( DataTable->pPrinterName ) ) ;
  210. #endif
  211. // number of connections
  212. MIB_PrintQTableElement->svPrintQNumJobs =
  213. DataTable->cJobs;
  214. MIB_PrintQTableElement ++ ; // and table entry
  215. DataTable ++ ; // advance pointer to next sess entry in buffer
  216. } // for each entry in the data table
  217. // free all of the printer enum data
  218. if(NULL!=bufptr) // free the table
  219. SnmpUtilMemFree( bufptr ) ;
  220. // iterate over the table populating the Oid field
  221. if (! build_prnt_entry_oids())
  222. {
  223. SNMPDBG((
  224. SNMP_LOG_TRACE,
  225. "SNMP: LMMIB2: build_prnt_entry_oids failed\n."));
  226. FreePrintQTable();
  227. cache_table[C_PRNT_TABLE].bufptr = NULL;
  228. nResult = SNMPAPI_ERROR;
  229. goto Exit;
  230. }
  231. // Sort the table information using MSC QuickSort routine
  232. qsort( &MIB_PrintQTable.Table[0], MIB_PrintQTable.Len,
  233. sizeof(PRINTQ_ENTRY), prnt_entry_cmp );
  234. //
  235. //
  236. // Cache table
  237. //
  238. //
  239. if(0 != MIB_PrintQTable.Len) {
  240. cache_table[C_PRNT_TABLE].acquisition_time = curr_time ;
  241. cache_table[C_PRNT_TABLE].bufptr = bufptr ;
  242. }
  243. //
  244. //
  245. // Return piece of information requested in global table
  246. //
  247. //
  248. Exit:
  249. return nResult;
  250. } // MIB_prnt_get
  251. //
  252. // MIB_prnt_cmp
  253. // Routine for sorting the session table.
  254. //
  255. // Notes:
  256. //
  257. // Return Codes:
  258. // SNMPAPI_NOERROR
  259. // SNMPAPI_ERROR
  260. //
  261. // Error Codes:
  262. // None.
  263. //
  264. int __cdecl prnt_entry_cmp(
  265. IN const PRINTQ_ENTRY *A,
  266. IN const PRINTQ_ENTRY *B
  267. )
  268. {
  269. // Compare the OID's
  270. return SnmpUtilOidCmp( (AsnObjectIdentifier *)&A->Oid,
  271. (AsnObjectIdentifier *)&B->Oid );
  272. } // MIB_prnt_cmp
  273. //
  274. // None.
  275. //
  276. BOOL build_prnt_entry_oids(
  277. )
  278. {
  279. AsnOctetString OSA ;
  280. PRINTQ_ENTRY *PrintQEntry ;
  281. unsigned i;
  282. // start pointer at 1st guy in the table
  283. PrintQEntry = MIB_PrintQTable.Table ;
  284. // now iterate over the table, creating an oid for each entry
  285. for( i=0; i<MIB_PrintQTable.Len ; i++) {
  286. // for each entry in the session table
  287. OSA.stream = PrintQEntry->svPrintQName.stream ;
  288. OSA.length = PrintQEntry->svPrintQName.length ;
  289. OSA.dynamic = TRUE;
  290. // Make the entry's OID from string index
  291. if (! MakeOidFromStr( &OSA, &PrintQEntry->Oid ))
  292. {
  293. return FALSE;
  294. }
  295. PrintQEntry++; // point to the next guy in the table
  296. } // for
  297. return TRUE;
  298. } // build_prnt_entry_oids
  299. void FreePrintQTable()
  300. {
  301. UINT i;
  302. PRINTQ_ENTRY *MIB_PrintQTableElement;
  303. MIB_PrintQTableElement = MIB_PrintQTable.Table;
  304. if (MIB_PrintQTableElement)
  305. {
  306. // iterate over the whole table
  307. for(i=0; i<MIB_PrintQTable.Len ;i++)
  308. {
  309. // free any alloc'ed elements of the structure
  310. SnmpUtilOidFree(&(MIB_PrintQTableElement->Oid));
  311. SnmpUtilMemFree(MIB_PrintQTableElement->svPrintQName.stream);
  312. MIB_PrintQTableElement ++; // increment table entry
  313. }
  314. SnmpUtilMemFree(MIB_PrintQTable.Table); // free the base Table
  315. }
  316. MIB_PrintQTable.Table = NULL;
  317. MIB_PrintQTable.Len = 0;
  318. }
  319. //-------------------------------- END --------------------------------------