mirror of
https://github.com/reactos/reactos.git
synced 2024-11-28 05:53:31 +08:00
334 lines
8.3 KiB
C
334 lines
8.3 KiB
C
/*
|
|
* ReactOS kernel
|
|
* Copyright (C) 2004 ReactOS Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*/
|
|
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS system libraries
|
|
* FILE: dll/win32/userenv/directory.c
|
|
* PURPOSE: User profile code
|
|
* PROGRAMMER: Eric Kohl
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
#define NDEBUG
|
|
#include <debug.h>
|
|
|
|
/* FUNCTIONS ***************************************************************/
|
|
|
|
BOOL
|
|
WINAPI
|
|
CopyProfileDirectoryA(LPCSTR lpSourcePath,
|
|
LPCSTR lpDestinationPath,
|
|
DWORD dwFlags)
|
|
{
|
|
UNICODE_STRING SrcPath;
|
|
UNICODE_STRING DstPath;
|
|
BOOL bResult;
|
|
|
|
if (!RtlCreateUnicodeStringFromAsciiz(&SrcPath,
|
|
(LPSTR)lpSourcePath))
|
|
{
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
return FALSE;
|
|
}
|
|
|
|
if (!RtlCreateUnicodeStringFromAsciiz(&DstPath,
|
|
(LPSTR)lpDestinationPath))
|
|
{
|
|
RtlFreeUnicodeString(&SrcPath);
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
return FALSE;
|
|
}
|
|
|
|
bResult = CopyProfileDirectoryW(SrcPath.Buffer,
|
|
DstPath.Buffer,
|
|
dwFlags);
|
|
|
|
RtlFreeUnicodeString(&DstPath);
|
|
RtlFreeUnicodeString(&SrcPath);
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
BOOL
|
|
WINAPI
|
|
CopyProfileDirectoryW(LPCWSTR lpSourcePath,
|
|
LPCWSTR lpDestinationPath,
|
|
DWORD dwFlags)
|
|
{
|
|
/* FIXME: dwFlags are ignored! */
|
|
return CopyDirectory(lpDestinationPath, lpSourcePath);
|
|
}
|
|
|
|
|
|
BOOL
|
|
CopyDirectory(LPCWSTR lpDestinationPath,
|
|
LPCWSTR lpSourcePath)
|
|
{
|
|
WCHAR szFileName[MAX_PATH];
|
|
WCHAR szFullSrcName[MAX_PATH];
|
|
WCHAR szFullDstName[MAX_PATH];
|
|
WIN32_FIND_DATAW FindFileData;
|
|
LPWSTR lpSrcPtr;
|
|
LPWSTR lpDstPtr;
|
|
HANDLE hFind;
|
|
|
|
DPRINT("CopyDirectory (%S, %S) called\n",
|
|
lpDestinationPath, lpSourcePath);
|
|
|
|
wcscpy(szFileName, lpSourcePath);
|
|
wcscat(szFileName, L"\\*.*");
|
|
|
|
hFind = FindFirstFileW(szFileName,
|
|
&FindFileData);
|
|
if (hFind == INVALID_HANDLE_VALUE)
|
|
{
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
return FALSE;
|
|
}
|
|
|
|
wcscpy(szFullSrcName, lpSourcePath);
|
|
lpSrcPtr = AppendBackslash(szFullSrcName);
|
|
|
|
wcscpy(szFullDstName, lpDestinationPath);
|
|
lpDstPtr = AppendBackslash(szFullDstName);
|
|
|
|
for (;;)
|
|
{
|
|
if (wcscmp(FindFileData.cFileName, L".") &&
|
|
wcscmp(FindFileData.cFileName, L".."))
|
|
{
|
|
wcscpy(lpSrcPtr, FindFileData.cFileName);
|
|
wcscpy(lpDstPtr, FindFileData.cFileName);
|
|
|
|
if (FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
DPRINT("Create directory: %S\n", szFullDstName);
|
|
if (!CreateDirectoryExW(szFullSrcName, szFullDstName, NULL))
|
|
{
|
|
if (GetLastError() != ERROR_ALREADY_EXISTS)
|
|
{
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
FindClose(hFind);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
if (!CopyDirectory(szFullDstName, szFullSrcName))
|
|
{
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
FindClose(hFind);
|
|
return FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPRINT("Copy file: %S -> %S\n", szFullSrcName, szFullDstName);
|
|
if (!CopyFileW(szFullSrcName, szFullDstName, FALSE))
|
|
{
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
|
|
FindClose(hFind);
|
|
return FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!FindNextFileW(hFind, &FindFileData))
|
|
{
|
|
if (GetLastError() != ERROR_NO_MORE_FILES)
|
|
{
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
FindClose(hFind);
|
|
|
|
DPRINT("CopyDirectory() done\n");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
BOOL
|
|
CreateDirectoryPath(LPCWSTR lpPathName,
|
|
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
|
{
|
|
WCHAR szPath[MAX_PATH];
|
|
LPWSTR Ptr;
|
|
DWORD dwError;
|
|
|
|
DPRINT("CreateDirectoryPath() called\n");
|
|
|
|
if (lpPathName == NULL || *lpPathName == 0)
|
|
return TRUE;
|
|
|
|
if (CreateDirectoryW(lpPathName,
|
|
lpSecurityAttributes))
|
|
return TRUE;
|
|
|
|
dwError = GetLastError();
|
|
if (dwError == ERROR_ALREADY_EXISTS)
|
|
return TRUE;
|
|
|
|
wcscpy(szPath, lpPathName);
|
|
|
|
if (wcslen(szPath) > 3 && szPath[1] == ':' && szPath[2] == '\\')
|
|
{
|
|
Ptr = &szPath[3];
|
|
}
|
|
else
|
|
{
|
|
Ptr = szPath;
|
|
}
|
|
|
|
while (Ptr != NULL)
|
|
{
|
|
Ptr = wcschr(Ptr, L'\\');
|
|
if (Ptr != NULL)
|
|
*Ptr = 0;
|
|
|
|
DPRINT("CreateDirectory(%S)\n", szPath);
|
|
if (!CreateDirectoryW(szPath,
|
|
lpSecurityAttributes))
|
|
{
|
|
dwError = GetLastError();
|
|
if (dwError != ERROR_ALREADY_EXISTS)
|
|
return FALSE;
|
|
}
|
|
|
|
if (Ptr != NULL)
|
|
{
|
|
*Ptr = L'\\';
|
|
Ptr++;
|
|
}
|
|
}
|
|
|
|
DPRINT("CreateDirectoryPath() done\n");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
static
|
|
BOOL
|
|
RecursiveRemoveDir(LPCWSTR lpPath)
|
|
{
|
|
WCHAR szPath[MAX_PATH];
|
|
WIN32_FIND_DATAW FindData;
|
|
HANDLE hFind;
|
|
BOOL bResult;
|
|
|
|
wcscpy(szPath, lpPath);
|
|
wcscat(szPath, L"\\*.*");
|
|
DPRINT("Search path: '%S'\n", szPath);
|
|
|
|
hFind = FindFirstFileW(szPath,
|
|
&FindData);
|
|
if (hFind == INVALID_HANDLE_VALUE)
|
|
return FALSE;
|
|
|
|
bResult = TRUE;
|
|
while (TRUE)
|
|
{
|
|
if (wcscmp(FindData.cFileName, L".") &&
|
|
wcscmp(FindData.cFileName, L".."))
|
|
{
|
|
wcscpy(szPath, lpPath);
|
|
wcscat(szPath, L"\\");
|
|
wcscat(szPath, FindData.cFileName);
|
|
DPRINT("File name: '%S'\n", szPath);
|
|
|
|
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
{
|
|
DPRINT("Delete directory: '%S'\n", szPath);
|
|
|
|
if (!RecursiveRemoveDir(szPath))
|
|
{
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
|
|
if (FindData.dwFileAttributes & FILE_ATTRIBUTE_READONLY)
|
|
{
|
|
SetFileAttributesW(szPath,
|
|
FindData.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY);
|
|
}
|
|
|
|
if (!RemoveDirectoryW(szPath))
|
|
{
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DPRINT("Delete file: '%S'\n", szPath);
|
|
|
|
if (FindData.dwFileAttributes & (FILE_ATTRIBUTE_READONLY | FILE_ATTRIBUTE_SYSTEM))
|
|
{
|
|
SetFileAttributesW(szPath,
|
|
FILE_ATTRIBUTE_NORMAL);
|
|
}
|
|
|
|
if (!DeleteFileW(szPath))
|
|
{
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!FindNextFileW(hFind, &FindData))
|
|
{
|
|
if (GetLastError() != ERROR_NO_MORE_FILES)
|
|
{
|
|
DPRINT1("Error: %lu\n", GetLastError());
|
|
bResult = FALSE;
|
|
break;
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
FindClose(hFind);
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
BOOL
|
|
RemoveDirectoryPath(LPCWSTR lpPathName)
|
|
{
|
|
if (!RecursiveRemoveDir(lpPathName))
|
|
return FALSE;
|
|
|
|
DPRINT("Delete directory: '%S'\n", lpPathName);
|
|
return RemoveDirectoryW(lpPathName);
|
|
}
|
|
|
|
/* EOF */
|