I provide an application developed with Visual C++ to a client and this application works well on my environment. Unfortunately, my client gets an error 22 when _tfopen
is call.
Here is a little snippet who is similar to the code I wrote in this application:
#include "pch.h"
#include <iostream>
#include <stdio.h>
#include <wchar.h>
#include "tchar.h"
FILE* fp;
int openFile(const TCHAR* p, const TCHAR* r)
{
errno_t err = 0;
fp = _tfopen(p, r);
if (!fp)
{
err = errno;
_tprintf(_T("Error %d, can't open file: %s with rights %s"), err, p, r);
}
else
{
printf("All is ok\n");
}
return err;
}
int main()
{
openFile(_T("\\\\127.0.0.1\\hidden_folder$\\folder\\video_file.mxf"), _T("rb"));
return 0;
}
My client gets:
Error 22, can't open file: \\127.0.0.1\hidden_folder$\folder\video_file.mxf with rights rb
Error 22 means EINVAL
for Invalid arguments. But, in my case, the arguments are corrects (according to the log).
What can be the reasons of this behavior?
I tried a lot of things to reproduce this error: remove video_file.mxf, change the location of the file, change the rights of the file, ... It doesn't matter, I never got the error 22.
Notes:
_tfopen
is now deprecated, I also created a version who uses _tfopen_s
, the problem is still there.I followed the idea of @Michael and changed my source code into this one:
#include "pch.h"
#include <iostream>
#include <stdio.h>
#include <wchar.h>
#include <windows.h>
#include "tchar.h"
FILE* fp;
int openFile(const TCHAR* p, const TCHAR* r)
{
errno_t err = 0;
fp = _tfopen(p, r);
if (!fp)
{
err = errno;
_tprintf(_T("Error %d, can't open file: %s with rights %s"), err, p, r);
HANDLE hFile;
hFile = ::CreateFile(path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
_tprintf(_T("GetLastError = %d"), GetLastError());
}
else
{
_tprintf(_T("No error with CreateFile"));
CloseHandle(hFile);
}
}
else
{
printf("All is ok\n");
}
return err;
}
int main()
{
openFile(_T("\\\\127.0.0.1\\hidden_folder$\\folder\\video_file.mxf"), _T("rb"));
return 0;
}
The idea is to continue to use _tfopen
to get a FILE
pointer (used a lot of time in my application) but now to use CreateFile
to get a more precise error code. And it works very well because I got error 1326:
The user name or password is incorrect.
So, now, I can conclude _tfopen
can throw error 22 when it can't log into the remote file server. This error is different of the error 13 (Permission denied) because error 13 means the user is correctly logged.