2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/file/file.c
5 * PURPOSE: Directory functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * GetTempFileName is modified from WINE [ Alexandre Juiliard ]
12 /* INCLUDES *****************************************************************/
15 #include <ddk/ntddk.h>
20 #include <kernel32/kernel32.h>
22 #define LPPROGRESS_ROUTINE void*
24 /* GLOBALS ******************************************************************/
26 static BOOLEAN bIsFileApiAnsi
; // set the file api to ansi or oem
28 /* FUNCTIONS ****************************************************************/
30 VOID STDCALL
SetFileApisToOEM(VOID
)
32 bIsFileApiAnsi
= FALSE
;
36 VOID STDCALL
SetFileApisToANSI(VOID
)
38 bIsFileApiAnsi
= TRUE
;
42 WINBOOL STDCALL
AreFileApisANSI(VOID
)
44 return(bIsFileApiAnsi
);
48 HFILE STDCALL
OpenFile(LPCSTR lpFileName
,
49 LPOFSTRUCT lpReOpenBuff
,
53 HANDLE FileHandle
= NULL
;
54 UNICODE_STRING FileNameString
;
55 WCHAR FileNameW
[MAX_PATH
];
56 WCHAR PathNameW
[MAX_PATH
];
58 OBJECT_ATTRIBUTES ObjectAttributes
;
59 IO_STATUS_BLOCK IoStatusBlock
;
63 if (lpReOpenBuff
== NULL
)
69 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
71 FileNameW
[i
] = *lpFileName
;
77 Len
= SearchPathW(NULL
,FileNameW
,NULL
,MAX_PATH
,PathNameW
,&FilePart
);
84 FileNameString
.Length
= lstrlenW(PathNameW
)*sizeof(WCHAR
);
85 FileNameString
.Buffer
= PathNameW
;
86 FileNameString
.MaximumLength
= FileNameString
.Length
+sizeof(WCHAR
);
88 ObjectAttributes
.Length
= sizeof(OBJECT_ATTRIBUTES
);
89 ObjectAttributes
.RootDirectory
= NULL
;
90 ObjectAttributes
.ObjectName
= &FileNameString
;
91 ObjectAttributes
.Attributes
= OBJ_CASE_INSENSITIVE
| OBJ_INHERIT
;
92 ObjectAttributes
.SecurityDescriptor
= NULL
;
93 ObjectAttributes
.SecurityQualityOfService
= NULL
;
96 // FILE_NO_INTERMEDIATE_BUFFERING
98 if ((uStyle
& OF_PARSE
) == OF_PARSE
)
101 errCode
= NtOpenFile(&FileHandle
,
102 GENERIC_READ
|SYNCHRONIZE
,
106 FILE_NON_DIRECTORY_FILE
);
108 lpReOpenBuff
->nErrCode
= RtlNtStatusToDosError(errCode
);
110 if (!NT_SUCCESS(errCode
))
112 SetLastError(RtlNtStatusToDosError(errCode
));
113 return (HFILE
)INVALID_HANDLE_VALUE
;
116 return (HFILE
)FileHandle
;
120 WINBOOL STDCALL
FlushFileBuffers(HANDLE hFile
)
123 IO_STATUS_BLOCK IoStatusBlock
;
125 errCode
= NtFlushBuffersFile(hFile
,
127 if (!NT_SUCCESS(errCode
))
129 SetLastError(RtlNtStatusToDosError(errCode
));
136 DWORD STDCALL
SetFilePointer(HANDLE hFile
,
137 LONG lDistanceToMove
,
138 PLONG lpDistanceToMoveHigh
,
141 FILE_POSITION_INFORMATION FilePosition
;
142 FILE_END_OF_FILE_INFORMATION FileEndOfFile
;
144 IO_STATUS_BLOCK IoStatusBlock
;
145 LARGE_INTEGER Distance
;
147 DPRINT("SetFilePointer(hFile %x, lDistanceToMove %d, dwMoveMethod %d)\n",
148 hFile
,lDistanceToMove
,dwMoveMethod
);
150 Distance
.u
.LowPart
= lDistanceToMove
;
151 Distance
.u
.HighPart
= (lpDistanceToMoveHigh
) ? *lpDistanceToMoveHigh
: 0;
153 if (dwMoveMethod
== FILE_CURRENT
)
155 NtQueryInformationFile(hFile
,
158 sizeof(FILE_POSITION_INFORMATION
),
159 FilePositionInformation
);
160 FilePosition
.CurrentByteOffset
.QuadPart
+= Distance
.QuadPart
;
162 else if (dwMoveMethod
== FILE_END
)
164 NtQueryInformationFile(hFile
,
167 sizeof(FILE_END_OF_FILE_INFORMATION
),
168 FileEndOfFileInformation
);
169 FilePosition
.CurrentByteOffset
.QuadPart
=
170 FileEndOfFile
.EndOfFile
.QuadPart
- Distance
.QuadPart
;
172 else if ( dwMoveMethod
== FILE_BEGIN
)
174 FilePosition
.CurrentByteOffset
.QuadPart
= Distance
.QuadPart
;
177 errCode
= NtSetInformationFile(hFile
,
180 sizeof(FILE_POSITION_INFORMATION
),
181 FilePositionInformation
);
182 if (!NT_SUCCESS(errCode
))
184 SetLastError(RtlNtStatusToDosError(errCode
));
188 if (lpDistanceToMoveHigh
!= NULL
)
190 *lpDistanceToMoveHigh
= FilePosition
.CurrentByteOffset
.u
.HighPart
;
192 return FilePosition
.CurrentByteOffset
.u
.LowPart
;
196 DWORD STDCALL
GetFileType(HANDLE hFile
)
198 return FILE_TYPE_UNKNOWN
;
202 DWORD STDCALL
GetFileSize(HANDLE hFile
,
203 LPDWORD lpFileSizeHigh
)
206 FILE_STANDARD_INFORMATION FileStandard
;
207 IO_STATUS_BLOCK IoStatusBlock
;
209 errCode
= NtQueryInformationFile(hFile
,
212 sizeof(FILE_STANDARD_INFORMATION
),
213 FileStandardInformation
);
214 if (!NT_SUCCESS(errCode
))
216 SetLastError(RtlNtStatusToDosError(errCode
));
217 if ( lpFileSizeHigh
== NULL
)
226 if ( lpFileSizeHigh
!= NULL
)
227 *lpFileSizeHigh
= FileStandard
.AllocationSize
.u
.HighPart
;
229 return FileStandard
.AllocationSize
.u
.LowPart
;
233 DWORD STDCALL
GetCompressedFileSizeA(LPCSTR lpFileName
,
234 LPDWORD lpFileSizeHigh
)
236 WCHAR FileNameW
[MAX_PATH
];
240 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
242 FileNameW
[i
] = *lpFileName
;
248 return GetCompressedFileSizeW(FileNameW
,lpFileSizeHigh
);
252 DWORD STDCALL
GetCompressedFileSizeW(LPCWSTR lpFileName
,
253 LPDWORD lpFileSizeHigh
)
255 FILE_COMPRESSION_INFORMATION FileCompression
;
257 IO_STATUS_BLOCK IoStatusBlock
;
260 hFile
= CreateFileW(lpFileName
,
265 FILE_ATTRIBUTE_NORMAL
,
268 errCode
= NtQueryInformationFile(hFile
,
271 sizeof(FILE_COMPRESSION_INFORMATION
),
272 FileCompressionInformation
);
273 if (!NT_SUCCESS(errCode
))
276 SetLastError(RtlNtStatusToDosError(errCode
));
284 WINBOOL STDCALL
GetFileInformationByHandle(HANDLE hFile
,
285 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
)
287 FILE_DIRECTORY_INFORMATION FileDirectory
;
288 FILE_INTERNAL_INFORMATION FileInternal
;
289 FILE_FS_VOLUME_INFORMATION FileFsVolume
;
290 FILE_STANDARD_INFORMATION FileStandard
;
292 IO_STATUS_BLOCK IoStatusBlock
;
294 errCode
= NtQueryInformationFile(hFile
,
297 sizeof(FILE_DIRECTORY_INFORMATION
),
298 FileDirectoryInformation
);
299 if (!NT_SUCCESS(errCode
))
301 SetLastError(RtlNtStatusToDosError(errCode
));
305 lpFileInformation
->dwFileAttributes
= (DWORD
)FileDirectory
.FileAttributes
;
306 memcpy(&lpFileInformation
->ftCreationTime
,&FileDirectory
.CreationTime
,sizeof(LARGE_INTEGER
));
307 memcpy(&lpFileInformation
->ftLastAccessTime
,&FileDirectory
.LastAccessTime
,sizeof(LARGE_INTEGER
));
308 memcpy(&lpFileInformation
->ftLastWriteTime
, &FileDirectory
.LastWriteTime
,sizeof(LARGE_INTEGER
));
309 lpFileInformation
->nFileSizeHigh
= FileDirectory
.AllocationSize
.u
.HighPart
;
310 lpFileInformation
->nFileSizeLow
= FileDirectory
.AllocationSize
.u
.LowPart
;
312 errCode
= NtQueryInformationFile(hFile
,
315 sizeof(FILE_INTERNAL_INFORMATION
),
316 FileInternalInformation
);
317 if (!NT_SUCCESS(errCode
))
319 SetLastError(RtlNtStatusToDosError(errCode
));
323 lpFileInformation
->nFileIndexHigh
= FileInternal
.IndexNumber
.u
.HighPart
;
324 lpFileInformation
->nFileIndexLow
= FileInternal
.IndexNumber
.u
.LowPart
;
326 errCode
= NtQueryVolumeInformationFile(hFile
,
329 sizeof(FILE_FS_VOLUME_INFORMATION
),
330 FileFsVolumeInformation
);
331 if (!NT_SUCCESS(errCode
))
333 SetLastError(RtlNtStatusToDosError(errCode
));
337 lpFileInformation
->dwVolumeSerialNumber
= FileFsVolume
.VolumeSerialNumber
;
339 errCode
= NtQueryInformationFile(hFile
,
342 sizeof(FILE_STANDARD_INFORMATION
),
343 FileStandardInformation
);
344 if (!NT_SUCCESS(errCode
))
346 SetLastError(RtlNtStatusToDosError(errCode
));
350 lpFileInformation
->nNumberOfLinks
= FileStandard
.NumberOfLinks
;
356 DWORD STDCALL
GetFileAttributesA(LPCSTR lpFileName
)
359 WCHAR FileNameW
[MAX_PATH
];
362 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
364 FileNameW
[i
] = *lpFileName
;
369 return GetFileAttributesW(FileNameW
);
373 DWORD STDCALL
GetFileAttributesW(LPCWSTR lpFileName
)
375 IO_STATUS_BLOCK IoStatusBlock
;
376 FILE_BASIC_INFORMATION FileBasic
;
380 hFile
= CreateFileW(lpFileName
,
381 FILE_READ_ATTRIBUTES
,
385 FILE_ATTRIBUTE_NORMAL
,
389 errCode
= NtQueryInformationFile(hFile
,
392 sizeof(FILE_BASIC_INFORMATION
),
393 FileBasicInformation
);
394 if (!NT_SUCCESS(errCode
))
397 SetLastError(RtlNtStatusToDosError(errCode
));
401 return (DWORD
)FileBasic
.FileAttributes
;
405 WINBOOL STDCALL
SetFileAttributesA(LPCSTR lpFileName
,
406 DWORD dwFileAttributes
)
409 WCHAR FileNameW
[MAX_PATH
];
411 while ((*lpFileName
)!=0 && i
< MAX_PATH
)
413 FileNameW
[i
] = *lpFileName
;
418 return SetFileAttributesW(FileNameW
, dwFileAttributes
);
422 WINBOOL STDCALL
SetFileAttributesW(LPCWSTR lpFileName
,
423 DWORD dwFileAttributes
)
425 IO_STATUS_BLOCK IoStatusBlock
;
426 FILE_BASIC_INFORMATION FileBasic
;
430 hFile
= CreateFileW(lpFileName
,
431 FILE_READ_ATTRIBUTES
| FILE_WRITE_ATTRIBUTES
,
435 FILE_ATTRIBUTE_NORMAL
,
438 errCode
= NtQueryInformationFile(hFile
,
441 sizeof(FILE_BASIC_INFORMATION
),
442 FileBasicInformation
);
443 if (!NT_SUCCESS(errCode
))
446 SetLastError(RtlNtStatusToDosError(errCode
));
449 FileBasic
.FileAttributes
= dwFileAttributes
;
450 errCode
= NtSetInformationFile(hFile
,
453 sizeof(FILE_BASIC_INFORMATION
),
454 FileBasicInformation
);
455 if (!NT_SUCCESS(errCode
))
458 SetLastError(RtlNtStatusToDosError(errCode
));
466 UINT STDCALL
GetTempFileNameA(LPCSTR lpPathName
,
467 LPCSTR lpPrefixString
,
469 LPSTR lpTempFileName
)
472 UINT unique
= uUnique
;
474 if (lpPathName
== NULL
)
478 uUnique
= GetCurrentTime();
480 * sprintf(lpTempFileName,"%s\\%c%.3s%4.4x%s",
481 * lpPathName,'~',lpPrefixString,uUnique,".tmp");
486 while ((hFile
= CreateFileA(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
487 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
488 0)) == INVALID_HANDLE_VALUE
)
490 // wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
491 // lpPathName,'~',lpPrefixString,++uUnique,".tmp");
494 CloseHandle((HANDLE
)hFile
);
499 UINT STDCALL
GetTempFileNameW(LPCWSTR lpPathName
,
500 LPCWSTR lpPrefixString
,
502 LPWSTR lpTempFileName
)
505 UINT unique
= uUnique
;
507 if (lpPathName
== NULL
)
511 uUnique
= GetCurrentTime();
513 // swprintf(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
514 // lpPathName,'~',lpPrefixString,uUnique,L".tmp");
519 while ((hFile
= CreateFileW(lpTempFileName
, GENERIC_WRITE
, 0, NULL
,
520 CREATE_NEW
, FILE_ATTRIBUTE_TEMPORARY
,
521 0)) == INVALID_HANDLE_VALUE
)
523 // wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
524 // lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
527 CloseHandle((HANDLE
)hFile
);
532 WINBOOL STDCALL
GetFileTime(HANDLE hFile
,
533 LPFILETIME lpCreationTime
,
534 LPFILETIME lpLastAccessTime
,
535 LPFILETIME lpLastWriteTime
)
537 IO_STATUS_BLOCK IoStatusBlock
;
538 FILE_BASIC_INFORMATION FileBasic
;
541 errCode
= NtQueryInformationFile(hFile
,
544 sizeof(FILE_BASIC_INFORMATION
),
545 FileBasicInformation
);
546 if (!NT_SUCCESS(errCode
))
548 SetLastError(RtlNtStatusToDosError(errCode
));
552 memcpy(lpCreationTime
,&FileBasic
.CreationTime
,sizeof(FILETIME
));
553 memcpy(lpLastAccessTime
,&FileBasic
.LastAccessTime
,sizeof(FILETIME
));
554 memcpy(lpLastWriteTime
,&FileBasic
.LastWriteTime
,sizeof(FILETIME
));
560 WINBOOL STDCALL
SetFileTime(HANDLE hFile
,
561 CONST FILETIME
*lpCreationTime
,
562 CONST FILETIME
*lpLastAccessTime
,
563 CONST FILETIME
*lpLastWriteTime
)
565 FILE_BASIC_INFORMATION FileBasic
;
566 IO_STATUS_BLOCK IoStatusBlock
;
569 memcpy(&FileBasic
.CreationTime
,lpCreationTime
,sizeof(FILETIME
));
570 memcpy(&FileBasic
.LastAccessTime
,lpLastAccessTime
,sizeof(FILETIME
));
571 memcpy(&FileBasic
.LastWriteTime
,lpLastWriteTime
,sizeof(FILETIME
));
573 // shoud i initialize changetime ???
575 errCode
= NtSetInformationFile(hFile
,
578 sizeof(FILE_BASIC_INFORMATION
),
579 FileBasicInformation
);
580 if (!NT_SUCCESS(errCode
))
582 SetLastError(RtlNtStatusToDosError(errCode
));
590 WINBOOL STDCALL
SetEndOfFile(HANDLE hFile
)
594 return WriteFile(hFile
,&x
,1,&Num
,NULL
);