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