reshuffling of dlls
[reactos.git] / reactos / dll / 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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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 STDCALL
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 STDCALL
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 (!CreateDirectoryW (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 /* Copy file attributes */
159 if (FindFileData.dwFileAttributes & ~FILE_ATTRIBUTE_DIRECTORY)
160 {
161 SetFileAttributesW (szFullDstName,
162 FindFileData.dwFileAttributes);
163 }
164 }
165
166 if (!FindNextFileW (hFind, &FindFileData))
167 {
168 if (GetLastError () != ERROR_NO_MORE_FILES)
169 {
170 DPRINT1 ("Error: %lu\n", GetLastError());
171 }
172
173 break;
174 }
175 }
176
177 FindClose (hFind);
178
179 DPRINT ("Copy Directory() done\n");
180
181 return TRUE;
182 }
183
184
185 BOOL
186 CreateDirectoryPath (LPCWSTR lpPathName,
187 LPSECURITY_ATTRIBUTES lpSecurityAttributes)
188 {
189 WCHAR szPath[MAX_PATH];
190 LPWSTR Ptr;
191 DWORD dwError;
192
193 DPRINT ("CreateDirectoryPath() called\n");
194
195 if (lpPathName == NULL || *lpPathName == 0)
196 return TRUE;
197
198 if (CreateDirectoryW (lpPathName,
199 lpSecurityAttributes))
200 return TRUE;
201
202 dwError = GetLastError ();
203 if (dwError == ERROR_ALREADY_EXISTS)
204 return TRUE;
205
206 wcscpy (szPath, lpPathName);
207
208 if (wcslen(szPath) > 3 && szPath[1] == ':' && szPath[2] == '\\')
209 {
210 Ptr = &szPath[3];
211 }
212 else
213 {
214 Ptr = szPath;
215 }
216
217 while (Ptr != NULL)
218 {
219 Ptr = wcschr (Ptr, L'\\');
220 if (Ptr != NULL)
221 *Ptr = 0;
222
223 DPRINT ("CreateDirectory(%S)\n", szPath);
224 if (!CreateDirectoryW (szPath,
225 lpSecurityAttributes))
226 {
227 dwError = GetLastError ();
228 if (dwError != ERROR_ALREADY_EXISTS)
229 return FALSE;
230 }
231
232 if (Ptr != NULL)
233 {
234 *Ptr = L'\\';
235 Ptr++;
236 }
237 }
238
239 DPRINT ("CreateDirectoryPath() done\n");
240
241 return TRUE;
242 }
243
244
245 static BOOL
246 RecursiveRemoveDir (LPCWSTR lpPath)
247 {
248 WCHAR szPath[MAX_PATH];
249 WIN32_FIND_DATAW FindData;
250 HANDLE hFind;
251 BOOL bResult;
252
253 wcscpy (szPath, lpPath);
254 wcscat (szPath, L"\\*.*");
255 DPRINT ("Search path: '%S'\n", szPath);
256
257 hFind = FindFirstFileW (szPath,
258 &FindData);
259 if (hFind == INVALID_HANDLE_VALUE)
260 return FALSE;
261
262 bResult = TRUE;
263 while (TRUE)
264 {
265 if (wcscmp (FindData.cFileName, L".") &&
266 wcscmp (FindData.cFileName, L".."))
267 {
268 wcscpy (szPath, lpPath);
269 wcscat (szPath, L"\\");
270 wcscat (szPath, FindData.cFileName);
271 DPRINT ("File name: '%S'\n", szPath);
272
273 if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
274 {
275 DPRINT ("Delete directory: '%S'\n", szPath);
276
277 if (!RecursiveRemoveDir (szPath))
278 {
279 bResult = FALSE;
280 break;
281 }
282
283 if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
284 {
285 SetFileAttributesW (szPath,
286 FindData.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
287 }
288
289 if (!RemoveDirectoryW (szPath))
290 {
291 bResult = FALSE;
292 break;
293 }
294 }
295 else
296 {
297 DPRINT ("Delete file: '%S'\n", szPath);
298
299 if (FindData.dwFileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))
300 {
301 SetFileAttributesW (szPath,
302 FILE_ATTRIBUTE_NORMAL);
303 }
304
305 if (!DeleteFileW (szPath))
306 {
307 bResult = FALSE;
308 break;
309 }
310 }
311 }
312
313 if (!FindNextFileW (hFind, &FindData))
314 {
315 if (GetLastError () != ERROR_NO_MORE_FILES)
316 {
317 DPRINT1 ("Error: %lu\n", GetLastError());
318 bResult = FALSE;
319 break;
320 }
321
322 break;
323 }
324 }
325
326 FindClose (hFind);
327
328 return bResult;
329 }
330
331
332 BOOL
333 RemoveDirectoryPath (LPCWSTR lpPathName)
334 {
335 if (!RecursiveRemoveDir (lpPathName))
336 return FALSE;
337
338 DPRINT ("Delete directory: '%S'\n", lpPathName);
339 return RemoveDirectoryW (lpPathName);
340 }
341
342 /* EOF */