- Timestamp:
- Nov 21, 2013 1:26:52 AM (11 years ago)
- Location:
- trunk/src/lib/nt
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/nt/nthlp.h
r2702 r2704 56 56 HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess, 57 57 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs); 58 HANDLE birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess, 59 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs, 60 MY_UNICODE_STRING *pNameUniStr); 58 61 void birdCloseFile(HANDLE hFile); 62 void birdFreeNtPath(MY_UNICODE_STRING *pNtPath); 59 63 60 64 -
trunk/src/lib/nt/nthlpfs.c
r2703 r2704 36 36 37 37 38 /******************************************************************************* 39 * Global Variables * 40 *******************************************************************************/ 41 static int g_fHaveOpenReparsePoint = -1; 42 43 38 44 39 45 static int birdHasTrailingSlash(const char *pszPath) … … 71 77 } 72 78 73 #ifndef BIRD_USE_WIN3274 79 75 80 static int birdDosToNtPath(const char *pszPath, MY_UNICODE_STRING *pNtPath) … … 112 117 113 118 114 staticvoid birdFreeNtPath(MY_UNICODE_STRING *pNtPath)119 void birdFreeNtPath(MY_UNICODE_STRING *pNtPath) 115 120 { 116 121 HeapFree(GetProcessHeap(), 0, pNtPath->Buffer); 117 122 pNtPath->Buffer = NULL; 118 } 119 120 #endif /* !BIRD_USE_WIN32 */ 121 122 123 HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess, 124 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs) 125 { 126 static int s_fHaveOpenReparsePoint = -1; 127 HANDLE hFile; 128 #ifdef BIRD_USE_WIN32 129 SECURITY_ATTRIBUTES SecAttr; 130 DWORD dwErr; 131 DWORD fW32Disp; 132 DWORD fW32Flags; 133 #else 134 MY_UNICODE_STRING NtPath; 135 MY_NTSTATUS rcNt; 136 #endif 137 138 birdResolveImports(); 139 140 if (birdIsPathDirSpec(pszPath)) 141 fCreateOptions |= FILE_DIRECTORY_FILE; 123 pNtPath->Length = 0; 124 pNtPath->MaximumLength = 0; 125 } 126 127 128 static MY_NTSTATUS birdOpenFileInternal(MY_UNICODE_STRING *pNtPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, 129 ULONG fShareAccess, ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs, 130 HANDLE *phFile) 131 { 132 MY_IO_STATUS_BLOCK Ios; 133 MY_OBJECT_ATTRIBUTES ObjAttr; 134 MY_NTSTATUS rcNt; 135 142 136 if ( (fCreateOptions & FILE_OPEN_REPARSE_POINT) 143 && s_fHaveOpenReparsePoint == 0)137 && g_fHaveOpenReparsePoint == 0) 144 138 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT; 145 139 146 #ifdef BIRD_USE_WIN32 147 /* NT -> W32 */ 148 149 SecAttr.nLength = sizeof(SecAttr); 150 SecAttr.lpSecurityDescriptor = NULL; 151 SecAttr.bInheritHandle = fObjAttribs & OBJ_INHERIT ? TRUE : FALSE; 152 153 fW32Flags = 0; 154 if (!(fObjAttribs & OBJ_CASE_INSENSITIVE)) 155 fW32Flags |= FILE_FLAG_POSIX_SEMANTICS; 156 if (fCreateOptions & FILE_OPEN_FOR_BACKUP_INTENT) 157 fW32Flags |= FILE_FLAG_BACKUP_SEMANTICS; 158 if (fCreateOptions & FILE_OPEN_REPARSE_POINT) 159 fW32Flags |= FILE_FLAG_OPEN_REPARSE_POINT; 160 //?? if (fCreateOptions & FILE_DIRECTORY_FILE) 161 //?? fW32Flags |= ; 162 163 switch (fCreateDisposition) 164 { 165 case FILE_OPEN: fW32Disp = OPEN_EXISTING; break; 166 case FILE_CREATE: fW32Disp = CREATE_NEW; break; 167 case FILE_OPEN_IF: fW32Disp = OPEN_ALWAYS; break; 168 case FILE_OVERWRITE_IF: fW32Disp = CREATE_ALWAYS; break; 169 default: 170 # ifndef NDEBUG 171 __debugbreak(); 172 # endif 173 return INVALID_HANDLE_VALUE; 174 } 175 176 hFile = CreateFileA(pszPath, fDesiredAccess, fShareAccess, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/); 177 if (hFile != INVALID_HANDLE_VALUE) 178 return hFile; 179 180 dwErr = GetLastError(); 181 182 /* Deal with FILE_FLAG_OPEN_REPARSE_POINT the first times around. */ 183 if ( dwErr == ERROR_INVALID_PARAMETER 184 && s_fHaveOpenReparsePoint < 0 185 && (fCreateOptions & FILE_OPEN_REPARSE_POINT) ) 140 Ios.Information = -1; 141 Ios.u.Status = 0; 142 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/); 143 144 rcNt = g_pfnNtCreateFile(phFile, 145 fDesiredAccess, 146 &ObjAttr, 147 &Ios, 148 NULL, /* cbFileInitialAlloc */ 149 fFileAttribs, 150 fShareAccess, 151 fCreateDisposition, 152 fCreateOptions, 153 NULL, /* pEaBuffer */ 154 0); /* cbEaBuffer*/ 155 if ( rcNt == STATUS_INVALID_PARAMETER 156 && g_fHaveOpenReparsePoint < 0 157 && (fCreateOptions & FILE_OPEN_REPARSE_POINT)) 186 158 { 187 159 fCreateOptions &= ~FILE_OPEN_REPARSE_POINT; 188 fW32Flags &= ~FILE_FLAG_OPEN_REPARSE_POINT;189 hFile = CreateFileA(pszPath, fDesiredAccess, fFileAttribs, &SecAttr, fW32Disp, fW32Flags, NULL /*hTemplateFile*/);190 if (hFile != INVALID_HANDLE_VALUE)191 {192 s_fHaveOpenReparsePoint = 0;193 return hFile;194 }195 }196 197 birdSetErrnoFromWin32(dwErr);198 199 #else /* !BIRD_USE_WIN32 */200 201 /*202 * Call the NT API directly.203 */204 if (birdDosToNtPath(pszPath, &NtPath) == 0)205 {206 MY_IO_STATUS_BLOCK Ios;207 MY_OBJECT_ATTRIBUTES ObjAttr;208 160 209 161 Ios.Information = -1; 210 162 Ios.u.Status = 0; 211 212 MyInitializeObjectAttributes(&ObjAttr, &NtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/); 213 214 rcNt = g_pfnNtCreateFile(&hFile, 163 MyInitializeObjectAttributes(&ObjAttr, pNtPath, fObjAttribs, NULL /*hRoot*/, NULL /*pSecAttr*/); 164 165 rcNt = g_pfnNtCreateFile(phFile, 215 166 fDesiredAccess, 216 167 &ObjAttr, … … 223 174 NULL, /* pEaBuffer */ 224 175 0); /* cbEaBuffer*/ 176 if (rcNt != STATUS_INVALID_PARAMETER) 177 g_fHaveOpenReparsePoint = 0; 178 } 179 return rcNt; 180 } 181 182 183 HANDLE birdOpenFile(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess, 184 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs) 185 { 186 MY_UNICODE_STRING NtPath; 187 MY_NTSTATUS rcNt; 188 189 birdResolveImports(); 190 191 /* 192 * Adjust inputs. 193 */ 194 if (birdIsPathDirSpec(pszPath)) 195 fCreateOptions |= FILE_DIRECTORY_FILE; 196 197 /* 198 * Call the NT API directly. 199 */ 200 if (birdDosToNtPath(pszPath, &NtPath) == 0) 201 { 202 HANDLE hFile; 203 rcNt = birdOpenFileInternal(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess, 204 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile); 225 205 if (MY_NT_SUCCESS(rcNt)) 226 206 { … … 233 213 } 234 214 235 #endif /* !BIRD_USE_WIN32 */236 215 return INVALID_HANDLE_VALUE; 237 216 } 238 217 239 218 219 HANDLE birdOpenParentDir(const char *pszPath, ACCESS_MASK fDesiredAccess, ULONG fFileAttribs, ULONG fShareAccess, 220 ULONG fCreateDisposition, ULONG fCreateOptions, ULONG fObjAttribs, 221 MY_UNICODE_STRING *pNameUniStr) 222 { 223 MY_UNICODE_STRING NtPath; 224 MY_NTSTATUS rcNt; 225 226 birdResolveImports(); 227 228 /* 229 * Adjust inputs. 230 */ 231 fCreateOptions |= FILE_DIRECTORY_FILE; 232 233 /* 234 * Convert the path and split off the filename. 235 */ 236 if (birdDosToNtPath(pszPath, &NtPath) == 0) 237 { 238 USHORT offName = NtPath.Length / sizeof(WCHAR); 239 USHORT cwcName = offName; 240 WCHAR wc = 0; 241 242 while ( offName > 0 243 && (wc = NtPath.Buffer[offName - 1]) != '\\' 244 && wc != '/' 245 && wc != ':') 246 offName--; 247 if (offName > 0) 248 { 249 cwcName -= offName; 250 251 /* Make a copy of the file name, if requested. */ 252 rcNt = STATUS_SUCCESS; 253 if (pNameUniStr) 254 { 255 pNameUniStr->Length = cwcName * sizeof(WCHAR); 256 pNameUniStr->MaximumLength = pNameUniStr->Length + sizeof(WCHAR); 257 pNameUniStr->Buffer = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, pNameUniStr->MaximumLength); 258 if (pNameUniStr->Buffer) 259 { 260 memcpy(pNameUniStr->Buffer, &NtPath.Buffer[offName],pNameUniStr->Length); 261 pNameUniStr->Buffer[cwcName] = '\0'; 262 } 263 else 264 rcNt = STATUS_NO_MEMORY; 265 } 266 267 /* Chop, chop. */ 268 // Bad idea, breaks \\?\c:\pagefile.sys. //while ( offName > 0 269 // Bad idea, breaks \\?\c:\pagefile.sys. // && ( (wc = NtPath.Buffer[offName - 1]) == '\\' 270 // Bad idea, breaks \\?\c:\pagefile.sys. // || wc == '/')) 271 // Bad idea, breaks \\?\c:\pagefile.sys. // offName--; 272 NtPath.Length = offName * sizeof(WCHAR); 273 NtPath.Buffer[offName] = '\0'; 274 if (MY_NT_SUCCESS(rcNt)) 275 { 276 /* 277 * Finally, try open the directory. 278 */ 279 HANDLE hFile; 280 rcNt = birdOpenFileInternal(&NtPath, fDesiredAccess, fFileAttribs, fShareAccess, 281 fCreateDisposition, fCreateOptions, fObjAttribs, &hFile); 282 if (MY_NT_SUCCESS(rcNt)) 283 { 284 birdFreeNtPath(&NtPath); 285 return hFile; 286 } 287 } 288 289 if (pNameUniStr) 290 birdFreeNtPath(pNameUniStr); 291 } 292 293 birdFreeNtPath(&NtPath); 294 birdSetErrnoFromNt(rcNt); 295 } 296 297 return INVALID_HANDLE_VALUE; 298 } 299 300 240 301 void birdCloseFile(HANDLE hFile) 241 302 { 242 #ifdef BIRD_USE_WIN32243 CloseHandle(hFile);244 #else245 303 birdResolveImports(); 246 304 g_pfnNtClose(hFile); 247 #endif 248 } 249 305 } 306 -
trunk/src/lib/nt/ntstat.c
r2703 r2704 133 133 134 134 /* File type. */ 135 if (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT) 135 if ( (fAttribs & FILE_ATTRIBUTE_REPARSE_POINT) 136 && hFile != INVALID_HANDLE_VALUE) 136 137 { 137 138 MY_FILE_ATTRIBUTE_TAG_INFORMATION TagInfo; … … 357 358 //fprintf(stderr, "stat: %s -> %u\n", pszPath, GetLastError()); 358 359 359 /* On things like pagefile.sys we may get sharing violation. */ 360 if (errno == ETXTBSY) 361 { 362 /** @todo Fall back on the parent directory enum if we run into a sharing 363 * violation. */ 360 /* 361 * On things like pagefile.sys we may get sharing violation. We fall 362 * back on directory enumeration for dealing with that. 363 */ 364 if ( errno == ETXTBSY 365 && strchr(pszPath, '*') == NULL /* Serious paranoia... */ 366 && strchr(pszPath, '?') == NULL) 367 { 368 MY_UNICODE_STRING NameUniStr; 369 hFile = birdOpenParentDir(pszPath, 370 FILE_READ_DATA | SYNCHRONIZE, 371 FILE_ATTRIBUTE_NORMAL, 372 FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 373 FILE_OPEN, 374 FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT, 375 OBJ_CASE_INSENSITIVE, 376 &NameUniStr); 377 if (hFile != INVALID_HANDLE_VALUE) 378 { 379 MY_FILE_ID_FULL_DIR_INFORMATION *pBuf; 380 ULONG cbBuf = sizeof(*pBuf) + NameUniStr.MaximumLength + 1024; 381 MY_IO_STATUS_BLOCK Ios; 382 MY_NTSTATUS rcNt; 383 384 pBuf = (MY_FILE_ID_FULL_DIR_INFORMATION *)alloca(cbBuf); 385 Ios.u.Status = -1; 386 Ios.Information = -1; 387 rcNt = g_pfnNtQueryDirectoryFile(hFile, NULL, NULL, NULL, &Ios, pBuf, cbBuf, 388 MyFileIdFullDirectoryInformation, FALSE, &NameUniStr, TRUE); 389 if (MY_NT_SUCCESS(rcNt)) 390 rcNt = Ios.u.Status; 391 if (MY_NT_SUCCESS(rcNt)) 392 { 393 /* 394 * Convert the data. 395 */ 396 pStat->st_mode = birdFileInfoToMode(INVALID_HANDLE_VALUE, pBuf->FileAttributes, pszPath, 397 NULL, &pStat->st_dirsymlink); 398 pStat->st_padding0[0] = 0; 399 pStat->st_padding0[1] = 0; 400 pStat->st_size = pBuf->EndOfFile.QuadPart; 401 birdNtTimeToTimeSpec(pBuf->CreationTime.QuadPart, &pStat->st_birthtim); 402 birdNtTimeToTimeSpec(pBuf->ChangeTime.QuadPart, &pStat->st_ctim); 403 birdNtTimeToTimeSpec(pBuf->LastWriteTime.QuadPart, &pStat->st_mtim); 404 birdNtTimeToTimeSpec(pBuf->LastAccessTime.QuadPart, &pStat->st_atim); 405 pStat->st_ino = pBuf->FileId.QuadPart; 406 pStat->st_nlink = 1; 407 pStat->st_rdev = 0; 408 pStat->st_uid = 0; 409 pStat->st_gid = 0; 410 pStat->st_padding1[0] = 0; 411 pStat->st_padding1[1] = 0; 412 pStat->st_padding1[2] = 0; 413 pStat->st_blksize = 65536; 414 pStat->st_blocks = (pBuf->AllocationSize.QuadPart + BIRD_STAT_BLOCK_SIZE - 1) 415 / BIRD_STAT_BLOCK_SIZE; 416 417 /* Get the serial number, reusing the buffer from above. */ 418 rcNt = g_pfnNtQueryVolumeInformationFile(hFile, &Ios, pBuf, cbBuf, MyFileFsVolumeInformation); 419 if (MY_NT_SUCCESS(rcNt)) 420 rcNt = Ios.u.Status; 421 if (MY_NT_SUCCESS(rcNt)) 422 { 423 MY_FILE_FS_VOLUME_INFORMATION const *pVolInfo = (MY_FILE_FS_VOLUME_INFORMATION const *)pBuf; 424 pStat->st_dev = pVolInfo->VolumeSerialNumber 425 | (pVolInfo->VolumeCreationTime.QuadPart << 32); 426 rc = 0; 427 } 428 else 429 { 430 pStat->st_dev = 0; 431 rc = birdSetErrnoFromNt(rcNt); 432 } 433 } 434 435 birdFreeNtPath(&NameUniStr); 436 birdCloseFile(hFile); 437 438 if (MY_NT_SUCCESS(rcNt)) 439 return 0; 440 birdSetErrnoFromNt(rcNt); 441 } 364 442 } 365 443 rc = -1; -
trunk/src/lib/nt/ntstuff.h
r2702 r2704 179 179 /** The sizeof(MY_FILE_NAMES_INFORMATION) without the FileName. */ 180 180 #define MIN_SIZEOF_MY_FILE_NAMES_INFORMATION (4 + 4 + 4) 181 182 183 typedef struct MY_FILE_ID_FULL_DIR_INFORMATION 184 { 185 ULONG NextEntryOffset; 186 ULONG FileIndex; 187 LARGE_INTEGER CreationTime; 188 LARGE_INTEGER LastAccessTime; 189 LARGE_INTEGER LastWriteTime; 190 LARGE_INTEGER ChangeTime; 191 LARGE_INTEGER EndOfFile; 192 LARGE_INTEGER AllocationSize; 193 ULONG FileAttributes; 194 ULONG FileNameLength; 195 ULONG EaSize; 196 LARGE_INTEGER FileId; 197 WCHAR FileName[1]; 198 } MY_FILE_ID_FULL_DIR_INFORMATION; 181 199 182 200
Note:
See TracChangeset
for help on using the changeset viewer.