/* NETPRD.C -- a program demonstrating the DosPrintDest API functions. Admin or print operator privilege is required to successfully execute the Print Destination API functions on a remote server. This program calls DosPrintDestAdd to add a printer to the specified server, then manipulates that printer using DosPrintDestControl. DosPrintDestGetInfo displays status information about the printer. DosPrintDestSetInfo is called to disconnect the printer from the computer. DosPrintDestEnum lists all printers on the computer. DosPrintDestDel then deletes the print destination. Usage: netprd [-s \\server] [-p printername] [-a address] [-l level] [-o operation] [-d driver] [-f flag] where: \\server = Name of the server. A servername must be preceded by two backslashes (\\). printername = Name of the printer. address = Logical address, such as LPT1. level = Level of detail. operation = Integer code for DosPrintDestControl. driver = Name of the print driver. flag = Flag whether to delete the printer (0 or 1). API Used to... =================== =============================================== DosPrintDestAdd Add a new print destination DosPrintDestControl Control the status of the printer DosPrintDestGetInfo Get specific information about a single printer DosPrintDestSetInfo Set specific information for a single printer DosPrintDestEnum List all printers available DosPrintDestDel Delete the print destination This code sample is provided for demonstration purposes only. Microsoft makes no warranty, either express or implied, as to its usability in any given situation. */ #define INCL_BASE #include // MS OS/2 base header files #include // Print definitions #define INCL_NETERRORS #include // LAN Manager header files #include // C run-time header files #include #include #include "samples.h" // Internal routine header file #define NEWPORTNAME "LPT1" #define NEWPRINTERNAME "PrntDestTest" #define NEWDRIVER "IBM4201" #define DEFAULT_BUF_SIZE 512 #define MAX_BUFFER_SIZE 65535 #define MAX_PDEST 10 // Limit for this program only void DisplayInfo(short sLevel, char *pbBuffer, unsigned short cEntries); void Usage(char *pszProgram); void main(int argc, char *argv[]) { char * pbBuffer; // Return data char * pszServer = ""; // Server; default to local computer char * szNull = ""; // Null string char far * pszPrinterName = NEWPRINTERNAME; char far * pszLogAddr = NEWPORTNAME; char far * pszDriver = NEWDRIVER; int iCount; // Index counter PRDINFO3 prd3; // Level 3 data structure short sLevel = 3; // Level of detail unsigned uRet; // Return code unsigned short fDone; // Flag successful call unsigned short fDelete = TRUE; // Delete flag unsigned short cEntriesRead; // Count of entries read unsigned short cTotal; // Count of entries available unsigned short cbBuffer = 0; // Count of bytes in data buffer unsigned short cbBufferNeeded = 0; // Bytes needed for GetInfo call unsigned short uControl = PRD_CONT; // DosPrintDestControl operation for (iCount = 1; iCount < argc; iCount++) // Get cmd-line switches { if ((*argv[iCount] == '-') || (*argv[iCount] == '/')) { switch (tolower(*(argv[iCount]+1))) // Process switches { case 's': // -s servername pszServer = argv[++iCount]; break; case 'l': // -l level sLevel = atoi(argv[++iCount]); break; case 'p': // -p printername pszPrinterName = argv[++iCount]; break; case 'd': // -d drivername pszDriver = argv[++iCount]; break; case 'f': // -f flag deletion fDelete = atoi(argv[++iCount]); break; case 'a': // -a address pszLogAddr = argv[++iCount]; break; case 'o': // -o operation uControl = atoi(argv[++iCount]); break; case 'h': default: Usage(argv[0]); } } else Usage(argv[0]); } printf("\nPrint Destination Category API Examples\n"); //======================================================================= // DosPrintDestAdd // // This API adds the specified printer to the specified server. //======================================================================= memset(&prd3, 0, sizeof(PRDINFO3)); // Initialize memory prd3.pszPrinterName = pszPrinterName; // Set names prd3.pszLogAddr = pszLogAddr; prd3.pszDrivers = pszDriver; uRet = DosPrintDestAdd(pszServer, // Servername 3, // Level; must be 3 (char far *)&prd3, // New printer struct sizeof(PRDINFO3)); // Size of buffer printf("DosPrintDestAdd returned %u\n", uRet); if (uRet == NERR_Success) { printf(" %Fs added to ", prd3.pszPrinterName); if ((pszServer == NULL) || (*pszServer == '\0')) printf("the local computer\n"); else printf(" %s\n", pszServer); printf(" Printer port set to %Fs\n", prd3.pszLogAddr); } //======================================================================= // DosPrintDestControl // // This API controls a printer destination. It can delete, // pause, continue, or restart the printer. If a job is printing at the // time the API is executed, that print job receives the new // printer status. The print dest name must be a logical address. //======================================================================= uRet = DosPrintDestControl(pszServer, // Computername pszLogAddr, // Print dest name uControl); // Operation printf("DosPrintDestControl returned %u\n", uRet); //======================================================================= // DosPrintDestGetInfo // // This API returns information about the specified print destination. //======================================================================= // Call with zero-length buffer, expect NERR_BufTooSmall. uRet = DosPrintDestGetInfo(pszServer, // Servername pszPrinterName, // Printername sLevel, // Call level NULL, // Data buffer 0, // Size of buffer &cbBufferNeeded); // Returns required size if (uRet == NERR_BufTooSmall) { cbBuffer = cbBufferNeeded; pbBuffer = SafeMalloc(cbBuffer); // SafeMalloc() is in SAMPLES.C uRet = DosPrintDestGetInfo(pszServer, // Server name pszPrinterName, // Printer name sLevel, // Call level pbBuffer, // Data buffer cbBuffer, // Size of buffer &cbBufferNeeded); // Size required printf("DosPrintDestGetInfo returned %u\n", uRet); if (uRet == NERR_Success) DisplayInfo(sLevel, pbBuffer, 1); // Display buffer free(pbBuffer); } else printf("DosPrintDestGetInfo returned %u\n", uRet); //======================================================================= // DosPrintDestSetInfo // // This API allows control over print destination settings. // It must be called using level 3 (PRDINFO3). // // In this example, a single element is set to the desired value. // A program can also set all elements by setting the parameter number // code to PARMNUM_ALL. // // Setting the logical address to a null string disconnects this // printer from the computer. //======================================================================= uRet = DosPrintDestSetInfo(pszServer, // Servername pszPrinterName, // Printername 3, // Level; must be 3 (char far *)szNull, // Data sizeof(szNull), // Size of buffer PRD_LOGADDR_PARMNUM); // Parameter number code printf("DosPrintDestSetInfo returned %u", uRet); if (uRet) printf(": Disconnect failed"); printf("\n"); //======================================================================== // DosPrintDestEnum // // This API lists all printers connected to the specified server. // Allocate a buffer for the returned data. If the buffer is too small, // try again with a bigger buffer, and keep trying until the buffer // is large enough or until it cannot be made any larger. //======================================================================== cbBuffer = DEFAULT_BUF_SIZE; pbBuffer = SafeMalloc(cbBuffer); // SafeMalloc() is in SAMPLES.C do { uRet = DosPrintDestEnum (pszServer, // Servername sLevel, // Call level pbBuffer, // Buffer for info cbBuffer, // Size of buffer &cEntriesRead, // Count of entries read &cTotal); // Count of entries available if (uRet == ERROR_MORE_DATA) { free(pbBuffer); // Buffer too small if (cbBuffer == MAX_BUFFER_SIZE) { printf("Exceeded buffer size\n"); exit(1); } else if (cbBuffer > (MAX_BUFFER_SIZE/2)) cbBuffer = MAX_BUFFER_SIZE; else cbBuffer += cbBuffer; // Allocate larger buffer pbBuffer = SafeMalloc(cbBuffer); fDone = FALSE; } else fDone = TRUE; } while (fDone == FALSE); // Loop until buffer big enough or call fails printf("DosPrintDestEnum returned %u\n", uRet); printf(" Entries read = %hu out of %hu\n", cEntriesRead, cTotal); if (uRet == NERR_Success) DisplayInfo(sLevel, pbBuffer, cEntriesRead); free(pbBuffer); //======================================================================== // DosPrintDestDel // // This API deletes the print destination. //======================================================================== if (fDelete == TRUE) { uRet = DosPrintDestDel(pszServer, // Servername pszPrinterName); // Printername printf("DosPrintDestDel returned %u\n", uRet); } exit(0); } // End of main //======================================================================= // DisplayInfo // // Displays the print destination information obtained by // DosPrintDestGetInfo or DosPrintDestEnum. //======================================================================= void DisplayInfo(short sLevel, char *pbBuffer, unsigned short cEntries) { char * pprd0Info; // Level 0 data PPRDINFO pprd1Info; // Pointer to level 1 structure PSZ * pprd2Info; // Array of pointers PPRDINFO3 pprd3Info; // Pointer to level 3 structure unsigned short iCount; // Index counter pprd0Info = (char *) pbBuffer; pprd1Info = (PPRDINFO) pbBuffer; pprd2Info = (PSZ *) pbBuffer; pprd3Info = (PPRDINFO3) pbBuffer; for (iCount = 0; iCount < cEntries; iCount++) { switch (sLevel) { case 0: printf(" Printer Name: %s\n", pprd0Info); pprd0Info += (strlen(pprd0Info) + 1); break; case 1: printf(" Printer Name: %s\n", pprd1Info->szName); printf(" User Name : %s\n", pprd1Info->szUserName); printf(" Job Id : %hu\n", pprd1Info->uJobId); if (pprd1Info->uJobId) // Data valid only while job prints { printf(" Job Status : 0x%hx\n", pprd1Info->fsStatus); printf(" Status Text : %Fs\n", pprd1Info->pszStatus); printf(" Time : %hu\n", pprd1Info->time); } pprd1Info++; break; case 2: printf(" Printer Name: %Fs\n", *pprd2Info++); break; case 3: printf(" Printer Name: %Fs\n", pprd3Info->pszPrinterName); printf(" Logical Addr: %Fs\n", pprd3Info->pszLogAddr); printf(" Drivers : %Fs\n", pprd3Info->pszDrivers); printf(" Comment : %Fs\n", pprd3Info->pszComment); printf(" Job Id : %hu\n", pprd3Info->uJobId); if (pprd3Info->uJobId) { printf(" User Name : %Fs\n", pprd3Info->pszUserName); printf(" Job Status : 0x%hx\n", pprd3Info->fsStatus); printf(" Status Text : %Fs\n", pprd3Info->pszStatus); printf(" Print time : %hu\n", pprd3Info->time); } pprd3Info++; break; default: break; } // End switch sLevel } // End for loop } // End function //======================================================================= // Usage // // Displays possible command-line switches for this sample program. //======================================================================= void Usage(char *pszProgram) { fprintf(stderr, "Usage: %s [-s \\\\server] [-l level]", pszProgram); fprintf(stderr, " [-d driver]\n\t[-p printer] [-f flag delete]"); fprintf(stderr, " [-a address] [-o operation]\n"); exit(1); }