VirtualBox

source: kBuild/trunk/src/lib/nt/ntunlink.c@ 3126

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

ntunlink.h: Almost looks like we need SYNCHRONIZE as well as DELETE when deleting files using NtCreateFile.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.8 KB
Line 
1/* $Id: ntunlink.c 3126 2017-11-16 16:05:25Z bird $ */
2/** @file
3 * MSC + NT unlink and variations.
4 */
5
6/*
7 * Copyright (c) 2005-2017 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 "ntunlink.h"
36
37#include "ntstuff.h"
38#include "nthlp.h"
39
40
41static MY_NTSTATUS birdMakeWritable(MY_UNICODE_STRING *pNtPath)
42{
43 MY_NTSTATUS rcNt;
44 HANDLE hFile;
45
46 rcNt = birdOpenFileUniStr(NULL /*hRoot*/,
47 pNtPath,
48 FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | SYNCHRONIZE,
49 FILE_ATTRIBUTE_NORMAL,
50 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
51 FILE_OPEN,
52 FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT,
53 OBJ_CASE_INSENSITIVE,
54 &hFile);
55 if (MY_NT_SUCCESS(rcNt))
56 {
57 MY_FILE_BASIC_INFORMATION BasicInfo;
58 MY_IO_STATUS_BLOCK Ios;
59 DWORD dwAttr;
60
61 Ios.Information = -1;
62 Ios.u.Status = -1;
63 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation);
64
65 if (MY_NT_SUCCESS(rcNt) && MY_NT_SUCCESS(Ios.u.Status))
66 dwAttr = BasicInfo.FileAttributes & ~FILE_ATTRIBUTE_READONLY;
67 else
68 dwAttr = FILE_ATTRIBUTE_NORMAL;
69 memset(&BasicInfo, 0, sizeof(BasicInfo));
70 BasicInfo.FileAttributes = dwAttr;
71
72 Ios.Information = -1;
73 Ios.u.Status = -1;
74 rcNt = g_pfnNtSetInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation);
75
76 birdCloseFile(hFile);
77 }
78
79 return rcNt;
80}
81
82
83static int birdUnlinkInternal(HANDLE hRoot, const char *pszFile, const wchar_t *pwszFile, int fReadOnlyToo, int fFast)
84{
85 MY_UNICODE_STRING NtPath;
86 int rc;
87
88 if (hRoot == INVALID_HANDLE_VALUE)
89 hRoot = NULL;
90 if (hRoot == NULL)
91 {
92 if (pwszFile)
93 rc = birdDosToNtPathW(pwszFile, &NtPath);
94 else
95 rc = birdDosToNtPath(pszFile, &NtPath);
96 }
97 else
98 {
99 if (pwszFile)
100 rc = birdDosToRelativeNtPathW(pwszFile, &NtPath);
101 else
102 rc = birdDosToRelativeNtPath(pszFile, &NtPath);
103 }
104 if (rc == 0)
105 {
106 MY_NTSTATUS rcNt;
107 if (fFast)
108 {
109 /* This uses FILE_DELETE_ON_CLOSE. Probably only suitable when in a hurry... */
110 MY_OBJECT_ATTRIBUTES ObjAttr;
111 MyInitializeObjectAttributes(&ObjAttr, &NtPath, OBJ_CASE_INSENSITIVE, hRoot, NULL /*pSecAttr*/);
112 rcNt = g_pfnNtDeleteFile(&ObjAttr);
113
114 /* In case some file system does things differently than NTFS. */
115 if (rcNt == STATUS_CANNOT_DELETE)
116 {
117 birdMakeWritable(&NtPath);
118 rcNt = g_pfnNtDeleteFile(&ObjAttr);
119 }
120 }
121 else
122 {
123 /* Use the set information stuff. Probably more reliable. */
124 HANDLE hFile;
125 int fMayTryAgain = 1;
126 for (;;)
127 {
128 rcNt = birdOpenFileUniStr(hRoot,
129 &NtPath,
130 DELETE | SYNCHRONIZE,
131 FILE_ATTRIBUTE_NORMAL,
132 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
133 FILE_OPEN,
134 FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT,
135 OBJ_CASE_INSENSITIVE,
136 &hFile);
137 if (MY_NT_SUCCESS(rcNt))
138 {
139 MY_FILE_DISPOSITION_INFORMATION DispInfo;
140 MY_IO_STATUS_BLOCK Ios;
141
142 DispInfo.DeleteFile = TRUE;
143
144 Ios.Information = -1;
145 Ios.u.Status = -1;
146
147 rcNt = g_pfnNtSetInformationFile(hFile, &Ios, &DispInfo, sizeof(DispInfo), MyFileDispositionInformation);
148
149 birdCloseFile(hFile);
150 }
151 if (rcNt != STATUS_CANNOT_DELETE || !fMayTryAgain)
152 break;
153
154 fMayTryAgain = 0;
155 birdMakeWritable(&NtPath);
156 }
157 }
158
159 birdFreeNtPath(&NtPath);
160
161 if (MY_NT_SUCCESS(rcNt))
162 rc = 0;
163 else
164 rc = birdSetErrnoFromNt(rcNt);
165 }
166 return rc;
167}
168
169
170int birdUnlink(const char *pszFile)
171{
172 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
173}
174
175
176int birdUnlinkW(const wchar_t *pwszFile)
177{
178 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pwszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
179}
180
181
182int birdUnlinkEx(void *hRoot, const char *pszFile)
183{
184 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
185}
186
187
188int birdUnlinkExW(void *hRoot, const wchar_t *pwszFile)
189{
190 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
191}
192
193
194int birdUnlinkForced(const char *pszFile)
195{
196 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
197}
198
199
200int birdUnlinkForcedW(const wchar_t *pwszFile)
201{
202 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
203}
204
205
206int birdUnlinkForcedEx(void *hRoot, const char *pszFile)
207{
208 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
209}
210
211
212int birdUnlinkForcedExW(void *hRoot, const wchar_t *pwszFile)
213{
214 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
215}
216
217
218int birdUnlinkForcedFast(const char *pszFile)
219{
220 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
221}
222
223
224int birdUnlinkForcedFastW(const wchar_t *pwszFile)
225{
226 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
227}
228
229
230int birdUnlinkForcedFastEx(void *hRoot, const char *pszFile)
231{
232 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
233}
234
235
236int birdUnlinkForcedFastExW(void *hRoot, const wchar_t *pwszFile)
237{
238 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
239}
240
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