ReactOS  0.4.15-dev-1049-g1062a29
setlocal.c
Go to the documentation of this file.
1 /*
2  * SETLOCAL.C - setlocal and endlocal internal batch commands.
3  *
4  * History:
5  *
6  * 1 Feb 2008 (Christoph von Wittich)
7  * started.
8 */
9 
10 #include "precomp.h"
11 
12 #include <direct.h> // For _getdrive().
13 
14 typedef struct _SETLOCAL
15 {
16  struct _SETLOCAL *Prev;
22 
23 /* Create a copy of the current environment */
24 LPTSTR
26 {
27  LPTSTR Environ = GetEnvironmentStrings();
28  LPTSTR End, EnvironCopy;
29 
30  if (!Environ) return NULL;
31 
32  for (End = Environ; *End; End += _tcslen(End) + 1) ;
33  EnvironCopy = cmd_alloc((End + 1 - Environ) * sizeof(TCHAR));
34 
35  if (EnvironCopy)
36  memcpy(EnvironCopy, Environ, (End + 1 - Environ) * sizeof(TCHAR));
37 
38  FreeEnvironmentStrings(Environ);
39  return EnvironCopy;
40 }
41 
43 {
44  PSETLOCAL Saved;
45  LPTSTR* arg;
46  INT argc, i;
47 
48  if (!_tcscmp(param, _T("/?")))
49  {
50  // FIXME
51  ConOutPuts(_T("SETLOCAL help not implemented yet!\n"));
52  return 0;
53  }
54 
55  /* SETLOCAL only works inside a batch context */
56  if (!bc)
57  return 0;
58 
59  Saved = cmd_alloc(sizeof(SETLOCAL));
60  if (!Saved)
61  {
62  WARN("Cannot allocate memory for Saved!\n");
64  return 1;
65  }
66 
68  if (!Saved->Environment)
69  {
71  cmd_free(Saved);
72  return 1;
73  }
74  /*
75  * Save the current drive; the duplicated environment
76  * contains the corresponding current directory.
77  */
78  Saved->CurDrive = _getdrive();
79 
82 
83  Saved->Prev = bc->setlocal;
84  bc->setlocal = Saved;
85 
86  nErrorLevel = 0;
87 
88  arg = splitspace(param, &argc);
89  for (i = 0; i < argc; i++)
90  {
91  if (!_tcsicmp(arg[i], _T("ENABLEEXTENSIONS")))
93  else if (!_tcsicmp(arg[i], _T("DISABLEEXTENSIONS")))
95  else if (!_tcsicmp(arg[i], _T("ENABLEDELAYEDEXPANSION")))
97  else if (!_tcsicmp(arg[i], _T("DISABLEDELAYEDEXPANSION")))
99  else
100  {
102  break;
103  }
104  }
105  freep(arg);
106 
107  return nErrorLevel;
108 }
109 
111 {
112  LPTSTR Environ, Name, Value;
113  PSETLOCAL Saved;
114  TCHAR drvEnvVar[] = _T("=?:");
115  TCHAR szCurrent[MAX_PATH];
116 
117  if (!_tcscmp(param, _T("/?")))
118  {
119  // FIXME
120  ConOutPuts(_T("ENDLOCAL help not implemented yet!\n"));
121  return 0;
122  }
123 
124  /* Pop a SETLOCAL struct off of this batch context's stack */
125  if (!bc || !(Saved = bc->setlocal))
126  return 0;
127  bc->setlocal = Saved->Prev;
128 
131 
132  /* First, clear out the environment. Since making any changes to the
133  * environment invalidates pointers obtained from GetEnvironmentStrings(),
134  * we must make a copy of it and get the variable names from that. */
135  Environ = DuplicateEnvironment();
136  if (Environ)
137  {
138  for (Name = Environ; *Name; Name += _tcslen(Name) + 1)
139  {
140  if (!(Value = _tcschr(Name + 1, _T('='))))
141  continue;
142  *Value++ = _T('\0');
144  Name = Value;
145  }
146  cmd_free(Environ);
147  }
148 
149  /* Now, restore variables from the copy saved by cmd_setlocal() */
150  for (Name = Saved->Environment; *Name; Name += _tcslen(Name) + 1)
151  {
152  if (!(Value = _tcschr(Name + 1, _T('='))))
153  continue;
154  *Value++ = _T('\0');
156  Name = Value;
157  }
158 
159  /* Restore the current drive and its current directory from the environment */
160  drvEnvVar[1] = _T('A') + Saved->CurDrive - 1;
161  if (!GetEnvironmentVariable(drvEnvVar, szCurrent, ARRAYSIZE(szCurrent)))
162  {
163  _stprintf(szCurrent, _T("%C:\\"), _T('A') + Saved->CurDrive - 1);
164  }
165  _tchdir(szCurrent); // SetRootPath(NULL, szCurrent);
166 
167  cmd_free(Saved->Environment);
168  cmd_free(Saved);
169  return 0;
170 }
INT nErrorLevel
Definition: cmd.c:158
static int argc
Definition: ServiceArgs.c:12
INT cmd_setlocal(LPTSTR param)
Definition: setlocal.c:42
#define _tcsicmp
Definition: xmlstorage.h:205
int _tcscmp(const _TCHAR *s1, const _TCHAR *s2)
Definition: tcscmp.h:8
#define TRUE
Definition: types.h:120
#define WARN(fmt,...)
Definition: debug.h:112
_Check_return_ _CRTIMP int __cdecl _getdrive(void)
Definition: getdrive.c:20
LPTSTR * splitspace(LPTSTR, LPINT)
Definition: misc.c:381
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
void * arg
Definition: msvc.h:10
int32_t INT
Definition: typedefs.h:58
CHAR * LPTSTR
Definition: xmlstorage.h:192
IN UCHAR Value
Definition: halp.h:394
VOID error_invalid_parameter_format(PCTSTR s)
Definition: error.c:145
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 FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL EnableExtensions
Definition: setlocal.c:19
struct NameRec_ * Name
Definition: cdprocs.h:459
struct _SETLOCAL * setlocal
Definition: batch.h:42
size_t __cdecl _tcslen(const _TCHAR *str)
Definition: tcslen.h:9
static VOID freep(LPSTR *p)
Definition: cmdcons.c:98
smooth NULL
Definition: ftsmooth.c:416
VOID error_out_of_memory(VOID)
Definition: error.c:138
_TCHAR * _tcschr(const _TCHAR *s, _XINT c)
Definition: tcschr.h:4
char TCHAR
Definition: xmlstorage.h:189
#define _T(x)
Definition: vfdio.h:22
GLfloat param
Definition: glext.h:5796
#define MAX_PATH
Definition: compat.h:34
BOOL bEnableExtensions
Definition: cmd.c:161
struct _SETLOCAL * Prev
Definition: setlocal.c:16
BOOL DelayedExpansion
Definition: setlocal.c:20
LPTSTR DuplicateEnvironment(VOID)
Definition: setlocal.c:25
LPTSTR Environment
Definition: setlocal.c:17
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define SetEnvironmentVariable
Definition: winbase.h:3748
#define _stprintf
Definition: utility.h:124
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define cmd_free(ptr)
Definition: cmddbg.h:31
struct _SETLOCAL * PSETLOCAL
INT cmd_endlocal(LPTSTR param)
Definition: setlocal.c:110
BOOL bDelayedExpansion
Definition: cmd.c:162
LPSTR WINAPI GetEnvironmentStrings(void)
INT CurDrive
Definition: setlocal.c:18
#define GetEnvironmentVariable
Definition: winbase.h:3654
PBATCH_CONTEXT bc
Definition: batch.c:67
#define FreeEnvironmentStrings
Definition: winbase.h:3636
struct _SETLOCAL SETLOCAL
int _tchdir(const _TCHAR *_path)
Definition: chdir.c:8
VOID ConOutPuts(LPTSTR szText)
Definition: tee.c:27