Serial Port Communication Issues (C code) - c

I recently tried to get access to a serial communication using a Bluetooth usb dongle.
I used the C code below, and keep getting error 5, which is “Access denied”. I am the administrator for the system (which seemed to be the common solution to this problem on the forums) and no other application is accessing the same port I am using (also another common solution). I’m running on a Windows Vista Home Basic 32bit system. I was wondering if anyone had a solution for this
My C code is:
HANDLE hComm;
hComm = CreateFile( _T("\\.\COM3"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hComm == INVALID_HANDLE_VALUE)
printf("Error number: %ld\n", GetLastError());
else
printf("success\n");

I don't know if this is your problem or not, but I suspect you need to escape the backslashes in the path, like so: "\\\\.\\COM3"

That does look like you have to escape your backslashes again. You can also verify that the COM port you're targeting exists on your system by using an object viewer, such as WinObj (http://technet.microsoft.com/en-us/sysinternals/bb896657.aspx), although I don't know if WinObj runs on Vista.

In my experience the backslashes are not needed
hComm = CreateFile( _T("COM3"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

Thanks for the tips but it turns out the bluetooth passkey was not set properly and therefore it was denying access to the serial port.

Just replace your COM# with \.\COM# in your code,
hComm = CreateFile("\\\\.\\COM15",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);

Related

USB VCP connection fails occasionally

My question is quite simple:
I operate 20 CP210x (Silicon Lab) devices over an industrial 20 Port USB Hub.
In one of about 1000 trials to open the port I get a problem: The call to
CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
is blocking and doesn't return. In this case it doesn't help to repeat or to restart my software. Only plugging out/in the device helps.
Of course the port name is including backslashes, as required for higher COM Port numbers. The port is closed without getting an error after each communication by
CloseHandle(comport_p);
I could give more details on my source, but think, that the relevant parts are the mentioned lines. Is there something else I have to consider in my software or could there be a driver problem?

Check if a file is being written using Win32 API or C/C++. I do not have write access myself

Inside a Windows C/C++ programm, I need to process a text file. So I just need to open the file for reading. However, I do not want to do that while the file is still being written to by another process. I also know that this other process will eventually close the file and never write to it agin.
Looking at similar questions on stackoverflow, the typical answer is "try and open the file for writing - if that fails then try again later").
Now in this case, my process does not have write access to the file at all. So checking if the file can be opened for writing is not an option . It will always fail irrespective of any other process having write access or not.
As Hans Passant and Igor Tandetnik said you just need to pass the appropriate sharing flag to CreateFile. As the MSDN documentation for CreateFile says:
FILE_SHARE_WRITE 0x00000002
Enables subsequent open operations on a file or device to request write access.
Otherwise, other processes cannot open the file or device if they request write access.
If this flag is not specified, but the file or device has been opened for write access
or has a file mapping with write access, the function fails.
You'll want to use code like the following:
HANDLE handle = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL,
OPEN_EXISTING, 0, NULL);
if (handle == INVALID_HANDLE_VALUE) {
DWORD errcode = GetLastError();
if (errcode == ERROR_SHARING_VIOLATION) {
printf("%s: sharing violation\n", name);
} else {
printf("%s: CreateFile failed, error code = %lu\n", name, errcode);
}
} else {
printf("%s: CreateFile succeeded\n", name);
}
This code in unable to tell if the ERROR_SHARING_VIOLATION occurred because the other process has the file open for writing or because the another process didn't use FILE_SHARE_READ when opening the file. In the later case any attempt to read from the file will fail with a sharing violation. The FILE_SHARE_READ flag is passed to prevent sharing violations in the case when the file already been opened and FILE_SHARE_READ was used. You could also add FILE_SHARE_DELETE but I assume you'd consider that the same as write access.

Serial COM Port not opening

I am trying to open the serial COM PORT in a Win32 Application. The port is opening correctly but I can send a receive bytes just if I previously opened it using Teraterm or Hyperterminal.
If I deactivate and activate the COM port from Device Manager (so the port is freshly unused) I need to simply open the COM port with Teraterm or Putty and afer I closed it and then run my software I can send and receive properly at anytime.
I am using Embarcadero X3 with FileMonkey to make the application compatible with MACOSX and Win32 at the same time. FileMonkey does not suuport VCL.
The same code is working fine on Builder 6 c++ using VCL but it should not influence it in anyway. My code is really simple.
This is a very weird behavior. Seems like I need to INIT the COM (I am using FTDI converter) before I can use it and when the PC restarts or I deactivate and activate back the COM from Device Manager it seems this INIT is vanished and I simply need to open up the COM to revive it using another Serial Software and then use my software.
Note: Once the port is INIT I have the full control from my software. I am sure my code is truly opening the COM port because the COM appears busy once the iNIT is done if I try to use it with other softwares. So no flase alarm and more the application is working on the other side so far.
I have this problem since long and I now decided to solve it!
This is my code:
// GLOBAL VARIABLES
HANDLE hComm = NULL;
COMMTIMEOUTS ctmoNew = {0}, ctmoOld;
DCB dcbCommPort;
hComm = CreateFile("COM2",
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,
0);
if(hComm == INVALID_HANDLE_VALUE)
{
Application->Terminate();
}
GetCommTimeouts(hComm,&ctmoOld);
ctmoNew.ReadTotalTimeoutConstant = 100;
ctmoNew.ReadTotalTimeoutMultiplier = 0;
ctmoNew.WriteTotalTimeoutMultiplier = 0;
ctmoNew.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(hComm, &ctmoNew);
dcbCommPort.DCBlength = sizeof(DCB);
GetCommState(hComm, &dcbCommPort);
BuildCommDCB("115200,N,8,1", &dcbCommPort);
SetCommState(hComm, &dcbCommPort);
Just a possibility, not certain that this is the problem.
But one difference to our typical COM port opening code is that we use SetupCom directly after the CreateFile succeeded and set our buffer sizes, typically 4KB.
Change your settings to:
"115200,NOPARITY,8,ONESTOPBIT"

WinAPI Named Pipe location

HANDLE pipe = CreateFile( L"\\\\.\\pipe\\my_pipe",
GENERIC_READ, // only need read access
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
I'm new to win api and i'd like to know where is the "my_pipe" file created on the hard disk?
I can't find it anywhere near the binary or sources
Windows doesn't follow the UNIX philosophy "everything is a file", so the named objects you create with the kernel APIs aren't files, but are objects in various NT objects namespaces. You can see them with tools like WinObj.
You may want to have a look at the article about the object manager in Windows.

Waiting until a file is available for reading with Win32

I'm watching a directory by calling ReadDirectoryChangesW synchronously. When a new file is available, I try to access it immediately with CreateFile with GENERIC_READ and FILE_SHARE_READ, but this gives me ERROR_SHARING_VIOLATION. The process that put the file in the watched directory does not finish writing by the time I try to read it.
Is there any way to reliably wait until the file is available for reading? I can put the method into a loop like the one below, but I'm hoping there's a better way.
while ((hFile = CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_SHARING_VIOLATION)
Sleep (500);
else
break; // some other error occurred
}
if (hFile == INVALID_HANDLE_VALUE)
{
// deal with other error
return 0;
}
ReadFile (...);
I don't think there is a notification for the kind of event you're looking for, but as an improvement, I'd suggest progressive delays. This way you will get fast response times for stuff like a drag/drop and won't hog the CPU with a tight loop if the user keeps the file open for an hour in Excel.
int delay= 10;
while ((hFile = CreateFile (path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
{
if (GetLastError() == ERROR_SHARING_VIOLATION) {
Sleep (delay);
if (delay<5120) // max delay approx 5.Sec
delay*= 2;
}
else
break; // some other error occurred
}
There's no user-mode API for notifications on a closed file that I'm aware of. The loop you've proposed is really probably the best way. The only other thing you could do would be to watch for CloseFile in a filter driver ala Process Monitor, but yuck...
As #Matt Davis said, there is unfortunately no user-mode API but there is a workaround that depending on your use-case (I've written mine below) may do just what you want.
What worked for me in the past was registering for FILE_NOTIFY_CHANGE_LAST_WRITE instead of FILE_NOTIFY_CHANGE_FILE_NAME when calling ReadDirectoryChangesW:
ZeroMemory(&overlapped, sizeof(OVERLAPPED));
overlapped.hEvent = hChangeEvent;
// ...
ReadDirectoryChangesW(hSpoolPath,
eventBuffer,
EVENT_BUF_LENGTH,
FALSE,
FILE_NOTIFY_CHANGE_LAST_WRITE, // <----
NULL,
&overlapped,
NULL);
// ...
HANDLE events[2];
events[0] = hChangeEvent;
events[1] = hCancelEvent;
DWORD wRc = WaitForMultipleObjects(2, events, FALSE, DIRECTORY_WATCH_TIMEOUT);
The last write time gets updated as soon as the owning process closes the handle after creating the file and writing to it.
My use-case was one process that received HTTP-requests via TCP/IP and wrote the HTTP-body into a directory, where another process picked it up as soon as the receiving process was finished writing (and consequently closing the handle) it. The http-server was the only process that wrote to that directory, so I could rely on the create-write-close pattern.
If you know something about how the file is created, maybe wait until the file stops growing for X seconds, or wait until a sentinel file is deleted. Or sense the state of the program which creates them.

Resources