English 中文(简体)
Windows Named Pipe Problem
原标题:

I m writing a driver that communicates with a userland application through a named pipe. The userland application creates the named pipe by calling CreateNamedPipe() and then passes the pipe name to the driver by invoking an IOCTL. The driver then opens the pipe by calling ZwCreateFile().

The userland application then hits a loop that reads requests from the pipe, processes the requests and writes back the result to the pipe i.e.:

while(1) {
ReadFromPipe
ProcessRequest
WriteToPipe
}

The driver basically writes requests to the pipe and then directly reads back the answer:

WriteRequestToPipe
ReadAnswerFromPipe

My problem is that if the ReadAnswerFromPipe happens in the driver before the WriteToPipe happens in the application, ReadAnswerFromPipe never returns. So basically doing

WriteRequestToPipe
Sleep(10 seconds)
ReadAnswerFromPipe

fixes the problem.

Why am I seeing this?

Clarification: I m using two different unidirectional pipes and the ReadAnswerFromPipe call is never returning although the application eventually successfully calls WriteToPipe...

问题回答

Since named pipes support one-way communication at any given time, you will have to either use 2 pipes (as already suggested) for true asynchronous acces, or synchronize access to a single pipe (like a walkie-talkie). A semaphore object should work well for that. If you just set the Maximum Count parameter of CreateSemaphore() to 1 it will act as a binary semaphore. You can then ZwWaitForSingleObject() on that semaphore inside your while(true) message loop on both your client and server and you will have synchronized access.

Edit: Just remembered you are writing a driver as the server component of this, so you will need the kernel-specific functions and structs, the KSEMAPHORE struct on the driver side.

Pipes are generally taken to be uni-directional communications channels.

I believe that the easiest solution for you would be to create two pipes: one for application→driver messages, and one for driver→application messages.

Not knowing what version of Windows you re writing for, or what development environment you re in, I m not sure this will necessarily help, but it might.

If you re guaranteed to get a response from your user app every time you send the request from your driver, you might consider using the API function TransactNamedPipe() (see this page in the MSDN for full usage documentation).

It is specifically meant to do a send/receive and will wait until a response comes back before returning.

Alternatively, you can use this function in overlapped mode, in which case it will return immediately, after which you wait on an event - that you have to pass in as part of a TransactionOverlapped structure in the original call - to know that you ve received your answer.

It is better to use IOCTL for communication with userland. Why do you need pipes?

ephemient is correct. You could stick with a single pipe but then you d have to synchronise reads and writes between the two ends. The added sleep appears to be working for you as it is allowing the request to be read before the answer is read - but this is error prone as a delay on one end could cause errors.





相关问题
Fastest method for running a binary search on a file in C?

For example, let s say I want to find a particular word or number in a file. The contents are in sorted order (obviously). Since I want to run a binary search on the file, it seems like a real waste ...

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

Tips for debugging a made-for-linux application on windows?

I m trying to find the source of a bug I have found in an open-source application. I have managed to get a build up and running on my Windows machine, but I m having trouble finding the spot in the ...

Trying to split by two delimiters and it doesn t work - C

I wrote below code to readin line by line from stdin ex. city=Boston;city=New York;city=Chicago and then split each line by ; delimiter and print each record. Then in yet another loop I try to ...

Good, free, easy-to-use C graphics libraries? [closed]

I was wondering if there were any good free graphics libraries for C that are easy to use? It s for plotting 2d and 3d graphs and then saving to a file. It s on a Linux system and there s no gnuplot ...

Encoding, decoding an integer to a char array

Please note that this is not homework and i did search before starting this new thread. I got Store an int in a char array? I was looking for an answer but didn t get any satisfactory answer in the ...

热门标签