Windows Named Pipe is invalid - windows

I have no idea why this pipe is invalid. everything seems fine to me. This is just a test, i don't write or read from it. Anyone can tell me what's wrong?
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#define BUFSIZE 4096
int main()
{
HANDLE hPipe;
LPTSTR Pipename = TEXT("\\\\.\\pipe\\mypipe");
printf("Start Server\n");
for(;;)
{
hPipe = CreateNamedPipe( Pipename,
PIPE_ACCESS_DUPLEX,
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
PIPE_UNLIMITED_INSTANCES,
BUFSIZE,
BUFSIZE,
NMPWAIT_USE_DEFAULT_WAIT,
NULL );
if ( hPipe == INVALID_HANDLE_VALUE )
{
printf("CreatePipe failed");
return 0;
}
CloseHandle(hPipe);
}
return 1;
}

Without more detail about the error it is difficult to help. However, as a general rule create the server using CreateNamedPipe then use ConnectNamedPipe.
On the client side you can now use CreateFile, which ConnectNamedPipe is waiting for on the server side.

Related

Sys V IPC msgsnd(), msgrcv() after fork()

I have a program running on Linux that fork()s after a TCP connection was accept()ed. Before the fork, it connects to a message queue via msgget() and happily sends and receives messages. At some point in the program, both the parent and the child will be waiting at the same time on a msgrcv() using the same msgtype. A separate process then sends a message via msgsnd() using this same msgtype.
However, only one of the forked processes returns from msgrcv(), and it also seems to depend on the path, the parent and the child took. It is very repeatable. In one case, only the parent receives the message, in another case only the child receives the message, leaving the other one waiting infinitely.
Does anyone have a hint on what could go wrong and why not both the parent and the child always receive the message?
I wrote two little test programs, recv.c and send.c, see below.
It turns out that the parent and the child only receive every other message. It seems to be strictly "every other", not even by chance which of the two receives a message. This would very well explain what's happening to my software.
Is this how message queues are supposed to work? Can I not send a message to multiple recipients?
/* recv.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
int main(void)
{
int msgid = msgget(247, 0666 | IPC_CREAT);
pid_t cldpid = fork();
struct msgform
{
long mtype;
char mbuf[16];
} msg;
msg.mtype = 1;
if (cldpid == 0)
{
while(true)
{
printf("Child waiting\n");
msgrcv(msgid, &msg, sizeof(msg), 1, 0);
printf("Child done\n");
}
}
while(true)
{
printf("Parent waiting\n");
msgrcv(msgid, &msg, sizeof(msg), 1, 0);
printf("Parent done\n");
}
return 0;
}
and
/* send.c */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
int main(void)
{
int msgid = msgget(247, 0666 | IPC_CREAT);
struct msgform {
long mtype;
char mbuf[16];
} msg;
msg.mtype = 1;
msgsnd(msgid, &msg, sizeof(msg), IPC_NOWAIT);
return 0;
}
Thanks

what is the Windows equivalent of unix's flock(h, LOCK_SH)?

