1 /**
2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "os/file.h"
17 #include "utils/type_helpers.h"
18
19 #include <errhandlingapi.h>
20 #include <fcntl.h>
21 #include <fileapi.h>
22 #include <libloaderapi.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include <tchar.h>
26 #include <share.h>
27
28 namespace panda::os::file {
29
GetFlags(Mode mode)30 static int GetFlags(Mode mode)
31 {
32 switch (mode) {
33 case Mode::READONLY:
34 return _O_RDONLY | _O_BINARY;
35
36 case Mode::READWRITE:
37 return _O_RDWR | _O_BINARY;
38
39 case Mode::WRITEONLY:
40 return _O_WRONLY | _O_CREAT | _O_TRUNC | _O_BINARY; // NOLINT(hicpp-signed-bitwise)
41
42 case Mode::READWRITECREATE:
43 return _O_RDWR | _O_CREAT | _O_BINARY; // NOLINT(hicpp-signed-bitwise)
44
45 default:
46 break;
47 }
48
49 UNREACHABLE();
50 }
51
Open(std::string_view filename, Mode mode)52 File Open(std::string_view filename, Mode mode)
53 {
54 int fh;
55 // NOLINTNEXTLINE(hicpp-signed-bitwise)
56 const auto PERM = _S_IREAD | _S_IWRITE;
57 _sopen_s(&fh, filename.data(), GetFlags(mode), _SH_DENYNO, PERM);
58 return File(fh);
59 }
60
61 } // namespace panda::os::file
62
63 namespace panda::os::windows::file {
64
GetTmpPath()65 Expected<std::string, Error> File::GetTmpPath()
66 {
67 WCHAR tempPathBuffer[MAX_PATH];
68 DWORD dwRetVal = GetTempPathW(MAX_PATH, tempPathBuffer);
69 if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
70 return Unexpected(Error(GetLastError()));
71 }
72 std::wstring ws(tempPathBuffer);
73 return std::string(ws.begin(), ws.end());
74 }
75
GetExecutablePath()76 Expected<std::string, Error> File::GetExecutablePath()
77 {
78 WCHAR path[MAX_PATH];
79 DWORD dwRetVal = GetModuleFileNameW(NULL, path, MAX_PATH);
80 if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
81 return Unexpected(Error(GetLastError()));
82 }
83 std::wstring ws(path);
84 std::string::size_type pos = std::string(ws.begin(), ws.end()).find_last_of(File::GetPathDelim());
85
86 return (pos != std::string::npos) ? std::string(ws.begin(), ws.end()).substr(0, pos) : std::string("");
87 }
88
89 } // namespace panda::os::windows::file
90