-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
68 changed files
with
38,776 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} |
Oops, something went wrong.