OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. | 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. |
3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
4 * found in the LICENSE file. | 4 * found in the LICENSE file. |
5 */ | 5 */ |
6 | 6 |
7 /* | 7 /* |
8 * NaCl Service Runtime. Directory descriptor / Handle abstraction. | 8 * NaCl Service Runtime. Directory descriptor / Handle abstraction. |
9 */ | 9 */ |
10 #include "native_client/src/include/portability.h" | 10 #include "native_client/src/include/portability.h" |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 int NaClHostDirClose(struct NaClHostDir *d) { | 221 int NaClHostDirClose(struct NaClHostDir *d) { |
222 if (NULL == d) { | 222 if (NULL == d) { |
223 NaClLog(LOG_FATAL, "NaClHostDirClose: 'this' is NULL\n"); | 223 NaClLog(LOG_FATAL, "NaClHostDirClose: 'this' is NULL\n"); |
224 } | 224 } |
225 NaClMutexDtor(&d->mu); | 225 NaClMutexDtor(&d->mu); |
226 if (!FindClose(d->handle)) { | 226 if (!FindClose(d->handle)) { |
227 return -NaClXlateSystemError(GetLastError()); | 227 return -NaClXlateSystemError(GetLastError()); |
228 } | 228 } |
229 return 0; | 229 return 0; |
230 } | 230 } |
| 231 |
| 232 enum OBJECT_INFORMATION_CLASS { ObjectNameInformation = 1 }; |
| 233 enum FILE_INFORMATION_CLASS { FileNameInformation = 9 }; |
| 234 struct FILE_NAME_INFORMATION { ULONG FileNameLength; WCHAR FileName[1]; }; |
| 235 struct IO_STATUS_BLOCK { PVOID Dummy; ULONG_PTR Information; }; |
| 236 struct UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; }; |
| 237 struct MOUNTMGR_TARGET_NAME { USHORT DeviceNameLength; WCHAR DeviceName[1]; }; |
| 238 struct MOUNTMGR_VOLUME_PATHS { ULONG MultiSzLength; WCHAR MultiSz[1]; }; |
| 239 |
| 240 extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryObject(IN HANDLE Handle OPTIONAL, |
| 241 IN OBJECT_INFORMATION_CLASS ObjectInformationClass, |
| 242 OUT PVOID ObjectInformation OPTIONAL, IN ULONG ObjectInformationLength, |
| 243 OUT PULONG ReturnLength OPTIONAL); |
| 244 extern "C" NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE FileHandle, |
| 245 OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, |
| 246 IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass); |
| 247 |
| 248 #define MOUNTMGRCONTROLTYPE ((ULONG) 'm') |
| 249 #define IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH \ |
| 250 CTL_CODE(MOUNTMGRCONTROLTYPE, 12, METHOD_BUFFERED, FILE_ANY_ACCESS) |
| 251 |
| 252 union ANY_BUFFER { |
| 253 MOUNTMGR_TARGET_NAME TargetName; |
| 254 MOUNTMGR_VOLUME_PATHS TargetPaths; |
| 255 FILE_NAME_INFORMATION NameInfo; |
| 256 UNICODE_STRING UnicodeString; |
| 257 WCHAR Buffer[USHRT_MAX]; |
| 258 }; |
| 259 |
| 260 int NaClHostDescFchdir(struct NaClHostDir *d) { |
| 261 static ANY_BUFFER nameFull, nameRel, nameMnt; |
| 262 ULONG returnedLength; |
| 263 IO_STATUS_BLOCK iosb; |
| 264 NTSTATUS status; |
| 265 |
| 266 if (0 != NtQueryObject(d->handle, |
| 267 ObjectNameInformation, |
| 268 nameFull.Buffer, |
| 269 sizeof(nameFull.Buffer), |
| 270 &returnedLength)) { |
| 271 } |
| 272 |
| 273 if (0 != NtQueryInformationFile(hFile, |
| 274 &iosb, |
| 275 nameRel.Buffer, |
| 276 sizeof(nameRel.Buffer), |
| 277 FileNameInformation)) { |
| 278 } |
| 279 |
| 280 /*I'm not sure how this works with network paths... */ |
| 281 assert(nameFull.UnicodeString.Length >= nameRel.NameInfo.FileNameLength); |
| 282 nameMnt.TargetName.DeviceNameLength = (USHORT)( |
| 283 nameFull.UnicodeString.Length - nameRel.NameInfo.FileNameLength); |
| 284 wcsncpy(nameMnt.TargetName.DeviceName, nameFull.UnicodeString.Buffer, |
| 285 nameMnt.TargetName.DeviceNameLength / sizeof(WCHAR)); |
| 286 HANDLE hMountPointMgr = CreateFile(_T("\\\\.\\MountPointManager"), |
| 287 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, |
| 288 NULL, OPEN_EXISTING, 0, NULL); |
| 289 __try |
| 290 { |
| 291 DWORD bytesReturned; |
| 292 BOOL success = DeviceIoControl(hMountPointMgr, |
| 293 IOCTL_MOUNTMGR_QUERY_DOS_VOLUME_PATH, &nameMnt, |
| 294 sizeof(nameMnt), &nameMnt, sizeof(nameMnt), |
| 295 &bytesReturned, NULL); |
| 296 assert(success && nameMnt.TargetPaths.MultiSzLength > 0); |
| 297 wcsncat(nameMnt.TargetPaths.MultiSz, nameRel.NameInfo.FileName, |
| 298 nameRel.NameInfo.FileNameLength / sizeof(WCHAR)); |
| 299 return nameMnt.TargetPaths.MultiSz; |
| 300 } |
| 301 __finally { CloseHandle(hMountPointMgr); } |
| 302 |
| 303 /*FILE_NAME_INFO name_info; |
| 304 |
| 305 if (!GetFileInformationByHandleEx(d->handle, |
| 306 FileNameInfo, |
| 307 &name_info, |
| 308 sizeof name_info)) { |
| 309 err = GetLastError(); |
| 310 return -NaClXlateSystemError(err); |
| 311 }*/ |
| 312 |
| 313 if (-1 == _wchdir(name_info.FileName)) { |
| 314 return -GetErrno(errno); |
| 315 } |
| 316 |
| 317 return 0; |
| 318 } |
| 319 |
| 320 int NaClHostDirFchmod(struct NaClHostDir *d, int mode) { |
| 321 if (-1 == _chmod(path, mode)) { |
| 322 return -GetErrno(); |
| 323 } |
| 324 return 0; |
| 325 } |
| 326 |
| 327 int NaClHostDirFsync(struct NaClHostDir *d) { |
| 328 DWORD err; |
| 329 |
| 330 if (!FlushFileBuffers(d->handle)) { |
| 331 err = GetLastError(); |
| 332 return -NaClXlateSystemError(err); |
| 333 } |
| 334 |
| 335 return 0; |
| 336 } |
| 337 |
| 338 int NaClHostDirFdatasync(struct NaClHostDir *d) { |
| 339 DWORD err; |
| 340 |
| 341 if (!FlushFileBuffers(d->handle)) { |
| 342 err = GetLastError(); |
| 343 return -NaClXlateSystemError(err); |
| 344 } |
| 345 |
| 346 return 0; |
| 347 } |
OLD | NEW |