ReactOS 0.4.15-dev-7953-g1f49173
internal.c File Reference
#include "precomp.h"
Include dependency graph for internal.c:

Go to the source code of this file.

Functions

INT GetRootPath (IN LPCTSTR InPath, OUT LPTSTR OutPath, IN INT size)
 
BOOL SetRootPath (TCHAR *oldpath, TCHAR *InPath)
 
INT cmd_chdir (LPTSTR param)
 
BOOL MakeFullPath (TCHAR *DirPath)
 
INT cmd_mkdir (LPTSTR param)
 
BOOL DeleteFolder (LPTSTR Directory)
 
INT cmd_rmdir (LPTSTR param)
 
INT CommandExit (LPTSTR param)
 
INT CommandRem (LPTSTR param)
 
INT CommandShowCommands (LPTSTR param)
 

Function Documentation

◆ cmd_chdir()

INT cmd_chdir ( LPTSTR  param)

Definition at line 240 of file internal.c.

241{
242 BOOL bChangeDrive = FALSE;
243 LPTSTR tmp;
244 TCHAR szCurrent[MAX_PATH];
245
246 /* Filter out special cases first */
247
248 /* Print help */
249 if (!_tcsncmp(param, _T("/?"), 2))
250 {
252 return 0;
253 }
254
255 //
256 // FIXME: Use the split() tokenizer if bEnableExtensions == FALSE,
257 // so as to cut the parameter at the first separator (space, ',', ';'):
258 // - When bEnableExtensions == FALSE, doing
259 // CD system32;winsxs
260 // will go into system32, (but: CD "system32;winsxs" will fail as below), while
261 // - When bEnableExtensions == TRUE, it will fail because the "system32;winsxs"
262 // directory does not exist.
263 //
264
265 /* Remove extra quotes */
267
269 {
270 /* Strip trailing whitespace */
271 tmp = param + _tcslen(param) - 1;
272 while (tmp > param && _istspace(*tmp))
273 --tmp;
274 *(tmp + 1) = _T('\0');
275 }
276
277 /* Reset the error level */
278 nErrorLevel = 0;
279
280 /* Print the current directory on a disk */
281 if (_tcslen(param) == 2 && param[1] == _T(':'))
282 {
283 if (GetRootPath(param, szCurrent, ARRAYSIZE(szCurrent)))
284 {
286 return 1;
287 }
288 ConOutPrintf(_T("%s\n"), szCurrent);
289 return 0;
290 }
291
292 /* Get the current directory */
293 GetCurrentDirectory(ARRAYSIZE(szCurrent), szCurrent);
294 if (param[0] == _T('\0'))
295 {
296 ConOutPrintf(_T("%s\n"), szCurrent);
297 return 0;
298 }
299
300 /* If the input string is prefixed with the /D switch, change the drive */
301 if (!_tcsncicmp(param, _T("/D"), 2))
302 {
303 bChangeDrive = TRUE;
304 param += 2;
305 while (_istspace(*param))
306 ++param;
307 }
308
309 if (!SetRootPath(bChangeDrive ? NULL : szCurrent, param))
310 {
311 nErrorLevel = 1;
312 return 1;
313 }
314
315 return 0;
316}
INT nErrorLevel
Definition: cmd.c:158
VOID error_invalid_drive(VOID)
Definition: error.c:117
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:182
#define ConOutPrintf(szStr,...)
Definition: console.h:41
INT GetRootPath(IN LPCTSTR InPath, OUT LPTSTR OutPath, IN INT size)
Definition: internal.c:152
BOOL SetRootPath(TCHAR *oldpath, TCHAR *InPath)
Definition: internal.c:182
#define STRING_CD_HELP
Definition: resource.h:72
static VOID StripQuotes(LPSTR in)
Definition: cmdcons.c:116
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
unsigned int BOOL
Definition: ntddk_ex.h:94
GLfloat param
Definition: glext.h:5796
#define _istspace
Definition: tchar.h:1504
#define _tcsncmp
Definition: tchar.h:1428
#define _tcsncicmp
Definition: tchar.h:1429
BOOL bEnableExtensions
Definition: more.c:53
#define _T(x)
Definition: vfdio.h:22
#define GetCurrentDirectory
Definition: winbase.h:3805
char TCHAR
Definition: xmlstorage.h:189
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcslen
Definition: xmlstorage.h:198

