ReactOS  0.4.13-dev-39-g8b6696f
move.c File Reference
#include <k32.h>
#include <malloc.h>
#include <strsafe.h>
#include <debug.h>
Include dependency graph for move.c:

Go to the source code of this file.

Classes

struct  _COPY_PROGRESS_CONTEXT
 

Macros

#define NDEBUG
 
#define STRING_LENGTH   0x400
 

Typedefs

typedef struct _COPY_PROGRESS_CONTEXT COPY_PROGRESS_CONTEXT
 
typedef struct _COPY_PROGRESS_CONTEXTPCOPY_PROGRESS_CONTEXT
 

Functions

 DEBUG_CHANNEL (kernel32file)
 
NTSTATUS WINAPI BasepMoveFileDelayed (IN PUNICODE_STRING ExistingPath, IN PUNICODE_STRING NewPath, IN INT KeyId, IN BOOL CreateIfNotFound)
 
DWORD WINAPI BasepGetComputerNameFromNtPath (IN PUNICODE_STRING NewPath, IN HANDLE NewHandle, OUT PWSTR ComputerName, IN OUT PULONG ComputerNameLength)
 
NTSTATUS WINAPI BasepNotifyTrackingService (IN OUT PHANDLE ExistingHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE NewHandle, IN PUNICODE_STRING NewPath)
 
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)
 
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)
 
BOOL WINAPI MoveFileWithProgressW (IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine, IN LPVOID lpData, IN DWORD dwFlags)
 
BOOL WINAPI MoveFileWithProgressA (IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName OPTIONAL, IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, IN LPVOID lpData OPTIONAL, IN DWORD dwFlags)
 
BOOL WINAPI MoveFileW (IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName)
 
BOOL WINAPI MoveFileExW (IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName OPTIONAL, IN DWORD dwFlags)
 
BOOL WINAPI MoveFileA (IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName)
 
BOOL WINAPI MoveFileExA (IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName OPTIONAL, IN DWORD dwFlags)
 
BOOL WINAPI ReplaceFileA (IN LPCSTR lpReplacedFileName, IN LPCSTR lpReplacementFileName, IN LPCSTR lpBackupFileName OPTIONAL, IN DWORD dwReplaceFlags, IN LPVOID lpExclude, IN LPVOID lpReserved)
 
BOOL WINAPI ReplaceFileW (LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileName, LPCWSTR lpBackupFileName, DWORD dwReplaceFlags, LPVOID lpExclude, LPVOID lpReserved)
 
BOOL WINAPI PrivMoveFileIdentityW (IN LPCWSTR lpSource, IN LPCWSTR lpDestination, IN DWORD dwFlags)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 21 of file move.c.

◆ STRING_LENGTH

#define STRING_LENGTH   0x400

Typedef Documentation

◆ COPY_PROGRESS_CONTEXT

◆ PCOPY_PROGRESS_CONTEXT

Function Documentation

◆ BasepGetComputerNameFromNtPath()

DWORD WINAPI BasepGetComputerNameFromNtPath ( IN PUNICODE_STRING  NewPath,
IN HANDLE  NewHandle,
OUT PWSTR  ComputerName,
IN OUT PULONG  ComputerNameLength 
)

Definition at line 185 of file move.c.

189 {
190  BOOL Query = FALSE;
191  WCHAR Letter;
192  PWSTR AbsolutePath, EndOfName;
193  USHORT AbsolutePathLength, NameLength;
194  WCHAR TargetDevice[0x105];
195  WCHAR DeviceName[] = {'A', ':', '\0'}; /* Init to something, will be set later */
196  UNICODE_STRING UncString = RTL_CONSTANT_STRING(L"\\??\\UNC\\");
197  UNICODE_STRING GlobalString = RTL_CONSTANT_STRING(L"\\??\\");
198 
199  DPRINT("BasepGetComputerNameFromNtPath(%wZ, %p, %p, %lu)\n", NewPath, NewHandle, ComputerName, ComputerNameLength);
200 
201  /* If it's an UNC path */
202  if (RtlPrefixUnicodeString(&UncString, NewPath, TRUE))
203  {
204  /* Check for broken caller */
205  if (NewPath->Length <= UncString.Length)
206  {
207  return ERROR_BAD_PATHNAME;
208  }
209 
210  /* Skip UNC prefix */
211  AbsolutePath = &NewPath->Buffer[UncString.Length / sizeof(WCHAR)];
212  AbsolutePathLength = NewPath->Length - UncString.Length;
213 
214  /* And query DFS */
215  Query = TRUE;
216  }
217  /* Otherwise, we have to be in global (NT path!), with drive letter */
218  else if (RtlPrefixUnicodeString(&GlobalString, NewPath, TRUE) && NewPath->Buffer[5] == ':')
219  {
220  /* Path is like that: \??\C:\Complete Path\To File.ext */
221  /* Get the letter and upcase it if required */
222  Letter = NewPath->Buffer[4];
223  if (Letter >= 'a' && Letter <= 'z')
224  {
225  Letter -= ('a' - 'A');
226  }
227  DeviceName[0] = Letter;
228 
229  /* Query the associated DOS device */
231  {
232  return GetLastError();
233  }
234 
235  /* If that's a network share */
236  if (TargetDevice == wcsstr(TargetDevice, L"\\Device\\LanmanRedirector\\;"))
237  {
238  /* Path is like that: \Device\LanmanRedirector\;C:0000000000000000\Complete Path\To File.ext */
239  /* Check we have the correct drive letter */
240  if (TargetDevice[26] == DeviceName[0] &&
241  TargetDevice[27] == ':')
242  {
243  /* Check for the path begin, computer name is before */
244  PWSTR Path = wcschr(&TargetDevice[28], '\\');
245  if (Path == NULL)
246  {
247  return ERROR_BAD_PATHNAME;
248  }
249 
250  AbsolutePath = Path + 1;
251  AbsolutePathLength = sizeof(WCHAR) * (ARRAYSIZE(TargetDevice) - (AbsolutePath - TargetDevice));
252  }
253  else
254  {
255  return ERROR_BAD_PATHNAME;
256  }
257  }
258  /* If it's a local device */
259  else if (TargetDevice == wcsstr(TargetDevice, L"\\Device\\Harddisk")
260  || TargetDevice == wcsstr(TargetDevice, L"\\Device\\CdRom")
261  || TargetDevice == wcsstr(TargetDevice, L"\\Device\\Floppy"))
262  {
263  /* Just query the computer name */
264  if (!GetComputerNameW(ComputerName, ComputerNameLength))
265  {
266  return GetLastError();
267  }
268 
269  return ERROR_SUCCESS;
270  }
271  /* If it's a DFS share */
272  else if (TargetDevice == wcsstr(TargetDevice, L"\\Device\\WinDfs\\"))
273  {
274  /* Obviously, query DFS */
275  Query = TRUE;
276  }
277  else
278  {
279  return ERROR_BAD_PATHNAME;
280  }
281  }
282  else
283  {
284  return ERROR_BAD_PATHNAME;
285  }
286 
287  /* Query DFS, currently not implemented - shouldn't be missing in ReactOS yet ;-) */
288  if (Query)
289  {
290  UNIMPLEMENTED_DBGBREAK("Querying DFS not implemented!\n");
291  AbsolutePath = NULL;
292  AbsolutePathLength = 0;
293  }
294 
295  /* Now, properly extract the computer name from the full path */
296  EndOfName = AbsolutePath;
297  if (AbsolutePathLength)
298  {
299  for (NameLength = 0; NameLength < AbsolutePathLength; NameLength += sizeof(WCHAR))
300  {
301  /* Look for the next \, it will be the end of computer name */
302  if (EndOfName[0] == '\\')
303  {
304  break;
305  }
306  /* Computer name cannot contain ., if we get to that point, something went wrong... */
307  else if (EndOfName[0] == '.')
308  {
309  return ERROR_BAD_PATHNAME;
310  }
311 
312  ++EndOfName;
313  }
314  }
315 
316  NameLength = EndOfName - AbsolutePath;
317  /* Check we didn't overflow and that our computer name isn't ill-formed */
318  if (NameLength >= AbsolutePathLength || NameLength >= MAX_COMPUTERNAME_LENGTH * sizeof(WCHAR))
319  {
320  return ERROR_BAD_PATHNAME;
321  }
322 
323  /* Check we can fit */
324  if (NameLength + sizeof(UNICODE_NULL) > *ComputerNameLength * sizeof(WCHAR))
325  {
326  return ERROR_BUFFER_OVERFLOW;
327  }
328 
329  /* Write, zero and done! */
330  RtlCopyMemory(ComputerName, AbsolutePath, NameLength);
331  *ComputerNameLength = NameLength / sizeof(WCHAR);
332  ComputerName[NameLength / sizeof(WCHAR)] = UNICODE_NULL;
333 
334  return ERROR_SUCCESS;
335 }
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ERROR_SUCCESS
Definition: deptool.c:10
_Must_inspect_result_ __drv_aliasesMem PDEVICE_OBJECT _In_ PDEVICE_OBJECT TargetDevice
Definition: iofuncs.h:688
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
_CONST_RETURN wchar_t *__cdecl wcsstr(_In_z_ const wchar_t *_Str, _In_z_ const wchar_t *_SubStr)
uint16_t * PWSTR
Definition: typedefs.h:54
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI GetComputerNameW(LPWSTR lpBuffer, LPDWORD lpnSize)
Definition: compname.c:440
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define UNICODE_NULL
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
DWORD WINAPI QueryDosDeviceW(LPCWSTR lpDeviceName, LPWSTR lpTargetPath, DWORD ucchMax)
Definition: dosdev.c:308
void DPRINT(...)
Definition: polytest.cpp:61
_CONST_RETURN wchar_t *__cdecl wcschr(_In_z_ const wchar_t *_Str, wchar_t _Ch)
__wchar_t WCHAR
Definition: xmlstorage.h:180
BOOL Query(LPCTSTR *ServiceArgs, DWORD ArgCount, BOOL bExtended)
Definition: query.c:292
static const WCHAR L[]
Definition: oid.c:1250
WCHAR Letter
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:240
PRTL_UNICODE_STRING_BUFFER Path
unsigned short USHORT
Definition: pedump.c:61
NTSYSAPI BOOLEAN NTAPI RtlPrefixUnicodeString(IN PUNICODE_STRING String1, IN PUNICODE_STRING String2, IN BOOLEAN CaseInSensitive)
#define UNIMPLEMENTED_DBGBREAK(...)
Definition: debug.h:57
#define ERROR_BAD_PATHNAME
Definition: winerror.h:233
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14

