Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Laurence Pithie

Pages: 1 2 [3] 4 5
31
Programming / Re: different types of keyboard input in cmd.exe
« on: February 20, 2020, 05:37:15 pm »
CON is the virtual file name. Child processes inherit the open file handles of the parent so opening CON read write in the parent process with the appropriate mode befire calling DosExecPgm should be inherited by the cmd.exe process.

32
Programming / Re: different types of keyboard input in cmd.exe
« on: February 19, 2020, 07:18:21 pm »
There's another case that you'll have to handle that COPY CON will not.
Code: [Select]
COPY filename.txt CON

33
Quote
even if it was just the reality of IBM clones which became the personal computer as we know it now.
That had very little to do with IBM, I think it was Compaq who did the clean room reverse engineering of the IBM PC bios which allowed the IBM PC to be cloned.

34
Programming / Re: different types of keyboard input in cmd.exe
« on: February 19, 2020, 01:53:42 pm »
Quote
My question concerns the type (3) "COPY CON": I need to interpretate the command which the user types behind the prompt. My first idea is to search for "<space>CON<space>" ?
You'll need to search for COPY followed by CON because there are other contexts in which CON is used (redirection for example). Doing that in a robust way is going to require dealing with an arbitrary number of spaces and text (filenames for example)  between the COPY and the CON so I would suggest using a regular expression.

However the command shell expects line oriented input, so if you send a line containing COPY CON then the shell will then read input on stdin line by line and echo that input on stdout, up until  it receives an EOF, which you're writing and reading stdin and stdout already anyway.

If what you wish to do is send an arbitrary block of text, possibly containing newlines, as an argument to an arbitrary command then I would suggest using a separate command to do that. Something along the lines of a send marked block command.

If you are doing all this command line processing before sending a line to the command processor you're not really creating a command line front end, you are implementing half a command processor and  duplicating  functions that the shell already implements. If that's what you want to do then you should look at examples of scanners and parsers. In the C world there are tools for creating these, Lexx and Yacc (Flex and Bison) Free Pascal comes with Plex and Pyacc. Using specialised tools for this is advisable because, while creating a scanner and parser isn't complicated it's not trivial , and creating an efficient scanner and parser is definitely not an exercise for the faint of heart. 

35
Programming / Re: Manipulating a PM window from another program
« on: February 18, 2020, 02:34:14 pm »
To disable the close menu option in the system menu you can send  a MIA_DISABLED message to the system menu.

Code: [Select]
hw = WinWindowFromID(VIOhandle, FID_SYSMENU);
WinSendMsg(hw, MM_SETITEMATTR,
         MPFROM2SHORT(SC_CLOSE, TRUE),
         MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED));

However, you still need to handle keyboard shortcuts like ctl-F4 as well. I would suggest   subclassing the VIO window (WinSubclassWindow) and handling WM_CLOSE and WM_SIZE messages sent  to the VIO window in a custom window procedure. That would allow you to do anything from simply ignoring the WM_CLOSE message to customized close procedures. You can also control which frame controls are created if you do this using a WmCreateFrameControls call in the WM_CREATE processing rather than deleting the frame control windows.

36
Programming / Re: Manipulating a PM window from another program
« on: February 17, 2020, 02:18:13 pm »
To disable a window use the WinEnableWindow call with the handle of the window you wish to disable as the first parameter and FALSE as the second parametert. To get the window handle of the control windows use WinWindowFromID with the Frame window handle as the first parameter and the window id of the control window as the second parameter. So to disable and hide the minimize and maximize control window you would use
Code: [Select]
hwnd = WinWindowFromID(hwndParent, FID_MINMAX);
WinEnableWindow(hwnd, FALSE);
WinShowWindow(hwnd, FALSE);
The identifier for the system menu is FID_SYSMENU.
To remove the windows instead of disabling and hiding them then call WinDestroyWindow.
However, given that the VIO window has standard input and standard output redirected(If you're interested in stderror you could redirect that as well) it's not really going to be showing anything of interest so it would be simpler to simply hide the entire window. To prevent the user from closing it from the window list you'd need to get the Switch entry handle for the window and then remove it from the switch list using WinQuerySwitchHandle and WinRemoveSwitchEntry.



37
My apologies, I didn't read your orignal post properly. The problem occurs when the client program calls DosOpen. It sounds like a race condition, The server creates the pipe and then calls DosConnectNPipe to put it into a listening state. If the client program calls DosOpen before the DosConnectNPipe call completes the client will get an ERROR_PIPE_BUSY returned from the call to DosOpen. You can either check for the error and issue a DosWaitNPipe call or synchronose the pipe setup in the server with the opening of the pipe in the client using a semaphore.

38
In regard to parsing the prompt the simplest solution is to set the prompt to a known state at the start of the session and prevent the user from changing it during the session.

39
You only have to use DosClose in the server because threads in the process that creates the pipe have access to it and don't need to call DosOpen. DosDisconnectNPipe doesn't deallocate the pipe, which is why it can be reopened with another call to DosConnectNPipe without haveing to call DosCreateNPipe to recreate it. .
Quote
DosDisConnectNPipe is issued by a server process to acknowledge that a client process has closed a named pipe. (If a client process tries to issue DosDisConnectNPipe, ERROR_BAD_PIPE is returned.) The pipe cannot be opened by another client process until the server process issues this function, followed by DosConnectNPipe.

Quote
But the PM editor has to know whether to send each keyboard user input character to cmd.exe immediately (within a sub program) or (prompting/idle) to wait until the user presses Enter.
If it's using standard i/o then it doesn't matter whether the editor waits for the enter key to be pressed before sending the character, If it's doing single character i/o and you send it a line of characters then they'll be buffered for subsequent reads, if it's only expecting a single character input then it should ignore the enter key, and if it's not flushing the input buffer before each read then that's a bug. If it's using Vio calls to read character strings then you can't use it from a pipe.

So, if you've got a prompt Y/N and you send "Y\n" the newline "\n"  should be discarded by the calling program.

40
Quote
- Problem with named pipes error 231 "pipe busy" when DosOpen
Generally you should check for this error and issue a DosWaitNPipe on reciept of this error followed by another call to DosOpen.
Quote
DosClose in the helper program of the previous session also returns 0
Are you issuing a DosClose call on the pipe from the server application?
Quote
Named-Pipe Considerations

DosClose closes a named pipe by handle. When all handles that refer to one end of a pipe are closed, the pipe is considered broken.

If the client end closes, no other process can reopen the pipe until the serving end issues DosDisConnectNPipe, followed by DosConnectNPipe.

If the server end closes when the pipe is already broken, the pipe is immediately deallocated; otherwise, it is not deallocated until the last client handle is closed.

The pipe isn't deallocated until both server and client handles are closed.

Quote
Or I need a very intelligent interpretation of the proposed prompt string?)
Isn't the user seeing the contents of stdout?