◆ cmd_mkdir()

INT cmd_mkdir ( LPTSTR  param)

Definition at line 360 of file internal.c.

361{
362 LPTSTR *p;
363 INT argc, i;
364 DWORD dwLastError;
365
366 if (!_tcsncmp (param, _T("/?"), 2))
367 {
369 return 0;
370 }
371
372 p = split (param, &argc, FALSE, FALSE);
373 if (argc == 0)
374 {
376 freep(p);
377 nErrorLevel = 1;
378 return 1;
379 }
380
381 nErrorLevel = 0;
382 for (i = 0; i < argc; i++)
383 {
384 if (!MakeFullPath(p[i]))
385 {
386 dwLastError = GetLastError();
387 switch (dwLastError)
388 {
391 break;
392
396 break;
397
398 default:
400 }
401 nErrorLevel = 1;
402 }
403 }
404
405 freep (p);
406 return nErrorLevel;
407}
static int argc
Definition: ServiceArgs.c:12
static VOID ErrorMessage(_In_ DWORD dwErrorCode, _In_opt_ PCWSTR pszMsg,...)
Definition: attrib.c:33
#define ConErrResPuts(uID)
Definition: console.h:38
#define ConErrResPrintf(uID,...)
Definition: console.h:50
BOOL MakeFullPath(TCHAR *DirPath)
Definition: internal.c:325
#define STRING_MD_ERROR2
Definition: resource.h:221
#define STRING_MKDIR_HELP
Definition: resource.h:139
#define STRING_ERROR_REQ_PARAM_MISSING
Definition: resource.h:10
#define STRING_MD_ERROR
Definition: resource.h:220
static VOID freep(LPSTR *p)
Definition: cmdcons.c:98
static LPSTR * split(LPSTR s, LPINT args)
Definition: cmdcons.c:163
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat GLfloat p
Definition: glext.h:8902
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
int32_t INT
Definition: typedefs.h:58
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
#define ERROR_FILE_EXISTS
Definition: winerror.h:165

◆ cmd_rmdir()

INT cmd_rmdir ( LPTSTR  param)

Definition at line 521 of file internal.c.

522{
523 INT nError = 0;
524 INT res;
525 LPTSTR *arg;
526 INT args;
527 INT dirCount;
528 INT i;
529 TCHAR ch;
530 BOOL bRecurseDir = FALSE;
531 BOOL bQuiet = FALSE;
532
533 if (!_tcsncmp(param, _T("/?"), 2))
534 {
536 return 0;
537 }
538
539 arg = split(param, &args, FALSE, FALSE);
540 dirCount = 0;
541
542 /* Check for options anywhere in command line */
543 for (i = 0; i < args; i++)
544 {
545 if (*arg[i] == _T('/'))
546 {
547 /* Found an option, but check to make sure it has something after it */
548 if (_tcslen(arg[i]) == 2)
549 {
550 ch = _totupper(arg[i][1]);
551
552 if (ch == _T('S'))
553 bRecurseDir = TRUE;
554 else if (ch == _T('Q'))
555 bQuiet = TRUE;
556 }
557 }
558 else
559 {
560 dirCount++;
561 }
562 }
563
564 if (dirCount == 0)
565 {
566 /* No folder to remove */
568 freep(arg);
569 return 1;
570 }
571
572 for (i = 0; i < args; i++)
573 {
574 if (*arg[i] == _T('/'))
575 continue;
576
577 if (bRecurseDir)
578 {
579 /* Ask the user whether to delete everything in the folder */
580 if (!bQuiet)
581 {
583 if (res == PROMPT_NO || res == PROMPT_BREAK)
584 {
585 nError = 1;
586 continue;
587 }
588 if (res == PROMPT_ALL)
589 bQuiet = TRUE;
590 }
591
592 res = DeleteFolder(arg[i]);
593 }
594 else
595 {
596 /* Without /S, do not force directory deletion even if it's read-only */
598 }
599
600 if (!res)
601 {
602 /* Couldn't delete the folder, print out the error */
603 nError = GetLastError();
604 ErrorMessage(nError, NULL);
605 }
606 }
607
608 freep(arg);
609 return nError;
610}
INT FilePromptYNA(UINT)
Definition: misc.c:622
VOID error_req_param_missing(VOID)
Definition: error.c:110
#define PROMPT_NO
Definition: cmd.h:330
#define PROMPT_ALL
Definition: cmd.h:332
#define PROMPT_BREAK
Definition: cmd.h:333
BOOL DeleteFolder(LPTSTR Directory)
Definition: internal.c:414
#define STRING_RMDIR_HELP
Definition: resource.h:165
#define STRING_DEL_HELP2
Definition: resource.h:101
GLuint res
Definition: glext.h:9613
#define _totupper
Definition: tchar.h:1509
#define args
Definition: format.c:66
Definition: match.c:390
#define RemoveDirectory
Definition: winbase.h:3895
void * arg
Definition: msvc.h:10

