| Index: src/shared/platform/win/nacl_host_dir.c
|
| diff --git a/src/shared/platform/win/nacl_host_dir.c b/src/shared/platform/win/nacl_host_dir.c
|
| index 0b1376d269a7d01d881e613b79daa8f105a892dd..ecbbce8c9961ab0aff460ce59ae276e9ac18f052 100644
|
| --- a/src/shared/platform/win/nacl_host_dir.c
|
| +++ b/src/shared/platform/win/nacl_host_dir.c
|
| @@ -228,3 +228,120 @@ int NaClHostDirClose(struct NaClHostDir *d) {
|
| }
|
| return 0;
|
| }
|
| +
|
| +enum OBJECT_INFORMATION_CLASS { ObjectNameInformation = 1 };
|
| +enum FILE_INFORMATION_CLASS { FileNameInformation = 9 };
|
| +struct FILE_NAME_INFORMATION { ULONG FileNameLength; WCHAR FileName[1]; };
|
| +struct IO_STATUS_BLOCK { PVOID Dummy; ULONG_PTR Information; };
|
| +struct UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; };
|
| +struct MOUNTMGR_TARGET_NAME { USHORT DeviceNameLength; WCHAR DeviceName[1]; };
|
| +struct MOUNTMGR_VOLUME_PATHS { ULONG MultiSzLength; WCHAR MultiSz[1]; };
|
| +
|
| +extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryObject(IN HANDLE Handle OPTIONAL,
|
| + IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
| + OUT PVOID ObjectInformation OPTIONAL, IN ULONG ObjectInformationLength,
|
| + OUT PULONG ReturnLength OPTIONAL);
|
| +extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE FileHandle,
|
| + OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation,
|
| + IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass);
|
| +
|
| +#define MOUNTMGRCONTROLTYPE ((ULONG) 'm')
|
| +#define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH \
|
| + CTL_CODE(MOUNTMGRCONTROLTYPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS)
|
| +
|
| +union ANY_BUFFER {
|
| + MOUNTMGR_TARGET_NAME TargetName;
|
| + MOUNTMGR_VOLUME_PATHS TargetPaths;
|
| + FILE_NAME_INFORMATION NameInfo;
|
| + UNICODE_STRING UnicodeString;
|
| + WCHAR Buffer[USHRT_MAX];
|
| +};
|
| +
|
| +int NaClHostDescFchdir(struct NaClHostDir *d) {
|
| + static ANY_BUFFER nameFull, nameRel, nameMnt;
|
| + ULONG returnedLength;
|
| + IO_STATUS_BLOCK iosb;
|
| + NTSTATUS status;
|
| +
|
| + if (0 != NtQueryObject(d->handle,
|
| + ObjectNameInformation,
|
| + nameFull.Buffer,
|
| + sizeof(nameFull.Buffer),
|
| + &returnedLength)) {
|
| + }
|
| +
|
| + if (0 != NtQueryInformationFile(hFile,
|
| + &iosb,
|
| + nameRel.Buffer,
|
| + sizeof(nameRel.Buffer),
|
| + FileNameInformation)) {
|
| + }
|
| +
|
| + /*I'm not sure how this works with network paths... */
|
| + assert(nameFull.UnicodeString.Length >= nameRel.NameInfo.FileNameLength);
|
| + nameMnt.TargetName.DeviceNameLength = (USHORT)(
|
| + nameFull.UnicodeString.Length - nameRel.NameInfo.FileNameLength);
|
| + wcsncpy(nameMnt.TargetName.DeviceName, nameFull.UnicodeString.Buffer,
|
| + nameMnt.TargetName.DeviceNameLength / sizeof(WCHAR));
|
| + HANDLE hMountPointMgr = CreateFile(_T("\\\\.\\MountPointManager"),
|
| + 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
| + NULL, OPEN_EXISTING, 0, NULL);
|
| + __try
|
| + {
|
| + DWORD bytesReturned;
|
| + BOOL success = DeviceIoControl(hMountPointMgr,
|
| + IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, &nameMnt,
|
| + sizeof(nameMnt), &nameMnt, sizeof(nameMnt),
|
| + &bytesReturned, NULL);
|
| + assert(success && nameMnt.TargetPaths.MultiSzLength > 0);
|
| + wcsncat(nameMnt.TargetPaths.MultiSz, nameRel.NameInfo.FileName,
|
| + nameRel.NameInfo.FileNameLength / sizeof(WCHAR));
|
| + return nameMnt.TargetPaths.MultiSz;
|
| + }
|
| + __finally { CloseHandle(hMountPointMgr); }
|
| +
|
| + /*FILE_NAME_INFO name_info;
|
| +
|
| + if (!GetFileInformationByHandleEx(d->handle,
|
| + FileNameInfo,
|
| + &name_info,
|
| + sizeof name_info)) {
|
| + err = GetLastError();
|
| + return -NaClXlateSystemError(err);
|
| + }*/
|
| +
|
| + if (-1 == _wchdir(name_info.FileName)) {
|
| + return -GetErrno(errno);
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +int NaClHostDirFchmod(struct NaClHostDir *d, int mode) {
|
| + if (-1 == _chmod(path, mode)) {
|
| + return -GetErrno();
|
| + }
|
| + return 0;
|
| +}
|
| +
|
| +int NaClHostDirFsync(struct NaClHostDir *d) {
|
| + DWORD err;
|
| +
|
| + if (!FlushFileBuffers(d->handle)) {
|
| + err = GetLastError();
|
| + return -NaClXlateSystemError(err);
|
| + }
|
| +
|
| + return 0;
|
| +}
|
| +
|
| +int NaClHostDirFdatasync(struct NaClHostDir *d) {
|
| + DWORD err;
|
| +
|
| + if (!FlushFileBuffers(d->handle)) {
|
| + err = GetLastError();
|
| + return -NaClXlateSystemError(err);
|
| + }
|
| +
|
| + return 0;
|
| +}
|
|
|