Skip to content

Commit

Permalink
Switches to using NtAllocateVirtualMemory.
Browse files Browse the repository at this point in the history
  • Loading branch information
abaire committed Sep 13, 2021
1 parent 12f8054 commit 7091a3d
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 93 deletions.
114 changes: 40 additions & 74 deletions lib/winapi/filemanip.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include <fileapi.h>
#include <winbase.h>
#include <winerror.h>
#include <winioctl.h>
#include <assert.h>
#include <ctype.h>
#include <stdbool.h>
Expand Down Expand Up @@ -242,50 +241,8 @@ BOOL MoveFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName)
}
}

// Determines if the two given handles refer to the same underlying file.
static BOOL TestSameFile(HANDLE hFirst, HANDLE hSecond) {
NTSTATUS status;
IO_STATUS_BLOCK ioStatusBlock;
FILE_OBJECTID_BUFFER firstObjectId, secondObjectId;

status = NtFsControlFile(
hFirst,
NULL,
NULL,
NULL,
&ioStatusBlock,
FSCTL_GET_OBJECT_ID,
NULL,
0,
&firstObjectId,
sizeof(firstObjectId));
if (!NT_SUCCESS(status)) {
SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}

status = NtFsControlFile(
hSecond,
NULL,
NULL,
NULL,
&ioStatusBlock,
FSCTL_GET_OBJECT_ID,
NULL,
0,
&secondObjectId,
sizeof(secondObjectId));
if (!NT_SUCCESS(status)) {
SetLastError(RtlNtStatusToDosError(status));
return FALSE;
}

return !memcmp(&firstObjectId.ObjectId, &secondObjectId.ObjectId, sizeof(firstObjectId.ObjectId));
}

BOOL CopyFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfExists)
{
static const DWORD readBufferSize = 0x10000;
NTSTATUS status;
HANDLE sourceHandle;
HANDLE targetHandle = INVALID_HANDLE_VALUE;
Expand All @@ -294,7 +251,8 @@ BOOL CopyFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfE
OBJECT_ATTRIBUTES objectAttributes;
IO_STATUS_BLOCK ioStatusBlock;
FILE_NETWORK_OPEN_INFORMATION networkOpenInformation;
LPVOID readBuffer;
LPVOID readBuffer = NULL;
SIZE_T readBufferRegionSize = 0x1000;
DWORD bytesRead;

RtlInitAnsiString(&sourcePath, lpExistingFileName);
Expand All @@ -312,21 +270,12 @@ BOOL CopyFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfE
return FALSE;
}

// Fail overwriting the file if the target == the source. This is
// intentionally done after the check for existence of the source
// to set the most appropriate LastError value.
if (!strcmp(lpExistingFileName, lpNewFileName)) {
NtClose(sourceHandle);
SetLastError(ERROR_SHARING_VIOLATION);
return FALSE;
}