41
For a rexx script check for the two charactee /* as the first two characters in the cmd file. You can extend this to other intepreted scripts by checking whether extrpoc or #!(4OS2 extension if the UnixPaths option is enabled) are the first characters in athe command fiile. and that is followed by the name of the external processor, perl, python, etc.

42
Quote
I  want to capture the VIO calls cmd.exe sends to the PM window or to the screen (fullscreen) when e.g. a user types "mode" or "cls".
To capture the indivdual calls you'd need to enable debugging in the call to DosExecPgm by setting the execFlag to EXEC_TRACE and using DosDebug to trace the execution of the process. I'm pretty sure this is not what you want to do, It dependson the debugging symbols being available for the executable and/or the ability to identify the assembly langage calls to the vio functions.

Quote
The problem I have is that I see the user input in the editor of course and the editor can interpretate these command by itself, but when cmd.exe executes a cmd file which holds "mode" or "cls", it won't get interpretated by the editor.
This is simpler, check for a .cmd extension then load the cmd file into a buffer and interpret it line by line and once you've done that send the cmd file to the cmd process. Implementing a full cmd file interpreter is non trivial,  but if you are only interested in specifc commands then it can be simplified to a straight word search.

43
Quote
(5) works now. I have indeed to pass the argument "cmd\0 /K" instead of "/K". The error message has vanished now. Does that mean that two instances of cmd.exe are executed?
No there's only one instance of the command shell,  It's a convention in C that the first entry in the array of command parmaters passed to a program is the name of the command. argv[0]. The called program skips the first parameter if it's the name of the called and reads the rest of the paramters. If the first parameter isn't the name of the shell then it treats it as an external command. If there are no parameters to pass then you can pass a null string and you won't get an error.

Quote
Of course I can read stdout, and this works fine already. My query relates to the other stuff which is sent to the PM window like changing the size with "mode" or deleting the screen buffer with "cls" and so on.
Write the commands you are sending to stdin to a log file in addition to sending them to stdin. Or are you asking how to capture the return code from the command you are sending to stdin? In which case check the %ERRORLEVEL% value immediately after issuing the command.

44
Here's a hello world example of overlaying vio and std i/o

45
Quote
) It would be interesting to see the communication between cmd.exe and the PM window where cmd.exe is executed. Is there any way to read/redirect this information? (I have no idea what to do with this information yet, but it could be useful.)
As you are reading and writing texts strings to/from the pipe do an additional write of the same strings to a log file after reading/writing them to/from the pipe is probably the simplest method.
Quote
(3) I have found an old OS/2 1.X program which simply shows a colored directory tree (see attachment). This program does not generate ANSI ESC sequences, but has normal stdout. In cmdme, it is shown without colors. I do not understand how it can show colors, support stdout and does not generate ANSI ESC sequences.
It's probably mixing standard i/o and vio calls. and overlaying one on top of the other. So you would get colour output on a terminal and plain text if the output was redirected.

Quote
(4) Where do I find a description of cmd.exe keyboard input? (E.g. cursor up restores old input, Ctrl-C breaks and so on). "help cmd" shows only the commands you can type.
The KEYS command implements command line editing.
Quote
SYS1034: The system cannot find the command processor in the path specified.
OS/2 Command Interpreter version 4.5
The first of the ASCIIZ strings passed as an argument to DosExecPgm should be the name of the command interpreter, "cmd\0" of "40s2\0"  for the os2 command intepreter and 4OS2 respectively. Otherwise it treats the first command you pass as the name of the program to load, which, if it an internal command or an option paramter (DIR or /K for example) you'll get a command not found error


Pages: 1 2 [3] 4 5