VirtualBox

source: kBuild/trunk/src/lib/nt/nthlpfs.c@ 2702

Last change on this file since 2702 was 2702, checked in by bird, 11 years ago

kmk/WindowsNT: Avoiding unnecessary stat() calls. Reimplemented stat(), lstat(), fstat(), opendir(), readdir(), and closedir() using native NT APIs.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.3 KB
Line 
1/* $Id: nthlpfs.c 2702 2013-11-21 00:11:08Z bird $ */
2/** @file
3 * MSC + NT helpers for file system related functions.
4 */
5
6/*
7 * Copyright (c) 2005-2013 knut st. osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 *
27 * Alternatively, the content of this file may be used under the terms of the
28 * GPL version 2 or later, or LGPL version 2.1 or later.
29 */
30
31
32/*******************************************************************************
33* Header Files *
34*******************************************************************************/
35#include "nthlp.h"
36
37
38
39static int birdHasTrailingSlash(const char *pszPath)
40{
41 char ch, ch2;
42
43 /* Skip leading slashes. */
44 while ((ch = *pszPath) == '/' || ch == '\\')
45 pszPath++;
46 if (ch == '\0')
47 return 0;
48
49 /* Find the last char. */
50 while ((ch2 = *++pszPath) != '\0')
51 ch = ch2;
52
53 return ch == '/' || ch == '\\' || ch == ':';
54}
55
56
57static int birdIsPathDirSpec(const char *pszPath)
58{
59 char ch, ch2;
60
61 /* Check for empty string. */
62 ch = *pszPath;
63 if (ch == '\0')
64 return 0;
65
66 /* Find the last char. */
67 while ((ch2 = *++pszPath) != '\0')
68 ch = ch2;
69
70 return ch == '/' || ch == '\\' || ch == ':';
71}
72
73#ifndef BIRD_USE_WIN32
74
75static int birdDosToNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
76{
77 MY_NTSTATUS rcNt;
78 WCHAR wszTmp[4096];
79 MY_UNICODE_STRING TmpUniStr;
80 MY_ANSI_STRING Src;
81
82 pNtPath->Length = pNtPath->MaximumLength = 0;
83 pNtPath->Buffer = NULL;
84
85 /*
86 * Convert the input to wide char.
87 */
88 Src.Buffer = (PCHAR)pszPath;
89 Src.MaximumLength = Src.Length = (USHORT)strlen(pszPath);
90
91 TmpUniStr.Length = 0;
92 TmpUniStr.MaximumLength = sizeof(wszTmp) - sizeof(WCHAR);
93 TmpUniStr.Buffer = wszTmp;
94
95 rcNt = g_pfnRtlAnsiStringToUnicodeString(&TmpUniStr, &Src, FALSE);
96 if (MY_NT_SUCCESS(rcNt))
97 {
98 if (TmpUniStr.Length > 0 && !(TmpUniStr.Length & 1))
99 {
100 wszTmp[TmpUniStr.Length / sizeof(WCHAR)] = '\0';
101
102 /*
103 * Convert the wide DOS path to an NT path.
104 */
105 if (g_pfnRtlDosPathNameToNtPathName_U(wszTmp, pNtPath, NULL, FALSE))
106 return 0;
107 }
108 rcNt = -1;
109 }
110 return birdSetErrnoFromNt(rcNt);
111}
112
113
114static void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
115{
116 HeapFree(GetProcessHeap(), 0, pNtPath->Buffer);
117 pNtPath->Buffer = NULL;
118}
119
120#endif /* !BIRD_USE_WIN32 */
121
122
123HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
124 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
125{
126 static int s_fHaveOpenReparsePoint = -1;
127 HANDLE hFile;
128#ifdef BIRD_USE_WIN32
129 SECURITY_ATTRIBUTES SecAttr;
130 DWORD dwErr;
131 DWORD fW32Disp;
132 DWORD fW32Flags;
133#else
134 MY_UNICODE_STRING NtPath;
135 MY_NTSTATUS rcNt;
136#endif
137
138 birdResolveImports();
139
140 if (birdIsPathDirSpec(pszPath))
141 fCreateOptions |= FILE_DIRECTORY_FILE;
142 if ( (fCreateOptions & FILE_OPEN_REPARSE_POINT)
143 && s_fHaveOpenReparsePoint == 0)
144 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
145
146#ifdef BIRD_USE_WIN32
147 /* NT -> W32 */
148
149 SecAttr.nLength = sizeof(SecAttr);
150 SecAttr.lpSecurityDescriptor = NULL;
151 SecAttr.bInheritHandle = fObjAttribs & OBJ_INHERIT ? TRUE : FALSE;
152
153 fW32Flags = 0;
154 if (!(fObjAttribs & OBJ_CASE_INSENSITIVE))
155 fW32Flags |= FILE_FLAG_POSIX_SEMANTICS;
156 if (fCreateOptions & FILE_OPEN_FOR_BACKUP_INTENT)
157 fW32Flags |= FILE_FLAG_BACKUP_SEMANTICS;
158 if (fCreateOptions & FILE_OPEN_REPARSE_POINT)
159 fW32Flags |= FILE_FLAG_OPEN_REPARSE_POINT;
160 //?? if (fCreateOptions & FILE_DIRECTORY_FILE)
161 //?? fW32Flags |= ;
162
163 switch (fCreateDisposition)
164 {
165 case FILE_OPEN: fW32Disp = OPEN_EXISTING; break;
166 case FILE_CREATE: fW32Disp = CREATE_NEW; break;
167 case FILE_OPEN_IF: fW32Disp = OPEN_ALWAYS; break;
168 case FILE_OVERWRITE_IF: fW32Disp = CREATE_ALWAYS; break;
169 default:
170 __debugbreak();
171 return INVALID_HANDLE_VALUE;
172 }
173
174 hFile = CreateFileA(pszPath, fDesiredAccess, fShareAccess, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/);
175 if (hFile != INVALID_HANDLE_VALUE)
176 return hFile;
177
178 dwErr = GetLastError();
179
180 /* Deal with FILE_FLAG_OPEN_REPARSE_POINT the first times around. */
181 if ( dwErr == ERROR_INVALID_PARAMETER
182 && s_fHaveOpenReparsePoint < 0
183 && (fCreateOptions & FILE_OPEN_REPARSE_POINT) )
184 {
185 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
186 fW32Flags &= ~FILE_FLAG_OPEN_REPARSE_POINT;
187 hFile = CreateFileA(pszPath, fDesiredAccess, fFileAttribs, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/);
188 if (hFile != INVALID_HANDLE_VALUE)
189 {
190 s_fHaveOpenReparsePoint = 0;
191 return hFile;
192 }
193 }
194
195 birdSetErrnoFromWin32(dwErr);
196
197#else
198 /*
199 * Call the NT API directly.
200 */
201 if (birdDosToNtPath(pszPath, &NtPath) == 0)
202 {
203 MY_IO_STATUS_BLOCK Ios;
204 MY_OBJECT_ATTRIBUTES ObjAttr;
205
206 Ios.Information = -1;
207 Ios.u.Status = 0;
208
209 MyInitializeObjectAttributes(&ObjAttr, &NtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
210
211 rcNt = g_pfnNtCreateFile(&hFile,
212 fDesiredAccess,
213 &ObjAttr,
214 &Ios,
215 NULL, /* cbFileInitialAlloc */
216 fFileAttribs,
217 fShareAccess,
218 fCreateDisposition,
219 fCreateOptions,
220 NULL, /* pEaBuffer */
221 0); /* cbEaBuffer*/
222 if (MY_NT_SUCCESS(rcNt))
223 {
224 birdFreeNtPath(&NtPath);
225 return hFile;
226 }
227
228 birdFreeNtPath(&NtPath);
229 birdSetErrnoFromNt(rcNt);
230 }
231
232#endif
233 return INVALID_HANDLE_VALUE;
234}
235
236
237void birdCloseFile(HANDLE hFile)
238{
239#ifdef BIRD_USE_WIN32
240 CloseHandle(hFile);
241#else
242 birdResolveImports();
243 g_pfnNtClose(hFile);
244#endif
245}
246
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette