mirror of
https://github.com/isar/libmdbx.git
synced 2025-11-07 07:18:56 +08:00
mdbx: Windows XP compatibility.
Change-Id: Iafe3a83110610071e42a168ef9fc5f8d3131854f
This commit is contained in:
178
src/osal.c
178
src/osal.c
@@ -17,7 +17,6 @@
|
||||
#include "./bits.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <winternl.h>
|
||||
|
||||
static int waitstatus2errcode(DWORD result) {
|
||||
switch (result) {
|
||||
@@ -105,13 +104,31 @@ extern NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle,
|
||||
IN OUT PSIZE_T RegionSize,
|
||||
IN ULONG FreeType);
|
||||
|
||||
#ifndef WOF_CURRENT_VERSION
|
||||
typedef struct _WOF_EXTERNAL_INFO {
|
||||
DWORD Version;
|
||||
DWORD Provider;
|
||||
} WOF_EXTERNAL_INFO, *PWOF_EXTERNAL_INFO;
|
||||
#endif /* WOF_CURRENT_VERSION */
|
||||
|
||||
#ifndef WIM_PROVIDER_CURRENT_VERSION
|
||||
#define WIM_PROVIDER_HASH_SIZE 20
|
||||
|
||||
typedef struct _WIM_PROVIDER_EXTERNAL_INFO {
|
||||
DWORD Version;
|
||||
DWORD Flags;
|
||||
LARGE_INTEGER DataSourceId;
|
||||
BYTE ResourceHash[WIM_PROVIDER_HASH_SIZE];
|
||||
} WIM_PROVIDER_EXTERNAL_INFO, *PWIM_PROVIDER_EXTERNAL_INFO;
|
||||
#endif /* WIM_PROVIDER_CURRENT_VERSION */
|
||||
|
||||
#ifndef FILE_PROVIDER_CURRENT_VERSION
|
||||
typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
|
||||
ULONG Version;
|
||||
ULONG Algorithm;
|
||||
ULONG Flags;
|
||||
} FILE_PROVIDER_EXTERNAL_INFO_V1, *PFILE_PROVIDER_EXTERNAL_INFO_V1;
|
||||
#endif
|
||||
#endif /* FILE_PROVIDER_CURRENT_VERSION */
|
||||
|
||||
#ifndef STATUS_OBJECT_NOT_EXTERNALLY_BACKED
|
||||
#define STATUS_OBJECT_NOT_EXTERNALLY_BACKED ((NTSTATUS)0xC000046DL)
|
||||
@@ -120,14 +137,6 @@ typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
|
||||
#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS)0xC0000010L)
|
||||
#endif
|
||||
|
||||
extern NTSTATUS
|
||||
NtFsControlFile(IN HANDLE FileHandle, IN OUT HANDLE Event,
|
||||
IN OUT PVOID /* PIO_APC_ROUTINE */ ApcRoutine,
|
||||
IN OUT PVOID ApcContext, OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG FsControlCode, IN OUT PVOID InputBuffer,
|
||||
IN ULONG InputBufferLength, OUT OPTIONAL PVOID OutputBuffer,
|
||||
IN ULONG OutputBufferLength);
|
||||
|
||||
#endif /* _WIN32 || _WIN64 */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@@ -740,80 +749,85 @@ int mdbx_is_file_local(mdbx_filehandle_t handle, int flags) {
|
||||
if (GetFileType(handle) != FILE_TYPE_DISK)
|
||||
return ERROR_FILE_OFFLINE;
|
||||
|
||||
FILE_REMOTE_PROTOCOL_INFO RemoteProtocolInfo;
|
||||
if (GetFileInformationByHandleEx(handle, FileRemoteProtocolInfo,
|
||||
&RemoteProtocolInfo,
|
||||
sizeof(RemoteProtocolInfo))) {
|
||||
if ((RemoteProtocolInfo.Flags & (REMOTE_PROTOCOL_INFO_FLAG_LOOPBACK |
|
||||
REMOTE_PROTOCOL_INFO_FLAG_OFFLINE)) !=
|
||||
REMOTE_PROTOCOL_INFO_FLAG_LOOPBACK)
|
||||
return ERROR_FILE_OFFLINE;
|
||||
}
|
||||
|
||||
#if defined(_WIN64) && defined(WOF_CURRENT_VERSION)
|
||||
NTSTATUS rc;
|
||||
struct {
|
||||
WOF_EXTERNAL_INFO wof_info;
|
||||
union {
|
||||
WIM_PROVIDER_EXTERNAL_INFO wim_info;
|
||||
FILE_PROVIDER_EXTERNAL_INFO_V1 file_info;
|
||||
};
|
||||
size_t reserved_for_microsoft_madness[42];
|
||||
} GetExternalBacking_OutputBuffer;
|
||||
IO_STATUS_BLOCK StatusBlock;
|
||||
rc = NtFsControlFile(handle, NULL, NULL, NULL, &StatusBlock,
|
||||
FSCTL_GET_EXTERNAL_BACKING, NULL, 0,
|
||||
&GetExternalBacking_OutputBuffer,
|
||||
sizeof(GetExternalBacking_OutputBuffer));
|
||||
if (rc != STATUS_OBJECT_NOT_EXTERNALLY_BACKED &&
|
||||
rc != STATUS_INVALID_DEVICE_REQUEST)
|
||||
return NT_SUCCESS(rc) ? ERROR_REMOTE_STORAGE_MEDIA_ERROR
|
||||
: ntstatus2errcode(rc);
|
||||
#endif
|
||||
|
||||
WCHAR PathBuffer[INT16_MAX];
|
||||
DWORD VolumeSerialNumber, FileSystemFlags;
|
||||
if (!GetVolumeInformationByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
&VolumeSerialNumber, NULL,
|
||||
&FileSystemFlags, NULL, 0))
|
||||
return GetLastError();
|
||||
|
||||
if ((flags & MDBX_RDONLY) == 0) {
|
||||
if (FileSystemFlags & (FILE_SEQUENTIAL_WRITE_ONCE | FILE_READ_ONLY_VOLUME |
|
||||
FILE_VOLUME_IS_COMPRESSED))
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
}
|
||||
|
||||
if (!GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
FILE_NAME_NORMALIZED | VOLUME_NAME_NT))
|
||||
return GetLastError();
|
||||
|
||||
if (_wcsnicmp(PathBuffer, L"\\Device\\Mup\\", 12) == 0)
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
|
||||
if (GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
FILE_NAME_NORMALIZED | VOLUME_NAME_DOS)) {
|
||||
UINT DriveType = GetDriveTypeW(PathBuffer);
|
||||
if (DriveType == DRIVE_NO_ROOT_DIR &&
|
||||
wcsncmp(PathBuffer, L"\\\\?\\", 4) == 0 &&
|
||||
wcsncmp(PathBuffer + 5, L":\\", 2) == 0) {
|
||||
PathBuffer[7] = 0;
|
||||
DriveType = GetDriveTypeW(PathBuffer + 4);
|
||||
if (mdbx_GetFileInformationByHandleEx) {
|
||||
FILE_REMOTE_PROTOCOL_INFO RemoteProtocolInfo;
|
||||
if (mdbx_GetFileInformationByHandleEx(handle, FileRemoteProtocolInfo,
|
||||
&RemoteProtocolInfo,
|
||||
sizeof(RemoteProtocolInfo))) {
|
||||
if ((RemoteProtocolInfo.Flags & (REMOTE_PROTOCOL_INFO_FLAG_LOOPBACK |
|
||||
REMOTE_PROTOCOL_INFO_FLAG_OFFLINE)) !=
|
||||
REMOTE_PROTOCOL_INFO_FLAG_LOOPBACK)
|
||||
return ERROR_FILE_OFFLINE;
|
||||
}
|
||||
switch (DriveType) {
|
||||
case DRIVE_CDROM:
|
||||
if (flags & MDBX_RDONLY)
|
||||
break;
|
||||
// fall through
|
||||
case DRIVE_UNKNOWN:
|
||||
case DRIVE_NO_ROOT_DIR:
|
||||
case DRIVE_REMOTE:
|
||||
default:
|
||||
}
|
||||
|
||||
if (mdbx_NtFsControlFile) {
|
||||
NTSTATUS rc;
|
||||
struct {
|
||||
WOF_EXTERNAL_INFO wof_info;
|
||||
union {
|
||||
WIM_PROVIDER_EXTERNAL_INFO wim_info;
|
||||
FILE_PROVIDER_EXTERNAL_INFO_V1 file_info;
|
||||
};
|
||||
size_t reserved_for_microsoft_madness[42];
|
||||
} GetExternalBacking_OutputBuffer;
|
||||
IO_STATUS_BLOCK StatusBlock;
|
||||
rc = mdbx_NtFsControlFile(handle, NULL, NULL, NULL, &StatusBlock,
|
||||
FSCTL_GET_EXTERNAL_BACKING, NULL, 0,
|
||||
&GetExternalBacking_OutputBuffer,
|
||||
sizeof(GetExternalBacking_OutputBuffer));
|
||||
if (rc != STATUS_OBJECT_NOT_EXTERNALLY_BACKED &&
|
||||
rc != STATUS_INVALID_DEVICE_REQUEST)
|
||||
return NT_SUCCESS(rc) ? ERROR_REMOTE_STORAGE_MEDIA_ERROR
|
||||
: ntstatus2errcode(rc);
|
||||
}
|
||||
|
||||
if (mdbx_GetVolumeInformationByHandleW && mdbx_GetFinalPathNameByHandleW) {
|
||||
WCHAR PathBuffer[INT16_MAX];
|
||||
DWORD VolumeSerialNumber, FileSystemFlags;
|
||||
if (!mdbx_GetVolumeInformationByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
&VolumeSerialNumber, NULL,
|
||||
&FileSystemFlags, NULL, 0))
|
||||
return GetLastError();
|
||||
|
||||
if ((flags & MDBX_RDONLY) == 0) {
|
||||
if (FileSystemFlags & (FILE_SEQUENTIAL_WRITE_ONCE |
|
||||
FILE_READ_ONLY_VOLUME | FILE_VOLUME_IS_COMPRESSED))
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
}
|
||||
|
||||
if (!mdbx_GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
FILE_NAME_NORMALIZED | VOLUME_NAME_NT))
|
||||
return GetLastError();
|
||||
|
||||
if (_wcsnicmp(PathBuffer, L"\\Device\\Mup\\", 12) == 0)
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
case DRIVE_REMOVABLE:
|
||||
case DRIVE_FIXED:
|
||||
case DRIVE_RAMDISK:
|
||||
break;
|
||||
|
||||
if (mdbx_GetFinalPathNameByHandleW(handle, PathBuffer, INT16_MAX,
|
||||
FILE_NAME_NORMALIZED |
|
||||
VOLUME_NAME_DOS)) {
|
||||
UINT DriveType = GetDriveTypeW(PathBuffer);
|
||||
if (DriveType == DRIVE_NO_ROOT_DIR &&
|
||||
wcsncmp(PathBuffer, L"\\\\?\\", 4) == 0 &&
|
||||
wcsncmp(PathBuffer + 5, L":\\", 2) == 0) {
|
||||
PathBuffer[7] = 0;
|
||||
DriveType = GetDriveTypeW(PathBuffer + 4);
|
||||
}
|
||||
switch (DriveType) {
|
||||
case DRIVE_CDROM:
|
||||
if (flags & MDBX_RDONLY)
|
||||
break;
|
||||
// fall through
|
||||
case DRIVE_UNKNOWN:
|
||||
case DRIVE_NO_ROOT_DIR:
|
||||
case DRIVE_REMOTE:
|
||||
default:
|
||||
return ERROR_REMOTE_STORAGE_MEDIA_ERROR;
|
||||
case DRIVE_REMOVABLE:
|
||||
case DRIVE_FIXED:
|
||||
case DRIVE_RAMDISK:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
Reference in New Issue
Block a user