Windows ReadPrinter BIDI communication is possible!
Just read in a post from Jeffrey Tan that BIDI communication with the printer is actually possible.
I always thought that this was impossible, as Windows restrics the read access to any ports to language monitors only.
But now it turns out, you can work around this, by creating a dummy job, and then opening a handle to that job with OpenPrinter. You ofcourse still need the port monitor to support bidi.
#define BUFSIZE 256 BOOL TestReadPrinterWithJob(LPSTR szPrinterName) { HANDLE hPrinter = NULL; HANDLE hPrinterJob = NULL; DWORD dwBytesRead; LPVOID lpBytes = NULL; DOC_INFO_1 dc; DWORD jobid; TCHAR jobStr[100]; // Open a handle to the printer. if (!OpenPrinter(szPrinterName, &hPrinter, NULL)) { PrintError(GetLastError(), "OpenPrinter"); return FALSE; } // We can't read from a printer handle, but we can read from // a printer job handle, So the trick is to create a Job using // StartDocPrinter, then open a handle to the printer job... ZeroMemory(&dc, sizeof(DOC_INFO_1)); dc.pDocName="Dummy job"; jobid = StartDocPrinter(hPrinter,1,(LPSTR)&dc); // start a Doc if (jobid == 0) { ClosePrinter(hPrinter); PrintError(GetLastError(), "OpenPrinter"); return FALSE; } // Open handle to the printer job... wsprintf(jobStr, "%s,Job %i", szPrinterName, jobid); if (!OpenPrinter(jobStr, &hPrinterJob, NULL)) { ClosePrinter(hPrinter); PrintError(GetLastError(), "OpenPrinter Job"); return FALSE; } // Allocate a buffer to read printer data into... lpBytes = (LPVOID)malloc(BUFSIZE); if (!lpBytes) { PrintError(GetLastError(), "malloc"); ClosePrinter(hPrinter); ClosePrinter(hPrinterJob); return FALSE; } // Try ReadPrinter... SetLastError(0); if (!ReadPrinter(hPrinterJob, lpBytes, BUFSIZE, &dwBytesRead)) { PrintError(GetLastError(), "ReadPrinter"); ClosePrinter(hPrinter); ClosePrinter(hPrinterJob); if (lpBytes) free(lpBytes); return FALSE; } else { printf("%i bytes successfully read by ReadPrinter (%i attempted)\n", dwBytesRead, BUFSIZE); } // Clean up... ClosePrinter(hPrinterJob); EndDocPrinter(hPrinter); // end the doc ClosePrinter(hPrinter); if (lpBytes) free(lpBytes); return TRUE; } void PrintError( DWORD dwError, LPCSTR lpString ) { #define MAX_MSG_BUF_SIZE 512 char *msgBuf; DWORD cMsgLen; cMsgLen = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | 40, NULL, dwError, MAKELANGID(0, SUBLANG_ENGLISH_US), (LPTSTR) &msgBuf, MAX_MSG_BUF_SIZE, NULL); printf( "%s Error [%d]:: %s\n", lpString, dwError, msgBuf ); LocalFree( msgBuf ); #undef MAX_MSG_BUF_SIZE }
No comments yet
Leave a reply