Corrected a number of bugs, including the keyboard one
[reactos.git] / reactos / lib / kernel32 / file / file.c
1 /*
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 ]
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12
13
14 #undef WIN32_LEAN_AND_MEAN
15 #include <windows.h>
16 #include <ddk/ntddk.h>
17 #include <wstring.h>
18 #include <string.h>
19 #include <kernel32/li.h>
20 #include <ddk/rtl.h>
21
22 #define LPPROGRESS_ROUTINE void*
23
24
25
26
27 WINBOOL
28 CopyFileExW(
29 LPCWSTR lpExistingFileName,
30 LPCWSTR lpNewFileName,
31 LPPROGRESS_ROUTINE lpProgressRoutine,
32 LPVOID lpData,
33 WINBOOL * pbCancel,
34 DWORD dwCopyFlags
35 );
36
37 WINBOOL
38 CopyFileExA(
39 LPCSTR lpExistingFileName,
40 LPCSTR lpNewFileName,
41 LPPROGRESS_ROUTINE lpProgressRoutine,
42 LPVOID lpData,
43 WINBOOL * pbCancel,
44 DWORD dwCopyFlags
45 );
46
47 DWORD
48 GetCurrentTime(VOID);
49
50 BOOLEAN bIsFileApiAnsi; // set the file api to ansi or oem
51
52
53
54 VOID
55 STDCALL
56 SetFileApisToOEM(VOID)
57 {
58 bIsFileApiAnsi = FALSE;
59 return;
60 }
61
62 HANDLE STDCALL CreateFileA(LPCSTR lpFileName,
63 DWORD dwDesiredAccess,
64 DWORD dwShareMode,
65 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
66 DWORD dwCreationDisposition,
67 DWORD dwFlagsAndAttributes,
68 HANDLE hTemplateFile)
69 {
70
71 WCHAR FileNameW[MAX_PATH];
72 ULONG i = 0;
73
74 OutputDebugStringA("CreateFileA\n");
75
76 while ((*lpFileName)!=0 && i < MAX_PATH)
77 {
78 FileNameW[i] = *lpFileName;
79 lpFileName++;
80 i++;
81 }
82 FileNameW[i] = 0;
83
84 return CreateFileW(FileNameW,dwDesiredAccess,dwShareMode, lpSecurityAttributes,
85 dwCreationDisposition,dwFlagsAndAttributes, hTemplateFile);
86 }
87
88
89 HANDLE STDCALL CreateFileW(LPCWSTR lpFileName,
90 DWORD dwDesiredAccess,
91 DWORD dwShareMode,
92 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
93 DWORD dwCreationDisposition,
94 DWORD dwFlagsAndAttributes,
95 HANDLE hTemplateFile)
96 {
97 HANDLE FileHandle;
98 NTSTATUS Status;
99
100 OBJECT_ATTRIBUTES ObjectAttributes;
101 IO_STATUS_BLOCK IoStatusBlock;
102 UNICODE_STRING FileNameString;
103 ULONG Flags = 0;
104 WCHAR PathNameW[MAX_PATH];
105 WCHAR *FilePart;
106 UINT Len = 0;
107
108 OutputDebugStringA("CreateFileW\n");
109
110 if (!(dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED))
111 {
112 Flags |= FILE_SYNCHRONOUS_IO_ALERT;
113 }
114
115 #if 0
116
117 if ( ( ( dwCreationDisposition & OPEN_EXISTING ) == OPEN_EXISTING ) ||
118 ( ( dwCreationDisposition & TRUNCATE_EXISTING ) == TRUNCATE_EXISTING ) )
119 Len = SearchPathW(NULL,lpFileName,NULL,MAX_PATH,PathNameW,&FilePart);
120 if ( Len == 0 )
121 return NULL;
122 else {
123 Len = GetCurrentDirectoryW(MAX_PATH,PathNameW);
124 if ( Len == 0 )
125 return NULL;
126 if ( PathNameW[Len-1] != L'\\' ) {
127 PathNameW[Len] = L'\\';
128 PathNameW[Len+1] = 0;
129 }
130 lstrcatW(PathNameW,lpFileName);
131 }
132 FileNameString.Length = lstrlenW( PathNameW)*sizeof(WCHAR);
133
134 if ( FileNameString.Length == 0 )
135 return NULL;
136
137 if ( FileNameString.Length > MAX_PATH )
138 return NULL;
139
140 FileNameString.Buffer = (WCHAR *)PathNameW;
141 FileNameString.MaximumLength = FileNameString.Length;
142 #endif
143
144 FileNameString.Buffer = lpFileName;
145 FileNameString.Length =
146 FileNameString.MaximumLength = lstrlenW(lpFileName) * sizeof(WCHAR);
147
148 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
149 ObjectAttributes.RootDirectory = NULL;
150 ObjectAttributes.ObjectName = &FileNameString;
151 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
152 ObjectAttributes.SecurityDescriptor = NULL;
153 ObjectAttributes.SecurityQualityOfService = NULL;
154
155 Status = NtCreateFile(&FileHandle,
156 dwDesiredAccess,
157 &ObjectAttributes,
158 &IoStatusBlock,
159 NULL,
160 dwFlagsAndAttributes,
161 dwShareMode,
162 dwCreationDisposition,
163 Flags,
164 NULL,
165 0);
166 return(FileHandle);
167 }
168
169
170 WINBASEAPI
171 VOID
172 WINAPI
173 SetFileApisToANSI(VOID)
174 {
175 bIsFileApiAnsi = TRUE;
176 return;
177 }
178
179
180
181 WINBOOL
182 STDCALL
183 AreFileApisANSI(VOID)
184 {
185 return bIsFileApiAnsi;
186
187 }
188
189
190
191
192 WINBOOL STDCALL WriteFile(HANDLE hFile,
193 LPCVOID lpBuffer,
194 DWORD nNumberOfBytesToWrite,
195 LPDWORD lpNumberOfBytesWritten,
196 LPOVERLAPPED lpOverLapped)
197 {
198
199 LARGE_INTEGER Offset;
200 HANDLE hEvent = NULL;
201 NTSTATUS errCode;
202
203 if (lpOverLapped != NULL )
204 {
205 Offset.LowPart = lpOverLapped->Offset;
206 Offset.HighPart = lpOverLapped->OffsetHigh;
207 lpOverLapped->Internal = STATUS_PENDING;
208 hEvent= lpOverLapped->hEvent;
209 }
210 errCode = NtWriteFile(hFile,hEvent,NULL,NULL,
211 (PIO_STATUS_BLOCK)lpOverLapped,
212 (PVOID)lpBuffer,
213 nNumberOfBytesToWrite,
214 &Offset,
215 NULL);
216 if (!NT_SUCCESS(errCode))
217 {
218 SetLastError(RtlNtStatusToDosError(errCode));
219 return FALSE;
220 }
221
222 return(TRUE);
223 }
224
225 WINBOOL STDCALL ReadFile(HANDLE hFile,
226 LPVOID lpBuffer,
227 DWORD nNumberOfBytesToRead,
228 LPDWORD lpNumberOfBytesRead,
229 LPOVERLAPPED lpOverLapped)
230 {
231
232 HANDLE hEvent = NULL;
233 LARGE_INTEGER Offset;
234 NTSTATUS errCode;
235 PIO_STATUS_BLOCK IoStatusBlock;
236 IO_STATUS_BLOCK IIosb;
237
238
239 if ( lpOverLapped != NULL )
240 {
241 Offset.LowPart = lpOverLapped->Offset;
242 Offset.HighPart = lpOverLapped->OffsetHigh;
243 lpOverLapped->Internal = STATUS_PENDING;
244 hEvent = lpOverLapped->hEvent;
245 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
246 }
247 else
248 {
249 IoStatusBlock = &IIosb;
250 }
251
252 errCode = NtReadFile(hFile,
253 hEvent,
254 NULL,
255 NULL,
256 IoStatusBlock,
257 lpBuffer,
258 nNumberOfBytesToRead,
259 &Offset,
260 NULL);
261 if ( !NT_SUCCESS(errCode) )
262 {
263 SetLastError(RtlNtStatusToDosError(errCode));
264 return FALSE;
265 }
266 return TRUE;
267 }
268
269 WINBOOL
270 STDCALL
271 ReadFileEx(
272 HANDLE hFile,
273 LPVOID lpBuffer,
274 DWORD nNumberOfBytesToRead,
275 LPOVERLAPPED lpOverLapped,
276 LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
277 )
278 {
279 HANDLE hEvent = NULL;
280 LARGE_INTEGER Offset;
281 NTSTATUS errCode;
282 IO_STATUS_BLOCK IIosb;
283 PIO_STATUS_BLOCK IoStatusBlock;
284
285
286 if ( lpOverLapped != NULL ) {
287 Offset.LowPart = lpOverLapped->Offset;
288 Offset.HighPart = lpOverLapped->OffsetHigh;
289 lpOverLapped->Internal = STATUS_PENDING;
290 hEvent = lpOverLapped->hEvent;
291 IoStatusBlock = (PIO_STATUS_BLOCK)lpOverLapped;
292 }
293 else {
294 Offset.LowPart = 0;
295 Offset.HighPart = 0;
296 IoStatusBlock = &IIosb;
297 }
298
299
300
301
302 errCode = NtReadFile(hFile,
303 hEvent,
304 (PIO_APC_ROUTINE)lpCompletionRoutine,
305 NULL,
306 IoStatusBlock,
307 lpBuffer,
308 nNumberOfBytesToRead,
309 &Offset,
310 NULL);
311 if ( !NT_SUCCESS(errCode) ) {
312 SetLastError(RtlNtStatusToDosError(errCode));
313 return FALSE;
314 }
315 return TRUE;
316 }
317
318
319 WINBOOL
320 STDCALL
321 LockFile(
322 HANDLE hFile,
323 DWORD dwFileOffsetLow,
324 DWORD dwFileOffsetHigh,
325 DWORD nNumberOfBytesToLockLow,
326 DWORD nNumberOfBytesToLockHigh
327 )
328 {
329 DWORD dwReserved;
330 OVERLAPPED Overlapped;
331
332 Overlapped.Offset = dwFileOffsetLow;
333 Overlapped.OffsetHigh = dwFileOffsetHigh;
334 dwReserved = 0;
335
336 return LockFileEx(hFile, LOCKFILE_FAIL_IMMEDIATELY|LOCKFILE_EXCLUSIVE_LOCK,dwReserved,nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, &Overlapped ) ;
337
338 }
339
340 WINBOOL
341 STDCALL
342 LockFileEx(
343 HANDLE hFile,
344 DWORD dwFlags,
345 DWORD dwReserved,
346 DWORD nNumberOfBytesToLockLow,
347 DWORD nNumberOfBytesToLockHigh,
348 LPOVERLAPPED lpOverlapped
349 )
350 {
351 LARGE_INTEGER BytesToLock;
352 BOOL LockImmediate;
353 BOOL LockExclusive;
354 NTSTATUS errCode;
355 LARGE_INTEGER Offset;
356
357 if(dwReserved != 0)
358 {
359 SetLastError(ERROR_INVALID_PARAMETER);
360 return FALSE;
361 }
362
363 lpOverlapped->Internal = STATUS_PENDING;
364
365 Offset.LowPart = lpOverlapped->Offset;
366 Offset.HighPart = lpOverlapped->OffsetHigh;
367
368 if ( (dwFlags & LOCKFILE_FAIL_IMMEDIATELY) == LOCKFILE_FAIL_IMMEDIATELY )
369 LockImmediate = TRUE;
370 else
371 LockImmediate = FALSE;
372
373 if ( (dwFlags & LOCKFILE_EXCLUSIVE_LOCK) == LOCKFILE_EXCLUSIVE_LOCK )
374 LockExclusive = TRUE;
375 else
376 LockExclusive = FALSE;
377
378 BytesToLock.LowPart = nNumberOfBytesToLockLow;
379 BytesToLock.HighPart = nNumberOfBytesToLockHigh;
380
381 errCode = NtLockFile(hFile,
382 NULL,
383 NULL,
384 NULL,
385 (PIO_STATUS_BLOCK)lpOverlapped,
386 &Offset,
387 &BytesToLock,
388 NULL,
389 LockImmediate,
390 LockExclusive);
391 if ( !NT_SUCCESS(errCode) )
392 {
393 SetLastError(RtlNtStatusToDosError(errCode));
394 return FALSE;
395 }
396
397 return TRUE;
398
399 }
400
401 WINBOOL
402 STDCALL
403 UnlockFile(
404 HANDLE hFile,
405 DWORD dwFileOffsetLow,
406 DWORD dwFileOffsetHigh,
407 DWORD nNumberOfBytesToUnlockLow,
408 DWORD nNumberOfBytesToUnlockHigh
409 )
410 {
411 DWORD dwReserved;
412 OVERLAPPED Overlapped;
413 Overlapped.Offset = dwFileOffsetLow;
414 Overlapped.OffsetHigh = dwFileOffsetHigh;
415 dwReserved = 0;
416 return UnlockFileEx(hFile, dwReserved, nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh, &Overlapped);
417
418 }
419
420
421
422 WINBOOL
423 STDCALL
424 UnlockFileEx(
425 HANDLE hFile,
426 DWORD dwReserved,
427 DWORD nNumberOfBytesToUnLockLow,
428 DWORD nNumberOfBytesToUnLockHigh,
429 LPOVERLAPPED lpOverlapped
430 )
431 {
432 LARGE_INTEGER BytesToUnLock;
433 LARGE_INTEGER StartAddress;
434 NTSTATUS errCode;
435
436 if(dwReserved != 0)
437 {
438 SetLastError(ERROR_INVALID_PARAMETER);
439 return FALSE;
440 }
441 if ( lpOverlapped == NULL )
442 {
443 SetLastError(ERROR_INVALID_PARAMETER);
444 return FALSE;
445 }
446
447 BytesToUnLock.LowPart = nNumberOfBytesToUnLockLow;
448 BytesToUnLock.HighPart = nNumberOfBytesToUnLockHigh;
449
450 StartAddress.LowPart = lpOverlapped->Offset;
451 StartAddress.HighPart = lpOverlapped->OffsetHigh;
452
453 errCode = NtUnlockFile(hFile,
454 (PIO_STATUS_BLOCK)lpOverlapped,
455 &StartAddress,
456 &BytesToUnLock,
457 NULL);
458 if ( !NT_SUCCESS(errCode) ) {
459 SetLastError(RtlNtStatusToDosError(errCode));
460 return FALSE;
461 }
462
463 return TRUE;
464 }
465
466
467
468
469
470
471
472 WINBOOL
473 STDCALL
474 CopyFileA(
475 LPCSTR lpExistingFileName,
476 LPCSTR lpNewFileName,
477 WINBOOL bFailIfExists
478 )
479 {
480 return CopyFileExA(lpExistingFileName,lpNewFileName,NULL,NULL,FALSE,bFailIfExists);
481 }
482
483 WINBOOL
484 STDCALL
485 CopyFileExA(
486 LPCSTR lpExistingFileName,
487 LPCSTR lpNewFileName,
488 LPPROGRESS_ROUTINE lpProgressRoutine,
489 LPVOID lpData,
490 WINBOOL * pbCancel,
491 DWORD dwCopyFlags
492 )
493 {
494 ULONG i;
495 WCHAR ExistingFileNameW[MAX_PATH];
496 WCHAR NewFileNameW[MAX_PATH];
497
498
499
500 i = 0;
501 while ((*lpExistingFileName)!=0 && i < MAX_PATH)
502 {
503 ExistingFileNameW[i] = *lpExistingFileName;
504 lpExistingFileName++;
505 i++;
506 }
507 ExistingFileNameW[i] = 0;
508
509 i = 0;
510 while ((*lpNewFileName)!=0 && i < MAX_PATH)
511 {
512 NewFileNameW[i] = *lpNewFileName;
513 lpNewFileName++;
514 i++;
515 }
516 NewFileNameW[i] = 0;
517
518 return CopyFileExW(ExistingFileNameW,NewFileNameW,lpProgressRoutine,lpData,pbCancel,dwCopyFlags);
519 }
520
521
522 WINBOOL
523 STDCALL
524 CopyFileW(
525 LPCWSTR lpExistingFileName,
526 LPCWSTR lpNewFileName,
527 WINBOOL bFailIfExists
528 )
529 {
530 return CopyFileExW(lpExistingFileName,lpNewFileName,NULL,NULL,NULL,bFailIfExists);
531 }
532
533
534
535
536
537 WINBOOL
538 STDCALL
539 CopyFileExW(
540 LPCWSTR lpExistingFileName,
541 LPCWSTR lpNewFileName,
542 LPPROGRESS_ROUTINE lpProgressRoutine,
543 LPVOID lpData,
544 WINBOOL * pbCancel,
545 DWORD dwCopyFlags
546 )
547 {
548
549 NTSTATUS errCode = 0;
550 HANDLE FileHandleSource, FileHandleDest;
551 IO_STATUS_BLOCK IoStatusBlock;
552
553 FILE_STANDARD_INFORMATION FileStandard;
554 FILE_BASIC_INFORMATION FileBasic;
555 FILE_POSITION_INFORMATION FilePosition;
556
557 UCHAR *lpBuffer = NULL;
558
559
560
561 ULONG RegionSize = 0x1000000;
562
563 BOOL bCancel = FALSE;
564
565
566
567 FileHandleSource = CreateFileW(
568 lpExistingFileName,
569 GENERIC_READ,
570 FILE_SHARE_READ,
571 NULL,
572 OPEN_EXISTING,
573 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_NO_BUFFERING,
574 NULL
575 );
576
577
578
579 if ( !NT_SUCCESS(errCode) ) {
580 SetLastError(RtlNtStatusToDosError(errCode));
581 return FALSE;
582 }
583
584
585 errCode = NtQueryInformationFile(FileHandleSource,
586 &IoStatusBlock,&FileStandard, sizeof(FILE_STANDARD_INFORMATION),
587 FileStandardInformation);
588 if ( !NT_SUCCESS(errCode) ) {
589 NtClose(FileHandleSource);
590 SetLastError(RtlNtStatusToDosError(errCode));
591 return FALSE;
592 }
593
594 errCode = NtQueryInformationFile(FileHandleSource,
595 &IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),
596 FileBasicInformation);
597 if ( !NT_SUCCESS(errCode) ) {
598 NtClose(FileHandleSource);
599 SetLastError(RtlNtStatusToDosError(errCode));
600 return FALSE;
601 }
602
603
604
605
606
607
608 FileHandleDest = CreateFileW(
609 lpNewFileName,
610 GENERIC_WRITE,
611 FILE_SHARE_WRITE,
612 NULL,
613 dwCopyFlags ? CREATE_NEW : CREATE_ALWAYS ,
614 FileBasic.FileAttributes|FILE_FLAG_NO_BUFFERING,
615 NULL
616 );
617
618 if ( !NT_SUCCESS(errCode) ) {
619 NtClose(FileHandleSource);
620 SetLastError(RtlNtStatusToDosError(errCode));
621 return FALSE;
622 }
623
624
625
626
627 FilePosition.CurrentByteOffset.LowPart = 0;
628 FilePosition.CurrentByteOffset.HighPart = 0;
629
630 errCode = NtSetInformationFile(FileHandleSource,
631 &IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),
632 FilePositionInformation);
633 if ( !NT_SUCCESS(errCode) ) {
634 NtClose(FileHandleSource);
635 NtClose(FileHandleDest);
636 SetLastError(RtlNtStatusToDosError(errCode));
637 return FALSE;
638 }
639
640 errCode = NtSetInformationFile(FileHandleDest,
641 &IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),
642 FilePositionInformation);
643
644 if ( !NT_SUCCESS(errCode) ) {
645 NtClose(FileHandleSource);
646 NtClose(FileHandleDest);
647 SetLastError(RtlNtStatusToDosError(errCode));
648 return FALSE;
649 }
650
651
652
653 errCode = NtAllocateVirtualMemory(
654 NtCurrentProcess(),
655 (PVOID *)&lpBuffer,
656 2,
657 &RegionSize,
658 MEM_COMMIT,
659 PAGE_READWRITE
660 );
661
662 if ( !NT_SUCCESS(errCode) ) {
663 NtClose(FileHandleSource);
664 NtClose(FileHandleDest);
665 SetLastError(RtlNtStatusToDosError(errCode));
666 return FALSE;
667 }
668
669
670
671
672
673
674 do {
675
676 errCode = NtReadFile(
677 FileHandleSource,
678 NULL,
679 NULL,
680 NULL,
681 (PIO_STATUS_BLOCK)&IoStatusBlock,
682 lpBuffer,
683 RegionSize,
684 NULL,
685 NULL);
686 if ( pbCancel != NULL )
687 bCancel = *pbCancel;
688
689
690 if ( !NT_SUCCESS(errCode) || bCancel ) {
691 NtFreeVirtualMemory(NtCurrentProcess(),(PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE);
692 NtClose(FileHandleSource);
693 NtClose(FileHandleDest);
694 if ( errCode == STATUS_END_OF_FILE )
695 break;
696 else
697 return FALSE;
698
699 }
700
701 errCode = NtWriteFile(FileHandleDest,
702 NULL,
703 lpProgressRoutine,
704 lpData,
705 (PIO_STATUS_BLOCK)&IoStatusBlock,
706 lpBuffer,
707 RegionSize,
708 NULL,
709 NULL);
710
711
712
713 if ( !NT_SUCCESS(errCode) ) {
714 NtFreeVirtualMemory(NtCurrentProcess(),(PVOID *)&lpBuffer, &RegionSize,MEM_RELEASE);
715 NtClose(FileHandleSource);
716 NtClose(FileHandleDest);
717 return FALSE;
718 }
719
720 } while ( TRUE );
721
722 return TRUE;
723
724
725 }
726
727
728 HFILE
729 STDCALL
730 OpenFile(
731 LPCSTR lpFileName,
732 LPOFSTRUCT lpReOpenBuff,
733 UINT uStyle
734 )
735 {
736 NTSTATUS errCode;
737 HANDLE FileHandle = NULL;
738 UNICODE_STRING FileNameString;
739 WCHAR FileNameW[MAX_PATH];
740 WCHAR PathNameW[MAX_PATH];
741 ULONG i;
742 OBJECT_ATTRIBUTES ObjectAttributes;
743 IO_STATUS_BLOCK IoStatusBlock;
744 WCHAR *FilePart;
745 ULONG Len;
746
747 if ( lpReOpenBuff == NULL ) {
748 return FALSE;
749 }
750
751
752
753
754 i = 0;
755 while ((*lpFileName)!=0 && i < MAX_PATH)
756 {
757 FileNameW[i] = *lpFileName;
758 lpFileName++;
759 i++;
760 }
761 FileNameW[i] = 0;
762
763
764 Len = SearchPathW(NULL,FileNameW,NULL,MAX_PATH,PathNameW,&FilePart);
765 if ( Len == 0 )
766 return (HFILE)NULL;
767
768
769 if ( Len > MAX_PATH )
770 return (HFILE)NULL;
771
772 FileNameString.Length = lstrlenW(PathNameW)*sizeof(WCHAR);
773 FileNameString.Buffer = PathNameW;
774 FileNameString.MaximumLength = FileNameString.Length;
775
776
777
778
779 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
780 ObjectAttributes.RootDirectory = NULL;
781 ObjectAttributes.ObjectName = &FileNameString;
782 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
783 ObjectAttributes.SecurityDescriptor = NULL;
784 ObjectAttributes.SecurityQualityOfService = NULL;
785
786 // FILE_SHARE_READ
787 // FILE_NO_INTERMEDIATE_BUFFERING
788
789
790
791 if ((uStyle & OF_PARSE) == OF_PARSE )
792 return (HFILE)NULL;
793
794
795 errCode = NtOpenFile(
796 &FileHandle,
797 GENERIC_READ|SYNCHRONIZE,
798 &ObjectAttributes,
799 &IoStatusBlock,
800 FILE_SHARE_READ,
801 FILE_NON_DIRECTORY_FILE
802 );
803
804 lpReOpenBuff->nErrCode = RtlNtStatusToDosError(errCode);
805
806 if ( !NT_SUCCESS(errCode) ) {
807 SetLastError(RtlNtStatusToDosError(errCode));
808 return (HFILE)INVALID_HANDLE_VALUE;
809 }
810
811 return (HFILE)FileHandle;
812
813 }
814
815
816 WINBOOL
817 STDCALL
818 MoveFileA(
819 LPCSTR lpExistingFileName,
820 LPCSTR lpNewFileName
821 )
822 {
823 return MoveFileExA(lpExistingFileName,lpNewFileName,MOVEFILE_COPY_ALLOWED);
824 }
825
826 WINBOOL
827 STDCALL
828 MoveFileExA(
829 LPCSTR lpExistingFileName,
830 LPCSTR lpNewFileName,
831 DWORD dwFlags
832 )
833 {
834 ULONG i;
835 WCHAR ExistingFileNameW[MAX_PATH];
836 WCHAR NewFileNameW[MAX_PATH];
837
838
839
840 i = 0;
841 while ((*lpExistingFileName)!=0 && i < MAX_PATH)
842 {
843 ExistingFileNameW[i] = *lpExistingFileName;
844 lpExistingFileName++;
845 i++;
846 }
847 ExistingFileNameW[i] = 0;
848
849 i = 0;
850 while ((*lpNewFileName)!=0 && i < MAX_PATH)
851 {
852 NewFileNameW[i] = *lpNewFileName;
853 lpNewFileName++;
854 i++;
855 }
856 NewFileNameW[i] = 0;
857
858 return MoveFileExW(ExistingFileNameW,NewFileNameW,dwFlags);
859
860 }
861
862
863
864 WINBOOL
865 STDCALL
866 MoveFileW(
867 LPCWSTR lpExistingFileName,
868 LPCWSTR lpNewFileName
869 )
870 {
871 return MoveFileExW(lpExistingFileName,lpNewFileName,MOVEFILE_COPY_ALLOWED);
872 }
873
874 #define FILE_RENAME_SIZE MAX_PATH +sizeof(FILE_RENAME_INFORMATION)
875
876 WINBOOL
877 STDCALL
878 MoveFileExW(
879 LPCWSTR lpExistingFileName,
880 LPCWSTR lpNewFileName,
881 DWORD dwFlags
882 )
883 {
884 HANDLE hFile = NULL;
885 IO_STATUS_BLOCK IoStatusBlock;
886 FILE_RENAME_INFORMATION *FileRename;
887 USHORT Buffer[FILE_RENAME_SIZE];
888 NTSTATUS errCode;
889
890 hFile = CreateFileW(
891 lpExistingFileName,
892 GENERIC_ALL,
893 FILE_SHARE_WRITE|FILE_SHARE_READ,
894 NULL,
895 OPEN_EXISTING,
896 FILE_ATTRIBUTE_NORMAL,
897 NULL
898 );
899
900
901
902 FileRename = (FILE_RENAME_INFORMATION *)Buffer;
903 if ( ( dwFlags & MOVEFILE_REPLACE_EXISTING ) == MOVEFILE_REPLACE_EXISTING )
904 FileRename->Replace = TRUE;
905 else
906 FileRename->Replace = FALSE;
907
908 FileRename->FileNameLength = lstrlenW(lpNewFileName);
909 memcpy(FileRename->FileName,lpNewFileName,min(FileRename->FileNameLength,MAX_PATH));
910
911 errCode = NtSetInformationFile(hFile,&IoStatusBlock,FileRename, FILE_RENAME_SIZE, FileRenameInformation);
912 if ( !NT_SUCCESS(errCode) ) {
913 if ( CopyFileW(lpExistingFileName,lpNewFileName,FileRename->Replace) )
914 DeleteFileW(lpExistingFileName);
915 }
916
917 CloseHandle(hFile);
918 return TRUE;
919 }
920
921 WINBOOL
922 STDCALL
923 DeleteFileA(
924 LPCSTR lpFileName
925 )
926 {
927 ULONG i;
928
929 WCHAR FileNameW[MAX_PATH];
930
931
932
933 i = 0;
934 while ((*lpFileName)!=0 && i < MAX_PATH)
935 {
936 FileNameW[i] = *lpFileName;
937 lpFileName++;
938 i++;
939 }
940 FileNameW[i] = 0;
941 return DeleteFileW(FileNameW);
942
943 }
944
945 WINBOOL
946 STDCALL
947 DeleteFileW(
948 LPCWSTR lpFileName
949 )
950 {
951 OBJECT_ATTRIBUTES ObjectAttributes;
952 UNICODE_STRING FileNameString;
953 NTSTATUS errCode;
954 WCHAR PathNameW[MAX_PATH];
955 UINT Len;
956
957 Len = GetCurrentDirectoryW(MAX_PATH,PathNameW);
958 if ( Len == 0 )
959 return FALSE;
960 if ( PathNameW[Len-1] != L'\\' ) {
961 PathNameW[Len] = L'\\';
962 PathNameW[Len+1] = 0;
963 }
964 lstrcatW(PathNameW,lpFileName);
965 FileNameString.Length = lstrlenW( PathNameW)*sizeof(WCHAR);
966 if ( FileNameString.Length == 0 )
967 return FALSE;
968
969 if ( FileNameString.Length > MAX_PATH )
970 return FALSE;
971
972
973
974
975 FileNameString.Buffer = (WCHAR *)PathNameW;
976 FileNameString.MaximumLength = FileNameString.Length;
977
978
979
980
981 ObjectAttributes.Length = sizeof(OBJECT_ATTRIBUTES);
982 ObjectAttributes.RootDirectory = NULL;
983 ObjectAttributes.ObjectName = &FileNameString;
984 ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE| OBJ_INHERIT;
985 ObjectAttributes.SecurityDescriptor = NULL;
986 ObjectAttributes.SecurityQualityOfService = NULL;
987
988
989
990
991 errCode = NtDeleteFile(&ObjectAttributes);
992 if ( !NT_SUCCESS(errCode) ) {
993 SetLastError(RtlNtStatusToDosError(errCode));
994 return FALSE;
995 }
996 return TRUE;
997 }
998
999 WINBOOL
1000 STDCALL
1001 FlushFileBuffers(
1002 HANDLE hFile
1003 )
1004 {
1005 NTSTATUS errCode;
1006 IO_STATUS_BLOCK IoStatusBlock;
1007
1008 errCode = NtFlushBuffersFile(
1009 hFile,
1010 &IoStatusBlock
1011 );
1012 if ( !NT_SUCCESS(errCode) ) {
1013 SetLastError(RtlNtStatusToDosError(errCode));
1014 return FALSE;
1015 }
1016 return TRUE;
1017 }
1018
1019
1020 DWORD
1021 STDCALL
1022 SetFilePointer(
1023 HANDLE hFile,
1024 LONG lDistanceToMove,
1025 PLONG lpDistanceToMoveHigh,
1026 DWORD dwMoveMethod
1027 )
1028 {
1029 FILE_POSITION_INFORMATION FilePosition;
1030 FILE_END_OF_FILE_INFORMATION FileEndOfFile;
1031 NTSTATUS errCode;
1032 IO_STATUS_BLOCK IoStatusBlock;
1033 if ( dwMoveMethod == FILE_CURRENT ) {
1034 NtQueryInformationFile(hFile,&IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),FilePositionInformation);
1035 FilePosition.CurrentByteOffset.LowPart += lDistanceToMove;
1036 if ( lpDistanceToMoveHigh != NULL )
1037 FilePosition.CurrentByteOffset.HighPart += *lpDistanceToMoveHigh;
1038 }
1039 else if ( dwMoveMethod == FILE_END ) {
1040 NtQueryInformationFile(hFile,&IoStatusBlock,&FileEndOfFile, sizeof(FILE_END_OF_FILE_INFORMATION),FileEndOfFileInformation);
1041 FilePosition.CurrentByteOffset.LowPart = FileEndOfFile.EndOfFile.LowPart - lDistanceToMove;
1042 if ( lpDistanceToMoveHigh != NULL )
1043 FilePosition.CurrentByteOffset.HighPart = FileEndOfFile.EndOfFile.HighPart - *lpDistanceToMoveHigh;
1044 else
1045 FilePosition.CurrentByteOffset.HighPart = FileEndOfFile.EndOfFile.HighPart;
1046 }
1047 else if ( dwMoveMethod == FILE_CURRENT ) {
1048 FilePosition.CurrentByteOffset.LowPart = lDistanceToMove;
1049 if ( lpDistanceToMoveHigh != NULL )
1050 FilePosition.CurrentByteOffset.HighPart = *lpDistanceToMoveHigh;
1051 else
1052 FilePosition.CurrentByteOffset.HighPart = 0;
1053 }
1054
1055 errCode = NtSetInformationFile(hFile,&IoStatusBlock,&FilePosition, sizeof(FILE_POSITION_INFORMATION),FilePositionInformation);
1056 if ( !NT_SUCCESS(errCode) ) {
1057 SetLastError(RtlNtStatusToDosError(errCode));
1058 return -1;
1059 }
1060
1061 if ( lpDistanceToMoveHigh != NULL )
1062 lpDistanceToMoveHigh = &FilePosition.CurrentByteOffset.HighPart ;
1063 return FilePosition.CurrentByteOffset.LowPart;
1064 }
1065
1066 DWORD
1067 STDCALL
1068 GetFileType(
1069 HANDLE hFile
1070 )
1071 {
1072 return FILE_TYPE_UNKNOWN;
1073 }
1074
1075
1076 DWORD
1077 STDCALL
1078 GetFileSize(
1079 HANDLE hFile,
1080 LPDWORD lpFileSizeHigh
1081 )
1082 {
1083 NTSTATUS errCode;
1084 FILE_STANDARD_INFORMATION FileStandard;
1085 IO_STATUS_BLOCK IoStatusBlock;
1086
1087
1088 errCode = NtQueryInformationFile(hFile,
1089 &IoStatusBlock,&FileStandard, sizeof(FILE_STANDARD_INFORMATION),
1090 FileStandardInformation);
1091 if ( !NT_SUCCESS(errCode) ) {
1092 CloseHandle(hFile);
1093 SetLastError(RtlNtStatusToDosError(errCode));
1094 if ( lpFileSizeHigh == NULL ) {
1095 return -1;
1096 }
1097 else
1098 return 0;
1099 }
1100 if ( lpFileSizeHigh != NULL )
1101 *lpFileSizeHigh = FileStandard.AllocationSize.HighPart;
1102
1103 CloseHandle(hFile);
1104 return FileStandard.AllocationSize.LowPart;
1105 }
1106
1107 DWORD
1108 STDCALL
1109 GetCompressedFileSizeA(
1110 LPCSTR lpFileName,
1111 LPDWORD lpFileSizeHigh
1112 )
1113 {
1114 WCHAR FileNameW[MAX_PATH];
1115 ULONG i;
1116 i = 0;
1117 while ((*lpFileName)!=0 && i < MAX_PATH)
1118 {
1119 FileNameW[i] = *lpFileName;
1120 lpFileName++;
1121 i++;
1122 }
1123 FileNameW[i] = 0;
1124
1125
1126 return GetCompressedFileSizeW(FileNameW,lpFileSizeHigh);
1127
1128 }
1129
1130 DWORD
1131 STDCALL
1132 GetCompressedFileSizeW(
1133 LPCWSTR lpFileName,
1134 LPDWORD lpFileSizeHigh
1135 )
1136 {
1137 FILE_COMPRESSION_INFORMATION FileCompression;
1138 NTSTATUS errCode;
1139 IO_STATUS_BLOCK IoStatusBlock;
1140 HANDLE hFile;
1141
1142 hFile = CreateFileW(
1143 lpFileName,
1144 GENERIC_READ,
1145 FILE_SHARE_READ,
1146 NULL,
1147 OPEN_EXISTING,
1148 FILE_ATTRIBUTE_NORMAL,
1149 NULL
1150 );
1151
1152 errCode = NtQueryInformationFile(hFile,
1153 &IoStatusBlock,&FileCompression, sizeof(FILE_COMPRESSION_INFORMATION),
1154 FileCompressionInformation);
1155 if ( !NT_SUCCESS(errCode) ) {
1156 CloseHandle(hFile);
1157 SetLastError(RtlNtStatusToDosError(errCode));
1158 return 0;
1159 }
1160 CloseHandle(hFile);
1161 return 0;
1162
1163 }
1164
1165
1166
1167 WINBOOL
1168 STDCALL
1169 GetFileInformationByHandle(
1170 HANDLE hFile,
1171 LPBY_HANDLE_FILE_INFORMATION lpFileInformation
1172 )
1173 {
1174 FILE_DIRECTORY_INFORMATION FileDirectory;
1175 FILE_INTERNAL_INFORMATION FileInternal;
1176 FILE_FS_VOLUME_INFORMATION FileFsVolume;
1177 FILE_STANDARD_INFORMATION FileStandard;
1178
1179 NTSTATUS errCode;
1180 IO_STATUS_BLOCK IoStatusBlock;
1181 errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileDirectory, sizeof(FILE_DIRECTORY_INFORMATION),FileDirectoryInformation);
1182 if ( !NT_SUCCESS(errCode) ) {
1183 SetLastError(RtlNtStatusToDosError(errCode));
1184 return FALSE;
1185 }
1186 lpFileInformation->dwFileAttributes = (DWORD)FileDirectory.FileAttributes;
1187 memcpy(&lpFileInformation->ftCreationTime,&FileDirectory.CreationTime,sizeof(LARGE_INTEGER));
1188 memcpy(&lpFileInformation->ftLastAccessTime,&FileDirectory.LastAccessTime,sizeof(LARGE_INTEGER));
1189 memcpy(&lpFileInformation->ftLastWriteTime, &FileDirectory.LastWriteTime,sizeof(LARGE_INTEGER));
1190 lpFileInformation->nFileSizeHigh = FileDirectory.AllocationSize.HighPart;
1191 lpFileInformation->nFileSizeLow = FileDirectory.AllocationSize.LowPart;
1192
1193
1194
1195 errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileInternal, sizeof(FILE_INTERNAL_INFORMATION),FileInternalInformation);
1196 if ( !NT_SUCCESS(errCode) ) {
1197 SetLastError(RtlNtStatusToDosError(errCode));
1198 return FALSE;
1199 }
1200 lpFileInformation->nFileIndexHigh = FileInternal.IndexNumber.HighPart;
1201 lpFileInformation->nFileIndexLow = FileInternal.IndexNumber.LowPart;
1202
1203
1204 errCode = NtQueryVolumeInformationFile(hFile,&IoStatusBlock,&FileFsVolume, sizeof(FILE_FS_VOLUME_INFORMATION),FileFsVolumeInformation);
1205 if ( !NT_SUCCESS(errCode) ) {
1206 SetLastError(RtlNtStatusToDosError(errCode));
1207 return FALSE;
1208 }
1209 lpFileInformation->dwVolumeSerialNumber = FileFsVolume.VolumeSerialNumber;
1210
1211
1212 errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileStandard, sizeof(FILE_STANDARD_INFORMATION),FileStandardInformation);
1213 if ( !NT_SUCCESS(errCode) ) {
1214 CloseHandle(hFile);
1215 SetLastError(RtlNtStatusToDosError(errCode));
1216 return FALSE;
1217 }
1218 lpFileInformation->nNumberOfLinks = FileStandard.NumberOfLinks;
1219 CloseHandle(hFile);
1220 return TRUE;
1221
1222 }
1223
1224
1225
1226
1227
1228
1229 DWORD
1230 STDCALL
1231 GetFileAttributesA(
1232 LPCSTR lpFileName
1233 )
1234 {
1235 ULONG i;
1236 WCHAR FileNameW[MAX_PATH];
1237 i = 0;
1238 while ((*lpFileName)!=0 && i < MAX_PATH)
1239 {
1240 FileNameW[i] = *lpFileName;
1241 lpFileName++;
1242 i++;
1243 }
1244 FileNameW[i] = 0;
1245 return GetFileAttributesW(FileNameW);
1246 }
1247
1248
1249 DWORD
1250 STDCALL
1251 GetFileAttributesW(
1252 LPCWSTR lpFileName
1253 )
1254 {
1255 IO_STATUS_BLOCK IoStatusBlock;
1256 FILE_BASIC_INFORMATION FileBasic;
1257 HANDLE hFile;
1258 NTSTATUS errCode;
1259
1260
1261 hFile = CreateFileW(
1262 lpFileName,
1263 GENERIC_READ,
1264 FILE_SHARE_READ,
1265 NULL,
1266 OPEN_EXISTING,
1267 FILE_ATTRIBUTE_NORMAL,
1268 NULL
1269 );
1270
1271
1272 errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
1273 if ( !NT_SUCCESS(errCode) ) {
1274 CloseHandle(hFile);
1275 SetLastError(RtlNtStatusToDosError(errCode));
1276 return 0;
1277 }
1278 CloseHandle(hFile);
1279 return (DWORD)FileBasic.FileAttributes;
1280
1281 }
1282
1283
1284
1285 DWORD
1286 GetCurrentTime(VOID)
1287 {
1288 NTSTATUS errCode;
1289 FILETIME CurrentTime;
1290 errCode = NtQuerySystemTime (
1291 (TIME *)&CurrentTime
1292 );
1293 return CurrentTime.dwLowDateTime;
1294 }
1295
1296 UINT
1297 STDCALL
1298 GetTempFileNameA(
1299 LPCSTR lpPathName,
1300 LPCSTR lpPrefixString,
1301 UINT uUnique,
1302 LPSTR lpTempFileName
1303 )
1304 {
1305 HANDLE hFile;
1306 UINT unique = uUnique;
1307
1308 if (lpPathName == NULL)
1309 return 0;
1310
1311 if (uUnique == 0)
1312 uUnique = GetCurrentTime();
1313
1314 wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
1315 lpPathName,'~',lpPrefixString,uUnique,".tmp");
1316
1317 if (unique)
1318 return uUnique;
1319
1320 while ((hFile = CreateFileA(lpTempFileName, GENERIC_WRITE, 0, NULL,
1321 CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
1322 0)) == INVALID_HANDLE_VALUE)
1323 {
1324 wsprintfA(lpTempFileName,"%s\\%c%.3s%4.4x%s",
1325 lpPathName,'~',lpPrefixString,++uUnique,".tmp");
1326 }
1327
1328 CloseHandle((HANDLE)hFile);
1329 return uUnique;
1330 }
1331
1332
1333 UINT
1334 STDCALL
1335 GetTempFileNameW(
1336 LPCWSTR lpPathName,
1337 LPCWSTR lpPrefixString,
1338 UINT uUnique,
1339 LPWSTR lpTempFileName
1340 )
1341 {
1342 HANDLE hFile;
1343 UINT unique = uUnique;
1344
1345 if (lpPathName == NULL)
1346 return 0;
1347
1348 if (uUnique == 0)
1349 uUnique = GetCurrentTime();
1350
1351 wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
1352 lpPathName,'~',lpPrefixString,uUnique,L".tmp");
1353
1354 if (unique)
1355 return uUnique;
1356
1357 while ((hFile = CreateFileW(lpTempFileName, GENERIC_WRITE, 0, NULL,
1358 CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY,
1359 0)) == INVALID_HANDLE_VALUE)
1360 {
1361 wsprintfW(lpTempFileName,L"%s\\%c%.3s%4.4x%s",
1362 lpPathName,'~',lpPrefixString,++uUnique,L".tmp");
1363 }
1364
1365 CloseHandle((HANDLE)hFile);
1366 return uUnique;
1367 }
1368
1369 WINBOOL
1370 STDCALL
1371 GetFileTime(
1372 HANDLE hFile,
1373 LPFILETIME lpCreationTime,
1374 LPFILETIME lpLastAccessTime,
1375 LPFILETIME lpLastWriteTime
1376 )
1377 {
1378 IO_STATUS_BLOCK IoStatusBlock;
1379 FILE_BASIC_INFORMATION FileBasic;
1380 NTSTATUS errCode;
1381
1382
1383
1384 errCode = NtQueryInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
1385 if ( !NT_SUCCESS(errCode) ) {
1386 SetLastError(RtlNtStatusToDosError(errCode));
1387 return FALSE;
1388 }
1389 memcpy(lpCreationTime,&FileBasic.CreationTime,sizeof(FILETIME));
1390 memcpy(lpLastAccessTime,&FileBasic.LastAccessTime,sizeof(FILETIME));
1391 memcpy(lpLastWriteTime,&FileBasic.LastWriteTime,sizeof(FILETIME));
1392 return TRUE;
1393 }
1394
1395 WINBOOL
1396 STDCALL
1397 SetFileTime(
1398 HANDLE hFile,
1399 CONST FILETIME *lpCreationTime,
1400 CONST FILETIME *lpLastAccessTime,
1401 CONST FILETIME *lpLastWriteTime
1402 )
1403 {
1404 FILE_BASIC_INFORMATION FileBasic;
1405 IO_STATUS_BLOCK IoStatusBlock;
1406 NTSTATUS errCode;
1407
1408
1409
1410 memcpy(&FileBasic.CreationTime,lpCreationTime,sizeof(FILETIME));
1411 memcpy(&FileBasic.LastAccessTime,lpLastAccessTime,sizeof(FILETIME));
1412 memcpy(&FileBasic.LastWriteTime,lpLastWriteTime,sizeof(FILETIME));
1413
1414 // shoud i initialize changetime ???
1415
1416 errCode = NtSetInformationFile(hFile,&IoStatusBlock,&FileBasic, sizeof(FILE_BASIC_INFORMATION),FileBasicInformation);
1417 if ( !NT_SUCCESS(errCode) ) {
1418 SetLastError(RtlNtStatusToDosError(errCode));
1419 return FALSE;
1420 }
1421
1422 return TRUE;
1423 }