MSFileSystemBasic.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167
  1. //===- llvm/Support/Windows/MSFileSystemBasic.cpp DXComplier Impl *- C++ -*-===//
  2. ///////////////////////////////////////////////////////////////////////////////
  3. // //
  4. // MSFileSystemBasic.cpp //
  5. // Copyright (C) Microsoft Corporation. All rights reserved. //
  6. // This file is distributed under the University of Illinois Open Source //
  7. // License. See LICENSE.TXT for details. //
  8. // //
  9. // This file implements the DXCompiler specific implementation of the Path API.//
  10. // //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #ifdef _WIN32
  13. #include "dxc/Support/WinIncludes.h"
  14. #include <fcntl.h>
  15. #include <io.h>
  16. #include <sys/stat.h>
  17. #include <sys/types.h>
  18. #include <stdint.h>
  19. #include <errno.h>
  20. #include <D3Dcommon.h>
  21. #include <new>
  22. #include <unordered_map>
  23. #include "llvm/Support/MSFileSystem.h"
  24. #include "dxc/Support/Global.h"
  25. #include "dxc/dxcapi.internal.h"
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // Externally visible functions.
  28. /// <summary>Creates an implementation based on IDxcSystemAccess.</summary>
  29. HRESULT CreateMSFileSystemForIface(_In_ IUnknown* pService, _COM_Outptr_ ::llvm::sys::fs::MSFileSystem** pResult) throw();
  30. /// <summary>Creates an implementation with no access to system resources.</summary>
  31. HRESULT CreateMSFileSystemBlocked(_COM_Outptr_ ::llvm::sys::fs::MSFileSystem** pResult) throw();
  32. ///////////////////////////////////////////////////////////////////////////////////////////////////
  33. // Helper functions.
  34. static
  35. DWORD WIN32_FROM_HRESULT(HRESULT hr)
  36. {
  37. if (SUCCEEDED(hr)) return ERROR_SUCCESS;
  38. if ((hr & 0xFFFF0000) == MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, 0))
  39. {
  40. // Could have come from many values, but we choose this one
  41. return HRESULT_CODE(hr);
  42. }
  43. if (hr == E_OUTOFMEMORY) return ERROR_OUTOFMEMORY;
  44. if (hr == E_NOTIMPL) return ERROR_CALL_NOT_IMPLEMENTED;
  45. return ERROR_FUNCTION_FAILED;
  46. }
  47. static
  48. HRESULT CopyStatStg(_In_ const STATSTG* statStg, _Out_ LPWIN32_FIND_DATAW lpFindFileData)
  49. {
  50. HRESULT hr = S_OK;
  51. lpFindFileData->dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
  52. lpFindFileData->ftCreationTime = statStg->ctime;
  53. lpFindFileData->ftLastAccessTime = statStg->atime;
  54. lpFindFileData->ftLastWriteTime = statStg->mtime;
  55. lpFindFileData->nFileSizeLow = statStg->cbSize.LowPart;
  56. lpFindFileData->nFileSizeHigh = statStg->cbSize.HighPart;
  57. if (statStg->pwcsName != nullptr)
  58. {
  59. IFC(StringCchCopyW(lpFindFileData->cFileName, _countof(lpFindFileData->cFileName), statStg->pwcsName));
  60. }
  61. Cleanup:
  62. return hr;
  63. }
  64. static
  65. void ClearStatStg(_Inout_ STATSTG* statStg)
  66. {
  67. DXASSERT_NOMSG(statStg != nullptr);
  68. if (statStg->pwcsName != nullptr)
  69. {
  70. CoTaskMemFree(statStg->pwcsName);
  71. statStg->pwcsName = nullptr;
  72. }
  73. }
  74. ///////////////////////////////////////////////////////////////////////////////////////////////////
  75. // IDxcSystemAccess-based MSFileSystem implementation.
  76. static const int FirstAllocFD = 10;
  77. static const int LastAllocFD = 8 * 1024;
  78. static const HANDLE FirstAllocHandle = (HANDLE)(uintptr_t)FirstAllocFD;
  79. static const HANDLE LastAllocHandle = (HANDLE)(uintptr_t)LastAllocFD;
  80. struct MSFileSystemHandle
  81. {
  82. enum MSFileSystemHandleKind
  83. {
  84. MSFileSystemHandleKind_FindHandle,
  85. MSFileSystemHandleKind_FileHandle,
  86. MSFileSystemHandleKind_FileMappingHandle
  87. };
  88. MSFileSystemHandleKind kind;
  89. CComPtr<IUnknown> storage;// For a file handle, the stream or directory handle.
  90. // For a find handle, the IEnumSTATSTG associated.
  91. CComPtr<IStream> stream; // For a file or console file handle, the stream interface.
  92. int fd; // For a file handle, its file descriptor.
  93. MSFileSystemHandle(int knownFD)
  94. : fd(knownFD)
  95. , kind(MSFileSystemHandleKind_FileHandle)
  96. {
  97. }
  98. MSFileSystemHandle(IUnknown* pMapping)
  99. : storage(pMapping)
  100. , kind(MSFileSystemHandleKind_FileMappingHandle)
  101. , fd(0)
  102. {
  103. }
  104. MSFileSystemHandle(IUnknown* pStorage, IStream* pStream)
  105. : storage(pStorage)
  106. , stream(pStream)
  107. , kind(MSFileSystemHandleKind_FileHandle)
  108. , fd(0)
  109. {
  110. }
  111. MSFileSystemHandle(IEnumSTATSTG* pEnumSTATG) : storage(pEnumSTATG), kind(MSFileSystemHandleKind_FindHandle)
  112. {
  113. }
  114. MSFileSystemHandle(MSFileSystemHandle&& other)
  115. {
  116. kind = other.kind;
  117. storage.p = other.storage.Detach();
  118. stream.p = other.stream.Detach();
  119. }
  120. HANDLE GetHandle() const { return (HANDLE)this; }
  121. IEnumSTATSTG* GetEnumStatStg()
  122. {
  123. DXASSERT(kind == MSFileSystemHandleKind_FindHandle, "otherwise caller didn't check");
  124. return (IEnumSTATSTG*)storage.p;
  125. }
  126. };
  127. namespace llvm {
  128. namespace sys {
  129. namespace fs {
  130. class MSFileSystemForIface : public MSFileSystem
  131. {
  132. private:
  133. CComPtr<IDxcSystemAccess> m_system;
  134. typedef std::unordered_multimap<LPCVOID, ID3D10Blob*> TViewMap;
  135. TViewMap m_mappingViews;
  136. MSFileSystemHandle m_knownHandle0;
  137. MSFileSystemHandle m_knownHandle1;
  138. MSFileSystemHandle m_knownHandle2;
  139. HRESULT AddFindHandle(_In_ IEnumSTATSTG* enumStatStg, _Out_ HANDLE* pResult) throw();
  140. HRESULT AddFileHandle(_In_ IUnknown* storage, _In_ IStream* stream, _Out_ HANDLE* pResult) throw();
  141. HRESULT AddMappingHandle(_In_ IUnknown* mapping, _Out_ HANDLE* pResult) throw();
  142. HRESULT AddMappingView(_In_ ID3D10Blob* blob) throw();
  143. HRESULT EnsureFDAvailable(int fd);
  144. HANDLE GetHandleForFD(int fd) throw();
  145. void GetFindHandle(HANDLE findHandle, _Outptr_ IEnumSTATSTG** enumStatStg) throw();
  146. int GetHandleFD(HANDLE fileHandle) throw();
  147. void GetHandleMapping(HANDLE fileHandle, _Outptr_ IUnknown** pResult) throw();
  148. void GetHandleStorage(HANDLE fileHandle, _Outptr_ IUnknown** pResult) throw();
  149. void GetHandleStream(HANDLE fileHandle, _Outptr_ IStream** pResult) throw();
  150. void CloseInternalHandle(HANDLE findHandle) throw();
  151. void RemoveMappingView(_In_ LPCVOID address) throw();
  152. public:
  153. MSFileSystemForIface(_In_ IDxcSystemAccess* access);
  154. virtual BOOL FindNextFileW(_In_ HANDLE hFindFile, _Out_ LPWIN32_FIND_DATAW lpFindFileData) throw() override;
  155. virtual HANDLE FindFirstFileW(_In_ LPCWSTR lpFileName, _Out_ LPWIN32_FIND_DATAW lpFindFileData) throw() override;
  156. virtual void FindClose(HANDLE findHandle) throw() override;
  157. virtual HANDLE CreateFileW(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_ DWORD dwFlagsAndAttributes) throw() override;
  158. virtual BOOL SetFileTime(_In_ HANDLE hFile, _In_opt_ const FILETIME *lpCreationTime, _In_opt_ const FILETIME *lpLastAccessTime, _In_opt_ const FILETIME *lpLastWriteTime) throw() override;
  159. virtual BOOL GetFileInformationByHandle(_In_ HANDLE hFile, _Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation) throw() override;
  160. virtual DWORD GetFileType(_In_ HANDLE hFile) throw() override;
  161. virtual BOOL CreateHardLinkW(_In_ LPCWSTR lpFileName, _In_ LPCWSTR lpExistingFileName) throw() override;
  162. virtual BOOL MoveFileExW(_In_ LPCWSTR lpExistingFileName, _In_opt_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) throw() override;
  163. virtual DWORD GetFileAttributesW(_In_ LPCWSTR lpFileName) throw() override;
  164. virtual BOOL CloseHandle(_In_ HANDLE hObject) throw() override;
  165. virtual BOOL DeleteFileW(_In_ LPCWSTR lpFileName) throw() override;
  166. virtual BOOL RemoveDirectoryW(_In_ LPCWSTR lpFileName) throw() override;
  167. virtual BOOL CreateDirectoryW(_In_ LPCWSTR lpPathName) throw() override;
  168. _Success_(return != 0 && return < nBufferLength)
  169. virtual DWORD GetCurrentDirectoryW(_In_ DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) throw() override;
  170. _Success_(return != 0 && return < nSize)
  171. virtual DWORD GetMainModuleFileNameW(__out_ecount_part(nSize, return +1) LPWSTR lpFilename, DWORD nSize) throw() override;
  172. virtual DWORD GetTempPathW(DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) throw() override;
  173. virtual BOOLEAN CreateSymbolicLinkW(_In_ LPCWSTR lpSymlinkFileName, _In_ LPCWSTR lpTargetFileName, DWORD dwFlags) throw() override;
  174. virtual bool SupportsCreateSymbolicLink() throw() override;
  175. virtual BOOL ReadFile(_In_ HANDLE hFile, _Out_ LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead) throw() override;
  176. virtual HANDLE CreateFileMappingW(_In_ HANDLE hFile, _In_ DWORD flProtect, _In_ DWORD dwMaximumSizeHigh, _In_ DWORD dwMaximumSizeLow) throw() override;
  177. virtual LPVOID MapViewOfFile(_In_ HANDLE hFileMappingObject, _In_ DWORD dwDesiredAccess, _In_ DWORD dwFileOffsetHigh, _In_ DWORD dwFileOffsetLow, _In_ SIZE_T dwNumberOfBytesToMap) throw() override;
  178. virtual BOOL UnmapViewOfFile(_In_ LPCVOID lpBaseAddress) throw() override;
  179. // Console APIs.
  180. virtual bool FileDescriptorIsDisplayed(int fd) throw() override;
  181. virtual unsigned GetColumnCount(DWORD nStdHandle) throw() override;
  182. virtual unsigned GetConsoleOutputTextAttributes() throw() override;
  183. virtual void SetConsoleOutputTextAttributes(unsigned attributes) throw() override;
  184. virtual void ResetConsoleOutputTextAttributes() throw() override;
  185. // CRT APIs.
  186. virtual int open_osfhandle(intptr_t osfhandle, int flags) throw() override;
  187. virtual intptr_t get_osfhandle(int fd) throw() override;
  188. virtual int close(int fd) throw() override;
  189. virtual long lseek(int fd, long offset, int origin) throw() override;
  190. virtual int setmode(int fd, int mode) throw() override;
  191. virtual errno_t resize_file(_In_ LPCWSTR path, uint64_t size) throw() override;
  192. virtual int Read(int fd, _Out_bytecap_(count) void* buffer, unsigned int count) throw() override;
  193. virtual int Write(int fd, _In_bytecount_(count) const void* buffer, unsigned int count) throw() override;
  194. };
  195. _Use_decl_annotations_
  196. MSFileSystemForIface::MSFileSystemForIface(IDxcSystemAccess* systemAccess)
  197. : m_system(systemAccess)
  198. , m_knownHandle0(0)
  199. , m_knownHandle1(1)
  200. , m_knownHandle2(2)
  201. {
  202. }
  203. _Use_decl_annotations_
  204. HRESULT MSFileSystemForIface::AddMappingHandle(IUnknown* mapping, HANDLE* pResult)
  205. {
  206. DXASSERT_NOMSG(mapping != nullptr);
  207. DXASSERT_NOMSG(pResult != nullptr);
  208. HRESULT hr = S_OK;
  209. MSFileSystemHandle* handle = nullptr;
  210. *pResult = INVALID_HANDLE_VALUE;
  211. handle = new (std::nothrow)MSFileSystemHandle(mapping);
  212. IFCOOM(handle);
  213. *pResult = handle->GetHandle();
  214. Cleanup:
  215. return hr;
  216. }
  217. _Use_decl_annotations_
  218. HRESULT MSFileSystemForIface::AddMappingView(ID3D10Blob* blob)
  219. {
  220. DXASSERT_NOMSG(blob != nullptr);
  221. LPVOID address = blob->GetBufferPointer();
  222. try
  223. {
  224. m_mappingViews.insert(std::pair<LPVOID, ID3D10Blob*>(address, blob));
  225. }
  226. catch (std::bad_alloc&)
  227. {
  228. return E_OUTOFMEMORY;
  229. }
  230. blob->AddRef();
  231. return S_OK;
  232. }
  233. _Use_decl_annotations_
  234. HRESULT MSFileSystemForIface::AddFindHandle(IEnumSTATSTG* enumStatStg, HANDLE* pResult)
  235. {
  236. DXASSERT_NOMSG(enumStatStg != nullptr);
  237. DXASSERT_NOMSG(pResult != nullptr);
  238. HRESULT hr = S_OK;
  239. MSFileSystemHandle* handle = nullptr;
  240. *pResult = INVALID_HANDLE_VALUE;
  241. handle = new (std::nothrow)MSFileSystemHandle(enumStatStg);
  242. IFCOOM(handle);
  243. *pResult = handle->GetHandle();
  244. Cleanup:
  245. return hr;
  246. }
  247. _Use_decl_annotations_
  248. HRESULT MSFileSystemForIface::AddFileHandle(IUnknown* storage, IStream* stream, HANDLE* pResult)
  249. {
  250. DXASSERT_NOMSG(storage != nullptr);
  251. DXASSERT_NOMSG(pResult != nullptr);
  252. HRESULT hr = S_OK;
  253. MSFileSystemHandle* handle = nullptr;
  254. *pResult = INVALID_HANDLE_VALUE;
  255. handle = new (std::nothrow)MSFileSystemHandle(storage, stream);
  256. IFCOOM(handle);
  257. *pResult = handle->GetHandle();
  258. Cleanup:
  259. return hr;
  260. }
  261. void MSFileSystemForIface::CloseInternalHandle(HANDLE handle)
  262. {
  263. DXASSERT_NOMSG(handle != nullptr);
  264. DXASSERT_NOMSG(handle != INVALID_HANDLE_VALUE);
  265. MSFileSystemHandle* fsHandle = reinterpret_cast<MSFileSystemHandle*>(handle);
  266. if (fsHandle == &m_knownHandle0 || fsHandle == &m_knownHandle1 || fsHandle == &m_knownHandle2)
  267. {
  268. fsHandle->stream.Release();
  269. fsHandle->storage.Release();
  270. }
  271. else
  272. {
  273. delete fsHandle;
  274. }
  275. }
  276. _Use_decl_annotations_
  277. void MSFileSystemForIface::RemoveMappingView(LPCVOID address)
  278. {
  279. TViewMap::iterator i = m_mappingViews.find(address);
  280. DXASSERT(i != m_mappingViews.end(), "otherwise pointer to view isn't in map");
  281. DXASSERT(i->second != nullptr, "otherwise blob is null and should not have been added");
  282. i->second->Release();
  283. m_mappingViews.erase(i);
  284. }
  285. _Use_decl_annotations_
  286. void MSFileSystemForIface::GetFindHandle(HANDLE findHandle, IEnumSTATSTG** enumStatStg)
  287. {
  288. DXASSERT_NOMSG(findHandle != nullptr);
  289. DXASSERT_NOMSG(enumStatStg != nullptr);
  290. MSFileSystemHandle* fsHandle = reinterpret_cast<MSFileSystemHandle*>(findHandle);
  291. DXASSERT(fsHandle->kind == MSFileSystemHandle::MSFileSystemHandleKind_FindHandle, "otherwise caller is passing wrong handle to API");
  292. *enumStatStg = fsHandle->GetEnumStatStg();
  293. DXASSERT(*enumStatStg != nullptr, "otherwise it should not have been added to handle entry");
  294. (*enumStatStg)->AddRef();
  295. }
  296. int MSFileSystemForIface::GetHandleFD(HANDLE fileHandle)
  297. {
  298. DXASSERT_NOMSG(fileHandle != nullptr);
  299. MSFileSystemHandle* fsHandle = reinterpret_cast<MSFileSystemHandle*>(fileHandle);
  300. DXASSERT(fsHandle->kind == MSFileSystemHandle::MSFileSystemHandleKind_FileHandle, "otherwise caller is passing wrong handle to API");
  301. return fsHandle->fd;
  302. }
  303. _Use_decl_annotations_
  304. void MSFileSystemForIface::GetHandleMapping(HANDLE mapping, _Outptr_ IUnknown** pResult)
  305. {
  306. DXASSERT_NOMSG(mapping != nullptr);
  307. DXASSERT_NOMSG(pResult != nullptr);
  308. MSFileSystemHandle* fsHandle = reinterpret_cast<MSFileSystemHandle*>(mapping);
  309. DXASSERT(fsHandle->kind == MSFileSystemHandle::MSFileSystemHandleKind_FileMappingHandle, "otherwise caller is passing wrong handle to API");
  310. *pResult = fsHandle->storage.p;
  311. DXASSERT(*pResult != nullptr, "otherwise it should not be requested through GetHandleMapping");
  312. (*pResult)->AddRef();
  313. }
  314. _Use_decl_annotations_
  315. void MSFileSystemForIface::GetHandleStorage(HANDLE fileHandle, _Outptr_ IUnknown** pResult)
  316. {
  317. DXASSERT_NOMSG(fileHandle != nullptr);
  318. DXASSERT_NOMSG(pResult != nullptr);
  319. MSFileSystemHandle* fsHandle = reinterpret_cast<MSFileSystemHandle*>(fileHandle);
  320. DXASSERT(fsHandle->kind == MSFileSystemHandle::MSFileSystemHandleKind_FileHandle, "otherwise caller is passing wrong handle to API");
  321. *pResult = fsHandle->storage.p;
  322. DXASSERT(*pResult != nullptr, "otherwise it should not be requested through GetHandleStorage");
  323. (*pResult)->AddRef();
  324. }
  325. _Use_decl_annotations_
  326. void MSFileSystemForIface::GetHandleStream(HANDLE fileHandle, _Outptr_ IStream** pResult)
  327. {
  328. DXASSERT_NOMSG(fileHandle != nullptr);
  329. DXASSERT_NOMSG(pResult != nullptr);
  330. MSFileSystemHandle* fsHandle = reinterpret_cast<MSFileSystemHandle*>(fileHandle);
  331. DXASSERT(fsHandle->kind == MSFileSystemHandle::MSFileSystemHandleKind_FileHandle, "otherwise caller is passing wrong handle to API");
  332. *pResult = fsHandle->stream.p;
  333. DXASSERT(*pResult != nullptr, "otherwise it should not be requested through GetHandleStream");
  334. (*pResult)->AddRef();
  335. }
  336. _Use_decl_annotations_
  337. HANDLE MSFileSystemForIface::FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
  338. {
  339. HRESULT hr = S_OK;
  340. CComPtr<IEnumSTATSTG> enumStatStg;
  341. HANDLE resultValue = INVALID_HANDLE_VALUE;
  342. STATSTG elt;
  343. ULONG fetched;
  344. ZeroMemory(&elt, sizeof(elt));
  345. ZeroMemory(lpFindFileData, sizeof(*lpFindFileData));
  346. fetched = 0;
  347. IFC(m_system->EnumFiles(lpFileName, &enumStatStg));
  348. IFC(enumStatStg->Next(1, &elt, &fetched));
  349. if (fetched == 0)
  350. {
  351. IFC(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  352. }
  353. else
  354. {
  355. IFC(CopyStatStg(&elt, lpFindFileData));
  356. IFC(AddFindHandle(enumStatStg, &resultValue));
  357. }
  358. Cleanup:
  359. ClearStatStg(&elt);
  360. if (FAILED(hr))
  361. {
  362. SetLastError(WIN32_FROM_HRESULT(hr));
  363. return INVALID_HANDLE_VALUE;
  364. }
  365. DXASSERT(resultValue != INVALID_HANDLE_VALUE, "otherwise AddFindHandle failed to return a valid handle");
  366. return resultValue;
  367. }
  368. _Use_decl_annotations_
  369. BOOL MSFileSystemForIface::FindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
  370. {
  371. HRESULT hr = S_OK;
  372. CComPtr<IEnumSTATSTG> enumStatStg;
  373. BOOL resultValue = FALSE;
  374. STATSTG elt;
  375. ULONG fetched;
  376. ZeroMemory(&elt, sizeof(elt));
  377. ZeroMemory(lpFindFileData, sizeof(*lpFindFileData));
  378. fetched = 0;
  379. GetFindHandle(hFindFile, &enumStatStg);
  380. IFC(enumStatStg->Next(1, &elt, &fetched));
  381. if (fetched == 0)
  382. {
  383. IFC(HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));
  384. }
  385. else
  386. {
  387. IFC(CopyStatStg(&elt, lpFindFileData));
  388. resultValue = TRUE;
  389. }
  390. Cleanup:
  391. if (FAILED(hr))
  392. {
  393. SetLastError(WIN32_FROM_HRESULT(hr));
  394. return FALSE;
  395. }
  396. return TRUE;
  397. }
  398. void MSFileSystemForIface::FindClose(HANDLE findHandle)
  399. {
  400. CloseInternalHandle(findHandle);
  401. }
  402. _Use_decl_annotations_
  403. HANDLE MSFileSystemForIface::CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes)
  404. {
  405. HRESULT hr = S_OK;
  406. CComPtr<IUnknown> storage;
  407. CComPtr<IStream> stream;
  408. HANDLE resultHandle = INVALID_HANDLE_VALUE;
  409. IFC(m_system->OpenStorage(lpFileName, dwDesiredAccess, dwShareMode, dwCreationDisposition, dwFlagsAndAttributes, &storage));
  410. IFC(storage.QueryInterface(&stream));
  411. IFC(AddFileHandle(storage, stream, &resultHandle));
  412. Cleanup:
  413. if (FAILED(hr))
  414. {
  415. SetLastError(WIN32_FROM_HRESULT(hr));
  416. return INVALID_HANDLE_VALUE;
  417. }
  418. return resultHandle;
  419. }
  420. _Use_decl_annotations_
  421. BOOL MSFileSystemForIface::SetFileTime(HANDLE hFile, _In_opt_ const FILETIME *lpCreationTime, _In_opt_ const FILETIME *lpLastAccessTime, _In_opt_ const FILETIME *lpLastWriteTime)
  422. {
  423. HRESULT hr = S_OK;
  424. CComPtr<IUnknown> storage;
  425. GetHandleStorage(hFile, &storage);
  426. IFC(m_system->SetStorageTime(storage, lpCreationTime, lpLastAccessTime, lpLastWriteTime));
  427. Cleanup:
  428. if (FAILED(hr))
  429. {
  430. SetLastError(WIN32_FROM_HRESULT(hr));
  431. return FALSE;
  432. }
  433. return TRUE;
  434. }
  435. _Use_decl_annotations_
  436. BOOL MSFileSystemForIface::GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMATION lpFileInformation)
  437. {
  438. HRESULT hr = S_OK;
  439. CComPtr<IUnknown> storage;
  440. GetHandleStorage(hFile, &storage);
  441. IFC(m_system->GetFileInformationForStorage(storage, lpFileInformation));
  442. Cleanup:
  443. if (FAILED(hr))
  444. {
  445. SetLastError(WIN32_FROM_HRESULT(hr));
  446. return FALSE;
  447. }
  448. return TRUE;
  449. }
  450. _Use_decl_annotations_
  451. DWORD MSFileSystemForIface::GetFileType(HANDLE hFile)
  452. {
  453. HRESULT hr = S_OK;
  454. CComPtr<IUnknown> storage;
  455. DWORD fileType;
  456. GetHandleStorage(hFile, &storage);
  457. IFC(m_system->GetFileTypeForStorage(storage, &fileType));
  458. if (fileType == FILE_TYPE_UNKNOWN)
  459. {
  460. SetLastError(NO_ERROR);
  461. }
  462. Cleanup:
  463. if (FAILED(hr))
  464. {
  465. SetLastError(WIN32_FROM_HRESULT(hr));
  466. fileType = FILE_TYPE_UNKNOWN;
  467. }
  468. return fileType;
  469. }
  470. _Use_decl_annotations_
  471. BOOL MSFileSystemForIface::CreateHardLinkW(LPCWSTR lpFileName, LPCWSTR lpExistingFileName)
  472. {
  473. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  474. return FALSE;
  475. }
  476. _Use_decl_annotations_
  477. BOOL MSFileSystemForIface::MoveFileExW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName, DWORD dwFlags)
  478. {
  479. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  480. return FALSE;
  481. }
  482. _Use_decl_annotations_
  483. DWORD MSFileSystemForIface::GetFileAttributesW(LPCWSTR lpFileName)
  484. {
  485. HRESULT hr = S_OK;
  486. DWORD attributes;
  487. IFC(m_system->GetFileAttributesForStorage(lpFileName, &attributes));
  488. Cleanup:
  489. if (FAILED(hr))
  490. {
  491. SetLastError(WIN32_FROM_HRESULT(hr));
  492. attributes = INVALID_FILE_ATTRIBUTES;
  493. }
  494. return attributes;
  495. }
  496. _Use_decl_annotations_
  497. BOOL MSFileSystemForIface::CloseHandle(HANDLE hObject)
  498. {
  499. this->CloseInternalHandle(hObject);
  500. return TRUE;
  501. }
  502. _Use_decl_annotations_
  503. BOOL MSFileSystemForIface::DeleteFileW(LPCWSTR lpFileName)
  504. {
  505. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  506. return FALSE;
  507. }
  508. _Use_decl_annotations_
  509. BOOL MSFileSystemForIface::RemoveDirectoryW(LPCWSTR lpFileName)
  510. {
  511. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  512. return FALSE;
  513. }
  514. _Use_decl_annotations_
  515. BOOL MSFileSystemForIface::CreateDirectoryW(LPCWSTR lpPathName)
  516. {
  517. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  518. return FALSE;
  519. }
  520. _Use_decl_annotations_
  521. DWORD MSFileSystemForIface::GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
  522. {
  523. DWORD written = 0;
  524. HRESULT hr = S_OK;
  525. IFC(m_system->GetCurrentDirectoryForStorage(nBufferLength, lpBuffer, &written));
  526. Cleanup:
  527. if (FAILED(hr))
  528. {
  529. SetLastError(WIN32_FROM_HRESULT(hr));
  530. return 0;
  531. }
  532. return written;
  533. }
  534. _Use_decl_annotations_
  535. DWORD MSFileSystemForIface::GetMainModuleFileNameW(LPWSTR lpFilename, DWORD nSize)
  536. {
  537. DWORD written = 0;
  538. HRESULT hr = S_OK;
  539. IFC(m_system->GetMainModuleFileNameW(nSize, lpFilename, &written));
  540. Cleanup:
  541. if (FAILED(hr))
  542. {
  543. SetLastError(WIN32_FROM_HRESULT(hr));
  544. return 0;
  545. }
  546. return written;
  547. }
  548. _Use_decl_annotations_
  549. DWORD MSFileSystemForIface::GetTempPathW(DWORD nBufferLength, LPWSTR lpBuffer)
  550. {
  551. DWORD written = 0;
  552. HRESULT hr = S_OK;
  553. IFC(m_system->GetTempStoragePath(nBufferLength, lpBuffer, &written));
  554. Cleanup:
  555. if (FAILED(hr))
  556. {
  557. SetLastError(WIN32_FROM_HRESULT(hr));
  558. return 0;
  559. }
  560. return written;
  561. }
  562. _Use_decl_annotations_
  563. BOOLEAN MSFileSystemForIface::CreateSymbolicLinkW(LPCWSTR lpSymlinkFileName, LPCWSTR lpTargetFileName, DWORD dwFlags)
  564. {
  565. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  566. return FALSE;
  567. }
  568. bool MSFileSystemForIface::SupportsCreateSymbolicLink()
  569. {
  570. return false;
  571. }
  572. _Use_decl_annotations_
  573. BOOL MSFileSystemForIface::ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead)
  574. {
  575. HRESULT hr = S_OK;
  576. CComPtr<IStream> stream;
  577. GetHandleStream(hFile, &stream);
  578. ULONG cbRead;
  579. IFC(stream->Read(lpBuffer, nNumberOfBytesToRead, &cbRead));
  580. if (lpNumberOfBytesRead != nullptr)
  581. {
  582. *lpNumberOfBytesRead = cbRead;
  583. }
  584. Cleanup:
  585. if (FAILED(hr))
  586. {
  587. SetLastError(WIN32_FROM_HRESULT(hr));
  588. return FALSE;
  589. }
  590. return TRUE;
  591. }
  592. _Use_decl_annotations_
  593. HANDLE MSFileSystemForIface::CreateFileMappingW(HANDLE hFile, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow)
  594. {
  595. HRESULT hr = S_OK;
  596. HANDLE result = INVALID_HANDLE_VALUE;
  597. CComPtr<IUnknown> storage;
  598. CComPtr<IUnknown> mapping;
  599. GetHandleStorage(hFile, &storage);
  600. IFC(m_system->CreateStorageMapping(storage, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, &mapping));
  601. IFC(AddMappingHandle(mapping, &result));
  602. Cleanup:
  603. if (FAILED(hr))
  604. {
  605. SetLastError(WIN32_FROM_HRESULT(hr));
  606. return INVALID_HANDLE_VALUE;
  607. }
  608. return result;
  609. }
  610. _Use_decl_annotations_
  611. LPVOID MSFileSystemForIface::MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap)
  612. {
  613. HRESULT hr = S_OK;
  614. CComPtr<IUnknown> mapping;
  615. CComPtr<ID3D10Blob> blob;
  616. GetHandleMapping(hFileMappingObject, &mapping);
  617. IFC(m_system->MapViewOfFile(mapping, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap, &blob));
  618. IFC(AddMappingView(blob));
  619. Cleanup:
  620. if (FAILED(hr))
  621. {
  622. SetLastError(WIN32_FROM_HRESULT(hr));
  623. return INVALID_HANDLE_VALUE;
  624. }
  625. return blob->GetBufferPointer();
  626. }
  627. _Use_decl_annotations_
  628. BOOL MSFileSystemForIface::UnmapViewOfFile(LPCVOID lpBaseAddress) throw()
  629. {
  630. RemoveMappingView(lpBaseAddress);
  631. return TRUE;
  632. }
  633. bool MSFileSystemForIface::FileDescriptorIsDisplayed(int fd)
  634. {
  635. return false;
  636. }
  637. unsigned MSFileSystemForIface::GetColumnCount(DWORD nStdHandle)
  638. {
  639. return 0;
  640. }
  641. unsigned MSFileSystemForIface::GetConsoleOutputTextAttributes() throw()
  642. {
  643. return 0;
  644. }
  645. void MSFileSystemForIface::SetConsoleOutputTextAttributes(unsigned attributes)
  646. {
  647. return;
  648. }
  649. void MSFileSystemForIface::ResetConsoleOutputTextAttributes()
  650. {
  651. }
  652. int MSFileSystemForIface::open_osfhandle(intptr_t osfhandle, int flags)
  653. {
  654. return GetHandleFD((HANDLE)osfhandle);
  655. }
  656. HRESULT MSFileSystemForIface::EnsureFDAvailable(int fd)
  657. {
  658. MSFileSystemHandle* ptr;
  659. switch (fd)
  660. {
  661. case 0: ptr = &m_knownHandle0; break;
  662. case 1: ptr = &m_knownHandle1; break;
  663. case 2: ptr = &m_knownHandle2; break;
  664. default:
  665. return S_OK;
  666. }
  667. HRESULT hr = S_OK;
  668. if (ptr->storage == nullptr)
  669. {
  670. CComPtr<IUnknown> storage;
  671. CComPtr<IStream> stream;
  672. IFC(m_system->OpenStdStorage(fd, &storage));
  673. IFC(storage.QueryInterface(&stream));
  674. ptr->storage = storage;
  675. ptr->stream = stream;
  676. }
  677. DXASSERT(ptr->storage != nullptr, "otherwise we should have failed to initialize");
  678. DXASSERT(ptr->stream != nullptr, "otherwise we should have failed to initialize - input/output/error should support streams");
  679. Cleanup:
  680. return hr;
  681. }
  682. HANDLE MSFileSystemForIface::GetHandleForFD(int fd)
  683. {
  684. MSFileSystemHandle* ptr;
  685. switch (fd)
  686. {
  687. case 0: ptr = &m_knownHandle0; break;
  688. case 1: ptr = &m_knownHandle1; break;
  689. case 2: ptr = &m_knownHandle2; break;
  690. default: ptr = (MSFileSystemHandle *)(uintptr_t)fd; break;
  691. }
  692. return ptr->GetHandle();
  693. }
  694. intptr_t MSFileSystemForIface::get_osfhandle(int fd) {
  695. if (FAILED(EnsureFDAvailable(fd))) {
  696. errno = EBADF;
  697. return -1;
  698. }
  699. return (intptr_t)GetHandleForFD(fd);
  700. }
  701. int MSFileSystemForIface::close(int fd)
  702. {
  703. HANDLE h = GetHandleForFD(fd);
  704. this->CloseInternalHandle(h);
  705. return 0;
  706. }
  707. long MSFileSystemForIface::lseek(int fd, long offset, int origin)
  708. {
  709. HRESULT hr = S_OK;
  710. CComPtr<IStream> stream;
  711. LARGE_INTEGER li;
  712. ULARGE_INTEGER uli;
  713. if (FAILED(EnsureFDAvailable(fd)))
  714. {
  715. errno = EBADF;
  716. return -1;
  717. }
  718. GetHandleStream(GetHandleForFD(fd), &stream);
  719. li.HighPart = 0;
  720. li.LowPart = offset;
  721. IFC(stream->Seek(li, origin, &uli));
  722. Cleanup:
  723. if (FAILED(hr))
  724. {
  725. errno = EINVAL;
  726. return -1;
  727. }
  728. if (uli.HighPart > 0)
  729. {
  730. errno = EOVERFLOW;
  731. return -1;
  732. }
  733. return uli.LowPart;
  734. }
  735. int MSFileSystemForIface::setmode(int fd, int mode)
  736. {
  737. return 0;
  738. }
  739. _Use_decl_annotations_
  740. errno_t MSFileSystemForIface::resize_file(LPCWSTR path, uint64_t size)
  741. {
  742. return EBADF;
  743. }
  744. _Use_decl_annotations_
  745. int MSFileSystemForIface::Read(int fd, void* buffer, unsigned int count)
  746. {
  747. HRESULT hr = S_OK;
  748. CComPtr<IStream> stream;
  749. ULONG cbRead = 0;
  750. if (FAILED(EnsureFDAvailable(fd)))
  751. {
  752. errno = EBADF;
  753. return -1;
  754. }
  755. GetHandleStream(GetHandleForFD(fd), &stream);
  756. IFC(stream->Read(buffer, count, &cbRead));
  757. Cleanup:
  758. if (FAILED(hr))
  759. {
  760. errno = EINVAL;
  761. return -1;
  762. }
  763. return (int)cbRead;
  764. }
  765. _Use_decl_annotations_
  766. int MSFileSystemForIface::Write(int fd, const void* buffer, unsigned int count)
  767. {
  768. HRESULT hr = S_OK;
  769. CComPtr<IStream> stream;
  770. ULONG cbWritten = 0;
  771. if (FAILED(EnsureFDAvailable(fd)))
  772. {
  773. errno = EBADF;
  774. return -1;
  775. }
  776. GetHandleStream(GetHandleForFD(fd), &stream);
  777. IFC(stream->Write(buffer, count, &cbWritten));
  778. Cleanup:
  779. if (FAILED(hr))
  780. {
  781. errno = EINVAL;
  782. return -1;
  783. }
  784. return (int)cbWritten;
  785. }
  786. } // end namespace fs
  787. } // end namespace sys
  788. } // end namespace llvm
  789. ///////////////////////////////////////////////////////////////////////////////////////////////////
  790. // Blocked MSFileSystem implementation.
  791. #ifdef DBG
  792. static void MSFileSystemBlockedCalled() { DebugBreak(); }
  793. #else
  794. static void MSFileSystemBlockedCalled() { }
  795. #endif
  796. static BOOL MSFileSystemBlockedErrWin32()
  797. {
  798. MSFileSystemBlockedCalled();
  799. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  800. return FALSE;
  801. }
  802. static HANDLE MSFileSystemBlockedHandle()
  803. {
  804. MSFileSystemBlockedCalled();
  805. SetLastError(ERROR_FUNCTION_NOT_CALLED);
  806. return INVALID_HANDLE_VALUE;
  807. }
  808. static int MSFileSystemBlockedErrno()
  809. {
  810. MSFileSystemBlockedCalled();
  811. errno = EBADF;
  812. return -1;
  813. }
  814. static int MSFileSystemBlockedErrnoT()
  815. {
  816. MSFileSystemBlockedCalled();
  817. return EBADF;
  818. }
  819. namespace llvm {
  820. namespace sys {
  821. namespace fs {
  822. class MSFileSystemBlocked : public MSFileSystem
  823. {
  824. private:
  825. public:
  826. MSFileSystemBlocked();
  827. virtual BOOL FindNextFileW(_In_ HANDLE , _Out_ LPWIN32_FIND_DATAW ) throw() override
  828. { return MSFileSystemBlockedErrWin32(); }
  829. virtual HANDLE FindFirstFileW(_In_ LPCWSTR lpFileName, _Out_ LPWIN32_FIND_DATAW lpFindFileData) throw() override
  830. { return MSFileSystemBlockedHandle(); }
  831. virtual void FindClose(HANDLE findHandle) throw() override
  832. { MSFileSystemBlockedCalled(); }
  833. virtual HANDLE CreateFileW(_In_ LPCWSTR lpFileName, _In_ DWORD dwDesiredAccess, _In_ DWORD dwShareMode, _In_ DWORD dwCreationDisposition, _In_ DWORD dwFlagsAndAttributes) throw() override
  834. { return MSFileSystemBlockedHandle(); }
  835. virtual BOOL SetFileTime(_In_ HANDLE hFile, _In_opt_ const FILETIME *lpCreationTime, _In_opt_ const FILETIME *lpLastAccessTime, _In_opt_ const FILETIME *lpLastWriteTime) throw() override
  836. { return MSFileSystemBlockedErrWin32(); }
  837. virtual BOOL GetFileInformationByHandle(_In_ HANDLE hFile, _Out_ LPBY_HANDLE_FILE_INFORMATION lpFileInformation) throw() override
  838. { return MSFileSystemBlockedErrWin32(); }
  839. virtual DWORD GetFileType(_In_ HANDLE hFile) throw() override
  840. { MSFileSystemBlockedErrWin32(); return FILE_TYPE_UNKNOWN; }
  841. virtual BOOL CreateHardLinkW(_In_ LPCWSTR lpFileName, _In_ LPCWSTR lpExistingFileName) throw() override
  842. { return MSFileSystemBlockedErrWin32(); }
  843. virtual BOOL MoveFileExW(_In_ LPCWSTR lpExistingFileName, _In_opt_ LPCWSTR lpNewFileName, _In_ DWORD dwFlags) throw() override
  844. { return MSFileSystemBlockedErrWin32(); }
  845. virtual DWORD GetFileAttributesW(_In_ LPCWSTR lpFileName) throw() override
  846. { MSFileSystemBlockedErrWin32(); return 0; }
  847. virtual BOOL CloseHandle(_In_ HANDLE hObject) throw() override
  848. { return MSFileSystemBlockedErrWin32(); }
  849. virtual BOOL DeleteFileW(_In_ LPCWSTR lpFileName) throw() override
  850. { return MSFileSystemBlockedErrWin32(); }
  851. virtual BOOL RemoveDirectoryW(LPCWSTR lpFileName) throw() override
  852. { return MSFileSystemBlockedErrWin32(); }
  853. virtual BOOL CreateDirectoryW(_In_ LPCWSTR lpPathName) throw() override
  854. { return MSFileSystemBlockedErrWin32(); }
  855. _Success_(return != 0 && return < nBufferLength)
  856. virtual DWORD GetCurrentDirectoryW(_In_ DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) throw() override;
  857. virtual DWORD GetMainModuleFileNameW(__out_ecount_part(nSize, return +1) LPWSTR lpFilename, DWORD nSize) throw() override;
  858. _Success_(return != 0 && return < nBufferLength)
  859. virtual DWORD GetTempPathW(DWORD nBufferLength, _Out_writes_to_opt_(nBufferLength, return +1) LPWSTR lpBuffer) throw() override;
  860. virtual BOOLEAN CreateSymbolicLinkW(_In_ LPCWSTR lpSymlinkFileName, _In_ LPCWSTR lpTargetFileName, DWORD dwFlags) throw() override
  861. { return MSFileSystemBlockedErrWin32(); }
  862. virtual bool SupportsCreateSymbolicLink() throw() override
  863. { MSFileSystemBlockedErrWin32(); return false; }
  864. virtual BOOL ReadFile(_In_ HANDLE hFile, _Out_ LPVOID lpBuffer, _In_ DWORD nNumberOfBytesToRead, _Out_opt_ LPDWORD lpNumberOfBytesRead) throw() override
  865. { return MSFileSystemBlockedErrWin32(); }
  866. virtual HANDLE CreateFileMappingW(_In_ HANDLE hFile, _In_ DWORD flProtect, _In_ DWORD dwMaximumSizeHigh, _In_ DWORD dwMaximumSizeLow) throw() override
  867. { return MSFileSystemBlockedHandle(); }
  868. virtual LPVOID MapViewOfFile(_In_ HANDLE hFileMappingObject, _In_ DWORD dwDesiredAccess, _In_ DWORD dwFileOffsetHigh, _In_ DWORD dwFileOffsetLow, _In_ SIZE_T dwNumberOfBytesToMap) throw() override
  869. { MSFileSystemBlockedErrWin32(); return nullptr; }
  870. virtual BOOL UnmapViewOfFile(_In_ LPCVOID lpBaseAddress) throw() override
  871. { return MSFileSystemBlockedErrWin32(); }
  872. // Console APIs.
  873. virtual bool FileDescriptorIsDisplayed(int fd) throw() override
  874. { MSFileSystemBlockedCalled(); return false; }
  875. virtual unsigned GetColumnCount(DWORD nStdHandle) throw() override
  876. { MSFileSystemBlockedCalled(); return 80; }
  877. virtual unsigned GetConsoleOutputTextAttributes() throw() override
  878. { MSFileSystemBlockedCalled(); return 0; }
  879. virtual void SetConsoleOutputTextAttributes(unsigned attributes) throw() override
  880. { MSFileSystemBlockedCalled(); }
  881. virtual void ResetConsoleOutputTextAttributes() throw() override
  882. { MSFileSystemBlockedCalled(); }
  883. // CRT APIs.
  884. virtual int open_osfhandle(intptr_t osfhandle, int flags) throw() override
  885. { return MSFileSystemBlockedErrno(); }
  886. virtual intptr_t get_osfhandle(int fd) throw() override
  887. { MSFileSystemBlockedErrno(); return 0; }
  888. virtual int close(int fd) throw() override
  889. { return MSFileSystemBlockedErrno(); }
  890. virtual long lseek(int fd, long offset, int origin) throw() override
  891. { return MSFileSystemBlockedErrno(); }
  892. virtual int setmode(int fd, int mode) throw() override
  893. { return MSFileSystemBlockedErrno(); }
  894. virtual errno_t resize_file(_In_ LPCWSTR path, uint64_t size) throw() override
  895. { return MSFileSystemBlockedErrnoT(); }
  896. virtual int Read(int fd, void* buffer, unsigned int count) throw() override
  897. { return MSFileSystemBlockedErrno(); }
  898. virtual int Write(int fd, const void* buffer, unsigned int count) throw() override
  899. { return MSFileSystemBlockedErrno(); }
  900. };
  901. MSFileSystemBlocked::MSFileSystemBlocked()
  902. {
  903. }
  904. _Use_decl_annotations_
  905. DWORD MSFileSystemBlocked::GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer)
  906. {
  907. if (nBufferLength > 1)
  908. {
  909. lpBuffer[0] = L'.';
  910. lpBuffer[1] = L'\0';
  911. }
  912. return 1;
  913. }
  914. _Use_decl_annotations_
  915. DWORD MSFileSystemBlocked::GetMainModuleFileNameW(LPWSTR lpFilename, DWORD nSize)
  916. {
  917. SetLastError(NO_ERROR);
  918. return 0;
  919. }
  920. _Use_decl_annotations_
  921. DWORD MSFileSystemBlocked::GetTempPathW(DWORD nBufferLength, LPWSTR lpBuffer)
  922. {
  923. if (nBufferLength > 1)
  924. {
  925. lpBuffer[0] = L'.';
  926. lpBuffer[1] = L'\0';
  927. }
  928. return 1;
  929. }
  930. } // end namespace fs
  931. } // end namespace sys
  932. } // end namespace llvm
  933. ///////////////////////////////////////////////////////////////////////////////////////////////////
  934. // Externally visible functions.
  935. _Use_decl_annotations_
  936. HRESULT CreateMSFileSystemForIface(IUnknown* pService, ::llvm::sys::fs::MSFileSystem** pResult) throw()
  937. {
  938. DXASSERT_NOMSG(pService != nullptr);
  939. DXASSERT_NOMSG(pResult != nullptr);
  940. CComPtr<IDxcSystemAccess> systemAccess;
  941. HRESULT hr = pService->QueryInterface(__uuidof(IDxcSystemAccess), (void**)&systemAccess);
  942. if (FAILED(hr)) return hr;
  943. *pResult = new (std::nothrow) ::llvm::sys::fs::MSFileSystemForIface(systemAccess);
  944. return (*pResult != nullptr) ? S_OK : E_OUTOFMEMORY;
  945. }
  946. _Use_decl_annotations_
  947. HRESULT CreateMSFileSystemBlocked(::llvm::sys::fs::MSFileSystem** pResult) throw()
  948. {
  949. DXASSERT_NOMSG(pResult != nullptr);
  950. *pResult = new (std::nothrow) ::llvm::sys::fs::MSFileSystemBlocked();
  951. return (*pResult != nullptr) ? S_OK : E_OUTOFMEMORY;
  952. }
  953. #endif // _WIN32