ReactOS 0.4.16-dev-2284-g3529151
move.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/file/move.c
5 * PURPOSE: Directory functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
7 * Gerhard W. Gruber (sparhawk_at_gmx.at)
8 * Dmitry Philippov (shedon@mail.ru)
9 * Pierre Schweitzer (pierre@reactos.org)
10 */
11
12/* INCLUDES *****************************************************************/
13
14#include <k32.h>
15#include <malloc.h>
16
17#define NDEBUG
18#include <debug.h>
20
21/* GLOBALS *****************************************************************/
22
23/* DEFINES *****************************************************************/
25{
30
31/* FUNCTIONS ****************************************************************/
32
89 _In_ PUNICODE_STRING ExistingPath,
90 _In_ PUNICODE_STRING NewPath,
91 _In_ INT KeyId,
92 _In_ BOOL CreateIfNotFound)
93{
94#define STRING_LENGTH 0x400
97 PVOID Buffer, BufferBegin;
99 PWSTR PendingOperations, BufferWrite;
100 ULONG DataSize, BufferLength, StringLength = STRING_LENGTH;
101 UNICODE_STRING SessionManagerString, PendingOperationsString;
102 /* +6 because a INT shouldn't take more than 6 chars. Especially given the call path */
103 WCHAR PendingOperationsBuffer[sizeof(L"PendingFileRenameOperations") / sizeof(WCHAR) + 6];
104
105 RtlInitUnicodeString(&SessionManagerString,
106 L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager");
107
108 /* Select appropriate key for adding our file */
109 if (KeyId == 1)
110 {
111 PendingOperations = L"PendingFileRenameOperations";
112 }
113 else
114 {
115 RtlStringCbPrintfW(PendingOperationsBuffer,
116 sizeof(PendingOperationsBuffer),
117 L"PendingFileRenameOperations%d", KeyId);
118 PendingOperations = PendingOperationsBuffer;
119 }
120 RtlInitUnicodeString(&PendingOperationsString, PendingOperations);
121
123 &SessionManagerString,
125 NULL, NULL);
126
127 /* Open parent key */
133 {
138 }
139
140 if (!NT_SUCCESS(Status))
141 {
142 return Status;
143 }
144
145 /* Reserve enough to read previous string + to append ours with required null chars */
146 BufferLength = NewPath->Length + ExistingPath->Length + STRING_LENGTH + 3 * sizeof(UNICODE_NULL);
147
148 while (TRUE)
149 {
150 /* Allocate output buffer */
151 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
152 if (Buffer == NULL)
153 {
155 return STATUS_NO_MEMORY;
156 }
157
159 &PendingOperationsString,
161 Buffer, StringLength, &DataSize);
163 {
164 break;
165 }
166
167 /* If buffer was too small, reallocate one which is big enough */
168 StringLength = DataSize;
169 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
170 BufferLength = ExistingPath->Length + StringLength + NewPath->Length + 3 * sizeof(UNICODE_NULL);
171 /* Check we didn't overflow */
172 if (BufferLength < StringLength)
173 {
176 }
177 }
178
179 /* Check if it existed; if not, create only IF asked to */
180 if (!NT_SUCCESS(Status) && (Status != STATUS_OBJECT_NAME_NOT_FOUND || !CreateIfNotFound))
181 {
183 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
184 return Status;
185 }
186
187 if (!NT_SUCCESS(Status))
188 {
189 /* We didn't find any: we create, so use complete buffer */
190 BufferBegin = Buffer;
191 BufferWrite = Buffer;
192 }
193 else
194 {
196
197 /* Get data, the buffer beginning, and where data should be appended
198 * (minus NULL char: this is REG_MULTI_SZ, it already includes double
199 * termination, but we keep only one). */
200 BufferBegin = PartialInfo->Data;
201 BufferWrite = (PWSTR)((ULONG_PTR)PartialInfo->Data + PartialInfo->DataLength - sizeof(UNICODE_NULL));
202 }
203
204 /* First copy existing */
205 RtlCopyMemory(BufferWrite, ExistingPath->Buffer, ExistingPath->Length);
206 BufferWrite += ExistingPath->Length / sizeof(WCHAR);
207 /* And append null char */
208 *BufferWrite = UNICODE_NULL;
209 ++BufferWrite;
210 /* Append destination */
211 RtlCopyMemory(BufferWrite, NewPath->Buffer, NewPath->Length);
212 BufferWrite += NewPath->Length / sizeof(WCHAR);
213 /* And append two null char (end of string) */
214 *BufferWrite = UNICODE_NULL;
215 ++BufferWrite;
216 *BufferWrite = UNICODE_NULL;
217
218 /* Set new value */
220 &PendingOperationsString,
221 0, REG_MULTI_SZ, BufferBegin,
222 (ULONG_PTR)BufferWrite - (ULONG_PTR)BufferBegin + sizeof(WCHAR));
223
225 RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
226
227 return Status;
228}
229
230
231/*
232 * @implemented
233 */
234DWORD
235WINAPI
237 IN HANDLE NewHandle,
238 OUT PWSTR ComputerName,
239 IN OUT PULONG ComputerNameLength)
240{
241 BOOL Query = FALSE;
243 PWSTR AbsolutePath, EndOfName;
244 USHORT AbsolutePathLength, NameLength;
246 WCHAR DeviceName[] = {'A', ':', '\0'}; /* Init to something, will be set later */
247 UNICODE_STRING UncString = RTL_CONSTANT_STRING(L"\\??\\UNC\\");
248 UNICODE_STRING GlobalString = RTL_CONSTANT_STRING(L"\\??\\");
249
250 DPRINT("BasepGetComputerNameFromNtPath(%wZ, %p, %p, %lu)\n",
251 NewPath, NewHandle, ComputerName, ComputerNameLength);
252
253 /* If it's an UNC path */
254 if (RtlPrefixUnicodeString(&UncString, NewPath, TRUE))
255 {
256 /* Check for broken caller */
257 if (NewPath->Length <= UncString.Length)
258 {
259 return ERROR_BAD_PATHNAME;
260 }
261
262 /* Skip UNC prefix */
263 AbsolutePath = &NewPath->Buffer[UncString.Length / sizeof(WCHAR)];
264 AbsolutePathLength = NewPath->Length - UncString.Length;
265
266 /* And query DFS */
267 Query = TRUE;
268 }
269 /* Otherwise, we have to be in global (NT path!), with drive letter */
270 else if (RtlPrefixUnicodeString(&GlobalString, NewPath, TRUE) && NewPath->Buffer[5] == ':')
271 {
272 /* Path is like that: \??\C:\Complete Path\To File.ext */
273 /* Get the letter and upcase it if required */
274 Letter = NewPath->Buffer[4];
275 if (Letter >= 'a' && Letter <= 'z')
276 {
277 Letter -= ('a' - 'A');
278 }
279 DeviceName[0] = Letter;
280
281 /* Query the associated DOS device */
283 {
284 return GetLastError();
285 }
286
287 /* If that's a network share */
288 if (TargetDevice == wcsstr(TargetDevice, L"\\Device\\LanmanRedirector\\;"))
289 {
290 /* Path is like that: \Device\LanmanRedirector\;C:0000000000000000\Complete Path\To File.ext */
291 /* Check we have the correct drive letter */
292 if (TargetDevice[26] == DeviceName[0] &&
293 TargetDevice[27] == ':')
294 {
295 /* Check for the path begin, computer name is before */
296 PWSTR Path = wcschr(&TargetDevice[28], L'\\');
297 if (Path == NULL)
298 {
299 return ERROR_BAD_PATHNAME;
300 }
301
302 AbsolutePath = Path + 1;
303 AbsolutePathLength = sizeof(WCHAR) * (ARRAYSIZE(TargetDevice) - (AbsolutePath - TargetDevice));
304 }
305 else
306 {
307 return ERROR_BAD_PATHNAME;
308 }
309 }
310 /* If it's a local device */
311 else if (TargetDevice == wcsstr(TargetDevice, L"\\Device\\Harddisk")
312 || TargetDevice == wcsstr(TargetDevice, L"\\Device\\CdRom")
313 || TargetDevice == wcsstr(TargetDevice, L"\\Device\\Floppy"))
314 {
315 /* Just query the computer name */
316 if (!GetComputerNameW(ComputerName, ComputerNameLength))
317 {
318 return GetLastError();
319 }
320
321 return ERROR_SUCCESS;
322 }
323 /* If it's a DFS share */
324 else if (TargetDevice == wcsstr(TargetDevice, L"\\Device\\WinDfs\\"))
325 {
326 /* Obviously, query DFS */
327 Query = TRUE;
328 }
329 else
330 {
331 return ERROR_BAD_PATHNAME;
332 }
333 }
334 else
335 {
336 return ERROR_BAD_PATHNAME;
337 }
338
339 /* Query DFS, currently not implemented - shouldn't be missing in ReactOS yet ;-) */
340 if (Query)
341 {
342 UNIMPLEMENTED_DBGBREAK("Querying DFS not implemented!\n");
343 AbsolutePath = NULL;
344 AbsolutePathLength = 0;
345 }
346
347 /* Now, properly extract the computer name from the full path */
348 EndOfName = AbsolutePath;
349 if (AbsolutePathLength)
350 {
351 for (NameLength = 0; NameLength < AbsolutePathLength; NameLength += sizeof(WCHAR))
352 {
353 /* Look for the next \, it will be the end of computer name */
354 if (EndOfName[0] == L'\\')
355 {
356 break;
357 }
358 /* Computer name cannot contain ., if we get to that point, something went wrong... */
359 else if (EndOfName[0] == L'.')
360 {
361 return ERROR_BAD_PATHNAME;
362 }
363
364 ++EndOfName;
365 }
366 }
367
368 NameLength = EndOfName - AbsolutePath;
369 /* Check we didn't overflow and that our computer name isn't ill-formed */
370 if (NameLength >= AbsolutePathLength || NameLength >= MAX_COMPUTERNAME_LENGTH * sizeof(WCHAR))
371 {
372 return ERROR_BAD_PATHNAME;
373 }
374
375 /* Check we can fit */
376 if (NameLength + sizeof(UNICODE_NULL) > *ComputerNameLength * sizeof(WCHAR))
377 {
379 }
380
381 /* Write, zero and done! */
382 RtlCopyMemory(ComputerName, AbsolutePath, NameLength);
383 *ComputerNameLength = NameLength / sizeof(WCHAR);
384 ComputerName[NameLength / sizeof(WCHAR)] = UNICODE_NULL;
385
386 return ERROR_SUCCESS;
387}
388
389
390/*
391 * @implemented
392 */
394WINAPI
397 IN HANDLE NewHandle,
398 IN PUNICODE_STRING NewPath)
399{
401 ULONG ComputerNameLength, FileAttributes;
402 WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
403 OEM_STRING ComputerNameStringA;
404 CHAR ComputerNameStringBuffer[MAX_PATH + 1];
405 UNICODE_STRING ComputerNameStringW;
408 HANDLE hFullWrite;
409 struct
410 {
412 CHAR Buffer[(MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR)];
413 } FileTrackingInfo;
414
415 DPRINT("BasepNotifyTrackingService(%p, %p, %p, %wZ)\n",
416 *ExistingHandle, ObjectAttributes, NewHandle, NewPath);
417
419 ComputerNameLength = ARRAYSIZE(ComputerName);
420
421 /* Attempt to get computer name of target handle */
422 if (BasepGetComputerNameFromNtPath(NewPath, NewHandle, ComputerName, &ComputerNameLength))
423 {
424 /* If we failed to get it, we will just notify with the handle */
425 FileTrackingInfo.ObjectInformationLength = 0;
426 }
427 else
428 {
429 /* Convert the retrieved computer name to ANSI and attach it to the notification */
430 RtlInitEmptyAnsiString(&ComputerNameStringA,
431 ComputerNameStringBuffer,
432 sizeof(ComputerNameStringBuffer));
433
434 RtlInitUnicodeString(&ComputerNameStringW, ComputerName);
435 Status = RtlUnicodeStringToOemString(&ComputerNameStringA, &ComputerNameStringW, FALSE);
436 if (!NT_SUCCESS(Status))
437 {
438 return Status;
439 }
440
441 RtlCopyMemory(FileTrackingInfo.ObjectInformation, ComputerNameStringA.Buffer, ComputerNameStringA.Length);
442 FileTrackingInfo.ObjectInformation[ComputerNameStringA.Length] = ANSI_NULL;
443 FileTrackingInfo.ObjectInformationLength = ComputerNameStringA.Length + 1;
444 }
445
446 /* Attach the handle we moved */
447 FileTrackingInfo.DestinationFile = NewHandle;
448
449 /* Final, notify */
450 Status = NtSetInformationFile(*ExistingHandle,
452 &FileTrackingInfo,
453 sizeof(FileTrackingInfo),
456 {
457 return Status;
458 }
459
460 /* If we get here, we got access denied error, this comes from a
461 * read-only flag. So, close the file, in order to reopen it with enough
462 * rights to remove said flag and reattempt notification.
463 */
464 CloseHandle(*ExistingHandle);
465
466 /* Reopen it, to be able to change the destination file attributes */
467 Status = NtOpenFile(ExistingHandle,
473 if (!NT_SUCCESS(Status))
474 {
475 *ExistingHandle = INVALID_HANDLE_VALUE;
476 return Status;
477 }
478
479 /* Get the file attributes */
480 Status = NtQueryInformationFile(*ExistingHandle,
483 sizeof(FileBasicInfo),
485 if (!NT_SUCCESS(Status))
486 {
487 return Status;
488 }
489
490 /* Get rid of the read only flag */
491 FileAttributes = FileBasicInfo.FileAttributes & ~FILE_ATTRIBUTE_READONLY;
493 FileBasicInfo.FileAttributes = FileAttributes;
494
495 /* Attempt... */
496 Status = NtSetInformationFile(*ExistingHandle,
499 sizeof(FileBasicInfo),
501 if (!NT_SUCCESS(Status))
502 {
503 return Status;
504 }
505
506 /* Now, reopen with maximum accesses to notify */
507 Status = NtOpenFile(&hFullWrite,
513 if (NT_SUCCESS(Status))
514 {
515 NtClose(*ExistingHandle);
516 *ExistingHandle = hFullWrite;
517
518 /* Full success, notify! */
519 Status = NtSetInformationFile(*ExistingHandle,
521 &FileTrackingInfo,
522 sizeof(FileTrackingInfo),
524 }
525
526 /* If opening with full access failed or if notify failed, restore read-only */
527 if (!NT_SUCCESS(Status))
528 {
529 FileBasicInfo.FileAttributes |= FILE_ATTRIBUTE_READONLY;
530
531 Status = NtSetInformationFile(*ExistingHandle,
534 sizeof(FileBasicInfo),
536 }
537
538 /* We're done */
539 return Status;
540}
541
542
543/*
544 * @implemented
545 */
547WINAPI
549 OUT PUNICODE_STRING RelativeNtName,
550 OUT LPWSTR * NtName,
556{
557 RTL_RELATIVE_NAME_U RelativeName;
561 ULONG IntShareAccess;
562 BOOLEAN HasRelative = FALSE;
563
565 {
566 /* Zero output */
567 RtlInitEmptyUnicodeString(RelativeNtName, NULL, 0);
568 *NtName = NULL;
569
570 if (!RtlDosPathNameToRelativeNtPathName_U(File, RelativeNtName, NULL, &RelativeName))
571 {
574 }
575
576 HasRelative = TRUE;
577 *NtName = RelativeNtName->Buffer;
578
579 if (RelativeName.RelativeName.Length)
580 {
581 RelativeNtName->Length = RelativeName.RelativeName.Length;
582 RelativeNtName->MaximumLength = RelativeName.RelativeName.MaximumLength;
583 RelativeNtName->Buffer = RelativeName.RelativeName.Buffer;
584 }
585 else
586 {
587 RelativeName.ContainingDirectory = NULL;
588 }
589
591 RelativeNtName,
593 RelativeName.ContainingDirectory,
594 NULL);
595 /* Force certain flags here, given ops we'll do */
596 IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE;
598
599 /* We'll try to read reparse tag */
604 IntShareAccess,
606 if (NT_SUCCESS(Status))
607 {
608 /* Attempt the read */
611 &TagInfo,
612 sizeof(TagInfo),
614
615 /* Return if failure with a status that wouldn't mean the FSD cannot support reparse points */
616 if (!NT_SUCCESS(Status) &&
618 {
620 }
621
622 if (NT_SUCCESS(Status))
623 {
624 /* This cannot happen on mount points */
627 {
629 }
630 }
631
634
635 IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_DELETE;
636 }
638 {
639 IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE;
640 }
641 else
642 {
644 }
645
646 /* Reattempt to open normally, following reparse point if needed */
651 IntShareAccess,
653 }
655 {
656 if (HasRelative)
657 {
658 RtlReleaseRelativeName(&RelativeName);
659 }
660 }
661 _SEH2_END;
662
663 return Status;
664}
665
666
667/*
668 * @implemented
669 */
670DWORD
671WINAPI
673 IN LARGE_INTEGER TotalBytesTransferred,
674 IN LARGE_INTEGER StreamSize,
675 IN LARGE_INTEGER StreamBytesTransferred,
676 IN DWORD dwStreamNumber,
677 IN DWORD dwCallbackReason,
678 IN HANDLE hSourceFile,
679 IN HANDLE hDestinationFile,
680 IN LPVOID lpData OPTIONAL)
681{
682 DWORD Ret = 0;
684
685 if (Context->Flags & MOVEFILE_WRITE_THROUGH)
686 {
687 if (!dwCallbackReason)
688 {
689 if (StreamBytesTransferred.QuadPart == StreamSize.QuadPart)
690 {
691 FlushFileBuffers(hDestinationFile);
692 }
693 }
694 }
695
696 if (Context->UserRoutine)
697 {
698 Ret = Context->UserRoutine(TotalFileSize,
699 TotalBytesTransferred,
700 StreamSize,
701 StreamBytesTransferred,
702 dwStreamNumber,
703 dwCallbackReason,
704 hSourceFile,
705 hDestinationFile,
706 Context->UserData);
707 }
708
709 return Ret;
710}
711
712
713/*
714 * @implemented
715 */
716BOOL
717WINAPI
719 IN LPCWSTR lpNewFileName,
720 IN LPPROGRESS_ROUTINE lpProgressRoutine,
721 IN LPVOID lpData,
723{
725 PWSTR NewBuffer;
729 PFILE_RENAME_INFORMATION RenameInfo;
730 UNICODE_STRING NewPathU, ExistingPathU;
732 HANDLE SourceHandle = INVALID_HANDLE_VALUE, NewHandle, ExistingHandle;
733 BOOL Ret = FALSE, ReplaceIfExists, DelayUntilReboot, AttemptReopenWithoutReparse;
734
735 DPRINT("MoveFileWithProgressW(%S, %S, %p, %p, %x)\n",
736 lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags);
737
738 NewPathU.Buffer = NULL;
739 ExistingPathU.Buffer = NULL;
740
742 {
743 /* Don't allow renaming to a disk */
744 if (lpNewFileName && RtlIsDosDeviceName_U(lpNewFileName))
745 {
748 }
749
750 ReplaceIfExists = !!(dwFlags & MOVEFILE_REPLACE_EXISTING);
751
752 /* Get file path */
753 if (!RtlDosPathNameToNtPathName_U(lpExistingFileName, &ExistingPathU, NULL, NULL))
754 {
757 }
758
759 /* Sanitize input */
760 DelayUntilReboot = !!(dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT);
761 if (DelayUntilReboot && (dwFlags & MOVEFILE_CREATE_HARDLINK))
762 {
765 }
766
767 /* Unless we manage a proper opening, we'll attempt to reopen without reparse support */
768 AttemptReopenWithoutReparse = TRUE;
770 &ExistingPathU,
772 NULL,
773 NULL);
774 /* Attempt to open source file */
781 if (!NT_SUCCESS(Status))
782 {
783 /* If we failed and the file doesn't exist, don't attempt to reopen without reparse */
784 if (DelayUntilReboot &&
786 {
787 /* Here we don't fail completely, as we postpone the operation to reboot.
788 * File might exist afterwards, and we don't need a handle here. */
790 AttemptReopenWithoutReparse = FALSE;
791 }
792 /* If we failed for any reason than unsupported reparse, fail completely */
794 {
797 }
798 }
799 else
800 {
801 /* We managed to open, so query information */
804 &TagInfo,
805 sizeof(TagInfo),
807 if (!NT_SUCCESS(Status))
808 {
809 /* Do not tolerate any other error than something related to not supported operation */
811 {
814 }
815
816 /* Not a reparse point, no need to reopen, it's fine */
817 AttemptReopenWithoutReparse = FALSE;
818 }
819 /* Validate the reparse point (do we support it?) */
820 else if ((TagInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
822 {
825 }
826 else
827 {
828 /* Mount point, let's rename it */
829 AttemptReopenWithoutReparse = FALSE;
830 }
831 }
832
833 /* Simply reopen if required */
834 if (AttemptReopenWithoutReparse)
835 {
842 if (!NT_SUCCESS(Status))
843 {
846 }
847 }
848
849 /* Nullify string if we're to use it */
850 if (DelayUntilReboot && !lpNewFileName)
851 {
852 RtlInitUnicodeString(&NewPathU, NULL);
853 }
854 /* Check whether path exists */
855 else if (!RtlDosPathNameToNtPathName_U(lpNewFileName, &NewPathU, NULL, NULL))
856 {
859 }
860
861 /* Handle postponed renaming */
862 if (DelayUntilReboot)
863 {
864 /* If new file exists and we're allowed to replace, then mark the path with ! */
865 if (ReplaceIfExists && NewPathU.Length)
866 {
867 NewBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(WCHAR));
868 if (NewBuffer == NULL)
869 {
872 }
873
874 NewBuffer[0] = L'!';
875 RtlCopyMemory(&NewBuffer[1], NewPathU.Buffer, NewPathU.Length);
876 NewPathU.Length += sizeof(WCHAR);
877 NewPathU.MaximumLength += sizeof(WCHAR);
878 RtlFreeHeap(RtlGetProcessHeap(), 0, NewPathU.Buffer);
879 NewPathU.Buffer = NewBuffer;
880 }
881
882 /* Check whether 'copy' renaming is allowed if required */
883 if ((RtlDetermineDosPathNameType_U(lpExistingFileName) == RtlPathTypeUncAbsolute) ||
885 {
887 }
888 else
889 {
890 /* First, probe 2nd key to see whether it exists - if so, it will be appended there */
891 Status = BasepMoveFileDelayed(&ExistingPathU, &NewPathU, 2, FALSE);
893 {
894 /* If doesn't exist, append to first key first, creating it if it doesn't exist */
895 Status = BasepMoveFileDelayed(&ExistingPathU, &NewPathU, 1, TRUE);
897 {
898 /* If it failed because it's too big, then create 2nd key and put it there */
899 Status = BasepMoveFileDelayed(&ExistingPathU, &NewPathU, 2, TRUE);
900 }
901 }
902 }
903
904 /* If we failed at some point, return the error */
905 if (!NT_SUCCESS(Status))
906 {
909 }
910
911 Ret = TRUE;
913 }
914
915 /* At that point, we MUST have a source handle */
917
918 /* Allocate renaming buffer and fill it */
919 RenameInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0,
920 NewPathU.Length + sizeof(FILE_RENAME_INFORMATION));
921 if (RenameInfo == NULL)
922 {
925 }
926
927 RtlCopyMemory(&RenameInfo->FileName, NewPathU.Buffer, NewPathU.Length);
928 RenameInfo->ReplaceIfExists = ReplaceIfExists;
929 RenameInfo->RootDirectory = NULL;
930 RenameInfo->FileNameLength = NewPathU.Length;
931
932 /* Attempt to rename the file */
935 RenameInfo,
936 NewPathU.Length + sizeof(FILE_RENAME_INFORMATION),
939 RtlFreeHeap(RtlGetProcessHeap(), 0, RenameInfo);
940 if (NT_SUCCESS(Status))
941 {
942 /* If it succeed, all fine, quit */
943 Ret = TRUE;
945 }
946 /* If we failed for any other reason than not the same device, fail.
947 * If we failed because of different devices, only allow renaming if user allowed copy.
948 */
950 {
951 /* ReactOS HACK! To be removed once all FSD have proper renaming support.
952 * Just leave status to error and leave. */
954 {
955 DPRINT1("Forcing copy, renaming not supported by FSD\n");
956 }
957 else
958 {
961 }
962 }
963
964 /* Close source file */
967
968 /* Issue the copy of the file */
969 CopyContext.Flags = dwFlags;
970 CopyContext.UserRoutine = lpProgressRoutine;
971 CopyContext.UserData = lpData;
972 NewHandle = INVALID_HANDLE_VALUE;
973 ExistingHandle = INVALID_HANDLE_VALUE;
974
975 Ret = BasepCopyFileExW(lpExistingFileName,
976 lpNewFileName,
979 NULL,
980 (!ReplaceIfExists ? COPY_FILE_FAIL_IF_EXISTS : 0)
982 0,
983 &ExistingHandle,
984 &NewHandle);
985 if (!Ret)
986 {
987 /* If it failed, don't leak any handle */
988 if (ExistingHandle != INVALID_HANDLE_VALUE)
989 {
990 CloseHandle(ExistingHandle);
991 ExistingHandle = INVALID_HANDLE_VALUE;
992 }
993 }
994 else if (ExistingHandle != INVALID_HANDLE_VALUE)
995 {
996 if (NewHandle != INVALID_HANDLE_VALUE)
997 {
998 /* If copying succeed, notify */
999 Status = BasepNotifyTrackingService(&ExistingHandle,
1001 NewHandle,
1002 &NewPathU);
1003 if (!NT_SUCCESS(Status))
1004 {
1005 /* Fail in case it had to succeed */
1007 {
1008 if (NewHandle != INVALID_HANDLE_VALUE)
1009 CloseHandle(NewHandle);
1010 NewHandle = INVALID_HANDLE_VALUE;
1011 DeleteFileW(lpNewFileName);
1012 Ret = FALSE;
1014 }
1015 }
1016 }
1017
1018 CloseHandle(ExistingHandle);
1019 ExistingHandle = INVALID_HANDLE_VALUE;
1020 }
1021
1022 /* In case copy worked, close file */
1023 if (NewHandle != INVALID_HANDLE_VALUE)
1024 {
1025 CloseHandle(NewHandle);
1026 NewHandle = INVALID_HANDLE_VALUE;
1027 }
1028
1029 /* If it succeed, delete source file */
1030 if (Ret)
1031 {
1032 if (!DeleteFileW(lpExistingFileName))
1033 {
1034 /* Reset file attributes if required */
1035 SetFileAttributesW(lpExistingFileName, FILE_ATTRIBUTE_NORMAL);
1036 DeleteFileW(lpExistingFileName);
1037 }
1038 }
1039 }
1041 {
1044
1045 RtlFreeHeap(RtlGetProcessHeap(), 0, ExistingPathU.Buffer);
1046 RtlFreeHeap(RtlGetProcessHeap(), 0, NewPathU.Buffer);
1047 }
1048 _SEH2_END;
1049
1050 return Ret;
1051}
1052
1053/*
1054 * @implemented
1055 */
1056BOOL
1057WINAPI
1058MoveFileW(IN LPCWSTR lpExistingFileName,
1059 IN LPCWSTR lpNewFileName)
1060{
1061 return MoveFileWithProgressW(lpExistingFileName,
1062 lpNewFileName,
1063 NULL,
1064 NULL,
1066}
1067
1068
1069/*
1070 * @implemented
1071 */
1072BOOL
1073WINAPI
1074MoveFileExW(IN LPCWSTR lpExistingFileName,
1075 IN LPCWSTR lpNewFileName OPTIONAL,
1077{
1078 return MoveFileWithProgressW(lpExistingFileName,
1079 lpNewFileName,
1080 NULL,
1081 NULL,
1082 dwFlags);
1083}
1084
1085/*
1086 * @unimplemented
1087 */
1088BOOL
1089WINAPI
1091 LPCWSTR lpReplacedFileName,
1092 LPCWSTR lpReplacementFileName,
1093 LPCWSTR lpBackupFileName,
1094 DWORD dwReplaceFlags,
1095 LPVOID lpExclude,
1097 )
1098{
1099 HANDLE hReplaced = NULL, hReplacement = NULL;
1100 UNICODE_STRING NtReplacedName = { 0, 0, NULL };
1101 UNICODE_STRING NtReplacementName = { 0, 0, NULL };
1104 BOOL Ret = FALSE;
1107 PVOID Buffer = NULL ;
1108
1109 if (dwReplaceFlags)
1110 FIXME("Ignoring flags %x\n", dwReplaceFlags);
1111
1112 /* First two arguments are mandatory */
1113 if (!lpReplacedFileName || !lpReplacementFileName)
1114 {
1116 return FALSE;
1117 }
1118
1119 /* Back it up */
1120 if(lpBackupFileName)
1121 {
1122 if(!CopyFileW(lpReplacedFileName, lpBackupFileName, FALSE))
1123 {
1124 Error = GetLastError();
1125 goto Cleanup ;
1126 }
1127 }
1128
1129 /* Open the "replaced" file for reading and writing */
1130 if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &NtReplacedName, NULL, NULL)))
1131 {
1133 goto Cleanup;
1134 }
1135
1137 &NtReplacedName,
1139 NULL,
1140 NULL);
1141
1142 Status = NtOpenFile(&hReplaced,
1148
1149 if (!NT_SUCCESS(Status))
1150 {
1153 else
1155 goto Cleanup;
1156 }
1157
1158 /* Blank it */
1159 SetEndOfFile(hReplaced) ;
1160
1161 /*
1162 * Open the replacement file for reading, writing, and deleting
1163 * (deleting is needed when finished)
1164 */
1165 if (!(RtlDosPathNameToNtPathName_U(lpReplacementFileName, &NtReplacementName, NULL, NULL)))
1166 {
1168 goto Cleanup;
1169 }
1170
1172 &NtReplacementName,
1174 NULL,
1175 NULL);
1176
1177 Status = NtOpenFile(&hReplacement,
1181 0,
1183
1184 if (!NT_SUCCESS(Status))
1185 {
1187 goto Cleanup;
1188 }
1189
1190 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 0x10000) ;
1191 if (!Buffer)
1192 {
1194 goto Cleanup ;
1195 }
1196 while (Status != STATUS_END_OF_FILE)
1197 {
1198 Status = NtReadFile(hReplacement, NULL, NULL, NULL, &IoStatusBlock, Buffer, 0x10000, NULL, NULL) ;
1199 if (NT_SUCCESS(Status))
1200 {
1203 if (!NT_SUCCESS(Status))
1204 {
1206 goto Cleanup;
1207 }
1208 }
1209 else if (Status != STATUS_END_OF_FILE)
1210 {
1212 goto Cleanup;
1213 }
1214 }
1215
1216 Ret = TRUE;
1217
1218 /* Perform resource cleanup */
1219Cleanup:
1220 if (hReplaced) NtClose(hReplaced);
1221 if (hReplacement) NtClose(hReplacement);
1222 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1223
1224 if (NtReplacementName.Buffer)
1225 RtlFreeHeap(GetProcessHeap(), 0, NtReplacementName.Buffer);
1226 if (NtReplacedName.Buffer)
1227 RtlFreeHeap(GetProcessHeap(), 0, NtReplacedName.Buffer);
1228
1229 /* If there was an error, set the error code */
1230 if(!Ret)
1231 {
1232 TRACE("ReplaceFileW failed (error=%lu)\n", Error);
1234 }
1235 return Ret;
1236}
1237
1238
1239/*
1240 * @implemented
1241 */
1242BOOL
1243WINAPI
1245{
1246 ACCESS_MASK SourceAccess;
1247 UNICODE_STRING NtSource, NtDestination;
1248 LPWSTR RelativeSource, RelativeDestination;
1249 HANDLE SourceHandle, DestinationHandle;
1250 OBJECT_ATTRIBUTES ObjectAttributesSource, ObjectAttributesDestination;
1251 NTSTATUS Status, OldStatus = STATUS_SUCCESS;
1252 ACCESS_MASK DestAccess;
1254 FILE_BASIC_INFORMATION SourceInformation, DestinationInformation;
1256
1257 DPRINT("PrivMoveFileIdentityW(%S, %S, %x)\n", lpSource, lpDestination, dwFlags);
1258
1260 RtlInitEmptyUnicodeString(&NtSource, NULL, 0);
1261 RelativeSource = NULL;
1262 DestinationHandle = INVALID_HANDLE_VALUE;
1263 RtlInitEmptyUnicodeString(&NtDestination, NULL, 0);
1264 RelativeDestination = NULL;
1265
1266 /* FILE_WRITE_DATA is required for later on notification */
1267 SourceAccess = FILE_READ_ATTRIBUTES | FILE_WRITE_DATA;
1269 {
1270 SourceAccess |= DELETE;
1271 }
1272
1273 _SEH2_TRY
1274 {
1275 /* We will loop twice:
1276 * First we attempt to open with FILE_WRITE_DATA for notification.
1277 * If it fails and we have flag for non-trackable files, we retry
1278 * without FILE_WRITE_DATA.
1279 * If that one fails, then, we quit for real.
1280 */
1281 while (TRUE)
1282 {
1283 Status = BasepOpenFileForMove(lpSource,
1284 &NtSource,
1285 &RelativeSource,
1286 &SourceHandle,
1287 &ObjectAttributesSource,
1288 SourceAccess,
1291 if (NT_SUCCESS(Status))
1292 {
1293 break;
1294 }
1295
1296 /* If we already attempted the opening without FILE_WRITE_DATA
1297 * or if we cannot move on non-trackable files, fail.
1298 */
1299 if (!(SourceAccess & FILE_WRITE_DATA) || !(dwFlags & PRIV_ALLOW_NON_TRACKABLE))
1300 {
1302 }
1303
1304 if (RelativeSource)
1305 {
1306 RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSource);
1307 RelativeSource = NULL;
1308 }
1309
1311 {
1314 }
1315
1316 SourceAccess &= ~FILE_WRITE_DATA;
1317
1318 /* Remember fist failure in the path */
1319 if (NT_SUCCESS(OldStatus))
1320 {
1321 OldStatus = Status;
1322 }
1323 }
1324
1325 DestAccess = FILE_WRITE_ATTRIBUTES;
1326 /* If we could preserve FILE_WRITE_DATA for source, attempt to
1327 * get it for destination, still for notification purposes. */
1328 if (SourceAccess & FILE_WRITE_DATA)
1329 {
1330 DestAccess |= FILE_WRITE_DATA;
1331 }
1332
1333 /* cf comment for first loop */
1334 while (TRUE)
1335 {
1336 Status = BasepOpenFileForMove(lpDestination,
1337 &NtDestination,
1338 &RelativeDestination,
1339 &DestinationHandle,
1340 &ObjectAttributesDestination,
1341 DestAccess,
1344 if (NT_SUCCESS(Status))
1345 {
1346 break;
1347 }
1348
1349 /* If we already attempted the opening without FILE_WRITE_DATA
1350 * or if we cannot move on non-trackable files, fail.
1351 */
1352 if (!(DestAccess & FILE_WRITE_DATA) || !(dwFlags & PRIV_ALLOW_NON_TRACKABLE))
1353 {
1355 }
1356
1357 if (RelativeDestination)
1358 {
1359 RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeDestination);
1360 RelativeDestination = NULL;
1361 }
1362
1363 if (DestinationHandle != INVALID_HANDLE_VALUE)
1364 {
1365 NtClose(DestinationHandle);
1366 DestinationHandle = INVALID_HANDLE_VALUE;
1367 }
1368
1369 DestAccess &= ~FILE_WRITE_DATA;
1370
1371 /* Remember fist failure in the path */
1372 if (NT_SUCCESS(OldStatus))
1373 {
1374 OldStatus = Status;
1375 }
1376 }
1377
1378 /* Get the creation time from source */
1381 &SourceInformation,
1382 sizeof(SourceInformation),
1384 if (NT_SUCCESS(Status))
1385 {
1386 /* Then, prepare to set it for destination */
1387 RtlZeroMemory(&DestinationInformation, sizeof(DestinationInformation));
1388 DestinationInformation.CreationTime.QuadPart = SourceInformation.CreationTime.QuadPart;
1389
1390 /* And set it, that's all folks! */
1391 Status = NtSetInformationFile(DestinationHandle,
1393 &DestinationInformation,
1394 sizeof(DestinationInformation),
1396 }
1397
1398 if (!NT_SUCCESS(Status))
1399 {
1401 {
1403 }
1404
1405 /* Remember the failure for later notification */
1406 if (NT_SUCCESS(OldStatus))
1407 {
1408 OldStatus = Status;
1409 }
1410 }
1411
1412 /* If we could open with FILE_WRITE_DATA both source and destination,
1413 * then, notify
1414 */
1415 if (DestAccess & FILE_WRITE_DATA && SourceAccess & FILE_WRITE_DATA)
1416 {
1418 &ObjectAttributesSource,
1419 DestinationHandle,
1420 &NtDestination);
1421 if (!NT_SUCCESS(Status))
1422 {
1424 {
1425 if (NT_SUCCESS(OldStatus))
1426 OldStatus = Status;
1427
1428 /* Reset status, we allow non trackable files */
1430 }
1431 }
1432 }
1433 }
1435 {
1436 if (RelativeSource)
1437 RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSource);
1438
1439 if (RelativeDestination)
1440 RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeDestination);
1441 }
1442 _SEH2_END;
1443
1444 /* If caller asked for source deletion, if everything succeed, proceed */
1446 {
1447 FileDispositionInfo.DeleteFile = TRUE;
1448
1452 sizeof(FileDispositionInfo),
1454 }
1455
1456 /* Cleanup/close portion */
1457 if (DestinationHandle != INVALID_HANDLE_VALUE)
1458 {
1459 NtClose(DestinationHandle);
1460 }
1461
1463 {
1465 }
1466
1467 /* Set last error if any, and quit */
1468 if (NT_SUCCESS(Status))
1469 {
1470 if (!NT_SUCCESS(OldStatus))
1471 {
1472 BaseSetLastNTError(OldStatus);
1473 }
1474 }
1475 else
1476 {
1478 }
1479
1480 return NT_SUCCESS(Status);
1481}
1482
1483/* EOF */
WCHAR Letter
PRTL_UNICODE_STRING_BUFFER Path
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
#define DEBUG_CHANNEL(args)
Definition: rdesktop.h:159
#define DPRINT1
Definition: precomp.h:8
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
#define FIXME(fmt,...)
Definition: precomp.h:53
BOOL Error
Definition: chkdsk.c:66
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
Definition: bufpool.h:45
Definition: File.h:16
BOOL WINAPI GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
Definition: compname.c:446
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define wcschr
Definition: compat.h:17
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:542
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:365
BOOL BasepCopyFileExW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, IN LPVOID lpData OPTIONAL, IN LPBOOL pbCancel OPTIONAL, IN DWORD dwCopyFlags, IN DWORD dwBasepFlags, OUT LPHANDLE lpExistingHandle, OUT LPHANDLE lpNewHandle)
Definition: copy.c:202
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:778
BOOL WINAPI FlushFileBuffers(IN HANDLE hFile)
Definition: fileinfo.c:25
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:988
struct _COPY_PROGRESS_CONTEXT COPY_PROGRESS_CONTEXT
BOOL WINAPI MoveFileWithProgressW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine, IN LPVOID lpData, IN DWORD dwFlags)
Definition: move.c:718
BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileName, LPCWSTR lpBackupFileName, DWORD dwReplaceFlags, LPVOID lpExclude, LPVOID lpReserved)
Definition: move.c:1090
NTSTATUS WINAPI BasepMoveFileDelayed(_In_ PUNICODE_STRING ExistingPath, _In_ PUNICODE_STRING NewPath, _In_ INT KeyId, _In_ BOOL CreateIfNotFound)
Adds an entry in the "PendingFileRenameOperations" registry value, that is parsed at boot-time by SMS...
Definition: move.c:88
DWORD WINAPI BasepMoveFileCopyProgress(IN LARGE_INTEGER TotalFileSize, IN LARGE_INTEGER TotalBytesTransferred, IN LARGE_INTEGER StreamSize, IN LARGE_INTEGER StreamBytesTransferred, IN DWORD dwStreamNumber, IN DWORD dwCallbackReason, IN HANDLE hSourceFile, IN HANDLE hDestinationFile, IN LPVOID lpData OPTIONAL)
Definition: move.c:672
NTSTATUS WINAPI BasepOpenFileForMove(IN LPCWSTR File, OUT PUNICODE_STRING RelativeNtName, OUT LPWSTR *NtName, OUT PHANDLE FileHandle, OUT POBJECT_ATTRIBUTES ObjectAttributes, IN ACCESS_MASK DesiredAccess, IN ULONG ShareAccess, IN ULONG OpenOptions)
Definition: move.c:548
BOOL WINAPI MoveFileExW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName OPTIONAL, IN DWORD dwFlags)
Definition: move.c:1074
struct _COPY_PROGRESS_CONTEXT * PCOPY_PROGRESS_CONTEXT
BOOL WINAPI MoveFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
Definition: move.c:1058
BOOL WINAPI PrivMoveFileIdentityW(IN LPCWSTR lpSource, IN LPCWSTR lpDestination, IN DWORD dwFlags)
Definition: move.c:1244
DWORD WINAPI BasepGetComputerNameFromNtPath(IN PUNICODE_STRING NewPath, IN HANDLE NewHandle, OUT PWSTR ComputerName, IN OUT PULONG ComputerNameLength)
Definition: move.c:236
#define STRING_LENGTH
NTSTATUS WINAPI BasepNotifyTrackingService(IN OUT PHANDLE ExistingHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE NewHandle, IN PUNICODE_STRING NewPath)
Definition: move.c:395
BOOL WINAPI CopyContext(CONTEXT *dst, DWORD context_flags, CONTEXT *src)
Definition: memory.c:1633
_ACRTIMP wchar_t *__cdecl wcsstr(const wchar_t *, const wchar_t *)
Definition: wcs.c:2993
static const WCHAR Cleanup[]
Definition: register.c:80
#define L(x)
Definition: resources.c:13
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB _In_ PDCB _In_ PDIRENT _In_ ULONG _In_ ULONG _In_ PUNICODE_STRING _In_ PACCESS_MASK _In_ USHORT ShareAccess
Definition: create.c:4148
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define MOVEFILE_WRITE_THROUGH
Definition: filesup.h:30
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1236
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileTrackingInformation
Definition: from_kernel.h:97
@ FileLinkInformation
Definition: from_kernel.h:72
@ FileAttributeTagInformation
Definition: from_kernel.h:96
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_OPEN_NO_RECALL
Definition: from_kernel.h:47
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
Status
Definition: gdiplustypes.h:25
#define OBJ_OPENIF
Definition: winternl.h:229
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define PRIV_ALLOW_NON_TRACKABLE
Definition: kernel32.h:131
#define kernel32file
Definition: kernel32.h:6
#define PRIV_DELETE_ON_SUCCESS
Definition: kernel32.h:130
@ FileDispositionInfo
Definition: minwinbase.h:308
@ FileBasicInfo
Definition: minwinbase.h:304
#define ASSERT(a)
Definition: mode.c:44
#define FILE_ATTRIBUTE_DEVICE
Definition: disk.h:27
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4755
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_STATUS _Out_ PNDIS_HANDLE _Out_ PUINT _In_ UINT _In_ NDIS_HANDLE _In_ NDIS_HANDLE _In_ PNDIS_STRING _In_ UINT OpenOptions
Definition: ndis.h:6017
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
VOID NTAPI RtlReleaseRelativeName(_In_ PRTL_RELATIVE_NAME_U RelativeName)
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToRelativeNtPathName_U(_In_ PCWSTR DosName, _Out_ PUNICODE_STRING NtName, _Out_ PCWSTR *PartName, _Out_ PRTL_RELATIVE_NAME_U RelativeName)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToNtPathName_U(_In_opt_z_ PCWSTR DosPathName, _Out_ PUNICODE_STRING NtPathName, _Out_opt_ PCWSTR *NtFileNamePart, _Out_opt_ PRTL_RELATIVE_NAME_U DirectoryInfo)
@ RtlPathTypeUncAbsolute
Definition: rtltypes.h:466
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
#define _In_
Definition: no_sal2.h:158
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI NTSTATUS NTAPI NtSetValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN ULONG TitleIndex OPTIONAL, IN ULONG Type, IN PVOID Data, IN ULONG DataSize)
Definition: ntapi.c:859
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define WRITE_DAC
Definition: nt_native.h:59
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
@ KeyValuePartialInformation
Definition: nt_native.h:1185
ULONG ACCESS_MASK
Definition: nt_native.h:40
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1060
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define REG_OPTION_BACKUP_RESTORE
Definition: nt_native.h:1069
#define REG_MULTI_SZ
Definition: nt_native.h:1504
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define DELETE
Definition: nt_native.h:57
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define GENERIC_WRITE
Definition: nt_native.h:90
NTSTATUS NTAPI NtCreateKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN ULONG TitleIndex, IN PUNICODE_STRING Class OPTIONAL, IN ULONG CreateOptions, OUT PULONG Disposition OPTIONAL)
Definition: ntapi.c:240
#define UNICODE_NULL
#define ANSI_NULL
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:542
NTSTRSAFEVAPI RtlStringCbPrintfW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCWSTR pszFormat,...)
Definition: ntstrsafe.h:1173
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_FINALLY
Definition: pseh2_64.h:130
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_LEAVE
Definition: pseh2_64.h:183
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define STATUS_END_OF_FILE
Definition: shellext.h:67
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
NTSTATUS NTAPI NtReadFile(HANDLE FileHandle, HANDLE Event, PIO_APC_ROUTINE ApcRoutine, PVOID ApcContext, PIO_STATUS_BLOCK IoStatusBlock, PVOID Buffer, ULONG Length, PLARGE_INTEGER ByteOffset, PULONG Key)
#define DPRINT
Definition: sndvol32.h:73
#define TRACE(s)
Definition: solgame.cpp:4
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
LPPROGRESS_ROUTINE UserRoutine
Definition: move.c:27
LARGE_INTEGER CreationTime
Definition: nt_native.h:942
UNICODE_STRING RelativeName
Definition: rtltypes.h:1374
HANDLE ContainingDirectory
Definition: rtltypes.h:1375
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
int32_t INT
Definition: typedefs.h:58
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
STRING OEM_STRING
Definition: umtypes.h:205
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2664
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3281
#define COPY_FILE_FAIL_IF_EXISTS
Definition: winbase.h:232
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define COPY_FILE_OPEN_SOURCE_FOR_WRITE
Definition: winbase.h:234
DWORD(WINAPI * LPPROGRESS_ROUTINE)(_In_ LARGE_INTEGER, _In_ LARGE_INTEGER, _In_ LARGE_INTEGER, _In_ LARGE_INTEGER, _In_ DWORD, _In_ DWORD, _In_ HANDLE, _In_ HANDLE, _In_opt_ LPVOID)
Definition: winbase.h:1197
#define MOVEFILE_FAIL_IF_NOT_TRACKABLE
Definition: winbase.h:380
#define MOVEFILE_CREATE_HARDLINK
Definition: winbase.h:379
#define MOVEFILE_DELAY_UNTIL_REBOOT
Definition: winbase.h:377
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:267
#define WINAPI
Definition: msvc.h:6
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:307
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_BAD_PATHNAME
Definition: winerror.h:355
#define ERROR_UNABLE_TO_REMOVE_REPLACED
Definition: winerror.h:1020
_In_ DWORD _In_ int _In_ int _In_opt_ LPNLSVERSIONINFO _In_opt_ LPVOID lpReserved
Definition: winnls.h:1268
_Must_inspect_result_ __drv_aliasesMem PDEVICE_OBJECT _In_ PDEVICE_OBJECT TargetDevice
Definition: iofuncs.h:691
struct _FILE_TRACKING_INFORMATION FILE_TRACKING_INFORMATION
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:7234
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char CHAR
Definition: xmlstorage.h:175