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