Fixed header inclusion order.
[reactos.git] / reactos / lib / kernel32 / file / copy.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/file/copy.c
5 * PURPOSE: Copying files
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * 01/11/98 Created
9 * 07/02/99 Moved to seperate file
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <windows.h>
16 #include <wchar.h>
17 #include <string.h>
18
19 #define NDEBUG
20 #include <kernel32/kernel32.h>
21
22 #define LPPROGRESS_ROUTINE void*
23
24 /* FUNCTIONS ****************************************************************/
25
26 WINBOOL STDCALL CopyFileExW(LPCWSTR lpExistingFileName,
27 LPCWSTR lpNewFileName,
28 LPPROGRESS_ROUTINE lpProgressRoutine,
29 LPVOID lpData,
30 WINBOOL * pbCancel,
31 DWORD dwCopyFlags)
32 {
33 NTSTATUS errCode = 0;
34 HANDLE FileHandleSource, FileHandleDest;
35 IO_STATUS_BLOCK IoStatusBlock;
36 FILE_STANDARD_INFORMATION FileStandard;
37 FILE_BASIC_INFORMATION FileBasic;
38 FILE_POSITION_INFORMATION FilePosition;
39 UCHAR *lpBuffer = NULL;
40 ULONG RegionSize = 0x1000000;
41 BOOL bCancel = FALSE;
42
43 FileHandleSource = CreateFileW(lpExistingFileName,
44 GENERIC_READ,
45 FILE_SHARE_READ,
46 NULL,
47 OPEN_EXISTING,
48 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
49 NULL);
50 if (FileHandleSource == NULL)
51 {
52 return(FALSE);
53 }
54
55 errCode = NtQueryInformationFile(FileHandleSource,
56 &IoStatusBlock,
57 &FileStandard,
58 sizeof(FILE_STANDARD_INFORMATION),
59 FileStandardInformation);
60 if (!NT_SUCCESS(errCode))
61 {
62 NtClose(FileHandleSource);
63 SetLastError(RtlNtStatusToDosError(errCode));
64 return FALSE;
65 }
66
67 errCode = NtQueryInformationFile(FileHandleSource,
68 &IoStatusBlock,&FileBasic,
69 sizeof(FILE_BASIC_INFORMATION),
70 FileBasicInformation);
71 if (!NT_SUCCESS(errCode))
72 {
73 NtClose(FileHandleSource);
74 SetLastError(RtlNtStatusToDosError(errCode));
75 return FALSE;
76 }
77
78 FileHandleDest = CreateFileW(lpNewFileName,
79 GENERIC_WRITE,
80 FILE_SHARE_WRITE,
81 NULL,
82 dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS ,
83 FileBasic.FileAttributes|FILE_FLAG_NO_BUFFERING,
84 NULL);
85 if (FileHandleDest == NULL)
86 {
87 return(FALSE);
88 }
89
90 FilePosition.CurrentByteOffset.QuadPart = 0;
91
92 errCode = NtSetInformationFile(FileHandleSource,
93 &IoStatusBlock,
94 &FilePosition,
95 sizeof(FILE_POSITION_INFORMATION),
96 FilePositionInformation);
97 if (!NT_SUCCESS(errCode))
98 {
99 NtClose(FileHandleSource);
100 NtClose(FileHandleDest);
101 SetLastError(RtlNtStatusToDosError(errCode));
102 return FALSE;
103 }
104
105 errCode = NtSetInformationFile(FileHandleDest,
106 &IoStatusBlock,
107 &FilePosition,
108 sizeof(FILE_POSITION_INFORMATION),
109 FilePositionInformation);
110 if (!NT_SUCCESS(errCode))
111 {
112 NtClose(FileHandleSource);
113 NtClose(FileHandleDest);
114 SetLastError(RtlNtStatusToDosError(errCode));
115 return FALSE;
116 }
117
118 errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
119 (PVOID *)&lpBuffer,
120 2,
121 &RegionSize,
122 MEM_COMMIT,
123 PAGE_READWRITE);
124
125 if (!NT_SUCCESS(errCode))
126 {
127 NtClose(FileHandleSource);
128 NtClose(FileHandleDest);
129 SetLastError(RtlNtStatusToDosError(errCode));
130 return FALSE;
131 }
132
133 do {
134 errCode = NtReadFile(FileHandleSource,
135 NULL,
136 NULL,
137 NULL,
138 (PIO_STATUS_BLOCK)&IoStatusBlock,
139 lpBuffer,
140 RegionSize,
141 NULL,
142 NULL);
143 if (pbCancel != NULL)
144 bCancel = *pbCancel;
145
146 if (!NT_SUCCESS(errCode) || bCancel)
147 {
148 NtFreeVirtualMemory(NtCurrentProcess(),
149 (PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE);
150 NtClose(FileHandleSource);
151 NtClose(FileHandleDest);
152 if ( errCode == STATUS_END_OF_FILE )
153 break;
154 else
155 return FALSE;
156 }
157
158 errCode = NtWriteFile(FileHandleDest,
159 NULL,
160 lpProgressRoutine,
161 lpData,
162 (PIO_STATUS_BLOCK)&IoStatusBlock,
163 lpBuffer,
164 RegionSize,
165 NULL,
166 NULL);
167
168 if (!NT_SUCCESS(errCode))
169 {
170 NtFreeVirtualMemory(NtCurrentProcess(),
171 (PVOID *)&lpBuffer,
172 &RegionSize,
173 MEM_RELEASE);
174 NtClose(FileHandleSource);
175 NtClose(FileHandleDest);
176 return FALSE;
177 }
178
179 } while ( TRUE );
180 return TRUE;
181 }
182
183 WINBOOL STDCALL CopyFileExA(LPCSTR lpExistingFileName,
184 LPCSTR lpNewFileName,
185 LPPROGRESS_ROUTINE lpProgressRoutine,
186 LPVOID lpData,
187 WINBOOL* pbCancel,
188 DWORD dwCopyFlags)
189 {
190 WCHAR ExistingFileNameW[MAX_PATH];
191 WCHAR NewFileNameW[MAX_PATH];
192
193 if (!KERNEL32_AnsiToUnicode(ExistingFileNameW,
194 lpExistingFileName,
195 MAX_PATH))
196 {
197 return(FALSE);
198 }
199 if (!KERNEL32_AnsiToUnicode(NewFileNameW,
200 lpNewFileName,
201 MAX_PATH))
202 {
203 return(FALSE);
204 }
205 return(CopyFileExW(ExistingFileNameW,
206 NewFileNameW,
207 lpProgressRoutine,
208 lpData,
209 pbCancel,
210 dwCopyFlags));
211 }
212
213
214 WINBOOL STDCALL CopyFileA(LPCSTR lpExistingFileName,
215 LPCSTR lpNewFileName,
216 WINBOOL bFailIfExists)
217 {
218 return CopyFileExA(lpExistingFileName,
219 lpNewFileName,
220 NULL,
221 NULL,
222 FALSE,
223 bFailIfExists);
224 }
225 WINBOOL STDCALL CopyFileW(LPCWSTR lpExistingFileName,
226 LPCWSTR lpNewFileName,
227 WINBOOL bFailIfExists)
228 {
229 return CopyFileExW(lpExistingFileName,
230 lpNewFileName,
231 NULL,
232 NULL,
233 NULL,
234 bFailIfExists);
235 }