- Timestamp:
- Aug 13, 2025, 1:34:19 AM (4 weeks ago)
- Location:
- trunk/src
- Files:
-
- 4 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/mscfakes.c
r3636 r3682 44 44 #undef utimes 45 45 #undef lutimes 46 #include "nt/ntmkdirat.h" 47 #undef mkdir 48 #undef mkdirat 46 49 47 50 #include "console.h" … … 314 317 int mkdir_msc(const char *path, mode_t mode) 315 318 { 319 #if 0 316 320 int rc = (mkdir)(path); 317 321 if (rc) … … 328 332 } 329 333 return rc; 334 #else 335 return birdMkDir(path, mode); 336 #endif 330 337 } 331 338 -
trunk/src/kmk/kmkbuiltin/mscfakes.h
r3636 r3682 50 50 #include <stdio.h> /* unlink for UCRT */ 51 51 #include "nt/ntstat.h" 52 #include "nt/ntunlink.h" 52 #include "nt/ntunlink.h" /* redefines both unlink and rmdir */ 53 53 #ifdef MSC_DO_64_BIT_IO 54 54 # if _MSC_VER >= 1400 /* We want 64-bit file lengths here when possible. */ … … 61 61 62 62 #undef PATH_MAX 63 #define PATH_MAX _MAX_PATH 63 /*#define PATH_MAX _MAX_PATH */ 64 #define PATH_MAX 1024 64 65 #undef MAXPATHLEN 65 #define MAXPATHLEN _MAX_PATH66 #define MAXPATHLEN PATH_MAX 66 67 67 68 #define EX_OK 0 … … 146 147 #define readlink(link, buf, size) -1 147 148 #define reallocf(old, size) realloc(old, size) 148 int rmdir_msc(const char *path);149 #define rmdir(path) rmdir_msc(path) 149 /*int rmdir_msc(const char *path); 150 #define rmdir(path) rmdir_msc(path) */ 150 151 intmax_t strtoimax(const char *nptr, char **endptr, int base); 151 152 uintmax_t strtoumax(const char *nptr, char **endptr, int base); -
trunk/src/kmk/kmkbuiltin/rm.c
r3618 r3682 82 82 # include "mscfakes.h" 83 83 # endif 84 # include "nt/ntunlink.h" 85 /* Use the special unlink implementation to do rmdir too. */ 86 # undef rmdir 87 # define rmdir(a_pszPath) birdUnlinkForced(a_pszPath) 84 # include "nt/ntunlink.h" /* redefines both unlink & rmdir */ 88 85 #endif 89 86 #if defined(__OS2__) || defined(_MSC_VER) … … 430 427 #ifdef KBUILD_OS_WINDOWS 431 428 if (p->fts_parent->fts_dirfd != NT_FTS_INVALID_HANDLE_VALUE) { 432 rval = bird UnlinkForcedEx(p->fts_parent->fts_dirfd, p->fts_name);429 rval = birdRmDirForcedEx(p->fts_parent->fts_dirfd, p->fts_name); 433 430 } else { 434 rval = bird UnlinkForced(p->fts_accpath);431 rval = birdRmDirForced(p->fts_accpath); 435 432 } 436 433 #else … … 480 477 rval = birdUnlinkForcedFastEx(p->fts_parent->fts_dirfd, p->fts_name); 481 478 } else { /* NtDeleteFile doesn't work on directory links, so slow symlink deletion: */ 482 rval = birdUnlinkForcedEx(p->fts_parent->fts_dirfd, p->fts_name); 479 if (p->fts_stat.st_isdirsymlink) { 480 rval = birdRmDirForcedEx(p->fts_parent->fts_dirfd, p->fts_name); 481 } else { 482 rval = birdUnlinkForcedEx(p->fts_parent->fts_dirfd, p->fts_name); 483 } 483 484 } 484 485 } else { … … 486 487 rval = birdUnlinkForcedFast(p->fts_accpath); 487 488 } else { /* NtDeleteFile doesn't work on directory links, so slow symlink deletion: */ 488 rval = birdUnlinkForced(p->fts_accpath); 489 if (p->fts_stat.st_isdirsymlink) { 490 rval = birdRmDirForced(p->fts_accpath); 491 } else { 492 rval = birdUnlinkForced(p->fts_accpath); 493 } 489 494 } 490 495 } … … 586 591 operation = "unlink"; 587 592 #else 588 if (pThis->fUseNtDeleteFile) { 593 /*if (sb.st_isdirsymlink) { 594 rval = birdRmDirForced(f); 595 operation = "rmdir"; 596 } else*/ if (pThis->fUseNtDeleteFile /*&& S_ISREG(sb.st_mode) && !sb.st_isdirsymlink*/) { 589 597 rval = birdUnlinkForcedFast(f); 590 598 operation = "NtDeleteFile"; -
trunk/src/lib/Makefile.kmk
r3551 r3682 56 56 nt/nthlpfs.c \ 57 57 nt/ntdir.c \ 58 nt/ntmkdirat.c \ 59 nt/ntopenat.c \ 58 60 nt/ntstat.c \ 59 61 nt/ntunlink.c \ -
trunk/src/lib/nt/nthlp.h
r3337 r3682 40 40 void birdResolveImportsWorker(void); 41 41 extern int g_fResolvedNtImports; 42 extern OSVERSIONINFOEXW g_NtVerInfo; 42 43 43 44 void *birdTmpAlloc(size_t cb); … … 53 54 int birdSetErrnoToInvalidArg(void); 54 55 int birdSetErrnoToBadFileNo(void); 56 int birdSetErrnoToDirNotEmpty(void); 55 57 56 58 HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, -
trunk/src/lib/nt/nthlpcore.c
r3534 r3682 60 60 MY_NTSTATUS (WINAPI *g_pfnNtSetInformationFile)(HANDLE, MY_IO_STATUS_BLOCK *, PVOID, LONG, MY_FILE_INFORMATION_CLASS); 61 61 BOOLEAN (WINAPI *g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *); 62 BOOLEAN (WINAPI *g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *); 63 MY_NTSTATUS (WINAPI *g_pfnRtlDosLongPathNameToNtPathName_U_WithStatus)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, 64 MY_RTL_RELATIVE_NAME_U *); 62 65 MY_NTSTATUS (WINAPI *g_pfnRtlAnsiStringToUnicodeString)(MY_UNICODE_STRING *, MY_ANSI_STRING const *, BOOLEAN); 63 66 MY_NTSTATUS (WINAPI *g_pfnRtlUnicodeStringToAnsiString)(MY_ANSI_STRING *, MY_UNICODE_STRING *, BOOLEAN); … … 68 71 VOID (WINAPI *g_pfnRtlAcquirePebLock)(VOID); 69 72 VOID (WINAPI *g_pfnRtlReleasePebLock)(VOID); 73 MY_NTSTATUS (WINAPI *g_pfnRtlGetVersion)(OSVERSIONINFOEXW *); 74 70 75 71 76 static struct … … 73 78 FARPROC *ppfn; 74 79 const char *pszName; 80 int fOptional; 75 81 } const g_apfnDynamicNtdll[] = 76 82 { 77 { (FARPROC *)&g_pfnNtClose, "NtClose" }, 78 { (FARPROC *)&g_pfnNtCreateFile, "NtCreateFile" }, 79 { (FARPROC *)&g_pfnNtDeleteFile, "NtDeleteFile" }, 80 { (FARPROC *)&g_pfnNtDuplicateObject, "NtDuplicateObject" }, 81 { (FARPROC *)&g_pfnNtReadFile, "NtReadFile" }, 82 { (FARPROC *)&g_pfnNtQueryInformationFile, "NtQueryInformationFile" }, 83 { (FARPROC *)&g_pfnNtQueryVolumeInformationFile, "NtQueryVolumeInformationFile" }, 84 { (FARPROC *)&g_pfnNtQueryDirectoryFile, "NtQueryDirectoryFile" }, 85 { (FARPROC *)&g_pfnNtQueryAttributesFile, "NtQueryAttributesFile" }, 86 { (FARPROC *)&g_pfnNtQueryFullAttributesFile, "NtQueryFullAttributesFile" }, 87 { (FARPROC *)&g_pfnNtSetInformationFile, "NtSetInformationFile" }, 88 { (FARPROC *)&g_pfnRtlDosPathNameToNtPathName_U, "RtlDosPathNameToNtPathName_U" }, 89 { (FARPROC *)&g_pfnRtlAnsiStringToUnicodeString, "RtlAnsiStringToUnicodeString" }, 90 { (FARPROC *)&g_pfnRtlUnicodeStringToAnsiString, "RtlUnicodeStringToAnsiString" }, 91 { (FARPROC *)&g_pfnRtlEqualUnicodeString, "RtlEqualUnicodeString" }, 92 { (FARPROC *)&g_pfnRtlEqualString, "RtlEqualString" }, 93 { (FARPROC *)&g_pfnRtlUpperChar, "RtlUpperChar" }, 94 { (FARPROC *)&g_pfnRtlNtStatusToDosError, "RtlNtStatusToDosError" }, 95 { (FARPROC *)&g_pfnRtlAcquirePebLock, "RtlAcquirePebLock" }, 96 { (FARPROC *)&g_pfnRtlReleasePebLock, "RtlReleasePebLock" }, 83 { (FARPROC *)&g_pfnNtClose, "NtClose", 0 }, 84 { (FARPROC *)&g_pfnNtCreateFile, "NtCreateFile", 0 }, 85 { (FARPROC *)&g_pfnNtDeleteFile, "NtDeleteFile", 0 }, 86 { (FARPROC *)&g_pfnNtDuplicateObject, "NtDuplicateObject", 0 }, 87 { (FARPROC *)&g_pfnNtReadFile, "NtReadFile", 0 }, 88 { (FARPROC *)&g_pfnNtQueryInformationFile, "NtQueryInformationFile", 0 }, 89 { (FARPROC *)&g_pfnNtQueryVolumeInformationFile, "NtQueryVolumeInformationFile", 0 }, 90 { (FARPROC *)&g_pfnNtQueryDirectoryFile, "NtQueryDirectoryFile", 0 }, 91 { (FARPROC *)&g_pfnNtQueryAttributesFile, "NtQueryAttributesFile", 0 }, 92 { (FARPROC *)&g_pfnNtQueryFullAttributesFile, "NtQueryFullAttributesFile", 0 }, 93 { (FARPROC *)&g_pfnNtSetInformationFile, "NtSetInformationFile", 0 }, 94 { (FARPROC *)&g_pfnRtlDosPathNameToNtPathName_U, "RtlDosPathNameToNtPathName_U", 0 }, 95 { (FARPROC *)&g_pfnRtlDosLongPathNameToNtPathName_U_WithStatus, "RtlDosLongPathNameToNtPathName_U_WithStatus", 1 }, 96 { (FARPROC *)&g_pfnRtlAnsiStringToUnicodeString, "RtlAnsiStringToUnicodeString", 0 }, 97 { (FARPROC *)&g_pfnRtlUnicodeStringToAnsiString, "RtlUnicodeStringToAnsiString", 0 }, 98 { (FARPROC *)&g_pfnRtlEqualUnicodeString, "RtlEqualUnicodeString", 0 }, 99 { (FARPROC *)&g_pfnRtlEqualString, "RtlEqualString", 0 }, 100 { (FARPROC *)&g_pfnRtlUpperChar, "RtlUpperChar", 0 }, 101 { (FARPROC *)&g_pfnRtlNtStatusToDosError, "RtlNtStatusToDosError", 0 }, 102 { (FARPROC *)&g_pfnRtlAcquirePebLock, "RtlAcquirePebLock", 0 }, 103 { (FARPROC *)&g_pfnRtlReleasePebLock, "RtlReleasePebLock", 0 }, 104 { (FARPROC *)&g_pfnRtlGetVersion, "RtlGetVersion", 1 }, 97 105 }; 98 106 /** Set to 1 if we've successfully resolved the imports, otherwise 0. */ 99 107 int g_fResolvedNtImports = 0; 100 108 109 /** Windows / NT version info. */ 110 OSVERSIONINFOEXW g_NtVerInfo; 101 111 102 112 103 113 void birdResolveImportsWorker(void) 104 114 { 115 /* Load the imports. */ 105 116 HMODULE hMod = LoadLibraryW(L"ntdll.dll"); 106 117 int i = sizeof(g_apfnDynamicNtdll) / sizeof(g_apfnDynamicNtdll[0]); … … 110 121 FARPROC pfn; 111 122 *g_apfnDynamicNtdll[i].ppfn = pfn = GetProcAddress(hMod, pszSym); 112 if (!pfn )123 if (!pfn && !g_apfnDynamicNtdll[i].fOptional) 113 124 { 114 125 /* Write short message and die. */ … … 124 135 } 125 136 137 /* Get the version. */ 138 #pragma warning(push) 139 #pragma warning(disable:4996) 140 g_NtVerInfo.dwOSVersionInfoSize = sizeof(g_NtVerInfo); 141 GetVersionExW((OSVERSIONINFOW *)&g_NtVerInfo); 142 #pragma warning(pop) 143 if (g_pfnRtlGetVersion) 144 g_pfnRtlGetVersion(&g_NtVerInfo); 145 146 /* Mark everything as done. */ 126 147 g_fResolvedNtImports = 1; 127 148 } … … 480 501 } 481 502 503 504 int birdSetErrnoToDirNotEmpty(void) 505 { 506 errno = ENOTEMPTY; 507 return -1; 508 } 509 -
trunk/src/lib/nt/nthlpfs.c
r3223 r3682 149 149 * Convert the wide DOS path to an NT path. 150 150 */ 151 if (g_pfnRtlDosPathNameToNtPathName_U(wszTmp, pNtPath, NULL, FALSE)) 151 if (g_pfnRtlDosLongPathNameToNtPathName_U_WithStatus) 152 { 153 rcNt = g_pfnRtlDosLongPathNameToNtPathName_U_WithStatus(wszTmp, pNtPath, NULL, NULL); 154 if (MY_NT_SUCCESS(rcNt)) 155 return 0; 156 } 157 else if (g_pfnRtlDosPathNameToNtPathName_U(wszTmp, pNtPath, NULL, NULL)) 152 158 return 0; 159 else 160 rcNt = -1; 153 161 } 154 rcNt = -1; 162 else 163 rcNt = -1; 155 164 } 156 165 return birdSetErrnoFromNt(rcNt); … … 168 177 * Convert the wide DOS path to an NT path. 169 178 */ 170 if (g_pfnRtlDosPathNameToNtPathName_U(pwszPath, pNtPath, NULL, FALSE)) 179 if (g_pfnRtlDosLongPathNameToNtPathName_U_WithStatus) 180 { 181 MY_NTSTATUS rcNt = g_pfnRtlDosLongPathNameToNtPathName_U_WithStatus(pwszPath, pNtPath, NULL, NULL); 182 if (MY_NT_SUCCESS(rcNt)) 183 return 0; 184 return birdSetErrnoFromNt(rcNt); 185 } 186 if (g_pfnRtlDosPathNameToNtPathName_U(pwszPath, pNtPath, NULL, NULL)) 171 187 return 0; 172 188 return birdSetErrnoFromNt(STATUS_NO_MEMORY); -
trunk/src/lib/nt/ntopenat.c
r3601 r3682 40 40 #include "ntstuff.h" 41 41 #include "nthlp.h" 42 #include "nthlpmisc.h" 42 43 #include "ntopenat.h" 43 44 #include "ntstat.h" 44 45 46 #define IS_ALPHA(ch) ( ((ch) >= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') )47 #define IS_SLASH(ch) ((ch) == '\\' || (ch) == '/')48 49 45 50 46 … … 95 91 96 92 93 /** 94 * Implements open. 95 */ 97 96 int birdOpen(const char *pszPath, int fFlags, ...) 98 97 { … … 160 159 } 161 160 162 -
trunk/src/lib/nt/ntopenat.h
r3533 r3682 33 33 34 34 #include "nttypes.h" 35 #include "ntat.h" 35 36 37 extern int birdOpen(const char *pszPath, int fFlags, ...); 36 38 extern int birdOpenAt(int fdDir, const char *pszPath, int fFlags, ...); 37 39 38 40 #define openat birdOpenAt 39 41 40 #define AT_FDCWD (-987654321)41 42 42 #endif 43 43 -
trunk/src/lib/nt/ntstuff.h
r3644 r3682 558 558 extern MY_NTSTATUS (WINAPI * g_pfnNtSetInformationFile)(HANDLE, MY_IO_STATUS_BLOCK *, PVOID, LONG, MY_FILE_INFORMATION_CLASS); 559 559 extern BOOLEAN (WINAPI * g_pfnRtlDosPathNameToNtPathName_U)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, MY_RTL_RELATIVE_NAME_U *); 560 extern MY_NTSTATUS (WINAPI * g_pfnRtlDosLongPathNameToNtPathName_U_WithStatus)(PCWSTR, MY_UNICODE_STRING *, PCWSTR *, 561 MY_RTL_RELATIVE_NAME_U *); 560 562 extern MY_NTSTATUS (WINAPI * g_pfnRtlAnsiStringToUnicodeString)(MY_UNICODE_STRING *, MY_ANSI_STRING const *, BOOLEAN); 561 563 extern MY_NTSTATUS (WINAPI * g_pfnRtlUnicodeStringToAnsiString)(MY_ANSI_STRING *, MY_UNICODE_STRING *, BOOLEAN); -
trunk/src/lib/nt/ntunlink.c
r3504 r3682 33 33 * Header Files * 34 34 *******************************************************************************/ 35 #include <io.h> /* for _get_osfhandle */ 35 36 #include "ntunlink.h" 36 37 37 38 #include "ntstuff.h" 38 39 #include "nthlp.h" 40 #include "nthlpmisc.h" 39 41 40 42 … … 82 84 83 85 84 static int birdUnlinkInternal(HANDLE hRoot, const char *pszFile, const wchar_t *pwszFile, int fReadOnlyToo, int fFast )86 static int birdUnlinkInternal(HANDLE hRoot, const char *pszFile, const wchar_t *pwszFile, int fReadOnlyToo, int fFast, int fRmDir) 85 87 { 86 88 MY_UNICODE_STRING NtPath; … … 108 110 if (fFast) 109 111 { 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) 112 /* 113 * This uses FILE_DELETE_ON_CLOSE. 114 * 115 * It is only suitable if in a hurry and when 100% sure it is a regular file. 116 * It will follow symbolic links by default, so subject to races and abuse. 117 * 118 * If used on a directory and the directory isn't empty, it will return success 119 * instead of STATUS_CANNOT_DELETE. 120 * 121 * To stay out of trouble, we always use the OBJ_DONT_REPARSE flag here. This 122 * is a relative new addition (windows 10, build unknown), so if it ain't 123 * supported or we encounter a reparse object we just fall back to the regular 124 * deletion code. 125 */ 126 static int volatile s_iSupportsDontReparse = 0; 127 if (s_iSupportsDontReparse >= 0 && !fRmDir) 117 128 { 118 birdMakeWritable(hRoot, &NtPath); 129 MY_OBJECT_ATTRIBUTES ObjAttr; 130 MyInitializeObjectAttributes(&ObjAttr, &NtPath, OBJ_DONT_REPARSE | OBJ_CASE_INSENSITIVE, hRoot, NULL /*pSecAttr*/); 119 131 rcNt = g_pfnNtDeleteFile(&ObjAttr); 132 133 /* In case some file system does things differently than NTFS. */ 134 if (rcNt == STATUS_CANNOT_DELETE && fReadOnlyToo) 135 { 136 birdMakeWritable(hRoot, &NtPath); 137 rcNt = g_pfnNtDeleteFile(&ObjAttr); 138 } 139 140 /* Do fallback. */ 141 if (rcNt == STATUS_REPARSE_POINT_ENCOUNTERED) 142 fFast = 0; 143 else if (rcNt == STATUS_INVALID_PARAMETER) 144 { 145 s_iSupportsDontReparse = -1; 146 fFast = 0; 147 } 148 } 149 else 150 { 151 rcNt = STATUS_INVALID_PARAMETER; 152 fFast = 0; 120 153 } 121 154 } 122 else 155 156 if (!fFast) 123 157 { 124 /* Use the set information stuff. Probably more reliable. */ 158 /* 159 * Use the set information stuff. Here we can better control reparsing. 160 */ 125 161 HANDLE hFile; 126 162 for (;;) 127 163 { 164 MY_IO_STATUS_BLOCK Ios; 165 128 166 rcNt = birdOpenFileUniStr(hRoot, 129 167 &NtPath, … … 132 170 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 133 171 FILE_OPEN, 134 FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT, 172 (!fRmDir ? FILE_NON_DIRECTORY_FILE : FILE_DIRECTORY_FILE) 173 | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT, 135 174 OBJ_CASE_INSENSITIVE, 136 175 &hFile); 176 177 /* Windows distinguishes between symlinks to directories and to files, so 178 unlink(symlink-dir) will fail and we have to retry w/o the non-dir-file 179 flag and make sure it didn't turn into a pure directory. */ 180 if ( rcNt == STATUS_FILE_IS_A_DIRECTORY 181 && !fRmDir) 182 { 183 rcNt = birdOpenFileUniStr(hRoot, 184 &NtPath, 185 DELETE | FILE_READ_ATTRIBUTES | SYNCHRONIZE, 186 FILE_ATTRIBUTE_REPARSE_POINT, 187 FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE, 188 FILE_OPEN, 189 FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT, 190 OBJ_CASE_INSENSITIVE, 191 &hFile); 192 if (MY_NT_SUCCESS(rcNt)) 193 { 194 MY_FILE_BASIC_INFORMATION BasicInfo; 195 memset(&BasicInfo, 0, sizeof(BasicInfo)); 196 197 Ios.Information = -1; 198 Ios.u.Status = -1; 199 200 rcNt = g_pfnNtQueryInformationFile(hFile, &Ios, &BasicInfo, sizeof(BasicInfo), MyFileBasicInformation); 201 if ( !MY_NT_SUCCESS(rcNt) 202 || !MY_NT_SUCCESS(Ios.u.Status) 203 || (BasicInfo.FileAttributes & (FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_DIRECTORY)) 204 == FILE_ATTRIBUTE_DIRECTORY) 205 { 206 birdCloseFile(hFile); 207 rcNt = STATUS_FILE_IS_A_DIRECTORY; 208 break; 209 } 210 } 211 } 212 137 213 if (MY_NT_SUCCESS(rcNt)) 138 214 { 139 215 MY_FILE_DISPOSITION_INFORMATION DispInfo; 140 MY_IO_STATUS_BLOCK Ios;141 142 216 DispInfo.DeleteFile = TRUE; 143 217 … … 161 235 if (MY_NT_SUCCESS(rcNt)) 162 236 rc = 0; 237 else if (rcNt == STATUS_SHARING_VIOLATION && fRmDir) 238 rc = birdSetErrnoToDirNotEmpty(); /* probably the case... */ 163 239 else 164 240 rc = birdSetErrnoFromNt(rcNt); … … 168 244 169 245 246 /* 247 * unlink: 248 */ 249 170 250 int birdUnlink(const char *pszFile) 171 251 { 172 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/ );252 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 173 253 } 174 254 … … 176 256 int birdUnlinkW(const wchar_t *pwszFile) 177 257 { 178 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pwszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/ );258 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pwszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 179 259 } 180 260 … … 182 262 int birdUnlinkEx(void *hRoot, const char *pszFile) 183 263 { 184 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/ );264 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 185 265 } 186 266 … … 188 268 int birdUnlinkExW(void *hRoot, const wchar_t *pwszFile) 189 269 { 190 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/ );270 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 191 271 } 192 272 … … 194 274 int birdUnlinkForced(const char *pszFile) 195 275 { 196 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/ );276 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 197 277 } 198 278 … … 200 280 int birdUnlinkForcedW(const wchar_t *pwszFile) 201 281 { 202 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/ );282 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 203 283 } 204 284 … … 206 286 int birdUnlinkForcedEx(void *hRoot, const char *pszFile) 207 287 { 208 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/ );288 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 209 289 } 210 290 … … 212 292 int birdUnlinkForcedExW(void *hRoot, const wchar_t *pwszFile) 213 293 { 214 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/ );294 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 0 /*fRmDir*/); 215 295 } 216 296 … … 218 298 int birdUnlinkForcedFast(const char *pszFile) 219 299 { 220 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/ );300 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/, 0 /*fRmDir*/); 221 301 } 222 302 … … 224 304 int birdUnlinkForcedFastW(const wchar_t *pwszFile) 225 305 { 226 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/ );306 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/, 0 /*fRmDir*/); 227 307 } 228 308 … … 230 310 int birdUnlinkForcedFastEx(void *hRoot, const char *pszFile) 231 311 { 232 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/ );312 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 1 /*fFast*/, 0 /*fRmDir*/); 233 313 } 234 314 … … 236 316 int birdUnlinkForcedFastExW(void *hRoot, const wchar_t *pwszFile) 237 317 { 238 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/); 239 } 240 318 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 1 /*fFast*/, 0 /*fRmDir*/); 319 } 320 321 322 /* 323 * rmdir 324 */ 325 326 int birdRmDir(const char *pszFile) 327 { 328 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 329 } 330 331 332 int birdRmDirW(const wchar_t *pwszFile) 333 { 334 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pwszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 335 } 336 337 338 int birdRmDirEx(void *hRoot, const char *pszFile) 339 { 340 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 341 } 342 343 344 int birdRmDirExW(void *hRoot, const wchar_t *pwszFile) 345 { 346 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 0 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 347 } 348 349 350 int birdRmDirForced(const char *pszFile) 351 { 352 return birdUnlinkInternal(NULL /*hRoot*/, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 353 } 354 355 356 int birdRmDirForcedW(const wchar_t *pwszFile) 357 { 358 return birdUnlinkInternal(NULL /*hRoot*/, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 359 } 360 361 362 int birdRmDirForcedEx(void *hRoot, const char *pszFile) 363 { 364 return birdUnlinkInternal((HANDLE)hRoot, pszFile, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 365 } 366 367 368 int birdRmDirForcedExW(void *hRoot, const wchar_t *pwszFile) 369 { 370 return birdUnlinkInternal((HANDLE)hRoot, NULL /*pszFile*/, pwszFile, 1 /*fReadOnlyToo*/, 0 /*fFast*/, 1 /*fRmDir*/); 371 } 372 373 374 /** 375 * Implements unlinkat(). 376 */ 377 int birdUnlinkAt(int fdDir, const char *pszPath, int fFlags) 378 { 379 HANDLE hDirRoot; 380 381 /** @todo validate input. */ 382 fFlags &= AT_REMOVEDIR; 383 384 /* 385 * Check the path its effectively a AT_FDCWD call. 386 */ 387 if (fdDir != AT_FDCWD) 388 { 389 if (IS_SLASH(pszPath[0])) 390 { 391 if (IS_SLASH(pszPath[1]) && !IS_SLASH(pszPath[2]) && pszPath[2] != '\0') 392 fdDir = AT_FDCWD; 393 } 394 else if (IS_ALPHA(pszPath[0]) && pszPath[1] == ':') 395 { 396 if (IS_SLASH(pszPath[2])) 397 fdDir = AT_FDCWD; 398 else 399 /* 400 * Drive letter relative path like "C:kernel32.dll". 401 * We could try use fdDir as the CWD here if it refers to the same drive, 402 * however that's can be implemented later... 403 */ 404 fdDir = AT_FDCWD; 405 } 406 } 407 408 /* 409 * Determine hDirRoot. 410 */ 411 if (fdDir == AT_FDCWD) 412 hDirRoot = NULL; 413 else 414 { 415 hDirRoot = (HANDLE)_get_osfhandle(fdDir); 416 if (hDirRoot == INVALID_HANDLE_VALUE || hDirRoot == NULL) 417 return birdSetErrnoToBadFileNo(); 418 } 419 420 return birdUnlinkInternal(hDirRoot, pszPath, NULL /*pwszFile*/, 1 /*fReadOnlyToo*/, 0 /*fFast*/, !!fFlags /*fRmDir*/); 421 } 422 -
trunk/src/lib/nt/ntunlink.h
r3060 r3682 33 33 34 34 #include "nttypes.h" 35 #include "ntat.h" 35 36 #include <wchar.h> 36 37 … … 48 49 int birdUnlinkForcedFastExW(void *hRoot, const wchar_t *pwszFile); 49 50 51 int birdRmDir(const char *pszFile); 52 int birdRmDirW(const wchar_t *pwszFile); 53 int birdRmDirEx(void *hRoot, const char *pszFile); 54 int birdRmDirExW(void *hRoot, const wchar_t *pwszFile); 55 int birdRmDirForced(const char *pszFile); 56 int birdRmDirForcedW(const wchar_t *pwszFile); 57 int birdRmDirForcedEx(void *hRoot, const char *pszFile); 58 int birdRmDirForcedExW(void *hRoot, const wchar_t *pszFile); 59 60 #define AT_REMOVEDIR 1 61 int birdUnlinkAt(int fdDir, const char *pszPath, int fFlags); 62 50 63 #undef unlink 51 64 #define unlink(a_pszPath) birdUnlinkForced(a_pszPath) 52 65 66 #undef rmdir 67 #define rmdir(a_pszPath) birdRmDirForced(a_pszPath) 68 69 #undef unlinkat 70 #define unlinkat(a_fdDir, a_pszPath, a_fFlags) birdUnlinkAt(a_fdDir, a_pszPath, a_fFlags) 71 53 72 #endif 54 73
Note:
See TracChangeset
for help on using the changeset viewer.