Referenced by BasepNotifyTrackingService().

◆ BasepMoveFileCopyProgress()

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 at line 621 of file move.c.

630 {
631  DWORD Ret = 0;
633 
634  if (Context->Flags & MOVEFILE_WRITE_THROUGH)
635  {
636  if (!dwCallbackReason)
637  {
638  if (StreamBytesTransferred.QuadPart == StreamSize.QuadPart)
639  {
640  FlushFileBuffers(hDestinationFile);
641  }
642  }
643  }
644 
645  if (Context->UserRoutine)
646  {
647  Ret = Context->UserRoutine(TotalFileSize,
648  TotalBytesTransferred,
649  StreamSize,
650  StreamBytesTransferred,
651  dwStreamNumber,
652  dwCallbackReason,
653  hSourceFile,
654  hDestinationFile,
655  Context->UserData);
656  }
657 
658  return Ret;
659 }
struct _COPY_PROGRESS_CONTEXT * PCOPY_PROGRESS_CONTEXT
#define MOVEFILE_WRITE_THROUGH
Definition: filesup.h:30
BOOL WINAPI FlushFileBuffers(IN HANDLE hFile)
Definition: fileinfo.c:175
unsigned long DWORD
Definition: ntddk_ex.h:95

Referenced by MoveFileWithProgressW().

◆ BasepMoveFileDelayed()

NTSTATUS WINAPI BasepMoveFileDelayed ( IN PUNICODE_STRING  ExistingPath,
IN PUNICODE_STRING  NewPath,
IN INT  KeyId,
IN BOOL  CreateIfNotFound 
)

Definition at line 41 of file move.c.

45 {
46 #define STRING_LENGTH 0x400
49  PVOID Buffer, BufferBegin;
51  PWSTR PendingOperations, BufferWrite;
52  ULONG DataSize, BufferLength, StringLength = STRING_LENGTH;
53  UNICODE_STRING SessionManagerString, PendingOperationsString;
54  /* +6 because a INT shouldn't take more than 6 chars. Especially given the call path */
55  WCHAR PendingOperationsBuffer[sizeof(L"PendingFileRenameOperations") / sizeof(WCHAR) + 6];
56 
57  RtlInitUnicodeString(&SessionManagerString, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Session Manager");
58 
59  /* Select appropriate key for adding our file */
60  if (KeyId == 1)
61  {
62  PendingOperations = L"PendingFileRenameOperations";
63  }
64  else
65  {
66  StringCbPrintfW(PendingOperationsBuffer, sizeof(PendingOperationsBuffer), L"PendingFileRenameOperations%d", KeyId);
67  PendingOperations = PendingOperationsBuffer;
68  }
69  RtlInitUnicodeString(&PendingOperationsString, PendingOperations);
70 
72  &SessionManagerString,
74  NULL, NULL);
75 
76  /* Open parent key */
82  {
87  }
88 
89  if (!NT_SUCCESS(Status))
90  {
91  return Status;
92  }
93 
94  /* Reserve enough to read previous string + to append our with required null chars */
95  BufferLength = NewPath->Length + ExistingPath->Length + STRING_LENGTH + 3 * sizeof(UNICODE_NULL);
96 
97  while (TRUE)
98  {
99  /* Allocate output buffer */
100  Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferLength);
101  if (Buffer == NULL)
102  {
104  return STATUS_NO_MEMORY;
105  }
106 
108  &PendingOperationsString,
110  Buffer, StringLength, &DataSize);
112  {
113  break;
114  }
115 
116  /* If buffer was too small, then, reallocate one which is big enough */
117  StringLength = DataSize;
118  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
119  BufferLength = ExistingPath->Length + StringLength + NewPath->Length + 3 * sizeof(UNICODE_NULL);
120  /* Check we didn't overflow */
121  if (BufferLength < StringLength)
122  {
125  }
126  }
127 
128  /* Check if it existed - if not, create only IF asked to */
129  if (!NT_SUCCESS(Status) && (Status != STATUS_OBJECT_NAME_NOT_FOUND || !CreateIfNotFound))
130  {
132  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
133  return Status;
134  }
135 
136  if (!NT_SUCCESS(Status))
137  {
138  /* We didn't find any - ie, we create, so use complete buffer */
139  BufferBegin = Buffer;
140  BufferWrite = Buffer;
141  }
142  else
143  {
145 
146  /* Get data, our buffer begin and then where we should append data
147  * (- null char, this is REG_MULTI_SZ, it already includes double termination, we keep only one)
148  */
149  BufferBegin = PartialInfo->Data;
150  BufferWrite = (PWSTR)((ULONG_PTR)PartialInfo->Data + PartialInfo->DataLength - sizeof(UNICODE_NULL));
151  }
152 
153  /* First copy existing */
154  RtlCopyMemory(BufferWrite, ExistingPath->Buffer, ExistingPath->Length);
155  BufferWrite += ExistingPath->Length / sizeof(WCHAR);
156  /* And append null char */
157  *BufferWrite = UNICODE_NULL;
158  ++BufferWrite;
159  /* Append destination */
160  RtlCopyMemory(BufferWrite, NewPath->Buffer, NewPath->Length);
161  BufferWrite += NewPath->Length / sizeof(WCHAR);
162  /* And append two null char (end of string) */
163  *BufferWrite = UNICODE_NULL;
164  ++BufferWrite;
165  *BufferWrite = UNICODE_NULL;
166 
167  /* Set new value */
169  &PendingOperationsString,
170  0, REG_MULTI_SZ, BufferBegin,
171  (ULONG_PTR)BufferWrite - (ULONG_PTR)BufferBegin + sizeof(WCHAR));
172 
174  RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
175 
176  return Status;
177 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define STRING_LENGTH
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
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
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
uint16_t * PWSTR
Definition: typedefs.h:54
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
#define OBJ_OPENIF
Definition: winternl.h:229
#define UNICODE_NULL
_In_ ULONG BufferLength
Definition: usbdlib.h:225
#define REG_MULTI_SZ
Definition: nt_native.h:1501
#define GENERIC_WRITE
Definition: nt_native.h:90
smooth NULL
Definition: ftsmooth.c:416
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
Definition: bufpool.h:45
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
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)
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define REG_OPTION_BACKUP_RESTORE
Definition: nt_native.h:1066
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static const WCHAR L[]
Definition: oid.c:1250
#define GENERIC_READ
Definition: compat.h:124
Status
Definition: gdiplustypes.h:24
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
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
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT _In_opt_ PVOID _In_ ULONG DataSize
Definition: ndis.h:4733

