Skip to content

Commit

Permalink
Add files via upload
Browse files Browse the repository at this point in the history
  • Loading branch information
834772509 committed Jan 24, 2024
1 parent 4f7a40e commit 4c99b3b
Show file tree
Hide file tree
Showing 68 changed files with 38,776 additions and 0 deletions.
52 changes: 52 additions & 0 deletions copy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include <stdio.h>
#include <fatio.h>
#include <wchar.h>

#include "fatfs/ff.h"

bool
fatio_copy(const wchar_t* in_name, const wchar_t* out_name)
{
bool rc = FALSE;
FRESULT res;
UINT br, bw;
UINT64 ofs = 0;
FIL out;
FILE* file = 0;
if (_wfopen_s(&file, in_name, L"rb") != 0)
{
grub_printf("src open failed\n");
return false;
}
res = f_open(&out, out_name, FA_WRITE | FA_CREATE_ALWAYS);
if (res)
{
grub_printf("dst open failed %d\n", res);
return false;
}
br = BUFFER_SIZE;
wprintf(L"copy %s -> %s\n", in_name, out_name);
for (;;)
{
// read file
br = fread(g_ctx.buffer, 1, BUFFER_SIZE, file);
grub_printf("\r%-20s", grub_get_human_size(ofs, GRUB_HUMAN_SIZE_SHORT));
ofs += br;
if (br == 0)
{
rc = true;
break;
}
res = f_write(&out, g_ctx.buffer, br, &bw);
if (res || bw < br)
{
grub_printf("write failed %d\n", res);
break; /* error or disk full */
}
}
grub_printf("\n");
fclose(file);
f_close(&out);

return rc;
}
137 changes: 137 additions & 0 deletions ctx.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
#include <stdio.h>
#include <fatio.h>
#include <dl.h>
#include <wchar.h>
#include <winioctl.h>

#include <grub/disk.h>
#include <grub/fs.h>
#include <grub/err.h>
#include <grub/partition.h>

#include "fatfs/ff.h"

struct fatio_ctx g_ctx;

void
fatio_remove_trailing_backslash(wchar_t* path)
{
size_t len = wcslen(path);
if (len < 1 || path[len - 1] != L'\\')
return;
path[len - 1] = L'\0';
}

static bool
lock_volume(unsigned disk_id)
{
WCHAR path[MAX_PATH];
grub_uint64_t lba = grub_partition_get_start(g_ctx.disk->partition);

grub_printf("disk %u, lba = %llu\n", disk_id, lba);

HANDLE volume = FindFirstVolumeW(path, MAX_PATH);

while (volume != NULL && volume != INVALID_HANDLE_VALUE)
{
DWORD dw = 0;
STORAGE_DEVICE_NUMBER sdn = { 0 };
PARTITION_INFORMATION_EX pie = { 0 };

fatio_remove_trailing_backslash(path);

HANDLE hv = CreateFileW(path, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (hv == INVALID_HANDLE_VALUE)
goto next;

if (!DeviceIoControl(hv, IOCTL_STORAGE_GET_DEVICE_NUMBER,
NULL, 0, &sdn, (DWORD)(sizeof(STORAGE_DEVICE_NUMBER)), &dw, NULL))
goto next;

switch (sdn.DeviceType)
{
case FILE_DEVICE_DISK:
case FILE_DEVICE_DISK_FILE_SYSTEM:
case FILE_DEVICE_FILE_SYSTEM:
if (sdn.DeviceNumber != disk_id)
goto next;
break;
default:
goto next;
}

dw = sizeof(PARTITION_INFORMATION_EX);
if (!DeviceIoControl(hv, IOCTL_DISK_GET_PARTITION_INFO_EX,
NULL, 0, &pie, dw, &dw, NULL))
goto next;
if (lba != (grub_uint64_t)(pie.StartingOffset.QuadPart >> GRUB_DISK_SECTOR_BITS))
goto next;
wprintf(L"Locking: %s, %lu, %lu, %llu\n", path, sdn.DeviceNumber, sdn.PartitionNumber, pie.StartingOffset.QuadPart >> GRUB_DISK_SECTOR_BITS);
dw = 0;
if (!DeviceIoControl(hv, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dw, NULL))
{
grub_printf("Failed to lock volume\n");
CloseHandle(hv);
return false;
}
g_ctx.volume = hv;
break;
next:
if (hv != INVALID_HANDLE_VALUE)
CloseHandle(hv);
if (FindNextVolumeW(volume, path, MAX_PATH) == 0)
break;
}
return true;
}

bool
fatio_set_disk(unsigned disk_id, unsigned part_id)
{
char* name = NULL;
g_ctx.volume = INVALID_HANDLE_VALUE;
name = grub_xasprintf("hd%u,%u", disk_id, part_id);
if (name == NULL)
return false;
g_ctx.disk = grub_disk_open(name);
grub_free(name);
if (g_ctx.disk == NULL)
return false;
if (g_ctx.disk->dev->id != GRUB_DISK_DEVICE_WINDISK_ID || !g_ctx.disk->partition)
{
grub_disk_close(g_ctx.disk);
g_ctx.disk = NULL;
return false;
}
g_ctx.total_sectors = grub_disk_native_sectors(g_ctx.disk);
g_ctx.buffer = grub_malloc(BUFFER_SIZE);
if (g_ctx.buffer == NULL)
{
grub_disk_close(g_ctx.disk);
g_ctx.disk = NULL;
return false;
}
if (lock_volume(disk_id))
return true;
grub_free(g_ctx.buffer);
g_ctx.buffer = NULL;
grub_disk_close(g_ctx.disk);
g_ctx.disk = NULL;
return false;
}

void
fatio_unset_disk(void)
{
if (g_ctx.disk)
grub_disk_close(g_ctx.disk);
g_ctx.disk = NULL;
g_ctx.total_sectors = 0;
if (g_ctx.buffer)
grub_free(g_ctx.buffer);
g_ctx.buffer = NULL;
if (g_ctx.volume != NULL && g_ctx.volume != INVALID_HANDLE_VALUE)
CloseHandle(g_ctx.volume);
GetLogicalDrives();
}
57 changes: 57 additions & 0 deletions dump.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#include <stdio.h>
#include <fatio.h>
#include <wchar.h>

#include "fatfs/ff.h"

bool
fatio_dump(const wchar_t* in_name, const wchar_t* out_name)
{
bool rc = FALSE;
FRESULT res;
UINT br, bw;
UINT64 ofs = 0;
FIL in;
FILE* file = 0;
res = f_open(&in, in_name, FA_READ);
if (res)
{
grub_printf("src open failed %d\n", res);
return false;
}
if (_wfopen_s(&file, out_name, L"wb") != 0)
{
grub_printf("dst open failed\n");
return false;
}
br = BUFFER_SIZE;
wprintf(L"copy %s -> %s\n", in_name, out_name);
for (;;)
{
// read file
res = f_read(&in, g_ctx.buffer, BUFFER_SIZE, &br);
if (res != FR_OK)
{
grub_printf("read failed %d\n", res);
break;
}
grub_printf("\r%-20s", grub_get_human_size(ofs, GRUB_HUMAN_SIZE_SHORT));
ofs += br;
if (br == 0)
{
rc = true;
break;
}
bw = fwrite(g_ctx.buffer, 1, br, file);
if (bw < br)
{
grub_printf("write failed %d\n", res);
break; /* error or disk full */
}
}
grub_printf("\n");
fclose(file);
f_close(&in);

return rc;
}
Loading

0 comments on commit 4c99b3b

Please sign in to comment.