3 #include <QSocketNotifier>
5 #include "qxtnamedpipe.h"
8 #define PIPE_TIMEOUT (120*1000) /*120 seconds*/
10 #include "qxtnamedpipe_win_p.h"
12 void QxtNamedPipePrivate::bytesAvailable()
15 bool fSuccess = false;
20 // Read from the pipe.
22 memset((void *)chBuf,0,BUFSIZE*sizeof(char));
25 this->win32Handle, // pipe handle
26 chBuf, // buffer to receive reply
27 BUFSIZE*sizeof(char), // size of buffer
28 &cbRead, // number of bytes read
29 NULL); // not overlapped
31 if (! fSuccess && GetLastError() != ERROR_MORE_DATA)
34 this->readBuffer.append(QByteArray(chBuf,cbRead));
37 while (!fSuccess); // repeat loop if ERROR_MORE_DATA
42 QxtNamedPipe::QxtNamedPipe(const QString& name, QObject* parent) : QIODevice(parent)
44 QXT_INIT_PRIVATE(QxtNamedPipe);
45 qxt_d().pipeName = name;
46 qxt_d().win32Handle = INVALID_HANDLE_VALUE;
48 qxt_d().serverMode = false;
53 bool QxtNamedPipe::open(QIODevice::OpenMode mode)
55 int m = PIPE_ACCESS_DUPLEX;
56 int m_client = GENERIC_READ | GENERIC_WRITE;
58 if (!(mode & QIODevice::ReadOnly))
60 m = PIPE_ACCESS_OUTBOUND;
61 m_client = GENERIC_WRITE;
63 else if (!(mode & QIODevice::WriteOnly))
65 m = PIPE_ACCESS_INBOUND;
66 m_client = GENERIC_READ;
69 QString pipePrefix("\\\\.\\pipe\\");
71 // first try to open in client mode
72 qxt_d().win32Handle = CreateFileA(qPrintable(pipePrefix+qxt_d().pipeName), // pipe name
73 m_client, // read and write access
75 NULL, // default security attributes
76 OPEN_EXISTING , // opens a pipe
77 0, // default attributes
78 NULL); // no template file
80 //if we have no success create the pipe and open it
81 if (qxt_d().win32Handle == NULL || qxt_d().win32Handle == INVALID_HANDLE_VALUE)
83 qxt_d().win32Handle = CreateNamedPipeA(qPrintable(pipePrefix+qxt_d().pipeName), //pipe Name must be \\.\pipe\userdefinedname
85 PIPE_NOWAIT, //don't block
86 1, //max number of instances 1
87 BUFSIZE, //ouput buffer size allocate as needed
88 BUFSIZE, //input buffer size allocate as needed
89 PIPE_TIMEOUT, //default timeout value
90 NULL); //security attributes
91 if (qxt_d().win32Handle != NULL && qxt_d().win32Handle != INVALID_HANDLE_VALUE)
92 qxt_d().serverMode = true;
96 qxt_d().serverMode = false;
98 DWORD pipeMode = PIPE_NOWAIT;
99 SetNamedPipeHandleState(
100 qxt_d().win32Handle, // pipe handle
101 &pipeMode, // new pipe mode
102 NULL, // don't set maximum bytes
103 NULL); // don't set maximum time
108 if (qxt_d().win32Handle != NULL && qxt_d().win32Handle != INVALID_HANDLE_VALUE)
110 qxt_d().fd = _open_osfhandle((long)qxt_d().win32Handle,0); //FIXME that is not x64 compatible
114 qxt_d().notify = new QSocketNotifier(qxt_d().fd,QSocketNotifier::Read,this);
116 qxt_d().notify->setEnabled(true);
117 connect(qxt_d().notify,SIGNAL(activated(int)),&qxt_d(),SLOT(bytesAvailable()));
118 connect(&qxt_d(),SIGNAL(readyRead()),this,SIGNAL(readyRead()));
128 bool QxtNamedPipe::open(const QString& name, QIODevice::OpenMode mode)
130 qxt_d().pipeName = name;
131 return QxtNamedPipe::open(mode);
134 void QxtNamedPipe::close()
136 if (qxt_d().win32Handle != NULL && qxt_d().win32Handle != INVALID_HANDLE_VALUE)
138 FlushFileBuffers(qxt_d().win32Handle);
139 if (qxt_d().serverMode)
141 DisconnectNamedPipe(qxt_d().win32Handle);
144 qxt_d().notify->setEnabled(false);
145 delete qxt_d().notify;
147 qxt_d().readBuffer.clear();
149 //this will close native and C handle
151 qxt_d().win32Handle = INVALID_HANDLE_VALUE;
154 setOpenMode(QIODevice::NotOpen);
157 QByteArray QxtNamedPipe::readAvailableBytes()
161 while (getChar(&ch)) rv += ch;
165 qint64 QxtNamedPipe::bytesAvailable () const
167 return qxt_d().readBuffer.size();
170 qint64 QxtNamedPipe::readData ( char * data, qint64 maxSize )
172 qint64 toRead = qxt_d().readBuffer.size() < maxSize ? qxt_d().readBuffer.size() : maxSize;
174 memcpy(data,qxt_d().readBuffer.data(),toRead);
175 qxt_d().readBuffer.remove(0,toRead);
181 qint64 QxtNamedPipe::writeData ( const char * data, qint64 maxSize )
183 DWORD bytesWritten = 0;
185 bool fSuccess = WriteFile(
186 qxt_d().win32Handle, // pipe handle
188 maxSize, // message length
189 &bytesWritten, // bytes written
190 NULL); // not overlapped
198 bool QxtNamedPipe::isSequential () const