VirtualBox

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

Last change on this file since 2985 was 2985, checked in by bird, 9 years ago

lib/nt: Got fts-nt halfways working, quite a few NT interface changes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: nthlpfs.c 2985 2016-11-01 18:26:35Z 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#include <stddef.h>
37#include <string.h>
38#include <wchar.h>
39#include <errno.h>
40
41
42/*******************************************************************************
43* Global Variables *
44*******************************************************************************/
45static int g_fHaveOpenReparsePoint = -1;
46
47
48
49static int birdHasTrailingSlash(const char *pszPath)
50{
51 char ch, ch2;
52
53 /* Skip leading slashes. */
54 while ((ch = *pszPath) == '/' || ch == '\\')
55 pszPath++;
56 if (ch == '\0')
57 return 0;
58
59 /* Find the last char. */
60 while ((ch2 = *++pszPath) != '\0')
61 ch = ch2;
62
63 return ch == '/' || ch == '\\' || ch == ':';
64}
65
66
67static int birdHasTrailingSlashW(const wchar_t *pwszPath)
68{
69 wchar_t wc, wc2;
70
71 /* Skip leading slashes. */
72 while ((wc = *pwszPath) == '/' || wc == '\\')
73 pwszPath++;
74 if (wc == '\0')
75 return 0;
76
77 /* Find the last char. */
78 while ((wc2 = *++pwszPath) != '\0')
79 wc = wc2;
80
81 return wc == '/' || wc == '\\' || wc == ':';
82}
83
84
85static int birdIsPathDirSpec(const char *pszPath)
86{
87 char ch, ch2;
88
89 /* Check for empty string. */
90 ch = *pszPath;
91 if (ch == '\0')
92 return 0;
93
94 /* Find the last char. */
95 while ((ch2 = *++pszPath) != '\0')
96 ch = ch2;
97
98 return ch == '/' || ch == '\\' || ch == ':';
99}
100
101
102static int birdIsPathDirSpecW(const wchar_t *pwszPath)
103{
104 wchar_t wc, wc2;
105
106 /* Check for empty string. */
107 wc = *pwszPath;
108 if (wc == '\0')
109 return 0;
110
111 /* Find the last char. */
112 while ((wc2 = *++pwszPath) != '\0')
113 wc = wc2;
114
115 return wc == '/' || wc == '\\' || wc == ':';
116}
117
118
119int birdDosToNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
120{
121 MY_NTSTATUS rcNt;
122 WCHAR wszTmp[4096];
123 MY_UNICODE_STRING TmpUniStr;
124 MY_ANSI_STRING Src;
125
126 birdResolveImports();
127
128 pNtPath->Length = pNtPath->MaximumLength = 0;
129 pNtPath->Buffer = NULL;
130
131 /*
132 * Convert the input to wide char.
133 */
134 Src.Buffer = (PCHAR)pszPath;
135 Src.MaximumLength = Src.Length = (USHORT)strlen(pszPath);
136
137 TmpUniStr.Length = 0;
138 TmpUniStr.MaximumLength = sizeof(wszTmp) - sizeof(WCHAR);
139 TmpUniStr.Buffer = wszTmp;
140
141 rcNt = g_pfnRtlAnsiStringToUnicodeString(&TmpUniStr, &Src, FALSE);
142 if (MY_NT_SUCCESS(rcNt))
143 {
144 if (TmpUniStr.Length > 0 && !(TmpUniStr.Length & 1))
145 {
146 wszTmp[TmpUniStr.Length / sizeof(WCHAR)] = '\0';
147
148 /*
149 * Convert the wide DOS path to an NT path.
150 */
151 if (g_pfnRtlDosPathNameToNtPathName_U(wszTmp, pNtPath, NULL, FALSE))
152 return 0;
153 }
154 rcNt = -1;
155 }
156 return birdSetErrnoFromNt(rcNt);
157}
158
159
160int birdDosToNtPathW(const wchar_t *pwszPath, MY_UNICODE_STRING *pNtPath)
161{
162 birdResolveImports();
163
164 pNtPath->Length = pNtPath->MaximumLength = 0;
165 pNtPath->Buffer = NULL;
166
167 /*
168 * Convert the wide DOS path to an NT path.
169 */
170 if (g_pfnRtlDosPathNameToNtPathName_U(pwszPath, pNtPath, NULL, FALSE))
171 return 0;
172 return birdSetErrnoFromNt(STATUS_NO_MEMORY);
173}
174
175
176/**
177 * Converts UNIX slashes to DOS ones and trims trailing ones.
178 *
179 * @returns 0
180 * @param pNtPath The relative NT path to fix up.
181 */
182static int birdFixRelativeNtPathSlashesAndReturn0(MY_UNICODE_STRING *pNtPath)
183{
184 size_t cwcLeft = pNtPath->Length / sizeof(wchar_t);
185 wchar_t *pwcStart = pNtPath->Buffer;
186 wchar_t *pwcHit;
187
188 /* Convert slashes. */
189 while ((pwcHit = wmemchr(pwcStart, '/', cwcLeft)) != NULL)
190 {
191 *pwcHit = '\\';
192 cwcLeft -= pwcHit - pwcStart;
193 pwcHit = pwcStart;
194 }
195
196 /* Strip trailing slashes (NT doesn't like them). */
197 while ( pNtPath->Length >= sizeof(wchar_t)
198 && pNtPath->Buffer[(pNtPath->Length - sizeof(wchar_t)) / sizeof(wchar_t)] == '\\')
199 {
200 pNtPath->Length -= sizeof(wchar_t);
201 pNtPath->Buffer[pNtPath->Length / sizeof(wchar_t)] = '\0';
202 }
203
204 /* If it was all trailing slashes we convert it to a dot path. */
205 if ( pNtPath->Length == 0
206 && pNtPath->MaximumLength >= sizeof(wchar_t) * 2)
207 {
208 pNtPath->Length = sizeof(wchar_t);
209 pNtPath->Buffer[0] = '.';
210 pNtPath->Buffer[1] = '\0';
211 }
212
213 return 0;
214}
215
216
217/**
218 * Similar to birdDosToNtPath, but it does call RtlDosPathNameToNtPathName_U.
219 *
220 * @returns 0 on success, -1 + errno on failure.
221 * @param pszPath The relative path.
222 * @param pNtPath Where to return the NT path. Call birdFreeNtPath when done.
223 */
224int birdDosToRelativeNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
225{
226 MY_NTSTATUS rcNt;
227 MY_ANSI_STRING Src;
228
229 birdResolveImports();
230
231 /*
232 * Just convert to wide char.
233 */
234 pNtPath->Length = pNtPath->MaximumLength = 0;
235 pNtPath->Buffer = NULL;
236
237 Src.Buffer = (PCHAR)pszPath;
238 Src.MaximumLength = Src.Length = (USHORT)strlen(pszPath);
239
240 rcNt = g_pfnRtlAnsiStringToUnicodeString(pNtPath, &Src, TRUE /* Allocate */);
241 if (MY_NT_SUCCESS(rcNt))
242 return birdFixRelativeNtPathSlashesAndReturn0(pNtPath);
243 return birdSetErrnoFromNt(rcNt);
244}
245
246
247/**
248 * Similar to birdDosToNtPathW, but it does call RtlDosPathNameToNtPathName_U.
249 *
250 * @returns 0 on success, -1 + errno on failure.
251 * @param pwszPath The relative path.
252 * @param pNtPath Where to return the NT path. Call birdFreeNtPath when done.
253 */
254int birdDosToRelativeNtPathW(const wchar_t *pwszPath, MY_UNICODE_STRING *pNtPath)
255{
256 size_t cwcPath = wcslen(pwszPath);
257 if (cwcPath < 0xfffe)
258 {
259 pNtPath->Length = (USHORT)(cwcPath * sizeof(wchar_t));
260 pNtPath->MaximumLength = pNtPath->Length + sizeof(wchar_t);
261 pNtPath->Buffer = HeapAlloc(GetProcessHeap(), 0, pNtPath->MaximumLength);
262 if (pNtPath->Buffer)
263 {
264 memcpy(pNtPath->Buffer, pwszPath, pNtPath->MaximumLength);
265 return birdFixRelativeNtPathSlashesAndReturn0(pNtPath);
266 }
267 errno = ENOMEM;
268 }
269 else
270 errno = ENAMETOOLONG;
271 return -1;
272}
273
274
275/**
276 * Frees a string returned by birdDosToNtPath, birdDosToNtPathW or
277 * birdDosToRelativeNtPath.
278 *
279 * @param pNtPath The the NT path to free.
280 */
281void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
282{
283 HeapFree(GetProcessHeap(), 0, pNtPath->Buffer);
284 pNtPath->Buffer = NULL;
285 pNtPath->Length = 0;
286 pNtPath->MaximumLength = 0;
287}
288
289
290MY_NTSTATUS birdOpenFileUniStr(HANDLE hRoot, MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
291 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
292 HANDLE *phFile)
293{
294 MY_IO_STATUS_BLOCK Ios;
295 MY_OBJECT_ATTRIBUTES ObjAttr;
296 MY_NTSTATUS rcNt;
297
298 birdResolveImports();
299
300 if ( (fCreateOptions & FILE_OPEN_REPARSE_POINT)
301 && g_fHaveOpenReparsePoint == 0)
302 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
303
304 Ios.Information = -1;
305 Ios.u.Status = 0;
306 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, hRoot, NULL /*pSecAttr*/);
307
308 rcNt = g_pfnNtCreateFile(phFile,
309 fDesiredAccess,
310 &ObjAttr,
311 &Ios,
312 NULL, /* cbFileInitialAlloc */
313 fFileAttribs,
314 fShareAccess,
315 fCreateDisposition,
316 fCreateOptions,
317 NULL, /* pEaBuffer */
318 0); /* cbEaBuffer*/
319 if ( rcNt == STATUS_INVALID_PARAMETER
320 && g_fHaveOpenReparsePoint < 0
321 && (fCreateOptions & FILE_OPEN_REPARSE_POINT))
322 {
323 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
324
325 Ios.Information = -1;
326 Ios.u.Status = 0;
327 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
328
329 rcNt = g_pfnNtCreateFile(phFile,
330 fDesiredAccess,
331 &ObjAttr,
332 &Ios,
333 NULL, /* cbFileInitialAlloc */
334 fFileAttribs,
335 fShareAccess,
336 fCreateDisposition,
337 fCreateOptions,
338 NULL, /* pEaBuffer */
339 0); /* cbEaBuffer*/
340 if (rcNt != STATUS_INVALID_PARAMETER)
341 g_fHaveOpenReparsePoint = 0;
342 }
343 return rcNt;
344}
345
346
347HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
348 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
349{
350 MY_UNICODE_STRING NtPath;
351 MY_NTSTATUS rcNt;
352
353 /*
354 * Adjust inputs.
355 */
356 if (birdIsPathDirSpec(pszPath))
357 fCreateOptions |= FILE_DIRECTORY_FILE;
358
359 /*
360 * Convert the path and call birdOpenFileUniStr to do the real work.
361 */
362 if (birdDosToNtPath(pszPath, &NtPath) == 0)
363 {
364 HANDLE hFile;
365 rcNt = birdOpenFileUniStr(NULL /*hRoot*/, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
366 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
367 birdFreeNtPath(&NtPath);
368 if (MY_NT_SUCCESS(rcNt))
369 return hFile;
370 birdSetErrnoFromNt(rcNt);
371 }
372
373 return INVALID_HANDLE_VALUE;
374}
375
376
377HANDLE birdOpenFileW(const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
378 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
379{
380 MY_UNICODE_STRING NtPath;
381 MY_NTSTATUS rcNt;
382
383 /*
384 * Adjust inputs.
385 */
386 if (birdIsPathDirSpecW(pwszPath))
387 fCreateOptions |= FILE_DIRECTORY_FILE;
388
389 /*
390 * Convert the path and call birdOpenFileUniStr to do the real work.
391 */
392 if (birdDosToNtPathW(pwszPath, &NtPath) == 0)
393 {
394 HANDLE hFile;
395 rcNt = birdOpenFileUniStr(NULL /*hRoot*/, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
396 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
397 birdFreeNtPath(&NtPath);
398 if (MY_NT_SUCCESS(rcNt))
399 return hFile;
400 birdSetErrnoFromNt(rcNt);
401 }
402
403 return INVALID_HANDLE_VALUE;
404}
405
406
407HANDLE birdOpenFileEx(HANDLE hRoot, const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
408 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
409{
410 MY_UNICODE_STRING NtPath;
411 MY_NTSTATUS rcNt;
412
413 /*
414 * Adjust inputs.
415 */
416 if (birdIsPathDirSpec(pszPath))
417 fCreateOptions |= FILE_DIRECTORY_FILE;
418
419 /*
420 * Convert the path and call birdOpenFileUniStr to do the real work.
421 */
422 if (hRoot == INVALID_HANDLE_VALUE)
423 hRoot = NULL;
424 if ((hRoot != NULL ? birdDosToRelativeNtPath(pszPath, &NtPath) : birdDosToNtPath(pszPath, &NtPath)) == 0)
425 {
426 HANDLE hFile;
427 rcNt = birdOpenFileUniStr(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
428 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
429 birdFreeNtPath(&NtPath);
430 if (MY_NT_SUCCESS(rcNt))
431 return hFile;
432 birdSetErrnoFromNt(rcNt);
433 }
434
435 return INVALID_HANDLE_VALUE;
436}
437
438
439HANDLE birdOpenFileExW(HANDLE hRoot, const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
440 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
441{
442 MY_UNICODE_STRING NtPath;
443 MY_NTSTATUS rcNt;
444
445 /*
446 * Adjust inputs.
447 */
448 if (birdIsPathDirSpecW(pwszPath))
449 fCreateOptions |= FILE_DIRECTORY_FILE;
450
451 /*
452 * Convert the path (could save ourselves this if pwszPath is perfect) and
453 * call birdOpenFileUniStr to do the real work.
454 */
455 if (hRoot == INVALID_HANDLE_VALUE)
456 hRoot = NULL;
457 if ((hRoot != NULL ? birdDosToRelativeNtPathW(pwszPath, &NtPath) : birdDosToNtPathW(pwszPath, &NtPath)) == 0)
458 {
459 HANDLE hFile;
460 rcNt = birdOpenFileUniStr(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
461 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
462 birdFreeNtPath(&NtPath);
463 if (MY_NT_SUCCESS(rcNt))
464 return hFile;
465 birdSetErrnoFromNt(rcNt);
466 }
467
468 return INVALID_HANDLE_VALUE;
469}
470
471
472static HANDLE birdOpenParentDirCommon(HANDLE hRoot, MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
473 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
474 MY_UNICODE_STRING *pNameUniStr)
475{
476 MY_NTSTATUS rcNt;
477
478 /*
479 * Strip the path down to the directory.
480 */
481 USHORT offName = pNtPath->Length / sizeof(WCHAR);
482 USHORT cwcName = offName;
483 WCHAR wc = 0;
484 while ( offName > 0
485 && (wc = pNtPath->Buffer[offName - 1]) != '\\'
486 && wc != '/'
487 && wc != ':')
488 offName--;
489 if ( offName > 0
490 || (hRoot != NULL && cwcName > 0))
491 {
492 cwcName -= offName;
493
494 /* Make a copy of the file name, if requested. */
495 rcNt = STATUS_SUCCESS;
496 if (pNameUniStr)
497 {
498 pNameUniStr->Length = cwcName * sizeof(WCHAR);
499 pNameUniStr->MaximumLength = pNameUniStr->Length + sizeof(WCHAR);
500 pNameUniStr->Buffer = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, pNameUniStr->MaximumLength);
501 if (pNameUniStr->Buffer)
502 {
503 memcpy(pNameUniStr->Buffer, &pNtPath->Buffer[offName], pNameUniStr->Length);
504 pNameUniStr->Buffer[cwcName] = '\0';
505 }
506 else
507 rcNt = STATUS_NO_MEMORY;
508 }
509
510 /* Chop, chop. */
511 // Bad idea, breaks \\?\c:\pagefile.sys. //while ( offName > 0
512 // Bad idea, breaks \\?\c:\pagefile.sys. // && ( (wc = pNtPath->Buffer[offName - 1]) == '\\'
513 // Bad idea, breaks \\?\c:\pagefile.sys. // || wc == '/'))
514 // Bad idea, breaks \\?\c:\pagefile.sys. // offName--;
515 if (offName == 0)
516 pNtPath->Buffer[offName++] = '.'; /* Hack for dir handle + dir entry name. */
517 pNtPath->Length = offName * sizeof(WCHAR);
518 pNtPath->Buffer[offName] = '\0';
519 if (MY_NT_SUCCESS(rcNt))
520 {
521 /*
522 * Finally, try open the directory.
523 */
524 HANDLE hFile;
525 fCreateOptions |= FILE_DIRECTORY_FILE;
526 rcNt = birdOpenFileUniStr(hRoot, pNtPath, fDesiredAccess, fFileAttribs, fShareAccess,
527 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
528 if (MY_NT_SUCCESS(rcNt))
529 {
530 birdFreeNtPath(pNtPath);
531 return hFile;
532 }
533 }
534
535 if (pNameUniStr)
536 birdFreeNtPath(pNameUniStr);
537 }
538 else
539 rcNt = STATUS_INVALID_PARAMETER;
540
541 birdFreeNtPath(pNtPath);
542 birdSetErrnoFromNt(rcNt);
543 return INVALID_HANDLE_VALUE;
544}
545
546
547HANDLE birdOpenParentDir(HANDLE hRoot, const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
548 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
549 MY_UNICODE_STRING *pNameUniStr)
550{
551 /*
552 * Convert the path and join up with the UTF-16 version (it'll free NtPath).
553 */
554 MY_UNICODE_STRING NtPath;
555 if (hRoot == INVALID_HANDLE_VALUE)
556 hRoot = NULL;
557 if ( hRoot == NULL
558 ? birdDosToNtPath(pszPath, &NtPath) == 0
559 : birdDosToRelativeNtPath(pszPath, &NtPath) == 0)
560 return birdOpenParentDirCommon(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
561 fCreateDisposition, fCreateOptions, fObjAttribs, pNameUniStr);
562 return INVALID_HANDLE_VALUE;
563}
564
565
566HANDLE birdOpenParentDirW(HANDLE hRoot, const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
567 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
568 MY_UNICODE_STRING *pNameUniStr)
569{
570 /*
571 * Convert the path and join up with the ansi version (it'll free NtPath).
572 */
573 MY_UNICODE_STRING NtPath;
574 if (hRoot == INVALID_HANDLE_VALUE)
575 hRoot = NULL;
576 if ( hRoot == NULL
577 ? birdDosToNtPathW(pwszPath, &NtPath) == 0
578 : birdDosToRelativeNtPathW(pwszPath, &NtPath) == 0)
579 return birdOpenParentDirCommon(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
580 fCreateDisposition, fCreateOptions, fObjAttribs, pNameUniStr);
581 return INVALID_HANDLE_VALUE;
582}
583
584
585/**
586 * Returns a handle to the current working directory of the process.
587 *
588 * @returns CWD handle with FILE_TRAVERSE and SYNCHRONIZE access. May return
589 * INVALID_HANDLE_VALUE w/ errno for invalid CWD.
590 */
591HANDLE birdOpenCurrentDirectory(void)
592{
593 PMY_RTL_USER_PROCESS_PARAMETERS pProcParams;
594 MY_NTSTATUS rcNt;
595 HANDLE hRet = INVALID_HANDLE_VALUE;
596
597 birdResolveImports();
598
599 /*
600 * We'll try get this from the PEB.
601 */
602 g_pfnRtlAcquirePebLock();
603 pProcParams = (PMY_RTL_USER_PROCESS_PARAMETERS)MY_NT_CURRENT_PEB()->ProcessParameters;
604 if (pProcParams != NULL)
605 rcNt = g_pfnNtDuplicateObject(MY_NT_CURRENT_PROCESS, pProcParams->CurrentDirectory.Handle,
606 MY_NT_CURRENT_PROCESS, &hRet,
607 FILE_TRAVERSE | SYNCHRONIZE,
608 0 /*fAttribs*/,
609 0 /*fOptions*/);
610 else
611 rcNt = STATUS_INVALID_PARAMETER;
612 g_pfnRtlReleasePebLock();
613 if (MY_NT_SUCCESS(rcNt))
614 return hRet;
615
616 /*
617 * Fallback goes thru birdOpenFileW.
618 */
619 return birdOpenFileW(L".",
620 FILE_TRAVERSE | SYNCHRONIZE,
621 FILE_ATTRIBUTE_NORMAL,
622 FILE_SHARE_READ | FILE_SHARE_WRITE,
623 FILE_OPEN,
624 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
625 OBJ_CASE_INSENSITIVE);
626}
627
628
629void birdCloseFile(HANDLE hFile)
630{
631 birdResolveImports();
632 g_pfnNtClose(hFile);
633}
634
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