Printers

 

File and print services has been a long requirement of the traditional network operating system. Over the years, networks have grown from a few computers in a single room to campuses of buildings hosting hundreds to thousands of computers around the globe, all of which need to print.

Regardless of how green an organization is, the need to print remains and has only become more complicated as networks span floors and buildings and mobile users are in the Mobile, Alabama branch today and the Charlotte, North Carolina branch tomorrow. IT networks added more printers; however, users were challenged to remember what printer to use depending on their building, floor or geographical location. To resolve these challenges, IT professionals developed mapped printer connections.

Mapped printer connections attacked the problem of users needing to remember what printer to use by reconciling users to printers based on group memberships or other criteria and then implemented that logic in complicated user logon scripts. User burden was reduced, but at the expense of the administrative overhead. Now IT administrators need to learn a complex logic scripting and programming experience. Group Policy Printers resolve aims to problem a simple resolution for both user and administrators.

Overview

The Group Policy Printers extension enables you to configure local, shared, or TCP/IP printers for an enterprise environment without the complicated mess of login scripts. You configure the Group Policy Printers extension using the same tools to configure Group Policy. As a result, managing printer connections for users and computers is consistent and does not require programming or scripting knowledge.

Capabilities

The Group Policy Printers extension provides the basic enterprise printer deployment and management by enabling you to create, replace, and delete local, shared, and TCP/IP based printers. In addition, the Group Policy Printers extension enables updating settings such as description and default printer status on these types of printers.

You can combine Printer preference items with Group Policy Preferences Item-level targeting to achieve granular and complex connected printers scenarios that remain simple, easy to manage, and do not use or require knowledge of scripting languages.

Pushed Printers

The Group Policy Printers extension should not be confused with the Pushed Printer Group Policy extension. Pushed printers is an alternative technology used to deploy printers in the enterprise that stores data in Active Directory as well as on SYSVOL share of a domain controllers. Group Policy Printers exclusively stores its configuration information on the SYSVOL share of domain controllers.

Processing Complete

The extension has completed processing the all inner and outer elements in the configuration file. To finalize the processing, the extension must updated the Group Policy history based on its actions during processing. Understand, the actions are not based on individual preference items, but rather the entire configuration file.

The extension caches the configuration files, if configured, for all Group Policy objects applied from the new or changed GPO list in the Group Policy Preference history. A configuration file hosted in a GPO appearing in the Out-of-scope GPO list is removed from the Group Policy Preference history.

Local Printer

The Group Policy Printers preference extension allows you to create, configure, and delete local printers by using the Local Printer preference item.

The Local Printer preference item provides several configuration points to help achieve most local printer scenarios that exist in enterprise environments.

Action (1)

This type of preference item provides a choice of four actions: Create, Replace, Update, and Delete. The behavior of the preference item varies with the action selected and whether the printer connection already exists.

Create

Create a new local printer. If a local printer with the same name exists, then it does not modify it.

Delete

Remove a local printer with the same name. The extension performs no action if the local printer does not exist. If a printer with the same name exists, the extension only removes the connection. It does not remove the printer driver.

Replace

Delete and Create the local printer. The net result of the Replace action overwrites all existing settings associated with the local printer. If the local printer does not exist, then the Replace action creates a new local printer.

Update

Rename or modify a local printer. The action differs from Replace in that it updates the settings defined within the preference item. All other settings remain as they were previously configured. If the local printer does not exist, then the Update action creates a new local printer.

Name (2)

The name of the targeted local printer. The preference extension creates a new local printer with this name if the local printer does not exist. If the printer exists, the preference extension uses the local printer with this name as the target of the requested action. Press F3 to display a list of variables from which you can select.

Port (3)

Choose a local port from the supplied list or type the name of the local port.

Printer Path (4)

The fully qualified UNC path of a shared printer connection. The preference extension uses this shared connection as an installation source for the printer driver. The actual printer should be physically connected to the workstation.

Set this printer as the default printer (5)

Makes the local printer the default Windows printer for the current user.

Location (6)

A description to where the printer is located. This information appears in the Location text box on the printer properties dialog box. Press F3 to display a list of variables from which you can select.

Comment (7)

Text that provides additional comments about the printer. This information appears in the Comments text box on the printer properties dialog box. Press F3 to display a list of variables from which you can select.

Shared Printer

The Printers preference extension allows you to create, configure and delete shared printer connections by using the Shared Printers preference item.

Action (1)

This type of preference item provides a choice of four actions: Create, Replace, Update, and Delete. The behavior of the preference item varies with the action selected and whether the printer connection already exists.

Create

Create a new local printer. If a local printer with the same name exists, then it does not modify it.

Delete

Remove a local printer with the same name. The extension performs no action if the local printer does not exist. If a printer with the same name exists, the extension only removes the connection. It does not remove the printer driver.

Replace

Delete and Create the local printer. The net result of the Replace action overwrites all existing settings associated with the local printer. If the local printer does not exist, then the Replace action creates a new local printer.

Update

Rename or modify a local printer. The action differs from Replace in that it updates the settings defined within the preference item. All other settings remain as they were previously configured. If the local printer does not exist, then the Update action creates a new local printer.

Action (1)

This type of preference item provides a choice of four actions: Create, Replace, Update, and Delete. The behavior of the preference item varies with the action selected and whether the printer connection already exists.

Create

Create a new shared printer connection. If a local printer with the same name exists, then it does not modify it.

Delete

Remove a shared printer connection with the same share path. The extension performs no action if the shared printer connection does not exist. If a printer with the same share path exists, the extension only removes the connection. It does not remove the printer driver.

Replace

Delete and Create the shared printer connection. The net result of the Replace action overwrites all existing settings associated with the shared printer connection. If the shared printer connection does not exist, then the Replace action creates a new shared printer connection.

Update

Modify a shared printer connection. The action differs from Replace in that it updates the settings defined within the preference item. All other settings remain as they were previously configured. If the shared printer connection does not exist, then the Update action creates a new shared printer connection.

Share Path (3)

A fully qualified UNC path of a shared printer.

Set this printer as the default printer (4)

Make the shared printer connection the default Windows printer for the current user.

Only if local printer is not present (5)

Bypasses changing the default printer if there is a local printer configured on the computer. This setting is unavailable until you select the Set this printer as the default printer check box.

A local printer is any printer that is not connected to a shared network printer. This includes physical printers connected to parallel, serial, and USB ports, TCP/IP printers, and virtual printers installed through software.

Local Port (6)

Choose a local port to which you want the shared connection mapped (optional).

When Local Port contains a value and the preference item action is set to Delete, the preference extension deletes the shared printer connection associated with that local port.

Reconnect (7)

Select this check box if you want the shared printer connection persistent. This option is unavailable until you choose a value from the Local Port list.

Unmap all local ports (8)

Select this check box if you want to delete shared printer connections from all local ports. This setting is available only when the preference item's action is set to Delete.

TCP/IP Printer (Port printer)

The Printers preference extension allows you to create, configure, and delete TCP/IP printers by using the TCP/IP Printer preference item.

General Tab

Action (1)

Create

Create a new TCP/IP printer connection. If a TCP/IP printer connection with the same IP address exists, then it does not modify it.

Delete

Remove a TCP/IP printer connection with the same IP address. The extension performs no action if the TCP/IP printer connection does not exist. The Delete action does not remove the printer driver or port. It only removes the TCP/IP printer connection.

Replace

Delete and Create the TCP/IP printer connection. The net result of the Replace action overwrites all existing settings associated with the TCP/IP printer connection. If the TCP/IP printer connection does not exist, then the Replace action creates a new TCP/IP printer connection.

Update

Modify a TCP/IP printer connection. The action differs from Replace in that it updates the settings defined within the preference item. All other settings remain as they were previously configured. If the TCP/IP printer connection does not exist, then the Update action creates a new TCP/IP printer connection.

Delete all IP printer connections (2)

Deletes all TCP/IP printer connections for the current user. This setting is available only when the preference item's action is set to Delete.

IP Address/DNS name (3)

The IP address of the remote printer. Or select the Use DNS name check box and type the fully qualified domain name of the remote printer.

Use DNS Name (4)

Toggles the formatting of the IP Address/ DNS name text box. When Use DNS Name cleared, the preference item configuration formats IP for Address text box for an IPv4 address. When Use DNS Name is selected, the preference item configuration formats the DNS name text box for a fully qualified domain name. The Group Policy Printers extension does directly support IPv6 addresses.

Local Name (5)

The local name of the targeted TCP/IP printer connection. The preference extension creates a new TCP/IP printer connection with this name if one does not exist. If a TCP/IP printer connection with this name exists, the preference extension uses the TCP/IP printer with this name as the target of the requested action. Press F3 to display a list of variables from which you can select.

The Group Policy Printers preference extension uses Local Name to determine if a TCP/IP printer exists when a Local Name is provided. Otherwise, the preference extension uses the TCP/IP address or the DNS Name to determine if the TCP/IP connection exits.

Printer path (6)

Type a fully qualified UNC path of a shared printer connection. The preference extension uses this shared connection as an installation source for the printer driver.

Set this printer as the default printer (7)

Make the TCP/IP printer connection the default Windows printer for the current user.

Only if local printer is not present (8)

Bypasses changing the default printer if there is a local printer configured on the computer. This setting is unavailable until you select the Set this printer as the default printer check box.

A local printer is any printer that is not connected to a shared network printer. This includes physical printers connected to parallel, serial, and USB ports, TCP/IP printers, and virtual printers installed through software.

Location (9)

A description to where the printer is located. This information appears in the Location text box on the printer properties dialog box. Press F3 to display a list of variables from which you can select.

Comment (10)

Text that provides additional comments about the printer. This information appears in the Comments text box on the printer properties dialog box. Press F3 to display a list of variables from which you can select.

Port Settings Tab

Protocol (1)

Specifies either a TCP/IP (Raw) printer or an RFC1179 compliant printer.

Port Number (2)

The port number used when communicating to the printer. The default port number is 9100.

LPR Settings (3)

The name of the LPR Queue to use when communicating with the printer. The default is "LPR".

LPR Byte Counting Enabled (4)

When selected, document sizes are calculated locally prior to being sent to the printer. Some LPR ports require this setting to be enabled to prevent data loss.

SNMP Status Enabled (5)

Specifies whether or not the printer port will support RFC1759

Community Name (6)

Specifies the SNMP community name used by the printer. The default is "public".

SNMP Device Index (7)

Specifies the SNMP device index used by the printer. The default is 1.

How does it work?

The Group Policy Printer preference extension is a Group Policy client side extension that is hosted in the gpprefcl.dll dynamic linked library. As part of the Group Policy specification, each component of data stored in a Group Policy object must have two 128-bit unique identifiers in a string format.

Client-side and Tool Identifiers

The first identifier associates the portion of data stored in the Group Policy object with the entity responsible for consuming, or processing the data. This identifier is known as the client-side extension identifier.

The second identifier associates the portion of data stored in the Group Policy object with the entity responsible for authoring, or managing it. This identifier is known as the snap-in identifier, or tool identifier.

The client –side extension unique for the Group Policy Printers preference extension is {BC75B1ED-5833-4858-9BB8-CBF0B166DF9D}. The snap-in unique identifier for the Group Policy Printers preference extension is {A8C42CEA-CDB8-4388-97F4-5831F933DA84}.

Group Policy uses the client-side identifier in many locations. First, the client side identifier is stored in the registry of the local computer. The registry location is

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions

The Group Policy infrastructure reads the preceding registry location to discover all Group Policy client-side extensions on the computer. Client-side extensions not listed at this location do not process during the application of Group Policy. The registration information includes a sub-key with the client-side extensions unique identifier as the name. Several registry values reside beneath the identifier key. These values are used by the Group Policy infrastructure, but also provide valuable information such as the name of the client side extension (in the Default registry value), the binary file that hosts the client-side extension code (in the DLLName registry value), and the event source and event log the extension uses to report information, warnings, and errors (in the EventSources registry value, separated by a comma, respectively).

When a Group Policy object is configured to include data from a specific client side extension, the editor must include the client-side extension and snap-in unique identifiers as part of the data saved in the Group Policy object.

Extensions specific data configured to apply to computers is saved to the gPCMachineExtensionNames attribute of the Group Policy container object. Extension specific data configured to apply to users is saved to the gPCUserExtensionNames attribute. If extension specific data is configured to apply to both user and computer, then the editor saves the extension identifier and the snap-in identifier to both attributes of the Group Policy container object

The gPCMachineExtensionNames and the gPCUserExtensionNames attribute can hold one or more groups of unique identifiers. Each identifier group is comprised of an extension identifier followed by one or more snap-in identifiers. The group of identifiers are bracketed accordingly by surrounding both identifiers within square brackets ([ ]).

extensionID1snapinID1snapinID2…… [ extensionIDnsnapinIDn…]

The unique identifier grouping must be listed in ascending alphanumeric order. Saving these in any other order prevents Group Policy from correctly applying or prevents you from editing existing extensions specific data within the Group Policy object.

Storing the extension identifier and the snap-in identifiers in the Group Policy object provides hints that optimize Group Policy processing and management. Processing is optimal because the Group Policy infrastructure knows prior to processing which extensions are required to apply the data hosted in the Group Policy object. Authoring is optimal because the editor has hints to determine what specific snap-ins are needed to edit the data.

XML Configuration

The Group Policy Printers preference extension stores all configuration data associated with the Group Policy object in an XML-formatted file. The Printers.xml file resides in the Printers folder in the Group Policy template that is hosted and shared on all domain controllers’ SYSVOL share. The Group Policy template location varies for each Group Policy object and is the string value stored in the gPCFileSysPath attribute on the Group Policy container object.

\\dns_domain_name\Sysvol\dns_domain_name\Policies\group_policy_id

XML Declaration

The Group Policy Printers configuration file starts with the XML declaration. The declaration describes two characteristics of the XML content: version and encoding.

The version declaration identifies the version of XML syntax the document uses. The encoding declaration identifies the characters used throughout the document.

The XML declaration used in the Group Policy Printers configuration file uses a value of 1 for the XML version and the encoding value is UTF-8

<?xml version="1.0" encoding="UTF-8"?>

The Group Policy Printers configuration file does not include the optional standalone declaration.

Elements

Group Policy Printers configuration files use four XML elements to describe the configuration data: an outer element and an inner element for each printer preference type. The outer element serves as a logical container of the inner XML elements. The inner elements represent the configuration of one or more preference items belonging to the container (outer XML element).

Outer Elements

The Group Policy Printers configuration file uses an outer XML element named Printers. This element serves as a collection of inner elements where each inner element represents a printer preference item. The Printers outer element supports two attributes: clsid and disabled.

Attributes

The Printers outer element of the Group Policy Printers configuration file contains one required and one optional attribute.

Clsid

The clsid attribute is a 128-bit unique identifier represented as global unique identifier (GUID). The clsid value identifies the type of outer element. The Group Policy Printers client-side extension expects the outer element’s clsid value to equal {1F577D12-3D1B-471e-A1B7-060317597B9C}. This is how the client-side extension identifies and validates the outer-element is of type Printers

Disabled

The disabled attribute is an optional attribute for the Drives outer element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicated false.

A Printers outer element with a disabled attribute equaling true indicates the configuration for all inner elements is disabled. This prevents the Group Policy Printers extension from processing any of the inner elements of the configuration file. A disabled attribute equaling false indicates the configuration for all inner elements is enabled and that processing continues as normal.

A Printers outer element without a disabled attribute indicates that the outer element has never been disabled. In this configuration, the default value for the disabled attribute is false, which means the outer element is enabled and processing continues normally. The disabled attribute appears in the configuration the first time the outer element is disabled and remains in the configuration for the remainder configuration files lifetime. Once in the configuration, the value of the attribute is changed with the respective configuration, but never removed.

<Printers clsid=" {1F577D12-3D1B-471e-A1B7-060317597B9C}" disabled="0">

Inner Elements

The Printers outer element accepts three types of inner elements. The LocalPrinter inner element represents a single local printer preference item. The SharedPrinter inner element represents a single shared printer preference item. And the PortPrinter inner element represents a single TCP/IP printer preference item. There can be any combination of one or more LocalPrinter, SharedPrinter, or PortPrinter inner elements within the Printers outer element.

Each inner element contains attributes that describe the inner element. These attributes are jointly used by management editors and client side extensions as a way to identify one inner element from the next. The inner element attributes do not contain configuration data.

Local Printer Element

Attributes

ByPassErrors

The byPassErrors attribute is an optional attribute for the LocalPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

One or more printer inner elements are contained within a single Printers outer element, which enables the client-side extension to process one or more preference items. A LocalPrinter inner element with a byPassErrors attribute equaling true indicates the Group Policy Printers extension should continue processing the next printer inner element regardless if the result of the current printer inner element is a failure. A byPassErrors attribute equaling false indicates the extension should stop processing subsequent printer inner elements if the result of the current inner element is a failure.

A LocalPrinter inner element without a byPassErrors attribute indicates that the inner element has never been configured to halt on errors. In this configuration, the default value for the byPassErrors attribute is true, which means the any inner element failure does not halt the processing of subsequent inner elements. The byPassErrors attribute appears in the configuration the first time the inner element is configured to stop on errors. Once in this configuration, the value of the attribute changes with each respective configuration, but never removed.

Changed

The changed attribute is an optional attribute for the LocalPrinter inner element. The attribute uses a string value to represent the date and time of when the inner element was last modified in UTC. The string value uses the format of YYYY-MM-DD HH:MM:SS.

Clsid

The clsid attribute is a 128-bit unique identifier represented as global unique identifier (GUID). The clsid value identifies the type of inner element. The Group Policy Printers client-side extension expects the LocalPrinter inner element’s clsid value to equal {F08996D5-568B-45f5-BB7A-D3FB1E370B0A}. This is how the client-side extension identifies and validates the inner element is of type LocalPrinter.

Disabled

The disabled attribute is an optional attribute for the LocalPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicated false.

A LocalPrinter inner element with a disabled attribute equaling true indicates the configuration for that inner element is disabled. This prevents the Group Policy Printers extension from processing that inner element in the configuration file. A disabled attribute equaling false indicates the configuration for that inner element is enabled and that processing continues as normal.

A LocalPrinter inner element without a disabled attribute indicates that the inner element has never been disabled. In this configuration, the default value for the disabled attribute is false, which means the inner element is enabled and processing continues normally. The disabled attribute appears in the configuration the first time the inner element is disabled and remains in the configuration for the remainder configuration files lifetime. Once in the configuration, the value of the attribute is changed with the respective configuration, but never removed.

Image

The image attribute is a numeric string value that represents the index of a bitmap resource used by the Group Policy Management editor as the icon image used to display the preference item in the editor. The value of the numeric string typically corresponds to the value of the action attribute in the properties element.

Image Value

Action Value

0

C

1

R

2

U

3

D

Name

The name attribute is a string value that represents the display name of the preference item. The name attribute has no impact on the processing of the preference item and is strictly used for management and reporting.

removePolicy

The removePolicy attribute is an optional attribute for the LocalPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

A LocalPrinter inner element with a removePolicy attribute equaling true indicates the Group Policy Printers extension should remove the configuration included in the inner element if the Group Policy object hosting the preference item is not within scope of the user or computer. Once the Group Policy object hosting the preference item no longer applies to the user, the Group Policy Printers extension removes the effective results of the inner element’s configuration from the user or computer.

The removePolicy attribute correlates to the value of the action attribute in the Properties element. A LocalPrinter inner element with a removePolicy attribute equal to true requires the value of the action attribute of Properties element to equal an uppercase R.

A LocalPrinter inner element with a removePolicy attribute equaling false indicates the extension should process the preference item as configured.

A LocalPrinter inner element without a removePolicy attribute indicates the inner element has never been configured to remove when it no longer applies. In this configuration, the default value for the removePolicy attribute is false, which means the extension processes the preference item as configured. The removePolicy attribute appears in the configuration the first time the inner element is configured to remove items when it no longer applies. Once in this configuration, the value of the attribute changes with each respective configuration, but is never removed.

Status

The status attribute is string value that represents a message that the Group Policy Preference editor can display in the status area of the Microsoft Management Console. The status attribute remains as part of the configuration; however, is no longer being actively implemented.

Uid

The uid attribute is a 128-bit identifier represented as global unique identifier (GUID). The uid value uniquely identifies each inner element. This is how the client-side extension identifies and differentiates each LocalPrinter inner element.

UserContext

The userContext attribute is an optional attribute for the LocalPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

A LocalPrinter inner element with a userContext attribute equaling true indicates the Group Policy Printers extension should create the mapped drive using the security context of the current user. A LocalPrinter inner element with a removePolicy attribute equaling false indicates the extension should process the preference item using the security context of the local system.

A LocalPrinter inner element without a userContext attribute indicates the inner element has been manually configured to apply in the security context of the current user. In this configuration, the default value varies on a per-policy basis using the simple guidelines of computer preference items run in the security context of the local system and user preference items run in the security context of the current user.

The userContext attribute appears in the configuration the first time the inner element is manually configured to apply using the security context of the current user. Once in this configuration, the value of the attribute changes with each respective configuration, but is never removed.

