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 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 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 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 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 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 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