We have a virtual printer (provided by a 3rd party) that is getting assigned to an invalid local printer port. The printer is always local (we aren\'t dealing with a remote
I guess your code merely worked by chance. According to https://docs.microsoft.com/en-us/windows-hardware/drivers/print/tcpmon-xcv-commands (and to my own experience) the real solution is:
PORT_DATA_1 pdPortData;
wcscpy_s(pdPortData.sztPortName, MAX_PORTNAME_LEN, lpPortName);
[...]
if (!XcvData(hXcv, L"AddPort", (BYTE*) &pdPortData, sizeof(PORT_DATA_1), NULL, 0, &dwNeeded, &dwStatus))
[...]
By chance sztPortName is the first element in PORT_DATA_1 structure. Maybe that's why your code did not fail, although it is wrong.
Wow, looks like that one stumped everyone... After much digging, here's how to do it:
DWORD CreatePort(LPWSTR portName)
{
HANDLE hPrinter;
PRINTER_DEFAULTS PrinterDefaults;
memset(&PrinterDefaults, 0, sizeof(PrinterDefaults));
PrinterDefaults.pDatatype = NULL;
PrinterDefaults.pDevMode = NULL;
PrinterDefaults.DesiredAccess = SERVER_ACCESS_ADMINISTER;
DWORD needed;
DWORD rslt;
if (!OpenPrinter(",XcvMonitor Local Port", &hPrinter, &PrinterDefaults))
return -1;
DWORD xcvresult= 0;
if (!XcvData(hPrinter, L"AddPort", (BYTE *)portName, (lstrlenW(portName) + 1)*2, NULL, 0, &needed, &xcvresult))
rslt= GetLastError();
if (!ClosePrinter(hPrinter))
rslt= GetLastError();
return rslt;
}
Setting the port on a given printer is relatively straight forward - OpenPrinter(), GetPrinter() with PRINTER_INFO_2, SetPrinter(), ClosePrinter()
Cheerio.