Announcement

Collapse
No announcement yet.

ConsIn / ConsOut under 9x

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • ConsIn / ConsOut under 9x

    It looks that these functions doesn't work correctly.
    Does anybody know, how to detect redirection to pipes under 9x by normal way (maybe using int 21h or something else) ?



    ------------------

  • #2
    PB/CC 3.x:
    Code:
    IsRedirected = GETSTDOUT <> GetStdHandle (%STD_OUTPUT_HANDLE)
    I qualified the PB/CC version because this is a known bug in PB/CC 3: GETSTDOUT does not return a handle to current STDOUT, it returns a handle to the console created by the program.

    I have no clue if this behavior was corrected in CC4.

    [later]
    Oops, my bad. This is PB/DOS, not PB/CC.

    Which begs the question...

    How do you redirect the STDIN/STDOUT of an MS-DOS program to a pipe? About all I can think of is CreateProcess (commandshell) and redirect the STDOUT of (commandshell)?






    [This message has been edited by Michael Mattias (edited April 25, 2005).]
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      I call Pb-Dos 3.5 program from Pb/Win app.

      Pb-Dos program works in two regims - 'normal' (if to run from Explorer) and 'secret' (if to run from Pb/Win).
      My target is to hide 'secret' regime as possible.
      Just now I used command line, what's I don't like.

      ------------------

      Comment


      • #4
        You can't "call" a program.. I assume you mean you CreateProcess/ShellExecute/SHELL...

        In which case, you could set an enviroment variable prior to launch.. the child process will be inherit the environement, and the environment variable will "die" when the calling process dies or when you reset it on return from the child process.

        Michael Mattias
        Tal Systems Inc. (retired)
        Racine WI USA
        [email protected]
        http://www.talsystems.com

        Comment


        • #5
          Of course, CreateProcess.

          Code:
             Function ShellHiddenConsoleApp (szExeDirectory As String, szExeName As String, szParam As String, szStartDirectory As String, _
                szStdInText As String, szStdOutText As String, ExitCode As Dword) As Dword
          
                Dim BytesRead                               As Local  Dword
                Dim BytesWritten                            As Local  Dword
                Dim dwResult                                As Local  Dword
                Dim fIsNt                                   As Local  Byte
                Dim hChildStdInRd                           As Local  Dword
                Dim hChildStdInWr                           As Local  Dword
                Dim hChildStdOutRd                          As Local  Dword
                Dim hChildStdOutWr                          As Local  Dword
                Dim os                                      As Local  OSVERSIONINFO
                Dim piProcInfo                              As Local  PROCESS_INFORMATION
                Dim saAttr                                  As Local  SECURITY_ATTRIBUTES
                Dim siStartInfo                             As Local  STARTUPINFO
                Dim szBuf                                   As Local  Asciiz * 4096
                Dim szPath                                  As Local  Asciiz * %MAX_PATH
                Dim szTmp                                   As Local  String
          
                szStdOutText = ""
          
                Do
                   ' Set current directory and retrive short path for Exe (to avoid problems with CreateProcess in some OSes)
                   szPath = szExeDirectory
                   If szPath = "" Then GetCurrentDirectory SizeOf(szPath), szPath
                   If Right$(szPath, 1) <> "\" Then szPath = szPath + "\"
                   GetShortPathName szPath + szExeName, szPath, SizeOf(szPath)
                   Replace " " With "" In szPath
                   If szPath = "" Then dwResult = 1: Exit Do
          
                   ' Set the bInheritHandle flag so pipe handles are inherited.
                   saAttr.nLength = SizeOf(SECURITY_ATTRIBUTES)
                   saAttr.bInheritHandle = 1
          
                   ' Create a pipe For the child process's STDOUT.
                   If CreatePipe (hChildStdOutRd, hChildStdOutWr, saAttr, ByVal 0) = 0 Then dwResult = 1: Exit Do
                   ' Create a pipe For the child process's STDIN.
                   If CreatePipe (hChildStdInRd,  hChildStdInWr,  saAttr, ByVal 0) = 0 Then dwResult = 1: Exit Do
          
                   ' Write to StdIn
                   If WriteFile (hChildStdInWr, ByVal StrPtr(szStdInText), Len(szStdInText), BytesWritten, ByVal 0) = 0 Then dwResult = 2: Exit Do
                   If BytesWritten <> Len(szStdInText) Then dwResult = 2: Exit Do      
          
                   '**** Start the program ****
                   siStartInfo.cb = SizeOf(STARTUPINFO)
                   siStartInfo.hStdError  = hChildStdOutWr
                   siStartInfo.hStdOutput = hChildStdOutWr
                   siStartInfo.hStdInput  = hChildStdInRd
                   siStartInfo.wShowWindow  = %SW_HIDE
                   siStartInfo.dwFlags = %STARTF_USESHOWWINDOW Or %STARTF_USESTDHANDLES
          
                   os.dwOSVersionInfoSize = SizeOf(os)
                   GetVersionEx ByVal VarPtr(os)
                   If (os.dwPlatformId = %VER_PLATFORM_WIN32_NT) Then fIsNt = 1
          
                   szTmp = szPath + " " + szParam
                   If fIsNt Then szTmp = Environ$("COMSPEC") + " /c" + szTmp
                   If CreateProcess ("", ByVal StrPtr(szTmp), ByVal 0&, ByVal 0&, 1, _
                      %NORMAL_PRIORITY_CLASS, ByVal 0&, ByVal StrPtr(szStartDirectory), siStartInfo, piProcInfo) = 0 Then
                      dwResult = 3: Exit Do
                   Else
                      WaitForSingleObject piProcInfo.hProcess, %INFINITE
                      GetExitCodeProcess piProcInfo.hProcess, ExitCode
                      CloseHandle piProcInfo.hThread
                      CloseHandle piProcInfo.hProcess
          
                      '**** Read the pipe ****
                      Do
                         szTmp = "End Of Pipe" ' Something unique
                         If WriteFile (hChildStdOutWr, ByVal StrPtr(szTmp), Len(szTmp), BytesWritten, ByVal 0) = 0 Then dwResult = 2: Exit Do
                         If BytesWritten <> Len(szTmp) Then dwResult = 2: Exit Do
                         Do
                            If ReadFile (hChildStdOutRd, szBuf, SizeOf(szBuf), BytesRead, ByVal 0) = 0 Then dwResult = 2: Exit Do
                            If BytesRead = 0 Then Exit Do
                            szStdOutText = szStdOutText + Left$(szBuf, BytesRead)
                            If Right$(szStdOutText, Len(szTmp)) = szTmp Then _
                               szStdOutText = Left$(szStdOutText, Len(szStdOutText) - Len(szTmp)): Exit Do
                         Loop
                         If Len(szStdOutText) Then OemToCharBuff ByVal StrPtr(szStdOutText), ByVal StrPtr(szStdOutText), Len(szStdOutText)
                         Exit Do
                      Loop
                   End If
          
                   Exit Do
                Loop
          
                '*** Close pipe handles ****
                If hChildStdInRd  Then CloseHandle hChildStdInRd
                If hChildStdInWr  Then CloseHandle hChildStdInWr
                If hChildStdOutRd Then CloseHandle hChildStdOutRd
                If hChildStdOutWr Then CloseHandle hChildStdOutWr
          
                Function = dwResult
          
             End Function
          I thought about environment and probably will use this way (better than command line).
          But should be (I hope) direct way, using DOS functions.




          [This message has been edited by Semen Matusovski (edited April 25, 2005).]

          Comment


          • #6
            Might it make a difference if you were not writing to a pipe, versus writing to an 'ordinart' disk file?

            Reason I ask is, the way you are doing this (waiting for the child process to finish before processing its output) there is no real advantage in using a pipe.

            When the child process ends, you could just read the 'ordinary' disk file from start to end. (of course the pipe prohibits access by other processes and eliminates any problems you might encounter were that to occur)

            I think there is an MS-DOS int &h21 service to obtain the (MS-DOS!) handles to stdout, stdin and stderr; but I can't see any function in PB/DOS which would allow you to open that file with a PB handle (like OPEN HANDLE under PB/WIN) and use PB file verbs, so I'm not sure that would get you a whole lot anyway.

            You might be able to do something with the MS-DOS duplicate handle function.. I know I did 'something' with that about ten years ago.. I redirected the MS-DOS stdout from within a PB/DOS program to somewhere else...but that was a long time ago and memory is the second thing to go...


            Michael Mattias
            Tal Systems Inc. (retired)
            Racine WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              ConsIn/ConsOut under 9x do not work with files also. Always - 1 instead of 0.
              Sure, that should be possible to recognize redirection.
              Probably, using IOCTL (2144). But I completely forgot all (last time I wrote low-level MS-DOS program in 1992).

              Why I use pipes ?
              This program tests license files, which linked with hardware.
              I need info, which I can't get in 32-bit app.
              Pipes are used for sequirity reasons.

              Added later.
              Probably I found the solution. Need to test in all OSes and to find explanation, why bit 5 of DX works, unlike expected bit 7.
              Code:
               DefInt A-Z
               If ConsIn = 0 Then
                  i = 1
               Else
                  REG 1, &H4400
                  REG 2, 0
                  Call Interrupt &H21
                  Dx?? = Reg(4)
                  If (Dx?? And &H20) Then i = 1 Else i = 0
               End If
              
              
               If i Then StdOut "StdIn is redirected" Else StdOut "StdIn is not redirected"
              
               If ConsOut = 0 Then
                  i = 1
               Else
                  REG 1, &H4400
                  REG 2, 1
                  Call Interrupt &H21
                  Dx?? = Reg(4)
                  If (Dx?? And &H20) Then i = 1 Else i = 0
               End If
               If i Then StdOut "StdOut is redirected" Else StdOut "StdOut is not redirected"
              
               StdOut "ConsIn=" + Str$(ConsIn)
               StdOut "ConsOut=" + Str$(ConsOut)


              [This message has been edited by Semen Matusovski (edited April 25, 2005).]

              Comment

              Working...
              X