status = NtQueryInformationFile(
sourceHandle,
&ioStatusBlock,
&networkOpenInformation,
sizeof(networkOpenInformation),
FileNetworkOpenInformation);
sourceHandle,
&ioStatusBlock,
&networkOpenInformation,
sizeof(networkOpenInformation),
FileNetworkOpenInformation);
if (!NT_SUCCESS(status)) {
DWORD lastError = RtlNtStatusToDosError(status);
SetLastError(lastError);
Expand All @@ -336,35 +285,52 @@ BOOL CopyFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfE
RtlInitAnsiString(&targetPath, lpNewFileName);
InitializeObjectAttributes(&objectAttributes, &targetPath, OBJ_CASE_INSENSITIVE, ObDosDevicesDirectory(), NULL);

// Fail overwriting the file if the target == the source. This is
// intentionally done after the check for existence of the source
// to set the most appropriate LastError value.
//
// NOTE: FATX does not have ".." entries in directory tables, so it is not
// possible to overlap a file via "subdir/../file".
if (!strcmp(lpExistingFileName, lpNewFileName)) {
NtClose(sourceHandle);
SetLastError(ERROR_SHARING_VIOLATION);
return FALSE;
}

status = NtCreateFile(
&targetHandle, // FileHandle
FILE_GENERIC_WRITE, // DesiredAccess
&objectAttributes, // ObjectAttributes
&ioStatusBlock, // IoStatusBlock
&networkOpenInformation.AllocationSize, // AllocationSize
networkOpenInformation.FileAttributes, // FileAttributes
FILE_SHARE_READ | FILE_SHARE_WRITE, // ShareAccess
bFailIfExists ? FILE_CREATE : FILE_SUPERSEDE, // CreateDisposition
FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT); // CreateOptions
&targetHandle,
FILE_GENERIC_WRITE,
&objectAttributes,
&ioStatusBlock,
&networkOpenInformation.AllocationSize,
networkOpenInformation.FileAttributes,
FILE_SHARE_READ | FILE_SHARE_WRITE,
bFailIfExists ? FILE_CREATE : FILE_SUPERSEDE,
FILE_SYNCHRONOUS_IO_NONALERT | FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS(status)) {
NtClose(sourceHandle);
DWORD lastError = RtlNtStatusToDosError(status);
SetLastError(lastError);
return FALSE;
}

readBuffer = MmAllocateContiguousMemory(readBufferSize);
if (!readBuffer) {
status = NtAllocateVirtualMemory(&readBuffer,
0,
&readBufferRegionSize,
MEM_RESERVE | MEM_COMMIT,
PAGE_READWRITE);
if (!NT_SUCCESS(status)) {
NtClose(sourceHandle);
NtClose(targetHandle);
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
DWORD lastError = RtlNtStatusToDosError(status);
SetLastError(lastError);
return FALSE;
}

while (TRUE) {
const BYTE *bufferPos = readBuffer;
if (!ReadFile(sourceHandle, readBuffer, readBufferSize, &bytesRead, NULL)) {
MmFreeContiguousMemory(readBuffer);
if (!ReadFile(sourceHandle, readBuffer, readBufferRegionSize, &bytesRead, NULL)) {
NtFreeVirtualMemory(&readBuffer, &readBufferRegionSize, MEM_RELEASE);
NtClose(sourceHandle);
NtClose(targetHandle);
return FALSE;
Expand All @@ -377,7 +343,7 @@ BOOL CopyFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfE
while (bytesRead > 0) {
DWORD bytesWritten = 0;
if (!WriteFile(targetHandle, bufferPos, bytesRead, &bytesWritten, NULL)) {
MmFreeContiguousMemory(readBuffer);
NtFreeVirtualMemory(&readBuffer, &readBufferRegionSize, MEM_RELEASE);
NtClose(sourceHandle);
NtClose(targetHandle);
return FALSE;
Expand All @@ -387,7 +353,7 @@ BOOL CopyFileA (LPCTSTR lpExistingFileName, LPCTSTR lpNewFileName, BOOL bFailIfE
}
}

MmFreeContiguousMemory(readBuffer);
NtFreeVirtualMemory(&readBuffer, &readBufferRegionSize, MEM_RELEASE);

status = NtClose(sourceHandle);
if (!NT_SUCCESS(status)) {
Expand Down
18 changes: 0 additions & 18 deletions lib/winapi/winioctl.h

This file was deleted.

1 change: 0 additions & 1 deletion lib/xboxkrnl/xboxkrnl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2861,7 +2861,6 @@ XBAPI NTSTATUS NTAPI NtOpenDirectoryObject

#define FILE_DEVICE_FILE_SYSTEM 0x00000009
#define FSCTL_DISMOUNT_VOLUME CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 8, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_GET_OBJECT_ID CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 39, METHOD_BUFFERED, FILE_ANY_ACCESS)

XBAPI NTSTATUS NTAPI NtFsControlFile
(
Expand Down

0 comments on commit 7091a3d

Please sign in to comment.