0

I'm trying to read printer port configuration using XcvData but it fails with error 87 (invalid parameter). I have no problem adding a port or setting port configuration. I've seen some c# code samples that do exactly what I do so I'm not sure what causes the failures. Any suggestions will be appreciated. Thanks.

Sample code:

PRINTER_DEFAULTS defaults = { NULL, NULL, SERVER_ACCESS_ADMINISTER };
HANDLE hPrinter;

if (::OpenPrinter(L", XcvMonitor Standard TCP/IP Port", hPrinter, &defaults))
{
    CONFIG_INFO_DATA_1 configInfoData1;
    memset(&configInfoData1, 0, sizeof(configInfoData1));
    configInfoData1.dwVersion = 1;

    PORT_DATA_1 portData1;
    // this initialization does not seem to help
    memset(&portData1, 0, sizeof(portData1));
    portData1.cbSize = sizeof(portData1);

    DWORD dwStatus = 0;
    DWORD dwNeeded = 0;

    // this always fails with dwStatus 87 (invalid parameter)
    if (XcvData(hPrinter, L"GetConfigInfo", (PBYTE)&configInfoData1, 
        sizeof(configInfoData1), (PBYTE)&portData1, sizeof(portData1), &dwNeeded, &dwStatus))
    {
        if (dwStatus != 0)
        {
            [...]
            // throw exception
        }

        _ASSERTE(dwNeeded > 0);

        [...]
    }


    // this works fine
    if (XcvData(hPrinter, L"ConfigPort", (PBYTE)&m_portData1, sizeof(m_portData1), 
        NULL, 0, &dwNeeded, &dwStatus))
    {
        [...]   
    }

    [...]
}
bdristan
  • 1,048
  • 1
  • 12
  • 36
  • `portData1` is uninitialized. That may well trip off the API. Use `PORT_DATA_1 portData1{};` instead. – IInspectable Oct 30 '17 at 10:12
  • portData1 is used for output so I don't see how initialization can help. However, before posting the question I did try memset it to 0 and even set its cbSize to a correct value. – bdristan Oct 30 '17 at 15:03
  • Post that code then, including your error discovery code. Many Windows API calls require that out parameters still are properly initialized (e.g. setting the size or version fields). – IInspectable Oct 30 '17 at 15:34
  • I just edited my original post. – bdristan Oct 30 '17 at 15:39
  • That doesn't show the error discovery code. It's the one thing that many developers get wrong. For all we know, the error code might just be meaningless at the point your are asking for it. – IInspectable Oct 30 '17 at 15:45
  • I simply check the status code returned by XcvData as seen with my most recent update. As I stated in my original post, dwStatus is set to 87 and dwNeeded is set to 0 when the call returns. – bdristan Oct 30 '17 at 16:01
  • Stepping into the API shouldn't be too complicated. – Nick Westgate Oct 31 '17 at 01:54

1 Answers1

0

` //////////////////////////////////////////////////////////////////

DWORD code = 0;
PRINTER_DEFAULTS Defaults1 = { NULL, NULL, SERVER_ACCESS_ADMINISTER };

HANDLE hXcv = NULL;
CString strPortName;
strPortName = _T(",XcvPort 168.118.18.156");//L",XcvMonitor Standard TCP/IP Port"
if (OpenPrinter((LPTSTR)(LPCTSTR)strPortName, &hXcv, &Defaults1))
{
    CONFIG_INFO_DATA_1 configInfoData1;
    memset(&configInfoData1, 0, sizeof(configInfoData1));
    configInfoData1.dwVersion = 1;

    PORT_DATA_1 portData1;
    // this initialization does not seem to help
    memset(&portData1, 0, sizeof(portData1));
    portData1.cbSize = sizeof(portData1);

    DWORD dwStatus = 0;
    DWORD dwNeeded = 0;

    // getconfiginfo
    if (XcvData(hXcv, L"GetConfigInfo", (PBYTE)&configInfoData1,
        sizeof(configInfoData1), (PBYTE)&portData1, sizeof(portData1), &dwNeeded, &dwStatus))
    {
    }

    _tcscpy(portData1.sztHostAddress,_T("168.118.18.148"));
    // setconfiginfo
    if (XcvData(hXcv, L"ConfigPort", (PBYTE)&portData1, sizeof(portData1),
        NULL, 0, &dwNeeded, &dwStatus))
    {
    }
    ClosePrinter(hXcv);
}
///////////////////////////

`OpenPrinter(L",XcvPort 168.118.18.156", hPrinter, &defaults);

Use the specific portname then GetConfigInfo is OK. portname:168.118.18.156

Curry30
  • 11
  • 2