You are not logged in. You can browse in the PowerBASIC Community, but you must click Login (top right) before you can post. If this is your first visit, check out the FAQ or Sign Up.
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) ?
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).]
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.
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.
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).]
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...
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).]
We process personal data about users of our site, through the use of cookies and other technologies, to deliver our services, and to analyze site activity. For additional details, refer to our Privacy Policy.
By clicking "I AGREE" below, you agree to our Privacy Policy and our personal data processing and cookie practices as described therein. You also acknowledge that this forum may be hosted outside your country and you consent to the collection, storage, and processing of your data in the country where this forum is hosted.
Comment