The userContext attribute remains as part of the configuration; however, is no longer actively implemented. Most of the Group Policy Preference extensions programmatically switch between the current user and system security contexts as needed, irrespective of the userContext attribute value present in the inner element configuration. The recommended configuration is to leave each preference item to the defaults and to not manually configure the security context of any preference item.

<LocalPrinter clsid="{F08996D5-568B-45f5-BB7A-D3FB1E370B0A}" name="LocalPrinter" status="Location" image="2" changed="2013-05-16 17:33:56" uid="{A10F181B-8938-44F6-9818-84A28B3A37E6}" bypassErrors="1">

Properties Element

Each inner element requires a Properties element in the configuration file. Group Policy Preference extensions read the Properties element for the preference item configuration.

Attributes

The Properties element shares unique and common attributes among all the Group Policy Preferences inner element classes. The common attributes characterize abstract functionality provided by the inner element classes (preference items) such as create, delete, or update. However, the implementation of these actions varies across each inner element.

Action

The action attribute is an optional string attribute in the Properties element used to describe the action the Group Policy Printers extension performs for the associated inner element. That action attribute value is a single, uppercase letter of C, R, U, or D. If the action attribute is not present in the Properties element then the default value is U.

Create

An action attribute value equaling an upper case C instructs the extension to create a new local printer using the settings in the current LocalPrinter inner element.

The create action instructs the extension to create a new local printer only when the computer or current user does not have a local printer that shares the same name with the value in the name attribute.

If the computer or current user has an existing local printer name that matches the value in the name attribute then the extension ignores the instruction and does not report an error.

The create action, after successfully creating the new local printer, may also set the newly created local printer as the default local printer based on the value configured in the default attribute.

Delete

An action attribute value equaling an upper case D instructs the Group Policy Printers extension to remove an existing local printer using the settings in the current LocalPrinter inner element.

The delete action has two behaviors based on the value in the deleteAll attribute. When the deleteAll attribute value equals 1, the delete action removes all local printers for the computer or current user. A deleteAll attribute value equaling 0 instructs the extension to remove a local printer only when the computer or current user has a local printer with a name that matches the value of the name attribute.

If the computer or current user does not have an existing local printer that shares the same name with the value in the name attribute then the extension ignores the instruction and does not report an error.

Replace

An action attribute value equaling an upper case R instructs the extension to replace the existing local printer with the settings in the current LocalPrinter inner element. The replace action instructs the extension to perform the delete action first, and then the create action. The delete instruction removes an existing local printer using the criteria identified in the Delete action. The create instruction creates a new local printer using the criteria identified in the Create action. The results of the replace action gives the perception that the extension overwrote all settings associated with the local printer.

Update

The action attribute value equaling an upper case U instructs the Group Policy Printers extension to update an existing local printer with the settings configured in the current LocalPrinter inner element.

The update action instructs the extension to update settings on the local printer only when the computer or current user has a local printer that shares the same name with the value in the name attribute.

If the computer or current user does not have an existing local printer name that matches the value in the name attribute then the extension creates a new local printer using the settings configured in the LocalPrinter inner element.

Comment

The comment attribute is an optional string attribute in the Properties element used to include additional remarks about the printer that are visible in the printer’s property page.

Default

The default attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a LocalPrinter inner element with a default attribute equaling true indicates the extension should make the printer targeted in the current inner element the default printer after it performs the configured action.

A Properties element within a LocalPrinter inner element with a default attribute equaling false indicates the extension should not make the printer in the current inner element the default printer.

Location

The location attribute is an optional string attribute in the Properties element used to include a description of the printer’s location that appears on the printer’s property page.

Name

The name attribute is a required attribute in the Properties element that accepts a string value. The extension uses the value of the name attribute as the name of newly created printer when the action attribute value equals an upper case C, R, or U and a local printer does not exist for the computer or local user.

A computer or current user with a local printer sharing the same name as the value of the name attribute causes the extension to use that printer as the target of the configured action when the action attribute value equals an upper case D, R, or U.

Path

The path attribute is a required attribute in the Properties element that accepts a string value Universal Naming Convention (UNC) path to a shared printer. The Group Policy Printers extension uses this path as the installation source for the printer driver used to configure the local (physically attached) printer.

Port

The port attribute is a required attribute in the Properties element that accepts a string value of the local computer port the extension uses when creating the new local printer.

<LocalPrinter clsid="{F08996D5-568B-45f5-BB7A-D3FB1E370B0A}" name="printer1" status="Location" image="2" changed="2013-05-16 17:33:56" uid="{A10F181B-8938-44F6-9818-84A28B3A37E6}" bypassErrors="1"><Properties action="U" name="printer1" port="LPT4:" path="\\server\somePrinter" default="0" deleteAll="0" location="Location" comment="Comments"/></LocalPrinter>

XML to User Interface mapping

The Group Policy Printers management snap-in determines the values and attributes stored in the XML configuration. The following figures correlate which components of the user interface control or show various elements and attributes in the XML file.

Port Printer Element

Attributes

ByPassErrors

The byPassErrors attribute is an optional attribute for the PortPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

One or more printer inner elements are contained within a single Printers outer element, which enables the client-side extension to process one or more preference items. A PortPrinter inner element with a byPassErrors attribute equaling true indicates the Group Policy Printers extension should continue processing the next printer inner element regardless if the result of the current printer inner element is a failure. A byPassErrors attribute equaling false indicates the extension should stop processing subsequent printer inner elements if the result of the current inner element is a failure.

A LocalPrinter inner element without a byPassErrors attribute indicates that the inner element has never been configured to halt on errors. In this configuration, the default value for the byPassErrors attribute is true, which means the any inner element failure does not halt the processing of subsequent inner elements. The byPassErrors attribute appears in the configuration the first time the inner element is configured to stop on errors. Once in this configuration, the value of the attribute changes with each respective configuration, but never removed.

Changed

The changed attribute is an optional attribute for the PortPrinter inner element. The attribute uses a string value to represent the date and time of when the inner element was last modified in UTC. The string value uses the format of YYYY-MM-DD HH:MM:SS.

Clsid

The clsid attribute is a 128-bit unique identifier represented as global unique identifier (GUID). The clsid value identifies the type of inner element. The Group Policy Printers client-side extension expects the PortPrinter inner element’s clsid value to equal {C3A739D2-4A44-401e-9F9D-88E5E77DFB3E}. This is how the client-side extension identifies and validates the inner element is of type PortPrinter.

Disabled

The disabled attribute is an optional attribute for the PortPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicated false.

A PortPrinter inner element with a disabled attribute equaling true indicates the configuration for that inner element is disabled. This prevents the Group Policy Printers extension from processing that inner element in the configuration file. A disabled attribute equaling false indicates the configuration for that inner element is enabled and that processing continues as normal.

A PortPrinter inner element without a disabled attribute indicates that the inner element has never been disabled. In this configuration, the default value for the disabled attribute is false, which means the inner element is enabled and processing continues normally. The disabled attribute appears in the configuration the first time the inner element is disabled and remains in the configuration for the remainder configuration files lifetime. Once in the configuration, the value of the attribute is changed with the respective configuration, but never removed.

Image

The image attribute is a numeric string value that represents the index of a bitmap resource used by the Group Policy Management editor as the icon image used to display the preference item in the editor. The value of the numeric string typically corresponds to the value of the action attribute in the properties element.

Image Value

Action Value

0

C

1

R

2

U

3

D

Name

The name attribute is a string value that represents the display name of the preference item. The name attribute has no impact on the processing of the preference item and is strictly used for management and reporting.

RemovePolicy

The removePolicy attribute is an optional attribute for the PortPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

A PortPrinter inner element with a removePolicy attribute equaling true indicates the Group Policy Printers extension should remove the configuration included in the inner element if the Group Policy object hosting the preference item is not within scope of the user or computer. Once the Group Policy object hosting the preference item no longer applies to the user, the Group Policy Printers extension removes the effective results of the inner element’s configuration from the user or computer.

The removePolicy attribute correlates to the value of the action attribute in the Properties element. A PortPrinter inner element with a removePolicy attribute equal to true requires the value of the action attribute of Properties element to equal an uppercase R.

A PortPrinter inner element with a removePolicy attribute equaling false indicates the extension should process the preference item as configured.

A PortPrinter inner element without a removePolicy attribute indicates the inner element has never been configured to remove when it no longer applies. In this configuration, the default value for the removePolicy attribute is false, which means the extension processes the preference item as configured. The removePolicy attribute appears in the configuration the first time the inner element is configured to remove items when it no longer applies. Once in this configuration, the value of the attribute changes with each respective configuration, but is never removed.

Status

The status attribute is string value that represents a message that the Group Policy Preference editor can display in the status area of the Microsoft Management Console. The status attribute remains as part of the configuration; however, is no longer being actively implemented.

Uid

The uid attribute is a 128-bit identifier represented as global unique identifier (GUID). The uid value uniquely identifies each inner element. This is how the client-side extension identifies and differentiates each PortPrinter inner element.

UserContext

The userContext attribute is an optional attribute for the PortPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

A PortPrinter inner element with a userContext attribute equaling true indicates the Group Policy Printers extension should create the mapped drive using the security context of the current user. A LocalPrinter inner element with a removePolicy attribute equaling false indicates the extension should process the preference item using the security context of the local system.

A LocalPrinter inner element without a userContext attribute indicates the inner element has been manually configured to apply in the security context of the current user. In this configuration, the default value varies on a per-policy basis using the simple guidelines of computer preference items run in the security context of the local system and user preference items run in the security context of the current user.

The userContext attribute appears in the configuration the first time the inner element is manually configured to apply using the security context of the current user. Once in this configuration, the value of the attribute changes with each respective configuration, but is never removed.

The userContext attribute remains as part of the configuration; however, is no longer actively implemented. Most of the Group Policy Preference extensions programmatically switch between the current user and system security contexts as needed, irrespective of the userContext attribute value present in the inner element configuration. The recommended configuration is to leave each preference item to the defaults and to not manually configure the security context of any preference item.

<PortPrinter clsid="{C3A739D2-4A44-401e-9F9D-88E5E77DFB3E}" name="TCP/IP Printer" status="TCP/IP Printer" image="2" changed="2013-06-05 22:11:27" uid="{3840AAFA-BFFE-46DD-8FDE-8DFE33F34908}">

Properties Element

Each inner element requires a Properties element in the configuration file. Group Policy Preference extensions read the Properties element for the preference item configuration.

Attributes

The Properties element shares unique and common attributes among all the Group Policy Preferences inner element classes. The common attributes characterize abstract functionality provided by the inner element classes (preference items) such as create, delete, or update. However, the implementation of these actions varies across each inner element.

Action

The action attribute is an optional string attribute in the Properties element used to describe the action the Group Policy Printers extension performs for the associated inner element. That action attribute value is a single, uppercase letter of C, R, U, or D. If the action attribute is not present in the Properties element then the default value is U.

Create

An action attribute value equaling an upper case C instructs the extension to create a new TCP/IP printer connection using the settings in the current PortPrinter inner element.

The create action instructs the extension to create a new TCP/IP printer connection only when the computer or current user does not have an existing TCP/IP printer connection. The extension determines the matching criterion by the localName attribute value.

A string value in the localName attribute causes the extension to use the localName attribute value as the matching criterion to determine if the printer connection exists. An empty localName attribute value causes the extension to use the value in the ipAddress attribute as the matching criterion to determine if the printer connection exists. An ipAddress attribute containing the fully qualified domain name of the remote printer causes the extension to resolve the name to an IPv4 address and use the resolved IPv4 address as the value to determine if the printer connection exists.

An existing printer connection found for the computer or current user causes the extension to ignore the action and does not report an error. A computer or current user without an existing printer connection causes the extension to create a new TCP/IP printer connection using the settings from the current PortPrinter inner element.

The create action, after successfully created the new TCP/IP printer connection, may also set the newly created TCP/IP printer connection as the default printer based on the value configured in the default attribute.

Delete

An action attribute value equaling an upper case D instructs the Group Policy Printers extension to remove an existing TCP/IP printer connection using the settings in the current PortPrinter element.

The delete action has two behaviors based on the value in the deleteAll attribute. When the deleteAll attribute value equals true (one [1]), the delete action removes all TCP/IP printer connections for the computer or current user. A deleteAll attribute value equaling false (zero [0]) instructs the extension to remove a TCP/IP printer connection only when the computer or current user has a TCP/IP printer connection matching the settings in the current PortPrinter inner element.

The extension determines the matching criterion by the localName attribute value. A string value in the localName attribute causes the extension to use the localName attribute value as the matching criterion to determine if the printer connection exists. An empty localName attribute value causes the extension to use the value in the ipAddress attribute as the matching criterion to determine if the printer connection exists. An ipAddress attribute containing the fully qualified domain name of the remote printer causes the extension to resolve the name to an IPv4 address and use the resolved IPv4 address as the value to determine if the printer connection exists.

Replace

An action attribute value equaling an upper case R instructs the extension to replace the existing TCP/IP printer connection with the settings in the current PortPrinter inner element. The replace action instructs the extension to perform the delete action first, and then the create action. The delete instruction removes an existing TCP/IP printer connection using the criteria identified in the Delete action. The create instruction creates a new TCP/IP printer connection using the criteria identified in the Create action. The results of the replace action gives the perception that the extension overwrote all settings associated with the local printer.

Update

The action attribute value equaling an upper case U instructs the Group Policy Printers extension to update an existing TCP/IP printer connection with the settings configured in the current PortPrinter inner element.

The update action instructs the extension to update settings on the TCP/IP printer connection only when the computer or current user has a matching TCP/IP printer.

The extension determines the matching criterion by the localName attribute value. A string value in the localName attribute causes the extension to use the localName attribute value as the matching criterion to determine if the printer connection exists. An empty localName attribute value causes the extension to use the value in the ipAddress attribute as the matching criterion to determine if the printer connection exists. An ipAddress attribute containing the fully qualified domain name of the remote printer causes the extension to resolve the name to an IPv4 address and use the resolved IPv4 address as the value to determine if the printer connection exists.

If the computer or current user does not have a matching TCP/IP printer connection then the extension creates a TCP/IP printer connection using the settings configured in the PortPrinter inner element.

Comment

The comment attribute is an optional string attribute in the Properties element used to include additional remarks about the printer that are visible in the printer’s property page.

Default

The default attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a PortlPrinter inner element with a default attribute equaling true indicates the extension makes the printer targeted in the current inner element the default printer after it performs the configured action.

A Properties element within a PortPrinter inner element with a default attribute equaling false indicates the extension does not make the printer in the current inner element the default printer.

DeleteAll

The deleteAll attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a PortPrinter inner element with a deleteAll attribute equaling true indicates the extension deletes all TCP/IP printer connections for the computer or current user when the action attribute value equals an upper case D.

A Properties element within a PortPrinter inner element with a deleteAll attribute equaling false indicates the extension does not delete all TCP/IP printer connections for the computer or current user when the action attribute value equals an upper case D.

DoubleSpool

The doubleSpool attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a PortPrinter inner element with a doubleSpool attribute equaling true indicates the extension enables double spooling for the targeted TCP/IP printer connection for the computer or current user.

A Properties element within a PortPrinter inner element with a doubleSpool attribute equaling false indicates the extension disabled or does not enabled double spooling for the targeted TCP/IP printer connections for the computer or current user.

The doubleSpool attribute only appears in the inner element when you configure one or more port settings for the targeted printer. Otherwise, the extension uses the default value of 0.

IPAddress

The ipAddress attribute is a required attribute in the Properties element that accepts a string value. The extension uses the value of the ipAddress to locate the remote printer it uses to process the configured action.

Also, the extension uses the ipAddress attribute value as the criterion used to determine if an existing TCP/IP printer connection exists when the localName attribute is not configured. An ipAddress attribute containing the fully qualified domain name of the remote printer causes the extension to resolve the name to an IPv4 address and use the resolved IPv4 address as the value to determine if the printer connection exists.

The extension expects the value of the ipAddress to be a numerical string of an IPv4 address of the remote printer when the useDNS attribute value equals false (zero [0]). When the useDNS attribute value equals true (one [1]), the extension expects the value of the ipAddress to be fully qualified domain name of the remote printer.

UseDNS

The useDNS attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a PortPrinter inner element with a useDNS attribute equaling true indicates the extension expects the ipAddress attribute value to be a fully qualified domain name of the remote printer. Additionally, the extension resolves the fully qualified domain name to an IPv4 address before performing the configured action.

A Properties element within a PortPrinter inner element with a useDNS attribute equaling false indicates the extension expects the ipAddress attribute value to be numerical string IPv4 address.

LocalName

The localName attribute is an optional string attribute. The extension uses this attribute as a name for newly created TCP/IP printer connections and as the matching criterion that determines if a TCP/IP printer connection exists for the computer or current user.

An unconfigured localName attribute instructs the extension to use the configured IPv4 address as the matching criterion that determines if a TCP/IP printer connection exists. Otherwise, the extension uses the localName attribute value as the matching criterion to determine if a TCP/IP printer connection exists. A TCP/IP printer connection sharing the same name as the localName attribute value becomes the targeted TCP/IP printer connection for the configured action.

Location

The location attribute is an optional string attribute in the Properties element used to include a description of the printer’s location that appears on the printer’s property page.

LPRQueue

The lprQueue attribute is an optional string attribute in the Properties element. A protocol attribute value equaling “PROTOCOL_LPR_TYPE” requires the lprQueue attribute to contain a string value that represents the name of the LPR queue. The extension ignored the lprQueue attribute when the protocol attribute value equals “PROTOCOL_RAWTCP_TYPE”

Path

The path attribute is a required attribute in the Properties element that accepts a string value Universal Naming Convention (UNC) path to a shared printer. The Group Policy Printers extension uses this path as the installation source for the printer driver used to configure the TCP/IP printer connection.

PortNumber

The portNumber attribute is an optional, numerical-string attribute in the Properties element when configuring a raw TCP/IP printer and a required numerical-string attribute when configuring a LPR printer. The attribute’s value must be the port number used to communicate with the targeted printer. A protocol attribute value equaling PROTOCOL_LPR_TYPE requires the portNumber to contain the numerical-string value 515.

The portNumber attribute only appears in the inner element when you configure one or more port settings for the targeted printer. Otherwise, the extension uses the default value of 9100.

Protocol

The protocol attribute is an optional, string attribute in the Properties element when configuring raw TCP/IP printer and a required string attribute when configuring a LPR printer. A protocol attribute value equaling “PROTOCOL_LPR_TYPE” indicates the targeted printer is configured as an LPR printer. A protocol attribute value equaling “PROTOCOL_RAWTCP_TYPE” or a missing protocol attribute indicates the targeted printer is configured as a raw TCP/IP printer.

The protocol attribute only appears in the inner element when you configure one or more port settings for the targeted printer. Otherwise, the extension uses the default value of “PROTOCOL_RAWTCP_TYPE”.

SkipLocal

The skipLocal attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false. The extension ignores attribute if the default attribute value equals false.

A Properties element within a PortPrinter inner element with a skipLocal attribute equaling true indicates the extension must bypass changing the default printer if a local printer is configured for the computer or current user.

A Properties element within a PortPrinter inner element with a skipLocal attribute equaling false indicates the extension does not bypass changing the default printer if a local printer is configured for the computer or current user.

SNMPCommunity

The snmpCommunity attribute is an optional string attribute in the Properties element. When configured, the snmpCommunity value represents the community named in which the printer participates. The attribute’s value defaults to “public” and applies to both raw and LPR TCP/IP printers.

The snmpCommunity attribute only appears in the inner element when you configure one or more port settings for the targeted printer. Otherwise, the extension uses the default value of “public.”

SNMPDevIndex

The snmpDevIndex is an optional attribute in the Properties element. The attribute uses a numerical string value to indicate the SNMP device index used for the targeted printer.

The snmpDevIndex attribute only appears in the inner element when you configure one or more port settings for the targeted printer. Otherwise, the extension uses the default value of 0.

SNMPEnabled

The snmpEnabled attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a PortPrinter inner element with a snmpEnabled attribute equaling true indicates the extension enables SNMP and its settings on the printer targeted in the current inner element.

A Properties element within a PortPrinter inner element with a snmpEnabled attribute equaling false indicates the extension does not enable SNMP and its settings on the printer targeted in the current inner element.

The snmpEnabled attribute only appears in the inner element when you configure one or more port settings for the targeted printer. Otherwise, the extension uses the default value of 0.

<PortPrinter clsid="{C3A739D2-4A44-401e-9F9D-88E5E77DFB3E}" name="dnsName" status="dnsName" image="2" changed="2013-06-05 22:11:27" uid="{3840AAFA-BFFE-46DD-8FDE-8DFE33F34908}"><Properties ipAddress="dnsName" action="U" location="Location" localName="Local Name" comment="Comment" default="1" skipLocal="1" useDNS="1" path="printer path" deleteAll="0"/></PortPrinter>

XML to User Interface mapping

The Group Policy Printers management snap-in determines the values and attributes stored in the XML configuration. The following figures correlate which components of the user interface control or show various elements and attributes in the XML file.

Shared Printer Element

Attributes

ByPassErrors

The byPassErrors attribute is an optional attribute for the SharedPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

