From: sasdxk@skyhawk.unx.sas.com (Dave Kolb)
Subject: Re: DuplicateHandle -- passing handles to other processes
Originator: sasdxk@skyhawk.unx.sas.com
Date: Tue, 10 Nov 1992 14:38:24 GMT
Organization: SAS Institute Inc.


In article <1992Nov10.060432.4835@maccs.dcss.mcmaster.ca>, beame@maccs.dcss.mcmaster.ca (Carl Beame) writes:
|> |> Forgive me if this has already been answered ... but ...
|> |>
|> |> I am trying to pass a handle to a named pipe to a process which I have just
|> |> created. After reading the docs :-), I called DuplicateHandle with
|> |> the GetCurrentProcess() as the source process handle, the handle returned
|> |> to me from the create process call as the destination handle and
|> |> the pipe as the handle to duplicate. The call returned TRUE and filled in
|> |> the new handle ... I passed this new handle to the new process via another
|> |> named pipe ... Using the new handle in the created proceedure fails.
|> |>
|> |> Help ... What am I doing wrong ... (if anything :-) ).
|> |>
|> |> - Carl Beame
|> |> beame@bws.com
|> >
|> >Post your code fragment.  I've coded this but not tested it yet.
|> >--
|> >Dave Kolb                     Opinions are mine not SAS'
|>
|> Well here is the code fragment. This code tries to pass the handle
|> "Remote" to the created process. The interprocess communication does work and
|> the duplicated handle value is correctly passed to the new process, but when
|> the handle is used in the new process it fails:
|>
|> {
|>      STARTUPINFO  sui;
|>      PROCESS_INFORMATION pi;
|>      HANDLE  Local,Remote,newh;
|>      char    my_pipe[40];
|>      int     ret;
|>
|> /* Remote is handle to pass */
|>      Remote = CreateFile("\\\\.\\PIPE\\somepipe", GENERIC_WRITE, 0, NULL,
|>                      OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|> /* Create unique name pipe for this process */
|>      wsprintf(my_pipe,"\\\\.\\PIPE\\myipipe%d",Remote);
|>      Local = CreateNamedPipe (my_pipe,
|>                     PIPE_ACCESS_OUTBOUND               // 1 way pipe.
|>                     | FILE_FLAG_WRITE_THROUGH,        // Use write through.
|>             PIPE_WAIT                         // Wait on messages.
|>                | PIPE_TYPE_BYTE,
|>                PIPE_UNLIMITED_INSTANCES,         // Unlimited instance limit.
|>                0,                                // Buffer sizes.
|>                0,
|>                5000,                         // Specify time out.
|>                NULL);                            // No securities specified.
|>
|>
|>      memset(&sui,0,sizeof(sui));
|>      sui.cb=sizeof(sui);
|>      sui.wShowWindow=SW_SHOWMINNOACTIVE;
|>
|> /* command_line contains the program to run and the string my_pipe to get
|>    the passed handle from. */
|>
|>      CreateProcess(NULL,command_line,NULL,NULL,TRUE,DETACHED_PROCESS,
|>                      NULL,NULL,&sui,&pi));
|>      ConnectNamedPipe(Local, NULL);
|>      DuplicateHandle(GetCurrentProcess(),Remote,pi.hProcess,&newh,
|>              GENERIC_READ,TRUE,DUPLICATE_SAME_ACCESS);
|>      WriteFile(Local,&newh,sizeof(HANDLE),&ret,NULL);
|>      CloseHandle(pi.hProcess);
|>      CloseHandle(pi.hThread);
|>      CloseHandle(Local);
|>      DisconnectNamedPipe(Local);
|> }
|>
|> - Carl Beame

My questions/suggestions are two:

- Does the pipe that CreateFile is opening already exist?  If not you
  don't have a valid handle to pass.

- You need to set the inherit flag in the lpsa security attributes
  data structure when creating the remote handle.

P.S. How does the created process open the local pipe if the remote# is part of
the pipe name and that's what you're trying to pass it?  And why pass it if it
already knows it?  Or why not just have the created process open up the remote pipe?

I guess this is a contrived fragment???

Let us know...

-- 
Dave Kolb                     Opinions are mine not SAS'
SAS Institute, Inc.           EMAIL:      sasdxk@unx.sas.com
SAS Campus Drive - J206       Phone:      (919) 677-8000 x6827
Cary, NC  27513-2414 USA      FAX:        (919) 677-8123