Re: implement PeekNamedPipe() for PipeDev/PipeLib

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Re: implement PeekNamedPipe() for PipeDev/PipeLib

Pedro Alves-4
[ Liu, I'm resending for the archives.  I now noticed that the
cegcc-devel@ address wasn't correct --- sourceforge.net bounced.
I was puzzled why your messages weren't showing up in the archives!
(But I do wonder why it didn't bounce before.  Sigh.) ]

On Tuesday 05 January 2010 05:22:23, Liu Yubao wrote:

> Pedro Alves wrote:
> > Ooops, this slipped through the cracks.  Sorry!
> >
> > On Tuesday 13 October 2009 07:50:07, Liu Yubao wrote:
> >> First, thank you for creating this utility library, it help me lot!
> >
> > You're welcome!  Glad it was of use to you.
> >
> >> I have added PeekNamedPipe() to PipeDev/PipeLib code, check it at here:
> >>   http://yabcalc.googlecode.com/svn/trunk/
> >
> > If you post a diff with your changes against the version over at
> > cegcc, it'd be easier to check what we're talking about.  Overwise,
> > I'll try to take a look later on.
> >
> Hi, see the attachment for the patch, if it's garbled by Thunderbird email client,
> you can get a copy at:
> http://jff.googlecode.com/svn/trunk/patches/PipeLib/
>
> The patch is made against r1416 at http://cegcc.svn.sourceforge.net/viewvc/
> cegcc/trunk/cegcc/tools/PipeLib/.
>
> I don't have building environment right now, but it should pass building without problem.
>
> >> Another problem is handles created by PipeLib doesn't supporting WaitForSingleObject()
> >> and WaitForMultiObjects(),  can you add support for these functions ?
> >
> > Hmm, the intention of the the library was to implement unnamed pipes
> > that worked as close as possible to the desktop Windows counterparts.  I
> > don't think you can wait on pipes on Desktop Windows as well.  In any
> > case, I've no idea at present how would one make it work.
> >
> Sorry, in fact I'm not very familiar with Win32/WinCE programming, it's ok
> if WaitForSingleObject()/WaitForMultiObjects() can't be used on pipes on
> Desktop Windows too.

Thank you, the patch looks great!  It applied cleanly and built fine.
I've applied it, with minor formatting tweaks (below), and this
ChangeLog entry:

2010-01-07  Liu Yubao  <[hidden email]>

        Implement PeekNamedPipe.

        * PipeDev.cpp (MapCallerPtr): Declare.
        (class PipeDeviceContext): Add new `peekBytes' method.
        (IOControl): Handle PIPE_IOCTL_PEEK_NAMED_PIPE.
        * PipeDev.h (PIPE_IOCTL_PEEK_NAMED_PIPE): Define.
        (struct PeekStruct): New, moved from PipeLib.cpp.
        * PipeLib.cpp (PeekNamedPipe): Don't #if 0.  Adjust, fix typo and
        and return TRUE on success.
        * PipeLib.h (PeekNamedPipe): Declare.

--
Pedro Alves

---
 PipeDev.cpp |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 PipeDev.h   |   13 ++++++++++++
 PipeLib.cpp |   31 ++++++------------------------
 PipeLib.h   |    3 +-
 4 files changed, 83 insertions(+), 25 deletions(-)

Index: PipeLib/PipeDev.cpp
===================================================================
--- PipeLib.orig/PipeDev.cpp 2008-04-16 23:59:18.000000000 +0100
+++ PipeLib/PipeDev.cpp 2010-01-07 01:04:17.000000000 +0000
@@ -31,6 +31,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE PO
 #include <set>
 #include <string>
 
+extern "C" LPVOID MapCallerPtr(LPVOID ptr, DWORD dwLen);
+
 #ifndef min
 #define min(A, B) ((A) < (B) ? (A) : (B))
 #endif
@@ -353,6 +355,14 @@ public:
     return fit;
   }
 
+  DWORD peekBytes (BYTE* buf, DWORD bsize)
+  {
+    DWORD fit = min (bsize, size ());
+    for (DWORD i = 0; i < fit; i++)
+      buf[i] = buffer[(head + i) & (sizeof (buffer) - 1)];
+    return fit;
+  }
+
 public:
   DWORD OpenCount;
   DWORD WROpenCount;
@@ -935,6 +945,57 @@ IOControl (PipeOpenContext* pOpenContext
       *pdwActualOut = (wcslen (dev->DeviceName) + 1) * sizeof (WCHAR);
       bRet = TRUE;
       break;
+    case PIPE_IOCTL_PEEK_NAMED_PIPE:
+      if (dwLenOut != sizeof (PeekStruct))
+ break; /* unknown version? */
+
+      PeekStruct* data = (PeekStruct *) pBufOut;
+      if (data->dwSize != sizeof (PeekStruct))
+ break; /* unknown version? */
+
+      *pdwActualOut = sizeof (PeekStruct);
+
+      DWORD actual = 0;
+      if (data->nBufferSize > 0 && data->lpBuffer != NULL)
+ {
+  LPVOID lpBuffer = MapCallerPtr (data->lpBuffer, data->nBufferSize);
+  if (NULL == lpBuffer)
+    break;
+
+  actual = dev->peekBytes ((BYTE *) lpBuffer, data->nBufferSize);
+
+  if (data->lpBytesRead != NULL)
+    {
+      LPDWORD lpBytesRead
+ = (LPDWORD) MapCallerPtr (data->lpBytesRead, sizeof (LPDWORD));
+      if (NULL == lpBytesRead)
+ break;
+      *lpBytesRead = actual;
+    }
+ }
+
+      if (data->lpTotalBytesAvail != NULL)
+ {
+  LPDWORD lpTotalBytesAvail
+    = (LPDWORD) MapCallerPtr (data->lpTotalBytesAvail,
+      sizeof (LPDWORD));
+  if (NULL == lpTotalBytesAvail)
+    break;
+  *lpTotalBytesAvail = dev->size ();
+ }
+
+      if (data->lpBytesLeftThisMessage != NULL)
+ {
+  LPDWORD lpBytesLeftThisMessage
+    = (LPDWORD) MapCallerPtr (data->lpBytesLeftThisMessage,
+      sizeof (LPDWORD));
+  if (NULL == lpBytesLeftThisMessage)
+    break;
+  *lpBytesLeftThisMessage = dev->size () - actual;
+ }
+
+      bRet = TRUE;
+      break;
     }
 
   return bRet;
Index: PipeLib/PipeDev.h
===================================================================
--- PipeLib.orig/PipeDev.h 2008-02-08 14:15:04.000000000 +0000
+++ PipeLib/PipeDev.h 2010-01-07 00:42:10.000000000 +0000
@@ -39,6 +39,19 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE PO
 #define PIPE_IOCTL_SET_PIPE_TAG \
  CTL_CODE(FILE_DEVICE_STREAMS, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
+#define PIPE_IOCTL_PEEK_NAMED_PIPE \
+ CTL_CODE(FILE_DEVICE_STREAMS, 2051, METHOD_BUFFERED, FILE_ANY_ACCESS)
+
 #define DEVICE_DLL_NAME L"PipeDev.dll"
 
+struct PeekStruct
+{
+    DWORD dwSize; /* for future extension */
+    LPVOID lpBuffer;
+    DWORD nBufferSize;
+    LPDWORD lpBytesRead;
+    LPDWORD lpTotalBytesAvail;
+    LPDWORD lpBytesLeftThisMessage;
+};
+
 #endif
Index: PipeLib/PipeLib.cpp
===================================================================
--- PipeLib.orig/PipeLib.cpp 2008-02-08 14:15:04.000000000 +0000
+++ PipeLib/PipeLib.cpp 2010-01-07 01:04:34.000000000 +0000
@@ -191,19 +191,6 @@ CreatePipe (PHANDLE hReadPipe,
   return TRUE;
 }
 
-#if 0
-
-struct PeekStruct
-{
-  DWORD Size; /* for future extension */
-  PVOID lpBuffer,
-    DWORD nBufferSize,
-
-    /* TODO: We need to use MapPtr for this to work */
-    LPDWORD lpBytesRead,
-    LPDWORD lpTotalBytesAvail,
-    LPDWORD lpBytesLeftThisMessage
-    };
 
 PIPELIB_API BOOL
 PeekNamedPipe (HANDLE hNamedPipe,
@@ -211,30 +198,26 @@ PeekNamedPipe (HANDLE hNamedPipe,
        DWORD nBufferSize,
        LPDWORD lpBytesRead,
        LPDWORD lpTotalBytesAvail,
-       LPDWORD lpBytesLeftThisMessage
-       )
+       LPDWORD lpBytesLeftThisMessage)
 {
-  DWORD avail;
   DWORD actual;
 
   PeekStruct data;
-  data.Size = sizeof (PeekStruct);
+  data.dwSize = sizeof (PeekStruct);
   data.lpBuffer = lpBuffer;
   data.nBufferSize = nBufferSize;
   data.lpBytesRead = lpBytesRead;
   data.lpTotalBytesAvail = lpTotalBytesAvail;
   data.lpBytesLeftThisMessage = lpBytesLeftThisMessage;
 
-  if (!DeviceIoControl (hNamedPipe, PIPE_IOCTRL_PEEK_NAMED_PIPE,
+  if (!DeviceIoControl (hNamedPipe, PIPE_IOCTL_PEEK_NAMED_PIPE,
  NULL, 0,
- (LPVOID)&data, sizeof (PeekStruct), &actual, NULL))
+ (LPVOID) &data, sizeof (PeekStruct), &actual, NULL))
     return FALSE;
 
-  /* We can detect here if we are talking to an older driver.  */
-  if (actual != data.Size)
+  /* We can detect here if we are talking to an older driver.  */
+  if (actual != data.dwSize)
     return FALSE;
 
-  return FALSE;
+  return TRUE;
 }
-
-#endif
Index: PipeLib/PipeLib.h
===================================================================
--- PipeLib.orig/PipeLib.h 2008-02-08 14:15:04.000000000 +0000
+++ PipeLib/PipeLib.h 2010-01-07 01:08:46.000000000 +0000
@@ -34,10 +34,11 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE PO
 #endif
 
 PIPELIB_API BOOL CreatePipe (PHANDLE,PHANDLE,LPSECURITY_ATTRIBUTES,DWORD);
+PIPELIB_API BOOL PeekNamedPipe (HANDLE,LPVOID,DWORD,LPDWORD,LPDWORD,LPDWORD);
+
 PIPELIB_API BOOL GetPipeName (HANDLE, WCHAR*);
 
 /* Internal, for pipedev.dll debugging purposes.  */
 PIPELIB_API BOOL SetPipeTag (HANDLE, const WCHAR*);
 
-
 #endif

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev 
_______________________________________________
Cegcc-devel mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/cegcc-devel