mirror of
https://github.com/rbmm/SC
synced 2026-06-08 17:03:41 +00:00
117 lines
3.0 KiB
C++
117 lines
3.0 KiB
C++
#include "stdafx.h"
|
|
#include "file.h"
|
|
|
|
NTSTATUS ReadFromFile(_In_ PCWSTR lpFileName,
|
|
_Out_ PBYTE* ppb,
|
|
_Out_ ULONG* pcb,
|
|
_In_opt_ ULONG cbBefore /*= 0 */,
|
|
_In_opt_ ULONG cbAfter /* = 0 */)
|
|
{
|
|
UNICODE_STRING ObjectName;
|
|
NTSTATUS status = RtlDosPathNameToNtPathName_U_WithStatus(lpFileName, &ObjectName, 0, 0);
|
|
|
|
DbgPrint("DosPathNameToNt(\"%ws\") = %x\r\n", lpFileName, status);
|
|
|
|
if (0 <= status)
|
|
{
|
|
HANDLE hFile;
|
|
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
|
|
IO_STATUS_BLOCK iosb;
|
|
status = NtOpenFile(&hFile, FILE_GENERIC_READ, &oa, &iosb, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_NONALERT);
|
|
|
|
DbgPrint("NtOpenFile(\"%wZ\") = %x\r\n", &ObjectName, status);
|
|
|
|
RtlFreeUnicodeString(&ObjectName);
|
|
|
|
if (0 <= status)
|
|
{
|
|
FILE_STANDARD_INFORMATION fsi;
|
|
if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation)))
|
|
{
|
|
DbgPrint("FileSize=%I64u\r\n", fsi.EndOfFile.QuadPart);
|
|
|
|
if (fsi.EndOfFile.QuadPart < 0x1000000)
|
|
{
|
|
if (PBYTE pb = new BYTE[cbBefore + fsi.EndOfFile.LowPart + cbAfter])
|
|
{
|
|
if (0 > (status = NtReadFile(hFile, 0, 0, 0, &iosb, pb + cbBefore, fsi.EndOfFile.LowPart, 0, 0)))
|
|
{
|
|
delete[] pb;
|
|
}
|
|
else
|
|
{
|
|
*ppb = pb;
|
|
*pcb = (ULONG)iosb.Information;
|
|
}
|
|
|
|
DbgPrint("NtReadFile=%x\r\n", status);
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_NO_MEMORY;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = STATUS_FILE_TOO_LARGE;
|
|
}
|
|
}
|
|
|
|
NtClose(hFile);
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS SaveToFile(
|
|
_In_ PCWSTR lpFileName,
|
|
_In_ const void* lpBuffer,
|
|
_In_ ULONG nNumberOfBytesToWrite,
|
|
_In_ BOOL MustBeEmpty /*= FALSE*/)
|
|
{
|
|
UNICODE_STRING ObjectName;
|
|
NTSTATUS status = RtlDosPathNameToNtPathName_U_WithStatus(lpFileName, &ObjectName, 0, 0);
|
|
|
|
DbgPrint("DosPathNameToNt(\"%ws\") = %x [%x]\r\n", lpFileName, status, MustBeEmpty);
|
|
|
|
if (0 <= status)
|
|
{
|
|
HANDLE hFile;
|
|
IO_STATUS_BLOCK iosb;
|
|
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
|
|
|
|
LARGE_INTEGER AllocationSize = { nNumberOfBytesToWrite };
|
|
|
|
if (MustBeEmpty)
|
|
{
|
|
if (0 <= (status = NtOpenFile(&hFile, FILE_READ_ATTRIBUTES, &oa, &iosb, FILE_SHARE_READ, 0)))
|
|
{
|
|
FILE_STANDARD_INFORMATION fsi;
|
|
if (0 <= (status = NtQueryInformationFile(hFile, &iosb, &fsi, sizeof(fsi), FileStandardInformation)))
|
|
{
|
|
MustBeEmpty = fsi.EndOfFile.QuadPart != 0;
|
|
}
|
|
|
|
NtClose(hFile);
|
|
}
|
|
}
|
|
|
|
status = NtCreateFile(&hFile, FILE_APPEND_DATA | SYNCHRONIZE, &oa, &iosb, &AllocationSize,
|
|
0, 0, FILE_OVERWRITE_IF, FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE, 0, 0);
|
|
|
|
DbgPrint("CreateFile(\"%wZ\") = %x [%x]\r\n", &ObjectName, status, MustBeEmpty);
|
|
|
|
RtlFreeUnicodeString(&ObjectName);
|
|
|
|
if (0 <= status)
|
|
{
|
|
status = MustBeEmpty ? STATUS_DIRECTORY_NOT_EMPTY :
|
|
NtWriteFile(hFile, 0, 0, 0, &iosb, const_cast<void*>(lpBuffer), nNumberOfBytesToWrite, 0, 0);
|
|
NtClose(hFile);
|
|
DbgPrint("WriteFile(%x) = %x\r\n", nNumberOfBytesToWrite, status);
|
|
}
|
|
}
|
|
|
|
return status;
|
|
} |