some more win32k 64 bit fixes
[reactos.git] / reactos / base / shell / cmd / ren.c
1 /*
2 * REN.C - rename internal command.
3 *
4 *
5 * History:
6 *
7 * 27-Jul-1998 (John P Price <linux-guru@gcfl.net>)
8 * added config.h include
9 *
10 * 18-Dec-1998 (Eric Kohl)
11 * Added support for quoted long file names with spaces.
12 *
13 * 20-Jan-1999 (Eric Kohl)
14 * Unicode and redirection safe!
15 *
16 * 17-Oct-2001 (Eric Kohl)
17 * Implemented basic rename code.
18 *
19 * 30-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
20 * Remove all hardcode string to En.rc
21 */
22
23 #include <precomp.h>
24
25 #ifdef INCLUDE_CMD_RENAME
26
27 enum
28 {
29 REN_ATTRIBUTES = 0x001, /* /A : not implemented */
30 REN_ERROR = 0x002, /* /E */
31 REN_NOTHING = 0x004, /* /N */
32 REN_PROMPT = 0x008, /* /P : not implemented */
33 REN_QUIET = 0x010, /* /Q */
34 REN_SUBDIR = 0x020, /* /S */
35 REN_TOTAL = 0x040, /* /T */
36 };
37
38
39 /*
40 * file rename internal command.
41 *
42 */
43 INT cmd_rename (LPTSTR cmd, LPTSTR param)
44 {
45 TCHAR szMsg[RC_STRING_MAX_SIZE];
46 LPTSTR *arg = NULL;
47 INT args = 0;
48 INT nEvalArgs = 0; /* nunber of evaluated arguments */
49 DWORD dwFlags = 0;
50 DWORD dwFiles = 0; /* number of renamedd files */
51 INT i;
52 LPTSTR srcPattern = NULL;
53 LPTSTR dstPattern = NULL;
54 TCHAR dstFile[MAX_PATH];
55 BOOL bDstWildcard = FALSE;
56
57 LPTSTR p,q,r;
58
59 HANDLE hFile;
60 WIN32_FIND_DATA f;
61
62 if (!_tcsncmp(param, _T("/?"), 2))
63 {
64 ConOutResPaging(TRUE,STRING_REN_HELP1);
65 return 0;
66 }
67
68 nErrorLevel = 0;
69
70 /* split the argument list */
71 arg = split(param, &args, FALSE);
72
73 if (args < 2)
74 {
75 if (!(dwFlags & REN_ERROR))
76 error_req_param_missing();
77 freep(arg);
78 return 1;
79 }
80
81 /* read options */
82 for (i = 0; i < args; i++)
83 {
84 if (*arg[i] == _T('/'))
85 {
86 if (_tcslen(arg[i]) >= 2)
87 {
88 switch (_totupper(arg[i][1]))
89 {
90 case _T('E'):
91 dwFlags |= REN_ERROR;
92 break;
93
94 case _T('N'):
95 dwFlags |= REN_NOTHING;
96 break;
97
98 case _T('P'):
99 dwFlags |= REN_PROMPT;
100 break;
101
102 case _T('Q'):
103 dwFlags |= REN_QUIET;
104 break;
105
106 case _T('S'):
107 dwFlags |= REN_SUBDIR;
108 break;
109
110 case _T('T'):
111 dwFlags |= REN_TOTAL;
112 break;
113 }
114 }
115 nEvalArgs++;
116 }
117 }
118
119 /* keep quiet within batch files */
120 if (bc != NULL)
121 dwFlags |= REN_QUIET;
122
123 /* there are only options on the command line --> error!!! */
124 if (args < nEvalArgs + 2)
125 {
126 if (!(dwFlags & REN_ERROR))
127 error_req_param_missing();
128 freep(arg);
129 return 1;
130 }
131
132 /* get destination pattern */
133 for (i = 0; i < args; i++)
134 {
135 if (*arg[i] == _T('/'))
136 continue;
137 dstPattern = arg[i];
138 }
139
140 if (_tcschr(dstPattern, _T('*')) || _tcschr(dstPattern, _T('?')))
141 bDstWildcard = TRUE;
142
143 /* enumerate source patterns */
144 for (i = 0; i < args; i++)
145 {
146 if (*arg[i] == _T('/') || arg[i] == dstPattern)
147 continue;
148
149 srcPattern = arg[i];
150
151 TRACE("\n\nSourcePattern: %s\n", debugstr_aw(srcPattern));
152 TRACE("DestinationPattern: %s\n", debugstr_aw(dstPattern));
153
154 hFile = FindFirstFile(srcPattern, &f);
155 if (hFile == INVALID_HANDLE_VALUE)
156 {
157 if (!(dwFlags & REN_ERROR))
158 error_file_not_found();
159 continue;
160 }
161
162 do
163 {
164 /* ignore "." and ".." */
165 if (!_tcscmp (f.cFileName, _T(".")) ||
166 !_tcscmp (f.cFileName, _T("..")))
167 continue;
168
169 /* do not rename hidden or system files */
170 if (f.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM))
171 continue;
172
173 /* do not rename directories when the destination pattern contains
174 * wildcards, unless option /S is used */
175 if ((f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
176 && bDstWildcard
177 && !(dwFlags & REN_SUBDIR))
178 continue;
179
180 TRACE("Found source name: %s\n", debugstr_aw(f.cFileName));
181
182 /* build destination file name */
183 p = f.cFileName;
184 q = dstPattern;
185 r = dstFile;
186 while(*q != 0)
187 {
188 if (*q == '*')
189 {
190 q++;
191 while (*p != 0 && *p != *q)
192 {
193 *r = *p;
194 p++;
195 r++;
196 }
197 }
198 else if (*q == '?')
199 {
200 q++;
201 if (*p != 0)
202 {
203 *r = *p;
204 p++;
205 r++;
206 }
207 }
208 else
209 {
210 *r = *q;
211 if (*p != 0)
212 p++;
213 q++;
214 r++;
215 }
216 }
217 *r = 0;
218
219 TRACE("DestinationFile: %s\n", debugstr_aw(dstFile));
220
221 if (!(dwFlags & REN_QUIET) && !(dwFlags & REN_TOTAL))
222 ConOutPrintf(_T("%s -> %s\n"), f.cFileName, dstFile);
223
224 /* rename the file */
225 if (!(dwFlags & REN_NOTHING))
226 {
227 if (MoveFile(f.cFileName, dstFile))
228 {
229 dwFiles++;
230 }
231 else
232 {
233 if (!(dwFlags & REN_ERROR))
234 {
235 LoadString(CMD_ModuleHandle, STRING_REN_ERROR1, szMsg, RC_STRING_MAX_SIZE);
236 ConErrPrintf(szMsg, GetLastError());
237 }
238 }
239 }
240 }
241 while (FindNextFile(hFile, &f));
242 FindClose(hFile);
243 }
244
245 if (!(dwFlags & REN_QUIET))
246 {
247 if (dwFiles == 1)
248 LoadString( CMD_ModuleHandle, STRING_REN_HELP2, szMsg, RC_STRING_MAX_SIZE);
249 else
250 LoadString( CMD_ModuleHandle, STRING_REN_HELP3, szMsg, RC_STRING_MAX_SIZE);
251 ConOutPrintf(szMsg,dwFiles);
252 }
253
254 freep(arg);
255
256 return 0;
257 }
258
259 #endif
260
261 /* EOF */