One or more printer inner elements are contained within a single Printers outer element, which enables the client-side extension to process one or more preference items. A SharedPrinter inner element with a byPassErrors attribute equaling true indicates the Group Policy Printers extension should continue processing the next printer inner element regardless if the result of the current printer inner element is a failure. A byPassErrors attribute equaling false indicates the extension should stop processing subsequent printer inner elements if the result of the current inner element is a failure.

A SharedPrinter inner element without a byPassErrors attribute indicates that the inner element has never been configured to halt on errors. In this configuration, the default value for the byPassErrors attribute is true, which means the any inner element failure does not halt the processing of subsequent inner elements. The byPassErrors attribute appears in the configuration the first time the inner element is configured to stop on errors. Once in this configuration, the value of the attribute changes with each respective configuration, but never removed.

Changed

The changed attribute is an optional attribute for the SharedPrinter inner element. The attribute uses a string value to represent the date and time of when the inner element was last modified in UTC. The string value uses the format of YYYY-MM-DD HH:MM:SS.

Clsid

The clsid attribute is a 128-bit unique identifier represented as global unique identifier (GUID). The clsid value identifies the type of inner element. The Group Policy Printers client-side extension expects the SharedPrinter inner element’s clsid value to equal {9A5E9697-9095-436d-A0EE-4D128FDFBCE5}. This is how the client-side extension identifies and validates the inner element is of type SharedPrinter.

Disabled

The disabled attribute is an optional attribute for the SharedPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicated false.

A SharedPrinter inner element with a disabled attribute equaling true indicates the configuration for that inner element is disabled. This prevents the Group Policy Printers extension from processing that inner element in the configuration file. A disabled attribute equaling false indicates the configuration for that inner element is enabled and that processing continues as normal.

A SharedPrinter inner element without a disabled attribute indicates that the inner element has never been disabled. In this configuration, the default value for the disabled attribute is false, which means the inner element is enabled and processing continues normally. The disabled attribute appears in the configuration the first time the inner element is disabled and remains in the configuration for the remainder configuration files lifetime. Once in the configuration, the value of the attribute is changed with the respective configuration, but never removed.

Image

The image attribute is a numeric string value that represents the index of a bitmap resource used by the Group Policy Management editor as the icon image used to display the preference item in the editor. The value of the numeric string typically corresponds to the value of the action attribute in the properties element.

Image Value

Action Value

0

C

1

R

2

U

3

D

Name

The name attribute is a string value that represents the display name of the preference item. The name attribute has no impact on the processing of the preference item and is strictly used for management and reporting.

RemovePolicy

The removePolicy attribute is an optional attribute for the SharedPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

A SharedPrinter inner element with a removePolicy attribute equaling true indicates the Group Policy Printers extension should remove the configuration included in the inner element if the Group Policy object hosting the preference item is not within scope of the user or computer. Once the Group Policy object hosting the preference item no longer applies to the user, the Group Policy Printers extension removes the effective results of the inner element’s configuration from the user or computer.

The removePolicy attribute correlates to the value of the action attribute in the Properties element. A SharedPrinter inner element with a removePolicy attribute equal to true requires the value of the action attribute of Properties element to equal an uppercase R.

A SharedPrinter inner element with a removePolicy attribute equaling false indicates the extension should process the preference item as configured.

A SharedPrinter inner element without a removePolicy attribute indicates the inner element has never been configured to remove when it no longer applies. In this configuration, the default value for the removePolicy attribute is false, which means the extension processes the preference item as configured. The removePolicy attribute appears in the configuration the first time the inner element is configured to remove items when it no longer applies. Once in this configuration, the value of the attribute changes with each respective configuration, but is never removed.

Status

The status attribute is string value that represents a message that the Group Policy Preference editor can display in the status area of the Microsoft Management Console. The status attribute remains as part of the configuration; however, is no longer being actively implemented.

Uid

The uid attribute is a 128-bit identifier represented as global unique identifier (GUID). The uid value uniquely identifies each inner element. This is how the client-side extension identifies and differentiates each SharedPrinter inner element.

UserContext

The userContext attribute is an optional attribute for the SharedPrinter inner element. The attribute uses a numeric string to represent a Boolean value. A value of 1 indicates true and a value of 0 indicates false.

A SharedPrinter inner element with a userContext attribute equaling true indicates the Group Policy Printers extension should create the mapped drive using the security context of the current user. A SharedPrinter inner element with a removePolicy attribute equaling false indicates the extension should process the preference item using the security context of the local system.

A SharedPrinter inner element without a userContext attribute indicates the inner element has been manually configured to apply in the security context of the current user. In this configuration, the default value varies on a per-policy basis using the simple guidelines of computer preference items run in the security context of the local system and user preference items run in the security context of the current user.

The userContext attribute appears in the configuration the first time the inner element is manually configured to apply using the security context of the current user. Once in this configuration, the value of the attribute changes with each respective configuration, but is never removed.

The userContext attribute remains as part of the configuration; however, is no longer actively implemented. Most of the Group Policy Preference extensions programmatically switch between the current user and system security contexts as needed, irrespective of the userContext attribute value present in the inner element configuration. The recommended configuration is to leave each preference item to the defaults and to not manually configure the security context of any preference item.

<SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="sharePath" status="sharePath" image="2" changed="2013-06-05 22:06:43" uid="{7C851C09-C0D2-4EFC-8FD6-6A5093EE644E}">

Properties Element

Action

The Properties element shares unique and common attributes among all the Group Policy Preferences inner element classes. The common attributes characterize abstract functionality provided by the inner element classes (preference items) such as create, delete, or update. However, the implementation of these actions varies across each inner element.

Create

An action attribute value equaling an upper case C instructs the extension to create a new shared printer connection using the settings in the current SharedPrinter inner element.

The create action instructs the extension to create a new shared printer connection only when the computer or current user does not have a shared printer connection that shares the same path with the value in the path attribute.

If the computer or current user has a shard printer connection with a share path that matches the value in the path attribute then the extension ignores the instruction and does not report an error.

The create action, after successfully creating the new shared printer connection, may also set the newly created shared printer connection as the default printer based on the value configured in the default attribute.

Delete

An action attribute value equaling an upper case D instructs the Group Policy Printers extension to remove an existing shared printer connection using the settings in the current SharedPrinter inner element.

The delete action has two behaviors based on the value in the deleteAll attribute and two behaviors based on the value in the deleteMaps attribute.

When the deleteAll attribute value equals true (one [1]), the delete action removes all shared printer connections from the computer or current user. A deleteAll attribute equaling false (zero [0]) instructs the extension to remove the shared printer connection only when the computer or current user has a shared printer connection with a share path that matches the value in the path attribute of the current inner element.

A computer or current user not having an existing shared printer connection with a share path matching the value in the path attribute causes the extension to ignore the instruction and not report an error.

When the deleteMaps attribute value equals true (one [1]), the delete action removes all shared printer connections from associated local ports for the computer or current user. A deleteMaps attribute value equaling false (zero [0]) case the extension to remove the shared printer connection associated with the port matching the value in the port attribute.

Replace

An action attribute value equaling an upper case R instructs the extension to replace the existing shared printer connecting with the settings in the current SharedPrinter inner element. The replace action instructs the extension to perform the delete action first, and then the create action. The delete instruction removes an existing shared printer connection using the criteria identified in the Delete action. The create instruction creates a new shared printer connection using the criteria identified in the Create action. The results of the replace action gives the perception that the extension overwrote all settings associated with the shared printer connection.

Update

The action attribute value equaling an upper case U instructs the Group Policy Printers extension to update an existing local printer with the settings configured in the current SharedPrinter inner element.

The update action instructs the extension to update the settings on the shared printer connections only when the computer or current user has a shared printer connection with a share path matching the path attribute value in the current inner element.

A computer or current user not having a shared printer connection with a share path matching the value in the path attribute cause the extension to create a new shared printer connection using the settings configured in the SharedPrinter inner element.

Comment

The comment attribute is an optional string attribute in the Properties element used to include additional remarks about the printer that are visible in the printer’s property page.

Cpassword

The cpassword attribute is an optional string attribute in the Properties element used to store a password needed to successfully connect the configured shared printer. The attribute value is a string representation of the password that is obfuscated using an AES-derived encryption key. The default value for the cpassword attribute is an empty string, or blank.

Default

The default attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a SharedPrinter inner element with a default attribute equaling true indicates the extension makes the printer targeted in the current inner element the default printer after it performs the configured action.

A Properties element within a SharedPrinter inner element with a default attribute equaling false indicates the extension does not make the printer in the current inner element the default printer.

DeleteAll

The deleteAll attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a SharedPrinter inner element with a deleteAll attribute equaling true indicates the extension deletes all shared printer connections for the computer or current user when the action attribute value equals an upper case D.

A Properties element within a SharedPrinter inner element with a deleteAll attribute equaling false indicates the extension does not delete all shared printer connections for the computer or current user when the action attribute value equals an upper case D.

DeleteMaps

The deleteMaps attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false.

A Properties element within a SharedPrinter inner element with a deleteMaps attribute equaling true indicates the extension removes all shared printer connections from associated local ports for the computer or current user when the action attribute value equals an upper case D.

A Properties element within a SharedPrinter inner element with a deleteAll attribute equaling false indicates the extension removes the shared printer connection associated with the port matching the value in the port attribute for the computer of current user when the action attribute value equals an upper case D.

Location

The location attribute is an optional string attribute in the Properties element used to include a description of the printer’s location that appears on the printer’s property page.

Path

The path attribute is a required attribute in the Properties element that accepts a string value Universal Naming Convention (UNC) path to a shared printer. The Group Policy Printers extension uses this path as the installation source for the printer driver used to configure the shared printer connection.

Persistent

The persistent attribute is an optional attribute in the Properties element. The attribute uses a numeric string to represent a Boolean value. A value equaling 1 indicates true and a value of 0 indicates false.

A Properties element within a SharedPrinter inner element with a persistent attribute equaling true indicates the Group Policy Printers extension creates the shared printer connection to remain persistent between user logons and computer reboots. Windows remembers the shared printer connection and reestablishes the connection on subsequent user logons.

A Properties element within a SharedPrinter inner element with a persistent attribute equaling false indicates the Group Policy Printers extension creates the shared printer connection not to persist between user logons and computer reboots. Windows does not remember the shared printer connection and does not reestablish the connection on subsequent reboots.

It’s important to understand that Windows configures persistency at the time it creates the shared printer connection. Therefore, if you want need to use the Replace action if you need to change a shared printer connection’s persistent state.

Port

The port attribute is a required attribute in the Properties element that accepts a string value of the local computer port the extension uses when creating the new shared printer connection.

SkipLocal

The skipLocal attribute is an optional attribute in the Properties element. The attribute uses a numerical string to represent a Boolean value. A value equaling 1 indicates true and a value equaling 0 indicates false. The extension ignores attribute if the default attribute value equals false.

A Properties element within a SharedPrinter inner element with a skipLocal attribute equaling true indicates the extension must bypass changing the default printer if a local printer is configured for the computer or current user.

A Properties element within a SharedPrinter inner element with a skipLocal attribute equaling false indicates the extension does not bypass changing the default printer if a local printer is configured for the computer or current user.

Username

The username attribute is an optional string attribute in the Properties element used to store the domain and username needed to successfully connect to the configured shared printer.

<SharedPrinter clsid="{9A5E9697-9095-436d-A0EE-4D128FDFBCE5}" name="sharePath" status="sharePath" image="2" changed="2013-06-05 22:06:43" uid="{7C851C09-C0D2-4EFC-8FD6-6A5093EE644E}"><Properties action="U" comment="" path="sharePath" location="" default="1" skipLocal="1" deleteAll="0" persistent="1" deleteMaps="0" port="Local Port"/></SharedPrinter>

XML to User Interface mapping

The Group Policy Printers management snap-in determines the values and attributes stored in the XML configuration. The following figures correlate which components of the user interface control or show various elements and attributes in the XML file.

Evaluation of XML

The extension reads the entire XML file into memory subsequently processes each element in the XML file starting with the outer element. The outer element defines the overarching class of preference items that appear in the inner elements of the file. Additionally, the outer element may contain the disabled attribute. A disabled attribute value equaling true (one [1]) in the outer element stops any further evaluation of the XML, effectively preventing all LocalPrinter, SharedPrinter, or PortPrinter inner elements from processing (applying to the computer or user).

After reading the Printers element, the extension focuses its attention to the next element in the XML file—one of possibly many printer inner element. As noted in the attribute section, printer inner elements contain metadata and processing control information used be the Group Policy management snap-ins and the client-side extensions.

The extension reads the attributes and values from the entire printer inner element, which includes the attributes and values of the LocalPrinter, SharedPrinter, or PortPrinter elements, the attributes and values of the Properties element and the attributes and values of an optional Filters element along with all its child elements and their attributes and values.

A printer inner element containing a disabled attribute equaling true (one [1]) stops the extension from processing this element (applying to the computer or user) and the extension moves its focus to the next inner element.

The extension continues processing the current inner element when it does not contain a disabled attribute or when it contains a disabled attribute with a value equaling false (zero [0]).

Next, the extension moves its focus on the Filter element of the inner element.

The Filters element holds Item-level targeting information that the extension uses as additional criteria to determine if the associated preference items (Printers) should apply to the user or computer.

The Filters element contains attributes, values and child elements that represent a sophisticated set of Boolean rules. The details of the Filters element are beyond the scope of this section. In this context, all that is needed to know is a Filter element, when evaluated by an extension, only returns true or false.

When present, the extension reads the entire Filters element and evaluates each Boolean expression included in the section. The evaluation of the Filters element can only result in a true or false response. A filter evaluation result equaling false means the one or more Boolean expressions in the Filters element evaluated to false. The false evaluation forces the extension to stop any further processing of the current inner element and moves focus to the next inner element.

A LocalPrinter, SharedPrinter, or PortPrinter inner element that does not contain a Filters inner element or an inner element containing a Filters inner element that evaluates to true moves its focus to the Properties element, which is the next element within the current inner element.

The Properties element within a LocalPrinter inner element contains all the local printer configuration information the extension needs to create, replace, update, or delete a local printer. The Group Policy Printer extension reads the attributes and values and performs the requested instructions and determines if the actions performed were successful.

If the actions performed were unsuccessful (an error occurred), the extension checks the bypassErrors attribute value read from the current LocalPrinter inner element. A false value (zero [0]) instructs the extension to discontinue further processing of all printer inner elements while a true value (one [1]) instructs the extension to ignore the unsuccessful result and continue processing additional inner elements.

The extension then moves its focus to the next printer inner element and the process repeats until the XML file reaches the Printers closing outer element.

CSE Processing

Group Policy client side extensions enable Group Policy to process a variety of different tasks because each client side extension is responsible for processing its portion of data stored in a Group Policy object.

The Group Policy Printers client side extension is one of many extensions included in the gpprefcl.dll file that is included in the Windows operating system starting with Windows Server 2008 and Windows Vista Service Pack 1.

Group Policy’s modular design enables each extension to process the data that is relevant to them. Therefore, the implementation of each Group Policy client side extension may be different.

The Group Policy Printers extension is one CSE in a family of Group Policy client side extensions known as Group Policy Preferences. The goal of this extension is to manage printer deployment scenarios. The extension comes registered on the Windows operating system by virtue of CSE specific metadata stored in the following registry location

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions\{BC75B1ED-5833-4858-9BB8-CBF0B166DF9D}

The information stored in this location is consistent on all computers. Therefore, restoring the information on a computer where it is missing is relatively easy using the export and import feature of the Registry editor.

Startup

The Group Policy service invokes this client side extension when it encounters a Group Policy object configured with Group Policy Printers. When activated, the extension must locate its configuration file.

Prerequisite information

When Group Policy invokes the client side extension, it provides to the extension information that enables it to process its portion of Group Policy. This information includes operational information that describes the current processing context such as if the processing is background or foreground, is the processing occurring over a slow link, or is the processing for the computer rather than the user. Also included in this information is a list of the Group Policy objects that were removed from the scope of application and the list of Group Policy objects that were changed.

Each entry in the list of Group Policy objects provides to the client side extension provides information about the Group Policy object in question. The entry includes the following table.

Field

Description

Options

Client side extensions use the options field to determine if the Group Policy object is disabled or if the Group Policy object is

Version

The Group Policy object version number increments with saved changes to the computer and user portions of a GPO, respectively. Client side extensions can use the version number to determine if any changes were made to the computer or user portion of a GPO.

DSPath

The DS path provides the LDAP path, which provides the location and common name of the Group Policy object in Active Directory. Remember, the common name of a GPO is its unique identifier; not its display name.

File system path

The file system path provides the root location of the files associated with the Group Policy object. These collection of files typically are used by one or more client side extensions as the data store for group policy settings.

Link Path

The link path field provides an LDAP path of the container to which the Group Policy is linked

Link Type

The link type field provides information about the container to which the GPO is linked such as computer, site, domain, or organizational unit.

Extensions

The extension field provides a list of the extensions that are configured in the Group Policy object.

Display name

The display name is the name of the GPO that is displayed in user interfaces and reporting tools.

The information in the table above is present for each GPO in both lists. The out-of-scope list contains a list of GPOs that applied to the user or computer on the last application of Group Policy but no longer apply on this application of Group Policy. The changed list contains a list of GPOs that include changes for one or more aspects of the Group Policy object.

The extension reads the operational information to understand what type of Group Policy processing Windows is performing: user or computer. How the processing is occurring: foreground or background. This enables the client side extensions to make operational decisions based on this processing characteristics.

The extension uses the lists of Group Policy objects to complete its portion of Group Policy processing. The Group Policy Printers extension starts by processing each of the GPOs in the out-of-scope list.

Out-of-Scope Group Policy objects

The Group Policy Printers extension processes the entire list of out-of-scope GPOs sequentially. The extension logs any errors reading the Group Policy objects and continues processing until it reaches the end of the list.

The extension cycles through the list of Group Policy objects in the list starting with the first entry in the list. The extension collects the prerequisite information about the current GPO. From this information and its own information, the extension builds file path location to the configuration file. The configuration file location path begins with the extensions history path.

Group Policy Preference History

The history path is a local data store of the last successfully applied data configuration files for each Group Policy object. The extension saves the last applied configuration files in the user’s local application folder, which holds a value equivalent to the Group Policy Preference environment variable %LOCALAPPDATA% on Windows 8 and Windows Server 2012. The root of the history folder looks similar to

C:\users\[username]\AppData\Local\Microsoft\Group Policy\History

Windows protects the history folder with the hidden attribute; therefore, by default, it is not visible from Windows Explorer or from the command line. The history folder contains sub folders, where each folder is named to the globally unique identifier (GUID) of a corresponding Group Policy object.

Each Group Policy object folder within the history folder contains sub folders where each folder is named to a corresponding security identifier (SID) of a user who has logged on to the current computer. The complete path to the history file for the Group Policy Printers extension is

C:\users\[username]\AppData\Local\Microsoft\Group Policy\History\[GUID]\SID\Preferences\Printers\Printers.xml

The extension then concatenates the string \User\Preferences\Printers\Printers.xml to the end of the GPO’s file system path. This creates a full path, including file name, to the configuration file.

Note

Windows allows the configuration and application of Group Policy Printers to computers and users.

The extensions opens this file and reads the entire contents of the file into memory and then closes the file. The CSE logs any errors occurring that may occur with the file operations and moves to the next GPO in the list.

Configuration File

The configuration file contains an outer element with multiple inner elements where each inner element represents a separate drive map preference item. Each inner element includes a Properties element that holds the respective elements configuration information.

The extension begins by settings its focus on the first inner element. The extension scans the current inner element for the removePolicy attribute. An inner element without a removePolicy attribute or an inner element with a removePolicy attribute value equaling false (zero [0]) causes the extension to move to the next inner element.

An inner element with a removePolicy attribute equaling true (one [1]) indicates to the extension that it must remove the settings in the current inner element. The extension uses the settings from the current inner element and its associated Properties element to undo, or remove the settings. The extension accomplishes this by forcing the processing to use the Remove action regardless of the action configured in the current inner element and continues this cycle until it has processed all inner elements in the configuration file. Once processing of all inner elements is complete, the extension deletes the \Printers\Printers.xml folder and file for the specific computer or user and GPO from the local history.

The extension then moves to the next Group Policy object in the list and processes it in the same fashion until it has processed all GPOs in the out-of-scope list. The extension begins processing the new and changed GPO list.

New and Changed Group Policy objects

The Group Policy Printers extension processes the entire list of new and changed GPOs sequentially. The extension logs any errors reading the Group Policy objects and continues processing until it reaches the end of the list.

The extension cycles through the list of Group Policy objects in the list starting with the first entry in the list. The extension collects the prerequisite information about the current GPO. From this information, the extension builds file path location to the configuration file. The configuration file location path begins with the GPO’s file system path. The extension then concatenates the string \User\Preferences\Printers\Printers.xml to the end of the GPO’s file system path. This creates a full path, including file name, to the configuration file.

Note

Windows allows the configuration and application of Group Policy Printers to computers and users.

Configuration File

The extension reads the entire configuration file into memory. The configuration file contains an outer element with multiple inner elements where each inner element represents a separate drive map preference item. Each inner element includes a Properties element that holds the respective elements configuration information.

Outer Element Processing

