return ret;
}
-
-static u64
-FILETIME_to_u64(const FILETIME *ft)
-{
- return ((u64)ft->dwHighDateTime << 32) | (u64)ft->dwLowDateTime;
-}
-
/* Load the short name of a file into a WIM dentry.
*
* If we can't read the short filename for some reason, we just ignore the error
size_t filename_nchars,
struct add_image_params *params,
struct win32_capture_state *state,
- unsigned vol_flags);
+ DWORD vol_flags);
/* Reads the directory entries of directory and recursively calls
* win32_build_dentry_tree() on them. */
struct wim_dentry *root,
struct add_image_params *params,
struct win32_capture_state *state,
- unsigned vol_flags)
+ DWORD vol_flags)
{
int ret;
struct wim_inode *inode,
struct list_head *unhashed_streams,
u64 file_size,
- unsigned vol_flags)
+ DWORD vol_flags)
{
int ret;
- u8 _buf[8192] _aligned_attribute(8);
+ u8 _buf[1024] _aligned_attribute(8);
u8 *buf;
size_t bufsize;
IO_STATUS_BLOCK io_status;
size_t filename_nchars,
struct add_image_params *params,
struct win32_capture_state *state,
- unsigned vol_flags)
+ DWORD vol_flags)
{
struct wim_dentry *root = NULL;
struct wim_inode *inode = NULL;
HANDLE h = INVALID_HANDLE_VALUE;
int ret;
NTSTATUS status;
- BY_HANDLE_FILE_INFORMATION file_info;
+ FILE_ALL_INFORMATION file_info;
u8 *rpbuf;
u16 rpbuflen;
u16 not_rpfixed;
goto out;
}
- if (!GetFileInformationByHandle(h, &file_info)) {
- set_errno_from_GetLastError();
- ERROR_WITH_ERRNO("\"%ls\": Can't get file information", full_path);
- ret = WIMLIB_ERR_STAT;
- goto out;
+ {
+ IO_STATUS_BLOCK iosb;
+
+ status = (*func_NtQueryInformationFile)(h, &iosb,
+ &file_info, sizeof(file_info),
+ FileAllInformation);
+ if (!NT_SUCCESS(status) && status != STATUS_BUFFER_OVERFLOW) {
+ set_errno_from_GetLastError();
+ ERROR_WITH_ERRNO("\"%ls\": Can't get file information", full_path);
+ ret = WIMLIB_ERR_STAT;
+ goto out;
+ }
}
- if (file_info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
+ if (!cur_dir) {
+ /* Root directory; get volume information. */
+ FILE_FS_ATTRIBUTE_INFORMATION attr_info;
+ FILE_FS_VOLUME_INFORMATION vol_info;
+ IO_STATUS_BLOCK iosb;
+
+ /* Get volume flags */
+ status = (*func_NtQueryVolumeInformationFile)(h, &iosb,
+ &attr_info, sizeof(attr_info),
+ FileFsAttributeInformation);
+ if ((NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) &&
+ iosb.Information >= offsetof(FILE_FS_ATTRIBUTE_INFORMATION,
+ FileSystemAttributes) +
+ sizeof(attr_info.FileSystemAttributes))
+ {
+ vol_flags = attr_info.FileSystemAttributes;
+ } else {
+ set_errno_from_nt_status(status);
+ WARNING_WITH_ERRNO("\"%ls\": Can't get volume attributes",
+ full_path);
+ vol_flags = 0;
+ }
+
+ /* Set inode number of root directory */
+ params->capture_root_ino = file_info.InternalInformation.IndexNumber.QuadPart;
+
+ /* Get volume ID */
+ status = (*func_NtQueryVolumeInformationFile)(h, &iosb,
+ &vol_info, sizeof(vol_info),
+ FileFsVolumeInformation);
+ if ((NT_SUCCESS(status) || (status == STATUS_BUFFER_OVERFLOW)) &&
+ iosb.Information >= offsetof(FILE_FS_VOLUME_INFORMATION,
+ VolumeSerialNumber) +
+ sizeof(vol_info.VolumeSerialNumber))
+ {
+ params->capture_root_dev = vol_info.VolumeSerialNumber;
+ } else {
+ set_errno_from_nt_status(status);
+ WARNING_WITH_ERRNO("\"%ls\": Can't get volume ID",
+ full_path);
+ params->capture_root_dev = 0;
+ }
+ }
+
+ if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
rpbuf = alloca(REPARSE_POINT_MAX_SIZE);
ret = win32_get_reparse_data(h, full_path,
params, rpbuf, &rpbuflen);
* directories on the FAT filesystem. */
ret = inode_table_new_dentry(params->inode_table,
filename,
- ((u64)file_info.nFileIndexHigh << 32) |
- (u64)file_info.nFileIndexLow,
- file_info.dwVolumeSerialNumber,
- (file_info.nNumberOfLinks <= 1 ||
- (file_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)),
+ file_info.InternalInformation.IndexNumber.QuadPart,
+ 0, /* We don't follow mount points, so we
+ currently don't need to get the
+ volume ID / device number. */
+ (file_info.StandardInformation.NumberOfLinks <= 1 ||
+ (file_info.BasicInformation.FileAttributes &
+ FILE_ATTRIBUTE_DIRECTORY)),
&root);
if (ret)
goto out;
goto out_progress;
}
- inode->i_attributes = file_info.dwFileAttributes;
- inode->i_creation_time = FILETIME_to_u64(&file_info.ftCreationTime);
- inode->i_last_write_time = FILETIME_to_u64(&file_info.ftLastWriteTime);
- inode->i_last_access_time = FILETIME_to_u64(&file_info.ftLastAccessTime);
+ inode->i_attributes = file_info.BasicInformation.FileAttributes;
+ inode->i_creation_time = file_info.BasicInformation.CreationTime.QuadPart;
+ inode->i_last_write_time = file_info.BasicInformation.LastWriteTime.QuadPart;
+ inode->i_last_access_time = file_info.BasicInformation.LastAccessTime.QuadPart;
inode->i_resolved = 1;
params->add_flags &= ~WIMLIB_ADD_FLAG_ROOT;
full_path_nchars,
inode,
params->unhashed_streams,
- ((u64)file_info.nFileSizeHigh << 32) |
- file_info.nFileIndexLow,
+ file_info.StandardInformation.EndOfFile.QuadPart,
vol_flags);
if (ret)
goto out;
const wchar_t *root_disk_path,
struct add_image_params *params)
{
- size_t path_nchars;
wchar_t *path;
+ DWORD dret;
+ size_t path_nchars;
int ret;
struct win32_capture_state state;
- unsigned vol_flags;
- DWORD dret;
-
- path_nchars = wcslen(root_disk_path);
- if (path_nchars > WINDOWS_NT_MAX_PATH)
- return WIMLIB_ERR_INVALID_PARAM;
-
- ret = win32_get_file_and_vol_ids(root_disk_path,
- ¶ms->capture_root_ino,
- ¶ms->capture_root_dev);
- if (ret) {
- ERROR_WITH_ERRNO("Can't open %ls", root_disk_path);
- return ret;
- }
-
- win32_get_vol_flags(root_disk_path, &vol_flags, NULL);
/* WARNING: There is no check for overflow later when this buffer is
* being used! But it's as long as the maximum path length understood
- * by Windows NT (which is NOT the same as MAX_PATH). */
+ * by Windows NT (which is NOT the same as MAX_PATH). */
path = MALLOC((WINDOWS_NT_MAX_PATH + 1) * sizeof(wchar_t));
if (!path)
return WIMLIB_ERR_NOMEM;
- /* Translate into full path */
+ /* Translate into full path. */
dret = GetFullPathName(root_disk_path, WINDOWS_NT_MAX_PATH - 3,
&path[4], NULL);
return WIMLIB_ERR_UNSUPPORTED;
}
- /* Add \??\ prefix */
+ /* Add \??\ prefix to form the NT namespace path. */
wmemcpy(path, L"\\??\\", 4);
path_nchars = dret + 4;
memset(&state, 0, sizeof(state));
ret = win32_build_dentry_tree_recursive(root_ret, NULL,
path, path_nchars, L"", 0,
- params, &state, vol_flags);
+ params, &state, 0);
FREE(path);
if (ret == 0)
win32_do_capture_warnings(root_disk_path, &state, params->add_flags);