3 * Copyright (C) 2002 ReactOS Team
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.
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.
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.
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 * Casper S. Hornstrup (chorns@users.sourceforge.net)
28 /* INCLUDES *****************************************************************/
30 #include <ddk/ntddk.h>
31 #include <ntdll/rtl.h>
38 /* FUNCTIONS ****************************************************************/
41 static BOOLEAN HasCurrentCabinet = FALSE;
42 static WCHAR CurrentCabinetName[MAX_PATH];
45 CreateDirectory(PWCHAR DirectoryName)
47 OBJECT_ATTRIBUTES ObjectAttributes;
48 IO_STATUS_BLOCK IoStatusBlock;
49 UNICODE_STRING PathName;
50 HANDLE DirectoryHandle;
53 RtlCreateUnicodeString(&PathName,
56 InitializeObjectAttributes(&ObjectAttributes,
58 OBJ_CASE_INSENSITIVE | OBJ_INHERIT,
62 Status = NtCreateFile(&DirectoryHandle,
67 FILE_ATTRIBUTE_DIRECTORY,
73 if (NT_SUCCESS(Status))
75 NtClose(DirectoryHandle);
78 RtlFreeUnicodeString(&PathName);
85 SetupCopyFile(PWCHAR SourceFileName,
86 PWCHAR DestinationFileName)
88 OBJECT_ATTRIBUTES ObjectAttributes;
89 HANDLE FileHandleSource;
90 HANDLE FileHandleDest;
91 IO_STATUS_BLOCK IoStatusBlock;
92 FILE_STANDARD_INFORMATION FileStandard;
93 FILE_BASIC_INFORMATION FileBasic;
94 FILE_POSITION_INFORMATION FilePosition;
97 UNICODE_STRING FileName;
102 RtlInitUnicodeString(&FileName,
105 InitializeObjectAttributes(&ObjectAttributes,
107 OBJ_CASE_INSENSITIVE,
111 Status = NtOpenFile(&FileHandleSource,
116 FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY);
117 if (!NT_SUCCESS(Status))
122 Status = NtQueryInformationFile(FileHandleSource,
125 sizeof(FILE_STANDARD_INFORMATION),
126 FileStandardInformation);
127 if (!NT_SUCCESS(Status))
129 NtClose(FileHandleSource);
133 Status = NtQueryInformationFile(FileHandleSource,
134 &IoStatusBlock,&FileBasic,
135 sizeof(FILE_BASIC_INFORMATION),
136 FileBasicInformation);
137 if (!NT_SUCCESS(Status))
139 NtClose(FileHandleSource);
143 RtlInitUnicodeString(&FileName,
144 DestinationFileName);
146 InitializeObjectAttributes(&ObjectAttributes,
148 OBJ_CASE_INSENSITIVE,
152 Status = NtCreateFile(&FileHandleDest,
157 FILE_ATTRIBUTE_NORMAL,
160 FILE_SYNCHRONOUS_IO_ALERT | FILE_SEQUENTIAL_ONLY,
163 if (!NT_SUCCESS(Status))
165 NtClose(FileHandleSource);
169 FilePosition.CurrentByteOffset.QuadPart = 0;
171 Status = NtSetInformationFile(FileHandleSource,
174 sizeof(FILE_POSITION_INFORMATION),
175 FilePositionInformation);
176 if (!NT_SUCCESS(Status))
178 NtClose(FileHandleSource);
179 NtClose(FileHandleDest);
183 Status = NtSetInformationFile(FileHandleDest,
186 sizeof(FILE_POSITION_INFORMATION),
187 FilePositionInformation);
188 if (!NT_SUCCESS(Status))
190 NtClose(FileHandleSource);
191 NtClose(FileHandleDest);
195 RegionSize = PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
196 if (RegionSize > 0x100000)
198 RegionSize = 0x100000;
200 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
204 MEM_RESERVE | MEM_COMMIT,
206 if (!NT_SUCCESS(Status))
208 NtClose(FileHandleSource);
209 NtClose(FileHandleDest);
215 Status = NtReadFile(FileHandleSource,
224 if (!NT_SUCCESS(Status))
226 NtFreeVirtualMemory(NtCurrentProcess(),
230 if (Status == STATUS_END_OF_FILE)
232 DPRINT("STATUS_END_OF_FILE\n");
235 NtClose(FileHandleSource);
236 NtClose(FileHandleDest);
240 DPRINT("Bytes read %lu\n", IoStatusBlock.Information);
242 Status = NtWriteFile(FileHandleDest,
248 IoStatusBlock.Information,
251 if (!NT_SUCCESS(Status))
253 NtFreeVirtualMemory(NtCurrentProcess(),
257 NtClose(FileHandleSource);
258 NtClose(FileHandleDest);
264 /* Copy file date/time from source file */
265 Status = NtSetInformationFile(FileHandleDest,
268 sizeof(FILE_BASIC_INFORMATION),
269 FileBasicInformation);
270 if (!NT_SUCCESS(Status))
272 DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status);
275 NtClose(FileHandleSource);
276 NtClose(FileHandleDest);
283 SetupExtractFile(PWCHAR CabinetFileName,
284 PWCHAR SourceFileName,
285 PWCHAR DestinationPathName)
289 DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n",
290 CabinetFileName, SourceFileName, DestinationPathName);
292 if (HasCurrentCabinet)
294 DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName);
297 if ((HasCurrentCabinet) && (wcscmp(CabinetFileName, CurrentCabinetName) == 0))
299 DPRINT("Using same cabinet as last time\n");
303 DPRINT("Using new cabinet\n");
305 if (HasCurrentCabinet)
310 wcscpy(CurrentCabinetName, CabinetFileName);
313 CabinetSetEventHandlers(NULL, NULL, NULL);
314 CabinetSetCabinetName(CabinetFileName);
316 CabStatus = CabinetOpen();
317 if (CabStatus == CAB_STATUS_SUCCESS)
319 DPRINT("Opened cabinet %S\n", CabinetGetCabinetName());
320 HasCurrentCabinet = TRUE;
324 DPRINT("Cannot open cabinet (%d)\n", CabStatus);
325 return STATUS_UNSUCCESSFUL;
329 CabinetSetDestinationPath(DestinationPathName);
330 CabStatus = CabinetExtractFile(SourceFileName);
331 if (CabStatus != CAB_STATUS_SUCCESS)
333 DPRINT("Cannot extract file %S (%d)\n", SourceFileName, CabStatus);
334 return STATUS_UNSUCCESSFUL;
337 return STATUS_SUCCESS;
342 DoesFileExist(PWSTR PathName,
345 OBJECT_ATTRIBUTES ObjectAttributes;
346 IO_STATUS_BLOCK IoStatusBlock;
348 WCHAR FullName[MAX_PATH];
352 wcscpy(FullName, PathName);
353 if (FileName != NULL)
355 if (FileName[0] != L'\\')
356 wcscat(FullName, L"\\");
357 wcscat(FullName, FileName);
360 RtlInitUnicodeString(&Name,
363 InitializeObjectAttributes(&ObjectAttributes,
365 OBJ_CASE_INSENSITIVE,
369 Status = NtOpenFile(&FileHandle,
374 FILE_SYNCHRONOUS_IO_ALERT);
375 if (!NT_SUCCESS(Status))