[2713] | 1 | /* $Id: ntunlink.c 3504 2021-12-15 22:50:14Z bird $ */
|
---|
| 2 | /** @file
|
---|
| 3 | * MSC + NT unlink and variations.
|
---|
| 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[3060] | 7 | * Copyright (c) 2005-2017 knut st. osmundsen <bird-kBuild-spamx@anduin.net>
|
---|
[2713] | 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 | *******************************************************************************/
|
---|
[3060] | 35 | #include "ntunlink.h"
|
---|
[2713] | 36 |
|
---|
| 37 | #include "ntstuff.h"
|
---|
| 38 | #include "nthlp.h"
|
---|
| 39 |
|
---|
| 40 |
|
---|
[3386] | 41 | static MY_NTSTATUS birdMakeWritable(HANDLE hRoot, MY_UNICODE_STRING *pNtPath)
|
---|
[2713] | 42 | {
|
---|
| 43 | MY_NTSTATUS rcNt;
|
---|
| 44 | HANDLE hFile;
|
---|
| 45 |
|
---|
[3386] | 46 | rcNt = birdOpenFileUniStr(hRoot,
|
---|
[2985] | 47 | pNtPath,
|
---|
[2713] | 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;
|
---|
[3388] | 63 | memset(&BasicInfo, 0, sizeof(BasicInfo));
|
---|
[2713] | 64 | rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation);
|
---|
| 65 |
|
---|
[3504] | 66 | if (MY_NT_SUCCESS(rcNt) && MY_NT_SUCCESS(Ios.u.Status) && BasicInfo.FileAttributes != FILE_ATTRIBUTE_READONLY)
|
---|
[2713] | 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 |
|
---|
[3009] | 84 | static int birdUnlinkInternal(HANDLE hRoot, const char *pszFile, const wchar_t *pwszFile, int fReadOnlyToo, int fFast)
|
---|
[2713] | 85 | {
|
---|
| 86 | MY_UNICODE_STRING NtPath;
|
---|
| 87 | int rc;
|
---|
| 88 |
|
---|
[2997] | 89 | if (hRoot == INVALID_HANDLE_VALUE)
|
---|
| 90 | hRoot = NULL;
|
---|
| 91 | if (hRoot == NULL)
|
---|
[3009] | 92 | {
|
---|
| 93 | if (pwszFile)
|
---|
| 94 | rc = birdDosToNtPathW(pwszFile, &NtPath);
|
---|
| 95 | else
|
---|
| 96 | rc = birdDosToNtPath(pszFile, &NtPath);
|
---|
| 97 | }
|
---|
[2997] | 98 | else
|
---|
[3009] | 99 | {
|
---|
| 100 | if (pwszFile)
|
---|
| 101 | rc = birdDosToRelativeNtPathW(pwszFile, &NtPath);
|
---|
| 102 | else
|
---|
| 103 | rc = birdDosToRelativeNtPath(pszFile, &NtPath);
|
---|
| 104 | }
|
---|
[2713] | 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;
|
---|
[2997] | 112 | MyInitializeObjectAttributes(&ObjAttr, &NtPath, OBJ_CASE_INSENSITIVE, hRoot, NULL /*pSecAttr*/);
|
---|
[2713] | 113 | rcNt = g_pfnNtDeleteFile(&ObjAttr);
|
---|
| 114 |
|
---|
| 115 | /* In case some file system does things differently than NTFS. */
|
---|
[3504] | 116 | if (rcNt == STATUS_CANNOT_DELETE && fReadOnlyToo)
|
---|
[2713] | 117 | {
|
---|
[3386] | 118 | birdMakeWritable(hRoot, &NtPath);
|
---|
[2713] | 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 | {
|
---|
[2997] | 128 | rcNt = birdOpenFileUniStr(hRoot,
|
---|
[2985] | 129 | &NtPath,
|
---|
[3126] | 130 | DELETE | SYNCHRONIZE,
|
---|
[2713] | 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 | }
|
---|
[3504] | 151 | if (rcNt != STATUS_CANNOT_DELETE || !fReadOnlyToo)
|
---|
[2713] | 152 | break;
|
---|
| 153 |
|
---|
[3504] | 154 | fReadOnlyToo = 0;
|
---|
[3386] | 155 | birdMakeWritable(hRoot, &NtPath);
|
---|
[2713] | 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 |
|
---|
| 170 | int birdUnlink(const char *pszFile)
|
---|
| 171 | {
|
---|
[3009] | 172 | return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
[2713] | 173 | }
|
---|
| 174 |
|
---|
| 175 |
|
---|
[3009] | 176 | int birdUnlinkW(const wchar_t *pwszFile)
|
---|
| 177 | {
|
---|
| 178 | return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pwszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
| 179 | }
|
---|
| 180 |
|
---|
| 181 |
|
---|
[2997] | 182 | int birdUnlinkEx(void *hRoot, const char *pszFile)
|
---|
| 183 | {
|
---|
[3009] | 184 | return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
[2997] | 185 | }
|
---|
| 186 |
|
---|
| 187 |
|
---|
[3009] | 188 | int birdUnlinkExW(void *hRoot, const wchar_t *pwszFile)
|
---|
| 189 | {
|
---|
| 190 | return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
| 191 | }
|
---|
| 192 |
|
---|
| 193 |
|
---|
[2713] | 194 | int birdUnlinkForced(const char *pszFile)
|
---|
| 195 | {
|
---|
[3009] | 196 | return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
[2713] | 197 | }
|
---|
| 198 |
|
---|
| 199 |
|
---|
[3009] | 200 | int birdUnlinkForcedW(const wchar_t *pwszFile)
|
---|
| 201 | {
|
---|
| 202 | return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
| 203 | }
|
---|
| 204 |
|
---|
| 205 |
|
---|
[2997] | 206 | int birdUnlinkForcedEx(void *hRoot, const char *pszFile)
|
---|
| 207 | {
|
---|
[3009] | 208 | return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
[2997] | 209 | }
|
---|
| 210 |
|
---|
| 211 |
|
---|
[3009] | 212 | int birdUnlinkForcedExW(void *hRoot, const wchar_t *pwszFile)
|
---|
| 213 | {
|
---|
| 214 | return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/);
|
---|
| 215 | }
|
---|
| 216 |
|
---|
| 217 |
|
---|
[2713] | 218 | int birdUnlinkForcedFast(const char *pszFile)
|
---|
| 219 | {
|
---|
[3009] | 220 | return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
|
---|
[2713] | 221 | }
|
---|
| 222 |
|
---|
[2997] | 223 |
|
---|
[3009] | 224 | int birdUnlinkForcedFastW(const wchar_t *pwszFile)
|
---|
| 225 | {
|
---|
| 226 | return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
|
---|
| 227 | }
|
---|
| 228 |
|
---|
| 229 |
|
---|
[2997] | 230 | int birdUnlinkForcedFastEx(void *hRoot, const char *pszFile)
|
---|
| 231 | {
|
---|
[3009] | 232 | return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
|
---|
[2997] | 233 | }
|
---|
| 234 |
|
---|
[3009] | 235 |
|
---|
| 236 | int birdUnlinkForcedFastExW(void *hRoot, const wchar_t *pwszFile)
|
---|
| 237 | {
|
---|
| 238 | return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/);
|
---|
| 239 | }
|
---|
| 240 |
|
---|