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