◆ CommandExit()

INT CommandExit ( LPTSTR  param)

Definition at line 621 of file internal.c.

622{
623 if (!_tcsncmp(param, _T("/?"), 2))
624 {
626
627 /* Just make sure we don't exit */
628 bExit = FALSE;
629 return 0;
630 }
631
632 if (_tcsnicmp(param, _T("/B"), 2) == 0)
633 {
634 param += 2;
635
636 /*
637 * If a current batch file is running, exit it,
638 * otherwise exit this command interpreter instance.
639 */
640 if (bc)
641 {
642 /* Windows' CMD compatibility: Use GOTO :EOF */
643 TCHAR EofLabel[] = _T(":EOF");
644
645#ifdef SUPPORT_EXIT_B_NO_EXTENSIONS
646 /*
647 * Temporarily enable extensions so as to support :EOF.
648 *
649 * Our GOTO implementation ensures that, when extensions are
650 * enabled and the label is ':EOF', no immediate change of batch
651 * context (done e.g. via ExitBatch() calls) is performed.
652 * This will therefore ensure that we do not spoil the extensions
653 * state when we restore it below.
654 */
655 BOOL bOldEnableExtensions = bEnableExtensions;
657#endif
658
659 cmd_goto(EofLabel);
660
661#ifdef SUPPORT_EXIT_B_NO_EXTENSIONS
662 /* Restore the original state of the extensions */
663 bEnableExtensions = bOldEnableExtensions;
664#endif
665 }
666 else
667 {
668 bExit = TRUE;
669 }
670 }
671 else
672 {
673 /* Exit this command interpreter instance */
674 bExit = TRUE;
675 }
676
677 /* Search for an optional exit code */
678 while (_istspace(*param))
679 ++param;
680
681 /* Set the errorlevel to the exit code */
682 if (_istdigit(*param))
683 {
685 // if (fSingleCommand == 1) return nErrorLevel;
686 }
687
688 return (bExit ? nErrorLevel : 0);
689}
PBATCH_CONTEXT bc
Definition: batch.c:67
BOOL bExit
Definition: cmd.c:152
INT cmd_goto(LPTSTR)
Definition: goto.c:36
#define STRING_EXIT_HELP
Definition: resource.h:126
#define _istdigit
Definition: tchar.h:1494
#define _ttoi
Definition: xmlstorage.h:195
#define _tcsnicmp
Definition: xmlstorage.h:207

◆ CommandRem()

INT CommandRem ( LPTSTR  param)

Definition at line 695 of file internal.c.

696{
697 if (_tcsstr(param, _T("/?")) == param)
698 {
700 }
701
702 return 0;
703}
#define STRING_REM_HELP
Definition: resource.h:159
#define _tcsstr
Definition: xmlstorage.h:199

◆ CommandShowCommands()

INT CommandShowCommands ( LPTSTR  param)

Definition at line 707 of file internal.c.

708{
710 return 0;
711}
VOID PrintCommandList(VOID)
Definition: cmdtable.c:234

◆ DeleteFolder()

BOOL DeleteFolder ( LPTSTR  Directory)

Definition at line 414 of file internal.c.

