home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l430 / 1.ddi / CHAP4.ZIP / SH.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-11  |  3.9 KB  |  166 lines

  1. /*
  2.     SH.C -- Command Shell for Windows
  3.  
  4.     Copyright (c) Andrew Schulman 1991, 1992
  5.     
  6.     From Chapter 4 of "Undocumented Windows" (Addison-Wesley 1992)
  7.     by Andrew Schulman, Dave Maxey and Matt Pietrek
  8.  
  9.     Build using: WINIOBC SH (for Borland C++ v3.00)
  10.                  WINIOMS SH (for Microsoft C/SDK)
  11. */
  12.  
  13. #include "windows.h"
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #ifdef __BORLANDC__
  17. #define __MSC
  18. #include <dir.h>
  19. #else
  20. #include <direct.h>
  21. #endif
  22. #include <dos.h>
  23. #include "winio.h"
  24.  
  25. int do_command(char *s);
  26. char *pwd(void);
  27.  
  28. static char buf[2048] = {0};
  29. static char orig[2048] = {0};
  30. static char title[80] = "Command Shell";
  31. static unsigned instance = 0;
  32. static HWND hwnd_sh;
  33.  
  34. int main()
  35. {
  36.     winio_about("SH - A Command Shell for Windows"
  37.         "\n\nFrom Chapter 4 of"
  38.         "\n\"Undocumented Windows\" (Addison-Wesley, 1992)"
  39.         "\nby Andrew Schulman, David Maxey and Matt Pietrek");
  40.         
  41.     hwnd_sh = winio_current();
  42.     winio_settitle(hwnd_sh, title);
  43.     winio_setfont(hwnd_sh, ANSI_FIXED_FONT);
  44.     
  45.     for (;;)
  46.     {
  47.         printf("%s>", pwd());
  48.         gets(buf);
  49.         if ((buf[0] == '\0') || (buf[0] == '\n')) 
  50.             continue;
  51.         strcpy(orig, buf);  // unmodified buffer
  52.         strupr(buf);
  53.         if (strcmp(buf, "EXIT") == 0) 
  54.             break;
  55.         if (! do_command(buf))
  56.             puts("Bad command or file name");
  57.     }
  58.     
  59.     winio_close(hwnd_sh);
  60.     return 0;
  61. }
  62.  
  63. char *pwd(void)
  64. {
  65.     static char buf[256];
  66.     char *s;
  67.     return ((s = getcwd(buf, 255)) != 0) ? s : "invalid";
  68. }
  69.  
  70. // NOTE: running multiple instances, Windows takes care of maintaining
  71. // multiple pwd within each instance
  72. int do_chdrive(char *s)
  73. {
  74. #ifdef __BORLANDC__ 
  75.     return (s[1] == ':') ? setdisk(s[0] - 'A') : 0;
  76. #else
  77.     return (s[1] == ':') ? (_chdrive(1 + s[0] - 'A') == 0) : 0;
  78. #endif
  79. }
  80.  
  81. int do_cd(char *s)
  82. {
  83.     if (s[1] == ':')
  84.     {
  85.         // allow drives in here too
  86.         if (! do_chdrive(s)) return 0;
  87.         s += 2;
  88.     }
  89.     return (chdir(s) == 0);
  90. }
  91.  
  92. void show_filename(struct find_t *pinfo)
  93. {
  94.     if (pinfo->attrib & _A_SUBDIR)
  95.         printf("%-13s\t<DIR>\n", pinfo->name);
  96.     else
  97.         printf("%-13s\t%9lu\n", pinfo->name, pinfo->size);
  98. }
  99.  
  100. int do_dir(char *s)
  101. {
  102.     struct find_t info;
  103.     char wildcard[80];
  104.     unsigned long bytes;
  105.     unsigned attrib, files;
  106.     strcpy(wildcard, s);
  107.     if (! strchr(wildcard, '.'))
  108.         strcat(wildcard, "*.*");
  109.     attrib = _A_NORMAL | _A_SUBDIR | _A_RDONLY;
  110.     if (_dos_findfirst(wildcard, attrib, &info) != 0)
  111.         return 0;
  112.     files = 1;
  113.     bytes = info.size;
  114.     winio_setpaint(hwnd_sh,FALSE);
  115.     show_filename(&info);
  116.     while (_dos_findnext(&info) == 0)
  117.     {
  118.         show_filename(&info);
  119.         files++;
  120.         bytes += info.size;
  121.     }
  122.     printf("%5u File(s)\t%lu bytes\n", files, bytes);
  123.     winio_setpaint(hwnd_sh,TRUE);
  124.     return 1;
  125. }
  126.  
  127. int do_activate(char *s)
  128. {
  129.     HWND hwnd = FindWindow(NULL, s);
  130.     if (! hwnd) return FALSE;
  131.     BringWindowToTop(hwnd);
  132.     if (IsIconic(hwnd)) ShowWindow(hwnd, SW_RESTORE);
  133.     return TRUE;
  134. }
  135.  
  136. // distinguish between built-in that failed, and not built-in
  137. #define NOT_BUILTIN     -1
  138.  
  139. #define MATCH(str, func)  if (strcmp(cmd, str) == 0) return func(args)
  140.  
  141. int do_builtin(char *s)
  142. {
  143.     char *cmd = strtok(s, " \t");
  144.     char *args = strtok(0, "\t");
  145.     if (strcmp(cmd, "ACTIVATE") == 0)
  146.         return do_activate(&orig[args-cmd]);    // unmodified string
  147.     else if ((strlen(cmd) == 2) && (cmd[1] == ':'))     // drive:
  148.         return do_chdrive(cmd);
  149.     else MATCH("CD", do_cd);
  150.     else MATCH("DIR", do_dir);
  151.     return NOT_BUILTIN;
  152. }
  153.  
  154. int do_command(char *s)
  155. {
  156.     int ret; 
  157.     if ((ret = do_builtin(s)) == NOT_BUILTIN)
  158.     {
  159.         unsigned retval;
  160.         ret = ((retval = WinExec(orig, SW_SHOWNORMAL)) > 32);
  161.         printf("%04X\n", retval);
  162.     }
  163.     return ret;
  164. }
  165.  
  166.