|
|
1.1.1.2 ! root 1: ! 2: /******************************************************************************\ ! 3: * This is a part of the Microsoft Source Code Samples. ! 4: * Copyright (C) 1993 Microsoft Corporation. ! 5: * All rights reserved. ! 6: * This source code is only intended as a supplement to ! 7: * Microsoft Development Tools and/or WinHelp documentation. ! 8: * See these sources for detailed information regarding the ! 9: * Microsoft samples programs. ! 10: \******************************************************************************/ ! 11: 1.1 root 12: /******************************************************************************\ 13: * 14: * PROGRAM: ENUMPRT.C 15: * 16: * PURPOSE: Handles display of information returned by calls to 17: * EnumPrinters, EnumPrinterDrivers. Info formatted and 18: * displayed in a dialog box. 19: * 20: * 21: * FUNTIONS: EnumPrintersDlgProc - handles messages for dialog 22: * DisplayEnumPrintersInfo - retrieves printer info 23: * SetEnumPrintersDlgFields - formats & displays printer info 24: * ComplexEnumPrintersLine - formats bitfield printer info 25: * EnumPrinterDriversDlgProc- handles messages for dialog 26: * DisplayPrinterDriversInfo- retrieves, formats, & displays 27: * printer info 28: * 29: \******************************************************************************/ 30: 31: #include <windows.h> 32: #include <string.h> 33: #include <drivinit.h> 34: #include <stdio.h> 35: #include <winspool.h> 36: #include "common.h" 37: #include "enumprt.h" 38: 39: 40: 41: /******************************************************************************\ 42: * 43: * FUNCTION: EnumPrintersDlgProc (standard dialog procedure INPUTS/RETURNS) 44: * 45: * COMMENTS: Processes messages for EnumPrinters dialog box 46: * 47: \******************************************************************************/ 48: 49: LRESULT CALLBACK EnumPrintersDlgProc (HWND hwnd, UINT msg, WPARAM wParam, 50: LPARAM lParam) 51: { 52: switch (msg) 53: { 54: case WM_INITDIALOG: 55: { 56: BOOL bReturn; 57: 58: // 59: // prompt user for EnumPrinters flags... 60: // 61: 62: if (DialogBox (GetModuleHandle (NULL), (LPCTSTR) "EnumPrtOpt", 63: NULL, (DLGPROC) EnumPrintersOptionsDlgProc)) 64: { 65: // 66: // shove all the enum printer info in the list box 67: // 68: 69: SetCursor (LoadCursor (NULL, IDC_WAIT)); 70: bReturn = DisplayEnumPrintersInfo (hwnd); 71: SetCursor (LoadCursor (NULL, IDC_ARROW)); 72: 73: if (!bReturn) 74: 75: EndDialog (hwnd, TRUE); 76: 77: else 78: 79: SetWindowText (hwnd, (LPCTSTR)"EnumPrinters"); 80: } 81: else 82: 83: EndDialog (hwnd, TRUE); 84: 85: break; 86: } 87: 88: case WM_COMMAND: 89: 90: switch (LOWORD (wParam)) 91: { 92: case DID_OK: 93: 94: EndDialog (hwnd, TRUE); 95: break; 96: } 97: break; 98: } 99: return 0; 100: } 101: 102: 103: 104: /******************************************************************************\ 105: * 106: * FUNCTION: EnumPrintersOptionsDlgProc (standard dlg proc INPUTS/RETURNS) 107: * 108: * COMMENTS: Processes messages for EnumPrtOpt dialog box 109: * 110: \******************************************************************************/ 111: 112: LRESULT CALLBACK EnumPrintersOptionsDlgProc (HWND hwnd, UINT msg, 113: WPARAM wParam, LPARAM lParam) 114: { 115: switch (msg) 116: { 117: case WM_INITDIALOG: 118: 119: gdwEnumFlags = 0; 120: gszEnumName[0] = 0; 121: break; 122: 123: case WM_COMMAND: 124: 125: switch (LOWORD (wParam)) 126: { 127: case DID_OK: 128: 129: if (gdwEnumFlags) 130: { 131: if (gdwEnumFlags & PRINTER_ENUM_NAME) 132: { 133: GetDlgItemText (hwnd, DID_EDITTEXT, (LPTSTR)gszEnumName, 134: BUFSIZE); 135: 136: if (!strlen (gszEnumName)) 137: { 138: MessageBox (hwnd, 139: (LPCTSTR) "Please enter a valid domain/server name", 140: (LPCTSTR) "", MB_OK); 141: SetFocus (GetDlgItem (hwnd, DID_EDITTEXT)); 142: break; 143: } 144: } 145: 146: EndDialog (hwnd, TRUE); 147: } 148: 149: else 150: 151: EndDialog (hwnd, FALSE); 152: 153: break; 154: 155: case DID_CANCEL: 156: 157: EndDialog (hwnd, FALSE); 158: break; 159: 160: default: 161: 162: if (HIWORD(wParam) == BN_CLICKED) 163: { 164: DWORD dwControlId = (DWORD) LOWORD (wParam); 165: 166: if (gdwEnumFlags & dwControlId) 167: { 168: // 169: // remove that flag, if PRINTER_ENUM_NAME disable edittext 170: // 171: 172: gdwEnumFlags &= ~dwControlId; 173: 174: if (dwControlId & PRINTER_ENUM_NAME) 175: { 176: SetDlgItemText (hwnd, DID_EDITTEXT, (LPCTSTR)""); 177: EnableWindow (GetDlgItem (hwnd, DID_EDITTEXT), FALSE); 178: } 179: } 180: 181: else 182: { 183: // 184: // add that flag, if PRINTER_ENUM_NAME enable edittext 185: // 186: 187: gdwEnumFlags |= dwControlId; 188: 189: if (dwControlId & PRINTER_ENUM_NAME) 190: 191: EnableWindow (GetDlgItem (hwnd, DID_EDITTEXT), TRUE); 192: } 193: } 194: break; 195: } 196: } 197: return 0; 198: } 199: 200: 201: 202: /******************************************************************************\ 203: * 204: * FUNCTION: DisplayEnumPrintersInfo 205: * 206: * INPUTS: hwnd - handle of the EnumPrinters dialog box 207: * 208: * RETURNS: TRUE if successful, 209: * FALSE otherwise 210: * 211: \******************************************************************************/ 212: 213: BOOL DisplayEnumPrintersInfo (HWND hwnd) 214: { 215: DWORD dwBytesNeeded; 216: DWORD dwPrtRet1, dwPrtRet2; 217: DWORD dwMaxPrt; 218: LPTSTR lpName = gdwEnumFlags & PRINTER_ENUM_NAME ? gszEnumName : NULL; 219: 220: LPPRINTER_INFO_1 pPrtInfo1; 221: LPPRINTER_INFO_2 pPrtInfo2; 222: 223: BOOL bReturn = TRUE; 224: 225: // 226: // get byte count needed for buffer, alloc buffer, the enum the printers 227: // 228: 229: EnumPrinters (gdwEnumFlags, lpName, 1, NULL, 0, &dwBytesNeeded, 230: &dwPrtRet1); 231: 232: // 233: // (simple error checking, if these work assume rest will too) 234: // 235: 236: if (!(pPrtInfo1 = (LPPRINTER_INFO_1) LocalAlloc (LPTR, dwBytesNeeded))) 237: { 238: ErrMsgBox ("EnumPrinters/LocalAlloc failed", ERR_MOD_NAME); 239: bReturn = FALSE; 240: goto display_prts_info_done1; 241: } 242: 243: if (!EnumPrinters (gdwEnumFlags, lpName, 1, (LPBYTE) pPrtInfo1, 244: dwBytesNeeded, &dwBytesNeeded, &dwPrtRet1)) 245: { 246: ErrMsgBox ("EnumPrinters failed", ERR_MOD_NAME); 247: bReturn = FALSE; 248: goto display_prts_info_done2; 249: } 250: 251: // 252: // get byte count needed for buffer, alloc buffer, the enum the printers 253: // 254: 255: EnumPrinters (gdwEnumFlags, lpName, 2, NULL, 0, &dwBytesNeeded, 256: &dwPrtRet2); 257: 258: pPrtInfo2 = (LPPRINTER_INFO_2) LocalAlloc (LPTR, dwBytesNeeded); 259: 260: EnumPrinters (gdwEnumFlags, lpName, 2, (LPBYTE) pPrtInfo2, 261: dwBytesNeeded, &dwBytesNeeded, &dwPrtRet2); 262: 263: if (!dwPrtRet1 || !dwPrtRet2) 264: { 265: ErrMsgBox ("EnumPrinters returned 0 printers", ""); 266: bReturn = FALSE; 267: goto display_prts_info_done3; 268: } 269: 270: dwMaxPrt = dwPrtRet1 > dwPrtRet2 ? dwPrtRet2 : dwPrtRet1; 271: 272: SetEnumPrintersDlgFields (hwnd, dwMaxPrt, pPrtInfo1, 273: pPrtInfo2); 274: 275: display_prts_info_done3: 276: 277: LocalFree (LocalHandle (pPrtInfo2)); 278: 279: display_prts_info_done2: 280: 281: LocalFree (LocalHandle (pPrtInfo1)); 282: 283: display_prts_info_done1: 284: 285: return bReturn; 286: } 287: 288: 289: /******************************************************************************\ 290: * 291: * FUNCTION: SetEnumPrintersDlgFields 292: * 293: * INPUTS: hwnd - handle of the EnumPrinters dialog box 294: * dwMaxPrt - number of elements in the following two arrays 295: * pdisplay_prts_info1 - ptr to an array of PRINTER_INFO_1 structs 296: * pdisplay_prts_info2 - ptr to an array of PRINTER_INFO_2 structs 297: * 298: * COMMENTS: This function formats the info returned by EnumPrinters() 299: * into readable strings and inserts them in the listbox. 300: * 301: \******************************************************************************/ 302: 303: void SetEnumPrintersDlgFields (HWND hwnd, DWORD dwMaxPrt, 304: LPPRINTER_INFO_1 pPrtInfo1, 305: LPPRINTER_INFO_2 pPrtInfo2) 306: { 307: char buf[256]; 308: WORD i; 309: DWORD j; 310: 311: SendDlgItemMessage (hwnd, DID_LISTBOX, LB_RESETCONTENT, 0, 0); 312: 313: for (j = 0; j < dwMaxPrt; j++) 314: { 315: // 316: // Stick PRINTER_INFO_1 data in listbox 317: // 318: 319: SendDlgItemMessage (hwnd, DID_LISTBOX, LB_INSERTSTRING, (UINT)-1, 320: (LONG) gaEnumPrt[0]); 321: 322: outstr (gaEnumPrt[1], (pPrtInfo1 + j)->pDescription); 323: outstr (gaEnumPrt[2], (pPrtInfo1 + j)->pName); 324: outstr (gaEnumPrt[3], (pPrtInfo1 + j)->pComment); 325: 326: // 327: // Stick PRINTER_INFO_2 data in listbox 328: // 329: 330: SendDlgItemMessage (hwnd, DID_LISTBOX, LB_INSERTSTRING, (UINT)-1, 331: (LONG) gaEnumPrt[4]); 332: 333: outstr (gaEnumPrt[5], (pPrtInfo2 + j)->pServerName); 334: outstr (gaEnumPrt[6], (pPrtInfo2 + j)->pPrinterName); 335: outstr (gaEnumPrt[7], (pPrtInfo2 + j)->pShareName); 336: outstr (gaEnumPrt[8], (pPrtInfo2 + j)->pPortName); 337: outstr (gaEnumPrt[9], (pPrtInfo2 + j)->pDriverName); 338: outstr (gaEnumPrt[10], (pPrtInfo2 + j)->pComment); 339: outstr (gaEnumPrt[11], (pPrtInfo2 + j)->pLocation); 340: 341: if ((pPrtInfo2 + j)->pDevMode) 342: { 343: DWORD dwFields; 344: 345: outstr (gaEnumPrt[12], ""); 346: outstr (gaEnumPrt[13], (pPrtInfo2 + j)->pDevMode->dmDeviceName); 347: outnum (gaEnumPrt[14], (pPrtInfo2 + j)->pDevMode->dmSpecVersion); 348: outnum (gaEnumPrt[15], (pPrtInfo2 + j)->pDevMode->dmDriverVersion); 349: outnum (gaEnumPrt[16], (pPrtInfo2 + j)->pDevMode->dmSize); 350: outnum (gaEnumPrt[17], (pPrtInfo2 + j)->pDevMode->dmDriverExtra); 351: 352: dwFields = (pPrtInfo2 + j)->pDevMode->dmFields; 353: ComplexEnumPrintersLine (hwnd, gaEnumPrt[18], gaFields, MAX_FIELDS, 354: dwFields); 355: 356: if (dwFields & DM_ORIENTATION) 357: 358: ComplexEnumPrintersLine (hwnd, gaEnumPrt[19], gaOrientation, 359: MAX_ORIENTATION, 360: (DWORD) 361: (pPrtInfo2+j)->pDevMode->dmOrientation); 362: 363: if (dwFields & DM_PAPERSIZE) 364: 365: ComplexEnumPrintersLine (hwnd, gaEnumPrt[20], gaPaperSize, 366: MAX_PAPERSIZE, 367: (DWORD)(pPrtInfo2 + j)->pDevMode->dmPaperSize); 368: 369: if (dwFields & DM_PAPERLENGTH) 370: 371: outnum (gaEnumPrt[21], (pPrtInfo2 + j)->pDevMode->dmPaperLength); 372: 373: 374: if (dwFields & DM_PAPERWIDTH) 375: 376: outnum (gaEnumPrt[22], (pPrtInfo2 + j)->pDevMode->dmPaperWidth); 377: 378: if (dwFields & DM_SCALE) 379: 380: outnum (gaEnumPrt[23], (pPrtInfo2 + j)->pDevMode->dmScale); 381: 382: if (dwFields & DM_COPIES) 383: 384: outnum (gaEnumPrt[24], (pPrtInfo2 + j)->pDevMode->dmCopies); 385: 386: if (dwFields & DM_DEFAULTSOURCE) 387: 388: ComplexEnumPrintersLine (hwnd, gaEnumPrt[25], gaDefaultSource, 389: MAX_DEFAULTSOURCE, 390: (DWORD)(pPrtInfo2+j)->pDevMode->dmDefaultSource); 391: 392: if (dwFields & DM_PRINTQUALITY) 393: 394: ComplexEnumPrintersLine (hwnd, gaEnumPrt[26], gaPrintQuality, 395: MAX_PRINTQUALITY, 396: (DWORD)(pPrtInfo2+j)->pDevMode->dmPrintQuality); 397: 398: if (dwFields & DM_COLOR) 399: 400: ComplexEnumPrintersLine (hwnd, gaEnumPrt[27], gaColor, 401: MAX_COLOR, 402: (DWORD)(pPrtInfo2 + j)->pDevMode->dmColor); 403: 404: if (dwFields & DM_DUPLEX) 405: 406: ComplexEnumPrintersLine (hwnd, gaEnumPrt[28], gaDuplex, 407: MAX_DUPLEX, 408: (DWORD)(pPrtInfo2 + j)->pDevMode->dmDuplex); 409: 410: if (dwFields & DM_YRESOLUTION) 411: 412: outnum (gaEnumPrt[29], NULL); 413: 414: if (dwFields & DM_TTOPTION) 415: 416: outnum (gaEnumPrt[29], NULL); 417: 418: if (dwFields & DM_COLLATE) 419: 420: outnum (gaEnumPrt[30], NULL); 421: 422: if (dwFields & DM_FORMNAME) 423: 424: outnum (gaEnumPrt[31], NULL); 425: } 426: else 427: { 428: outstr (gaEnumPrt[12], NULL); 429: } 430: 431: outstr (gaEnumPrt[33], (pPrtInfo2 + j)->pSepFile); 432: outstr (gaEnumPrt[34], (pPrtInfo2 + j)->pPrintProcessor); 433: outstr (gaEnumPrt[35], (pPrtInfo2 + j)->pDatatype); 434: outstr (gaEnumPrt[36], (pPrtInfo2 + j)->pParameters); 435: 436: ComplexEnumPrintersLine (hwnd, gaEnumPrt[37], gaAttributes, 437: MAX_ATTRIBUTES, 438: (pPrtInfo2 + j)->Attributes); 439: 440: for (i = 0; i < MAX_PRIORITIES; i++) 441: 442: if ((pPrtInfo2 + j)->Priority & gaPriorities[i].dwValue) 443: { 444: outstr (gaEnumPrt[38], gaPriorities[i].szValue); 445: break; 446: } 447: 448: if (i == MAX_PRIORITIES) 449: 450: outnum (gaEnumPrt[39], (pPrtInfo2 + j)->Priority); 451: 452: outnum (gaEnumPrt[40], (pPrtInfo2 + j)->DefaultPriority); 453: outnum (gaEnumPrt[41], (pPrtInfo2 + j)->StartTime); 454: outnum (gaEnumPrt[42], (pPrtInfo2 + j)->UntilTime); 455: 456: ComplexEnumPrintersLine (hwnd, gaEnumPrt[43], gaStatus, MAX_STATUS, 457: (pPrtInfo2 + j)->Status); 458: 459: outnum (gaEnumPrt[44], (pPrtInfo2 + j)->cJobs); 460: outnum (gaEnumPrt[45], (pPrtInfo2 + j)->AveragePPM); 461: } 462: } 463: 464: 465: 466: /******************************************************************************\ 467: * 468: * FUNCTION: ComplexEnumPrintersLine 469: * 470: * INPUTS: hwnd - handle of the EnumPrinters dialog box 471: * pbuf - pointer to buffer containing a cap-type 472: * string 473: * pLkUp - pointer to a CAPSLOOKUP table 474: * iMaxEntries - # of enries in table pointed at by pLkUp 475: * iValue - an integer containing 1+ bit-value flags. 476: * 477: * COMMENTS: This function is used to expand an int containing 478: * multiple bit-values into a set of strings which are 479: * inserted into the DevCapsDlg listbox. The iValue 480: * parameter is checked against each iIndex entry in the 481: * CAPSLOOKUP table pointed at by pLkUp, and when matches 482: * are found the corresponding (lpszValue) string is 483: * inserted. 484: * 485: * The buffer pointed to by pbuf will be destroyed. 486: * 487: \******************************************************************************/ 488: 489: void ComplexEnumPrintersLine (HWND hwnd, char *pstr, ENUMPRTLOOKUP *pLkUp, 490: int iMaxEntries, DWORD dwValue) 491: { 492: char buf [BUFSIZE]; 493: int i; 494: BOOL bNewLine = FALSE; 495: 496: strcpy (buf, pstr); 497: 498: for (i = 0; i < iMaxEntries; i++) 499: 500: if (dwValue & (pLkUp + i)->dwValue) 501: { 502: if (bNewLine) 503: { 504: // 505: // Keep the first symbolic constant on the same line as the 506: // cap type, eg: "TECHNOLOGY: DT_RASDISPLAY". 507: // 508: 509: strcpy (buf, BLANKS); 510: strcat (buf, (pLkUp + i)->szValue); 511: } 512: else 513: { 514: // 515: // Put symbolic constant on new line, eg: 516: // " DT_RASPRINTER". 517: // 518: 519: strcat (buf, (pLkUp + i)->szValue); 520: bNewLine = TRUE; 521: } 522: SendDlgItemMessage (hwnd, DID_LISTBOX, LB_INSERTSTRING, 523: (UINT)-1, (LONG) buf); 524: } 525: } 526: 527: 528: 529: /******************************************************************************\ 530: * 531: * FUNCTION: EnumPrinterDriversDlgProc (standard dlg proc INPUTS/RETURNS) 532: * 533: * COMMENTS: Processes messages for EnumPrinterDrivers dialog box 534: * 535: \******************************************************************************/ 536: 537: LRESULT CALLBACK EnumPrinterDriversDlgProc (HWND hwnd, UINT msg, 538: WPARAM wParam, LPARAM lParam) 539: { 540: switch (msg) 541: { 542: case WM_INITDIALOG: 543: { 544: BOOL bReturn; 545: 546: SetCursor (LoadCursor (NULL, IDC_WAIT)); 547: bReturn = DisplayPrinterDriversInfo (hwnd); 548: SetCursor (LoadCursor (NULL, IDC_ARROW)); 549: 550: if (!bReturn) 551: 552: EndDialog (hwnd, TRUE); 553: 554: else 555: 556: SetWindowText (hwnd, (LPCTSTR) "EnumPrinterDrivers"); 557: 558: break; 559: } 560: 561: case WM_COMMAND: 562: 563: switch (LOWORD (wParam)) 564: { 565: case DID_OK: 566: 567: EndDialog (hwnd, TRUE); 568: 569: return 1; 570: } 571: break; 572: } 573: return 0; 574: } 575: 576: 577: 578: /******************************************************************************\ 579: * 580: * FUNCTION: DisplayPrinterDriversInfo 581: * 582: * INPUTS: hwnd - handle of the EnumPrinterDrivers dialog box 583: * 584: * RETURNS: TRUE if successful, 585: * FALSE otherwise 586: * 587: * COMMENTS: Retrieves EnumPrinterDrivers info, formats, & inserts 588: * in listbox. 589: * 590: \******************************************************************************/ 591: 592: BOOL DisplayPrinterDriversInfo (HWND hwnd) 593: { 594: DWORD dwBytesNeeded, dwDrvRet, i; 595: DRIVER_INFO_1 *pDriverInfo1; 596: DRIVER_INFO_2 *pDriverInfo2; 597: char buf[BUFSIZE]; 598: BOOL bReturn = TRUE; 599: 600: // 601: // get byte count needed for buffer, alloc buffer, the enum the drivers 602: // 603: 604: EnumPrinterDrivers ((LPTSTR) NULL, (LPTSTR) NULL, 1, NULL, 605: 0, &dwBytesNeeded, &dwDrvRet); 606: 607: // 608: // simple error checking, if these work assume rest will too 609: // 610: 611: if (!(pDriverInfo1 = (DRIVER_INFO_1 *) LocalAlloc (LPTR, dwBytesNeeded))) 612: { 613: ErrMsgBox ("LocalAlloc failed", ERR_MOD_NAME); 614: bReturn = FALSE; 615: goto display_prt_drvs_info_done1; 616: } 617: 618: if (!EnumPrinterDrivers ((LPTSTR) NULL, (LPTSTR) NULL, 1, 619: (LPBYTE) pDriverInfo1, dwBytesNeeded, &dwBytesNeeded, 620: &dwDrvRet)) 621: { 622: ErrMsgBox ("EnumPrinterDrivers returned 0 drivers", ERR_MOD_NAME); 623: bReturn = FALSE; 624: goto display_prt_drvs_info_done2; 625: } 626: 627: EnumPrinterDrivers ((LPTSTR) NULL,(LPTSTR) NULL, 2, NULL, 628: 0, &dwBytesNeeded, &dwDrvRet); 629: 630: pDriverInfo2 = (DRIVER_INFO_2 *) LocalAlloc (LPTR, dwBytesNeeded); 631: 632: EnumPrinterDrivers ((LPTSTR) NULL, (LPTSTR) NULL, 2, 633: (LPBYTE) pDriverInfo2, dwBytesNeeded, &dwBytesNeeded, 634: &dwDrvRet); 635: 636: if (!dwDrvRet) 637: { 638: ErrMsgBox ("EnumPrinterDrivers returned 0 drivers", ""); 639: bReturn = FALSE; 640: goto display_prt_drvs_info_done3; 641: } 642: 643: // 644: // insert formatted info into listbox 645: // 646: 647: for (i = 0; i < dwDrvRet; i++) 648: { 649: sprintf (buf, gaDriverInfo[0]); 650: outstr3(); 651: 652: sprintf (buf, gaDriverInfo[1], (pDriverInfo1 + i)->pName); 653: outstr3(); 654: 655: sprintf (buf, gaDriverInfo[2]); 656: outstr3(); 657: 658: sprintf (buf, gaDriverInfo[3], (pDriverInfo2 + i)->cVersion); 659: outstr3(); 660: 661: sprintf (buf, gaDriverInfo[4], (pDriverInfo2 + i)->pName); 662: outstr3(); 663: 664: sprintf (buf, gaDriverInfo[5], (pDriverInfo2 + i)->pEnvironment); 665: outstr3(); 666: 667: sprintf (buf, gaDriverInfo[6], (pDriverInfo2 + i)->pDriverPath); 668: outstr3(); 669: 670: sprintf (buf, gaDriverInfo[7], (pDriverInfo2 + i)->pDataFile); 671: outstr3(); 672: 673: sprintf (buf, gaDriverInfo[8], (pDriverInfo2 + i)->pConfigFile); 674: outstr3(); 675: 676: } 677: 678: display_prt_drvs_info_done3: 679: 680: LocalFree (LocalHandle (pDriverInfo2)); 681: 682: display_prt_drvs_info_done2: 683: 684: LocalFree (LocalHandle (pDriverInfo1)); 685: 686: display_prt_drvs_info_done1: 687: 688: return bReturn; 689: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.