415{
416 LPTSTR pFileName;
419 DWORD dwAttribs;
420 TCHAR szFullPath[MAX_PATH];
421
422 _tcscpy(szFullPath, Directory);
423 pFileName = &szFullPath[_tcslen(szFullPath)];
424 /*
425 * Append a path separator if we don't have one already, and if this a drive root
426 * path is not specified (paths like "C:" mean the current directory on drive C:).
427 */
428 if (*szFullPath && *(pFileName - 1) != _T(':') && *(pFileName - 1) != _T('\\'))
429 *pFileName++ = _T('\\');
430 _tcscpy(pFileName, _T("*"));
431
432 hFile = FindFirstFile(szFullPath, &f);
434 {
435 do
436 {
437 /* Check Breaker */
438 if (bCtrlBreak)
439 break;
440
441 if (!_tcscmp(f.cFileName, _T(".")) ||
442 !_tcscmp(f.cFileName, _T("..")))
443 {
444 continue;
445 }
446
447 _tcscpy(pFileName, f.cFileName);
448
449 dwAttribs = f.dwFileAttributes;
450
451 if (dwAttribs & FILE_ATTRIBUTE_DIRECTORY)
452 {
453 if (!DeleteFolder(szFullPath))
454 {
455 /* Couldn't delete the file, print out the error */
456 ErrorMessage(GetLastError(), szFullPath);
457
458 /* Continue deleting files/subfolders */
459 }
460 }
461 else
462 {
463 /* Force file deletion even if it's read-only */
464 if (dwAttribs & FILE_ATTRIBUTE_READONLY)
465 SetFileAttributes(szFullPath, dwAttribs & ~FILE_ATTRIBUTE_READONLY);
466
467 if (!DeleteFile(szFullPath))
468 {
469 /* Couldn't delete the file, print out the error */
470 ErrorMessage(GetLastError(), szFullPath);
471
472 /* Restore file attributes */
473 SetFileAttributes(szFullPath, dwAttribs);
474
475 /* Continue deleting files/subfolders */
476 }
477 }
478
479 } while (FindNextFile(hFile, &f));
481 }
482
483 /* Ignore directory deletion if the user pressed Ctrl-C */
484 if (bCtrlBreak)
485 return TRUE;
486
487 /*
488 * Detect whether we are trying to delete a pure root drive (e.g. "C:\\", but not "C:");
489 * if so, just return success. Otherwise the RemoveDirectory() call below would fail
490 * and return ERROR_ACCESS_DENIED.
491 */
492 if (GetFullPathName(Directory, ARRAYSIZE(szFullPath), szFullPath, NULL) == 3 &&
493 szFullPath[1] == _T(':') && szFullPath[2] == _T('\\'))
494 {
495 return TRUE;
496 }
497
498 /* First attempt to delete the directory */
500 return TRUE;
501
502 /*
503 * It failed; if it was due to an denied access, check whether it was
504 * due to the directory being read-only. If so, remove its attribute
505 * and retry deletion.
506 */
508 {
509 /* Force directory deletion even if it's read-only */
510 dwAttribs = GetFileAttributes(Directory);
511 if (dwAttribs & FILE_ATTRIBUTE_READONLY)
512 {
515 }
516 }
517
518 return FALSE;
519}
BOOL bCtrlBreak
Definition: cmd.c:154
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
GLfloat f
Definition: glext.h:7540
#define _tcscmp
Definition: tchar.h:1424
#define _tcscpy
Definition: tchar.h:623
#define f
Definition: ke_i.h:83
_In_ HANDLE hFile
Definition: mswsock.h:90
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
base for all directory entries
Definition: entries.h:138
#define GetFileAttributes
Definition: winbase.h:3815
#define SetFileAttributes
Definition: winbase.h:3909
#define DeleteFile
Definition: winbase.h:3764
#define FindNextFile
Definition: winbase.h:3788
#define FindFirstFile
Definition: winbase.h:3782
#define GetFullPathName
Definition: winbase.h:3821

Referenced by cmd_rmdir(), DECLARE_INTERFACE_(), and DeleteFolder().

◆ GetRootPath()

INT GetRootPath ( IN LPCTSTR  InPath,
OUT LPTSTR  OutPath,
IN INT  size 
)

Definition at line 152 of file internal.c.

