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.
19 /* $Id: filesup.c,v 1.11 2004/08/15 22:29:50 chorns Exp $
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 *****************************************************************/
31 #include <ntdll/rtl.h>
40 /* FUNCTIONS ****************************************************************/
43 static BOOLEAN HasCurrentCabinet
= FALSE
;
44 static WCHAR CurrentCabinetName
[MAX_PATH
];
47 CreateDirectory(PWCHAR DirectoryName
)
49 OBJECT_ATTRIBUTES ObjectAttributes
;
50 IO_STATUS_BLOCK IoStatusBlock
;
51 UNICODE_STRING PathName
;
52 HANDLE DirectoryHandle
;
55 RtlCreateUnicodeString(&PathName
,
57 if (PathName
.Length
> sizeof(WCHAR
) &&
58 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
) - 2] == L
'\\' &&
59 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
) - 1] == L
'.')
61 PathName
.Length
-= sizeof(WCHAR
);
62 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
)] = 0;
65 if (PathName
.Length
> sizeof(WCHAR
) &&
66 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
) - 1] == L
'\\')
68 PathName
.Length
-= sizeof(WCHAR
);
69 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
)] = 0;
72 InitializeObjectAttributes(&ObjectAttributes
,
74 OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
,
78 Status
= NtCreateFile(&DirectoryHandle
,
83 FILE_ATTRIBUTE_DIRECTORY
,
86 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_DIRECTORY_FILE
,
89 if (NT_SUCCESS(Status
))
91 NtClose(DirectoryHandle
);
94 RtlFreeUnicodeString(&PathName
);
101 SetupCopyFile(PWCHAR SourceFileName
,
102 PWCHAR DestinationFileName
)
104 OBJECT_ATTRIBUTES ObjectAttributes
;
105 HANDLE FileHandleSource
;
106 HANDLE FileHandleDest
;
107 IO_STATUS_BLOCK IoStatusBlock
;
108 FILE_STANDARD_INFORMATION FileStandard
;
109 FILE_BASIC_INFORMATION FileBasic
;
110 FILE_POSITION_INFORMATION FilePosition
;
113 UNICODE_STRING FileName
;
118 RtlInitUnicodeString(&FileName
,
121 InitializeObjectAttributes(&ObjectAttributes
,
123 OBJ_CASE_INSENSITIVE
,
127 Status
= NtOpenFile(&FileHandleSource
,
132 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
);
133 if (!NT_SUCCESS(Status
))
138 Status
= NtQueryInformationFile(FileHandleSource
,
141 sizeof(FILE_STANDARD_INFORMATION
),
142 FileStandardInformation
);
143 if (!NT_SUCCESS(Status
))
145 NtClose(FileHandleSource
);
149 Status
= NtQueryInformationFile(FileHandleSource
,
150 &IoStatusBlock
,&FileBasic
,
151 sizeof(FILE_BASIC_INFORMATION
),
152 FileBasicInformation
);
153 if (!NT_SUCCESS(Status
))
155 NtClose(FileHandleSource
);
159 RtlInitUnicodeString(&FileName
,
160 DestinationFileName
);
162 InitializeObjectAttributes(&ObjectAttributes
,
164 OBJ_CASE_INSENSITIVE
,
168 Status
= NtCreateFile(&FileHandleDest
,
173 FILE_ATTRIBUTE_NORMAL
,
176 FILE_SYNCHRONOUS_IO_NONALERT
| FILE_SEQUENTIAL_ONLY
,
179 if (!NT_SUCCESS(Status
))
181 NtClose(FileHandleSource
);
185 FilePosition
.CurrentByteOffset
.QuadPart
= 0;
187 Status
= NtSetInformationFile(FileHandleSource
,
190 sizeof(FILE_POSITION_INFORMATION
),
191 FilePositionInformation
);
192 if (!NT_SUCCESS(Status
))
194 NtClose(FileHandleSource
);
195 NtClose(FileHandleDest
);
199 Status
= NtSetInformationFile(FileHandleDest
,
202 sizeof(FILE_POSITION_INFORMATION
),
203 FilePositionInformation
);
204 if (!NT_SUCCESS(Status
))
206 NtClose(FileHandleSource
);
207 NtClose(FileHandleDest
);
211 RegionSize
= PAGE_ROUND_UP(FileStandard
.EndOfFile
.u
.LowPart
);
212 if (RegionSize
> 0x100000)
214 RegionSize
= 0x100000;
216 Status
= NtAllocateVirtualMemory(NtCurrentProcess(),
220 MEM_RESERVE
| MEM_COMMIT
,
222 if (!NT_SUCCESS(Status
))
224 NtClose(FileHandleSource
);
225 NtClose(FileHandleDest
);
231 Status
= NtReadFile(FileHandleSource
,
240 if (!NT_SUCCESS(Status
))
242 NtFreeVirtualMemory(NtCurrentProcess(),
246 if (Status
== STATUS_END_OF_FILE
)
248 DPRINT("STATUS_END_OF_FILE\n");
251 NtClose(FileHandleSource
);
252 NtClose(FileHandleDest
);
256 DPRINT("Bytes read %lu\n", IoStatusBlock
.Information
);
258 Status
= NtWriteFile(FileHandleDest
,
264 IoStatusBlock
.Information
,
267 if (!NT_SUCCESS(Status
))
269 NtFreeVirtualMemory(NtCurrentProcess(),
273 NtClose(FileHandleSource
);
274 NtClose(FileHandleDest
);
280 /* Copy file date/time from source file */
281 Status
= NtSetInformationFile(FileHandleDest
,
284 sizeof(FILE_BASIC_INFORMATION
),
285 FileBasicInformation
);
286 if (!NT_SUCCESS(Status
))
288 DPRINT("NtSetInformationFile() failed (Status %lx)\n", Status
);
291 NtClose(FileHandleSource
);
292 NtClose(FileHandleDest
);
299 SetupExtractFile(PWCHAR CabinetFileName
,
300 PWCHAR SourceFileName
,
301 PWCHAR DestinationPathName
)
305 DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n",
306 CabinetFileName
, SourceFileName
, DestinationPathName
);
308 if (HasCurrentCabinet
)
310 DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName
);
313 if ((HasCurrentCabinet
) && (wcscmp(CabinetFileName
, CurrentCabinetName
) == 0))
315 DPRINT("Using same cabinet as last time\n");
319 DPRINT("Using new cabinet\n");
321 if (HasCurrentCabinet
)
326 wcscpy(CurrentCabinetName
, CabinetFileName
);
329 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
330 CabinetSetCabinetName(CabinetFileName
);
332 CabStatus
= CabinetOpen();
333 if (CabStatus
== CAB_STATUS_SUCCESS
)
335 DPRINT("Opened cabinet %S\n", CabinetGetCabinetName());
336 HasCurrentCabinet
= TRUE
;
340 DPRINT("Cannot open cabinet (%d)\n", CabStatus
);
341 return STATUS_UNSUCCESSFUL
;
345 CabinetSetDestinationPath(DestinationPathName
);
346 CabStatus
= CabinetExtractFile(SourceFileName
);
347 if (CabStatus
!= CAB_STATUS_SUCCESS
)
349 DPRINT("Cannot extract file %S (%d)\n", SourceFileName
, CabStatus
);
350 return STATUS_UNSUCCESSFUL
;
353 return STATUS_SUCCESS
;
358 DoesFileExist(PWSTR PathName
,
361 OBJECT_ATTRIBUTES ObjectAttributes
;
362 IO_STATUS_BLOCK IoStatusBlock
;
364 WCHAR FullName
[MAX_PATH
];
368 wcscpy(FullName
, PathName
);
369 if (FileName
!= NULL
)
371 if (FileName
[0] != L
'\\')
372 wcscat(FullName
, L
"\\");
373 wcscat(FullName
, FileName
);
376 RtlInitUnicodeString(&Name
,
379 InitializeObjectAttributes(&ObjectAttributes
,
381 OBJ_CASE_INSENSITIVE
,
385 Status
= NtOpenFile(&FileHandle
,
390 FILE_SYNCHRONOUS_IO_NONALERT
);
391 if (!NT_SUCCESS(Status
))