|
I have some C++ code which is based on WriteFile. To my understanding it uses this method to write: *both* to normal files on my filesystem and to USB also (HASP).
Basically this is the code in the constructor of the C++ class:
if(isOpen) return true ;
char PortNameUNC[256] ;
if(PortName[0] != '\\') strcpy(PortNameUNC, "\\\\.\\") ;
else *PortNameUNC = 0 ;
strcat(PortNameUNC, PortName) ;
*hDev = CreateFile(PortNameUNC, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(*hDev == INVALID_HANDLE_VALUE) return false ;
DCB *dcb = new DCB ;
memset(dcb, 0x00, sizeof(DCB)) ;
dcb->DCBlength = sizeof(DCB);
dcb->BaudRate = BaudRate;
dcb->Parity = Parity;
dcb->StopBits = StopBits;
dcb->ByteSize = ByteSize;
dcb->fBinary = TRUE;
dcb->fDsrSensitivity = 0;
dcb->fDtrControl = (DTR ? DTR_CONTROL_ENABLE : DTR_CONTROL_DISABLE) ;
dcb->fRtsControl = (RTS ? RTS_CONTROL_ENABLE : RTS_CONTROL_DISABLE) ;
dcb->fOutxCtsFlow = (CTS ? 1 : 0) ;
dcb->fOutxDsrFlow = (DSR ? 1 : 0) ;
dcb->fOutX = (XonnXoff ? 1 : 0) ;
dcb->fInX = 0 ;
if(!SetCommState(*hDev, dcb))
{
delete dcb ;
CloseHandle(*hDev) ;
*hDev = INVALID_HANDLE_VALUE ;
return false;
}
delete dcb ;
this->BaudRate = BaudRate;
this->Parity = Parity;
this->StopBits = StopBits;
this->ByteSize = ByteSize;
if(!SetTimeOut(readTimeOut, ReadIntervalTimeout) || !Reset())
{
CloseHandle(*hDev) ;
*hDev = INVALID_HANDLE_VALUE ;
return false;
}
isOpen = true ;
return true ;
And then there is method like write which simply calls `WriteFile` method - and passes the handle created in the constructor and data (I think this way it can write both to USB and my hard drive?)
Why is this `DCB` used additionally and also the `SetCommState` in the constructor?
What is the easiest way to mimic this behaviour in C#??? Do I need `SerialPort` class?
modified 28-Sep-15 9:32am.
|
|
|
|
|
The File[^] class has numerous methods that might suit you. As long as the USB device is mounted as a drive, you should easily be able to write to it using one of the Write... methods.
|
|
|
|
|
Dear Pete, I have changed my question a bit, and would very much appreciate if you can help! Thanks
|
|
|
|
|
"As long as the USB device is mounted as a drive,"
How do I ensure this happens?
|
|
|
|
|
That depends on what the USB device is?
USB is not a port. It is nothing like a serial or parallel port. It is a Bus, not unlike the expansion slots inside the machine. You have to talk to the device using whatever method it exposes to you. If it exposes itself as a serial device, you can use serial communication methods to talk to it. If it exposes itself as some kind of drive, you can use file methods.
|
|
|
|
|
How can I determine if it exposes as serial device or some kind of drive? It is HASP actually
(please see the updated question)
|
|
|
|
|
BY "HASP", I assume you're talking about one of these[^].
From the code you posted, it appears to expose itself as a serial device. The only way to be sure is to contact the manufacturer of it. They may even have a SDK for it to make writing code for it easier.
|
|
|
|
|
Dear Dave, please refer again to my original question. There is no SDK, this C++ project I have establishes communication with it. The only code is the one in constructor (which I posted), and then there is separate method like Write, which calls WriteFile (which I linked) - and I assume data is written either to USB or my file system (because it supports virtual HASPS also which is just file).
So my goal is to port that C++ code (which I posted) to C#. What approach should I take you think?
|
|
|
|
|
You can either rewrite the existing code, P/Invoking the functions the C code is using and rewriting the structures they use in C# (the most complicated way) or you can just rewrite using straight file and serial communication methods (simpler to write but you have no examples to work from). There is no "best" way.
|
|
|
|
|
I understand. So do you suggest:
- If the user has specified to use HASP, I use SerialPort class (from C#) for communication and its methods
- if User has specified file system to use I use just File class from C#
(So I must encapsulate this functionality in class and depending whether user uses HASP or ordinary files, I should perform that functionality inside functions, right? e.g. either ordinary Write versus write to Serial port etc.)
Did I get you correctly?
>> "simpler to write but you have no examples to work from"
What did you mean above?
|
|
|
|
|
user20044 wrote: What did you mean above?
Do you see any examples of using this HASP or the virtual HASP with normal serial and file operation methods? A little Google will tell you that.
|
|
|
|
|
Why would it be any different then using say Serial.Port to do simple read write operations, and in case of virtual HASP, to do read write operations using normal File.Write/Read methods?
|
|
|
|
|
plus isn't the code in my original question example of that? Other methods are just doing plain read/writes, with different number of bytes, etc.
|
|
|
|
|
No, your original code is serial only. What you send and receive over the serial port is the question. Does this key understand commands and responses? What are those commands? I don't need to know that. YOU do.
As for reading the file on disk....OK, you read the file, now what? What do you do with the data?
|
|
|
|
|
Dear Dave, the class I posted is like helper class to help establish communication. As I said it is using WriteFile method from Windows (to read both serial and filesystem, check this function can read both). Once I have a general means to communicate with the serial or file system - e.g., just read write methods - then I can check the functions what data they are sending to the serial, isn't it?
I understand what you mean, but in this class there are only methods like Read. Then some other class is calling this Read and passing parameters; or write thereof. Then I can see what parameters are passed to this serial from those other classes, isn't it?
This class I posted, like I said seems to be helper to send data to the serial or file system. Is it more clear now? Thanks.
|
|
|
|
|
After closer examination of your original post, it's pulling a little trick based on failure. The DCB structure is a Device Control Block[^] used in serial communication. The Win API treats files and serial comm the same, as a stream of data.
What it's doing is taking a path, to either a COM port or a file, and attempts to open that path and setup a DCB. If the DCB application to the CreateFile handle fails, it assumes the path is a file.
As has already been said, you can either use the same C code in C#, rewritten of course, and use the same trick, or you can simplify the code and just ask the user which they are going to use and go with normal SerialPort or File based code.
|
|
|
|
|
" or you can simplify the code and just ask the user which they are going to use and go with normal SerialPort or File based code."
Exactly this was my point. Thank you
|
|
|
|
|
It means I will have to duplicate code right? There are various kind of read write and query methods means I will have to write each separately for File and Serial Port classes, so be it, this is not big issue I guess?
|
|
|
|
|
user20044 wrote: There is no SDK They did when I had to interface with the HASP dongle. You'd first have to find out what you want exactly; write to a serial port, a USB or FileSystem. The C++ code is simply writing to a serial port.
You can do the same from C#, but may be easier to translate to managed C++[^]. Using those methods from C# is also possible, as shown here[^].
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
Well this code should be writing to both USB and file system, because if there is no physical HASP, there is also virtual HASP - which is just file - and that WriteFile can write both to USB(HASP) and file system, isn't it?
In C# code, can't I encapsulate such that if user chooses physical hasp, I use SerialPort class, and if not regular File methods? What do you think?
|
|
|
|
|
user20044 wrote: and that WriteFile can write both to USB(HASP) and file system, isn't it? It can write to different ports as documented.
user20044 wrote: In C# code, can't I encapsulate such that if user chooses physical hasp, I use
SerialPort class, and if not regular File methods? What do you think? If you are trying to convert then go for the File methods. Not the regular ones, the API call that C++ executes.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
As noted above with Dave Kreskowiak I think best is to use File methods if user chose virtual hasp and use Serial.Port if this is physical HASP
|
|
|
|
|
This class Serial Communication in Windows[^] you linked is using exact same approach as code I posted isn't it?
It seems those methods can write both to serial(what I need) and file system.
So, I need C# equivalent.
Can't I do it with Serial.Port class when I need HASP access, and ordinary File methods when I need file system access? I understand I may need to duplicate code, but I think this is easiest for me. What do you think? Thanks.
|
|
|
|
|
I don't think a file is a replacement for the dongle.
Bastard Programmer from Hell
If you can't read my code, try converting it here[^]
|
|
|
|
|
What do you mean? Like I said there are two options:
1. There is physical USB - HASP
2. Virtual HASP- which is just a file
So in 1st case I will use SerialPort, in the second, File methods.
Isn't it?
|
|
|
|