156{
157 if (InPath[0] && InPath[1] == _T(':'))
158 {
159 INT t = 0;
160
161 if ((InPath[0] >= _T('0')) && (InPath[0] <= _T('9')))
162 {
163 t = (InPath[0] - _T('0')) + 28;
164 }
165 else if ((InPath[0] >= _T('a')) && (InPath[0] <= _T('z')))
166 {
167 t = (InPath[0] - _T('a')) + 1;
168 }
169 else if ((InPath[0] >= _T('A')) && (InPath[0] <= _T('Z')))
170 {
171 t = (InPath[0] - _T('A')) + 1;
172 }
173
174 return (_tgetdcwd(t, OutPath, size) == NULL);
175 }
176
177 /* Get current directory */
178 return !GetCurrentDirectory(size, OutPath);
179}
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
#define _tgetdcwd
Definition: tchar.h:674

Referenced by cmd_chdir(), cmd_copy(), cmd_replace(), CommandDelete(), GetDirectory(), and getPath().

◆ MakeFullPath()

BOOL MakeFullPath ( TCHAR DirPath)

Definition at line 325 of file internal.c.

326{
328 TCHAR *p = DirPath;
329 INT_PTR n;
330
331 if (CreateDirectory(DirPath, NULL))
332 return TRUE;
334 return FALSE;
335
336 /* got ERROR_PATH_NOT_FOUND, so try building it up one component at a time */
337 if (p[0] && p[1] == _T(':'))
338 p += 2;
339 while (*p == _T('\\'))
340 p++; /* skip drive root */
341 do
342 {
343 p = _tcschr(p, _T('\\'));
344 n = p ? p++ - DirPath : _tcslen(DirPath);
345 _tcsncpy(path, DirPath, n);
346 path[n] = _T('\0');
347 if ( !CreateDirectory(path, NULL) &&
349 {
350 return FALSE;
351 }
352 } while (p != NULL);
353
354 return TRUE;
355}
GLdouble n
Definition: glext.h:7729
#define _tcsncpy
Definition: tchar.h:1410
#define _tcschr
Definition: tchar.h:1406
int32_t INT_PTR
Definition: typedefs.h:64
#define CreateDirectory
Definition: winbase.h:3746

Referenced by cmd_mkdir().

◆ SetRootPath()

BOOL SetRootPath ( TCHAR oldpath,
TCHAR InPath 
)

Definition at line 182 of file internal.c.

183{
184 DWORD dwLastError;
185 TCHAR OutPath[MAX_PATH];
186 TCHAR OutPathTemp[MAX_PATH];
187
188 StripQuotes(InPath);
189
190 /* Retrieve the full path name from the (possibly relative) InPath */
191 if (GetFullPathName(InPath, ARRAYSIZE(OutPathTemp), OutPathTemp, NULL) == 0)
192 {
193 dwLastError = GetLastError();
194 goto Fail;
195 }
196
198 {
199 /*
200 * Convert the full path to its correct case, and
201 * resolve any wilcard present as well in the path
202 * and retrieve the first result.
203 * Example: c:\windows\SYSTEM32 => C:\WINDOWS\System32
204 * Example: C:\WINDOWS\S* => C:\WINDOWS\System,
205 * or C:\WINDOWS\System32, depending on the user's OS.
206 */
207 GetPathCase(OutPathTemp, OutPath);
208 }
209 else
210 {
211 _tcscpy(OutPath, OutPathTemp);
212 }
213
214 /* Use _tchdir(), since unlike SetCurrentDirectory() it updates
215 * the current-directory-on-drive environment variables. */
216 if (_tchdir(OutPath) != 0)
217 {
218 dwLastError = GetLastError();
219 if (dwLastError == ERROR_FILE_NOT_FOUND)
220 dwLastError = ERROR_PATH_NOT_FOUND;
221 goto Fail;
222 }
223
224 /* Keep the original drive in ordinary CD/CHDIR (without /D switch) */
225 if (oldpath != NULL && _tcsncicmp(OutPath, oldpath, 2) != 0)
226 SetCurrentDirectory(oldpath);
227
228 return TRUE;
229
230Fail:
231 ConErrFormatMessage(dwLastError);
232 nErrorLevel = 1;
233 return FALSE;
234}
VOID GetPathCase(TCHAR *, TCHAR *)
Definition: misc.c:86
#define ConErrFormatMessage(MessageId,...)
Definition: console.h:56
int Fail
Definition: ehthrow.cxx:24
#define _tchdir
Definition: tchar.h:672
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define SetCurrentDirectory
Definition: winbase.h:3903

Referenced by cmd_chdir(), and CommandPushd().