10 Replies - 19281 Views - Last Post: 19 August 2009 - 02:56 AM Rate Topic: -----

#1 HyperEngineer  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 8
  • Joined: 21-May 08

Communicating with USB printer

Post icon  Posted 21 May 2008 - 02:08 PM

I am trying to write and read to a USB printer. I can get the device name to use in CreateFile() and it sends the bytes out. But I don't seem to be getting to the printer. I don't get any response from the printer. Here is the code I have:

void CTestPlace2008Dlg::OnBnClickedUsb()
{
	// TODO: Add your control notification handler code here

	// Try to get the devices on the USB.  If found try to communicate
	//   with it.  Skip the Host Controller enumeration, finding root
	//   hubs and then look for devices.

/*
	Use this block if I have to enumerate Host controllers, find root
	  hubs and then look for devices.
	char HCDName[16];
	int  HCDNum;
	HANDLE hHCDev;
*/
	HDEVINFO devs;
	SP_DEVINFO_DATA devinfo;
	SP_DEVICE_INTERFACE_DATA devinterface;
	GUID intfce;
	PSP_DEVICE_INTERFACE_DETAIL_DATA interface_detail;
	ULONG index;
	ULONG requiredLength;
	
	intfce = GUID_DEVINTERFACE_USBPRINT;

	devs = SetupDiGetClassDevs(&intfce,  //&GUID_DEVINTERFACE_USBPRINT,
							   NULL,
							   NULL,
							   DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

	if (GetLastError() == ERROR_INVALID_PARAMETER || GetLastError() == ERROR_INVALID_FLAGS 
			   || devs == INVALID_HANDLE_VALUE) {
		SetupDiDestroyDeviceInfoList(devs);
		return;
	}

	ZeroMemory(&devinterface, sizeof(SP_DEVICE_INTERFACE_DATA));
	devinterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
	devinterface.Flags = 0;

	for (index = 0;
		 SetupDiEnumDeviceInterfaces(devs,
		 0,
		 &intfce,  //&GUID_DEVINTERFACE_USBPRINT,
		 index,
		 &devinterface);
		 index++)
	{
		// Clear out error list
		GetLastError();

		char* interfacename;
		
		// Allocate space
		interfacename = (char*) malloc(2048);
	
		// Zero out buffer
		ZeroMemory(interfacename, 2048);

		requiredLength = 0;
		if (!SetupDiGetDeviceInterfaceDetail(devs,
											 &devinterface,
											 NULL,
											 0,
											 &requiredLength,
											 NULL)) {
			
			if (GetLastError() != 122){	 // If not wrong size
				char* buf;
				FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
							  FORMAT_MESSAGE_FROM_SYSTEM |
							  FORMAT_MESSAGE_IGNORE_INSERTS,
							  NULL,
							  GetLastError(),
							  0,
							  (LPTSTR) &buf,
							  0,
							  NULL);
				char* myerrmsg;
				myerrmsg = (char*) malloc(128);
				wsprintf(myerrmsg,"Error # = %d\n%s", GetLastError(), buf);
				AfxMessageBox(myerrmsg, MB_OK, 0);
				return;
			}
		}
	
//		interface_detail = (SP_DEVICE_INTERFACE_DETAIL_DATA*) malloc(requiredLength);
		interface_detail = (PSP_DEVICE_INTERFACE_DETAIL_DATA) calloc(1, requiredLength);

		if (interface_detail == NULL)
			AfxMessageBox("Memory allocation failed!",MB_OK,0);
		else {
			ZeroMemory(interface_detail, sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA));
			interface_detail->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
			devinfo.cbSize = sizeof(SP_DEVINFO_DATA);

			SetupDiGetDeviceInterfaceDetail(devs,
											&devinterface,
											interface_detail,
											requiredLength,
											&requiredLength,
											&devinfo);

			//interfacename = interface_detail->DevicePath;
			strcpy_s(interfacename, 0x800, interface_detail->DevicePath);
		}
//		strcpy_s(interfacename, sizeof("\\\\.\\USB001"), "\\\\.\\USB001");
		HANDLE BradyUSB = CreateFile(interfacename, 
									 GENERIC_READ | GENERIC_WRITE,
									 FILE_SHARE_READ | FILE_SHARE_WRITE,
									 NULL,
									 OPEN_ALWAYS,
									 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED,
									 NULL);

		if (BradyUSB == INVALID_HANDLE_VALUE){
			char* mybuf;
			mybuf = (char*) malloc(128);
			wsprintf(mybuf, "Did not open Brady printer");
			AfxMessageBox(mybuf, MB_OK | MB_ICONEXCLAMATION, 0);
			free(mybuf);
		} else {
			// Write to the printer
			OVERLAPPED olWrite = { 0 };
			olWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
			char cCommand1, cCommand2, cTermChar, cAllCommand[5];
			DWORD dwBytesWritten;
			DWORD dwBytesToWrite;
			bool writeSuccess;
			cCommand1 = 0x01;
			cCommand2 = '#';
				  cTermChar = '\n';
			dwBytesToWrite = 3;
			if(!WriteFile(BradyUSB, cAllCommand, dwBytesToWrite, &dwBytesWritten, &olWrite)) {
				// Wait until write operation is complete
				bool done = false;
				while (!done) {
					WaitForSingleObject(olWrite.hEvent, INFINITE);
					if (!GetOverlappedResult(BradyUSB, &olWrite, &dwBytesWritten, FALSE)) {
						if (!(GetLastError() == ERROR_IO_PENDING)) {
							// Get out of loop and check for bytes written
							done = true;
						} // IO Pending
					} else // GetOverlappedResult
						done = true;
				} // while loop
			} // write file
			if (dwBytesWritten == 0){
				char* mywriteerrorbuf;
				mywriteerrorbuf = (char*) malloc(64);
				wsprintf(mywriteerrorbuf, "Write error!");
				AfxMessageBox(mywriteerrorbuf, MB_OK | MB_ICONEXCLAMATION, 0);
				free(mywriteerrorbuf);
				writeSuccess = false;
			} else 
				writeSuccess = true;
			
			if (writeSuccess) {  // Write was a success, let's read
				// Clear the error
				SetLastError(0);
				ResetEvent(olWrite.hEvent);
				char myreadbuf[10];
				OVERLAPPED olRead = { 0 };
				olRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
				DWORD dwBytesRead;
						myreadbuf[9] = '\0';
				if (!ReadFile(BradyUSB, &myreadbuf, 0x100, &dwBytesRead, &olRead)) {
					// Wait for read operation to complete
					int retval = WaitForSingleObject(olRead.hEvent,5000);
				}
				if (dwBytesRead == 0) {
					// Nothing was read.
					char* myreaderrorbuf;
					myreaderrorbuf = (char*) malloc(64);
					wsprintf(myreaderrorbuf, "Nothing to read!");
					AfxMessageBox(myreaderrorbuf, MB_OK | MB_ICONEXCLAMATION, 0);
					free(myreaderrorbuf);
				}
			} // Write success
		}  // Printer handle
		if (BradyUSB != INVALID_HANDLE_VALUE)
			CloseHandle(BradyUSB);
	} // for loop
	SetupDiDestroyDeviceInfoList(devs);
}




