c42030b5b21967c243bd7f3f86f84562acf1ca40
[reactos.git] / reactos / dll / win32 / userenv / directory.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2004 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS system libraries
22 * FILE: lib/userenv/directory.c
23 * PURPOSE: User profile code
24 * PROGRAMMER: Eric Kohl
25 */
26
27 #include "precomp.h"
28
29 #define NDEBUG
30 #include <debug.h>
31
32
33 /* FUNCTIONS ***************************************************************/
34
35 BOOL WINAPI
36 CopyProfileDirectoryA(LPCSTR lpSourcePath,
37 LPCSTR lpDestinationPath,
38 DWORD dwFlags)
39 {
40 UNICODE_STRING SrcPath;
41 UNICODE_STRING DstPath;
42 NTSTATUS Status;
43 BOOL bResult;
44
45 Status = RtlCreateUnicodeStringFromAsciiz(&SrcPath,
46 (LPSTR)lpSourcePath);
47 if (!NT_SUCCESS(Status))
48 {
49 SetLastError (RtlNtStatusToDosError (Status));
50 return FALSE;
51 }
52
53 Status = RtlCreateUnicodeStringFromAsciiz(&DstPath,
54 (LPSTR)lpDestinationPath);
55 if (!NT_SUCCESS(Status))
56 {
57 RtlFreeUnicodeString(&SrcPath);
58 SetLastError (RtlNtStatusToDosError (Status));
59 return FALSE;
60 }
61
62 bResult = CopyProfileDirectoryW(SrcPath.Buffer,
63 DstPath.Buffer,
64 dwFlags);
65
66 RtlFreeUnicodeString(&DstPath);
67 RtlFreeUnicodeString(&SrcPath);
68
69 return bResult;
70 }
71
72
73 BOOL WINAPI
74 CopyProfileDirectoryW(LPCWSTR lpSourcePath,
75 LPCWSTR lpDestinationPath,
76 DWORD dwFlags)
77 {
78 /* FIXME: dwFlags are ignored! */
79 return CopyDirectory(lpDestinationPath, lpSourcePath);
80 }
81
82
83 BOOL
84 CopyDirectory (LPCWSTR lpDestinationPath,
85 LPCWSTR lpSourcePath)
86 {
87 WCHAR szFileName[MAX_PATH];
88 WCHAR szFullSrcName[MAX_PATH];
89 WCHAR szFullDstName[MAX_PATH];
90 WIN32_FIND_DATAW FindFileData;
91 LPWSTR lpSrcPtr;
92 LPWSTR lpDstPtr;
93 HANDLE hFind;
94
95 DPRINT ("CopyDirectory (%S, %S) called\n",
96 lpDestinationPath, lpSourcePath);
97
98 wcscpy (szFileName, lpSourcePath);
99 wcscat (szFileName, L"\\*.*");
100
101 hFind = FindFirstFileW (szFileName,
102 &FindFileData);
103 if (hFind == INVALID_HANDLE_VALUE)
104 {
105 DPRINT1 ("Error: %lu\n", GetLastError());
106 return FALSE;
107 }
108
109 wcscpy (szFullSrcName, lpSourcePath);
110 lpSrcPtr = AppendBackslash (szFullSrcName);
111
112 wcscpy (szFullDstName, lpDestinationPath);
113 lpDstPtr = AppendBackslash (szFullDstName);
114
115 for (;;)
116 {
117 if (wcscmp (FindFileData.cFileName, L".") &&
118 wcscmp (FindFileData.cFileName, L".."))
119 {
120 wcscpy (lpSrcPtr, FindFileData.cFileName);
121 wcscpy (lpDstPtr, FindFileData.cFileName);
122
123 if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
124 {
125 DPRINT ("Create directory: %S\n", szFullDstName);
126 if (!CreateDirectoryExW (szFullSrcName, szFullDstName, NULL))
127 {
128 if (GetLastError () != ERROR_ALREADY_EXISTS)
129 {
130 DPRINT1 ("Error: %lu\n", GetLastError());
131
132 FindClose (hFind);
133 return FALSE;
134 }
135 }
136
137 if (!CopyDirectory (szFullDstName, szFullSrcName))
138 {
139 DPRINT1 ("Error: %lu\n", GetLastError());
140
141 FindClose (hFind);
142 return FALSE;
143 }
144 }
145 else
146 {
147 DPRINT ("Copy file: %S -> %S\n", szFullSrcName, szFullDstName);
148 if (!CopyFileW (szFullSrcName, szFullDstName, FALSE))
149 {
150 DPRINT1 ("Error: %lu\n", GetLastError());
151
152 FindClose (hFind);
153 return FALSE;
154 }
155 }
156 }
157
158 if (!FindNextFileW (hFind, &FindFileData))
159 {
160 if (GetLastError () != ERROR_NO_MORE_FILES)
161 {
162 DPRINT1 ("Error: %lu\n", GetLastError());
163 }
164
165 break;
166 }
167 }
168
169 FindClose (hFind);
170
171 DPRINT ("CopyDirectory() done\n");
172
173 return TRUE;
174 }
175
176
177 BOOL
178 CreateDirectoryPath (LPCWSTR lpPathName,
179 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
180 {
181 WCHAR szPath[MAX_PATH];
182 LPWSTR Ptr;
183 DWORD dwError;
184
185 DPRINT ("CreateDirectoryPath() called\n");
186
187 if (lpPathName == NULL || *lpPathName == 0)
188 return TRUE;
189
190 if (CreateDirectoryW (lpPathName,
191 lpSecurityAttributes))
192 return TRUE;
193
194 dwError = GetLastError ();
195 if (dwError == ERROR_ALREADY_EXISTS)
196 return TRUE;
197
198 wcscpy (szPath, lpPathName);
199
200 if (wcslen(szPath) > 3 && szPath[1] == ':' && szPath[2] == '\\')
201 {
202 Ptr = &szPath[3];
203 }
204 else
205 {
206 Ptr = szPath;
207 }
208
209 while (Ptr != NULL)
210 {
211 Ptr = wcschr (Ptr, L'\\');
212 if (Ptr != NULL)
213 *Ptr = 0;
214
215 DPRINT ("CreateDirectory(%S)\n", szPath);
216 if (!CreateDirectoryW (szPath,
217 lpSecurityAttributes))
218 {
219 dwError = GetLastError ();
220 if (dwError != ERROR_ALREADY_EXISTS)
221 return FALSE;
222 }
223
224 if (Ptr != NULL)
225 {
226 *Ptr = L'\\';
227 Ptr++;
228 }
229 }
230
231 DPRINT ("CreateDirectoryPath() done\n");
232
233 return TRUE;
234 }
235
236
237 static BOOL
238 RecursiveRemoveDir (LPCWSTR lpPath)
239 {
240 WCHAR szPath[MAX_PATH];
241 WIN32_FIND_DATAW FindData;
242 HANDLE hFind;
243 BOOL bResult;
244
245 wcscpy (szPath, lpPath);
246 wcscat (szPath, L"\\*.*");
247 DPRINT ("Search path: '%S'\n", szPath);
248
249 hFind = FindFirstFileW (szPath,
250 &FindData);
251 if (hFind == INVALID_HANDLE_VALUE)
252 return FALSE;
253
254 bResult = TRUE;
255 while (TRUE)
256 {
257 if (wcscmp (FindData.cFileName, L".") &&
258 wcscmp (FindData.cFileName, L".."))
259 {
260 wcscpy (szPath, lpPath);
261 wcscat (szPath, L"\\");
262 wcscat (szPath, FindData.cFileName);
263 DPRINT ("File name: '%S'\n", szPath);
264
265 if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
266 {
267 DPRINT ("Delete directory: '%S'\n", szPath);
268
269 if (!RecursiveRemoveDir (szPath))
270 {
271 bResult = FALSE;
272 break;
273 }
274
275 if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
276 {
277 SetFileAttributesW (szPath,
278 FindData.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
279 }
280
281 if (!RemoveDirectoryW (szPath))
282 {
283 bResult = FALSE;
284 break;
285 }
286 }
287 else
288 {
289 DPRINT ("Delete file: '%S'\n", szPath);
290
291 if (FindData.dwFileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))
292 {
293 SetFileAttributesW (szPath,
294 FILE_ATTRIBUTE_NORMAL);
295 }
296
297 if (!DeleteFileW (szPath))
298 {
299 bResult = FALSE;
300 break;
301 }
302 }
303 }
304
305 if (!FindNextFileW (hFind, &FindData))
306 {
307 if (GetLastError () != ERROR_NO_MORE_FILES)
308 {
309 DPRINT1 ("Error: %lu\n", GetLastError());
310 bResult = FALSE;
311 break;
312 }
313
314 break;
315 }
316 }
317
318 FindClose (hFind);
319
320 return bResult;
321 }
322
323
324 BOOL
325 RemoveDirectoryPath (LPCWSTR lpPathName)
326 {
327 if (!RecursiveRemoveDir (lpPathName))
328 return FALSE;
329
330 DPRINT ("Delete directory: '%S'\n", lpPathName);
331 return RemoveDirectoryW (lpPathName);
332 }
333
334 /* EOF */