Search code examples
c++windowsprintinggetlasterror

insufficient buffer when call DocumentProperties, also, global unlock wouldn't unlock


please see comments inline

bool res = false;
DWORD dwNeeded = DocumentPropertiesW(NULL, m_currPrinterHandle, (LPWSTR) m_currPrinterName.c_str(), NULL, NULL, 0); 
if (m_devmode_buf)
{
    GlobalFree(m_devmode_buf);      
}
m_devmode_buf = GlobalAlloc(GPTR, dwNeeded);
GetLastError(); // = 0;
if (m_devmode_buf)
{
    LPDEVMODEW devmode_buf = (LPDEVMODEW) GlobalLock(m_devmode_buf);        
    GetLastError(); // = 0
    if (devmode_buf)
    {           
        if (devmode_buf)
        {
            lala = DocumentPropertiesW(NULL, m_currPrinterHandle, (LPWSTR) m_currPrinterName.c_str(), devmode_buf, NULL, DM_OUT_BUFFER);
            if (lala == IDOK)
            {
                res = true;
            }
            GetLastError(); // = 122. insufficient buffer here. why????
        }
        UInt32 res1 = GlobalUnlock(m_devmode_buf); // res1 is 1. should be 0
        res2 = GetLastError(); // = 0
        if (!(res1 == 0 && (res2 == ERROR_NOT_LOCKED || res2 == NO_ERROR)))
        {
            //res = false;
        }           
    }
}

Solution

  • If the second call to DocumentProperties() is returning 1 (i.e. IDOK) then it is not failing, thus the value of GetLastError() is meaningless. It is probably an expected condition that is raised and handled inside of DocumentProperties(). The convention of using GetLastError() is that you only set it on failure; you don't usually clear it on success. It is up to the documentation of each individual function to explain how errors are returned. The documentation for DocumentProperties() doesn't even mention GetLastError(), so checking it at all might be meaningless (though usually it is safe to assume that all Win32 functions return errors via GetLastError()).