ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

internal.c
Go to the documentation of this file.
00001 /*
00002  *  INTERNAL.C - command.com internal commands.
00003  *
00004  *
00005  *  History:
00006  *
00007  *  17/08/94 (Tim Norman)
00008  *    started.
00009  *
00010  *  08/08/95 (Matt Rains)
00011  *    i have cleaned up the source code. changes now bring this source into
00012  *    guidelines for recommended programming practice.
00013  *
00014  *  cd()
00015  *    started.
00016  *
00017  *  dir()
00018  *    i have added support for file attributes to the DIR() function. the
00019  *    routine adds "d" (directory) and "r" (read only) output. files with the
00020  *    system attribute have the filename converted to lowercase. files with
00021  *    the hidden attribute are not displayed.
00022  *
00023  *    i have added support for directorys. now if the directory attribute is
00024  *    detected the file size if replaced with the string "<dir>".
00025  *
00026  *  ver()
00027  *    started.
00028  *
00029  *  md()
00030  *    started.
00031  *
00032  *  rd()
00033  *    started.
00034  *
00035  *  del()
00036  *    started.
00037  *
00038  *  does not support wildcard selection.
00039  *
00040  *  todo: add delete directory support.
00041  *        add recursive directory delete support.
00042  *
00043  *  ren()
00044  *    started.
00045  *
00046  *  does not support wildcard selection.
00047  *
00048  *    todo: add rename directory support.
00049  *
00050  *  a general structure has been used for the cd, rd and md commands. this
00051  *  will be better in the long run. it is too hard to maintain such diverse
00052  *  functions when you are involved in a group project like this.
00053  *
00054  *  12/14/95 (Tim Norman)
00055  *    fixed DIR so that it will stick \*.* if a directory is specified and
00056  *    that it will stick on .* if a file with no extension is specified or
00057  *    *.* if it ends in a \
00058  *
00059  *  1/6/96 (Tim Norman)
00060  *    added an isatty call to DIR so it won't prompt for keypresses unless
00061  *    stdin and stdout are the console.
00062  *
00063  *    changed parameters to be mutually consistent to make calling the
00064  *    functions easier
00065  *
00066  *  rem()
00067  *    started.
00068  *
00069  *  doskey()
00070  *    started.
00071  *
00072  *    01/22/96 (Oliver Mueller)
00073  *        error messages are now handled by perror.
00074  *
00075  *    02/05/96 (Tim Norman)
00076  *        converted all functions to accept first/rest parameters
00077  *
00078  *    07/26/96 (Tim Norman)
00079  *        changed return values to int instead of void
00080  *
00081  *        path() started.
00082  *
00083  *    12/23/96 (Aaron Kaufman)
00084  *        rewrote dir() to mimic MS-DOS's dir
00085  *
00086  *    01/28/97 (Tim Norman)
00087  *        cleaned up Aaron's DIR code
00088  *
00089  *    06/13/97 (Tim Norman)
00090  *        moved DIR code to dir.c
00091  *        re-implemented Aaron's DIR code
00092  *
00093  *    06/14/97 (Steffan Kaiser)
00094  *        ctrl-break handling
00095  *        bug fixes
00096  *
00097  *    27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
00098  *        added config.h include
00099  *
00100  *    03-Dec-1998 (Eric Kohl)
00101  *        Replaced DOS calls by Win32 calls.
00102  *
00103  *    08-Dec-1998 (Eric Kohl)
00104  *        Added help texts ("/?").
00105  *
00106  *    18-Dec-1998 (Eric Kohl)
00107  *        Added support for quoted arguments (cd "program files").
00108  *
00109  *    07-Jan-1999 (Eric Kohl)
00110  *        Clean up.
00111  *
00112  *    26-Jan-1999 (Eric Kohl)
00113  *        Replaced remaining CRT io functions by Win32 io functions.
00114  *        Unicode safe!
00115  *
00116  *    30-Jan-1999 (Eric Kohl)
00117  *        Added "cd -" feature. Changes to the previous directory.
00118  *
00119  *    15-Mar-1999 (Eric Kohl)
00120  *        Fixed bug in "cd -" feature. If the previous directory was a root
00121  *        directory, it was ignored.
00122  *
00123  *    23-Feb-2001 (Carl Nettelblad <cnettel@hem.passagen.se>)
00124  *        Improved chdir/cd command.
00125  *
00126  *    02-Apr-2004 (Magnus Olsen <magnus@greatlord.com>)
00127  *        Remove all hard code string so they can be
00128  *        translate to other langues.
00129  *
00130  *    19-Jul-2005 (Brandon Turner <turnerb7@msu.edu>)
00131  *        Rewrite the CD, it working as Windows 2000 CMD
00132  *
00133  *    19-Jul-2005 (Magnus Olsen <magnus@greatlord.com>)
00134  *        Add SetRootPath and GetRootPath
00135  *
00136  *    14-Jul-2007 (Pierre Schweitzer <heis_spiter@hotmail.com>)
00137  *        Added commands help display to help command (ex. : "help cmd")
00138  */
00139 
00140 #include <precomp.h>
00141 
00142 #ifdef INCLUDE_CMD_CHDIR
00143 
00144 /* help functions for getting current path from drive
00145    without changing drive. Return code 0 = ok, 1 = fail.
00146    INT GetRootPath("C:",outbuffer,chater size of outbuffer);
00147    the first param can have any size, if the the two frist
00148    letter are not a drive with : it will get Currentpath on
00149    current drive exacly as GetCurrentDirectory does.
00150    */
00151 
00152 INT GetRootPath(TCHAR *InPath,TCHAR *OutPath,INT size)
00153 {
00154   if (InPath[0] && InPath[1] == _T(':'))
00155   {
00156       INT t=0;
00157 
00158       if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9')))
00159       {
00160           t = (InPath[0] - _T('0')) +28;
00161       }
00162 
00163       if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z')))
00164       {
00165           t = (InPath[0] - _T('a')) +1;
00166           InPath[0] = t + _T('A') - 1;
00167       }
00168 
00169        if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z')))
00170       {
00171           t = (InPath[0] - _T('A')) +1;
00172       }
00173 
00174       return _tgetdcwd(t,OutPath,size) == NULL;
00175   }
00176 
00177   /* Get current directory */
00178   return !GetCurrentDirectory(size,OutPath);
00179 }
00180 
00181 
00182 BOOL SetRootPath(TCHAR *oldpath, TCHAR *InPath)
00183 {
00184   TCHAR OutPath[MAX_PATH];
00185   TCHAR OutPathTemp[MAX_PATH];
00186 
00187   /* The use of both of these together will correct the case of a path
00188      where as one alone or GetFullPath will not.  Exameple:
00189       c:\windows\SYSTEM32 => C:\WINDOWS\system32 */
00190     if (GetFullPathName(InPath, MAX_PATH, OutPathTemp, NULL))
00191     {
00192         GetPathCase(OutPathTemp, OutPath);
00193 
00194         /* Use _tchdir, since unlike SetCurrentDirectory it updates
00195          * the current-directory-on-drive environment variables. */
00196         if (_tchdir(OutPath) != 0)
00197         {
00198             ConErrFormatMessage(GetLastError());
00199             nErrorLevel = 1;
00200             return FALSE;
00201         }
00202 
00203         /* Keep original drive in ordinary CD/CHDIR (without /D switch). */
00204         if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0)
00205             SetCurrentDirectory(oldpath);
00206     }
00207 
00208     return TRUE;
00209 }
00210 
00211 
00212 /*
00213  * CD / CHDIR
00214  *
00215  */
00216 INT cmd_chdir (LPTSTR param)
00217 {
00218     TCHAR szCurrent[MAX_PATH];
00219     BOOL bChangeDrive = FALSE;
00220 
00221     /* Filter out special cases first */
00222 
00223     /* Print Help */
00224     if (!_tcsncmp(param, _T("/?"), 2))
00225     {
00226         ConOutResPaging(TRUE,STRING_CD_HELP);
00227         return 0;
00228     }
00229 
00230     /* Remove " */
00231     StripQuotes(param);
00232 
00233     /* Set Error Level to Success */
00234     nErrorLevel = 0;
00235 
00236     /* Print Current Directory on a disk */
00237     if (_tcslen(param) == 2 && param[1] == _T(':'))
00238     {
00239         if (GetRootPath(param, szCurrent, MAX_PATH))
00240         {
00241             error_invalid_drive();
00242             return 1;
00243         }
00244         ConOutPuts(szCurrent);
00245         return 0;
00246     }
00247 
00248     /* Get Current Directory */
00249     GetCurrentDirectory(MAX_PATH, szCurrent);
00250     if (param[0] == _T('\0'))
00251     {
00252         ConOutPuts(szCurrent);
00253         return 0;
00254     }
00255 
00256     /* Input String Contains /D Switch */
00257     if (!_tcsncicmp(param, _T("/D"), 2))
00258     {
00259         bChangeDrive = TRUE;
00260         param += 2;
00261         while (_istspace(*param))
00262             param++;
00263     }
00264 
00265     if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param))
00266         return 1;
00267 
00268     return 0;
00269 }
00270 
00271 #endif
00272 
00273 
00274 
00275 #ifdef INCLUDE_CMD_MKDIR
00276 
00277 /* Helper funtion for mkdir to make directories in a path.
00278 Dont use the api to decrease depence on libs */
00279 BOOL
00280 MakeFullPath(TCHAR * DirPath)
00281 {
00282     TCHAR path[MAX_PATH];
00283     TCHAR *p = DirPath;
00284     INT_PTR  n;
00285 
00286     if (CreateDirectory(DirPath, NULL))
00287         return TRUE;
00288     else if (GetLastError() != ERROR_PATH_NOT_FOUND)
00289         return FALSE;
00290 
00291     /* got ERROR_PATH_NOT_FOUND, so try building it up one component at a time */
00292     if (p[0] && p[1] == _T(':'))
00293         p += 2;
00294     while (*p == _T('\\'))
00295         p++; /* skip drive root */
00296     do
00297     {
00298        p = _tcschr(p, _T('\\'));
00299        n = p ? p++ - DirPath : _tcslen(DirPath);
00300        _tcsncpy(path, DirPath, n);
00301        path[n] = _T('\0');
00302        if( !CreateDirectory(path, NULL) &&
00303            (GetLastError() != ERROR_ALREADY_EXISTS))
00304            return FALSE;
00305     } while (p != NULL);
00306 
00307     return TRUE;
00308 }
00309 
00310 /*
00311  * MD / MKDIR
00312  *
00313  */
00314 INT cmd_mkdir (LPTSTR param)
00315 {
00316     LPTSTR *p;
00317     INT argc, i;
00318     if (!_tcsncmp (param, _T("/?"), 2))
00319     {
00320         ConOutResPaging(TRUE,STRING_MKDIR_HELP);
00321         return 0;
00322     }
00323 
00324     p = split (param, &argc, FALSE, FALSE);
00325     if (argc == 0)
00326     {
00327         ConErrResPuts(STRING_ERROR_REQ_PARAM_MISSING);
00328         nErrorLevel = 1;
00329         freep(p);
00330         return 1;
00331     }
00332 
00333     nErrorLevel = 0;
00334     for (i = 0; i < argc; i++)
00335     {
00336         if (!MakeFullPath(p[i]))
00337         {
00338             if(GetLastError() == ERROR_PATH_NOT_FOUND)
00339             {
00340                 ConErrResPuts(STRING_MD_ERROR2);
00341             }
00342             else
00343             {
00344                 ErrorMessage (GetLastError(), _T("MD"));
00345             }
00346             nErrorLevel = 1;
00347         }
00348     }
00349 
00350     freep (p);
00351     return nErrorLevel;
00352 }
00353 #endif
00354 
00355 
00356 #ifdef INCLUDE_CMD_RMDIR
00357 /*
00358  * RD / RMDIR
00359  *
00360  */
00361 BOOL DeleteFolder(LPTSTR FileName)
00362 {
00363     TCHAR Base[MAX_PATH];
00364     TCHAR TempFileName[MAX_PATH];
00365     HANDLE hFile;
00366     WIN32_FIND_DATA f;
00367     _tcscpy(Base,FileName);
00368     _tcscat(Base,_T("\\*"));
00369     hFile = FindFirstFile(Base, &f);
00370     Base[_tcslen(Base) - 1] = _T('\0');
00371     if (hFile != INVALID_HANDLE_VALUE)
00372     {
00373         do
00374         {
00375             if (!_tcscmp(f.cFileName, _T(".")) ||
00376                 !_tcscmp(f.cFileName, _T("..")))
00377                 continue;
00378             _tcscpy(TempFileName,Base);
00379             _tcscat(TempFileName,f.cFileName);
00380 
00381             if(f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00382                 DeleteFolder(TempFileName);
00383             else
00384             {
00385                 SetFileAttributes(TempFileName,FILE_ATTRIBUTE_NORMAL);
00386                 if(!DeleteFile(TempFileName))
00387                     return 0;
00388             }
00389 
00390         }while (FindNextFile (hFile, &f));
00391         FindClose (hFile);
00392     }
00393     return RemoveDirectory(FileName);
00394 }
00395 INT cmd_rmdir (LPTSTR param)
00396 {
00397     TCHAR ch;
00398     INT args;
00399     INT dirCount;
00400     LPTSTR *arg;
00401     INT i;
00402     BOOL RD_SUB = FALSE;
00403     BOOL RD_QUIET = FALSE;
00404     INT res;
00405     INT nError = 0;
00406     TCHAR szFullPath[MAX_PATH];
00407 
00408     if (!_tcsncmp (param, _T("/?"), 2))
00409     {
00410         ConOutResPaging(TRUE,STRING_RMDIR_HELP);
00411         return 0;
00412     }
00413 
00414     arg = split (param, &args, FALSE, FALSE);
00415     dirCount = 0;
00416 
00417     /* check for options anywhere in command line */
00418     for (i = 0; i < args; i++)
00419     {
00420         if (*arg[i] == _T('/'))
00421         {
00422             /*found a command, but check to make sure it has something after it*/
00423             if (_tcslen (arg[i]) == 2)
00424             {
00425                 ch = _totupper (arg[i][1]);
00426 
00427                 if (ch == _T('S'))
00428                 {
00429                     RD_SUB = TRUE;
00430                 }
00431                 else if (ch == _T('Q'))
00432                 {
00433                     RD_QUIET = TRUE;
00434                 }
00435             }
00436         }
00437         else
00438         {
00439             dirCount++;
00440         }
00441     }
00442 
00443     if (dirCount == 0)
00444     {
00445         /* No folder to remove */
00446         error_req_param_missing();
00447         freep(arg);
00448         return 1;
00449     }
00450 
00451     for (i = 0; i < args; i++)
00452     {
00453         if (*arg[i] == _T('/'))
00454             continue;
00455 
00456         if (RD_SUB)
00457         {
00458             /* ask if they want to delete evrything in the folder */
00459             if (!RD_QUIET)
00460             {
00461                 res = FilePromptYNA (STRING_DEL_HELP2);
00462                 if (res == PROMPT_NO || res == PROMPT_BREAK)
00463                 {
00464                     nError = 1;
00465                     continue;
00466                 }
00467                 if (res == PROMPT_ALL)
00468                     RD_QUIET = TRUE;
00469             }
00470             /* get the folder name */
00471             GetFullPathName(arg[i],MAX_PATH,szFullPath,NULL);
00472 
00473             /* remove trailing \ if any, but ONLY if dir is not the root dir */
00474             if (_tcslen (szFullPath) >= 2 && szFullPath[_tcslen (szFullPath) - 1] == _T('\\'))
00475                 szFullPath[_tcslen(szFullPath) - 1] = _T('\0');
00476 
00477             res = DeleteFolder(szFullPath);
00478         }
00479         else
00480         {
00481             res = RemoveDirectory(arg[i]);
00482         }
00483 
00484         if (!res)
00485         {
00486             /* Couldn't delete the folder, print out the error */
00487             nError = GetLastError();
00488             ErrorMessage(nError, _T("RD"));
00489         }
00490     }
00491 
00492     freep (arg);
00493     return nError;
00494 }
00495 #endif
00496 
00497 
00498 /*
00499  * set the exitflag to true
00500  *
00501  */
00502 INT CommandExit (LPTSTR param)
00503 {
00504     if (!_tcsncmp (param, _T("/?"), 2))
00505     {
00506         ConOutResPaging(TRUE,STRING_EXIT_HELP);
00507         /* Just make sure */
00508         bExit = FALSE;
00509         /* Dont exit */
00510         return 0;
00511     }
00512 
00513     if (bc != NULL && _tcsnicmp(param,_T("/b"),2) == 0)
00514     {
00515         param += 2;
00516         while (_istspace (*param))
00517             param++;
00518         if (_istdigit(*param))
00519             nErrorLevel = _ttoi(param);
00520         ExitBatch();
00521     }
00522 
00523     else
00524         bExit = TRUE;
00525 
00526 
00527     return 0;
00528 
00529 }
00530 
00531 #ifdef INCLUDE_CMD_REM
00532 /*
00533  * does nothing
00534  *
00535  */
00536 INT CommandRem (LPTSTR param)
00537 {
00538     if (!_tcsncmp (param, _T("/?"), 2))
00539     {
00540         ConOutResPaging(TRUE,STRING_REM_HELP);
00541     }
00542 
00543     return 0;
00544 }
00545 #endif /* INCLUDE_CMD_REM */
00546 
00547 
00548 INT CommandShowCommands (LPTSTR param)
00549 {
00550     PrintCommandList ();
00551     return 0;
00552 }
00553 
00554 INT CommandShowCommandsDetail (LPTSTR param)
00555 {
00556     /* If a param was send, display help of correspondent command */
00557     if (_tcslen(param))
00558     {
00559         DoCommand(param, _T("/?"), NULL);
00560     }
00561     /* Else, display detailed commands list */
00562     else
00563     {
00564         PrintCommandListDetail ();
00565     }
00566     return 0;
00567 }
00568 
00569 /* EOF */

Generated on Sat May 26 2012 04:17:03 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.