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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 /* COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS text-mode setup
21 * FILE: subsys/system/usetup/filesup.c
22 * PURPOSE: File support functions
23 * PROGRAMMER: Eric Kohl
24 * Casper S. Hornstrup (chorns@users.sourceforge.net)
27 /* INCLUDES *****************************************************************/
34 /* FUNCTIONS ****************************************************************/
36 static BOOLEAN HasCurrentCabinet
= FALSE
;
37 static WCHAR CurrentCabinetName
[MAX_PATH
];
40 SetupCreateDirectory(PWCHAR DirectoryName
)
42 OBJECT_ATTRIBUTES ObjectAttributes
;
43 IO_STATUS_BLOCK IoStatusBlock
;
44 UNICODE_STRING PathName
;
45 HANDLE DirectoryHandle
;
48 RtlCreateUnicodeString(&PathName
,
50 if (PathName
.Length
> sizeof(WCHAR
) &&
51 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
) - 2] == L
'\\' &&
52 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
) - 1] == L
'.')
54 PathName
.Length
-= sizeof(WCHAR
);
55 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
)] = 0;
58 if (PathName
.Length
> sizeof(WCHAR
) &&
59 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
) - 1] == L
'\\')
61 PathName
.Length
-= sizeof(WCHAR
);
62 PathName
.Buffer
[PathName
.Length
/ sizeof(WCHAR
)] = 0;
65 InitializeObjectAttributes(&ObjectAttributes
,
67 OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
,
71 Status
= NtCreateFile(&DirectoryHandle
,
76 FILE_ATTRIBUTE_DIRECTORY
,
77 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
82 if (NT_SUCCESS(Status
))
84 NtClose(DirectoryHandle
);
87 RtlFreeUnicodeString(&PathName
);
94 SetupCopyFile(PWCHAR SourceFileName
,
95 PWCHAR DestinationFileName
)
97 OBJECT_ATTRIBUTES ObjectAttributes
;
98 HANDLE FileHandleSource
;
99 HANDLE FileHandleDest
;
100 static IO_STATUS_BLOCK IoStatusBlock
;
101 FILE_STANDARD_INFORMATION FileStandard
;
102 FILE_BASIC_INFORMATION FileBasic
;
104 UNICODE_STRING FileName
;
106 PVOID SourceFileMap
= 0;
107 HANDLE SourceFileSection
;
108 SIZE_T SourceSectionSize
= 0;
109 LARGE_INTEGER ByteOffset
;
112 RtlInitUnicodeString(&FileName
,
115 InitializeObjectAttributes(&ObjectAttributes
,
117 OBJ_CASE_INSENSITIVE
,
121 Status
= NtOpenFile(&FileHandleSource
,
126 FILE_SEQUENTIAL_ONLY
);
127 if(!NT_SUCCESS(Status
))
129 DPRINT1("NtOpenFile failed: %x\n", Status
);
133 FileHandleSource
= CreateFileW(SourceFileName
, GENERIC_READ
, FILE_SHARE_READ
, NULL
, OPEN_EXISTING
, 0, NULL
);
134 if (FileHandleSource
== INVALID_HANDLE_VALUE
)
136 Status
= STATUS_UNSUCCESSFUL
;
141 Status
= NtQueryInformationFile(FileHandleSource
,
144 sizeof(FILE_STANDARD_INFORMATION
),
145 FileStandardInformation
);
146 if(!NT_SUCCESS(Status
))
148 DPRINT1("NtQueryInformationFile failed: %x\n", Status
);
151 Status
= NtQueryInformationFile(FileHandleSource
,
152 &IoStatusBlock
,&FileBasic
,
153 sizeof(FILE_BASIC_INFORMATION
),
154 FileBasicInformation
);
155 if(!NT_SUCCESS(Status
))
157 DPRINT1("NtQueryInformationFile failed: %x\n", Status
);
161 Status
= NtCreateSection( &SourceFileSection
,
168 if(!NT_SUCCESS(Status
))
170 DPRINT1("NtCreateSection failed: %x\n", Status
);
174 Status
= NtMapViewOfSection( SourceFileSection
,
184 if(!NT_SUCCESS(Status
))
186 DPRINT1("NtMapViewOfSection failed: %x\n", Status
);
190 RtlInitUnicodeString(&FileName
,
191 DestinationFileName
);
193 InitializeObjectAttributes(&ObjectAttributes
,
195 OBJ_CASE_INSENSITIVE
,
199 Status
= NtCreateFile(&FileHandleDest
,
204 FILE_ATTRIBUTE_NORMAL
,
207 FILE_NO_INTERMEDIATE_BUFFERING
|
208 FILE_SEQUENTIAL_ONLY
|
209 FILE_SYNCHRONOUS_IO_NONALERT
,
212 if(!NT_SUCCESS(Status
))
214 DPRINT1("NtCreateFile failed: %x\n", Status
);
218 RegionSize
= (ULONG
)PAGE_ROUND_UP(FileStandard
.EndOfFile
.u
.LowPart
);
219 IoStatusBlock
.Status
= 0;
220 ByteOffset
.QuadPart
= 0;
221 Status
= NtWriteFile(FileHandleDest
,
230 if(!NT_SUCCESS(Status
))
232 DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n", Status
, IoStatusBlock
.Status
, &IoStatusBlock
, SourceFileMap
, RegionSize
);
235 /* Copy file date/time from source file */
236 Status
= NtSetInformationFile(FileHandleDest
,
239 sizeof(FILE_BASIC_INFORMATION
),
240 FileBasicInformation
);
241 if(!NT_SUCCESS(Status
))
243 DPRINT1("NtSetInformationFile failed: %x\n", Status
);
247 /* shorten the file back to it's real size after completing the write */
248 Status
= NtSetInformationFile(FileHandleDest
,
250 &FileStandard
.EndOfFile
,
251 sizeof(FILE_END_OF_FILE_INFORMATION
),
252 FileEndOfFileInformation
);
254 if(!NT_SUCCESS(Status
))
256 DPRINT1("NtSetInformationFile failed: %x\n", Status
);
260 NtClose(FileHandleDest
);
262 NtUnmapViewOfSection( NtCurrentProcess(), SourceFileMap
);
264 NtClose(SourceFileSection
);
266 NtClose(FileHandleSource
);
273 SetupExtractFile(PWCHAR CabinetFileName
,
274 PWCHAR SourceFileName
,
275 PWCHAR DestinationPathName
)
280 DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S, DestinationPathName %S)\n",
281 CabinetFileName
, SourceFileName
, DestinationPathName
);
283 if (HasCurrentCabinet
)
285 DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName
);
288 if ((HasCurrentCabinet
) && (wcscmp(CabinetFileName
, CurrentCabinetName
) == 0))
290 DPRINT("Using same cabinet as last time\n");
294 DPRINT("Using new cabinet\n");
296 if (HasCurrentCabinet
)
301 wcscpy(CurrentCabinetName
, CabinetFileName
);
304 CabinetSetEventHandlers(NULL
, NULL
, NULL
);
305 CabinetSetCabinetName(CabinetFileName
);
307 CabStatus
= CabinetOpen();
308 if (CabStatus
== CAB_STATUS_SUCCESS
)
310 DPRINT("Opened cabinet %S\n", CabinetGetCabinetName());
311 HasCurrentCabinet
= TRUE
;
315 DPRINT("Cannot open cabinet (%d)\n", CabStatus
);
316 return STATUS_UNSUCCESSFUL
;
320 CabinetSetDestinationPath(DestinationPathName
);
321 CabinetFindFirst( SourceFileName
, &Search
);
322 CabStatus
= CabinetExtractFile(&Search
);
323 if (CabStatus
!= CAB_STATUS_SUCCESS
)
325 DPRINT("Cannot extract file %S (%d)\n", SourceFileName
, CabStatus
);
326 return STATUS_UNSUCCESSFUL
;
329 return STATUS_SUCCESS
;
334 DoesFileExist(PWSTR PathName
,
337 OBJECT_ATTRIBUTES ObjectAttributes
;
338 IO_STATUS_BLOCK IoStatusBlock
;
340 WCHAR FullName
[MAX_PATH
];
344 wcscpy(FullName
, PathName
);
345 if (FileName
!= NULL
)
347 if (FileName
[0] != L
'\\')
348 wcscat(FullName
, L
"\\");
349 wcscat(FullName
, FileName
);
352 RtlInitUnicodeString(&Name
,
355 InitializeObjectAttributes(&ObjectAttributes
,
357 OBJ_CASE_INSENSITIVE
,
361 Status
= NtOpenFile(&FileHandle
,
366 FILE_SYNCHRONOUS_IO_NONALERT
);
367 if (!NT_SUCCESS(Status
))