The extension evaluates the outer element for the disabled attribute. An outer element with a disabled attribute equaling true (one [1]) indicates the all inner elements are considered disabled. The extension discontinues processing any part of the current configuration and moves to the next Group Policy object in the list. An outer element without a disabled attribute or with a disabled attribute value equaling false (zero [0]) continues processing by evaluating the inner elements,

Inner Element Processing

The extension begins by settings its focus on the first inner element. The extension evaluates the current inner element for the disabled attribute. An inner element with a disabled attribute equaling true (one [1]) indicates the inner element is disabled. The extension discontinues processing the current inner element and move to the next inner element. An inner element without a disabled attribute or inner element with a disabled attribute value equaling false (zero [0]) continues evaluating the inner element for item-level targeting information.

Item-level Targeting Processing

The extension scans the current inner element for a Filters element. The Filters element is an optional element that holds the item-level targeting configuration information for each inner element. A Filters element existing within the inner element indicates the extension must evaluate one or more Boolean criteria before processing the inner element configuration. A false result from a Filters evaluation forces the extension to ignore the current inner element and move to the next inner element. A true result from a Filters evaluation indicates the extension should continue processing the inner element and action configured within the current element.

Action Processing

Action processing occurs once the client side extension has evaluated all other criteria that would instruct it to bypass processing outer or the current inner element. Action processing correlates to the action configured in each inner element (reminder an inner element represents a single preference item). The four actions the Group Policy Printers extension can process are create, replace, update, and delete. The tree preferences items the Group Policy Printers extension recognizes are local printers, shared printers, and TCP/IP printers.

Local Printer

Create

The create action represents a configuration where the extension creates a local printer based on the configuration in the current inner element.

Prologue

The extension sets the default values for <default> and <deleteAll> to false and then extracts the values for <port>, <name>, <location>, <comment>, <path>, <processor>, and <dataType> from the configuration information.

Core

The core phase of create action processing uses the configuration information read during the prologue phase to create a local printer for the computer or current user.

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute. A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to abort its process and return an object already exists error. A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to proceed with the driver installation phase.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the newly created local printer. An unsuccessful response from the Windows API causes the extension to abort its processing and to return the underlying error provided by the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install driver, provided the driver is not already installed.

If the driver needed for the printer installation is not located on the remote location specified by the <path> attribute value, then the extension closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing and returns an out of memory error.

A failed response from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection and proceed with adding the local printer to the computer or current user.

Add the printer

The extension continues processing by creating a new local printer based on the configuration in the current inner element. Adding a printer begins with the extension reacquiring a handle to the remote printer using the <path> attribute value and the OpenPrinter Windows API. A failed response from the API causes the extension to abort its processing and return the underlying error it received from the API.

A successful response from the API enables the extension to gather supplemental configuration information from the remote printer using the EnumPrinters Windows API. An unsuccessful response from the EnumPrinters API causes the extension to close the printer connection using the ClosePrinter Windows API, abort its processing, and return the underlying error it received from the EnumPrinters API. A successful response from the EnumPrinters API causes the extension to continue processing by closing the printer connection using the ClosePrinter API.

The extensions modifies a portion of the supplemental data received from the EnumPrinters API. The first of the data modified by the extension is the security descriptor. The extensions changes the security descriptor data returned by the API to a null value. The Windows authorization subsystem interprets a null security descriptor as if every user on the computer has full access to the printer.

The extension ensures the <port> and <name> attribute values are not empty. If either of these attribute values are empty, then the extension aborts its processing and returns an invalid printer name error.

Once the <port> and <name> attributes are validated, the extension then removes the PRINTER_ATTRIBUTE_SHARED bit from the attributes of the supplemental data previously gathered. The extension then determines if the <default> attribute value equals true. A <default> attribute value equaling true (one [1]) causes the extension to add the PRINTER_ATTRIBUTE_DEFAULT bit to the attributes of the supplemental data. A false (zero [0]) causes the extension to remove the PRINTER_ATTRIBUTE_DEFAULT bit from the attributes of the supplemental data.

The extension concludes this phase by passing the supplemental data along with the values of the <port>, <name>, <location>,<path>, and <comment> attributes to the AddPrinter Windows API. An unsuccessful result from the API causes the extension to abort its processing and return the underlying error it received from the API while a successful result from the API enables the extension to continue processing, and set the default printer.

Epilogue

To this point, the extension verified a local printer using the same name as the value configured in <name> attribute does not exist. The extension connected to the remote printer, downloaded and installed the printer driver, and subsequently collected supplemental data in which it combined with its configuration data to create the newly created local printer. The create action processing concludes by setting the default printer.

Set the default printer

The last successful result received from Windows was from using the AddPrinter API. Therefore, the extension now determines whether to set the default printer by checking the <default> attribute value. A false (zero [0]) attribute value instructs the extension that the printer is not configured to be the default printer and exits without an error.

A true (one [1]) value instructs the extension to make the newly created printer the default printer for the computer or user. To do this, the extension switches to the security context of the local user (when applying to the current user). Any failure resulting from the security context switch causes the extension to abort its processing and return the underlying error it received when attempting the security context switch.

The extension proceeds by passing the <name> attribute value to the SetDefaultPrinter Windows API. The extension exits without an error when it receives a successful response from API. Otherwise, the extension exits with the underlying error it received from the SetDefaultPrinter API.

Create action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Delete

The delete action represents a configuration where the extension deletes a specific local printer based on the configuration in the current inner element.

Prologue

The extension sets the default values for <default> and <deleteAll> to false and then extracts the values for <port>, <name>, <location>, <comment>, <path>, <processor>, and <dataType> from the configuration information.

Core

The core phase of delete action processing uses the configuration information read during the prologue phase to delete a local printer for the computer or current user.

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute. A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to gracefully exit without an error. A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to proceed with the deletion phase.

Epilogue

The extension has inventoried all local printers for the computer or current user and has found a local printer with name matching the <name> attribute value.

Deletion

The extension begins the deletion processing by passing the <name> attribute value to the OpenPrinter Windows API requesting PRINTER_ALL_ACCESS. An unsuccessful response from the API with an underlying invalid printer name error causes the extension to abort its processing and return an unexpected error. An unsuccessful result from the API causes the extension to abort its processing and return the underlying error it received from the API.

A successful response enables the extension to pass the printer handle it received from the OpenPrinter API to the DeletePrinter Windows API. An unsuccessful response from the API causes the extension to close the printer connection using the ClosePrinter API and returning the underlying it received from the API. A successful response from the API cause the extension to close the printer connection using the ClosePrinter API and exiting the function without an error.

Delete action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Replace

The replace action represents a configuration where the extension replaces an existing local printer with a newly created local printer based on the configuration in the current inner element.

It is important to understand the differences between replace and update. The replace action typically deletes an existing local printer and creates a new one—essentially changing all configuration elements of the local printer. The update action only updates a portion of the configuration elements for an existing local printer.

Prologue

The extension sets the default values for <default> and <deleteAll> to false and then extracts the values for <port>, <name>, <location>, <comment>, <path>, <processor>, and <dataType> from the configuration information.

Core

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute. A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to proceed to the Driver installation phase. A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to proceed with the deletion phase.

Deletion

The extension begins deletion processing by passing the <name> attribute value to the OpenPrinter Windows API requesting PRINTER_ALL_ACCESS permissions. An unsuccessful response from the API with an underlying invalid printer name error causes the extension to abort its processing and return an unexpected error. An unsuccessful result from the API causes the extension to abort its processing and return the underlying error it received from the API.

A successful response enables the extension to pass the printer handle it received from the OpenPrinter API to the DeletePrinter Windows API. An unsuccessful response from the DeletePrinter API causes the extension to close the printer connection using the ClosePrinter API and return the underlying it received from the DeletePrinter API. A successful response from the API causes the extension to close the printer connection using the ClosePrinter API and proceed with Driver installation.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the newly created local printer. An unsuccessful response from the Windows API causes the extension to abort its processing and to return the underlying error provided by the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install driver, provided the driver is not already installed.

If the extension does not locate the driver needed for the printer installation on the remote location specified by the <path> attribute value, then it closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing and returns an out of memory error.

A failed response from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection and proceed with adding the local printer to the computer or current user.

Add the printer

Adding a printer begins with the extension reacquiring a handle to the remote printer using the <path> attribute value and the OpenPrinter Windows API. A failed response from the API causes the extension to abort its processing and return the underlying error it received from the API.

A successful response from the API enables the extension to gather supplemental configuration information from the remote printer using the EnumPrinters Windows API. An unsuccessful response from the EnumPrinters API causes the extension to close the printer connection using the ClosePrinter Windows API, abort its processing, and return the underlying error it received from the EnumPrinters API. A successful response from the API causes the extension to continue processing by closing the printer connection using the ClosePrinter API.

The extensions modifies a portion of the supplemental data received from the EnumPrinters API. The first of the data modified by the extension is the security descriptor. The extensions changes the security descriptor data returned by the API to a null value. The Windows authorization subsystem interprets a null security descriptor as if every user on the computer has full access to the printer.

The extension ensures the <port> and <name> attribute values are not empty. If either of these attribute values are empty, then the extension aborts its processing and returns an invalid printer name error.

Once the <port> and <name> attributes are validated, the extension then removes the PRINTER_ATTRIBUTE_SHARED bit from the attributes of the supplemental data previously gathered. The extension then determines if the <default> attribute value equals true. A <default> attribute value equaling true (one [1]) causes the extension to add the PRINTER_ATTRIBUTE_DEFAULT bit to the attributes of the supplemental data. A false (zero [0]) causes the extension to remove the PRINTER_ATTRIBUTE_DEFAULT bit from the attributes of the supplemental data.

The extension concludes this phase by passing the supplemental data along with the values of the <port>, <name>, <location>, <path>, and <comment> attributes to the AddPrinter Windows API. An unsuccessful result from the API causes the extension to abort its processing and return the underlying error it received from the API while a successful result from the API enables the extension to continue processing, and set the default printer.

Epilogue

Set the default printer

The last successful result received from Windows was from using the AddPrinter API. Therefore, the extension now determines whether to set the default printer by checking the <default> attribute value. A false (zero [0]) attribute value instructs the extension that the printer is not configured to be the default printer and exits without an error.

A true (one [1]) value instructs the extension to make the newly created printer the default printer for the computer or user. To do this, the extension switches to the security context of the local user (when applying to the current user). Any failure resulting from the security context switch causes the extension to abort its processing and return the underlying error it received when attempting the security context switch.

The extension proceeds by passing the <name> attribute value to the SetDefaultPrinter Windows API. The extension exits without an error when it receives a successful response from API. Otherwise, the extension exits with the underlying error it received from the SetDefaultPrinter API.

Replace action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Update

The update action represents a configuration where the extension refreshes an existing local printer based on the configuration in the current inner element. It is important to understand the difference between replace and update.

The replace action typically deletes the existing local printer and creates a new one—essentially changing all configurations elements of the local printer. The update action only updates a portion of configuration elements in an existing local printer.

Prologue

The extension sets the default values for <default> and <deleteAll> to false and then extracts the values for <port>, <name>, <location>, <comment>, <path>, <processor>, and <dataType> from the configuration information.

Core

The core phase of create action processing uses the configuration information read during the prologue phase to create a local printer for the computer or current user.

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute.

A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to proceed to the Set the default printer phase. A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to proceed with the driver installation phase.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the newly created local printer. An unsuccessful response from the Windows API causes the extension to abort its processing and to return the underlying error provided by the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install driver, provided the driver is not already installed.

If the driver needed for the printer installation is not located on the remote location specified by the <path> attribute value, then the extension closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing and returns an out of memory error.

A failed response from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection and proceed with adding the local printer to the computer or current user.

Add the printer

The extension continues processing by creating a new local printer based on the configuration in the current inner element. Adding a printer begins with the extension reacquiring a handle to the remote printer using the <path> attribute value and the OpenPrinter Windows API. A failed response from the API causes the extension to abort its processing and return the underlying error it received from the API.

A successful response from the API enables the extension to gather supplemental configuration information from the remote printer using the EnumPrinters Windows API. An unsuccessful response from the EnumPrinters API causes the extension to close the printer connection using the ClosePrinter Windows API, abort its processing, and return the underlying error it received from the EnumPrinters API. A successful response from the EnumPrinters API causes the extension to continue processing by closing the printer connection using the ClosePrinter API.

The extensions modifies a portion of the supplemental data received from the EnumPrinters API. The first of the data modified by the extension is the security descriptor. The extensions changes the security descriptor data returned by the API to a null value. The Windows authorization subsystem interprets a null security descriptor as if every user on the computer has full access to the printer.

The extension ensures the <port> and <name> attribute values are not empty. If either of these attribute values are empty, then the extension aborts its processing and returns an invalid printer name error.

Once the <port> and <name> attributes are validated, the extension then removes the PRINTER_ATTRIBUTE_SHARED bit from the attributes of the supplemental data previously gathered. The extension then determines if the <default> attribute value equals true. A <default> attribute value equaling true (one [1]) causes the extension to add the PRINTER_ATTRIBUTE_DEFAULT bit to the attributes of the supplemental data. A false (zero [0]) causes the extension to remove the PRINTER_ATTRIBUTE_DEFAULT bit from the attributes of the supplemental data.

The extension concludes this phase by passing the supplemental data along with the values of the <port>, <name>, <location>,<path>, and <comment> attributes to the AddPrinter Windows API. An unsuccessful result from the API causes the extension to abort its processing and return the underlying error it received from the API while a successful result from the API enables the extension to continue processing, and set the default printer.

Epilogue

To this point, the extension verified a local printer using the same name as the value configured in <name> attribute does not exist. The extension connected to the remote printer, downloaded and installed the printer driver, and subsequently collected supplemental data in which it combined with its configuration data to create the newly created local printer. The create action processing concludes by setting the default printer.

Set the default printer

The last successful result received from Windows was from using the AddPrinter API. Therefore, the extension now determines whether to set the default printer by checking the <default> attribute value. A false (zero [0]) attribute value instructs the extension that the printer is not configured to be the default printer and exits without an error.

A true (one [1]) value instructs the extension to make the newly created printer the default printer for the computer or user. To do this, the extension switches to the security context of the local user (when applying to the current user). Any failure resulting from the security context switch causes the extension to abort its processing and return the underlying error it received when attempting the security context switch.

The extension proceeds by passing the <name> attribute value to the SetDefaultPrinter Windows API. The extension exits without an error when it receives a successful response from API. Otherwise, the extension exits with the underlying error it received from the SetDefaultPrinter API.

Update action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Port Printer

Create

The create action represents a configuration where the extension creates a TCP/IP printer connection based on the configuration in the current inner element.

Prologue

The extension begins processing portPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <localName>, <ipAddress>, <deleteAll>, <default>, <skipLocal>, <useDNS>, and <lprQueue> attributes.

The extension reads the next set of attributes from the current inner element and assigns each a default value if a value is not present in the inner element. These attributes include

The <snmpCommunity> with a default value “public”

The <protocol> attribute with a default value of “PROTOCOL_RAWTCP_TYPE”

The <port> attribute with a default value of “9100”

The <doubleSpool>, <snmpEnabled>, and <snmpDevIndex> with a default value of “0”

Lastly, the extension reads the <processor> attribute and provides a default value of “winprint”, and the <dataType> attribute with a default value of “RAW”.

Core

Determine IP address

The extension begins by determining the IP address it uses for the remote printer. It determines this decision based on the <useDNS> attribute value. A <useDNS> attribute value equaling false (zero [0]) causes the extension to use the value of the <ipAddress> attribute as the IPv4 address of the remote printer and proceed with the Check for printer process.

A <useDNS> attribute value equaling true (one [1]) causes the extension to read the fully qualified domain name from the <ipAddress> attribute value and proceed with the Name resolution phase.

Name resolution

The extension begins the name resolution process by using the LoadLibrary Windows API to load the wsock32.dll dynamic linked library into memory. An unsuccessful response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API causes the extension to resolve the name into an IPv4 address.

The extension resolves the name into an IPv4 address by passing the <ipAddress> value, which is a fully qualified domain name of a remote printer, to the GetAddrInfoW Windows API. A failed response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API returns a list of network addresses for the name.

The extension enters a critical section, iterates through the list of address, stores all IPv4 addresses in memory, and exits the critical section. Any errors encountered due to memory allocations causes the extension to abort its processing and return an out of memory error. Otherwise the extension continues by calling the WsaCleanup API and then evaluates the list of return IPv4 addresses.

The extension uses the first IPv4 address in the list of addresses returned from the GetAddrInfoW API. The extension converts the IPv4 address into a dotted, numerical string format and proceeds to the Check for printer process.

Any error encounter encountered during the name resolution phase causes the extension to write “Error resolving IP address” and the underlying error code to the trace log and proceed to the Check for printer phase.

Check for printer

The extension continues processing by determining if a TCP/IP printer exists for the computer or current user. To do this, the extension prefixes the IPv4 address discovered in the Determine IP address phase with “IP_”. The new variation of the IPv4 address looks like “IP_0.0.0.0”; however, with the IPv4 address of the remote printer.

The extension determines how it searches for an existing TCP/IP printer connection by checking the value of the <localName> attribute. If an attribute value exists, then the extension proceeds to the Matching the printer by name phase. If an attribute value does not exist, then the extension proceeds with the Matching by IPv4 address phase.

Matching by IPv4 address

Detect port and TCP/IP printer

The extension detects an existing TCP/IP Printer connection by port name using the varied instance of the IPv4 address created in the Check for printer process as the matching criterion.

The extension uses the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing, write “Error finding TCP/IP printer…” to the trace log, and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers. With each iteration, the extension verifies the current printer in the list of printers is not a network printer connection by validating the PRINTER_ATTRIBUTE_NETWORK bit is disabled on the current printers attributes. Next, the extension performs a case insensitive comparison of the current printer’s port name with the varied instance of the IPv4 port name.

The extensions encounters a matched TCP/IP printer connection when the current printer is not a shared printer connection and the current printer’s port name matches the varied instance of the IPv4 port name.

A complete cycle through the list of printers without finding a matched printer (port or printer name) causes the extension to proceed with the Get remote printer settings phase.

Upon matching a TCP/IP printer connection (port and printer), the extension saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and proceeds with the Get remote printer settings phase.

Matching by name

Detect port

The matching by name phase uses the varied instance of the IPv4 address created in the Check for printer phase and passes it to the OpenPrinter Windows API using the XcvPort and SERVER_ACCESS_ADMINISTRATOR permissions. Any error encountered when attempting to connect to the printer causes the extension to internally report that it could not locate the specified remote port and proceeds with the Detect local printers phase.

A successful response from the API instructs the extension to use the GetConfigInfo API from the Windows Device Driver TCPMON XcvData category of functions. An unsuccessful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it could not locate the specified remote port, and proceed with the Inventory local printers phase. A successful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it located the specified remote port, and proceed with the Detect local printers phase.

Detect local printers

The extension continues by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute. A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to internally report it found a matching printer and to proceed to the Get remote printer settings phase.

A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to internally report it did not find a matching printer and to proceed to the Get remote printer settings phase.

Get remote printer settings

The extension begins this phase by evaluating the <localName> attribute value. The extension uses this value to determine if it needs retrieve the printer name for the remote printer. The extension already has the printer name if it matched the printer by name. In this scenario, the extension proceeds to the Detect default printer override phase.

The extension needs to retrieve the printer name if it matched the printer by IPv4 address. The extension gets this information by passing the <path> attribute value to the OpenPrinter Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “Error getting TCP/IP printer settings …” to the trace log, and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the GetPrinter API causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error.

Any errors regarding memory allocation occurring while gather remote printer information causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error. A successful response from the API causes the extension to retrieve additional information about the remote printer. The additional information retrieved from the remote printer includes: printer name, driver name, server name, share name, printer processor, location, and comments.

Upon successfully retrieving the remote printer information, the extension closes the connection to the remote printer using the ClosePrinter API, saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and proceeds with the Detect default printer override phase.

Detect default printer override

The extension detects the default printer override option by validating both the <default> and <skipLocal> attribute values equal true (one [1]). If either attribute equals false, the extension proceeds to the Create port phase.

When both attributes equal true, the extension continues processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing, write “Error finding local printers”, and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs multiple evaluations. The extension first validates that the current printer from the list of local printers is not a network connected printer by determining if the PRINTER_ATTRIBUTE_NETWORK bit is enabled in the current printers attributes. If the current printer is a network printer, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. If the current printer is not a network printer, then the extension proceeds with validating the printer name.

The second evaluation performed on the current printer is to guarantee the current printer does not match the previously discovered printer name. If the current printer name matches the previously discovered printer name, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. Otherwise, the current printer name and the previously discovered printer name do not match and the extension continues with its final evaluation.

The final evaluation performed by the extension is to determine if the current printer port is configured with a local port. The extension checks if the port name of the current printer from the list of local printers contains “LPT”, “COM”, or “USB” in the name. If the current printer’s port name does not contain these strings, then the extension cycles to the next printer in the list of local printers.

If the extensions iterates through all the printers and does not discover a printer in the list of local printers that passes these evaluations, then it internally reports that a local printer is not present. If the extension identifies a printer from the list of local printers passing all three evaluations, then it will cease the iteration and internally report a local printer exists.

