home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / DOSSYS.ZIP / CALLDOS.TXT
Text File  |  1990-09-12  |  12KB  |  387 lines

  1. ==========================
  2. ibm.os2/long.messages #200, from jgilliland, 11358 chars, Wed Sep 12 09:55:43 19
  3. 90
  4. --------------------------
  5. TITLE: OS/2 1.2 DOS.SYS interface
  6. Yet another of OS/2's mysteries has been unraveled.  OS/2 1.2 allows the
  7. Task Manager to initiate programs in the DOS box, but does not document
  8. the mechanism that is used, so it has not been possible to do the same
  9. thing from other applications.  Here is set of messages from the FidoNet
  10. OS/2 echo that documents the DOS.SYS driver interface that performs this
  11. magic, and sample code to show its use.  You'll also find a paragraph
  12. from Peter Fitzsimmons describing how he figured this all out.
  13.  
  14. Credit goes to Peter Fitzsimmons for doing the original research, and to
  15. Bill Andrus for tying together the loose ends and creating a usable
  16. program out of it.
  17.  
  18.  
  19.  
  20. 309/366 09 Sep 90 08:12:06
  21. From:   Peter Fitzsimmons
  22. To:     All
  23. Subj:   new trick
  24. Attr:
  25. ------------------------------------------------
  26.  
  27. I've figured out a little bit about DOS.SYS....
  28.  
  29. This little sample program uses DOS.SYS to change to C:,  change to \OS2, and
  30. run "edlin \config.sys".
  31.  
  32. When you Q)uit edlin, the session that was in the foreground prior to flipping
  33. to the dos box (not nec the session that 2dos.exe was running in) is restored
  34. to the foreground.
  35.  
  36. I have not yet figured out how to reboot through DOS.SYS -- but this is an easy
  37. thing to code yourself (such a program is included with Maximus).
  38.  
  39. -[2dos.c beings]----------------------------------
  40.  
  41.  #include <stdio.h>
  42.  #include <string.h>
  43.  #include <stdlib.h>
  44.  #define INCL_DOS
  45.  #define INCL_DOSERRORS
  46.  #define INCL_WINSWITCHLIST
  47.  #include <os2.h>
  48.  
  49.  void jump2dos(void);
  50.  
  51.  static char *cmd = "\x80 C:\r"
  52.                     "\x80 CD\\OS2\r"
  53.                     "\x80 edlin \\config.sys\r";
  54.  
  55.  void cdecl main(void)
  56.  {
  57.      HFILE hf;
  58.      USHORT rc, dummy;
  59.  
  60.      rc = DosOpen("DOS$", &hf, &dummy, 0L, FILE_NORMAL, FILE_OPEN,
  61.          OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE |
  62.          OPEN_FLAGS_FAIL_ON_ERROR, 0L);
  63.      if(!rc){
  64.          rc = DosWrite(hf, cmd, strlen(cmd)+1, &dummy);
  65.          DosClose(hf);
  66.          if(!rc)
  67.              jump2dos();
  68.          else if(rc == ERROR_NOT_READY)
  69.              printf("A program is already running in the DOS box\n");
  70.          else
  71.              printf("Unexpected OS/2 error SYS%04u\n", rc);
  72.      }
  73.      else
  74.          printf("DOS.SYS not installed (sys%04u)\n", rc);
  75.      DosBeep(1000, 100);
  76.  }
  77.  
  78.  void jump2dos(void)
  79.  {
  80.      USHORT num, i;
  81.      void *buf = malloc(32000);
  82.      SWENTRY *swe;
  83.      HSWITCH fgHandle;
  84.      SEL selGlobalSeg, selLocalSeg;
  85.      GINFOSEG FAR * volatile pgis;
  86.      UCHAR sgDos;
  87.  
  88.      /* find out who is in the foregound,  so we know who to switch
  89.       * back to after the dos box is done.  This method only works
  90.       * if the foreground session is NOT a pm program.  If it is a
  91.       * pm program,  the "Task List" will be the active app after
  92.       * the task switch
  93.       */
  94.      DosGetInfoSeg(&selGlobalSeg, &selLocalSeg);
  95.      pgis = MAKEPGINFOSEG(selGlobalSeg);
  96.      fgHandle = WinQuerySwitchHandle(0L, pgis->pidForeground);
  97.  
  98.      /* Find the switch list handle of the DOS box: */
  99.      num = WinQuerySwitchList(0L, buf, 32000);
  100.      swe = (SWENTRY *)((USHORT *)buf + 1);
  101.      for(i=0; i<num; i++){
  102.          if(!strcmp("DOS", swe[i].swctl.szSwtitle)){
  103.              WinSwitchToProgram(swe[i].hswitch);
  104.              break;
  105.          }
  106.      }
  107.      free(buf);
  108.      if(i==num){
  109.          printf("This system is configured without a dos box!\n");
  110.          return;
  111.      }
  112.      if(fgHandle){
  113.          DosSleep(100L);     /* give a moment for the task switch */
  114.          sgDos = pgis->sgCurrent;
  115.  
  116.          /*
  117.           * Wait (poll) current screen group -- waiting for the DOS
  118.           * program to end.  I don't like polling,  but this is the only
  119.           * solution I can come up with.  If you don't mind the "Task
  120.           * List" always being brought the the fore after the dos progam
  121.           * ends,  you can forget about all of this and exit() after the
  122.           * WinSwitchToProgram(), above.
  123.           */
  124.  
  125.          while( sgDos == pgis->sgCurrent )
  126.              DosSleep(500L);
  127.  
  128.          WinSwitchToProgram(fgHandle);   /* back to where we started */
  129.      }
  130.  }
  131.  
  132.  #if 0
  133.  
  134.  Comments
  135.  --------
  136.  
  137.  The only reason this program works is becuase WinSwitchToProgram()
  138.  allows you to:
  139.  
  140.      1) Switch a session to the foreground which is not one of your own
  141.         child sessions.
  142.  
  143.      2) Switch a session to the foreground when you are not running
  144.         in the foreground yourself.
  145.  
  146.  Acording to the documentation (IBM, v1.20),  you are not supposed to
  147.  be able to do either of these things.  However,  the "File Manager",
  148.  from what I can figure out,  uses this method to switch to the DOS
  149.  box too,  so I am confident that this program will continue to work
  150.  under OS/2 1.2x.
  151.  
  152.  Peter Fitzsimmons, A:WARE Inc. Thu  09-06-1990  22:15:11
  153.  #endif
  154.  
  155. -[2dos.c ends]----------------------------------
  156.  
  157. --- Maximus-CBCS v1.02-OS/2-r2
  158.  * Origin: Pete's Point (1:250/628.1)
  159.  
  160.  
  161. 311/366 09 Sep 90 08:12:29
  162. From:   Peter Fitzsimmons
  163. To:     All
  164. Subj:   new trick part 2
  165. Attr:
  166. ------------------------------------------------
  167.  
  168. And here is how to reboot via dos.sys:
  169.  
  170. ----[reboot.c begins]----
  171.  
  172.  #include <stdio.h>
  173.  #define INCL_DOS
  174.  #include <os2.h>
  175.  
  176.  void cdecl main(void)
  177.  {
  178.      HFILE hf;
  179.      USHORT rc, dummy;
  180.  
  181.      rc = DosOpen("DOS$", &hf, &dummy, 0L, FILE_NORMAL, FILE_OPEN,
  182.          OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE |
  183.          OPEN_FLAGS_FAIL_ON_ERROR, 0L);
  184.      if(!rc){
  185.          DosShutdown(0L);
  186.          DosDevIOCtl(NULL, NULL, 0xab, 0xd5, hf);        /* reboot */
  187.          DosClose(hf);
  188.      }
  189.      else
  190.          printf("DOS.SYS not installed (sys%04u)\n", rc);
  191.  }
  192. ----[reboot.c ends]------
  193.  
  194. How did I figure all of this DOS.SYS stuff out, you ask?  I wrote my own DOS$
  195. device driver,  and simply had it report what the programs that use the real
  196. DOS$ (boot.com, pmfile.exe) were trying to do with it.  (I was bored one day at
  197. work).
  198.  
  199. Pete.
  200.  
  201. --- Maximus-CBCS v1.02-OS/2-r2
  202.  * Origin: Pete's Point (1:250/628.1)
  203.  
  204.  
  205. 361/366 10 Sep 90 23:14:13
  206. From:   Bill Andrus
  207. To:     Peter Fitzsimmons
  208. Subj:   new trick part 3
  209. Attr:
  210. ------------------------------------------------
  211. Okay, here's the complete program that everyone says can't be done with the
  212. current documentation:
  213.  
  214. === CALLDOS.C ========================================================
  215.  
  216. /* Compiles with IBM C/2 1.1 and its MAKE/2 2.0 using:
  217.  
  218. ###############################################################
  219. #  Make file for CALLDOS.C                                    #
  220. #                                                             #
  221. #  use MAKE CALLDOS.C                                         #
  222. #                                                             #
  223. ###############################################################
  224. model=S            # use large model when debugging -- bugs JUMP out at you
  225. mode=p
  226. linklibs=$(model)libce$(mode).lib os2.lib
  227. CFLAGS=-A$(model) -Lp -Oxrn -Zpel -W3 -G2 -Gw -J -nologo
  228. LINK=D:\C\Bin\Link
  229.  
  230. calldos.exe : calldos.obj
  231.  $(LINK)
  232. calldos.obj,calldos.exe/A:16/FAR/NOD/PACKD/ST:3000,NUL.MAP,$(linklibs);
  233.  
  234. calldos.obj : calldos.c
  235.  !CL $(CFLAGS) -c $?
  236.  
  237. */
  238.  
  239. /* Merge of Peter Fitzsimmons' CALLBOX.C and 2DOS.C programs */
  240.  
  241. #include <stdio.h>
  242. #include <string.h>
  243. #include <stdlib.h>
  244. #define INCL_DOS
  245. #define INCL_DOSERRORS
  246. #define INCL_WINSWITCHLIST
  247. #include <os2.h>
  248.  
  249. void jump2dos(void)
  250. {
  251.     USHORT num, i;
  252.     void *buf = malloc(32000);
  253.     SWENTRY *swe;
  254.     HSWITCH fgHandle;
  255.     SEL selGlobalSeg, selLocalSeg;
  256.     GINFOSEG FAR * volatile pgis;
  257.     UCHAR sgDos;
  258.  
  259.     /* find out who is in the foregound,  so we know who to switch
  260.      * back to after the dos box is done.  This method only works
  261.      * if the foreground session is NOT a pm program.  If it is a
  262.      * pm program,  the "Task List" will be the active app after
  263.      * the task switch
  264.      */
  265.     DosGetInfoSeg(&selGlobalSeg, &selLocalSeg);
  266.     pgis = MAKEPGINFOSEG(selGlobalSeg);
  267.     fgHandle = WinQuerySwitchHandle(0L, pgis->pidForeground);
  268.  
  269.     /* Find the switch list handle of the DOS box: */
  270.     num = WinQuerySwitchList(0L, buf, 32000);
  271.     swe = (SWENTRY *)((USHORT *)buf + 1);
  272.     for(i=0; i<num; i++){
  273.         if(!strcmp("DOS", swe[i].swctl.szSwtitle)){
  274.             WinSwitchToProgram(swe[i].hswitch);
  275.             break;
  276.         }
  277.     }
  278.     free(buf);
  279.     if(i==num){
  280.         printf("This system is configured without a dos box!\n");
  281.         return;
  282.     }
  283.     if(fgHandle){
  284.         DosSleep(500L);     /* give a moment for the task switch */
  285.         sgDos = pgis->sgCurrent;
  286.  
  287.         /*
  288.          * Wait (poll) current screen group -- waiting for the DOS
  289.          * program to end.  I don't like polling,  but this is the only
  290.          * solution I can come up with.  If you don't mind the "Task
  291.          * List" always being brought the the fore after the dos progam
  292.          * ends,  you can forget about all of this and exit() after the
  293.          * WinSwitchToProgram(), above.
  294.          */
  295.  
  296.         while( sgDos == pgis->sgCurrent )
  297.             DosSleep(500L);
  298.  
  299.         WinSwitchToProgram(fgHandle);   /* back to where we started */
  300.     }
  301. }
  302.  
  303. #if 0
  304.  
  305. Comments
  306. --------
  307.  
  308. The only reason this program works is becuase WinSwitchToProgram()
  309. allows you to:
  310.  
  311.     1) Switch a session to the foreground which is not one of your own
  312.        child sessions.
  313.  
  314.     2) Switch a session to the foreground when you are not running
  315.        in the foreground yourself.
  316.  
  317. Acording to the documentation (IBM, v1.20),  you are not supposed to
  318. be able to do either of these things.  However,  the "File Manager",
  319. from what I can figure out,  uses this method to switch to the DOS
  320. box too,  so I am confident that this program will continue to work
  321. under OS/2 1.2x.
  322.  
  323. Peter Fitzsimmons, A:WARE Inc. Thu  09-06-1990  22:15:11
  324. #endif
  325.  
  326. void main(int argc, char **argv)
  327. {
  328.     HFILE hf;
  329.     USHORT rc, dummy;
  330.     static char cmd[256];
  331.     int i;
  332.  
  333.     if( argc < 2 ){
  334.  
  335.  printf("\nUsage CALLDOS  <command>\n\n");
  336.  printf("   Each <command> with blanks should be enclosed by quotes\n\n");
  337.  printf("For example:\n");
  338.  printf("CALLDOS C: \"CD \\OS2\" \"DIR > \\DIR.LST\" \"CD \\\"\n\n");
  339.  printf("Will make C:\\OS2 current, list the files to C:\\DIR.LST,\n");
  340.  printf("and switch back to C:\\.\n\n");
  341.  printf("If invoked while a PM session is current, the focus returns,\n");
  342.  printf("to the Task List, else returns to the current session.\n\n");
  343.         exit (255);
  344.     }
  345.     cmd[0] = '\0';
  346.     for(i=1; i<argc; i++){
  347.         strcat(cmd, "\x80 ");
  348.         strcat(cmd, argv[i]);
  349.         strcat(cmd, "\r");
  350.         if( i != (argc-1) )
  351.             strcat(cmd, " ");
  352.     }
  353.     rc = DosOpen("DOS$", &hf, &dummy, 0L, FILE_NORMAL, FILE_OPEN,
  354.         OPEN_ACCESS_WRITEONLY | OPEN_SHARE_DENYNONE |
  355.         OPEN_FLAGS_FAIL_ON_ERROR, 0L);
  356.     if(!rc){
  357.         rc = DosWrite(hf, cmd, strlen(cmd)+1, &dummy);
  358.         DosClose(hf);
  359.         if(!rc)
  360.             jump2dos();
  361.         else if(rc == ERROR_NOT_READY) {
  362.             printf("A program is already running in the DOS box\n");
  363.             exit (1);
  364.         }
  365.         else {
  366.             printf("Unexpected OS/2 error SYS%04u\n", rc);
  367.             exit (2);
  368.         }
  369.     }
  370.     else {
  371.         printf("DOS.SYS not installed (sys%04u)\n", rc);
  372.         exit (3);
  373.     }
  374.     DosBeep(1000, 100);
  375. }
  376.  
  377. === End of CALLDOS.C ===============================================
  378.  
  379.  
  380.  
  381. --- msged 2.00 OS/2
  382.  * Origin: RC13's OS/2 Point in the Pit (1:109/301.10@fidonet)
  383.  
  384. No more unread messages in this topic
  385. Hit <RETURN> for next active conf/topic.
  386. Read:
  387.