4.3 Enumerating and Managing Printers

To manage printers on a print server ("CORPSERV"), a client ("TESTCLT") performs the following steps.

  1. Enumerate existing printers using RpcEnumPrinters.

    • The client calls RpcEnumPrinters.

     RpcEnumPrinters( PRINTER_ENUM_NAME, L"\\\\CORPSERV", 2, NULL, 0, &countBytesNeeded, &printersFound );
    
    • The server returns ERROR_INSUFFICIENT_BUFFER and sets countBytesNeeded to the size needed to store _PRINTER_INFO_2 structures for all shared print queues.

    • The client allocates memory in printerInfo2[] with the size set to countBytesNeeded.

    • The client calls RpcEnumPrinters.

       RpcEnumPrinters( PRINTER_ENUM_NAME, L"\\\\CORPSERV", 2, printerInfo2, countBytesNeeded, &countBytesNeeded, &printersFound );
      
    • The server writes a _PRINTER_INFO_2 structure for each shared print queue to the output buffer, writes the number of _PRINTER_INFO_2 structures to printersFound, and returns 0 (success).

      Note: If the number of shared print queues on the server has increased between the first and second call to RpcEnumPrinters, the server returns ERROR_INSUFFICIENT_BUFFER from the second call as well. In that case, the server updates countBytesNeeded, and the client allocates more memory and repeats the call to RpcEnumPrinters.

  2. Open a handle to the print queue using RpcOpenPrinter.

    • The client selects a print queue from the _PRINTER_INFO_2 structure and uses the pPrinterName or pShareName to open the print queue handle as follows:

      • The client allocates and initializes a DEVMODE_CONTAINER devmodeContainer structure.

      • The client calls RpcOpenPrinter.

       RpcOpenPrinter( L"\\\\CORPSERV\\My Printer", &hPrinter, L"RAW", &devmodeContainer, PRINTER_ACCESS_USE);
      
    • The server allocates printer handle, writes it to hPrinter, and returns 0 (success).

  3. Retrieve current information about a printer using RpcGetPrinter.

    • The client calls RpcGetPrinter.

       RpcGetPrinter(hPrinter, 2, NULL, 0, &countBytesNeeded);
      
    • The server returns ERROR_INSUFFICIENT_BUFFER and sets countBytesNeeded to store a _PRINTER_INFO_2 structure for the print queue.

    • The client allocates memory in printerInfo2[] with size set to countBytesNeeded.

    • The client calls RpcGetPrinter.

       RpcGetPrinter( hPrinter, 2, printerInfo2, countBytesNeeded, &countBytesNeeded );
      
    • The server writes a _PRINTER_INFO_2 structure for the print queue to the output buffer and returns 0 (success).

      Note: If the size of data for the print queue on the server has increased between the first and second call to RpcGetPrinter, the server returns ERROR_INSUFFICIENT_BUFFER from the second call as well. That can happen under a race condition if another client changes the print queue data. In that case, the server updates countBytesNeeded, and the client allocates more memory and repeats the call to RpcGetPrinter.

  4. Use RpcSetPrinter to modify the state of the printer.

    • The client allocates a PRINTER_INFO_2 structure and populates it with members from the previously acquired _PRINTER_INFO_2. The client changes those members that require change:

       pLocation = L"Building 84, Room 1129";
      
    • The client allocates a PRINTER_CONTAINER printerContainer structure and initializes it to contain the prepared PRINTER_INFO_2.

    • The client allocates a DEVMODE_CONTAINER devmodeContainer structure, and optionally initializes it with a DEVMODE structure.

    • The client allocates a SECURITY_CONTAINER securityContainer structure, and optionally initializes it with a SECURITY_DESCRIPTOR.

    • The client calls RpcSetPrinter.

       RpcSetPrinter( hPrinter, &printerContainer, &devmodeContainer, &securityContainer, 0 );
      
    • The server modifies the print queue and returns 0 (success).

  5. Close the printer using RpcClosePrinter.

    • The client calls RpcClosePrinter.

       RpcClosePrinter( &hPrinter );
      
    • The server frees the memory associated with the print queue handle, sets hPrinter to NULL, and returns 0 (success).

Enumerating and managing printers on a server

Figure 7: Enumerating and managing printers on a server