A local printer not existing for the computer or current user with both the <default> and <skipLocal> attributes equaling true causes the extension to proceed to the Create port phase.

A local printer existing for the computer or current user with both the <default>< and <skipLocal> attributes equaling true causes the extension to internally change the <default> attribute to equal false (zero [0]) and proceed to the Create port phase.

Create port

The extension determines if it needs to create the port for the computer or current user by internally referencing if it discovered the port through either the Detect port and TCP/IP printer phase or the Detect port phase. The extension proceeds to the Create printer phase if it successfully discovered the port.

Before creating the port, the extension ensures the computer has the necessary components installed to create a TCP/IP printer port. The extension accomplishes this using the EnumMonitors Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the API.

A successful result from the API also returns a list of print monitors available on the computer. The extension iterates through the list of print monitors until it locates a monitor name that matches the string “Standard TCP/IP Port”. If the extension does not discover the Standard TCP/IP Port monitor, then the extension aborts its processing, writes “Error adding TCP/IP printer port to the trace log, and returns an invalid printer monitor error.

The extension continues with port creation by passing the varied instance of the IPv4 address (port name) to the OpenPrinter Windows API using the XcvPort moniker and SERVER_ACCESS_ADMINISTRATOR permissions. A failed result from the API causes the extension to abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the API.

A successful response from the API causes the extension use the AddPort Windows Device Driver TCPMON XcvData API to create the port using the following values:

  1. The varied instance of the IPv4 address (port name)

  2. The DNS host name or IPv4 address (whichever is the value of the <ipAddress> attribute)

  3. The numerical value of the <protocol> attribute

  4. The <portNumber> attribute value

  5. The <doubleSpool> attribute value

  6. The <snmpEnabled> attribute value

  7. The <snmpDevIndex> attribute value

  8. The <lprQueue> attribute value

  9. The <snmpCommunity> attribute value

The extension ignores a printer already existed error, uses the ClosePrinter API, and proceeds with the Create printer phase. All other unsuccessful results returned from the API cause the extension to use the ClosePrinter API, abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the AddPort API. A successful response from the AddPort API causes the extension to use the ClosePrinter API and proceed to the Create Printer phase.

Create printer

The extension determines if it needs to create the printer for the computer or current user by internally referencing if it discovered the printer through either the Detect port and TCP/IP printer phase or the Detect port phase. The extension gracefully exits with an object name exists error if it previously discovered the printer. Otherwise the extension proceeds to the Driver installation phase.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the new TCP/IP printer connection. An unsuccessful response from the Windows API causes the extension to abort its processing, write “Error installing printer driver” to the trace log, and return the underlying error provided by the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install driver, provided the driver is not already installed.

If the extension cannot locate the driver needed for the printer installation on the remote location specified by the <path> attribute value, then it closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns an out of memory error.

All other failed responses from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection and proceed to the Add TCP/IP printer phase.

Add TCP/IP printer

The extension continues processing by creating a new TCP/IP printer connection based on the configuration in the current inner element. Adding a printer begins with the extension acquiring a handle to the remote printer using the <path> attribute value and the OpenPrinter Windows API. A failed response from the API causes the extension to abort its processing, write “Error creating TCP/IP printer connection” to the trace log, and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the GetPrinter API causes the extension to abort its processing, write “Error creating TCP/IP printer settings” to the trace log, and return an unexpected error.

A successful response from the API causes the extension to retrieve additional information about the remote printer. Any errors regarding memory allocation occurring while gather remote printer information causes the extension to abort its processing, write “Error creating TCP/IP printer settings” to the trace log, and return an unexpected error. The additional information the extension retrieves from the remote printer includes the following information: printer name, driver name, server name, share name, printer processor, location, and comments. The extension continues by releasing the printer handle using the ClosePrinter API.

The extension modifies a portion of the supplemental data received from the GetPrinter API. The first of the data modified by the extension is the security descriptor. The extensions changes the security descriptor data returned by the API to a null value. The Windows authorization subsystem interprets a null security descriptor as if every user on the computer has full access to the printer.

The extension continues by ensuring it has previously discovered the port name and printer name. If either of these internal values remain empty, then the extension aborts its processing, writes “Error creating TCP/IP printer connection” to the trace log, and returns an invalid printer name error.

The extension assigns the port name and printer name values to newly created printer and then removes the PRINTER_ATTRIBUTE_SHARED bit from the attributes of the supplemental data previously gathered.

The remaining data modified by the extension include <location>, <comment>, <processor>, and <dataType> values. The extension overwrites the information retrieved from the GetPrinter API with information from the configuration file, when the values in the configuration file are not empty.

The extension references the internal <default> value as it may have modified the attribute value during the Detect default printer override phase to determine if the new TCP/IP printer connection should be the default printer. A <default> attribute value equaling true (one [1]) causes the extension to add the PRINTER_ATTRIBUTE_DEFAULT bit to the attributes of the supplemental data. A false (zero [0]) value causes the extension to remove the PRINTER_ATTRIBUTE_DEFAULT bit from the attributes of the supplemental data.

The extension concludes this phase by passing the supplemental data along with the values of the port name, printer name, <location>, <path>, and <comment> attributes to the AddPrinter Windows API.

The extension ignores an unsuccessful result from the API with a printer already exists error code. Otherwise, all other unsuccessful results from the API cause the extension to abort its processing, write “Error creating TCP/IP printer connection” to the trace log, and return the underlying error it received from the API. A successful result from the API enables the extension to continue processing, and set the default printer.

Epilogue

Set default printer

The extension concludes its processing by configuring the printer as the default printer. The extension has already gracefully exited if it previously discovered the printer during the Detect port and TCP/IP printers or Detect local printers phases. Therefore, the extension processes the default printer phase only when it has not previously discovered the printer (just created the new printer).

The extension references the internal <default> value as it may have modified the attribute value during the Detect default printer override phase to determine if the new TCP/IP printer connection should be the default printer. An internal <default> value equaling false (zero [0]) causes the extension to exit gracefully without reporting an error.

An internal <default> value equaling true (one [1]) causes the extension to change its security context to the local system. Any error occurring when switching security contexts causes the extension to abort its processing, write “Error settings default printer” to the trace log, and return the underlying error it encountered during the security context switch.

The extension sets the default printer by passing the internal printer name value to the SetDefaultPrinter Windows API. An unsuccessful result from the API causes the extension write “Error setting default printer” to the trace log, exit gracefully, and return the underlying error it received from the API. Otherwise, the extension exits gracefully without any error.

Create action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Delete

The delete action represents a configuration where the extension deletes a specific TCP/IP printer connection based on the configuration in the current inner element for the computer or current user or all TCP/IP printer connections for the computer or current user.

Prologue

The extension begins processing portPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <localName>, <ipAddress>, <deleteAll>, <default>, <skipLocal>, <useDNS>, and <lprQueue> attributes.

The extension reads the next set of attributes from the current inner element and assigns each a default value if a value is not present in the inner element. These attributes include

The <snmpCommunity> with a default value “public”

The <protocol> attribute with a default value of “PROTOCOL_RAWTCP_TYPE”

The <port> attribute with a default value of “9100”

The <doubleSpool>, <snmpEnabled>, and <snmpDevIndex> with a default value of “0”

Lastly, the extension reads the <processor> attribute and provides a default value of “winprint”, and the <dataType> attribute with a default value of “RAW”.

Core

Delete all TCP/IP printer connections

The extension beings the core processing by checking the value of the <deleteAll> attribute. A <deleteAll> attribute value equaling false causes the extension to proceed to the Delete a specific TCP/IP printer connection phase.

Inventory local printers

The extension inventories local printers by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API. A successful result from the API causes the extension to cycle through the list of returned local printers to determine which local printers are TCP/IP printer connections.

Identify and delete TCP/IP printer connections

The extensions begins the process of deleting TCP/IP printer connections by integrating through the list of local printers. The extension determines if the current printer’s port name of the list of local printers begins with the string “IP_”.

If the current printer’s port name begins with the string “IP_”, then the extension passes the current printer’s name and PRINTER_ALL_ACCESS to the OpenPrinter Windows API.

An unsuccessful response from the API with an invalid printer name error causes the extension to abort its processing and return an unexpected error. All other unsuccessful response from the API cause the extension to abort its processing, and return the underlying error it received from the API. A successful response from API causes the extension to pass the printer handle received from the OpenPrinter API to the DeletePrinter Windows API.

An unsuccessful response from the API causes the extension to close the printer handle using the ClosePrinter API, abort its processing, and return the underlying error it received from the API. A successful response from the API causes the extension to continue its iteration of printers and subsequent deletion.

The extension continues the cycle through printers until it has examined all printers in the list of printers or it encounters an error attempting to delete a printer. The extension closes the printer handle it received from OpenPrinter API and gracefully exits without an error after successfully examining all printers in the list.

Delete a specific TCP/IP printer connection

The extension needs to delete a specific TCP/IP printer connection rather than all TCP/IP printer connections based on the <deleteAll> attribute value equaling false (zero [0]).

Determine IP address

The extension begins by determining the IP address it uses for the remote printer. It determines this decision based on the <useDNS> attribute value. A <useDNS> attribute value equaling false (zero [0]) causes the extension to use the value of the <ipAddress> attribute as the IPv4 address of the remote printer and proceed with the Check for printer process.

A <useDNS> attribute value equaling true (one [1]) causes the extension to read the fully qualified domain name from the <ipAddress> attribute value and proceed with the Name resolution phase.

Name resolution

The extension begins the name resolution process by using the LoadLibrary Windows API to load the wsock32.dll dynamic linked library into memory. An unsuccessful response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API causes the extension to resolve the name into an IPv4 address.

The extension resolves the name into an IPv4 address by passing the <ipAddress> value, which is a fully qualified domain name of a remote printer, to the GetAddrInfoW Windows API. A failed response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API returns a list of network addresses for the name.

The extension enters a critical section, iterates through the list of address, stores all IPv4 addresses in memory, and exits the critical section. Any errors encountered due to memory allocations causes the extension to abort its processing and return an out of memory error. Otherwise the extension continues by calling the WsaCleanup API and then evaluates the list of return IPv4 addresses.

The extension uses the first IPv4 address in the list of addresses returned from the GetAddrInfoW API. The extension converts the IPv4 address into a dotted, numerical string format and proceeds to the Check for printer phase.

Any error encounter encountered during the name resolution phase causes the extension to write “Error resolving IP address” and the underlying error code to the trace log and proceed to the Check for printer phase.

Check for printer

The extension continues processing by determining if a TCP/IP printer exists for the computer or current user. To do this, the extension prefixes the IPv4 address discovered in the Determine IP address phase with “IP_”. The new variation of the IPv4 address looks like “IP_0.0.0.0”; however, with the IPv4 address of the remote printer.

The extension determines how it searches for an existing TCP/IP printer connection by checking the value of the <localName> attribute. If an attribute value exists, then the extension proceeds to the Matching the printer by name phase. If an attribute value does not exist, then the extension proceeds with the Matching by IPv4 address phase.

Matching by IPv4 address

Detect port and TCP/IP printer

The extension detects an existing TCP/IP Printer connection by port name using the varied instance of the IPv4 address created in the Check for printer process as the matching criterion.

The extension uses the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing, write “Error finding TCP/IP printer…” to the trace log, and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers. With each iteration, the extension verifies the current printer in the list of printers is not a network printer connection by validating the PRINTER_ATTRIBUTE_NETWORK bit is disabled on the current printers attributes. Next, the extension performs a case insensitive comparison of the current printer’s port name with the varied instance of the IPv4 port name.

The extensions encounters a matched TCP/IP printer connection when the current printer is not a shared printer connection and the current printer’s port name matches the varied instance of the IPv4 port name.

A complete cycle through the list of printers without finding a matched printer (port or printer name) causes the extension to proceed with the Get remote printer settings phase.

Upon matching a TCP/IP printer connection (port and printer), the extension saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and proceeds with the Delete TCP/IP printer connection phase.

Matching by name

Detect port

The matching by name phase uses the varied instance of the IPv4 address created in the Check for printer phase and passes it to the OpenPrinter Windows API using the XcvPort and SERVER_ACCESS_ADMINISTRATOR permissions. Any error encountered when attempting to connect to the printer causes the extension to internally report that it could not locate the specified remote port and proceeds with the Detect local printers phase.

A successful response from the API instructs the extension to use the GetConfigInfo API from the Windows Device Driver TCPMON XcvData category of functions. An unsuccessful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it could not locate the specified remote port, and proceed with the Inventory local printers phase. A successful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it located the specified remote port, and proceed with the Detect local printers phase.

Detect local printers

The extension continues by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute. A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to internally report it found a matching printer and to proceed to the Delete TCP/IP printer connection phase.

A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to internally report it did not find a matching printer and to proceed to the Delete TCP/IP printer connection phase.

Delete TCP/IP printer connection

The extension internally references if it successfully discovered the printer during the Check for printer phase. If the extension did not successfully discover the printer at that time, then the extension proceeds to the Get remote printer settings phase.

Successfully discovering the printer during the Check for printer phase causes the extension to pass the current printer’s name and PRINTER_ALL_ACCESS to the OpenPrinter Windows API.

An unsuccessful response from the API with an invalid printer name error causes the extension to abort its processing and return an unexpected error. All other unsuccessful response from the API cause the extension to abort its processing, and return the underlying error it received from the API. A successful response from API causes the extension to pass the printer handle received from the OpenPrinter API to the DeletePrinter Windows API.

An unsuccessful response from the API causes the extension to close the printer handle using the ClosePrinter API, abort its processing, and return the underlying error it received from the API. A successful response from the API causes the extension to proceed to the Get remote printer settings phase.

Epilogue

Get remote printer settings

The extension begins this phase by evaluating the <localName> attribute value. The extension uses this value to determine if it needs retrieve the printer name for the remote printer. The extension already has the printer name if it matched the printer by name. In this scenario, the extension proceeds to the Detect default printer override phase.

The extension needs to retrieve the printer name if it matched the printer by IPv4 address. The extension gets this information by passing the <path> attribute value to the OpenPrinter Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “Error getting TCP/IP printer settings …” to the trace log, and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the GetPrinter API causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error.

Any errors regarding memory allocation occurring while gather remote printer information causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error. A successful response from the API causes the extension to retrieve additional information about the remote printer. The additional information retrieved from the remote printer includes: printer name, driver name, server name, share name, printer processor, location, and comments.

Upon successfully retrieving the remote printer information, the extension closes the connection to the remote printer using the ClosePrinter API, saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and gracefully exits without reporting an error.

Delete action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Replace

The replace action represents a configuration where the extension replaces an existing TCP/IP printer connection with a newly created TCP/IP printer connection based on the configuration in the current inner element.

It is important to understand the differences between replace and update. The replace action typically deletes an existing TCP/IP printer connection and creates a new one—essentially changing all configuration elements of the printer connection. The update action only updates a portion of the configuration elements for an existing TCP/IP printer connection.

Prologue

The extension begins processing portPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <localName>, <ipAddress>, <deleteAll>, <default>, <skipLocal>, <useDNS>, and <lprQueue> attributes.

The extension reads the next set of attributes from the current inner element and assigns each a default value if a value is not present in the inner element. These attributes include

The <snmpCommunity> with a default value “public”

The <protocol> attribute with a default value of “PROTOCOL_RAWTCP_TYPE”

The <port> attribute with a default value of “9100”

The <doubleSpool>, <snmpEnabled>, and <snmpDevIndex> with a default value of “0”

Lastly, the extension reads the <processor> attribute and provides a default value of “winprint”, and the <dataType> attribute with a default value of “RAW”.

Core

Delete a specific TCP/IP printer connection

The extension needs to delete a specific TCP/IP printer connection based on the <deleteAll> attribute value equaling false (zero [0]).

Determine IP address

The extension begins by determining the IP address it uses for the remote printer. It determines this decision based on the <useDNS> attribute value. A <useDNS> attribute value equaling false (zero [0]) causes the extension to use the value of the <ipAddress> attribute as the IPv4 address of the remote printer and proceed with the Check for printer process.

A <useDNS> attribute value equaling true (one [1]) causes the extension to read the fully qualified domain name from the <ipAddress> attribute value and proceed with the Name resolution phase.

Name resolution

The extension begins the name resolution process by using the LoadLibrary Windows API to load the wsock32.dll dynamic linked library into memory. An unsuccessful response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API causes the extension to resolve the name into an IPv4 address.

The extension resolves the name into an IPv4 address by passing the <ipAddress> value, which is a fully qualified domain name of a remote printer, to the GetAddrInfoW Windows API. A failed response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API returns a list of network addresses for the name.

The extension enters a critical section, iterates through the list of address, stores all IPv4 addresses in memory, and exits the critical section. Any errors encountered due to memory allocations causes the extension to abort its processing and return an out of memory error. Otherwise the extension continues by calling the WsaCleanup API and then evaluates the list of return IPv4 addresses.

The extension uses the first IPv4 address in the list of addresses returned from the GetAddrInfoW API. The extension converts the IPv4 address into a dotted, numerical string format and proceeds to the Check for printer phase.

Any error encounter encountered during the name resolution phase causes the extension to write “Error resolving IP address” and the underlying error code to the trace log and proceed to the Check for printer phase.

Check for printer

The extension continues processing by determining if a TCP/IP printer exists for the computer or current user. To do this, the extension prefixes the IPv4 address discovered in the Determine IP address phase with “IP_”. The new variation of the IPv4 address looks like “IP_0.0.0.0”; however, with the IPv4 address of the remote printer.

The extension determines how it searches for an existing TCP/IP printer connection by checking the value of the <localName> attribute. If an attribute value exists, then the extension proceeds to the Matching the printer by name phase. If an attribute value does not exist, then the extension proceeds with the Matching by IPv4 address phase.

Matching by IPv4 address

Detect port and TCP/IP printer

The extension detects an existing TCP/IP Printer connection by port name using the varied instance of the IPv4 address created in the Check for printer process as the matching criterion.

The extension uses the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing, write “Error finding TCP/IP printer…” to the trace log, and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers. With each iteration, the extension verifies the current printer in the list of printers is not a network printer connection by validating the PRINTER_ATTRIBUTE_NETWORK bit is disabled on the current printers attributes. Next, the extension performs a case insensitive comparison of the current printer’s port name with the varied instance of the IPv4 port name.

The extensions encounters a matched TCP/IP printer connection when the current printer is not a shared printer connection and the current printer’s port name matches the varied instance of the IPv4 port name.

A complete cycle through the list of printers without finding a matched printer (port or printer name) causes the extension to proceed with the Get remote printer settings phase.

Upon matching a TCP/IP printer connection (port and printer), the extension saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and proceeds with the Delete TCP/IP printer connection phase.

Matching by name

Detect port

The matching by name phase uses the varied instance of the IPv4 address created in the Check for printer phase and passes it to the OpenPrinter Windows API using the XcvPort and SERVER_ACCESS_ADMINISTRATOR permissions. Any error encountered when attempting to connect to the printer causes the extension to internally report that it could not locate the specified remote port and proceeds with the Detect local printers phase.

A successful response from the API instructs the extension to use the GetConfigInfo API from the Windows Device Driver TCPMON XcvData category of functions. An unsuccessful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it could not locate the specified remote port, and proceed with the Inventory local printers phase. A successful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it located the specified remote port, and proceed with the Detect local printers phase.

Detect local printers

The extension continues by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute. A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to internally report it found a matching printer and to proceed to the Delete TCP/IP printer connection phase.

A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to internally report it did not find a matching printer and to proceed to the Delete TCP/IP printer connection phase.

Delete TCP/IP printer connection

The extension internally references if it successfully discovered the printer during the Check for printer phase. If the extension did not successfully discover the printer at that time, then the extension proceeds to the Get remote printer settings phase.

Successfully discovering the printer during the Check for printer phase causes the extension to pass the current printer’s name and PRINTER_ALL_ACCESS to the OpenPrinter Windows API.

An unsuccessful response from the API with an invalid printer name error causes the extension to abort its processing and return an unexpected error. All other unsuccessful response from the API cause the extension to abort its processing, and return the underlying error it received from the API. A successful response from API causes the extension to pass the printer handle received from the OpenPrinter API to the DeletePrinter Windows API.

An unsuccessful response from the API causes the extension to close the printer handle using the ClosePrinter API, abort its processing, and return the underlying error it received from the API. A successful response from the API causes the extension to proceed to the Get remote printer settings phase.

Get remote printer settings

The extension begins this phase by evaluating the <localName> attribute value. The extension uses this value to determine if it needs retrieve the printer name for the remote printer. The extension already has the printer name if it matched the printer by name. In this scenario, the extension proceeds to the Detect default printer override phase.

The extension needs to retrieve the printer name if it matched the printer by IPv4 address. The extension gets this information by passing the <path> attribute value to the OpenPrinter Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “Error getting TCP/IP printer settings …” to the trace log, and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the GetPrinter API causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error.

Any errors regarding memory allocation occurring while gather remote printer information causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error. A successful response from the API causes the extension to retrieve additional information about the remote printer. The additional information retrieved from the remote printer includes: printer name, driver name, server name, share name, printer processor, location, and comments.

