VirtualBox

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

Last change on this file was 3504, checked in by bird, 3 years ago

ntunlink.c: Fixed deleteing read-only files. Respect the fReadOnlyToo parameter.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 7.9 KB
Line 
1/* $Id: ntunlink.c 3504 2021-12-15 22:50:14Z bird $ */
2/** @file
3 * MSC + NT unlink and variations.
4 */
5
6/*
7 * Copyright (c) 2005-2017 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
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(HANDLE hRoot, MY_UNICODE_STRING *pNtPath)
42{
43 MY_NTSTATUS rcNt;
44 HANDLE hFile;
45
46 rcNt = birdOpenFileUniStr(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 memset(&BasicInfo, 0, sizeof(BasicInfo));
64 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation);
65
66 if (MY_NT_SUCCESS(rcNt) && MY_NT_SUCCESS(Ios.u.Status) && BasicInfo.FileAttributes != FILE_ATTRIBUTE_READONLY)
67 dwAttr = BasicInfo.FileAttributes & ~FILE_ATTRIBUTE_READONLY;
68 else
69 dwAttr = FILE_ATTRIBUTE_NORMAL;
70 memset(&BasicInfo, 0, sizeof(BasicInfo));
71 BasicInfo.FileAttributes = dwAttr;
72
73 Ios.Information = -1;
74 Ios.u.Status = -1;
75 rcNt = g_pfnNtSetInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation);
76
77 birdCloseFile(hFile);
78 }
79
80 return rcNt;
81}
82
83
84static int birdUnlinkInternal(HANDLE hRoot, const char *pszFile, const wchar_t *pwszFile, int fReadOnlyToo, int fFast)
85{
86 MY_UNICODE_STRING NtPath;
87 int rc;
88
89 if (hRoot == INVALID_HANDLE_VALUE)
90 hRoot = NULL;
91 if (hRoot == NULL)
92 {
93 if (pwszFile)
94 rc = birdDosToNtPathW(pwszFile, &NtPath);
95 else
96 rc = birdDosToNtPath(pszFile, &NtPath);
97 }
98 else
99 {
100 if (pwszFile)
101 rc = birdDosToRelativeNtPathW(pwszFile, &NtPath);
102 else
103 rc = birdDosToRelativeNtPath(pszFile, &NtPath);
104 }
105 if (rc == 0)
106 {
107 MY_NTSTATUS rcNt;
108 if (fFast)
109 {
110 /* This uses FILE_DELETE_ON_CLOSE. Probably only suitable when in a hurry... */
111 MY_OBJECT_ATTRIBUTES ObjAttr;
112 MyInitializeObjectAttributes(&ObjAttr, &NtPath, OBJ_CASE_INSENSITIVE, hRoot, NULL /*pSecAttr*/);
113 rcNt = g_pfnNtDeleteFile(&ObjAttr);
114
115 /* In case some file system does things differently than NTFS. */
116 if (rcNt == STATUS_CANNOT_DELETE && fReadOnlyToo)
117 {
118 birdMakeWritable(hRoot, &NtPath);
119 rcNt = g_pfnNtDeleteFile(&ObjAttr);
120 }
121 }
122 else
123 {
124 /* Use the set information stuff. Probably more reliable. */
125 HANDLE hFile;
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 || !fReadOnlyToo)
152 break;
153
154 fReadOnlyToo = 0;
155 birdMakeWritable(hRoot, &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.

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