VirtualBox

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

Last change on this file since 3021 was 3009, checked in by bird, 8 years ago

ntunlink: W apis.

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