Upon successfully retrieving the remote printer information, the extension closes the connection to the remote printer using the ClosePrinter API, saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and proceeds with the Detect default printer override phase.

Detect default printer override

The extension detects the default printer override option by validating both the <default> and <skipLocal> attribute values equal true (one [1]). If either attribute equals false, the extension proceeds to the Create port phase.

When both attributes equal true, the extension continues processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing, write “Error finding local printers”, and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs multiple evaluations. The extension first validates that the current printer from the list of local printers is not a network connected printer by determining if the PRINTER_ATTRIBUTE_NETWORK bit is enabled in the current printers attributes. If the current printer is a network printer, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. If the current printer is not a network printer, then the extension proceeds with validating the printer name.

The second evaluation performed on the current printer is to guarantee the current printer does not match the previously discovered printer name. If the current printer name matches the previously discovered printer name, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. Otherwise, the current printer name and the previously discovered printer name do not match and the extension continues with its final evaluation.

The final evaluation performed by the extension is to determine if the current printer port is configured with a local port. The extension checks if the port name of the current printer from the list of local printers contains “LPT”, “COM”, or “USB” in the name. If the current printer’s port name does not contain these strings, then the extension cycles to the next printer in the list of local printers.

If the extensions iterates through all the printers and does not discover a printer in the list of local printers that passes these evaluations, then it internally reports that a local printer is not present. If the extension identifies a printer from the list of local printers passing all three evaluations, then it will cease the iteration and internally report a local printer exists.

A local printer not existing for the computer or current user with both the <default> and <skipLocal> attributes equaling true causes the extension to proceed to the Create port phase.

A local printer existing for the computer or current user with both the <default>< and <skipLocal> attributes equaling true causes the extension to internally change the <default> attribute to equal false (zero [0]) and proceed to the Create port phase.

Create port

The extension determines if it needs to create the port for the computer or current user by internally referencing if it discovered the port through either the Detect port and TCP/IP printer phase or the Detect port phase. The extension proceeds to the Create printer phase if it successfully discovered the port.

Before creating the port, the extension ensures the computer has the necessary components installed to create a TCP/IP printer port. The extension accomplishes this using the EnumMonitors Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the API.

A successful result from the API also returns a list of print monitors available on the computer. The extension iterates through the list of print monitors until it locates a monitor name that matches the string “Standard TCP/IP Port”. If the extension does not discover the Standard TCP/IP Port monitor, then the extension aborts its processing, writes “Error adding TCP/IP printer port to the trace log, and returns an invalid printer monitor error.

The extension continues with port creation by passing the varied instance of the IPv4 address (port name) to the OpenPrinter Windows API using the XcvPort moniker and SERVER_ACCESS_ADMINISTRATOR permissions. A failed result from the API causes the extension to abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the API.

A successful response from the API causes the extension use the AddPort Windows Device Driver TCPMON XcvData API to create the the port using the following values:

  1. The varied instance of the IPv4 address (port name)

  2. The DNS host name or IPv4 address (whichever is the value of the <ipAddress> attribute)

  3. The numerical value of the <protocol> attribute

  4. The <portNumber> attribute value

  5. The <doubleSpool> attribute value

  6. The <snmpEnabled> attribute value

  7. The <snmpDevIndex> attribute value

  8. The <lprQueue> attribute value

  9. The <snmpCommunity> attribute value

The extension ignores a printer already existed error, uses the ClosePrinter API, and proceeds with the Create printer phase. All other unsuccessful results returned from the API cause the extension to use the ClosePrinter API, abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the AddPort API. A successful response from the AddPort API causes the extension to use the ClosePrinter API and proceed to the Create Printer phase.

Create printer

The extension determines if it needs to create the printer for the computer or current user by internally referencing if it discovered the printer through either the Detect port and TCP/IP printer phase or the Detect port phase. The extension gracefully exits with an object name exists error if it previously discovered the printer. Otherwise the extension proceeds to the Driver installation phase.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the new TCP/IP printer connection. An unsuccessful response from the Windows API causes the extension to abort its processing, write “Error installing printer driver” to the trace log, and return the underlying error provided by the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install driver, provided the driver is not already installed.

If the extension cannot locate the driver needed for the printer installation on the remote location specified by the <path> attribute value, then it closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns an out of memory error.

All other failed responses from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection and proceed to the Add TCP/IP printer phase.

Add TCP/IP printer

The extension continues processing by creating a new TCP/IP printer connection based on the configuration in the current inner element. Adding a printer begins with the extension acquiring a handle to the remote printer using the <path> attribute value and the OpenPrinter Windows API. A failed response from the API causes the extension to abort its processing, write “Error creating TCP/IP printer connection” to the trace log, and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the GetPrinter API causes the extension to abort its processing, write “Error creating TCP/IP printer settings” to the trace log, and return an unexpected error.

A successful response from the API causes the extension to retrieve additional information about the remote printer. Any errors regarding memory allocation occurring while gather remote printer information causes the extension to abort its processing, write “Error creating TCP/IP printer settings” to the trace log, and return an unexpected error. The additional information the extension retrieves from the remote printer includes the following information: printer name, driver name, server name, share name, printer processor, location, and comments. The extension continues by releasing the printer handle using the ClosePrinter API.

The extension modifies a portion of the supplemental data received from the GetPrinter API. The first of the data modified by the extension is the security descriptor. The extensions changes the security descriptor data returned by the API to a null value. The Windows authorization subsystem interprets a null security descriptor as if every user on the computer has full access to the printer.

The extension continues by ensuring it has previously discovered the port name and printer name. If either of these internal values remain empty, then the extension aborts its processing, writes “Error creating TCP/IP printer connection” to the trace log, and returns an invalid printer name error.

The extension assigns the port name and printer name values to newly created printer and then removes the PRINTER_ATTRIBUTE_SHARED bit from the attributes of the supplemental data previously gathered.

The remaining data modified by the extension include <location>, <comment>, <processor>, and <dataType> values. The extension overwrites the information retrieved from the GetPrinter API with information from the configuration file, when the values in the configuration file are not empty.

The extension references the internal <default> value as it may have modified the attribute value during the Detect default printer override phase to determine if the new TCP/IP printer connection should be the default printer. A <default> attribute value equaling true (one [1]) causes the extension to add the PRINTER_ATTRIBUTE_DEFAULT bit to the attributes of the supplemental data. A false (zero [0]) value causes the extension to remove the PRINTER_ATTRIBUTE_DEFAULT bit from the attributes of the supplemental data.

The extension concludes this phase by passing the supplemental data along with the values of the port name, printer name, <location>, <path>, and <comment> attributes to the AddPrinter Windows API.

The extension ignores an unsuccessful result from the API with a printer already exists error code. Otherwise, all other unsuccessful results from the API cause the extension to abort its processing, write “Error creating TCP/IP printer connection” to the trace log, and return the underlying error it received from the API. A successful result from the API enables the extension to continue processing, and set the default printer.

Epilogue

Set default printer

The extension concludes its processing by configuring the printer as the default printer. The extension has already gracefully exited if it previously discovered the printer during the Detect port and TCP/IP printers or Detect local printers phases. Therefore, the extension processes the default printer phase only when it has not previously discovered the printer (just created the new printer).

The extension references the internal <default> value as it may have modified the attribute value during the Detect default printer override phase to determine if the new TCP/IP printer connection should be the default printer. An internal <default> value equaling false (zero [0]) causes the extension to exit gracefully without reporting an error.

An internal <default> value equaling true (one [1]) causes the extension to change its security context to the local system. Any error occurring when switching security contexts causes the extension to abort its processing, write “Error settings default printer” to the trace log, and return the underlying error it encountered during the security context switch.

The extension sets the default printer by passing the internal printer name value to the SetDefaultPrinter Windows API. An unsuccessful result from the API causes the extension write “Error setting default printer” to the trace log, exit gracefully, and return the underlying error it received from the API. Otherwise, the extension exits gracefully without any error.

Update

The update action represents a configuration where the extension refreshes an existing TCP/IP printer connection based on the configuration in the current inner element. It is important to understand the difference between replace and update.

The replace action typically deletes the existing TCP/IP printer connection and creates a new one—essentially changing all configurations elements of the local printer. The update action only updates a portion of configuration elements in an existing TCP/IP printer connection.

Prologue

The extension begins processing portPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <localName>, <ipAddress>, <deleteAll>, <default>, <skipLocal>, <useDNS>, and <lprQueue> attributes.

The extension reads the next set of attributes from the current inner element and assigns each a default value if a value is not present in the inner element. These attributes include

The <snmpCommunity> with a default value “public”

The <protocol> attribute with a default value of “PROTOCOL_RAWTCP_TYPE”

The <port> attribute with a default value of “9100”

The <doubleSpool>, <snmpEnabled>, and <snmpDevIndex> with a default value of “0”

Lastly, the extension reads the <processor> attribute and provides a default value of “winprint”, and the <dataType> attribute with a default value of “RAW”.

Core

Determine IP address

The extension begins by determining the IP address it uses for the remote printer. It determines this decision based on the <useDNS> attribute value. A <useDNS> attribute value equaling false (zero [0]) causes the extension to use the value of the <ipAddress> attribute as the IPv4 address of the remote printer and proceed with the Check for printer process.

A <useDNS> attribute value equaling true (one [1]) causes the extension to read the fully qualified domain name from the <ipAddress> attribute value and proceed with the Name resolution phase.

Name resolution

The extension begins the name resolution process by using the LoadLibrary Windows API to load the wsock32.dll dynamic linked library into memory. An unsuccessful response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API causes the extension to resolve the name into an IPv4 address.

The extension resolves the name into an IPv4 address by passing the <ipAddress> value, which is a fully qualified domain name of a remote printer, to the GetAddrInfoW Windows API. A failed response from the API causes the extension to abort its processing and return the underlying error it received from the API. A successful response from the API returns a list of network addresses for the name.

The extension enters a critical section, iterates through the list of address, stores all IPv4 addresses in memory, and exits the critical section. Any errors encountered due to memory allocations causes the extension to abort its processing and return an out of memory error. Otherwise the extension continues by calling the WsaCleanup API and then evaluates the list of return IPv4 addresses.

The extension uses the first IPv4 address in the list of addresses returned from the GetAddrInfoW API. The extension converts the IPv4 address into a dotted, numerical string format and proceeds to the Check for printer process.

Any error encounter encountered during the name resolution phase causes the extension to write “Error resolving IP address” and the underlying error code to the trace log and proceed to the Check for printer phase.

Check for printer

The extension continues processing by determining if a TCP/IP printer exists for the computer or current user. To do this, the extension prefixes the IPv4 address discovered in the Determine IP address phase with “IP_”. The new variation of the IPv4 address looks like “IP_0.0.0.0”; however, with the IPv4 address of the remote printer.

The extension determines how it searches for an existing TCP/IP printer connection by checking the value of the <localName> attribute. If an attribute value exists, then the extension proceeds to the Matching the printer by name phase. If an attribute value does not exist, then the extension proceeds with the Matching by IPv4 address phase.

Matching by IPv4 address

Detect port and TCP/IP printer

The extension detects an existing TCP/IP Printer connection by port name using the varied instance of the IPv4 address created in the Check for printer process as the matching criterion.

The extension uses the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing, write “Error finding TCP/IP printer…” to the trace log, and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers. With each iteration, the extension verifies the current printer in the list of printers is not a network printer connection by validating the PRINTER_ATTRIBUTE_NETWORK bit is disabled on the current printers attributes. Next, the extension performs a case insensitive comparison of the current printer’s port name with the varied instance of the IPv4 port name.

The extensions encounters a matched TCP/IP printer connection when the current printer is not a shared printer connection and the current printer’s port name matches the varied instance of the IPv4 port name.

A complete cycle through the list of printers without finding a matched printer (port or printer name) causes the extension to proceed with the Get remote printer settings phase.

Upon matching a TCP/IP printer connection (port and printer), the extension saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and proceeds with the Get remote printer settings phase.

Matching by name

Detect port

The matching by name phase uses the varied instance of the IPv4 address created in the Check for printer phase and passes it to the OpenPrinter Windows API using the XcvPort and SERVER_ACCESS_ADMINISTRATOR permissions. Any error encountered when attempting to connect to the printer causes the extension to internally report that it could not locate the specified remote port and proceeds with the Detect local printers phase.

A successful response from the API instructs the extension to use the GetConfigInfo API from the Windows Device Driver TCPMON XcvData category of functions. An unsuccessful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it could not locate the specified remote port, and proceed with the Inventory local printers phase. A successful response from the API causes the extension to close the connection to the remote printer using the ClosePrinter API, internally report that it located the specified remote port, and proceed with the Detect local printers phase.

Detect local printers

The extension continues by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs a case insensitive comparison of the current printer’s name with the value of the <name> attribute. A computer or current user with a local printer name matching the value of the <name> attribute causes the extension to internally report it found a matching printer and to proceed to the Get remote printer settings phase.

A computer or current user without a local printer name matching the value of the <name> attribute causes the extension to internally report it did not find a matching printer and to proceed to the Get remote printer settings phase.

Get remote printer settings

The extension begins this phase by evaluating the <localName> attribute value. The extension uses this value to determine if it needs retrieve the printer name for the remote printer. The extension already has the printer name if it matched the printer by name. In this scenario, the extension proceeds to the Detect default printer override phase.

The extension needs to retrieve the printer name if it matched the printer by IPv4 address. The extension gets this information by passing the <path> attribute value to the OpenPrinter Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “Error getting TCP/IP printer settings …” to the trace log, and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the GetPrinter API causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error.

Any errors regarding memory allocation occurring while gather remote printer information causes the extension to abort its processing, write “Error getting TCP/IP printer settings” to the trace log, and return an unexpected error. A successful response from the API causes the extension to retrieve additional information about the remote printer. The additional information retrieved from the remote printer includes: printer name, driver name, server name, share name, printer processor, location, and comments.

Upon successfully retrieving the remote printer information, the extension closes the connection to the remote printer using the ClosePrinter API, saves the printer name to memory, alters a copy of the printer name by removing any indication of a UNC path from the name—if any—leaving just the printer name, and proceeds with the Detect default printer override phase.

Detect default printer override

The extension detects the default printer override option by validating both the <default> and <skipLocal> attribute values equal true (one [1]). If either attribute equals false, the extension proceeds to the Create port phase.

When both attributes equal true, the extension continues processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to abort its processing, write “Error finding local printers”, and return the underlying error received from the Windows API.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs multiple evaluations. The extension first validates that the current printer from the list of local printers is not a network connected printer by determining if the PRINTER_ATTRIBUTE_NETWORK bit is enabled in the current printers attributes. If the current printer is a network printer, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. If the current printer is not a network printer, then the extension proceeds with validating the printer name.

The second evaluation performed on the current printer is to guarantee the current printer does not match the previously discovered printer name. If the current printer name matches the previously discovered printer name, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. Otherwise, the current printer name and the previously discovered printer name do not match and the extension continues with its final evaluation.

The final evaluation performed by the extension is to determine if the current printer port is configured with a local port. The extension checks if the port name of the current printer from the list of local printers contains “LPT”, “COM”, or “USB” in the name. If the current printer’s port name does not contain these strings, then the extension cycles to the next printer in the list of local printers.

If the extensions iterates through all the printers and does not discover a printer in the list of local printers that passes these evaluations, then it internally reports that a local printer is not present. If the extension identifies a printer from the list of local printers passing all three evaluations, then it will cease the iteration and internally report a local printer exists.

A local printer not existing for the computer or current user with both the <default> and <skipLocal> attributes equaling true causes the extension to proceed to the Create/Update port phase.

A local printer existing for the computer or current user with both the <default>< and <skipLocal> attributes equaling true causes the extension to internally change the <default> attribute to equal false (zero [0]) and proceed to the Create port phase.

Create/Update port

Before creating the port, the extension ensures the computer has the necessary components installed to create a TCP/IP printer port. The extension accomplishes this using the EnumMonitors Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the API.

A successful result from the API also returns a list of print monitors available on the computer. The extension iterates through the list of print monitors until it locates a monitor name that matches the string “Standard TCP/IP Port”. If the extension does not discover the Standard TCP/IP Port monitor and the extension aborts its processing. If the extension did not previously discover the port, then it writes “Error adding TCP/IP printer port” to the trace log. The extension writes “Error configuring TCP/IP printer port” to the trace log if it did not previously discover the port. Regardless of port discovery status, the extension returns an invalid printer monitor error.

If the extension did not previously discover the port, then it proceeds with the Create port sub-phase. Otherwise, the extension proceeds with the Update port sub-phase.

Create port

The extension continues with port creation by passing the varied instance of the IPv4 address (port name) to the OpenPrinter Windows API using the XcvPort moniker and SERVER_ACCESS_ADMINISTRATOR permissions. A failed result from the API causes the extension to abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the API.

A successful response from the API causes the extension use the AddPort Windows Device Driver TCPMON XcvData API to create the port using the following values:

  1. The varied instance of the IPv4 address (port name)

  2. The DNS host name or IPv4 address (whichever is the value of the <ipAddress> attribute)

  3. The numerical value of the <protocol> attribute

  4. The <portNumber> attribute value

  5. The <doubleSpool> attribute value

  6. The <snmpEnabled> attribute value

  7. The <snmpDevIndex> attribute value

  8. The <lprQueue> attribute value

  9. The <snmpCommunity> attribute value

The extension ignores a printer already existed error, uses the ClosePrinter API, and proceeds with the Create printer phase. All other unsuccessful results returned from the API cause the extension to use the ClosePrinter API, abort its processing, write “Error adding TCP/IP printer port” to the trace log, and return the underlying error it received from the AddPort API. A successful response from the AddPort API causes the extension to use the ClosePrinter API and proceed to the Create Printer phase.

Update port

The extension continues with updating the port by passing the varied instance of the IPv4 address (port name) to the OpenPrinter Windows API using the XcvPort moniker and SERVER_ACCESS_ADMINISTRATOR permissions. A failed result from the API causes the extension to abort its processing, write “Error configuring TCP/IP printer port” to the trace log, and return the underlying error it received from the API.

A successful response from the API causes the extension use the ConfigurePort Windows Device Driver TCPMON XcvData API to configure the port using the following values:

  1. The varied instance of the IPv4 address (port name)

  2. The DNS host name or IPv4 address (whichever is the value of the <ipAddress> attribute)

  3. The numerical value of the <protocol> attribute

  4. The <portNumber> attribute value

  5. The <doubleSpool> attribute value

  6. The <snmpEnabled> attribute value

  7. The <snmpDevIndex> attribute value

  8. The <lprQueue> attribute value

  9. The <snmpCommunity> attribute value

The extension ignores a printer already existed error, uses the ClosePrinter API, and proceeds with the Create printer phase. All other unsuccessful results returned from the API cause the extension to use the ClosePrinter API, abort its processing, write “Error configuring TCP/IP printer port” to the trace log, and return the underlying error it received from the ConfigurePort API. A successful response from the ConfigurePort API causes the extension to use the ClosePrinter API and proceed to the Create Printer phase.

Create printer

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the new TCP/IP printer connection. An unsuccessful response from the Windows API causes the extension to abort its processing, write “Error installing printer driver” to the trace log, and return the underlying error provided by the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install driver, provided the driver is not already installed.

If the extension cannot locate the driver needed for the printer installation on the remote location specified by the <path> attribute value, then it closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns an out of memory error.

All other failed responses from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “Error installing printer driver” to the trace log, and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection and proceed to the Add TCP/IP printer phase.

Add TCP/IP printer

The extension continues processing by creating a new TCP/IP printer connection based on the configuration in the current inner element. Adding a printer begins with the extension acquiring a handle to the remote printer using the <path> attribute value and the OpenPrinter Windows API. A failed response from the API causes the extension to abort its processing, write “Error creating TCP/IP printer connection” to the trace log, and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the GetPrinter API causes the extension to abort its processing, write “Error creating TCP/IP printer settings” to the trace log, and return an unexpected error.

A successful response from the API causes the extension to retrieve additional information about the remote printer. Any errors regarding memory allocation occurring while gather remote printer information causes the extension to abort its processing, write “Error creating TCP/IP printer settings” to the trace log, and return an unexpected error. The additional information the extension retrieves from the remote printer includes the following information: printer name, driver name, server name, share name, printer processor, location, and comments. The extension continues by releasing the printer handle using the ClosePrinter API.

The extension modifies a portion of the supplemental data received from the GetPrinter API. The first of the data modified by the extension is the security descriptor. The extensions changes the security descriptor data returned by the API to a null value. The Windows authorization subsystem interprets a null security descriptor as if every user on the computer has full access to the printer.

The extension continues by ensuring it has previously discovered the port name and printer name. If either of these internal values remain empty, then the extension aborts its processing, writes “Error creating TCP/IP printer connection” to the trace log, and returns an invalid printer name error.

The extension assigns the port name and printer name values to newly created printer and then removes the PRINTER_ATTRIBUTE_SHARED bit from the attributes of the supplemental data previously gathered.

The remaining data modified by the extension include <location>, <comment>, <processor>, and <dataType> values. The extension overwrites the information retrieved from the GetPrinter API with information from the configuration file, when the values in the configuration file are not empty.

