update for HEAD-2003021201
[reactos.git] / subsys / system / usetup / filesup.c
1 /*
2  *  ReactOS kernel
3  *  Copyright (C) 2002 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
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19 /* $Id$
20  * COPYRIGHT:       See COPYING in the top level directory
21  * PROJECT:         ReactOS text-mode setup
22  * FILE:            subsys/system/usetup/filesup.c
23  * PURPOSE:         File support functions
24  * PROGRAMMER:      Eric Kohl
25  */
26
27 /* INCLUDES *****************************************************************/
28
29 #include <ddk/ntddk.h>
30 #include <ntdll/rtl.h>
31
32 #include "usetup.h"
33 #include "filesup.h"
34
35
36 /* FUNCTIONS ****************************************************************/
37
38
39 NTSTATUS
40 CreateDirectory(PWCHAR DirectoryName)
41 {
42   OBJECT_ATTRIBUTES ObjectAttributes;
43   IO_STATUS_BLOCK IoStatusBlock;
44   UNICODE_STRING PathName;
45   HANDLE DirectoryHandle;
46   NTSTATUS Status;
47
48   RtlCreateUnicodeString(&PathName,
49                          DirectoryName);
50
51   InitializeObjectAttributes(&ObjectAttributes,
52                              &PathName,
53                              OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
54                              NULL,
55                              NULL);
56
57   Status = NtCreateFile(&DirectoryHandle,
58                         DIRECTORY_ALL_ACCESS,
59                         &ObjectAttributes,
60                         &IoStatusBlock,
61                         NULL,
62                         FILE_ATTRIBUTE_DIRECTORY,
63                         0,
64                         FILE_CREATE,
65                         FILE_DIRECTORY_FILE,
66                         NULL,
67                         0);
68   if (NT_SUCCESS(Status))
69     {
70       NtClose(DirectoryHandle);
71     }
72
73   RtlFreeUnicodeString(&PathName);
74
75   return(Status);
76 }
77
78
79 NTSTATUS
80 SetupCopyFile(PWCHAR SourceFileName,
81               PWCHAR DestinationFileName)
82 {
83   OBJECT_ATTRIBUTES ObjectAttributes;
84   HANDLE FileHandleSource;
85   HANDLE FileHandleDest;
86   IO_STATUS_BLOCK IoStatusBlock;
87   FILE_STANDARD_INFORMATION FileStandard;
88   FILE_BASIC_INFORMATION FileBasic;
89   FILE_POSITION_INFORMATION FilePosition;
90   PUCHAR Buffer;
91   ULONG RegionSize;
92   UNICODE_STRING FileName;
93   NTSTATUS Status;
94
95   Buffer = NULL;
96
97   RtlInitUnicodeString(&FileName,
98                        SourceFileName);
99
100   InitializeObjectAttributes(&ObjectAttributes,
101                              &FileName,
102                              OBJ_CASE_INSENSITIVE,
103                              NULL,
104                              NULL);
105
106   Status = NtOpenFile(&FileHandleSource,
107                       FILE_READ_ACCESS,
108                       &ObjectAttributes,
109                       &IoStatusBlock,
110                       FILE_SHARE_READ,
111                       FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY);
112   if (!NT_SUCCESS(Status))
113     {
114 CHECKPOINT1;
115       return(Status);
116     }
117
118   Status = NtQueryInformationFile(FileHandleSource,
119                                   &IoStatusBlock,
120                                   &FileStandard,
121                                   sizeof(FILE_STANDARD_INFORMATION),
122                                   FileStandardInformation);
123   if (!NT_SUCCESS(Status))
124     {
125 CHECKPOINT1;
126      NtClose(FileHandleSource);
127      return(Status);
128     }
129
130   Status = NtQueryInformationFile(FileHandleSource,
131                                   &IoStatusBlock,&FileBasic,
132                                   sizeof(FILE_BASIC_INFORMATION),
133                                   FileBasicInformation);
134   if (!NT_SUCCESS(Status))
135     {
136 CHECKPOINT1;
137       NtClose(FileHandleSource);
138       return(Status);
139     }
140
141   RtlInitUnicodeString(&FileName,
142                        DestinationFileName);
143
144   InitializeObjectAttributes(&ObjectAttributes,
145                              &FileName,
146                              OBJ_CASE_INSENSITIVE,
147                              NULL,
148                              NULL);
149
150   Status = NtCreateFile(&FileHandleDest,
151                         FILE_WRITE_ACCESS,
152                         &ObjectAttributes,
153                         &IoStatusBlock,
154                         NULL,
155                         FILE_ATTRIBUTE_NORMAL,
156                         0,
157                         FILE_OVERWRITE_IF,
158                         FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
159                         NULL,
160                         0);
161   if (!NT_SUCCESS(Status))
162     {
163 CHECKPOINT1;
164       NtClose(FileHandleSource);
165       return(Status);
166     }
167
168   FilePosition.CurrentByteOffset.QuadPart = 0;
169
170   Status = NtSetInformationFile(FileHandleSource,
171                                 &IoStatusBlock,
172                                 &FilePosition,
173                                 sizeof(FILE_POSITION_INFORMATION),
174                                 FilePositionInformation);
175   if (!NT_SUCCESS(Status))
176     {
177 CHECKPOINT1;
178       NtClose(FileHandleSource);
179       NtClose(FileHandleDest);
180       return(Status);
181     }
182
183   Status = NtSetInformationFile(FileHandleDest,
184                                 &IoStatusBlock,
185                                 &FilePosition,
186                                 sizeof(FILE_POSITION_INFORMATION),
187                                 FilePositionInformation);
188   if (!NT_SUCCESS(Status))
189     {
190 CHECKPOINT1;
191       NtClose(FileHandleSource);
192       NtClose(FileHandleDest);
193       return(Status);
194     }
195
196   RegionSize = PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
197   if (RegionSize > 0x100000)
198     {
199       RegionSize = 0x100000;
200     }
201   Status = NtAllocateVirtualMemory(NtCurrentProcess(),
202                                    (PVOID *)&Buffer,
203                                    2,
204                                    &RegionSize,
205                                    MEM_RESERVE | MEM_COMMIT,
206                                    PAGE_READWRITE);
207   if (!NT_SUCCESS(Status))
208     {
209 CHECKPOINT1;
210       NtClose(FileHandleSource);
211       NtClose(FileHandleDest);
212       return(Status);
213     }
214
215   while (TRUE)
216     {
217       Status = NtReadFile(FileHandleSource,
218                           NULL,
219                           NULL,
220                           NULL,
221                           &IoStatusBlock,
222                           Buffer,
223                           RegionSize,
224                           NULL,
225                           NULL);
226       if (!NT_SUCCESS(Status))
227         {
228           NtFreeVirtualMemory(NtCurrentProcess(),
229                               (PVOID *)&Buffer,
230                               &RegionSize,
231                               MEM_RELEASE);
232           if (Status == STATUS_END_OF_FILE)
233             {
234               DPRINT("STATUS_END_OF_FILE\n");
235               break;
236             }
237 CHECKPOINT1;
238           NtClose(FileHandleSource);
239           NtClose(FileHandleDest);
240           return(Status);
241         }
242
243       DPRINT("Bytes read %lu\n", IoStatusBlock.Information);
244
245       Status = NtWriteFile(FileHandleDest,
246                            NULL,
247                            NULL,
248                            NULL,
249                            &IoStatusBlock,
250                            Buffer,
251                            IoStatusBlock.Information,
252                            NULL,
253                            NULL);
254       if (!NT_SUCCESS(Status))
255         {
256 CHECKPOINT1;
257           NtFreeVirtualMemory(NtCurrentProcess(),
258                               (PVOID *)&Buffer,
259                               &RegionSize,
260                               MEM_RELEASE);
261           NtClose(FileHandleSource);
262           NtClose(FileHandleDest);
263           return(Status);
264         }
265     }
266
267
268   /* Copy file date/time from source file */
269   Status = NtSetInformationFile(FileHandleDest,
270                                 &IoStatusBlock,
271                                 &FileBasic,
272                                 sizeof(FILE_BASIC_INFORMATION),
273                                 FileBasicInformation);
274   if (!NT_SUCCESS(Status))
275     {
276       DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status);
277     }
278
279   NtClose(FileHandleSource);
280   NtClose(FileHandleDest);
281
282   return(Status);
283 }
284
285
286 BOOLEAN
287 DoesFileExist(PWSTR PathName,
288               PWSTR FileName)
289 {
290   OBJECT_ATTRIBUTES ObjectAttributes;
291   IO_STATUS_BLOCK IoStatusBlock;
292   UNICODE_STRING Name;
293   WCHAR FullName[MAX_PATH];
294   HANDLE FileHandle;
295   NTSTATUS Status;
296
297   wcscpy(FullName, PathName);
298   if (FileName != NULL)
299     {
300       if (FileName[0] != L'\\')
301         wcscat(FullName, L"\\");
302       wcscat(FullName, FileName);
303     }
304
305   RtlInitUnicodeString(&Name,
306                        FullName);
307
308   InitializeObjectAttributes(&ObjectAttributes,
309                              &Name,
310                              OBJ_CASE_INSENSITIVE,
311                              NULL,
312                              NULL);
313
314   Status = NtOpenFile(&FileHandle,
315                       FILE_READ_ACCESS,
316                       &ObjectAttributes,
317                       &IoStatusBlock,
318                       0,
319                       FILE_SYNCHRONOUS_IO_ALERT);
320   if (!NT_SUCCESS(Status))
321     {
322 CHECKPOINT1;
323       return(FALSE);
324     }
325
326   NtClose(FileHandle);
327
328   return(TRUE);
329 }
330
331 /* EOF */