VirtualBox

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

Last change on this file since 3372 was 3223, checked in by bird, 7 years ago

nt/ntstat.c: Use NtQueryFullAttributesFile for implementing birdStatModTimeOnly instead of open+query+close, only using the latter if we encounter a reparse point.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: nthlpfs.c 3223 2018-03-31 02:29:56Z 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
85int 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.
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#if 0
197 /* Strip trailing slashes (NT doesn't like them). */
198 while ( pNtPath->Length >= sizeof(wchar_t)
199 && pNtPath->Buffer[(pNtPath->Length - sizeof(wchar_t)) / sizeof(wchar_t)] == '\\')
200 {
201 pNtPath->Length -= sizeof(wchar_t);
202 pNtPath->Buffer[pNtPath->Length / sizeof(wchar_t)] = '\0';
203 }
204
205 /* If it was all trailing slashes we convert it to a dot path. */
206 if ( pNtPath->Length == 0
207 && pNtPath->MaximumLength >= sizeof(wchar_t) * 2)
208 {
209 pNtPath->Length = sizeof(wchar_t);
210 pNtPath->Buffer[0] = '.';
211 pNtPath->Buffer[1] = '\0';
212 }
213#endif
214
215 return 0;
216}
217
218
219/**
220 * Similar to birdDosToNtPath, but it does call RtlDosPathNameToNtPathName_U.
221 *
222 * @returns 0 on success, -1 + errno on failure.
223 * @param pszPath The relative path.
224 * @param pNtPath Where to return the NT path. Call birdFreeNtPath when done.
225 */
226int birdDosToRelativeNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath)
227{
228 MY_NTSTATUS rcNt;
229 MY_ANSI_STRING Src;
230
231 birdResolveImports();
232
233 /*
234 * Just convert to wide char.
235 */
236 pNtPath->Length = pNtPath->MaximumLength = 0;
237 pNtPath->Buffer = NULL;
238
239 Src.Buffer = (PCHAR)pszPath;
240 Src.MaximumLength = Src.Length = (USHORT)strlen(pszPath);
241
242 rcNt = g_pfnRtlAnsiStringToUnicodeString(pNtPath, &Src, TRUE /* Allocate */);
243 if (MY_NT_SUCCESS(rcNt))
244 return birdFixRelativeNtPathSlashesAndReturn0(pNtPath);
245 return birdSetErrnoFromNt(rcNt);
246}
247
248
249/**
250 * Similar to birdDosToNtPathW, but it does call RtlDosPathNameToNtPathName_U.
251 *
252 * @returns 0 on success, -1 + errno on failure.
253 * @param pwszPath The relative path.
254 * @param pNtPath Where to return the NT path. Call birdFreeNtPath when done.
255 */
256int birdDosToRelativeNtPathW(const wchar_t *pwszPath, MY_UNICODE_STRING *pNtPath)
257{
258 size_t cwcPath = wcslen(pwszPath);
259 if (cwcPath < 0xfffe)
260 {
261 pNtPath->Length = (USHORT)(cwcPath * sizeof(wchar_t));
262 pNtPath->MaximumLength = pNtPath->Length + sizeof(wchar_t);
263 pNtPath->Buffer = HeapAlloc(GetProcessHeap(), 0, pNtPath->MaximumLength);
264 if (pNtPath->Buffer)
265 {
266 memcpy(pNtPath->Buffer, pwszPath, pNtPath->MaximumLength);
267 return birdFixRelativeNtPathSlashesAndReturn0(pNtPath);
268 }
269 errno = ENOMEM;
270 }
271 else
272 errno = ENAMETOOLONG;
273 return -1;
274}
275
276
277/**
278 * Frees a string returned by birdDosToNtPath, birdDosToNtPathW or
279 * birdDosToRelativeNtPath.
280 *
281 * @param pNtPath The the NT path to free.
282 */
283void birdFreeNtPath(MY_UNICODE_STRING *pNtPath)
284{
285 HeapFree(GetProcessHeap(), 0, pNtPath->Buffer);
286 pNtPath->Buffer = NULL;
287 pNtPath->Length = 0;
288 pNtPath->MaximumLength = 0;
289}
290
291
292MY_NTSTATUS birdOpenFileUniStr(HANDLE hRoot, MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
293 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
294 HANDLE *phFile)
295{
296 MY_IO_STATUS_BLOCK Ios;
297 MY_OBJECT_ATTRIBUTES ObjAttr;
298 MY_NTSTATUS rcNt;
299
300 birdResolveImports();
301
302 if ( (fCreateOptions & FILE_OPEN_REPARSE_POINT)
303 && g_fHaveOpenReparsePoint == 0)
304 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
305
306 Ios.Information = -1;
307 Ios.u.Status = 0;
308 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, hRoot, NULL /*pSecAttr*/);
309
310 rcNt = g_pfnNtCreateFile(phFile,
311 fDesiredAccess,
312 &ObjAttr,
313 &Ios,
314 NULL, /* cbFileInitialAlloc */
315 fFileAttribs,
316 fShareAccess,
317 fCreateDisposition,
318 fCreateOptions,
319 NULL, /* pEaBuffer */
320 0); /* cbEaBuffer*/
321 if ( rcNt == STATUS_INVALID_PARAMETER
322 && g_fHaveOpenReparsePoint < 0
323 && (fCreateOptions & FILE_OPEN_REPARSE_POINT))
324 {
325 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT;
326
327 Ios.Information = -1;
328 Ios.u.Status = 0;
329 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/);
330
331 rcNt = g_pfnNtCreateFile(phFile,
332 fDesiredAccess,
333 &ObjAttr,
334 &Ios,
335 NULL, /* cbFileInitialAlloc */
336 fFileAttribs,
337 fShareAccess,
338 fCreateDisposition,
339 fCreateOptions,
340 NULL, /* pEaBuffer */
341 0); /* cbEaBuffer*/
342 if (rcNt != STATUS_INVALID_PARAMETER)
343 g_fHaveOpenReparsePoint = 0;
344 }
345 return rcNt;
346}
347
348
349HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
350 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
351{
352 MY_UNICODE_STRING NtPath;
353 MY_NTSTATUS rcNt;
354
355 /*
356 * Adjust inputs.
357 */
358 if (birdIsPathDirSpec(pszPath))
359 fCreateOptions |= FILE_DIRECTORY_FILE;
360
361 /*
362 * Convert the path and call birdOpenFileUniStr to do the real work.
363 */
364 if (birdDosToNtPath(pszPath, &NtPath) == 0)
365 {
366 HANDLE hFile;
367 rcNt = birdOpenFileUniStr(NULL /*hRoot*/, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
368 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
369 birdFreeNtPath(&NtPath);
370 if (MY_NT_SUCCESS(rcNt))
371 return hFile;
372 birdSetErrnoFromNt(rcNt);
373 }
374
375 return INVALID_HANDLE_VALUE;
376}
377
378
379HANDLE birdOpenFileW(const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
380 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
381{
382 MY_UNICODE_STRING NtPath;
383 MY_NTSTATUS rcNt;
384
385 /*
386 * Adjust inputs.
387 */
388 if (birdIsPathDirSpecW(pwszPath))
389 fCreateOptions |= FILE_DIRECTORY_FILE;
390
391 /*
392 * Convert the path and call birdOpenFileUniStr to do the real work.
393 */
394 if (birdDosToNtPathW(pwszPath, &NtPath) == 0)
395 {
396 HANDLE hFile;
397 rcNt = birdOpenFileUniStr(NULL /*hRoot*/, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
398 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
399 birdFreeNtPath(&NtPath);
400 if (MY_NT_SUCCESS(rcNt))
401 return hFile;
402 birdSetErrnoFromNt(rcNt);
403 }
404
405 return INVALID_HANDLE_VALUE;
406}
407
408
409HANDLE birdOpenFileEx(HANDLE hRoot, const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
410 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
411{
412 MY_UNICODE_STRING NtPath;
413 MY_NTSTATUS rcNt;
414
415 /*
416 * Adjust inputs.
417 */
418 if (birdIsPathDirSpec(pszPath))
419 fCreateOptions |= FILE_DIRECTORY_FILE;
420
421 /*
422 * Convert the path and call birdOpenFileUniStr to do the real work.
423 */
424 if (hRoot == INVALID_HANDLE_VALUE)
425 hRoot = NULL;
426 if ((hRoot != NULL ? birdDosToRelativeNtPath(pszPath, &NtPath) : birdDosToNtPath(pszPath, &NtPath)) == 0)
427 {
428 HANDLE hFile;
429 rcNt = birdOpenFileUniStr(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
430 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
431 birdFreeNtPath(&NtPath);
432 if (MY_NT_SUCCESS(rcNt))
433 return hFile;
434 birdSetErrnoFromNt(rcNt);
435 }
436
437 return INVALID_HANDLE_VALUE;
438}
439
440
441HANDLE birdOpenFileExW(HANDLE hRoot, const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
442 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs)
443{
444 MY_UNICODE_STRING NtPath;
445 MY_NTSTATUS rcNt;
446
447 /*
448 * Adjust inputs.
449 */
450 if (birdIsPathDirSpecW(pwszPath))
451 fCreateOptions |= FILE_DIRECTORY_FILE;
452
453 /*
454 * Convert the path (could save ourselves this if pwszPath is perfect) and
455 * call birdOpenFileUniStr to do the real work.
456 */
457 if (hRoot == INVALID_HANDLE_VALUE)
458 hRoot = NULL;
459 if ((hRoot != NULL ? birdDosToRelativeNtPathW(pwszPath, &NtPath) : birdDosToNtPathW(pwszPath, &NtPath)) == 0)
460 {
461 HANDLE hFile;
462 rcNt = birdOpenFileUniStr(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
463 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
464 birdFreeNtPath(&NtPath);
465 if (MY_NT_SUCCESS(rcNt))
466 return hFile;
467 birdSetErrnoFromNt(rcNt);
468 }
469
470 return INVALID_HANDLE_VALUE;
471}
472
473
474static HANDLE birdOpenParentDirCommon(HANDLE hRoot, MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
475 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
476 MY_UNICODE_STRING *pNameUniStr)
477{
478 MY_NTSTATUS rcNt;
479
480 /*
481 * Strip the path down to the directory.
482 */
483 USHORT offName = pNtPath->Length / sizeof(WCHAR);
484 USHORT cwcName = offName;
485 WCHAR wc = 0;
486 while ( offName > 0
487 && (wc = pNtPath->Buffer[offName - 1]) != '\\'
488 && wc != '/'
489 && wc != ':')
490 offName--;
491 if ( offName > 0
492 || (hRoot != NULL && cwcName > 0))
493 {
494 cwcName -= offName;
495
496 /* Make a copy of the file name, if requested. */
497 rcNt = STATUS_SUCCESS;
498 if (pNameUniStr)
499 {
500 pNameUniStr->Length = cwcName * sizeof(WCHAR);
501 pNameUniStr->MaximumLength = pNameUniStr->Length + sizeof(WCHAR);
502 pNameUniStr->Buffer = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, pNameUniStr->MaximumLength);
503 if (pNameUniStr->Buffer)
504 {
505 memcpy(pNameUniStr->Buffer, &pNtPath->Buffer[offName], pNameUniStr->Length);
506 pNameUniStr->Buffer[cwcName] = '\0';
507 }
508 else
509 rcNt = STATUS_NO_MEMORY;
510 }
511
512 /* Chop, chop. */
513 // Bad idea, breaks \\?\c:\pagefile.sys. //while ( offName > 0
514 // Bad idea, breaks \\?\c:\pagefile.sys. // && ( (wc = pNtPath->Buffer[offName - 1]) == '\\'
515 // Bad idea, breaks \\?\c:\pagefile.sys. // || wc == '/'))
516 // Bad idea, breaks \\?\c:\pagefile.sys. // offName--;
517 if (offName == 0)
518 pNtPath->Buffer[offName++] = '.'; /* Hack for dir handle + dir entry name. */
519 pNtPath->Length = offName * sizeof(WCHAR);
520 pNtPath->Buffer[offName] = '\0';
521 if (MY_NT_SUCCESS(rcNt))
522 {
523 /*
524 * Finally, try open the directory.
525 */
526 HANDLE hFile;
527 fCreateOptions |= FILE_DIRECTORY_FILE;
528 rcNt = birdOpenFileUniStr(hRoot, pNtPath, fDesiredAccess, fFileAttribs, fShareAccess,
529 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile);
530 if (MY_NT_SUCCESS(rcNt))
531 {
532 birdFreeNtPath(pNtPath);
533 return hFile;
534 }
535 }
536
537 if (pNameUniStr)
538 birdFreeNtPath(pNameUniStr);
539 }
540 else
541 rcNt = STATUS_INVALID_PARAMETER;
542
543 birdFreeNtPath(pNtPath);
544 birdSetErrnoFromNt(rcNt);
545 return INVALID_HANDLE_VALUE;
546}
547
548
549HANDLE birdOpenParentDir(HANDLE hRoot, const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
550 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
551 MY_UNICODE_STRING *pNameUniStr)
552{
553 /*
554 * Convert the path and join up with the UTF-16 version (it'll free NtPath).
555 */
556 MY_UNICODE_STRING NtPath;
557 if (hRoot == INVALID_HANDLE_VALUE)
558 hRoot = NULL;
559 if ( hRoot == NULL
560 ? birdDosToNtPath(pszPath, &NtPath) == 0
561 : birdDosToRelativeNtPath(pszPath, &NtPath) == 0)
562 return birdOpenParentDirCommon(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
563 fCreateDisposition, fCreateOptions, fObjAttribs, pNameUniStr);
564 return INVALID_HANDLE_VALUE;
565}
566
567
568HANDLE birdOpenParentDirW(HANDLE hRoot, const wchar_t *pwszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs,
569 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs,
570 MY_UNICODE_STRING *pNameUniStr)
571{
572 /*
573 * Convert the path and join up with the ansi version (it'll free NtPath).
574 */
575 MY_UNICODE_STRING NtPath;
576 if (hRoot == INVALID_HANDLE_VALUE)
577 hRoot = NULL;
578 if ( hRoot == NULL
579 ? birdDosToNtPathW(pwszPath, &NtPath) == 0
580 : birdDosToRelativeNtPathW(pwszPath, &NtPath) == 0)
581 return birdOpenParentDirCommon(hRoot, &NtPath, fDesiredAccess, fFileAttribs, fShareAccess,
582 fCreateDisposition, fCreateOptions, fObjAttribs, pNameUniStr);
583 return INVALID_HANDLE_VALUE;
584}
585
586
587/**
588 * Returns a handle to the current working directory of the process.
589 *
590 * @returns CWD handle with FILE_TRAVERSE and SYNCHRONIZE access. May return
591 * INVALID_HANDLE_VALUE w/ errno for invalid CWD.
592 */
593HANDLE birdOpenCurrentDirectory(void)
594{
595 PMY_RTL_USER_PROCESS_PARAMETERS pProcParams;
596 MY_NTSTATUS rcNt;
597 HANDLE hRet = INVALID_HANDLE_VALUE;
598
599 birdResolveImports();
600
601 /*
602 * We'll try get this from the PEB.
603 */
604 g_pfnRtlAcquirePebLock();
605 pProcParams = (PMY_RTL_USER_PROCESS_PARAMETERS)MY_NT_CURRENT_PEB()->ProcessParameters;
606 if (pProcParams != NULL)
607 rcNt = g_pfnNtDuplicateObject(MY_NT_CURRENT_PROCESS, pProcParams->CurrentDirectory.Handle,
608 MY_NT_CURRENT_PROCESS, &hRet,
609 FILE_TRAVERSE | SYNCHRONIZE,
610 0 /*fAttribs*/,
611 0 /*fOptions*/);
612 else
613 rcNt = STATUS_INVALID_PARAMETER;
614 g_pfnRtlReleasePebLock();
615 if (MY_NT_SUCCESS(rcNt))
616 return hRet;
617
618 /*
619 * Fallback goes thru birdOpenFileW.
620 */
621 return birdOpenFileW(L".",
622 FILE_TRAVERSE | SYNCHRONIZE,
623 FILE_ATTRIBUTE_NORMAL,
624 FILE_SHARE_READ | FILE_SHARE_WRITE,
625 FILE_OPEN,
626 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
627 OBJ_CASE_INSENSITIVE);
628}
629
630
631void birdCloseFile(HANDLE hFile)
632{
633 birdResolveImports();
634 g_pfnNtClose(hFile);
635}
636
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