The extension references the internal <default> value as it may have modified the attribute value during the Detect default printer override phase to determine if the new TCP/IP printer connection should be the default printer. A <default> attribute value equaling true (one [1]) causes the extension to add the PRINTER_ATTRIBUTE_DEFAULT bit to the attributes of the supplemental data. A false (zero [0]) value causes the extension to remove the PRINTER_ATTRIBUTE_DEFAULT bit from the attributes of the supplemental data.

The extension concludes this phase by passing the supplemental data along with the values of the port name, printer name, <location>, <path>, and <comment> attributes to the AddPrinter Windows API.

The extension ignores an unsuccessful result from the API with a printer already exists error code. Otherwise, all other unsuccessful results from the API cause the extension to abort its processing, write “Error creating TCP/IP printer connection” to the trace log, and return the underlying error it received from the API. A successful result from the API enables the extension to continue processing, and set the default printer.

Epilogue

Set default printer

The extension concludes its processing by configuring the printer as the default printer. The extension has already gracefully exited if it previously discovered the printer during the Detect port and TCP/IP printers or Detect local printers phases. Therefore, the extension processes the default printer phase only when it has not previously discovered the printer (just created the new printer).

The extension references the internal <default> value as it may have modified the attribute value during the Detect default printer override phase to determine if the new TCP/IP printer connection should be the default printer. An internal <default> value equaling false (zero [0]) causes the extension to exit gracefully without reporting an error.

An internal <default> value equaling true (one [1]) causes the extension to change its security context to the local system. Any error occurring when switching security contexts causes the extension to abort its processing, write “Error settings default printer” to the trace log, and return the underlying error it encountered during the security context switch.

The extension sets the default printer by passing the internal printer name value to the SetDefaultPrinter Windows API. An unsuccessful result from the API causes the extension write “Error setting default printer” to the trace log, exit gracefully, and return the underlying error it received from the API. Otherwise, the extension exits gracefully without any error.

Update action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Shared Printer

Create

The create action represents a configuration where the extension creates a local printer based on the configuration in the current inner element.

Prologue

The extension begins processing SharedPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <port>, <username>, and <cPassword> attributes from the current inner element.

The extension reads the next set of attributes from the current inner element and assign each attribute a default value of false (zero [0]) if a value is not present in the inner element. These attributes include <deleteAll>, <default>, <skipLocal>, <persistent>, and <deleteMaps>.

If the <cPassword> attribute contains a value, then the extension reverse-obfuscates the password into its clear text equivalent. The extensions prepares for the core processing phase by setting the security context to the computer or current user (depending how the preference item is deployed).

Core

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension indicate a matching printer does not exists and proceeds with the Detect default printer override phase.

A successful result from the API causes the extension to cycle through the list of returned local printers. The extension begins the cycle with the current printer and determines if the printer is a network printer by the PRINTER_ATTRIBUTE_NETWORK bit in the current printer’s attributes. If the PRINTER_ATTRIBUTE_NETWORK bit is not enabled, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the PRINTER_ATTRIBUTE_NETWORK bit is disabled, then the extension attempts to discover a matching printer.

Match printer by share name

The extension detects a matched printer when it identifies a local printer sharing the same share name as the <path> attribute value. To begin, the extension uses the GetComputerName Windows API to retrieve and store the computers name. The extension begins a series of comparisons starting with the current printer’ server name.

If the current printer’s server name is empty, then the extension creates a temporary path value represented as UNC path using the recently discover computer name for the server portion and the current printer’s share name value as the share portion (\\computerName\printerShareName). Additionally, the extension creates a temporay name value represented as a UNC path using the recently discovered computer name for the server portion and the current printer’s name as the share portion (\\computerName\printerName).

If the current printer’s server name contains a value, then the extension creates a temporary path value represented as a UNC path using the current printer’s server name as the server portion and the current printer’s share name as the share portion (\\currentPrinterServerName\currentPrinterShareName). Additionally, the extension creates a temporary name value and assigns the current printer’s name to the temporary value.

The extension determines if the current printer matches the printer specified in the inner element configuration by comparing the temporary path value to the current printer’s path value, comparing the temporary name value to the current printer’s path value, and comparing the current printer’s port name to the current printer’s path value.

If none of these comparisons indicate a successful match, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the extension completes the iteration of printers without finding a matching printer, then the extension indicates a matching printer does not exist and proceeds to the Detect default printer override phase.

If at least one of the comparisons indicates a successful match, then the extension stops iterating through the list of printers and indicates a matching printer exists. The extension writes “FindSharedPrinterEx: “ and the <path> attribute value to the trace log, and proceeds to the Detect default printer override phase.

Detect default printer override

The extension detects the default printer override option by validating both the <default> and <skipLocal> attribute values equal true (one [1]). If either attribute equals false, the extension proceeds to the Create printer phase.

When both attributes equal true, the extension continues processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to proceed to the Create printer phase.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs multiple evaluations. The extension first validates the current printer from the list of local printers is not a network connected printer by determining if the PRINTER_ATTRIBUTE_NETWORK bit is enabled in the current printers attributes. If the current printer is a network printer, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. If the current printer is not a network printer, then the extension proceeds with validating the printer name.

The second evaluation performed on the current printer is to guarantee the current printer does not match the previously discovered printer name. If the current printer name matches the previously discovered printer name, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. Otherwise, the current printer name and the previously discovered printer name do not match and the extension continues with its final evaluation.

The final evaluation performed by the extension is to determine if the current printer port is configured with a local port. The extension checks if the port name of the current printer from the list of local printers contains “LPT”, “COM”, or “USB” in the name. If the current printer’s port name does not contain these strings, then the extension cycles to the next printer in the list of local printers.

If the extensions iterates through all the printers and does not discover a printer in the list of local printers that passes these evaluations, then it internally reports that a local printer is not present. If the extension identifies a printer from the list of local printers passing all three evaluations, then it will cease the iteration and internally report a local printer exists.

A local printer not existing for the computer or current user with both the <default> and <skipLocal> attributes equaling true causes the extension to proceed to write “IsOtherLocalPrinterEx” and the last observed error code to the trace log and proceed to the Create printer phase.

A local printer existing for the computer or current user with both the <default>< and <skipLocal> attributes equaling true causes the extension to internally change the <default> attribute to equal false (zero [0]), write “IsOtherLocalPrinterEx” and the last observed error code to the trace log and proceed to the Create printer phase.

Create printer

The extension internally references if it previously detected a local printer. If the extension discovered a printer existed, then the extension exits gracefully with an object name exists error. If the extension did not discover a printer during the Match printer by share name phase, then it proceeds with the Driver installation phase.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the newly created local printer. An unsuccessful response from the Windows API causes the extension to abort its processing, write “InstallDriversEx:” and the <path> attribute value to the trace log, and return the underlying error it received from the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install the driver, provided the driver is not already installed.

If the driver needed for the printer installation is not located on the remote location specified by the <path> attribute value, then the extension closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “InstallDriversEx:” and the <path> attribute value to the trace log, and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing, writes “InstallDriversEx: “and the <path> attribute value to the trace log, and returns an out of memory error.

A failed response from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “InstallDriversEx: “and the <path> attribute value to the trace log, and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection, write “InstallDriversEx: “and the <path> attribute value to the trace log, and proceed with the Add shared printer phase.

Add shared printer

The extension adds the shared printer to the computer or current user by passing the <path> attribute value to the AddPrinterConnection Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “AddSharedPrinterEx: “and the <path> attribute value to the trace log, and return the underlying error code I received from the API.

A successful response from the API causes the extension write “AddSharedPrinterEx: “and the <path> attribute value to the trace log, and proceed to the Set default printer phase.

Set default printer

To set the default printer, the extension internally references if it previously discovered an existing printer. If the extension previously discovered a printer, then the extension proceeds to the Map printer port phase. If the extension did not previously discover a printer, then it checks the internal <default> attribute to determine if it was modified during the Detect default printer override phase.

If the extension determined the internal <default> attribute value equals false (zero [0]), then it proceeds to the map printer port phase. If the extension determines the internal <default> attribute value equals true (one [1]), then it passes the <path> attribute value to the SetDefaultPrinter Windows API.

An unsuccessful response from the API causes the extension to abort its processing, write “SetDefaultPrinterEx: “and the <path> attribute value to the trace log, and return the underlying error provided by the API. A successful response from the API causes the extension to abort its processing, write “SetDefaultPrinterEx: “and the <path> attribute value to the trace log, and proceed to the Map printer port phase.

Map printer port

The extension begins by verifying that the <port> attribute value is not empty. If the <port> attribute value is empty, then the extension proceeds to the Epilogue phase. Otherwise, the extension proceeds with the Get remote printer settings phase.

Get remote printer settings

The extension begins this phase by retrieving information about the remote printer. The extension gets this information by passing the <path> attribute value to the OpenPrinter Windows API. An unsuccessful response from the API causes the extension to abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the API causes the extension to close the printer handle using the ClosePrinter API; abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return an unexpected error.

Any errors regarding memory allocation occurring while gather remote printer information causes the extension to close the printer handle using the ClosePrinter API; abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return an unexpected error. A successful response from the API causes the extension to retrieve additional information about the remote printer. The additional information retrieved from the remote printer includes: printer name, driver name, server name, share name, printer processor, location, and comments.

Upon successfully retrieving the remote printer information, the extension closes the connection to the remote printer using the ClosePrinter API, write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and returning the underlying response code it received from the GetPrinter API. The extension creates a temporary internal string value by combining the printers share path and share name in a UNC syntax.

Detect mapped port

Next, the extension determines if the port matching the <port> attribute value is currently mapped to another printer. The extension determines this by passing the <port> attribute value to the WNetGetConnection Windows API.

An unsuccessful response from the API also returns an empty internal remote path value, which indicates the port is not mapped. The extension writes “IsMapped: “along with the <port> attribute value, and the blank internal remote path value to the trace log. The extension proceeds to the Map port phase.

A successful response from the API also returns an internal remote path value in the form of a UNC path to which the port is mapped. The extension writes “IsMapped: “along with the <port> attribute value and the internal remote path value to which the port is mapped to the trace log.

The extension then performs a case insensitive comparison between the <path> attribute value and the internal remote path value. If the comparison results in a match, then the extension proceeds to the Epilogue phase.

If the comparisons results conclude that the two string values do not match, then the extension writes the <port> attribute value “already mapped to “ the remote path value to the trace log, sets the error code to already exists, and proceeds to the Epilogue phase.

Map port

The extension maps the local port matching the <port> attribute value to the <path> attribute value by passing the <port>, <path>, <persistent> attribute values to the WNetUseConnection Windows API. The extension also passes the <username> and <cPassword> attribute values to the API provided these values are not empty.

Regardless of the response, the extension writes “MapPort: “along with the <port> and <shared> attribute values to the trace log. The extension also sets the error code to the underlying error code it received from the WNetUseConnection API. The extension proceeds to the Epilogue phase.

Epilogue

The extension completes the processing by securely deleting the clear text instance of the <cPassword> attribute value.

Create action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Delete

The delete action represents a configuration where the extension deletes a specific shared printer connection based on the configuration in the current inner element for the computer or current user or all shared printer connections for the computer or current user. Also the extension deletes all LPT printer mappings or a specific printer mapping based on the current inner element.

Prologue

The extension begins processing SharedPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <port>, <username>, and <cPassword> attributes from the current inner element.

The extension reads the next set of attributes from the current inner element and assign each attribute a default value of false (zero [0]) if a value is not present in the inner element. These attributes include <deleteAll>, <default>, <skipLocal>, <persistent>, and <deleteMaps>.

If the <cPassword> attribute contains a value, then the extension reverse-obfuscates the password into its clear text equivalent. The extensions prepares for the core processing phase by setting the security context to the computer or current user (depending how the preference item is deployed).

Core

The extension begins this processing by determining if it is configured to delete all shared printer connections or a specific printer connection by evaluating the <deleteAll> attribute. If the attribute value equals false (zero [0]), then the extension proceed to the Delete a specific shared printer connection phase. If the attribute value equals true, then the extension proceeds to the Delete all shared printer connections phases

Delete all shared printer connections

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension abort its processing and proceed to the Epilogue phase.

A successful result from the API causes the extension to cycle through the list of returned local printers. The extension begins the cycle with the current printer and determines if the printer is a network printer by the PRINTER_ATTRIBUTE_NETWORK bit in the current printer’s attributes. If the PRINTER_ATTRIBUTE_NETWORK bit is not enabled, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the PRINTER_ATTRIBUTE_NETWORK bit is disabled, then the extension attempts to discover a matching printer.

Delete shared printer connection

The extension deletes the shared printer connection by passing the current printer name to the DeletePrinterConnection Windows API. An unsuccessful response indicating an invalid printer name causes the extension to abort its processing and return an unexpected error. All other unsuccessful responses cause the extension to abort its processing and return the underlying error it received from the API. A successful response from the API cause the extension to proceed to the Epilogue phase.

Delete a specific shared printer connection

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension indicate a matching printer does not exists and proceeds with the Detect default printer override phase.

A successful result from the API causes the extension to cycle through the list of returned local printers. The extension begins the cycle with the current printer and determines if the printer is a network printer by the PRINTER_ATTRIBUTE_NETWORK bit in the current printer’s attributes. If the PRINTER_ATTRIBUTE_NETWORK bit is not enabled, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the PRINTER_ATTRIBUTE_NETWORK bit is disabled, then the extension attempts to discover a matching printer.

Match printer by share name

The extension detects a matched printer when it identifies a local printer sharing the same share name as the <path> attribute value. To begin, the extension uses the GetComputerName Windows API to retrieve and store the computers name. The extension begins a series of comparisons starting with the current printer’ server name.

If the current printer’s server name is empty, then the extension creates a temporary path value represented as UNC path using the recently discover computer name for the server portion and the current printer’s share name value as the share portion (\\computerName\printerShareName). Additionally, the extension creates a temporary name value represented as a UNC path using the recently discovered computer name for the server portion and the current printer’s name as the share portion (\\computerName\printerName).

If the current printer’s server name contains a value, then the extension creates a temporary path value represented as a UNC path using the current printer’s server name as the server portion and the current printer’s share name as the share portion (\\currentPrinterServerName\currentPrinterShareName). Additionally, the extension creates a temporary name value and assigns the current printer’s name to the temporary value.

The extension determines if the current printer matches the printer specified in the inner element configuration by comparing the temporary path value to the current printer’s path value, comparing the temporary name value to the current printer’s path value, and comparing the current printer’s port name to the current printer’s path value.

If none of these comparisons indicate a successful match, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the extension completes the iteration of printers without finding a matching printer, then the extension indicates a matching printer does not exist and proceeds to the Detect default printer override phase.

If at least one of the comparisons indicates a successful match, then the extension stops iterating through the list of printers and indicates a matching printer exists. The extension writes “FindSharedPrinterEx: “ and the <path> attribute value to the trace log, and proceeds to the Detect default printer override phase.

Delete shared printer connection

The extension determines if it previously discovered a shared printer matching the <path> attribute value. If the extension did not discover a shared printer with a matching path name then it proceeds to the Delete printer mappings phase.

The extension deletes the shared printer connection by passing the <path> attribute value to the DeletePrinterConnection Windows API. An unsuccessful response indicating an invalid printer name causes the extension to abort its processing and return an unexpected error. All other unsuccessful responses cause the extension to abort its processing and return the underlying error it received from the API. A successful response from the API cause the extension to proceed to the Delete printer mapping phase.

Delete printer mappings

The extension determines if it should delete all printer mappings or a specific mapped printer by evaluating the <deleteMaps> attribute value. An attribute value equaling true (one [1]) causes the extension to proceed to the Delete all printer mappings phase. An attribute value equaling false causes the extension to proceed to the Delete a specific mapped printer.

Delete all printer mappings

The extension begins by using the EnumPorts Windows API to gather a list of ports available for printer for the computer or current user. An unsuccessful response from the API causes proceed to the Epilogue phase. A successful response from the API also returns a list of ports for the computer or current user. The extension begins to iterate through the list of ports by making the first port in the list the current port.

Detect LPT port

The extension looks for the string “LPT’ in the current port’s name. If the current port does not include the string “LPT” in its name, then the extension moves to the next port in the list and repeats the evaluation with the new current port. If the current port does include the string “LPT” in its name, then the extension proceeds to the Detect mapped port phase.

Detect and delete mapped port

Next, the extension determines if the port matching the <port> attribute value is currently mapped. The extension determines this by passing the <port> attribute value to the WNetGetConnection Windows API.

An unsuccessful response from the API also returns an empty internal remote path value, which indicates the port is not mapped. This result causes the extension to makes the next port in the list ports the current port and return to the Detect LPT port phases.

A successful response from the API also returns an internal remote path value in the form of a UNC path to which the port is mapped, which indicates the port is mapped. This result causes the extension to pass the current port to the WNetCancelConnection2 Windows API, which removes the mapping from the current port.

All responses from the API cause the extension to make the next port in the list ports the current port and return to the Detect LPT port phase. The extension proceeds to the Epilogue phases if it completely iterates through the list of ports in the list.

Delete a specific mapped printer

The extension determines confirms the <port> attribute value is present in the configuration. If the <port> attribute value is empty, then the extension proceeds to the Epilogue phase; otherwise it proceeds to the Detect and delete mapped port phase.

Detect and delete mapped port

Next, the extension determines if the port matching the <port> attribute value is currently mapped. The extension determines this by passing the <port> attribute value to the WNetGetConnection Windows API.

An unsuccessful response from the API also returns an empty internal remote path value, which indicates the port is not mapped. This result causes the extension to write “IsMapped: “along with the <port> attribute value to the trace log and proceed to the Epilogue phase.

A successful response from the API also returns an internal remote path value in the form of a UNC path to which the port is mapped, which indicates the port is mapped. This result causes the extension to pass the current port to the WNetCancelConnection2 Windows API, which removes the mapping from the current port.

All responses from the API cause the extension to write “UnMapPort: “along with the <port> attribute value to the trace log and proceed to the Epilogue phase.

Epilogue

The extension completes the processing by securely deleting the clear text instance of the <cPassword> attribute value.

