VirtualBox

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

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

Some unlink(), rmdir() and kmk_rm optimizations.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 9.7 KB
Line 
1/* $Id: nthlpfs.c 2713 2013-11-21 21:11:00Z 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/*******************************************************************************
39* Global Variables *
40*******************************************************************************/
41static int g_fHaveOpenReparsePoint = -1;
42
43
44
45static int birdHasTrailingSlash(const char *pszPath)
46{
47 char ch, ch2;
48
49 /* Skip leading slashes. */
50 while ((ch = *pszPath) == '/' || ch == '\\')
51 pszPath++;
52 if (ch == '\0')
53 return 0;
54
55 /* Find the last char. */
56 while ((ch2 = *++pszPath) != '\0')
57 ch = ch2;
58
59 return ch == '/' || ch == '\\' || ch == ':';
60}
61
62
63static int birdIsPathDirSpec(const char *pszPath)
64{
65 char ch, ch2;
66
67 /* Check for empty string. */
68 ch = *pszPath;
69 if (ch == '\0')
70 return 0;
71
72 /* Find the last char. */
73 while ((ch2 = *++pszPath) != '\0')
74 ch = ch2;
75
76 return ch == '/' || ch == '\\' || ch == ':';
77}
78
79
80int birdDosToNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
81{
82 MY_NTSTATUS rcNt;
83 WCHAR wszTmp[4096];
84 MY_UNICODE_STRING TmpUniStr;
85 MY_ANSI_STRING Src;
86
87 birdResolveImports();
88
89 pNtPath->Length = pNtPath->MaximumLength = 0;
90 pNtPath->Buffer = NULL;
91
92 /*
93 * Convert the input to wide char.
94 */
95 Src.Buffer = (PCHAR)pszPath;
96 Src.MaximumLength = Src.Length = (USHORT)strlen(pszPath);
97
98 TmpUniStr.Length = 0;
99 TmpUniStr.MaximumLength = sizeof(wszTmp) - sizeof(WCHAR);
100 TmpUniStr.Buffer = wszTmp;
101
102 rcNt = g_pfnRtlAnsiStringToUnicodeString(&TmpUniStr, &Src, FALSE);
103 if (MY_NT_SUCCESS(rcNt))
104 {
105 if (TmpUniStr.Length > 0 && !(TmpUniStr.Length & 1))
106 {
107 wszTmp[TmpUniStr.Length / sizeof(WCHAR)] = '\0';
108
109 /*
110 * Convert the wide DOS path to an NT path.
111 */
112 if (g_pfnRtlDosPathNameToNtPathName_U(wszTmp, pNtPath, NULL, FALSE))
113 return 0;
114 }
115 rcNt = -1;
116 }
117 return birdSetErrnoFromNt(rcNt);
118}
119
120
121void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
122{
123 HeapFree(GetProcessHeap(), 0, pNtPath->Buffer);
124 pNtPath->Buffer = NULL;
125 pNtPath->Length = 0;
126 pNtPath->MaximumLength = 0;
127}
128
129
130MY_NTSTATUS birdOpenFileUniStr(MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
131 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
132 HANDLE *phFile)
133{
134 MY_IO_STATUS_BLOCK Ios;
135 MY_OBJECT_ATTRIBUTES ObjAttr;
136 MY_NTSTATUS rcNt;
137
138 birdResolveImports();
139
140 if ( (fCreateOptions & FILE_OPEN_REPARSE_POINT)
141 && g_fHaveOpenReparsePoint == 0)
142 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
143
144 Ios.Information = -1;
145 Ios.u.Status = 0;
146 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
147
148 rcNt = g_pfnNtCreateFile(phFile,
149 fDesiredAccess,
150 &ObjAttr,
151 &Ios,
152 NULL, /* cbFileInitialAlloc */
153 fFileAttribs,
154 fShareAccess,
155 fCreateDisposition,
156 fCreateOptions,
157 NULL, /* pEaBuffer */
158 0); /* cbEaBuffer*/
159 if ( rcNt == STATUS_INVALID_PARAMETER
160 && g_fHaveOpenReparsePoint < 0
161 && (fCreateOptions & FILE_OPEN_REPARSE_POINT))
162 {
163 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
164
165 Ios.Information = -1;
166 Ios.u.Status = 0;
167 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
168
169 rcNt = g_pfnNtCreateFile(phFile,
170 fDesiredAccess,
171 &ObjAttr,
172 &Ios,
173 NULL, /* cbFileInitialAlloc */
174 fFileAttribs,
175 fShareAccess,
176 fCreateDisposition,
177 fCreateOptions,
178 NULL, /* pEaBuffer */
179 0); /* cbEaBuffer*/
180 if (rcNt != STATUS_INVALID_PARAMETER)
181 g_fHaveOpenReparsePoint = 0;
182 }
183 return rcNt;
184}
185
186
187HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
188 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
189{
190 MY_UNICODE_STRING NtPath;
191 MY_NTSTATUS rcNt;
192
193 /*
194 * Adjust inputs.
195 */
196 if (birdIsPathDirSpec(pszPath))
197 fCreateOptions |= FILE_DIRECTORY_FILE;
198
199 /*
200 * Call the NT API directly.
201 */
202 if (birdDosToNtPath(pszPath, &NtPath) == 0)
203 {
204 HANDLE hFile;
205 rcNt = birdOpenFileUniStr(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
206 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
207 if (MY_NT_SUCCESS(rcNt))
208 {
209 birdFreeNtPath(&NtPath);
210 return hFile;
211 }
212
213 birdFreeNtPath(&NtPath);
214 birdSetErrnoFromNt(rcNt);
215 }
216
217 return INVALID_HANDLE_VALUE;
218}
219
220
221HANDLE birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess,
222 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
223 MY_UNICODE_STRING *pNameUniStr)
224{
225 MY_UNICODE_STRING NtPath;
226 MY_NTSTATUS rcNt;
227
228 /*
229 * Adjust inputs.
230 */
231 fCreateOptions |= FILE_DIRECTORY_FILE;
232
233 /*
234 * Convert the path and split off the filename.
235 */
236 if (birdDosToNtPath(pszPath, &NtPath) == 0)
237 {
238 USHORT offName = NtPath.Length / sizeof(WCHAR);
239 USHORT cwcName = offName;
240 WCHAR wc = 0;
241
242 while ( offName > 0
243 && (wc = NtPath.Buffer[offName - 1]) != '\\'
244 && wc != '/'
245 && wc != ':')
246 offName--;
247 if (offName > 0)
248 {
249 cwcName -= offName;
250
251 /* Make a copy of the file name, if requested. */
252 rcNt = STATUS_SUCCESS;
253 if (pNameUniStr)
254 {
255 pNameUniStr->Length = cwcName * sizeof(WCHAR);
256 pNameUniStr->MaximumLength = pNameUniStr->Length + sizeof(WCHAR);
257 pNameUniStr->Buffer = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, pNameUniStr->MaximumLength);
258 if (pNameUniStr->Buffer)
259 {
260 memcpy(pNameUniStr->Buffer, &NtPath.Buffer[offName],pNameUniStr->Length);
261 pNameUniStr->Buffer[cwcName] = '\0';
262 }
263 else
264 rcNt = STATUS_NO_MEMORY;
265 }
266
267 /* Chop, chop. */
268 // Bad idea, breaks \\?\c:\pagefile.sys. //while ( offName > 0
269 // Bad idea, breaks \\?\c:\pagefile.sys. // && ( (wc = NtPath.Buffer[offName - 1]) == '\\'
270 // Bad idea, breaks \\?\c:\pagefile.sys. // || wc == '/'))
271 // Bad idea, breaks \\?\c:\pagefile.sys. // offName--;
272 NtPath.Length = offName * sizeof(WCHAR);
273 NtPath.Buffer[offName] = '\0';
274 if (MY_NT_SUCCESS(rcNt))
275 {
276 /*
277 * Finally, try open the directory.
278 */
279 HANDLE hFile;
280 rcNt = birdOpenFileUniStr(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
281 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
282 if (MY_NT_SUCCESS(rcNt))
283 {
284 birdFreeNtPath(&NtPath);
285 return hFile;
286 }
287 }
288
289 if (pNameUniStr)
290 birdFreeNtPath(pNameUniStr);
291 }
292
293 birdFreeNtPath(&NtPath);
294 birdSetErrnoFromNt(rcNt);
295 }
296
297 return INVALID_HANDLE_VALUE;
298}
299
300
301void birdCloseFile(HANDLE hFile)
302{
303 birdResolveImports();
304 g_pfnNtClose(hFile);
305}
306
Note: See TracBrowser for help on using the repository browser.

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