how do you get a read-lock on Windows? like on Linux you'd do
#include <fcntl.h>
#include <sys/file.h>
int main(int argc, char **argv){
int h=open(argv[0],O_RDONLY);
flock(h,LOCK_SH);
flock(h,LOCK_UN);
close(h);
}
what's the Windows equivalent?
LockFileEx for basic locking. For a very soft lock there are also opportunistic locks.
expanding on #Anders's answer, the answer is LockFileEx, and the type of lock is decided by the dwFlags arguments,
linux=>windows
LOCK_SH => 0
LOCK_EX => LOCKFILE_EXCLUSIVE_LOCK
LOCK_NB => LOCKFILE_FAIL_IMMEDIATELY
the Windows API is quite a bit more complex (and powerful) than the Linux one, allowing you to lock "just parts" of the file, but you're free to effectively lock the whole file by just specifying that you want "the first 18446744073709551615 bytes locked" (meaning you want the first 18.45 exabytes of the file locked...), you're also able to "lock bytes that doesn't exist yet", hence a rough port of the code in the top post would be:
#include <cstdint>
#include <iostream>
#include <windows.h>
int main(int argc, char **argv){
HANDLE handle = CreateFileA(argv[0], GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handle == INVALID_HANDLE_VALUE) {
throw std::runtime_error("CreateFile failed with error " + std::to_string(GetLastError()) + " for " + std::string(argv[0]));
}
const DWORD allBitsSet = ~DWORD(0);
DWORD flags = 0; // LOCK_SH = 0, LOCK_EX = LOCKFILE_EXCLUSIVE_LOCK, LOCK_NB = LOCKFILE_FAIL_IMMEDIATELY
_OVERLAPPED overlapped1 = {0};
_OVERLAPPED overlapped2 = {0};
if (!LockFileEx(handle, flags, 0, allBitsSet, allBitsSet, &overlapped1)) {
throw std::runtime_error("LockFileEx failed with error " + std::to_string(GetLastError()));
}
if(!UnlockFileEx(handle, 0, allBitsSet, allBitsSet, &overlapped2)) {
throw std::runtime_error("UnlockFileEx failed with error " + std::to_string(GetLastError()));
}
CloseHandle(handle);
}

GetThreadSelectorEntry throwing ERROR_NOT_SUPPORTED for x64 App

I trying to write a very simple app to debug a Win32 64-bit app. My end goal is to get the TIB and PEB of the remote thread, but for some reason the way I did this on 32-bit app is not working for 64-bit ones (Aside from looking at Esp vs Rsp and checking SegFs vs SegGs). The code I'm trying to use is here:
#include <windows.h>
#include <stdio.h>
#include <tlhelp32.h>
int main(int argc, char *argv[]){
LDT_ENTRY entry;
DWORD pid;
HANDLE hThread;
HANDLE hSnapshot;
CONTEXT context;
context.ContextFlags = CONTEXT_CONTROL;
if(argc < 2){
printf("Usage: %s PID\n", argv[0]);
exit(1);
}
pid = atoi(argv[1]);
THREADENTRY32 te32;
te32.dwSize = sizeof(te32);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD,0);
while(Thread32Next(hSnapshot, &te32)){
if(pid == te32.th32OwnerProcessID){
hThread = OpenThread(THREAD_ALL_ACCESS, 0, te32.th32ThreadID);
if(!hThread)
exit(1);
if(SuspendThread(hThread) == (DWORD) -1)
exit(1);
if(!GetThreadContext(hThread, &context))
exit(1);
printf("Rsp = 0x%x\n", context.Rsp);
if(!GetThreadSelectorEntry(hThread, context.SegGs, &entry)){
LPSTR buff = NULL;
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL,
GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buff, 0, NULL);
printf("Error: %s\n", buff); //ERROR_NOT_SUPPORTED 50 0x32 The request is not supported.
LocalFree(buff);
exit(1);
}
}
}
CloseHandle(hSnapshot);
return 0;
}
but it's always throwing an error at "GetThreadSelectorEntry". The error code that's thrown is ERROR_NOT_SUPPORTED: The request is not supported.
I am not able to understand why it's not supported. Does anyone know why?
[EDIT]
Okay GetThreadSelectorEntry is not available to x86_64 processes, does anyone know how I can get the TIB/PEB addresses of a remote process?

Weird case of AccessViolation while using overlapped IO in Windows

I've been experimenting with Overlapped IO feature of Win32 API, namely ReadFileEx and WriteFileEx functions.
Here is a simplest example:
#include <iostream>
#include <string>
#include <Windows.h>
const DWORD blockSize = 512;
char buffer[blockSize];
bool done = false;
OVERLAPPED overlapped;
void Completion(DWORD error, DWORD read, LPOVERLAPPED overlapped) {
}
int _tmain(int argc, _TCHAR* argv[])
{
std::wstring fileName;
std::wcout << "Enter file name: ";
std::getline(std::wcin, fileName);
HANDLE file = CreateFile(
fileName.c_str(),
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL
);
if (file == INVALID_HANDLE_VALUE) {
std::wcout << "Error while opening file: " << GetLastError() << std::endl;
std::cin.get();
return -1;
}
overlapped.Offset = overlapped.OffsetHigh = 0;
ReadFileEx(file, buffer, blockSize, &overlapped, (LPOVERLAPPED_COMPLETION_ROUTINE) &Completion);
while (!done)
SleepEx(1000, TRUE);
return 0;
}
As you can see, I'm starting overlapped reading with ReadFileEx and waiting for it to finish using SleepEx. Although Completion has empty body and the program should hang forever after reading first block, it does something completely different. In fact, it raises AccessViolation with code 0xC0000005 on the first call to SleepEx. This happens on Windows machines with Win 7 and Win Vista I've tried, including fresh 64 bit virtual machine with Windows 7. But, curiously, it does not fail on one Windows 8.1 machine and runs just as expected. This was compiled with Visual Studio 2010, but I don't think it matters.
I can not understand what have I done wrong, so if anyone knows the answer, please help me.
The callback must be of the following form, as stated clearly in the documentation:
VOID CALLBACK FileIOCompletionRoutine(
_In_    DWORD        dwErrorCode,
_In_    DWORD        dwNumberOfBytesTransfered,
_Inout_ LPOVERLAPPED lpOverlapped
);
Your function has the wrong calling convention. Your cast does not change that. It is simply a way for you to stop the compiler rejecting your ill-formed program. Don't lie to the compiler. Correct the function declaration by adding the CALLBACK calling convention.

C shell printing output infinitely without stopping at gets()

I am trying to use the SIGCHLD handler but for some reason it prints of the command I gave infinitely. If I remove the struct act it works fine.
Can anyone take a look at it, I am not able to understand what the problem is.
Thanks in advance!!
/* Simplest dead child cleanup in a SIGCHLD handler. Prevent zombie processes
but dont actually do anything with the information that a child died. */
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
typedef char *string;
/* SIGCHLD handler. */
static void sigchld_hdl (int sig)
{
/* Wait for all dead processes.
* We use a non-blocking call to be sure this signal handler will not
* block if a child was cleaned up in another part of the program. */
while (waitpid(-1, NULL, WNOHANG) > 0) {
}
}
int main (int argc, char *argv[])
{
struct sigaction act;
int i;
int nbytes = 100;
char my_string[nbytes];
string arg_list[5];
char *str;
memset (&act, 0, sizeof(act));
act.sa_handler = sigchld_hdl;
if (sigaction(SIGCHLD, &act, 0)) {
perror ("sigaction");
return 1;
}
while(1){
printf("myshell>> ");
gets(my_string);
str=strtok(my_string," \n");
arg_list[0]=str;
i =1;
while ( (str=strtok (NULL," \n")) != NULL){
arg_list[i]= str;
i++;
}
if (i==1)
arg_list[i]=NULL;
else
arg_list[i+1]=NULL;
pid_t child_pid;
child_pid=fork();
if (child_pid == (pid_t)-1){
printf("ERROR OCCURED");
exit(0);
}
if(child_pid!=0){
printf("this is the parent process id is %d\n", (int) getpid());
printf("the child's process ID is %d\n",(int)child_pid);
}
else{
printf("this is the child process, with id %d\n", (int) getpid());
execvp(arg_list[0],arg_list);
printf("this should not print - ERROR occured");
abort();
}
}
return 0;
}
I haven't run your code, and am merely hypothesizing:
SIGCHLD is arriving and interrupting fgets (I'll just pretend you didn't use gets). fgets returns before actually reading any data, my_string contains the tokenized list that it had on the previous loop, you fork again, enter fgets, which is interrupted before reading any data, and repeat indefinitely.
In other words, check the return value of fgets. If it is NULL and has set errno to EINTR, then call fgets again. (Or set act.sa_flags = SA_RESTART.)

Resources