Delete action processing is complete. The extension moves to the next inner element (preference item

Replace

The replace action represents a configuration where the extension replaces an existing shared printer connection with a newly created shared printer connection based on the configuration in the current inner element.

It is important to understand the differences between replace and update. The replace action typically deletes an existing shared printer connection and creates a new one—essentially changing all configuration elements of the printer connection. The update action only updates a portion of the configuration elements for an existing shared printer connection.

Prologue

The extension begins processing SharedPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <port>, <username>, and <cPassword> attributes from the current inner element.

The extension reads the next set of attributes from the current inner element and assign each attribute a default value of false (zero [0]) if a value is not present in the inner element. These attributes include <deleteAll>, <default>, <skipLocal>, <persistent>, and <deleteMaps>.

If the <cPassword> attribute contains a value, then the extension reverse-obfuscates the password into its clear text equivalent. The extensions prepares for the core processing phase by setting the security context to the computer or current user (depending how the preference item is deployed).

Core

Delete a specific shared printer connection

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension indicate a matching printer does not exists and proceeds with the Detect default printer override phase.

A successful result from the API causes the extension to cycle through the list of returned local printers. The extension begins the cycle with the current printer and determines if the printer is a network printer by the PRINTER_ATTRIBUTE_NETWORK bit in the current printer’s attributes. If the PRINTER_ATTRIBUTE_NETWORK bit is not enabled, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the PRINTER_ATTRIBUTE_NETWORK bit is disabled, then the extension attempts to discover a matching printer.

Match printer by share name

The extension detects a matched printer when it identifies a local printer sharing the same share name as the <path> attribute value. To begin, the extension uses the GetComputerName Windows API to retrieve and store the computers name. The extension begins a series of comparisons starting with the current printer’ server name.

If the current printer’s server name is empty, then the extension creates a temporary path value represented as UNC path using the recently discover computer name for the server portion and the current printer’s share name value as the share portion (\\computerName\printerShareName). Additionally, the extension creates a temporary name value represented as a UNC path using the recently discovered computer name for the server portion and the current printer’s name as the share portion (\\computerName\printerName).

If the current printer’s server name contains a value, then the extension creates a temporary path value represented as a UNC path using the current printer’s server name as the server portion and the current printer’s share name as the share portion (\\currentPrinterServerName\currentPrinterShareName). Additionally, the extension creates a temporary name value and assigns the current printer’s name to the temporary value.

The extension determines if the current printer matches the printer specified in the inner element configuration by comparing the temporary path value to the current printer’s path value, comparing the temporary name value to the current printer’s path value, and comparing the current printer’s port name to the current printer’s path value.

If none of these comparisons indicate a successful match, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the extension completes the iteration of printers without finding a matching printer, then the extension indicates a matching printer does not exist and proceeds to the Detect default printer override phase.

If at least one of the comparisons indicates a successful match, then the extension stops iterating through the list of printers and indicates a matching printer exists. The extension writes “FindSharedPrinterEx: “ and the <path> attribute value to the trace log, and proceeds to the Detect default printer override phase.

Delete shared printer connection

The extension determines if it previously discovered a shared printer matching the <path> attribute value. If the extension did not discover a shared printer with a matching path name then it proceeds to the Delete printer mappings phase.

The extension deletes the shared printer connection by passing the <path> attribute value to the DeletePrinterConnection Windows API. An unsuccessful response indicating an invalid printer name causes the extension to abort its processing and return an unexpected error. All other unsuccessful responses cause the extension to abort its processing and return the underlying error it received from the API. A successful response from the API cause the extension to proceed to the Delete printer mapping phase.

Detect default printer override

The extension detects the default printer override option by validating both the <default> and <skipLocal> attribute values equal true (one [1]). If either attribute equals false, the extension proceeds to the Create printer phase.

When both attributes equal true, the extension continues processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to proceed to the Create printer phase.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs multiple evaluations. The extension first validates the current printer from the list of local printers is not a network connected printer by determining if the PRINTER_ATTRIBUTE_NETWORK bit is enabled in the current printers attributes. If the current printer is a network printer, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. If the current printer is not a network printer, then the extension proceeds with validating the printer name.

The second evaluation performed on the current printer is to guarantee the current printer does not match the previously discovered printer name. If the current printer name matches the previously discovered printer name, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. Otherwise, the current printer name and the previously discovered printer name do not match and the extension continues with its final evaluation.

The final evaluation performed by the extension is to determine if the current printer port is configured with a local port. The extension checks if the port name of the current printer from the list of local printers contains “LPT”, “COM”, or “USB” in the name. If the current printer’s port name does not contain these strings, then the extension cycles to the next printer in the list of local printers.

If the extensions iterates through all the printers and does not discover a printer in the list of local printers that passes these evaluations, then it internally reports that a local printer is not present. If the extension identifies a printer from the list of local printers passing all three evaluations, then it will cease the iteration and internally report a local printer exists.

A local printer not existing for the computer or current user with both the <default> and <skipLocal> attributes equaling true causes the extension to proceed to write “IsOtherLocalPrinterEx” and the last observed error code to the trace log and proceed to the Create printer phase.

A local printer existing for the computer or current user with both the <default>< and <skipLocal> attributes equaling true causes the extension to internally change the <default> attribute to equal false (zero [0]), write “IsOtherLocalPrinterEx” and the last observed error code to the trace log and proceed to the Create printer phase.

Create printer

The extension internally references if it previously detected the local printer or if it previously deleted the local printer. If the extension did not previously delete or previously detect a local printer, then the extension proceeds to the Set default printer phase. If the extension discovers it previously deleted or detected a local printer then the extension proceeds with the Driver installation phase.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the newly created local printer. An unsuccessful response from the Windows API causes the extension to abort its processing, write “InstallDriversEx:” and the <path> attribute value to the trace log, and return the underlying error it received from the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install the driver, provided the driver is not already installed.

If the driver needed for the printer installation is not located on the remote location specified by the <path> attribute value, then the extension closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “InstallDriversEx:” and the <path> attribute value to the trace log, and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing, writes “InstallDriversEx: “and the <path> attribute value to the trace log, and returns an out of memory error.

A failed response from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “InstallDriversEx: “and the <path> attribute value to the trace log, and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection, write “InstallDriversEx: “and the <path> attribute value to the trace log, and proceed with the Add shared printer phase.

Add shared printer

The extension adds the shared printer to the computer or current user by passing the <path> attribute value to the AddPrinterConnection Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “AddSharedPrinterEx: “and the <path> attribute value to the trace log, and return the underlying error code I received from the API.

A successful response from the API causes the extension write “AddSharedPrinterEx: “and the <path> attribute value to the trace log, and proceed to the Set default printer phase.

Set default printer

To set the default printer, the extension internally references if it previously discovered an existing printer. If the extension previously discovered a printer, then the extension proceeds to the Map printer port phase. If the extension did not previously discover a printer, then it checks the internal <default> attribute to determine if it was modified during the Detect default printer override phase.

If the extension determined the internal <default> attribute value equals false (zero [0]), then it proceeds to the map printer port phase. If the extension determines the internal <default> attribute value equals true (one [1]), then it passes the <path> attribute value to the SetDefaultPrinter Windows API.

An unsuccessful response from the API causes the extension to abort its processing, write “SetDefaultPrinterEx: “and the <path> attribute value to the trace log, and return the underlying error provided by the API. A successful response from the API causes the extension to abort its processing, write “SetDefaultPrinterEx: “and the <path> attribute value to the trace log, and proceed to the Map printer port phase.

Map printer port

The extension begins by verifying that the <port> attribute value is not empty. If the <port> attribute value is empty, then the extension proceeds to the Epilogue phase. Otherwise, the extension proceeds with the Get remote printer settings phase.

Get remote printer settings

The extension begins this phase by retrieving information about the remote printer. The extension gets this information by passing the <path> attribute value to the OpenPrinter Windows API. An unsuccessful response from the API causes the extension to abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the API causes the extension to close the printer handle using the ClosePrinter API; abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return an unexpected error.

Any errors regarding memory allocation occurring while gather remote printer information causes the extension to close the printer handle using the ClosePrinter API; abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return an unexpected error. A successful response from the API causes the extension to retrieve additional information about the remote printer. The additional information retrieved from the remote printer includes: printer name, driver name, server name, share name, printer processor, location, and comments.

Upon successfully retrieving the remote printer information, the extension closes the connection to the remote printer using the ClosePrinter API, write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and returning the underlying response code it received from the GetPrinter API. The extension creates a temporary internal string value by combining the printers share path and share name in a UNC syntax.

Detect mapped port

Next, the extension determines if the port matching the <port> attribute value is currently mapped to another printer. The extension determines this by passing the <port> attribute value to the WNetGetConnection Windows API.

An unsuccessful response from the API also returns an empty internal remote path value, which indicates the port is not mapped. The extension writes “IsMapped: “along with the <port> attribute value, and the blank internal remote path value to the trace log. The extension proceeds to the Map port phase.

A successful response from the API also returns an internal remote path value in the form of a UNC path to which the port is mapped. The extension writes “IsMapped: “along with the <port> attribute value and the internal remote path value to which the port is mapped to the trace log.

The extension then performs a case insensitive comparison between the <path> attribute value and the internal remote path value. If the comparison results in a match, then the extension proceeds to the Epilogue phase.

If the comparisons results conclude that the two string values do not match, then the extension writes the <port> attribute value “already mapped to “ the remote path value to the trace log, sets the error code to already exists, and proceeds to the Epilogue phase.

Map port

The extension maps the local port matching the <port> attribute value to the <path> attribute value by passing the <port>, <path>, <persistent> attribute values to the WNetUseConnection Windows API. The extension also passes the <username> and <cPassword> attribute values to the API provided these values are not empty.

Regardless of the response, the extension writes “MapPort: “along with the <port> and <shared> attribute values to the trace log. The extension also sets the error code to the underlying error code it received from the WNetUseConnection API. The extension proceeds to the Epilogue phase.

Epilogue

The extension completes the processing by securely deleting the clear text instance of the <cPassword> attribute value.

Replace action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Update

The update action represents a configuration where the extension refreshes an existing shared printer connection based on the configuration in the current inner element. It is important to understand the difference between replace and update.

It is important to understand the differences between replace and update. The replace action typically deletes an existing shared printer connection and creates a new one—essentially changing all configuration elements of the printer connection. The update action only updates a portion of the configuration elements for an existing shared printer connection.

Prologue

The extension begins processing SharedPrinter inner elements by extracting the values of the <comment>, <location>, <path>, <port>, <username>, and <cPassword> attributes from the current inner element.

The extension reads the next set of attributes from the current inner element and assign each attribute a default value of false (zero [0]) if a value is not present in the inner element. These attributes include <deleteAll>, <default>, <skipLocal>, <persistent>, and <deleteMaps>.

If the <cPassword> attribute contains a value, then the extension reverse-obfuscates the password into its clear text equivalent. The extensions prepares for the core processing phase by setting the security context to the computer or current user (depending how the preference item is deployed).

Core

Delete a specific shared printer connection

Inventory local printers

The extension begins core processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension indicate a matching printer does not exists and proceeds with the Detect default printer override phase.

A successful result from the API causes the extension to cycle through the list of returned local printers. The extension begins the cycle with the current printer and determines if the printer is a network printer by the PRINTER_ATTRIBUTE_NETWORK bit in the current printer’s attributes. If the PRINTER_ATTRIBUTE_NETWORK bit is not enabled, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the PRINTER_ATTRIBUTE_NETWORK bit is disabled, then the extension attempts to discover a matching printer.

Match printer by share name

The extension detects a matched printer when it identifies a local printer sharing the same share name as the <path> attribute value. To begin, the extension uses the GetComputerName Windows API to retrieve and store the computers name. The extension begins a series of comparisons starting with the current printer’ server name.

If the current printer’s server name is empty, then the extension creates a temporary path value represented as UNC path using the recently discover computer name for the server portion and the current printer’s share name value as the share portion (\\computerName\printerShareName). Additionally, the extension creates a temporary name value represented as a UNC path using the recently discovered computer name for the server portion and the current printer’s name as the share portion (\\computerName\printerName).

If the current printer’s server name contains a value, then the extension creates a temporary path value represented as a UNC path using the current printer’s server name as the server portion and the current printer’s share name as the share portion (\\currentPrinterServerName\currentPrinterShareName). Additionally, the extension creates a temporary name value and assigns the current printer’s name to the temporary value.

The extension determines if the current printer matches the printer specified in the inner element configuration by comparing the temporary path value to the current printer’s path value, comparing the temporary name value to the current printer’s path value, and comparing the current printer’s port name to the current printer’s path value.

If none of these comparisons indicate a successful match, then the extension makes the next printer in the list of printers the current printer and starts a new iteration. If the extension completes the iteration of printers without finding a matching printer, then the extension indicates a matching printer does not exist and proceeds to the Detect default printer override phase.

If at least one of the comparisons indicates a successful match, then the extension stops iterating through the list of printers and indicates a matching printer exists. The extension writes “FindSharedPrinterEx: “and the <path> attribute value to the trace log, and proceeds to the Detect default printer override phase.

Detect default printer override

The extension detects the default printer override option by validating both the <default> and <skipLocal> attribute values equal true (one [1]). If either attribute equals false, the extension proceeds to the Create printer phase.

When both attributes equal true, the extension continues processing by using the Windows API EnumPrinters to retrieve a list of locally installed printers. A failed result from the API causes the extension to proceed to the Create printer phase.

A successful result from the API causes the extension to cycle through the list of returned local printers where it performs multiple evaluations. The extension first validates the current printer from the list of local printers is not a network connected printer by determining if the PRINTER_ATTRIBUTE_NETWORK bit is enabled in the current printers attributes. If the current printer is a network printer, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. If the current printer is not a network printer, then the extension proceeds with validating the printer name.

The second evaluation performed on the current printer is to guarantee the current printer does not match the previously discovered printer name. If the current printer name matches the previously discovered printer name, then the extension skips the remaining evaluations and cycles to the next printer in the list of local printers. Otherwise, the current printer name and the previously discovered printer name do not match and the extension continues with its final evaluation.

The final evaluation performed by the extension is to determine if the current printer port is configured with a local port. The extension checks if the port name of the current printer from the list of local printers contains “LPT”, “COM”, or “USB” in the name. If the current printer’s port name does not contain these strings, then the extension cycles to the next printer in the list of local printers.

If the extensions iterates through all the printers and does not discover a printer in the list of local printers that passes these evaluations, then it internally reports that a local printer is not present. If the extension identifies a printer from the list of local printers passing all three evaluations, then it will cease the iteration and internally report a local printer exists.

A local printer not existing for the computer or current user with both the <default> and <skipLocal> attributes equaling true causes the extension to proceed to write “IsOtherLocalPrinterEx” and the last observed error code to the trace log and proceed to the Create printer phase.

A local printer existing for the computer or current user with both the <default>< and <skipLocal> attributes equaling true causes the extension to internally change the <default> attribute to equal false (zero [0]), write “IsOtherLocalPrinterEx” and the last observed error code to the trace log and proceed to the Create printer phase.

Create printer

The extension internally references if it previously detected the local printer. If the extension did previously detect a local printer, then the extension proceeds to the Set default printer phase. If the extension discovers it did not previously detected a local printer then the extension proceeds with the Driver installation phase.

Driver installation

The extension begins the driver installation phase by using the Windows API OpenPrinter using the <path> attribute value as the shared printer that hosts the printer driver for the newly created local printer. An unsuccessful response from the Windows API causes the extension to abort its processing, write “InstallDriversEx:” and the <path> attribute value to the trace log, and return the underlying error it received from the API.

A successful response from the OpenPrinter API causes the extension to use the GetPrinterDriver Windows API to retrieve the printer driver from the <path> attribute value and install the driver, provided the driver is not already installed.

If the driver needed for the printer installation is not located on the remote location specified by the <path> attribute value, then the extension closes the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “InstallDriversEx:” and the <path> attribute value to the trace log, and returns an unknown printer driver error.

A failed response from the GetPrinterDriver API indicating a problem with allocating memory causes the extension to close the printer connection using the ClosePrinter API. The extension aborts its processing, writes “InstallDriversEx: “and the <path> attribute value to the trace log, and returns an out of memory error.

A failed response from the GetPrinterDriver API causes the extension to close the printer connection using the ClosePrinter Windows API. The extension aborts its processing, writes “InstallDriversEx: “and the <path> attribute value to the trace log, and returns the underlying error it received from the Windows API.

A successful response from the API causes the extension to close the printer connection, write “InstallDriversEx: “and the <path> attribute value to the trace log, and proceed with the Add shared printer phase.

Add shared printer

The extension adds the shared printer to the computer or current user by passing the <path> attribute value to the AddPrinterConnection Windows API. An unsuccessful response from the API causes the extension to abort its processing, write “AddSharedPrinterEx: “and the <path> attribute value to the trace log, and return the underlying error code I received from the API.

A successful response from the API causes the extension write “AddSharedPrinterEx: “and the <path> attribute value to the trace log, and proceed to the Set default printer phase.

Set default printer

To set the default printer, the extension internally references if it previously discovered an existing printer. If the extension previously discovered a printer, then the extension proceeds to the Map printer port phase. If the extension did not previously discover a printer, then it checks the internal <default> attribute to determine if it was modified during the Detect default printer override phase.

If the extension determined the internal <default> attribute value equals false (zero [0]), then it proceeds to the map printer port phase. If the extension determines the internal <default> attribute value equals true (one [1]), then it passes the <path> attribute value to the SetDefaultPrinter Windows API.

An unsuccessful response from the API causes the extension to abort its processing, write “SetDefaultPrinterEx: “and the <path> attribute value to the trace log, and return the underlying error provided by the API. A successful response from the API causes the extension to abort its processing, write “SetDefaultPrinterEx: “and the <path> attribute value to the trace log, and proceed to the Map printer port phase.

Map printer port

The extension begins by verifying that the <port> attribute value is not empty. If the <port> attribute value is empty, then the extension proceeds to the Epilogue phase. Otherwise, the extension proceeds with the Get remote printer settings phase.

Get remote printer settings

The extension begins this phase by retrieving information about the remote printer. The extension gets this information by passing the <path> attribute value to the OpenPrinter Windows API. An unsuccessful response from the API causes the extension to abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return the underlying error it received from the API.

A successful response causes the extension to pass the printer handle it received from the OpenPrinter API to the GetPrinter Windows API. An unsuccessful response from the API causes the extension to close the printer handle using the ClosePrinter API; abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return an unexpected error.

Any errors regarding memory allocation occurring while gather remote printer information causes the extension to close the printer handle using the ClosePrinter API; abort its processing; write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and return an unexpected error. A successful response from the API causes the extension to retrieve additional information about the remote printer. The additional information retrieved from the remote printer includes: printer name, driver name, server name, share name, printer processor, location, and comments.

Upon successfully retrieving the remote printer information, the extension closes the connection to the remote printer using the ClosePrinter API, write “GetRemotePrinterSettingsEx: ”along with printer path, printer share path, and printer share name to the trace log; and returning the underlying response code it received from the GetPrinter API. The extension creates a temporary internal string value by combining the printers share path and share name in a UNC syntax.

Detect mapped port

Next, the extension determines if the port matching the <port> attribute value is currently mapped to another printer. The extension determines this by passing the <port> attribute value to the WNetGetConnection Windows API.

An unsuccessful response from the API also returns an empty internal remote path value, which indicates the port is not mapped. The extension writes “IsMapped: “along with the <port> attribute value, and the blank internal remote path value to the trace log. The extension proceeds to the Map port phase.

A successful response from the API also returns an internal remote path value in the form of a UNC path to which the port is mapped. The extension writes “IsMapped: “along with the <port> attribute value and the internal remote path value to which the port is mapped to the trace log.

The extension then performs a case insensitive comparison between the <path> attribute value and the internal remote path value. If the comparison results in a match, then the extension proceeds to the Epilogue phase.

If the comparisons results conclude that the two string values do not match, then the extension writes the <port> attribute value “already mapped to “ the remote path value to the trace log, sets the error code to already exists, and proceeds to the Epilogue phase.

Map port

The extension maps the local port matching the <port> attribute value to the <path> attribute value by passing the <port>, <path>, <persistent> attribute values to the WNetUseConnection Windows API. The extension also passes the <username> and <cPassword> attribute values to the API provided these values are not empty.

Regardless of the response, the extension writes “MapPort: “along with the <port> and <shared> attribute values to the trace log. The extension also sets the error code to the underlying error code it received from the WNetUseConnection API. The extension proceeds to the Epilogue phase.

Epilogue

The extension completes the processing by securely deleting the clear text instance of the <cPassword> attribute value.

Update action processing is complete. The extension moves to the next inner element (preference item) and begins inner element processing on the new, current inner element.

Dependencies

The Group Policy Printers extension is one of many extensions provided in a single dynamic linked library, gpprecl.dll. This extension has one or more dependencies on the following dynamic linked libraries that are included in the Windows operating system.

  1. ACTIVEDS.DLL

  2. ADVAPI32.DLL

  3. IPHLPAPI.DLL

  4. KERNEL32.DLL

  5. MPR.DLL

  6. MSI.DLL

  7. MSVCRT.DLL

  8. NETAPI32.DLL

  9. NTDLL.DLL

  10. OLE32.DLL

  11. OLEAUT32.DLL

  12. POWRPROF.DLL

  13. RPCRT4.DLL

  14. SECUR32.DLL

  15. SETUPAPI.DLL

  16. SHELL32.DLL

  17. SHLWAPI.DLL

  18. USER32.DLL

  19. USERENV.DLL

  20. VERSION.DLL

  21. WINSPOOL.DRV

  22. WINSTA.DLL

  23. WLDAP32.DLL

  24. WS2_32.DLL

  25. WTSAPI32.DLL

  26. XMLLITE.DLL

Interaction with other components

The Windows operating system enables many different configurations to accomplish a single task. Creating and managing printers is one of those tasks.

The most common configuration for mapping printers occurs during the user logon. Historically, IT departments have accomplished this configuration using network logon scripts—scripts that process as part of the user logon. Users can map printers using Windows Explorer and make them persistent between computer reboots. You can use Deployed Printers, which is an alternative Group Policy-based technology that stores configuration information in Active Directory. Lastly, you can use the Group Policy Drive Map extension to map drives during logon.

Flexible configurations are important; however, understanding that incorporating the one or more of the configurations into one solution needs to be thoroughly tested for each specific environment as many of these technologies can encroach on the other thereby creating unpredictable results. A suggested best practice is to pick one configuration and use it exclusively in your environment, especially when managing printers during logon. Incorporating multiple configurations could be counterproductive and cause conflict between the configurations. This conflict is likely to produce unwanted results, increases the complexity of the solution, increases administrative overhead of the solution, and increase the difficulty of troubleshooting the cause of the problem.

Logging

In addition to the event messages recorded in the application log, the Group Policy Printers extension has trace logging to help diagnose preference items that are not applying or undesired or unexpected results from preference items that are applying.

You enable Group Policy Preference logging using Computer\Policies namespace of the Group Policy Management Editor. The Configure Printers preference logging and tracing policy setting resides under the Administrative Templates\System\Group Policy\Logging and tracing node. The policy setting enables a variety of configuration options that affect the types of events the extension reports to the event log, trace logging, and the filename and location of the trace logs.

The best configuration for capturing Group Policy Printers information for troubleshooting is to configure Event Logging using the Informational, Warnings, and Errors option and configure Tracing to On.

Trace logging file name and locations are configurable to any name and location to where the user or computer has read and write permissions. The default paths for these files use a Group Policy Preference variable %COMMONAPPDATA%\GroupPolicy\Preference\Trace\<filename>. The Group Policy Preference %COMMONAPPDATA% variable equates to the All Users’ application data folder.

Starting with Windows Vista, the All Users’ folder was deprecated with the introduction of the version 2 user profile structure. To ensure compatibility among applications, Windows creates a symbolic link named All Users in the file system under the %SYSTEMDRIVE%\Users folder. The symbolic link redirects file system requests to the All Users folder to the C:\ProgramData folder. Therefore, the default location for Group Policy Preference trace logs is C:\ProgramData\GroupPolicy\Preference\Trace\<filename>.