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; |
+} |