Referenced by MoveFileWithProgressW().

◆ BasepNotifyTrackingService()

NTSTATUS WINAPI BasepNotifyTrackingService ( IN OUT PHANDLE  ExistingHandle,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN HANDLE  NewHandle,
IN PUNICODE_STRING  NewPath 
)

Definition at line 343 of file move.c.

347 {
349  ULONG ComputerNameLength, FileAttributes;
350  WCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
351  OEM_STRING ComputerNameStringA;
352  CHAR ComputerNameStringBuffer[0x105];
353  UNICODE_STRING ComputerNameStringW;
355  FILE_BASIC_INFORMATION FileBasicInfo;
356  HANDLE hFullWrite;
357  struct
358  {
360  CHAR Buffer[(MAX_COMPUTERNAME_LENGTH + 1) * sizeof(WCHAR)];
361  } FileTrackingInfo;
362 
363  DPRINT("BasepNotifyTrackingService(%p, %p, %p, %wZ)\n", *ExistingHandle, ObjectAttributes, NewHandle, NewPath);
364 
366  ComputerNameLength = ARRAYSIZE(ComputerName);
367 
368  /* Attempt to get computer name of target handle */
369  if (BasepGetComputerNameFromNtPath(NewPath, NewHandle, ComputerName, &ComputerNameLength))
370  {
371  /* If we failed to get it, we will just notify with the handle */
372  FileTrackingInfo.ObjectInformationLength = 0;
373  }
374  else
375  {
376  /* Convert the retrieved computer name to ANSI and attach it to the notification */
377  ComputerNameStringA.Length = 0;
378  ComputerNameStringA.MaximumLength = ARRAYSIZE(ComputerNameStringBuffer);
379  ComputerNameStringA.Buffer = ComputerNameStringBuffer;
380 
381  RtlInitUnicodeString(&ComputerNameStringW, ComputerName);
382  Status = RtlUnicodeStringToOemString(&ComputerNameStringA, &ComputerNameStringW, 0);
383  if (!NT_SUCCESS(Status))
384  {
385  return Status;
386  }
387 
388  RtlCopyMemory(FileTrackingInfo.ObjectInformation, ComputerNameStringA.Buffer, ComputerNameStringA.Length);
389  FileTrackingInfo.ObjectInformation[ComputerNameStringA.Length] = 0;
390  FileTrackingInfo.ObjectInformationLength = ComputerNameStringA.Length + 1;
391  }
392 
393  /* Attach the handle we moved */
394  FileTrackingInfo.DestinationFile = NewHandle;
395 
396  /* Final, notify */
397  Status = NtSetInformationFile(*ExistingHandle,
398  &IoStatusBlock,
399  &FileTrackingInfo,
400  sizeof(FileTrackingInfo),
403  {
404  return Status;
405  }
406 
407  /* If we get here, we got access denied error, this comes from a
408  * read-only flag. So, close the file, in order to reopen it with enough
409  * rights to remove said flag and reattempt notification
410  */
411  CloseHandle(*ExistingHandle);
412 
413  /* Reopen it, to be able to change the destination file attributes */
414  Status = NtOpenFile(ExistingHandle,
417  &IoStatusBlock,
420  if (!NT_SUCCESS(Status))
421  {
422  *ExistingHandle = INVALID_HANDLE_VALUE;
423  return Status;
424  }
425 
426  /* Get the file attributes */
427  Status = NtQueryInformationFile(*ExistingHandle,
428  &IoStatusBlock,
429  &FileBasicInfo,
430  sizeof(FileBasicInfo),
432  if (!NT_SUCCESS(Status))
433  {
434  return Status;
435  }
436 
437  /* Get rid of the read only flag */
439  RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
440  FileBasicInfo.FileAttributes = FileAttributes;
441 
442  /* Attempt... */
443  Status = NtSetInformationFile(*ExistingHandle,
444  &IoStatusBlock,
445  &FileBasicInfo,
446  sizeof(FileBasicInfo),
448  if (!NT_SUCCESS(Status))
449  {
450  return Status;
451  }
452 
453  /* Now, reopen with maximum accesses to notify */
454  Status = NtOpenFile(&hFullWrite,
457  &IoStatusBlock,
460  if (NT_SUCCESS(Status))
461  {
462  NtClose(*ExistingHandle);
463  *ExistingHandle = hFullWrite;
464 
465  /* Full success, notify! */
466  Status = NtSetInformationFile(*ExistingHandle,
467  &IoStatusBlock,
468  &FileTrackingInfo,
469  sizeof(FileTrackingInfo),
471  }
472 
473  /* If opening with full access failed or if notify failed, restore read-only */
474  if (!NT_SUCCESS(Status))
475  {
476  FileBasicInfo.FileAttributes |= FILE_ATTRIBUTE_READONLY;
477 
478  Status = NtSetInformationFile(*ExistingHandle,
479  &IoStatusBlock,
480  &FileBasicInfo,
481  sizeof(FileBasicInfo),
483  }
484 
485  /* We're done */
486  return Status;
487 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CloseHandle
Definition: compat.h:398
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
STRING OEM_STRING
Definition: umtypes.h:203
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_SHARE_READ
Definition: compat.h:125
#define GENERIC_WRITE
Definition: nt_native.h:90
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
DWORD WINAPI BasepGetComputerNameFromNtPath(IN PUNICODE_STRING NewPath, IN HANDLE NewHandle, OUT PWSTR ComputerName, IN OUT PULONG ComputerNameLength)
Definition: move.c:185
_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:1230
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:3951
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToOemString(POEM_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
#define MAX_COMPUTERNAME_LENGTH
Definition: winbase.h:240
struct _FILE_TRACKING_INFORMATION FILE_TRACKING_INFORMATION
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
return STATUS_SUCCESS
Definition: btrfs.c:2725
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:3042

Referenced by MoveFileWithProgressW(), and PrivMoveFileIdentityW().

◆ BasepOpenFileForMove()

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 at line 495 of file move.c.

503 {
504  RTL_RELATIVE_NAME_U RelativeName;
508  ULONG IntShareAccess;
509  BOOLEAN HasRelative = FALSE;
510 
511  _SEH2_TRY
512  {
513  /* Zero output */
514  RelativeNtName->Length =
515  RelativeNtName->MaximumLength = 0;
516  RelativeNtName->Buffer = NULL;
517  *NtName = NULL;
518 
519  if (!RtlDosPathNameToRelativeNtPathName_U(File, RelativeNtName, NULL, &RelativeName))
520  {
522  _SEH2_LEAVE;
523  }
524 
525  HasRelative = TRUE;
526  *NtName = RelativeNtName->Buffer;
527 
528  if (RelativeName.RelativeName.Length)
529  {
530  RelativeNtName->Length = RelativeName.RelativeName.Length;
531  RelativeNtName->MaximumLength = RelativeName.RelativeName.MaximumLength;
532  RelativeNtName->Buffer = RelativeName.RelativeName.Buffer;
533  }
534  else
535  {
536  RelativeName.ContainingDirectory = 0;
537  }
538 
540  RelativeNtName,
542  RelativeName.ContainingDirectory,
543  NULL);
544  /* Force certain flags here, given ops we'll do */
545  IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE;
547 
548  /* We'll try to read reparse tag */
552  &IoStatusBlock,
553  IntShareAccess,
555  if (NT_SUCCESS(Status))
556  {
557  /* Attempt the read */
559  &IoStatusBlock,
560  &TagInfo,
563 
564  /* Return if failure with a status that wouldn't mean the FSD cannot support reparse points */
565  if (!NT_SUCCESS(Status) &&
567  {
568  _SEH2_LEAVE;
569  }
570 
571  if (NT_SUCCESS(Status))
572  {
573  /* This cannot happen on mount points */
574  if (TagInfo.FileAttributes & FILE_ATTRIBUTE_DEVICE ||
576  {
577  _SEH2_LEAVE;
578  }
579  }
580 
583 
584  IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_DELETE;
585  }
586  else if (Status == STATUS_INVALID_PARAMETER)
587  {
588  IntShareAccess = ShareAccess | FILE_SHARE_READ | FILE_SHARE_WRITE;
589  }
590  else
591  {
592  _SEH2_LEAVE;
593  }
594 
595  /* Reattempt to open normally, following reparse point if needed */
599  &IoStatusBlock,
600  IntShareAccess,
601  OpenOptions);
602  }
604  {
605  if (HasRelative)
606  {
607  RtlReleaseRelativeName(&RelativeName);
608  }
609  }
610  _SEH2_END;
611 
612  return Status;
613 }
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define TRUE
Definition: types.h:120
_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:5995
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
HANDLE ContainingDirectory
Definition: rtltypes.h:1375
VOID NTAPI RtlReleaseRelativeName(_In_ PRTL_RELATIVE_NAME_U RelativeName)
LONG NTSTATUS
Definition: precomp.h:26
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
_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:4157
#define FILE_SHARE_READ
Definition: compat.h:125
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToRelativeNtPathName_U(_In_ PCWSTR DosName, _Out_ PUNICODE_STRING NtName, _Out_ PCWSTR *PartName, _Out_ PRTL_RELATIVE_NAME_U RelativeName)
_SEH2_TRY
Definition: create.c:4250
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6874
HANDLE FileHandle
Definition: stats.c:38
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
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:3951
#define FILE_ATTRIBUTE_DEVICE
Definition: disk.h:27
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
_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 DesiredAccess
Definition: create.c:4157
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
_SEH2_FINALLY
Definition: create.c:4395
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
unsigned int ULONG
Definition: retypes.h:1
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
UNICODE_STRING RelativeName
Definition: rtltypes.h:1374
Definition: File.h:15
#define _SEH2_LEAVE
Definition: filesup.c:20
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46

Referenced by PrivMoveFileIdentityW().

◆ DEBUG_CHANNEL()

DEBUG_CHANNEL ( kernel32file  )

◆ MoveFileA()

BOOL WINAPI MoveFileA ( IN LPCSTR  lpExistingFileName,
IN LPCSTR  lpNewFileName 
)

Definition at line 1077 of file move.c.

1079 {
1080  return MoveFileWithProgressA(lpExistingFileName,
1081  lpNewFileName,
1082  NULL,
1083  NULL,
1085 }
BOOL WINAPI MoveFileWithProgressA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName OPTIONAL, IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, IN LPVOID lpData OPTIONAL, IN DWORD dwFlags)
Definition: move.c:1003
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
smooth NULL
Definition: ftsmooth.c:416

Referenced by DosInt21h(), mmioDosIOProc(), test_continuouscabs(), test_delete(), test_filenames(), test_FindFirstChangeNotification(), test_MoveFileA(), and VerInstallFileA().

◆ MoveFileExA()

BOOL WINAPI MoveFileExA ( IN LPCSTR  lpExistingFileName,
IN LPCSTR lpNewFileName  OPTIONAL,
IN DWORD  dwFlags 
)

Definition at line 1093 of file move.c.

1096 {
1097  return MoveFileWithProgressA(lpExistingFileName,
1098  lpNewFileName,
1099  NULL,
1100  NULL,
1101  dwFlags);
1102 }
BOOL WINAPI MoveFileWithProgressA(IN LPCSTR lpExistingFileName, IN LPCSTR lpNewFileName OPTIONAL, IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL, IN LPVOID lpData OPTIONAL, IN DWORD dwFlags)
Definition: move.c:1003
smooth NULL
Definition: ftsmooth.c:416
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175

Referenced by cleanup_eventlog(), process_pending_renames(), and rename().

◆ MoveFileExW()

BOOL WINAPI MoveFileExW ( IN LPCWSTR  lpExistingFileName,
IN LPCWSTR lpNewFileName  OPTIONAL,
IN DWORD  dwFlags 
)

Definition at line 1060 of file move.c.

1063 {
1064  return MoveFileWithProgressW(lpExistingFileName,
1065  lpNewFileName,
1066  NULL,
1067  NULL,
1068  dwFlags);
1069 }
smooth NULL
Definition: ftsmooth.c:416
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
BOOL WINAPI MoveFileWithProgressW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine, IN LPVOID lpData, IN DWORD dwFlags)
Definition: move.c:667

Referenced by _wrename(), BackgroundCopyJob_Complete(), cabinet_copy_file(), copy_install_file(), DelayedMove(), do_file_copyW(), extract_cabinet_file(), msi_move_file(), pendingRename(), and SaveDefaultUserHive().

◆ MoveFileW()

BOOL WINAPI MoveFileW ( IN LPCWSTR  lpExistingFileName,
IN LPCWSTR  lpNewFileName 
)

Definition at line 1044 of file move.c.

1046 {
1047  return MoveFileWithProgressW(lpExistingFileName,
1048  lpNewFileName,
1049  NULL,
1050  NULL,
1052 }
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI MoveFileWithProgressW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine, IN LPVOID lpData, IN DWORD dwFlags)
Definition: move.c:667

Referenced by BrsFolder_Treeview_Rename(), BtrfsRecv::cmd_rename(), CFileDefExt::GeneralPageProc(), patch_file(), RecycleBin5_RecycleBin5_DeleteFile(), CFSFolder::SetNameOf(), SetupCommitFileQueueW(), SHNotifyMoveFileW(), test_MoveFileW(), test_readdirectorychanges_cr(), and wmain().

◆ MoveFileWithProgressA()

BOOL WINAPI MoveFileWithProgressA ( IN LPCSTR  lpExistingFileName,
IN LPCSTR lpNewFileName  OPTIONAL,
IN LPPROGRESS_ROUTINE lpProgressRoutine  OPTIONAL,
IN LPVOID lpData  OPTIONAL,
IN DWORD  dwFlags 
)

Definition at line 1003 of file move.c.

1008 {
1009  BOOL Ret;
1010  UNICODE_STRING ExistingFileNameW, NewFileNameW;
1011 
1012  if (!Basep8BitStringToDynamicUnicodeString(&ExistingFileNameW, lpExistingFileName))
1013  {
1014  return FALSE;
1015  }
1016 
1017  if (lpNewFileName)
1018  {
1019  if (!Basep8BitStringToDynamicUnicodeString(&NewFileNameW, lpNewFileName))
1020  {
1021  RtlFreeUnicodeString(&ExistingFileNameW);
1022  return FALSE;
1023  }
1024  }
1025  else
1026  {
1027  NewFileNameW.Buffer = NULL;
1028  }
1029 
1030  Ret = MoveFileWithProgressW(ExistingFileNameW.Buffer, NewFileNameW.Buffer, lpProgressRoutine, lpData, dwFlags);
1031 
1032  RtlFreeUnicodeString(&ExistingFileNameW);
1033  RtlFreeUnicodeString(&NewFileNameW);
1034 
1035  return Ret;
1036 }
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:225
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
BOOL WINAPI MoveFileWithProgressW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN LPPROGRESS_ROUTINE lpProgressRoutine, IN LPVOID lpData, IN DWORD dwFlags)
Definition: move.c:667

Referenced by MoveFileA(), and MoveFileExA().

◆ MoveFileWithProgressW()

BOOL WINAPI MoveFileWithProgressW ( IN LPCWSTR  lpExistingFileName,
IN LPCWSTR  lpNewFileName,
IN LPPROGRESS_ROUTINE  lpProgressRoutine,
IN LPVOID  lpData,
IN DWORD  dwFlags 
)

Definition at line 667 of file move.c.

672 {
674  PWSTR NewBuffer;
676  COPY_PROGRESS_CONTEXT CopyContext;
678  PFILE_RENAME_INFORMATION RenameInfo;
679  UNICODE_STRING NewPathU, ExistingPathU;
680  FILE_ATTRIBUTE_TAG_INFORMATION FileAttrTagInfo;
681  HANDLE SourceHandle = INVALID_HANDLE_VALUE, NewHandle, ExistingHandle;
682  BOOL Ret = FALSE, ReplaceIfExists, DelayUntilReboot, AttemptReopenWithoutReparse;
683 
684  DPRINT("MoveFileWithProgressW(%S, %S, %p, %p, %x)\n", lpExistingFileName, lpNewFileName, lpProgressRoutine, lpData, dwFlags);
685 
686  NewPathU.Buffer = NULL;
687  ExistingPathU.Buffer = NULL;
688 
689  _SEH2_TRY
690  {
691  /* Don't allow renaming to a disk */
692  if (lpNewFileName && RtlIsDosDeviceName_U(lpNewFileName))
693  {
695  _SEH2_LEAVE;
696  }
697 
698  ReplaceIfExists = !!(dwFlags & MOVEFILE_REPLACE_EXISTING);
699 
700  /* Get file path */
701  if (!RtlDosPathNameToNtPathName_U(lpExistingFileName, &ExistingPathU, NULL, NULL))
702  {
704  _SEH2_LEAVE;
705  }
706 
707  /* Sanitize input */
708  DelayUntilReboot = !!(dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT);
709  if (DelayUntilReboot && (dwFlags & MOVEFILE_CREATE_HARDLINK))
710  {
712  _SEH2_LEAVE;
713  }
714 
715  /* Unless we manage a proper opening, we'll attempt to reopen without reparse support */
716  AttemptReopenWithoutReparse = TRUE;
718  &ExistingPathU,
720  NULL,
721  NULL);
722  /* Attempt to open source file */
726  &IoStatusBlock,
729  if (!NT_SUCCESS(Status))
730  {
731  /* If we failed and the file doesn't exist, don't attempt to reopen without reparse */
732  if (DelayUntilReboot &&
734  {
735  /* Here we don't fail completely, as we postpone the operation to reboot
736  * File might exist afterwards, and we don't need a handle here
737  */
739  AttemptReopenWithoutReparse = FALSE;
740  }
741  /* If we failed for any reason than unsupported reparse, fail completely */
742  else if (Status != STATUS_INVALID_PARAMETER)
743  {
745  _SEH2_LEAVE;
746  }
747  }
748  else
749  {
750  /* We managed to open, so query information */
752  &IoStatusBlock,
753  &FileAttrTagInfo,
756  if (!NT_SUCCESS(Status))
757  {
758  /* Do not tolerate any other error than something related to not supported operation */
760  {
762  _SEH2_LEAVE;
763  }
764 
765  /* Not a reparse point, no need to reopen, it's fine */
766  AttemptReopenWithoutReparse = FALSE;
767  }
768  /* Validate the reparse point (do we support it?) */
769  else if (FileAttrTagInfo.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT &&
770  FileAttrTagInfo.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)
771  {
774  }
775  else
776  {
777  /* Mount point, let's rename it */
778  AttemptReopenWithoutReparse = FALSE;
779  }
780  }
781 
782  /* Simply reopen if required */
783  if (AttemptReopenWithoutReparse)
784  {
788  &IoStatusBlock,
791  if (!NT_SUCCESS(Status))
792  {
794  _SEH2_LEAVE;
795  }
796  }
797 
798  /* Nullify string if we're to use it */
799  if (DelayUntilReboot && !lpNewFileName)
800  {
801  RtlInitUnicodeString(&NewPathU, 0);
802  }
803  /* Check whether path exists */
804  else if (!RtlDosPathNameToNtPathName_U(lpNewFileName, &NewPathU, 0, 0))
805  {
807  _SEH2_LEAVE;
808  }
809 
810  /* Handle postponed renaming */
811  if (DelayUntilReboot)
812  {
813  /* If new file exists and we're allowed to replace, then mark the path with ! */
814  if (ReplaceIfExists && NewPathU.Length)
815  {
816  NewBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(WCHAR));
817  if (NewBuffer == NULL)
818  {
820  _SEH2_LEAVE;
821  }
822 
823  NewBuffer[0] = L'!';
824  RtlCopyMemory(&NewBuffer[1], NewPathU.Buffer, NewPathU.Length);
825  NewPathU.Length += sizeof(WCHAR);
826  NewPathU.MaximumLength += sizeof(WCHAR);
827  RtlFreeHeap(RtlGetProcessHeap(), 0, NewPathU.Buffer);
828  NewPathU.Buffer = NewBuffer;
829  }
830 
831  /* Check whether 'copy' renaming is allowed if required */
833  {
835  }
836  else
837  {
838  /* First, probe 2nd key to see whether it exists - if so, it will be appended there */
839  Status = BasepMoveFileDelayed(&ExistingPathU, &NewPathU, 2, FALSE);
841  {
842  /* If doesn't exist, append to first key first, creating it if it doesn't exist */
843  Status = BasepMoveFileDelayed(&ExistingPathU, &NewPathU, 1, TRUE);
844 
846  {
847  /* If it failed because it's too big, then create 2nd key and put it there */
848  Status = BasepMoveFileDelayed(&ExistingPathU, &NewPathU, 2, TRUE);
849  }
850  }
851  }
852 
853  /* If we failed at some point, return the error */
854  if (!NT_SUCCESS(Status))
855  {
857  _SEH2_LEAVE;
858  }
859 
860  Ret = TRUE;
861  _SEH2_LEAVE;
862  }
863 
864  /* At that point, we MUST have a source handle */
866 
867  /* Allocate renaming buffer and fill it */
868  RenameInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(FILE_RENAME_INFORMATION));
869  if (RenameInfo == NULL)
870  {
872  _SEH2_LEAVE;
873  }
874 
875  RtlCopyMemory(&RenameInfo->FileName, NewPathU.Buffer, NewPathU.Length);
876  RenameInfo->ReplaceIfExists = ReplaceIfExists;
877  RenameInfo->RootDirectory = 0;
878  RenameInfo->FileNameLength = NewPathU.Length;
879 
880  /* Attempt to rename the file */
882  &IoStatusBlock,
883  RenameInfo,
884  NewPathU.Length + sizeof(FILE_RENAME_INFORMATION),
886  RtlFreeHeap(RtlGetProcessHeap(), 0, RenameInfo);
887  if (NT_SUCCESS(Status))
888  {
889  /* If it succeed, all fine, quit */
890  Ret = TRUE;
891  _SEH2_LEAVE;
892  }
893  /* If we failed for any other reason than not the same device, fail
894  * If we failed because of different devices, only allow renaming if user allowed copy
895  */
897  {
898  /* ReactOS hack! To be removed once all FSD have proper renaming support
899  * Just leave status to error and leave
900  */
902  {
903  DPRINT1("Forcing copy, renaming not supported by FSD\n");
904  }
905  else
906  {
908  _SEH2_LEAVE;
909  }
910  }
911 
912  /* Close source file */
915 
916  /* Issue the copy of the file */
917  CopyContext.Flags = dwFlags;
918  CopyContext.UserRoutine = lpProgressRoutine;
919  CopyContext.UserData = lpData;
920  NewHandle = INVALID_HANDLE_VALUE;
921  ExistingHandle = INVALID_HANDLE_VALUE;
922 
923  Ret = BasepCopyFileExW(lpExistingFileName,
924  lpNewFileName,
926  &CopyContext,
927  NULL,
928  (ReplaceIfExists == 0) | COPY_FILE_OPEN_SOURCE_FOR_WRITE,
929  0,
930  &ExistingHandle,
931  &NewHandle);
932  if (!Ret)
933  {
934  /* If it failed, don't leak any handle */
935  if (ExistingHandle != INVALID_HANDLE_VALUE)
936  {
937  CloseHandle(ExistingHandle);
938  ExistingHandle = INVALID_HANDLE_VALUE;
939  }
940  }
941  else if (ExistingHandle != INVALID_HANDLE_VALUE)
942  {
943  if (NewHandle != INVALID_HANDLE_VALUE)
944  {
945  /* If copying succeed, notify */
946  Status = BasepNotifyTrackingService(&ExistingHandle, &ObjectAttributes, NewHandle, &NewPathU);
947  if (!NT_SUCCESS(Status))
948  {
949  /* Fail in case it had to succeed */
951  {
952  if (NewHandle != INVALID_HANDLE_VALUE)
953  CloseHandle(NewHandle);
954  NewHandle = INVALID_HANDLE_VALUE;
955  DeleteFileW(lpNewFileName);
956  Ret = FALSE;
958  }
959  }
960  }
961 
962  CloseHandle(ExistingHandle);
963  ExistingHandle = INVALID_HANDLE_VALUE;
964  }
965 
966  /* In case copy worked, close file */
967  if (NewHandle != INVALID_HANDLE_VALUE)
968  {
969  CloseHandle(NewHandle);
970  NewHandle = INVALID_HANDLE_VALUE;
971  }
972 
973  /* If it succeed, delete source file */
974  if (Ret)
975  {
976  if (!DeleteFileW(lpExistingFileName))
977  {
978  /* Reset file attributes if required */
979  SetFileAttributesW(lpExistingFileName, FILE_ATTRIBUTE_NORMAL);
980  DeleteFileW(lpExistingFileName);
981  }
982  }
983  }
985  {
988 
989  RtlFreeHeap(RtlGetProcessHeap(), 0, ExistingPathU.Buffer);
990  RtlFreeHeap(RtlGetProcessHeap(), 0, NewPathU.Buffer);
991  }
992  _SEH2_END;
993 
994  return Ret;
995 }
BOOL WINAPI SetFileAttributesW(LPCWSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:944
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
LPPROGRESS_ROUTINE UserRoutine
Definition: move.c:31
#define MOVEFILE_CREATE_HARDLINK
Definition: winbase.h:383
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define CloseHandle
Definition: compat.h:398
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:434
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:54
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
#define FILE_SHARE_READ
Definition: compat.h:125
_SEH2_TRY
Definition: create.c:4250
#define IO_REPARSE_TAG_MOUNT_POINT
Definition: iotypes.h:6874
#define STATUS_SHARING_VIOLATION
Definition: udferr_usr.h:154
#define MOVEFILE_WRITE_THROUGH
Definition: filesup.h:30
unsigned int BOOL
Definition: ntddk_ex.h:94
NTSTATUS WINAPI BasepNotifyTrackingService(IN OUT PHANDLE ExistingHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE NewHandle, IN PUNICODE_STRING NewPath)
Definition: move.c:343
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
#define COPY_FILE_OPEN_SOURCE_FOR_WRITE
Definition: winbase.h:207
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
smooth NULL
Definition: ftsmooth.c:416
#define MOVEFILE_DELAY_UNTIL_REBOOT
Definition: winbase.h:381
void DPRINT(...)
Definition: polytest.cpp:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
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:3951
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
static const WCHAR L[]
Definition: oid.c:1250
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
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
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
NTSTATUS WINAPI BasepMoveFileDelayed(IN PUNICODE_STRING ExistingPath, IN PUNICODE_STRING NewPath, IN INT KeyId, IN BOOL CreateIfNotFound)
Definition: move.c:41
_SEH2_END
Definition: create.c:4424
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
_SEH2_FINALLY
Definition: create.c:4395
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define DPRINT1
Definition: precomp.h:8
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:621
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define _SEH2_LEAVE
Definition: filesup.c:20
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
#define MOVEFILE_FAIL_IF_NOT_TRACKABLE
Definition: winbase.h:384
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:3042
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)
#define DELETE
Definition: nt_native.h:57
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)

Referenced by MoveFileExW(), MoveFileW(), MoveFileWithProgressA(), and SHNotifyMoveFileW().

◆ PrivMoveFileIdentityW()

BOOL WINAPI PrivMoveFileIdentityW ( IN LPCWSTR  lpSource,
IN LPCWSTR  lpDestination,
IN DWORD  dwFlags 
)

Definition at line 1321 of file move.c.

1322 {
1323  ACCESS_MASK SourceAccess;
1324  UNICODE_STRING NtSource, NtDestination;
1325  LPWSTR RelativeSource, RelativeDestination;
1326  HANDLE SourceHandle, DestinationHandle;
1327  OBJECT_ATTRIBUTES ObjectAttributesSource, ObjectAttributesDestination;
1328  NTSTATUS Status, OldStatus = STATUS_SUCCESS;
1329  ACCESS_MASK DestAccess;
1331  FILE_BASIC_INFORMATION SourceInformation, DestinationInformation;
1332  FILE_DISPOSITION_INFORMATION FileDispositionInfo;
1333 
1334  DPRINT("PrivMoveFileIdentityW(%S, %S, %x)\n", lpSource, lpDestination, dwFlags);
1335 
1337  NtSource.Length =
1338  NtSource.MaximumLength = 0;
1339  NtSource.Buffer = NULL;
1340  RelativeSource = NULL;
1341  DestinationHandle = INVALID_HANDLE_VALUE;
1342  NtDestination.Length =
1343  NtDestination.MaximumLength = 0;
1344  NtDestination.Buffer = NULL;
1345  RelativeDestination = NULL;
1346 
1347  /* FILE_WRITE_DATA is required for later on notification */
1348  SourceAccess = FILE_READ_ATTRIBUTES | FILE_WRITE_DATA;
1350  {
1351  SourceAccess |= DELETE;
1352  }
1353 
1354  _SEH2_TRY
1355  {
1356  /* We will loop twice:
1357  * First we attempt to open with FILE_WRITE_DATA for notification
1358  * If it fails and we have flag for non-trackable files, we retry
1359  * without FILE_WRITE_DATA.
1360  * If that one fails, then, we quit for real
1361  */
1362  while (TRUE)
1363  {
1364  Status = BasepOpenFileForMove(lpSource,
1365  &NtSource,
1366  &RelativeSource,
1367  &SourceHandle,
1368  &ObjectAttributesSource,
1369  SourceAccess,
1372  if (NT_SUCCESS(Status))
1373  {
1374  break;
1375  }
1376 
1377  /* If we already attempted the opening without FILE_WRITE_DATA
1378  * or if we cannot move on non-trackable files, fail.
1379  */
1380  if (!(SourceAccess & FILE_WRITE_DATA) || !(dwFlags & PRIV_ALLOW_NON_TRACKABLE))
1381  {
1382  _SEH2_LEAVE;
1383  }
1384 
1385  if (RelativeSource)
1386  {
1387  RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSource);
1388  RelativeSource = NULL;
1389  }
1390 
1392  {
1395  }
1396 
1397  SourceAccess &= ~FILE_WRITE_DATA;
1398 
1399  /* Remember fist failure in the path */
1400  if (NT_SUCCESS(OldStatus))
1401  {
1402  OldStatus = Status;
1403  }
1404  }
1405 
1406  DestAccess = FILE_WRITE_ATTRIBUTES;
1407  /* If we could preserve FILE_WRITE_DATA for source, attempt to get it for destination
1408  * Still for notification purposes
1409  */
1410  if (SourceAccess & FILE_WRITE_DATA)
1411  {
1412  DestAccess |= FILE_WRITE_DATA;
1413  }
1414 
1415  /* cf comment for first loop */
1416  while (TRUE)
1417  {
1418  Status = BasepOpenFileForMove(lpDestination,
1419  &NtDestination,
1420  &RelativeDestination,
1421  &DestinationHandle,
1422  &ObjectAttributesDestination,
1423  DestAccess,
1426  if (NT_SUCCESS(Status))
1427  {
1428  break;
1429  }
1430 
1431  /* If we already attempted the opening without FILE_WRITE_DATA
1432  * or if we cannot move on non-trackable files, fail.
1433  */
1434  if (!(DestAccess & FILE_WRITE_DATA) || !(dwFlags & PRIV_ALLOW_NON_TRACKABLE))
1435  {
1436  _SEH2_LEAVE;
1437  }
1438 
1439  if (RelativeDestination)
1440  {
1441  RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeDestination);
1442  RelativeDestination = NULL;
1443  }
1444 
1445  if (DestinationHandle != INVALID_HANDLE_VALUE)
1446  {
1447  NtClose(DestinationHandle);
1448  DestinationHandle = INVALID_HANDLE_VALUE;
1449  }
1450 
1451  DestAccess &= ~FILE_WRITE_DATA;
1452 
1453  /* Remember fist failure in the path */
1454  if (NT_SUCCESS(OldStatus))
1455  {
1456  OldStatus = Status;
1457  }
1458  }
1459 
1460  /* Get the creation time from source */
1462  &IoStatusBlock,
1463  &SourceInformation,
1464  sizeof(SourceInformation),
1466  if (NT_SUCCESS(Status))
1467  {
1468  /* Then, prepare to set it for destination */
1469  RtlZeroMemory(&DestinationInformation, sizeof(DestinationInformation));
1470  DestinationInformation.CreationTime.QuadPart = SourceInformation.CreationTime.QuadPart;
1471 
1472  /* And set it, that's all folks! */
1473  Status = NtSetInformationFile(DestinationHandle,
1474  &IoStatusBlock,
1475  &DestinationInformation,
1476  sizeof(DestinationInformation),
1478  }
1479 
1480  if (!NT_SUCCESS(Status))
1481  {
1483  {
1484  _SEH2_LEAVE;
1485  }
1486 
1487  /* Remember the failure for later notification */
1488  if (NT_SUCCESS(OldStatus))
1489  {
1490  OldStatus = Status;
1491  }
1492  }
1493 
1494  /* If we could open with FILE_WRITE_DATA both source and destination,
1495  * then, notify
1496  */
1497  if (DestAccess & FILE_WRITE_DATA && SourceAccess & FILE_WRITE_DATA)
1498  {
1500  &ObjectAttributesSource,
1501  DestinationHandle,
1502  &NtDestination);
1503  if (!NT_SUCCESS(Status))
1504  {
1506  {
1507  if (NT_SUCCESS(OldStatus))
1508  OldStatus = Status;
1509 
1510  /* Reset status, we allow non trackable files */
1512  }
1513  }
1514  }
1515  }
1517  {
1518  if (RelativeSource)
1519  RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeSource);
1520 
1521  if (RelativeDestination)
1522  RtlFreeHeap(RtlGetProcessHeap(), 0, RelativeDestination);
1523  }
1524  _SEH2_END;
1525 
1526  /* If caller asked for source deletion, if everything succeed, proceed */
1528  {
1529  FileDispositionInfo.DeleteFile = TRUE;
1530 
1532  &IoStatusBlock,
1533  &FileDispositionInfo,
1534  sizeof(FileDispositionInfo),
1536  }
1537 
1538  /* Cleanup/close portion */
1539  if (DestinationHandle != INVALID_HANDLE_VALUE)
1540  {
1541  NtClose(DestinationHandle);
1542  }
1543 
1545  {
1547  }
1548 
1549  /* Set last error if any, and quit */
1550  if (NT_SUCCESS(Status))
1551  {
1552  if (!NT_SUCCESS(OldStatus))
1553  {
1554  BaseSetLastNTError(OldStatus);
1555  }
1556  }
1557  else
1558  {
1560  }
1561 
1562  return NT_SUCCESS(Status);
1563 }
#define TRUE
Definition: types.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define FILE_OPEN_NO_RECALL
Definition: from_kernel.h:47
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_SHARE_READ
Definition: compat.h:125
_SEH2_TRY
Definition: create.c:4250
#define PRIV_ALLOW_NON_TRACKABLE
Definition: kernel32.h:134
NTSTATUS WINAPI BasepNotifyTrackingService(IN OUT PHANDLE ExistingHandle, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE NewHandle, IN PUNICODE_STRING NewPath)
Definition: move.c:343
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:166
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
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:495
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define PRIV_DELETE_ON_SUCCESS
Definition: kernel32.h:133
LARGE_INTEGER CreationTime
Definition: nt_native.h:939
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1175
NTSTATUS NTAPI NtQueryInformationFile(HANDLE hFile, PIO_STATUS_BLOCK io, PVOID ptr, ULONG len, FILE_INFORMATION_CLASS FileInformationClass)
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4424
_SEH2_FINALLY
Definition: create.c:4395
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define _SEH2_LEAVE
Definition: filesup.c:20
WCHAR * LPWSTR
Definition: xmlstorage.h:184
return STATUS_SUCCESS
Definition: btrfs.c:2725
ULONG ACCESS_MASK
Definition: nt_native.h:40
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:3042
#define DELETE
Definition: nt_native.h:57
LONGLONG QuadPart
Definition: typedefs.h:112

◆ ReplaceFileA()

BOOL WINAPI ReplaceFileA ( IN LPCSTR  lpReplacedFileName,
IN LPCSTR  lpReplacementFileName,
IN LPCSTR lpBackupFileName  OPTIONAL,
IN DWORD  dwReplaceFlags,
IN LPVOID  lpExclude,
IN LPVOID  lpReserved 
)

Definition at line 1109 of file move.c.

1115 {
1116  BOOL Ret;
1117  UNICODE_STRING ReplacedFileNameW, ReplacementFileNameW, BackupFileNameW;
1118 
1119  if (!lpReplacedFileName || !lpReplacementFileName || lpExclude || lpReserved || dwReplaceFlags & ~(REPLACEFILE_WRITE_THROUGH | REPLACEFILE_IGNORE_MERGE_ERRORS))
1120  {
1122  return FALSE;
1123  }
1124 
1125  if (!Basep8BitStringToDynamicUnicodeString(&ReplacedFileNameW, lpReplacedFileName))
1126  {
1127  return FALSE;
1128  }
1129 
1130  if (!Basep8BitStringToDynamicUnicodeString(&ReplacementFileNameW, lpReplacementFileName))
1131  {
1132  RtlFreeUnicodeString(&ReplacedFileNameW);
1133  return FALSE;
1134  }
1135 
1136  if (lpBackupFileName)
1137  {
1138  if (!Basep8BitStringToDynamicUnicodeString(&BackupFileNameW, lpBackupFileName))
1139  {
1140  RtlFreeUnicodeString(&ReplacementFileNameW);
1141  RtlFreeUnicodeString(&ReplacedFileNameW);
1142  return FALSE;
1143  }
1144  }
1145  else
1146  {
1147  BackupFileNameW.Buffer = NULL;
1148  }
1149 
1150  Ret = ReplaceFileW(ReplacedFileNameW.Buffer, ReplacementFileNameW.Buffer, BackupFileNameW.Buffer, dwReplaceFlags, 0, 0);
1151 
1152  if (lpBackupFileName)
1153  {
1154  RtlFreeUnicodeString(&BackupFileNameW);
1155  }
1156  RtlFreeUnicodeString(&ReplacementFileNameW);
1157  RtlFreeUnicodeString(&ReplacedFileNameW);
1158 
1159  return Ret;
1160 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:225
unsigned int BOOL
Definition: ntddk_ex.h:94
BOOL WINAPI ReplaceFileW(LPCWSTR lpReplacedFileName, LPCWSTR lpReplacementFileName, LPCWSTR lpBackupFileName, DWORD dwReplaceFlags, LPVOID lpExclude, LPVOID lpReserved)
Definition: move.c:1167
smooth NULL
Definition: ftsmooth.c:416
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define SetLastError(x)
Definition: compat.h:409

◆ ReplaceFileW()

BOOL WINAPI ReplaceFileW ( LPCWSTR  lpReplacedFileName,
LPCWSTR  lpReplacementFileName,
LPCWSTR  lpBackupFileName,
DWORD  dwReplaceFlags,
LPVOID  lpExclude,
LPVOID  lpReserved 
)

Definition at line 1167 of file move.c.

1175 {
1176  HANDLE hReplaced = NULL, hReplacement = NULL;
1177  UNICODE_STRING NtReplacedName = { 0, 0, NULL };
1178  UNICODE_STRING NtReplacementName = { 0, 0, NULL };
1180  NTSTATUS Status;
1181  BOOL Ret = FALSE;
1184  PVOID Buffer = NULL ;
1185 
1186  if (dwReplaceFlags)
1187  FIXME("Ignoring flags %x\n", dwReplaceFlags);
1188 
1189  /* First two arguments are mandatory */
1190  if (!lpReplacedFileName || !lpReplacementFileName)
1191  {
1193  return FALSE;
1194  }
1195 
1196  /* Back it up */
1197  if(lpBackupFileName)
1198  {
1199  if(!CopyFileW(lpReplacedFileName, lpBackupFileName, FALSE))
1200  {
1201  Error = GetLastError();
1202  goto Cleanup ;
1203  }
1204  }
1205 
1206  /* Open the "replaced" file for reading and writing */
1207  if (!(RtlDosPathNameToNtPathName_U(lpReplacedFileName, &NtReplacedName, NULL, NULL)))
1208  {
1210  goto Cleanup;
1211  }
1212 
1214  &NtReplacedName,
1216  NULL,
1217  NULL);
1218 
1219  Status = NtOpenFile(&hReplaced,
1222  &IoStatusBlock,
1225 
1226  if (!NT_SUCCESS(Status))
1227  {
1230  else
1232  goto Cleanup;
1233  }
1234 
1235  /* Blank it */
1236  SetEndOfFile(hReplaced) ;
1237 
1238  /*
1239  * Open the replacement file for reading, writing, and deleting
1240  * (deleting is needed when finished)
1241  */
1242  if (!(RtlDosPathNameToNtPathName_U(lpReplacementFileName, &NtReplacementName, NULL, NULL)))
1243  {
1245  goto Cleanup;
1246  }
1247 
1249  &NtReplacementName,
1251  NULL,
1252  NULL);
1253 
1254  Status = NtOpenFile(&hReplacement,
1257  &IoStatusBlock,
1258  0,
1260 
1261  if (!NT_SUCCESS(Status))
1262  {
1264  goto Cleanup;
1265  }
1266 
1267  Buffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 0x10000) ;
1268  if (!Buffer)
1269  {
1271  goto Cleanup ;
1272  }
1273  while (Status != STATUS_END_OF_FILE)
1274  {
1275  Status = NtReadFile(hReplacement, NULL, NULL, NULL, &IoStatusBlock, Buffer, 0x10000, NULL, NULL) ;
1276  if (NT_SUCCESS(Status))
1277  {
1278  Status = NtWriteFile(hReplaced, NULL, NULL, NULL, &IoStatusBlock, Buffer,
1280  if (!NT_SUCCESS(Status))
1281  {
1283  goto Cleanup;
1284  }
1285  }
1286  else if (Status != STATUS_END_OF_FILE)
1287  {
1289  goto Cleanup;
1290  }
1291  }
1292 
1293  Ret = TRUE;
1294 
1295  /* Perform resource cleanup */
1296 Cleanup:
1297  if (hReplaced) NtClose(hReplaced);
1298  if (hReplacement) NtClose(hReplacement);
1299  if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
1300 
1301  if (NtReplacementName.Buffer)
1302  RtlFreeHeap(GetProcessHeap(), 0, NtReplacementName.Buffer);
1303  if (NtReplacedName.Buffer)
1304  RtlFreeHeap(GetProcessHeap(), 0, NtReplacedName.Buffer);
1305 
1306  /* If there was an error, set the error code */
1307  if(!Ret)
1308  {
1309  TRACE("ReplaceFileW failed (error=%lu)\n", Error);
1311  }
1312  return Ret;
1313 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:91
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI SetEndOfFile(HANDLE hFile)
Definition: fileinfo.c:1154
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_READ
Definition: compat.h:125
#define STATUS_END_OF_FILE
Definition: shellext.h:62
unsigned int BOOL
Definition: ntddk_ex.h:94
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FIXME(fmt,...)
Definition: debug.h:110
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
#define FILE_DELETE_ON_CLOSE
Definition: constants.h:494
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:3951
#define TRACE(s)
Definition: solgame.cpp:4
#define GetProcessHeap()
Definition: compat.h:395
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define ERROR_UNABLE_TO_REMOVE_REPLACED
Definition: winerror.h:696
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WRITE_DAC
Definition: nt_native.h:59
BOOL Error
Definition: chkdsk.c:66
#define SetLastError(x)
Definition: compat.h:409
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
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_NON_DIRECTORY_FILE
Definition: constants.h:492
#define GENERIC_READ
Definition: compat.h:124
static const WCHAR Cleanup[]
Definition: register.c:80
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
NTSYSAPI ULONG WINAPI RtlNtStatusToDosError(NTSTATUS)
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:106
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)
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 DELETE
Definition: nt_native.h:57

Referenced by ReplaceFileA().