diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:21:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-11 08:21:29 +0000 |
commit | 29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc (patch) | |
tree | 63ef546b10a81d461e5cf5ed9e98a68cd7dee1aa /src/lib/nt/ntunlink.c | |
parent | Initial commit. (diff) | |
download | kbuild-29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc.tar.xz kbuild-29cd838eab01ed7110f3ccb2e8c6a35c8a31dbcc.zip |
Adding upstream version 1:0.1.9998svn3589+dfsg.upstream/1%0.1.9998svn3589+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/lib/nt/ntunlink.c')
-rw-r--r-- | src/lib/nt/ntunlink.c | 240 |
1 files changed, 240 insertions, 0 deletions
diff --git a/src/lib/nt/ntunlink.c b/src/lib/nt/ntunlink.c new file mode 100644 index 0000000..8d037d5 --- /dev/null +++ b/src/lib/nt/ntunlink.c @@ -0,0 +1,240 @@ +/* $Id: ntunlink.c 3504 2021-12-15 22:50:14Z bird $ */ +/** @file + * MSC + NT unlink and variations. + */ + +/* + * Copyright (c) 2005-2017 knut st. osmundsen <bird-kBuild-spamx@anduin.net> + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Alternatively, the content of this file may be used under the terms of the + * GPL version 2 or later, or LGPL version 2.1 or later. + */ + + +/******************************************************************************* +* Header Files * +*******************************************************************************/ +#include "ntunlink.h" + +#include "ntstuff.h" +#include "nthlp.h" + + +static MY_NTSTATUS birdMakeWritable(HANDLE hRoot, MY_UNICODE_STRING *pNtPath) +{ + MY_NTSTATUS rcNt; + HANDLE hFile; + + rcNt = birdOpenFileUniStr(hRoot, + pNtPath, + FILE_WRITE_ATTRIBUTES | FILE_READ_ATTRIBUTES | SYNCHRONIZE, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, + OBJ_CASE_INSENSITIVE, + &hFile); + if (MY_NT_SUCCESS(rcNt)) + { + MY_FILE_BASIC_INFORMATION BasicInfo; + MY_IO_STATUS_BLOCK Ios; + DWORD dwAttr; + + Ios.Information = -1; + Ios.u.Status = -1; + memset(&BasicInfo, 0, sizeof(BasicInfo)); + rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation); + + if (MY_NT_SUCCESS(rcNt) && MY_NT_SUCCESS(Ios.u.Status) && BasicInfo.FileAttributes != FILE_ATTRIBUTE_READONLY) + dwAttr = BasicInfo.FileAttributes & ~FILE_ATTRIBUTE_READONLY; + else + dwAttr = FILE_ATTRIBUTE_NORMAL; + memset(&BasicInfo, 0, sizeof(BasicInfo)); + BasicInfo.FileAttributes = dwAttr; + + Ios.Information = -1; + Ios.u.Status = -1; + rcNt = g_pfnNtSetInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation); + + birdCloseFile(hFile); + } + + return rcNt; +} + + +static int birdUnlinkInternal(HANDLE hRoot, const char *pszFile, const wchar_t *pwszFile, int fReadOnlyToo, int fFast) +{ + MY_UNICODE_STRING NtPath; + int rc; + + if (hRoot == INVALID_HANDLE_VALUE) + hRoot = NULL; + if (hRoot == NULL) + { + if (pwszFile) + rc = birdDosToNtPathW(pwszFile, &NtPath); + else + rc = birdDosToNtPath(pszFile, &NtPath); + } + else + { + if (pwszFile) + rc = birdDosToRelativeNtPathW(pwszFile, &NtPath); + else + rc = birdDosToRelativeNtPath(pszFile, &NtPath); + } + if (rc == 0) + { + MY_NTSTATUS rcNt; + if (fFast) + { + /* This uses FILE_DELETE_ON_CLOSE. Probably only suitable when in a hurry... */ + MY_OBJECT_ATTRIBUTES ObjAttr; + MyInitializeObjectAttributes(&ObjAttr, &NtPath, OBJ_CASE_INSENSITIVE, hRoot, NULL /*pSecAttr*/); + rcNt = g_pfnNtDeleteFile(&ObjAttr); + + /* In case some file system does things differently than NTFS. */ + if (rcNt == STATUS_CANNOT_DELETE && fReadOnlyToo) + { + birdMakeWritable(hRoot, &NtPath); + rcNt = g_pfnNtDeleteFile(&ObjAttr); + } + } + else + { + /* Use the set information stuff. Probably more reliable. */ + HANDLE hFile; + for (;;) + { + rcNt = birdOpenFileUniStr(hRoot, + &NtPath, + DELETE | SYNCHRONIZE, + FILE_ATTRIBUTE_NORMAL, + FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT, + OBJ_CASE_INSENSITIVE, + &hFile); + if (MY_NT_SUCCESS(rcNt)) + { + MY_FILE_DISPOSITION_INFORMATION DispInfo; + MY_IO_STATUS_BLOCK Ios; + + DispInfo.DeleteFile = TRUE; + + Ios.Information = -1; + Ios.u.Status = -1; + + rcNt = g_pfnNtSetInformationFile(hFile, &Ios, &DispInfo, sizeof(DispInfo), MyFileDispositionInformation); + + birdCloseFile(hFile); + } + if (rcNt != STATUS_CANNOT_DELETE || !fReadOnlyToo) + break; + + fReadOnlyToo = 0; + birdMakeWritable(hRoot, &NtPath); + } + } + + birdFreeNtPath(&NtPath); + + if (MY_NT_SUCCESS(rcNt)) + rc = 0; + else + rc = birdSetErrnoFromNt(rcNt); + } + return rc; +} + + +int birdUnlink(const char *pszFile) +{ + return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkW(const wchar_t *pwszFile) +{ + return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pwszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkEx(void *hRoot, const char *pszFile) +{ + return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkExW(void *hRoot, const wchar_t *pwszFile) +{ + return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkForced(const char *pszFile) +{ + return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkForcedW(const wchar_t *pwszFile) +{ + return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkForcedEx(void *hRoot, const char *pszFile) +{ + return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkForcedExW(void *hRoot, const wchar_t *pwszFile) +{ + return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/); +} + + +int birdUnlinkForcedFast(const char *pszFile) +{ + return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/); +} + + +int birdUnlinkForcedFastW(const wchar_t *pwszFile) +{ + return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/); +} + + +int birdUnlinkForcedFastEx(void *hRoot, const char *pszFile) +{ + return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/); +} + + +int birdUnlinkForcedFastExW(void *hRoot, const wchar_t *pwszFile) +{ + return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/); +} + |