I have a Named Pipe and It Works Fine While I access it using a Client which runs on My System
The Client tries to open the File using following code:
LPTSTR lpszPipename = TEXT("\\\\smyServerName\\pipe\\iPipe01");
hPipe = CreateFile(
lpszPipename, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // default attributes
NULL);
if (hPipe != INVALID_HANDLE_VALUE)
break;
// Exit if an error other than ERROR_PIPE_BUSY occurs.
if (GetLastError() != ERROR_PIPE_BUSY)
{
_tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() );
return -1;
}
While Creating the Named Pipe I have used
lpszPipename = TEXT("\\\\.\\pipe\\iPipe01");
Instead of myServerName I have used .(Dot). I get GLE 5 (Access denied) while I run the client from another system.
First things first - check your permissions and firewall. Almost always, when something works locally but not on the network, it's permissions.
(Had this problem more times than I can count!)
AFAIR there was a change of security of anonymous access to named pipes in Windows Vista.
When you want to open it (with write access) from the anonymous account, you may have to change the pipe's security attributes as described here.
Related
In my current work, we have several threads running simultaneously,
Through one of the thread we have open a file:
std::ofstream fs;
fs.open(filename.c_str(), std::ofstream::out);
if( fs.is_open() ){
// do some file operation and write
fs.close();
}
while a separate thread also access the same file:
HANDLE handle = CreateFileW(filename.c_str(), GENERIC_READ,0, NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
it fails and gives error ERROR_SHARING_VIOLATION.
I know, we can overcome the issue using synchronisation mechanism,
But can we handle it using file sharing mechanism while opening the file, since one thread is using stream API to open the file, while other uses createFile.
Any input is appreciable.
Your CreateFile() call is setting the dwShareMode parameter to 0, so it is trying to open the file for exclusive access, which will fail if the file is already open.
You need to specify sharing rights that are compatible with how the ofstream opens the file, eg:
HANDLE handle = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
I am opening a file with CreateFile on Windows 8 from within a printer filter environment. The code is effectively straight C, even though the filter is built in C++. CreateFile returns INVALID_HANDLE_VALUE but an immediate call to GetLastError returns 0. I have seen this before, back in the old NT4 days (and through to Windows 7) if a directory of the same name as the file existed, a file open attempt would fail with error 0; but I have checked and the file name is different from any subdirectories in the destination directory.
Code:
io_buf[fh].fh = CreateFile(name, GENERIC_READ|GENERIC_WRITE, 0, p_sa,
CREATE_ALWAYS, 0, (HANDLE)0);
io_buf[fh].read_mode = FALSE;
io_buf[fh].file_start = 0L;
io_buf[fh].folder = 0;
if (io_buf[fh].fh == INVALID_HANDLE_VALUE)
{
LogMsg("BufCreate: CreateFile failed (%ld); retrying with SharedWrite\r\n", GetLastError());
io_buf[fh].fh = CreateFile(name, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, p_sa,
CREATE_ALWAYS, 0, (HANDLE) 0);
}
if (io_buf[fh].fh == INVALID_HANDLE_VALUE)
{
LogMsg("BufCreate: CreateFile failed (%ld)\r\n", GetLastError());
return (Vers_FAILURE);
}
LogMsg output:
Render 15:41:46.715: BufCreate: CreateFile failed (0); retrying with SharedWrite
Render 15:41:46.715: BufCreate: CreateFile failed (0)
Because this occurs relatively randomly, sending it to MS would not work; they'd fire it back to me with a "no rep" and I'd get dinged for the SRX. Has anyone got any clue on how I would proceed?
This is vexing. Turns out that I was not writing the file where I thought I was, and that's why it failed. But it should have returned error 5 (Access denied), and I was led up a stump because of this bedamned 0 in GetLastError.
For what it's worth: I had created a path to a temp directory. Because my security context at the time was LocalSystem (I'm in the PrinterPipeline service), that file was in c:\Windows\System32\Services\LocalService\AppData\Local\Temp. No ordinary user can reach that space, and the attempt will quite possibly leave your OS hooped. I had changed to user security context to write to C:\Temp, and was getting a failure because I had forgotten to change my filename to C:\Temp. The error 0 made it look like possibly I was faced with file system redirection mapping c:\temp into LocalService space.
Correcting that so that I was actually writing where I thought I was got rid of the failure... but I still don't understand why Windows was handing me back an error 0.
On the MSDN documentation, see https://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx a sample is shown using anonymous pipes.
In the description can be read:
"...Note that named pipes can also be used to redirect process I/O."
Now, I am struggling to make this happen
For stdin, I do something like
serverPipe = CreateNamedPipe(
szPipeName,
PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
1,
sizeof(TCHAR) * BUFSIZE,
sizeof(TCHAR) * BUFSIZE,
PIPE_TIMEOUT,
lpSa ); //lpSa has its inherited attribute set, just like in the msdn sample.
clientPipe = CreateFile(szPipeName, GENERIC_READ | GENERIC_WRITE, 0, lpSa, OPEN_EXISTING, 0, NULL);
Both pipes create fine, later I close the server (parent process) pipe
CloseHandle(serverPipe);
So the call to ConnectNamedPipe does not return error "there is already a process at the other end of the pipe".
Here is the code for ConnectNamedPipe
do
{
bSuccess = ConnectNamedPipe(serverPipe, &ol);
if (!bSuccess)
{
DWORD dwCode = GetLastError();
if (dwCode == ERROR_NO_DATA) continue;
if (dwCode == ERROR_PIPE_CONNECTED) break;
report_error(NULL);
}
} while (!bSuccess);
The problem is that it always returns error with ERROR_NO_DATA (The pipe is being closed). So never finished the loop.
NOTE: I need to inherit to the child process the handles to the pipes already opened, because I dont have the source of the children and thus cannot change it.
So, can someone point the right way to do this? or the a full working sample using named pipes for IO redirection for a child process using Win32 API?
PS. The reason I need named pipes is because I want to use Overlapped IO, which doesnt seem to be configurable in anonymous pipes.
I have a modem on COM44 and when I try to access it via C++ I end up receiving ERROR_SHARING_VIOLATION. The code I am using is and m_hFile ends up as -1:
void* m_hFile;
m_hFile = ::CreateFile( "\\\\.\\COM44",
GENERIC_READ | GENERIC_WRITE,
NULL,
NULL,
OPEN_EXISTING,
NULL,
NULL );
I have tested access to the modem via Putty and was able to open its comport and send AT commands to it without any problem so I know it works.
The problem ends up not being with the CreateFile code but with the registry code I have above it which determines the com port number to use which I hadn't added because I didn't think it was relevant.
I have written a sample application to read the file from the other file. When I run this application form virtual machine I am getting Access denied. Below is the code.
int _tmain(int argc, _TCHAR* argv[])
{
WCHAR *wcsPath = L"\\\\150.160.130.22\\share\\123.XML";
HANDLE hFile = CreateFileW(wcsPath,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
0,
0);
if (NULL == hFile)
{
printf("failed - %d", GetLastError());
}
return 0;
}
Please let me know any changes.
Error code 5 stands for "Access is Denied". You should check your user's access rights.
I believe the documentation for CreateFile holds the answer.
It may be that your dwShareMode is causing the problem. Using FILE_SHARE_READ there says, "allow other openers to open the file for READ access". If you do not specify FILE_SHARE_WRITE` , then other openers will not be able to open the file for writing - your call would prevent that.
But, CreateFile, I believe, also fails when the sharemode would be violated by prior openers. If this is true, then if another application already has the file open for write access, then your call to CreateFile will fail, if you specify dwShareMode = FILE_SHARE_READ. Do you see? You may need to specify FILE_SHARE_WRITE | FILE_SHARE_READ for that dwShareMode parameter.
Try it.
The error output of CreateFileW() is INVALID_HANDLE_VALUE, not NULL. Now, NULL definitely sounds like a wrong value for a file handle too, but still.
Is the pasted code snippet exactly the content of your program, or a retelling?
EDIT: I see there's a VM involved. Can you open the file in Notepad from the virtual machine where the program is running and erroring out?