The CreateFile gives a valid handle. The interface name from the device detail devicepath is:
\\?\usb#vid_0b0b&pid_106e#5&11dad59d&0&1#{28d78fad-5a12-11d1-ae5b-0000f803a8c2}.

Thanks,
HyperEngineer

Is This A Good Question/Topic? 0
  • +

Replies To: Communicating with USB printer

#2 perfectly.insane  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 70
  • View blog
  • Posts: 644
  • Joined: 22-March 08

Re: Communicating with USB printer

Posted 21 May 2008 - 03:01 PM

Quote

			OVERLAPPED olWrite = { 0 };
			olWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
			char cCommand1, cCommand2, cTermChar, cAllCommand[5];
			DWORD dwBytesWritten;
			DWORD dwBytesToWrite;
			bool writeSuccess;
			cCommand1 = 0x01;
			cCommand2 = '#';
				  cTermChar = '\n';
			dwBytesToWrite = 3;
			if(!WriteFile(BradyUSB, cAllCommand, dwBytesToWrite, &dwBytesWritten, &olWrite)) {



I don't see the bytes from cCommand1, cCommand2, and cTermChar being copied to the cAllCommand buffer (which is what is being sent to the printer, per the WriteFile line). You're most likely writing random garbage left on the stack. I haven't read the whole thing yet though, so there may be more issues.
Was This Post Helpful? 1

#3 HyperEngineer  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 8
  • Joined: 21-May 08

Re: Communicating with USB printer

Posted 21 May 2008 - 03:21 PM

Thanks for the reply perfectly.insane. I did a copy and paste then changed the code and missed updating that part. Here is the code for that section:

	OVERLAPPED olWrite = { 0 };
	olWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	char cCommand1, cCommand2, cTermChar, cAllCommand[5];
	DWORD dwBytesWritten;
	DWORD dwBytesToWrite;
	bool writeSuccess;
	cCommand1 = 0x01;
	cCommand2 = '#';
	cTermChar = '\n';
	cAllCommand[0] = cCommand1;
	cAllCommand[1] = cCommand2;
	cAllCommand[2] = cTermChar;
	cAllCommand[4] = '\0';
	dwBytesToWrite = 3;
	if(!WriteFile(BradyUSB, cAllCommand, dwBytesToWrite, &dwBytesWritten, &olWrite)) {




Sorry about that. I put the NULL character there to terminate the string even though it's only suppose to read the first 3 bytes. But it helps in the debug.

Thanks,
Was This Post Helpful? 0
  • +
  • -

#4 perfectly.insane  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 70
  • View blog
  • Posts: 644
  • Joined: 22-March 08

Re: Communicating with USB printer

Posted 21 May 2008 - 03:30 PM

A few more points....

I'm not sure what 0b0b:106e is, but a net search indicates that the vendor is "Rhino". Must be the maker of the chip set in the printer?

Also, if you want to access paths like \\.\USB001, you need to use NtCreateFile. CreateFile can only open paths like \\?\GlobalDeviceName, where GlobalDeviceName is a device present in the \GLOBAL?? namespace in the device namespace.
Was This Post Helpful? 0
  • +
  • -

#5 perfectly.insane  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 70
  • View blog
  • Posts: 644
  • Joined: 22-March 08

Re: Communicating with USB printer

Posted 21 May 2008 - 03:41 PM

Did you check the buffer to see if anything was read? I noticed that there is no call to GetOverlappedResult on the read, which I believe that call is what modifies the length received if the I/O operation does not complete at the ReadFile call.

This post has been edited by perfectly.insane: 21 May 2008 - 03:42 PM

Was This Post Helpful? 0
  • +
  • -

#6 HyperEngineer  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 8
  • Joined: 21-May 08

Re: Communicating with USB printer

Posted 22 May 2008 - 07:29 AM

I added the GetOverlappedResult() to the ReadFile() section. The WaitForSingleObject times out in 5 seconds. The dwBytesRead is 0. GetLastError() does not return ERROR_IO_PENDING. I will put something in there to determine what code is returned. I will also investigate the suggestion of using NtCreateFile() using \\.\USB001. Do I have to use NtReadFile() and NtWriteFile()? Those are not in my copy of MSDN ver9.0.

I added the routine to get the last error:

Error# = 996
Overlapped I/O event is not in a signaled state.

Thanks,
Was This Post Helpful? 0
  • +
  • -

#7 perfectly.insane  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 70
  • View blog
  • Posts: 644
  • Joined: 22-March 08

Re: Communicating with USB printer

Posted 22 May 2008 - 09:55 AM

View PostHyperEngineer, on 22 May, 2008 - 07:29 AM, said:

I added the GetOverlappedResult() to the ReadFile() section. The WaitForSingleObject times out in 5 seconds. The dwBytesRead is 0. GetLastError() does not return ERROR_IO_PENDING. I will put something in there to determine what code is returned. I will also investigate the suggestion of using NtCreateFile() using \\.\USB001. Do I have to use NtReadFile() and NtWriteFile()? Those are not in my copy of MSDN ver9.0.

I added the routine to get the last error:

Error# = 996
Overlapped I/O event is not in a signaled state.

Thanks,


If this is comming from GetOverlappedResult, then this is probably correct. You're trying to read 256 bytes from the device (0x100, as specified in ReadFile). If the response from the printer is not 256 or more bytes, then the I/O operation will never complete. I do believe that the GetOverlappedResult function is still supposed to update the dwBytesRead argument in this case though.

(There's a potential buffer overflow there also, as your buffer is only 10 bytes...).

As far as NtReadFile and NtWriteFile, these are "undocumented" calls, and are probably not in many, if any, header files. You'll need to use LoadLibrary/GetProcAddress to get these from ntdll.dll. You can find the function prototypes by searching on Google.

As far as the printing issue, you might want to find a program that captures activity on a USB port. I believe there are free ones that exist (though I'm not sure how good they are), to make sure that your commands are actually getting sent to the printer in the first place.

If they're not, then you might want to investigate what driver is providing the \\?\usb#vi...{28d78fad-5a12-11d1-ae5b-0000f803a8c2} object. If it's not standard, then you might not be interfacing with it correctly. Printer drivers usually include a user-space component, except when not necessary (sometimes in the case of postscript printers). I don't think printer interfaces at the HAL are required to conform to a standard because of this (as the user-space driver is written by the manufacturer also).

Is there any reason for not interfacing with the printer using GDI?
Was This Post Helpful? 0
  • +
  • -

#8 perfectly.insane  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 70
  • View blog
  • Posts: 644
  • Joined: 22-March 08

Re: Communicating with USB printer

Posted 22 May 2008 - 01:06 PM

myself said:

Is there any reason for not interfacing with the printer using GDI?


I think I found the answer to this question... But I'm curious as to what Brady printer supports this command protocol over USB as opposed to RS232 serial?
Was This Post Helpful? 0
  • +
  • -

#9 HyperEngineer  Icon User is offline

  • New D.I.C Head

Reputation: 2
  • View blog
  • Posts: 8
  • Joined: 21-May 08

Re: Communicating with USB printer

Posted 22 May 2008 - 02:02 PM

It is a USB printer from Brady (BP-1244), but the innards are by Datamax (E4204). Nobody at either company can give me any help on talking to this device. But there are label programs out there that do talk to this device.
At your suggestion, I have found a monitor for the USB. It is HDD Software's Device Monitoring Studio 5.22. It sees the three bytes going to the printer, the request for a response from the printer. and that the printer does not send anything back. I'm going to try to use a labeller program to send something to the printer to see if it responds.
Was This Post Helpful? 0
  • +
  • -

#10 jyotiranjanr  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 5
  • Joined: 12-August 09

Re: Communicating with USB printer

Posted 17 August 2009 - 01:56 AM

View PostHyperEngineer, on 22 May, 2008 - 01:02 PM, said:

It is a USB printer from Brady (BP-1244), but the innards are by Datamax (E4204). Nobody at either company can give me any help on talking to this device. But there are label programs out there that do talk to this device.
At your suggestion, I have found a monitor for the USB. It is HDD Software's Device Monitoring Studio 5.22. It sees the three bytes going to the printer, the request for a response from the printer. and that the printer does not send anything back. I'm going to try to use a labeller program to send something to the printer to see if it responds.



Dear All,
I'm New to USB Port communication.My Aim is to write the data to the USB port, which is connected to a Barcode Printer(currently its Datamax printer).I do not have any Idea how to startup? I referd to "USB Complete" Book By Jan Axelson and found bit useful but still i'm not clear how to startup.I'm going to write a code in VC++ with MFC dialog based.Can any one suggest me where i can found a complete example code (VC++/MFC) to communicate with barcode printer through USB ? Or Please guide me how to startup with some example code.
Pl. Help me.
Thanks in advance.

This post has been edited by jyotiranjanr: 17 August 2009 - 01:59 AM

Was This Post Helpful? 0
  • +
  • -

#11 jyotiranjanr  Icon User is offline

  • New D.I.C Head

Reputation: 1
  • View blog
  • Posts: 5
  • Joined: 12-August 09

Re: Communicating with USB printer

Posted 19 August 2009 - 02:56 AM

View Postjyotiranjanr, on 17 Aug, 2009 - 12:56 AM, said:

View PostHyperEngineer, on 22 May, 2008 - 01:02 PM, said:

It is a USB printer from Brady (BP-1244), but the innards are by Datamax (E4204). Nobody at either company can give me any help on talking to this device. But there are label programs out there that do talk to this device.
At your suggestion, I have found a monitor for the USB. It is HDD Software's Device Monitoring Studio 5.22. It sees the three bytes going to the printer, the request for a response from the printer. and that the printer does not send anything back. I'm going to try to use a labeller program to send something to the printer to see if it responds.



Dear All,
I'm New to USB Port communication.My Aim is to write the data to the USB port, which is connected to a Barcode Printer(currently its Datamax printer).I do not have any Idea how to startup? I referd to "USB Complete" Book By Jan Axelson and found bit useful but still i'm not clear how to startup.I'm going to write a code in VC++ with MFC dialog based.Can any one suggest me where i can found a complete example code (VC++/MFC) to communicate with barcode printer through USB ? Or Please guide me how to startup with some example code.
Pl. Help me.
Thanks in advance.




Dear All,
I have implemented the above code for my Barcode printer and found a problem while debugging.Pls go through the follwing:-

I found a problem here(Not while linking but at the time of debugging).That is my "SetupDiEnumDeviceInterfaces" function is returning fasle,that is why i'm not able to go to the writefile function(which will print).Kindly see the above code.Here i would like to tell you that my printer is right now not connected.Should i connect the printer and try it out? or without printer it will work?Lindly suggest me some solution. i have checked the parameter to the function "SetupDiEnumDeviceInterfaces" ,its correct.Then why this function is returning FALSE.As i mentioned in the above code in "for" loop,but instade of "for" loop i put "while" loop also,but still its not working.


while(TRUE == SetupDiEnumDeviceInterfaces(devs,0,&intfce,index,&devinterface))

{

....
....
}
Its not going inside the while loop.Kindly suggest some solution.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1