Reverted latest changes.
[reactos.git] / reactos / lib / kernel32 / file / copy.c
1 /* $Id: copy.c,v 1.11 2002/09/08 10:22:41 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/copy.c
6 * PURPOSE: Copying files
7 * PROGRAMMER: Ariadne (ariadne@xs4all.nl)
8 * UPDATE HISTORY:
9 * 01/11/98 Created
10 * 07/02/99 Moved to seperate file
11 */
12
13 /* INCLUDES ****************************************************************/
14
15 #include <ddk/ntddk.h>
16 #include <windows.h>
17
18 #define NDEBUG
19 #include <kernel32/kernel32.h>
20 #include <kernel32/error.h>
21
22
23 #define LPPROGRESS_ROUTINE void*
24
25
26 /* FUNCTIONS ****************************************************************/
27
28 WINBOOL
29 STDCALL
30 CopyFileExW (
31 LPCWSTR lpExistingFileName,
32 LPCWSTR lpNewFileName,
33 LPPROGRESS_ROUTINE lpProgressRoutine,
34 LPVOID lpData,
35 WINBOOL *pbCancel,
36 DWORD dwCopyFlags
37 )
38 {
39 NTSTATUS errCode = 0;
40 HANDLE FileHandleSource, FileHandleDest;
41 IO_STATUS_BLOCK IoStatusBlock;
42 FILE_STANDARD_INFORMATION FileStandard;
43 FILE_BASIC_INFORMATION FileBasic;
44 FILE_POSITION_INFORMATION FilePosition;
45 UCHAR *lpBuffer = NULL;
46 ULONG RegionSize = 0x1000000;
47 BOOL bCancel = FALSE;
48
49 FileHandleSource = CreateFileW(lpExistingFileName,
50 GENERIC_READ,
51 FILE_SHARE_READ,
52 NULL,
53 OPEN_EXISTING,
54 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
55 NULL);
56 if (FileHandleSource == NULL)
57 {
58 return(FALSE);
59 }
60
61 errCode = NtQueryInformationFile(FileHandleSource,
62 &IoStatusBlock,
63 &FileStandard,
64 sizeof(FILE_STANDARD_INFORMATION),
65 FileStandardInformation);
66 if (!NT_SUCCESS(errCode))
67 {
68 NtClose(FileHandleSource);
69 SetLastErrorByStatus(errCode);
70 return FALSE;
71 }
72
73 errCode = NtQueryInformationFile(FileHandleSource,
74 &IoStatusBlock,&FileBasic,
75 sizeof(FILE_BASIC_INFORMATION),
76 FileBasicInformation);
77 if (!NT_SUCCESS(errCode))
78 {
79 NtClose(FileHandleSource);
80 SetLastErrorByStatus(errCode);
81 return FALSE;
82 }
83
84 FileHandleDest = CreateFileW(lpNewFileName,
85 GENERIC_WRITE,
86 FILE_SHARE_WRITE,
87 NULL,
88 dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS,
89 FileBasic.FileAttributes|FILE_FLAG_NO_BUFFERING,
90 NULL);
91 if (FileHandleDest == NULL)
92 {
93 return(FALSE);
94 }
95
96 FilePosition.CurrentByteOffset.QuadPart = 0;
97
98 errCode = NtSetInformationFile(FileHandleSource,
99 &IoStatusBlock,
100 &FilePosition,
101 sizeof(FILE_POSITION_INFORMATION),
102 FilePositionInformation);
103 if (!NT_SUCCESS(errCode))
104 {
105 NtClose(FileHandleSource);
106 NtClose(FileHandleDest);
107 SetLastErrorByStatus(errCode);
108 return FALSE;
109 }
110
111 errCode = NtSetInformationFile(FileHandleDest,
112 &IoStatusBlock,
113 &FilePosition,
114 sizeof(FILE_POSITION_INFORMATION),
115 FilePositionInformation);
116 if (!NT_SUCCESS(errCode))
117 {
118 NtClose(FileHandleSource);
119 NtClose(FileHandleDest);
120 SetLastErrorByStatus(errCode);
121 return FALSE;
122 }
123
124 errCode = NtAllocateVirtualMemory(NtCurrentProcess(),
125 (PVOID *)&lpBuffer,
126 2,
127 &RegionSize,
128 MEM_RESERVE | MEM_COMMIT,
129 PAGE_READWRITE);
130
131 if (!NT_SUCCESS(errCode))
132 {
133 NtClose(FileHandleSource);
134 NtClose(FileHandleDest);
135 SetLastErrorByStatus(errCode);
136 return FALSE;
137 }
138
139 do {
140 errCode = NtReadFile(FileHandleSource,
141 NULL,
142 NULL,
143 NULL,
144 (PIO_STATUS_BLOCK)&IoStatusBlock,
145 lpBuffer,
146 RegionSize,
147 NULL,
148 NULL);
149 if (pbCancel != NULL)
150 bCancel = *pbCancel;
151
152 if (!NT_SUCCESS(errCode) || bCancel)
153 {
154 NtFreeVirtualMemory(NtCurrentProcess(),
155 (PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE);
156 NtClose(FileHandleSource);
157 NtClose(FileHandleDest);
158 if ( errCode == STATUS_END_OF_FILE )
159 break;
160 else
161 return FALSE;
162 }
163
164 errCode = NtWriteFile(FileHandleDest,
165 NULL,
166 lpProgressRoutine,
167 lpData,
168 (PIO_STATUS_BLOCK)&IoStatusBlock,
169 lpBuffer,
170 IoStatusBlock.Information,
171 NULL,
172 NULL);
173
174 if (!NT_SUCCESS(errCode))
175 {
176 NtFreeVirtualMemory(NtCurrentProcess(),
177 (PVOID *)&lpBuffer,
178 &RegionSize,
179 MEM_RELEASE);
180 NtClose(FileHandleSource);
181 NtClose(FileHandleDest);
182 return FALSE;
183 }
184
185 } while ( TRUE );
186 return TRUE;
187 }
188
189
190 WINBOOL
191 STDCALL
192 CopyFileExA (
193 LPCSTR lpExistingFileName,
194 LPCSTR lpNewFileName,
195 LPPROGRESS_ROUTINE lpProgressRoutine,
196 LPVOID lpData,
197 WINBOOL *pbCancel,
198 DWORD dwCopyFlags
199 )
200 {
201 UNICODE_STRING ExistingFileNameU;
202 UNICODE_STRING NewFileNameU;
203 ANSI_STRING ExistingFileName;
204 ANSI_STRING NewFileName;
205 WINBOOL Result;
206
207 RtlInitAnsiString (&ExistingFileName,
208 (LPSTR)lpExistingFileName);
209
210 RtlInitAnsiString (&NewFileName,
211 (LPSTR)lpNewFileName);
212
213 /* convert ansi (or oem) string to unicode */
214 if (bIsFileApiAnsi)
215 {
216 RtlAnsiStringToUnicodeString (&ExistingFileNameU,
217 &ExistingFileName,
218 TRUE);
219 RtlAnsiStringToUnicodeString (&NewFileNameU,
220 &NewFileName,
221 TRUE);
222 }
223 else
224 {
225 RtlOemStringToUnicodeString (&ExistingFileNameU,
226 &ExistingFileName,
227 TRUE);
228 RtlOemStringToUnicodeString (&NewFileNameU,
229 &NewFileName,
230 TRUE);
231 }
232
233 Result = CopyFileExW (ExistingFileNameU.Buffer,
234 NewFileNameU.Buffer,
235 lpProgressRoutine,
236 lpData,
237 pbCancel,
238 dwCopyFlags);
239
240 RtlFreeHeap (RtlGetProcessHeap (),
241 0,
242 ExistingFileNameU.Buffer);
243 RtlFreeHeap (RtlGetProcessHeap (),
244 0,
245 NewFileNameU.Buffer);
246
247 return Result;
248 }
249
250
251 WINBOOL
252 STDCALL
253 CopyFileA (
254 LPCSTR lpExistingFileName,
255 LPCSTR lpNewFileName,
256 WINBOOL bFailIfExists
257 )
258 {
259 return CopyFileExA (lpExistingFileName,
260 lpNewFileName,
261 NULL,
262 NULL,
263 NULL,
264 bFailIfExists);
265 }
266
267
268 WINBOOL
269 STDCALL
270 CopyFileW (
271 LPCWSTR lpExistingFileName,
272 LPCWSTR lpNewFileName,
273 WINBOOL bFailIfExists
274 )
275 {
276 return CopyFileExW (lpExistingFileName,
277 lpNewFileName,
278 NULL,
279 NULL,
280 NULL,
281 bFailIfExists);
282 }
283
284 /* EOF */