ReactOS  0.4.15-dev-509-g96a357b
fileinfo.c File Reference
#include "fatprocs.h"
Include dependency graph for fileinfo.c:

Go to the source code of this file.

Macros

#define BugCheckFileId   (FAT_BUG_CHECK_FILEINFO)
 
#define Dbg   (DEBUG_TRACE_FILEINFO)
 

Functions

VOID FatQueryBasicInfo (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFILE_OBJECT FileObject, IN OUT PFILE_BASIC_INFORMATION Buffer, IN OUT PLONG Length)
 
 _Requires_lock_held_ (_Global_critical_region_)
 
 _Function_class_ (IRP_MJ_SET_INFORMATION)
 
VOID FatQueryInternalInfo (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN OUT PFILE_INTERNAL_INFORMATION Buffer, IN OUT PLONG Length)
 
VOID FatQueryEaInfo (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN OUT PFILE_EA_INFORMATION Buffer, IN OUT PLONG Length)
 
VOID FatQueryPositionInfo (IN PIRP_CONTEXT IrpContext, IN PFILE_OBJECT FileObject, IN OUT PFILE_POSITION_INFORMATION Buffer, IN OUT PLONG Length)
 
VOID FatQueryShortNameInfo (IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN OUT PFILE_NAME_INFORMATION Buffer, IN OUT PLONG Length)
 
NTSTATUS FatSetRenameInfo (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PVCB Vcb, IN PFCB Fcb, IN PCCB Ccb)
 
NTSTATUS FatSetPositionInfo (IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PFILE_OBJECT FileObject)
 

Macro Definition Documentation

◆ BugCheckFileId

#define BugCheckFileId   (FAT_BUG_CHECK_FILEINFO)

Definition at line 23 of file fileinfo.c.

◆ Dbg

#define Dbg   (DEBUG_TRACE_FILEINFO)

Definition at line 29 of file fileinfo.c.

Function Documentation

◆ _Function_class_()

_Function_class_ ( IRP_MJ_SET_INFORMATION  )

Definition at line 280 of file fileinfo.c.

309 {
311  PIRP_CONTEXT IrpContext = NULL;
312 
314 
315  PAGED_CODE();
316 
317  DebugTrace(+1, Dbg, "FatFsdSetInformation\n", 0);
318 
319  //
320  // Call the common set routine, with blocking allowed if synchronous
321  //
322 
324 
326 
327  _SEH2_TRY {
328 
329  IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
330 
331  Status = FatCommonSetInformation( IrpContext, Irp );
332 
334 
335  //
336  // We had some trouble trying to perform the requested
337  // operation, so we'll abort the I/O request with
338  // the error status that we get back from the
339  // execption code
340  //
341 
342  Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
343  } _SEH2_END;
344 
345  if (TopLevel) { IoSetTopLevelIrp( NULL ); }
346 
348 
349  //
350  // And return to our caller
351  //
352 
353  DebugTrace(-1, Dbg, "FatFsdSetInformation -> %08lx\n", Status);
354 
355  UNREFERENCED_PARAMETER( VolumeDeviceObject );
356 
357  return Status;
358 }
#define FsRtlEnterFileSystem
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define FsRtlExitFileSystem
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
_SEH2_TRY
Definition: create.c:4226
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2410
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define Dbg
Definition: fileinfo.c:29
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2289
#define CanFsdWait(I)
Definition: cdprocs.h:2001
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4400
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define PAGED_CODE()

◆ _Requires_lock_held_()

_Requires_lock_held_ ( _Global_critical_region_  )

Definition at line 40 of file fileinfo.c.

228 {
230  PIRP_CONTEXT IrpContext = NULL;
231 
233 
234  PAGED_CODE();
235 
236  DebugTrace(+1, Dbg, "FatFsdQueryInformation\n", 0);
237 
238  //
239  // Call the common query routine, with blocking allowed if synchronous
240  //
241 
243 
245 
246  _SEH2_TRY {
247 
248  IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );
249 
250  Status = FatCommonQueryInformation( IrpContext, Irp );
251 
253 
254  //
255  // We had some trouble trying to perform the requested
256  // operation, so we'll abort the I/O request with
257  // the error status that we get back from the
258  // execption code
259  //
260 
261  Status = FatProcessException( IrpContext, Irp, _SEH2_GetExceptionCode() );
262  } _SEH2_END;
263 
264  if (TopLevel) { IoSetTopLevelIrp( NULL ); }
265 
267 
268  //
269  // And return to our caller
270  //
271 
272  DebugTrace(-1, Dbg, "FatFsdQueryInformation -> %08lx\n", Status);
273 
274  UNREFERENCED_PARAMETER( VolumeDeviceObject );
275 
276  return Status;
277 }
#define FsRtlEnterFileSystem
BOOLEAN FatIsIrpTopLevel(IN PIRP Irp)
Definition: fatdata.c:817
#define FsRtlExitFileSystem
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
_SEH2_TRY
Definition: create.c:4226
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2410
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:11
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define Dbg
Definition: fileinfo.c:29
PIRP_CONTEXT FatCreateIrpContext(IN PIRP Irp, IN BOOLEAN Wait)
Definition: strucsup.c:2289
#define CanFsdWait(I)
Definition: cdprocs.h:2001
VOID NTAPI IoSetTopLevelIrp(IN PIRP Irp)
Definition: irp.c:2000
Status
Definition: gdiplustypes.h:24
_SEH2_END
Definition: create.c:4400
ULONG FatExceptionFilter(IN PIRP_CONTEXT IrpContext, IN PEXCEPTION_POINTERS ExceptionPointer)
Definition: fatdata.c:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
#define PAGED_CODE()

◆ FatQueryBasicInfo()

VOID FatQueryBasicInfo ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN PFILE_OBJECT  FileObject,
IN OUT PFILE_BASIC_INFORMATION  Buffer,
IN OUT PLONG  Length 
)

Definition at line 1044 of file fileinfo.c.

1075 {
1076  PAGED_CODE();
1077 
1079  UNREFERENCED_PARAMETER( IrpContext );
1080 
1081  DebugTrace(+1, Dbg, "FatQueryBasicInfo...\n", 0);
1082 
1083  //
1084  // Zero out the output buffer, and set it to indicate that
1085  // the query is a normal file. Later we might overwrite the
1086  // attribute.
1087  //
1088 
1090 
1091  //
1092  // Extract the data and fill in the non zero fields of the output
1093  // buffer
1094  //
1095 
1096  if (Fcb->Header.NodeTypeCode == FAT_NTC_ROOT_DCB) {
1097 
1098  //
1099  // We have to munge a lie on the fly. Every time we have to
1100  // use 1/1/80 we need to convert to GMT since the TZ may have
1101  // changed on us.
1102  //
1103 
1105  &Buffer->LastWriteTime );
1106  Buffer->CreationTime = Buffer->LastAccessTime = Buffer->LastWriteTime;
1107 
1108  } else {
1109 
1110  Buffer->LastWriteTime = Fcb->LastWriteTime;
1111  Buffer->CreationTime = Fcb->CreationTime;
1112  Buffer->LastAccessTime = Fcb->LastAccessTime;
1113  }
1114 
1115  Buffer->FileAttributes = Fcb->DirentFatFlags;
1116 
1117 
1118  //
1119  // If the temporary flag is set, then set it in the buffer.
1120  //
1121 
1123 
1124  SetFlag( Buffer->FileAttributes, FILE_ATTRIBUTE_TEMPORARY );
1125  }
1126 
1127  //
1128  // If no attributes were set, set the normal bit.
1129  //
1130 
1131  if (Buffer->FileAttributes == 0) {
1132 
1133  Buffer->FileAttributes = FILE_ATTRIBUTE_NORMAL;
1134  }
1135 
1136  //
1137  // Update the length and status output variables
1138  //
1139 
1140  *Length -= sizeof( FILE_BASIC_INFORMATION );
1141 
1142  DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
1143 
1144  DebugTrace(-1, Dbg, "FatQueryBasicInfo -> VOID\n", 0);
1145 
1146  return;
1147 }
LONGLONG CreationTime
Definition: cdstruc.h:1036
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:921
#define FILE_ATTRIBUTE_TEMPORARY
Definition: nt_native.h:708
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define FCB_STATE_TEMPORARY
Definition: fatstruc.h:1197
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:920
LARGE_INTEGER FatJanOne1980
Definition: fatdata.c:73
UCHAR DirentFatFlags
Definition: fatstruc.h:1132
Definition: bufpool.h:45
#define Dbg
Definition: fileinfo.c:29
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define ExLocalTimeToSystemTime(LocTime, SysTime)
Definition: env_spec_w32.h:738
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
_In_ PFCB Fcb
Definition: cdprocs.h:159
ULONG FcbState
Definition: cdstruc.h:977
#define PAGED_CODE()
#define FILE_BASIC_INFORMATION
Definition: disk.h:53

◆ FatQueryEaInfo()

VOID FatQueryEaInfo ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN OUT PFILE_EA_INFORMATION  Buffer,
IN OUT PLONG  Length 
)

Definition at line 1306 of file fileinfo.c.

1335 {
1336  PBCB Bcb;
1337 
1338  PAGED_CODE();
1339 
1341  UNREFERENCED_PARAMETER( IrpContext );
1342 
1343  DebugTrace(+1, Dbg, "FatQueryEaInfo...\n", 0);
1344 
1345  Bcb = NULL;
1346 
1347  _SEH2_TRY {
1348 
1349  //
1350  // Zero out the output buffer
1351  //
1352 
1354 
1355 #if 0
1356  //
1357  // The Root dcb does not have any EAs so don't look for any. Fat32
1358  // doesn't have any, either.
1359  //
1360 
1361  if ( NodeType( Fcb ) != FAT_NTC_ROOT_DCB &&
1362  !FatIsFat32( Fcb->Vcb )) {
1363 
1364  PDIRENT Dirent;
1365 
1366  //
1367  // Try to get the dirent for this file.
1368  //
1369 
1370  FatGetDirentFromFcbOrDcb( IrpContext,
1371  Fcb,
1372  &Dirent,
1373  &Bcb );
1374 
1375  if (Dirent != NULL) {
1376 
1377  //
1378  // Get a the size needed to store the full eas for the file.
1379  //
1380 
1381  FatGetEaLength( IrpContext,
1382  Fcb->Vcb,
1383  Dirent,
1384  &Buffer->EaSize );
1385  }
1386  }
1387 #endif
1388 
1389  //
1390  // Update the length and status output variables
1391  //
1392 
1393  *Length -= sizeof( FILE_EA_INFORMATION );
1394 
1395  } _SEH2_FINALLY {
1396 
1398 
1399  //
1400  // Unpin the dirent if pinned.
1401  //
1402 
1403  FatUnpinBcb( IrpContext, Bcb );
1404 
1405  DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
1406 
1407  DebugTrace(-1, Dbg, "FatQueryEaInfo -> VOID\n", 0);
1408  } _SEH2_END;
1409 }
IN PVCB IN VBO IN ULONG OUT PBCB * Bcb
Definition: fatprocs.h:411
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
_SEH2_TRY
Definition: create.c:4226
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
#define Dbg
Definition: fileinfo.c:29
NodeType
Definition: Node.h:5
#define DebugUnwind(X)
Definition: fatdata.h:315
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
struct _FILE_EA_INFORMATION FILE_EA_INFORMATION
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446
_SEH2_END
Definition: create.c:4400
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
_SEH2_FINALLY
Definition: create.c:4371
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:424
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PVCB Vcb
Definition: cdstruc.h:939
_In_ PFCB Fcb
Definition: cdprocs.h:159
VOID FatQueryEaInfo(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN OUT PFILE_EA_INFORMATION Buffer, IN OUT PLONG Length)
Definition: fileinfo.c:1306
#define PAGED_CODE()

◆ FatQueryInternalInfo()

VOID FatQueryInternalInfo ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN OUT PFILE_INTERNAL_INFORMATION  Buffer,
IN OUT PLONG  Length 
)

Definition at line 1242 of file fileinfo.c.

1271 {
1272  PAGED_CODE();
1273 
1274  UNREFERENCED_PARAMETER( IrpContext );
1275 
1276  DebugTrace(+1, Dbg, "FatQueryInternalInfo...\n", 0);
1277 
1278  _SEH2_TRY {
1279 
1280  Buffer->IndexNumber.QuadPart = FatGenerateFileIdFromFcb( Fcb );
1281 
1282  //
1283  // Update the length and status output variables
1284  //
1285 
1286  *Length -= sizeof( FILE_INTERNAL_INFORMATION );
1287 
1288  } _SEH2_FINALLY {
1289 
1291 
1292  DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
1293 
1294  DebugTrace(-1, Dbg, "FatQueryInternalInfo -> VOID\n", 0);
1295  } _SEH2_END;
1296 
1297  return;
1298 }
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
VOID FatQueryInternalInfo(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN OUT PFILE_INTERNAL_INFORMATION Buffer, IN OUT PLONG Length)
Definition: fileinfo.c:1242
_SEH2_TRY
Definition: create.c:4226
Definition: bufpool.h:45
#define Dbg
Definition: fileinfo.c:29
#define DebugUnwind(X)
Definition: fatdata.h:315
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define FatGenerateFileIdFromFcb(Fcb)
Definition: fatprocs.h:3063
_SEH2_END
Definition: create.c:4400
_SEH2_FINALLY
Definition: create.c:4371
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define PAGED_CODE()

◆ FatQueryPositionInfo()

VOID FatQueryPositionInfo ( IN PIRP_CONTEXT  IrpContext,
IN PFILE_OBJECT  FileObject,
IN OUT PFILE_POSITION_INFORMATION  Buffer,
IN OUT PLONG  Length 
)

Definition at line 1417 of file fileinfo.c.

1446 {
1447  PAGED_CODE();
1448 
1449  DebugTrace(+1, Dbg, "FatQueryPositionInfo...\n", 0);
1450 
1451  //
1452  // Get the current position found in the file object.
1453  //
1454 
1455  Buffer->CurrentByteOffset = FileObject->CurrentByteOffset;
1456 
1457  //
1458  // Update the length and status output variables
1459  //
1460 
1461  *Length -= sizeof( FILE_POSITION_INFORMATION );
1462 
1463  DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
1464 
1465  DebugTrace(-1, Dbg, "FatQueryPositionInfo -> VOID\n", 0);
1466 
1467  UNREFERENCED_PARAMETER( IrpContext );
1468 
1469  return;
1470 }
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
Definition: bufpool.h:45
#define Dbg
Definition: fileinfo.c:29
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define PAGED_CODE()

◆ FatQueryShortNameInfo()

VOID FatQueryShortNameInfo ( IN PIRP_CONTEXT  IrpContext,
IN PFCB  Fcb,
IN OUT PFILE_NAME_INFORMATION  Buffer,
IN OUT PLONG  Length 
)

Definition at line 1686 of file fileinfo.c.

1715 {
1716  NTSTATUS Status;
1717 
1719  WCHAR ShortNameBuffer[12];
1721 
1722  PAGED_CODE();
1723 
1724  DebugTrace(+1, Dbg, "FatQueryNameInfo...\n", 0);
1725 
1726  //
1727  // Convert the name to UNICODE
1728  //
1729 
1730  ShortName.Length = 0;
1731  ShortName.MaximumLength = sizeof(ShortNameBuffer);
1732  ShortName.Buffer = ShortNameBuffer;
1733 
1735 
1736 #ifdef _MSC_VER
1737 #pragma prefast( suppress:28931, "needed for debug build" )
1738 #endif
1740  &Fcb->ShortName.Name.Oem,
1741  FALSE );
1742 
1744 
1745  //
1746  // If we overflow, set *Length to -1 as a flag.
1747  //
1748 
1749  if (*Length < ShortName.Length) {
1750 
1751  BytesToCopy = *Length;
1752  *Length = -1;
1753 
1754  } else {
1755 
1756  BytesToCopy = ShortName.Length;
1757  *Length -= ShortName.Length;
1758  }
1759 
1760  RtlCopyMemory( &Buffer->FileName[0],
1761  &ShortName.Buffer[0],
1762  BytesToCopy );
1763 
1764  Buffer->FileNameLength = ShortName.Length;
1765 
1766  //
1767  // Return to caller
1768  //
1769 
1770  DebugTrace( 0, Dbg, "*Length = %08lx\n", *Length);
1771 
1772  DebugTrace(-1, Dbg, "FatQueryNameInfo -> VOID\n", 0);
1773 
1774  UNREFERENCED_PARAMETER( IrpContext );
1775 
1776  return;
1777 }
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING ShortName
Definition: fatprocs.h:1303
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
union _FILE_NAME_NODE::@710 Name
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
NTSTATUS NTAPI RtlOemStringToCountedUnicodeString(IN OUT PUNICODE_STRING UniDest, IN PCOEM_STRING OemSource, IN BOOLEAN AllocateDestinationString)
Definition: unicode.c:1463
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3167
Definition: bufpool.h:45
#define Dbg
Definition: fileinfo.c:29
OEM_STRING Oem
Definition: fatstruc.h:692
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
Status
Definition: gdiplustypes.h:24
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB Fcb
Definition: cdprocs.h:159
return STATUS_SUCCESS
Definition: btrfs.c:3014
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1114
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312

◆ FatSetPositionInfo()

NTSTATUS FatSetPositionInfo ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp,
IN PFILE_OBJECT  FileObject 
)

Definition at line 4010 of file fileinfo.c.

4036 {
4038 
4039  PAGED_CODE();
4040 
4041  DebugTrace(+1, Dbg, "FatSetPositionInfo...\n", 0);
4042 
4043  Buffer = Irp->AssociatedIrp.SystemBuffer;
4044 
4045  //
4046  // Check if the file does not use intermediate buffering. If it
4047  // does not use intermediate buffering then the new position we're
4048  // supplied must be aligned properly for the device
4049  //
4050 
4052 
4054 
4056 
4057  if ((Buffer->CurrentByteOffset.LowPart & DeviceObject->AlignmentRequirement) != 0) {
4058 
4059  DebugTrace(0, Dbg, "Cannot set position due to aligment conflict\n", 0);
4060  DebugTrace(-1, Dbg, "FatSetPositionInfo -> %08lx\n", STATUS_INVALID_PARAMETER);
4061 
4062  return STATUS_INVALID_PARAMETER;
4063  }
4064  }
4065 
4066  //
4067  // The input parameter is fine so set the current byte offset and
4068  // complete the request
4069  //
4070 
4071  DebugTrace(0, Dbg, "Set the new position to %08lx\n", Buffer->CurrentByteOffset);
4072 
4073  FileObject->CurrentByteOffset = Buffer->CurrentByteOffset;
4074 
4075  DebugTrace(-1, Dbg, "FatSetPositionInfo -> %08lx\n", STATUS_SUCCESS);
4076 
4077  UNREFERENCED_PARAMETER( IrpContext );
4078 
4079  return STATUS_SUCCESS;
4080 }
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
#define FO_NO_INTERMEDIATE_BUFFERING
Definition: iotypes.h:1737
Definition: bufpool.h:45
#define Dbg
Definition: fileinfo.c:29
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
PDEVICE_OBJECT DeviceObject
Definition: iotypes.h:2869
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ULONG AlignmentRequirement
Definition: env_spec_w32.h:420
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1569
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define PAGED_CODE()

◆ FatSetRenameInfo()

NTSTATUS FatSetRenameInfo ( IN PIRP_CONTEXT  IrpContext,
IN PIRP  Irp,
IN PVCB  Vcb,
IN PFCB  Fcb,
IN PCCB  Ccb 
)

Definition at line 2694 of file fileinfo.c.

2728 {
2731  BOOLEAN CaseOnlyRename;
2732  BOOLEAN ContinueWithRename;
2734  BOOLEAN DeleteSourceDirent;
2735  BOOLEAN DeleteTarget;
2736  BOOLEAN NewDirentFromPool;
2737  BOOLEAN RenamedAcrossDirectories;
2738  BOOLEAN ReplaceIfExists;
2739 
2740  CCB LocalCcb;
2741  PCCB SourceCcb;
2742 
2743  DIRENT Dirent;
2744 
2746 
2747  OEM_STRING OldOemName;
2748  OEM_STRING NewOemName;
2749  UCHAR OemNameBuffer[24*2];
2750 
2751  PBCB DotDotBcb;
2752  PBCB NewDirentBcb;
2753  PBCB OldDirentBcb;
2754  PBCB SecondPageBcb;
2755  PBCB TargetDirentBcb;
2756 
2757  PDCB TargetDcb = NULL;
2758  PDCB OldParentDcb;
2759 
2760  PDIRENT DotDotDirent = NULL;
2761  PDIRENT FirstPageDirent = NULL;
2762  PDIRENT NewDirent = NULL;
2763  PDIRENT OldDirent = NULL;
2764  PDIRENT SecondPageDirent = NULL;
2765  PDIRENT ShortDirent = NULL;
2766  PDIRENT TargetDirent = NULL;
2767 
2768  PFCB TempFcb;
2769 
2770  PFILE_OBJECT TargetFileObject;
2772 
2774 
2775  PLIST_ENTRY Links;
2776 
2777  ULONG BytesInFirstPage = 0;
2778  ULONG DirentsInFirstPage = 0;
2779  ULONG DirentsRequired = 0;
2780  ULONG NewOffset = 0;
2781  ULONG NotifyAction = 0;
2782  ULONG SecondPageOffset = 0;
2783  ULONG ShortDirentOffset = 0;
2784  ULONG TargetDirentOffset = 0;
2785  ULONG TargetLfnOffset = 0;
2786 
2787  // NewName comes from the IRP buffer or the TargetFileObject, so we can't
2788  // go around modifying it. Instead we modify NewNameCopy.
2790 
2791  // NB: these five UNICODE_STRINGS are allocated
2792  // from one chopped up pool allocation called UnicodeBuffer.
2793  UNICODE_STRING NewNameCopy;
2794  UNICODE_STRING NewUpcasedName;
2795  UNICODE_STRING OldName;
2796  UNICODE_STRING OldUpcasedName;
2797  UNICODE_STRING TargetLfn;
2798  PWCHAR UnicodeBuffer;
2799 
2800  UNICODE_STRING TargetOrigLfn = {0};
2801 
2802  UNICODE_STRING UniTunneledShortName;
2803  WCHAR UniTunneledShortNameBuffer[12];
2804  UNICODE_STRING UniTunneledLongName;
2805  WCHAR UniTunneledLongNameBuffer[26];
2806 
2807  LARGE_INTEGER TunneledCreationTime;
2808  ULONG TunneledDataSize;
2809  BOOLEAN HaveTunneledInformation = FALSE;
2810  BOOLEAN UsingTunneledLfn = FALSE;
2811 
2812  BOOLEAN InvalidateFcbOnRaise = FALSE;
2813 
2814  PFILE_OBJECT DirectoryFileObject = NULL;
2815  ULONG Flags = 0;
2816 
2817  PAGED_CODE();
2818 
2819  DebugTrace(+1, Dbg, "FatSetRenameInfo...\n", 0);
2820 
2821  //
2822  // P H A S E 0: Initialize some variables.
2823  //
2824 
2825  CaseOnlyRename = FALSE;
2826  ContinueWithRename = FALSE;
2827  DeleteSourceDirent = FALSE;
2828  DeleteTarget = FALSE;
2829  NewDirentFromPool = FALSE;
2830  RenamedAcrossDirectories = FALSE;
2831 
2832  DotDotBcb = NULL;
2833  NewDirentBcb = NULL;
2834  OldDirentBcb = NULL;
2835  SecondPageBcb = NULL;
2836  TargetDirentBcb = NULL;
2837 
2838  NewOemName.Length = 0;
2839  NewOemName.MaximumLength = 24;
2840  NewOemName.Buffer = (PCHAR)&OemNameBuffer[0];
2841 
2842  OldOemName.Length = 0;
2843  OldOemName.MaximumLength = 24;
2844  OldOemName.Buffer = (PCHAR)&OemNameBuffer[24];
2845 
2846  UnicodeBuffer = FsRtlAllocatePoolWithTag( PagedPool,
2847  5 * MAX_LFN_CHARACTERS * sizeof(WCHAR),
2849 
2850  NewUpcasedName.Length = 0;
2851  NewUpcasedName.MaximumLength = MAX_LFN_CHARACTERS * sizeof(WCHAR);
2852  NewUpcasedName.Buffer = &UnicodeBuffer[0];
2853 
2854  OldName.Length = 0;
2855  OldName.MaximumLength = MAX_LFN_CHARACTERS * sizeof(WCHAR);
2856  OldName.Buffer = &UnicodeBuffer[MAX_LFN_CHARACTERS];
2857 
2858  OldUpcasedName.Length = 0;
2859  OldUpcasedName.MaximumLength = MAX_LFN_CHARACTERS * sizeof(WCHAR);
2860  OldUpcasedName.Buffer = &UnicodeBuffer[MAX_LFN_CHARACTERS * 2];
2861 
2862  TargetLfn.Length = 0;
2863  TargetLfn.MaximumLength = MAX_LFN_CHARACTERS * sizeof(WCHAR);
2864  TargetLfn.Buffer = &UnicodeBuffer[MAX_LFN_CHARACTERS * 3];
2865 
2866  NewNameCopy.Length = 0;
2867  NewNameCopy.MaximumLength = MAX_LFN_CHARACTERS * sizeof(WCHAR);
2868  NewNameCopy.Buffer = &UnicodeBuffer[MAX_LFN_CHARACTERS * 4];
2869 
2870  UniTunneledShortName.Length = 0;
2871  UniTunneledShortName.MaximumLength = sizeof(UniTunneledShortNameBuffer);
2872  UniTunneledShortName.Buffer = &UniTunneledShortNameBuffer[0];
2873 
2874  UniTunneledLongName.Length = 0;
2875  UniTunneledLongName.MaximumLength = sizeof(UniTunneledLongNameBuffer);
2876  UniTunneledLongName.Buffer = &UniTunneledLongNameBuffer[0];
2877 
2878  //
2879  // Remember the name in case we have to modify the name
2880  // value in the ea.
2881  //
2882 
2883  RtlCopyMemory( OldOemName.Buffer,
2884  Fcb->ShortName.Name.Oem.Buffer,
2885  OldOemName.Length );
2886 
2887  //
2888  // Get the current stack location
2889  //
2890 
2892 
2893  //
2894  // Extract information from the Irp to make our life easier
2895  //
2896 
2898  SourceCcb = FileObject->FsContext2;
2899  TargetFileObject = IrpSp->Parameters.SetFile.FileObject;
2900  ReplaceIfExists = IrpSp->Parameters.SetFile.ReplaceIfExists;
2901 
2902  RtlZeroMemory( &LocalCcb, sizeof(CCB) );
2903 
2904  //
2905  // P H A S E 1:
2906  //
2907  // Test if rename is legal. Only small side-effects are not undone.
2908  //
2909 
2910  _SEH2_TRY {
2911 
2912  //
2913  // Can't rename the root directory
2914  //
2915 
2916  if ( NodeType(Fcb) == FAT_NTC_ROOT_DCB ) {
2917 
2919  }
2920 
2921  //
2922  // Check that we were not given a dcb with open handles beneath
2923  // it. If there are only UncleanCount == 0 Fcbs beneath us, then
2924  // remove them from the prefix table, and they will just close
2925  // and go away naturally.
2926  //
2927 
2928  if (NodeType(Fcb) == FAT_NTC_DCB) {
2929 
2930  PFCB BatchOplockFcb;
2931  ULONG BatchOplockCount;
2932 
2933  //
2934  // Loop until there are no batch oplocks in the subtree below
2935  // this directory.
2936  //
2937 
2938  while (TRUE) {
2939 
2940  BatchOplockFcb = NULL;
2941  BatchOplockCount = 0;
2942 
2943  //
2944  // First look for any UncleanCount != 0 Fcbs, and fail if we
2945  // find any.
2946  //
2947 
2948  for ( TempFcb = FatGetNextFcbBottomUp(IrpContext, NULL, Fcb);
2949  TempFcb != Fcb;
2950  TempFcb = FatGetNextFcbBottomUp(IrpContext, TempFcb, Fcb) ) {
2951 
2952  if ( TempFcb->UncleanCount != 0 ) {
2953 
2954  //
2955  // If there is a batch oplock on this file then
2956  // increment our count and remember the Fcb if
2957  // this is the first.
2958  //
2959 
2960  if (FatIsFileOplockable( TempFcb ) &&
2962 #if (NTDDI_VERSION >= NTDDI_WIN7)
2963  ||
2964  FsRtlCurrentOplockH( FatGetFcbOplock(TempFcb) )
2965 #endif
2966  )) {
2967 
2968  BatchOplockCount += 1;
2969  if ( BatchOplockFcb == NULL ) {
2970 
2971  BatchOplockFcb = TempFcb;
2972  }
2973 
2974  } else {
2975 
2977  }
2978  }
2979  }
2980 
2981  //
2982  // If this is not the first pass for rename and the number
2983  // of batch oplocks has not decreased then give up.
2984  //
2985 
2986  if ( BatchOplockFcb != NULL ) {
2987 
2988  if ( (Irp->IoStatus.Information != 0) &&
2989  (BatchOplockCount >= Irp->IoStatus.Information) ) {
2990 
2992  }
2993 
2994  //
2995  // Try to break this batch oplock.
2996  //
2997 
2998  Irp->IoStatus.Information = BatchOplockCount;
2999  Status = FsRtlCheckOplock( FatGetFcbOplock(BatchOplockFcb),
3000  Irp,
3001  IrpContext,
3003  NULL );
3004 
3005  //
3006  // If the oplock was already broken then look for more
3007  // batch oplocks.
3008  //
3009 
3010  if (Status == STATUS_SUCCESS) {
3011 
3012  continue;
3013  }
3014 
3015  //
3016  // Otherwise the oplock package will post or complete the
3017  // request.
3018  //
3019 
3021  }
3022 
3023  break;
3024  }
3025 
3026  //
3027  // Now try to get as many of these file object, and thus Fcbs
3028  // to go away as possible, flushing first, of course.
3029  //
3030 
3031  FatPurgeReferencedFileObjects( IrpContext, Fcb, Flush );
3032 
3033  //
3034  // OK, so there are no UncleanCount != 0, Fcbs. Infact, there
3035  // shouldn't really be any Fcbs left at all, except obstinate
3036  // ones from user mapped sections .... Remove the full file name
3037  // and exact case lfn.
3038  //
3039 
3040  for ( TempFcb = FatGetNextFcbBottomUp(IrpContext, NULL, Fcb);
3041  TempFcb != Fcb;
3042  TempFcb = FatGetNextFcbBottomUp(IrpContext, TempFcb, Fcb) ) {
3043 
3044  FatAcquireExclusiveFcb( IrpContext, TempFcb );
3045 
3046  if (TempFcb->FullFileName.Buffer != NULL) {
3047 
3048  ExFreePool( TempFcb->FullFileName.Buffer );
3049  TempFcb->FullFileName.Buffer = NULL;
3050  }
3051 
3052  FatReleaseFcb( IrpContext, TempFcb );
3053  }
3054  }
3055 
3056  //
3057  // Check if this is a simple rename or a fully-qualified rename
3058  // In both cases we need to figure out what the TargetDcb, and
3059  // NewName are.
3060  //
3061 
3062  if (TargetFileObject == NULL) {
3063 
3064  //
3065  // In the case of a simple rename the target dcb is the
3066  // same as the source file's parent dcb, and the new file name
3067  // is taken from the system buffer
3068  //
3069 
3071 
3072  Buffer = Irp->AssociatedIrp.SystemBuffer;
3073 
3074  TargetDcb = Fcb->ParentDcb;
3075 
3076  NewName.Length = (USHORT) Buffer->FileNameLength;
3077  NewName.Buffer = (PWSTR) &Buffer->FileName;
3078 
3079  //
3080  // Make sure the name is of legal length.
3081  //
3082 
3083  if (NewName.Length > 255*sizeof(WCHAR)) {
3084 
3086  }
3087 
3088  RtlCopyUnicodeString(&NewNameCopy,&NewName);
3089 
3090  } else {
3091 
3092  //
3093  // For a fully-qualified rename the target dcb is taken from
3094  // the target file object, which must be on the same vcb as
3095  // the source.
3096  //
3097 
3098  PVCB TargetVcb;
3099  PCCB TargetCcb;
3100 
3101  if ((FatDecodeFileObject( TargetFileObject,
3102  &TargetVcb,
3103  &TargetDcb,
3104  &TargetCcb ) != UserDirectoryOpen) ||
3105  (TargetVcb != Vcb)) {
3106 
3108  }
3109 
3110  //
3111  // This name is by definition legal.
3112  //
3113 
3114  NewName = *((PUNICODE_STRING)&TargetFileObject->FileName);
3115 
3116  RtlCopyUnicodeString(&NewNameCopy,&NewName);
3117 
3118  }
3119 
3120  //
3121  // We will need an upcased version of the unicode name and the
3122  // old name as well.
3123  //
3124 
3125  Status = RtlUpcaseUnicodeString( &NewUpcasedName, &NewName, FALSE );
3126 
3127  if (!NT_SUCCESS(Status)) {
3128 
3129  try_return( Status );
3130  }
3131 
3132  FatGetUnicodeNameFromFcb( IrpContext, Fcb, &OldName );
3133 
3134  Status = RtlUpcaseUnicodeString( &OldUpcasedName, &OldName, FALSE );
3135 
3136  if (!NT_SUCCESS(Status)) {
3137  try_return(Status);
3138  }
3139 
3140  //
3141  // Check if the current name and new name are equal, and the
3142  // DCBs are equal. If they are then our work is already done.
3143  //
3144 
3145  if (TargetDcb == Fcb->ParentDcb) {
3146 
3147  //
3148  // OK, now if we found something then check if it was an exact
3149  // match or just a case match. If it was an exact match, then
3150  // we can bail here.
3151  //
3152 
3154  &OldName,
3155  FALSE,
3156  NULL )) {
3157 
3159  }
3160 
3161  //
3162  // Check now for a case only rename.
3163  //
3164 
3165 
3166  if (FsRtlAreNamesEqual( &NewUpcasedName,
3167  &OldUpcasedName,
3168  FALSE,
3169  NULL )) {
3170 
3171  CaseOnlyRename = TRUE;
3172  }
3173 
3174  } else {
3175 
3176  RenamedAcrossDirectories = TRUE;
3177  }
3178 
3179  //
3180  // Upcase the name and convert it to the Oem code page.
3181  //
3182  // If the new UNICODE name is already more than 12 characters,
3183  // then we know the Oem name will not be valid
3184  //
3185 
3186  if (NewName.Length <= 12*sizeof(WCHAR)) {
3187 
3188  FatUnicodeToUpcaseOem( IrpContext, &NewOemName, &NewName );
3189 
3190  //
3191  // If the name is not valid 8.3, zero the length.
3192  //
3193 
3194  if (FatSpaceInName( IrpContext, &NewName ) ||
3195  !FatIsNameShortOemValid( IrpContext, NewOemName, FALSE, FALSE, FALSE)) {
3196 
3197  NewOemName.Length = 0;
3198  }
3199 
3200  } else {
3201 
3202  NewOemName.Length = 0;
3203  }
3204 
3205  //
3206  // Look in the tunnel cache for names and timestamps to restore
3207  //
3208 
3209  TunneledDataSize = sizeof(LARGE_INTEGER);
3210  HaveTunneledInformation = FsRtlFindInTunnelCache( &Vcb->Tunnel,
3212  &NewName,
3213  &UniTunneledShortName,
3214  &UniTunneledLongName,
3215  &TunneledDataSize,
3216  &TunneledCreationTime );
3217  NT_ASSERT(TunneledDataSize == sizeof(LARGE_INTEGER));
3218 
3219 
3220  //
3221  // Now we need to determine how many dirents this new name will
3222  // require.
3223  //
3224 
3225  if ((NewOemName.Length == 0) ||
3226  (FatEvaluateNameCase( IrpContext,
3227  &NewNameCopy,
3230  &CreateLfn ),
3231  CreateLfn)) {
3232 
3233  DirentsRequired = FAT_LFN_DIRENTS_NEEDED(&NewNameCopy) + 1;
3234 
3235  } else {
3236 
3237  //
3238  // The user-given name is a short name, but we might still have
3239  // a tunneled long name we want to use. See if we can.
3240  //
3241 
3242  if (UniTunneledLongName.Length &&
3243  !FatLfnDirentExists(IrpContext, TargetDcb, &UniTunneledLongName, &TargetLfn)) {
3244 
3245  UsingTunneledLfn = CreateLfn = TRUE;
3246  DirentsRequired = FAT_LFN_DIRENTS_NEEDED(&UniTunneledLongName) + 1;
3247 
3248  } else {
3249 
3250  //
3251  // This really is a simple dirent. Note that the two AllLower BOOLEANs
3252  // are correctly set now.
3253  //
3254 
3255  DirentsRequired = 1;
3256 
3257 
3258  }
3259  }
3260 
3261  //
3262  // Do some extra checks here if we are not in Chicago mode.
3263  //
3264 
3265  if (!FatData.ChicagoMode) {
3266 
3267  //
3268  // If the name was not 8.3 valid, fail the rename.
3269  //
3270 
3271  if (NewOemName.Length == 0) {
3272 
3274  }
3275 
3276  //
3277  // Don't use the magic bits.
3278  //
3279 
3282  CreateLfn = FALSE;
3283  UsingTunneledLfn = FALSE;
3284  }
3285 
3286  if (!CaseOnlyRename) {
3287 
3288  //
3289  // Check if the new name already exists, wait is known to be
3290  // true.
3291  //
3292 
3293  if (NewOemName.Length != 0) {
3294 
3295  FatStringTo8dot3( IrpContext,
3296  NewOemName,
3297  &LocalCcb.OemQueryTemplate.Constant );
3298 
3299  } else {
3300 
3302  }
3303 
3304  LocalCcb.UnicodeQueryTemplate = NewUpcasedName;
3305  LocalCcb.ContainsWildCards = FALSE;
3306 
3307  Flags = 0;
3308 
3309 
3310  FatLocateDirent( IrpContext,
3311  TargetDcb,
3312  &LocalCcb,
3313  0,
3314  &Flags,
3315  &TargetDirent,
3316  &TargetDirentBcb,
3317  (PVBO)&TargetDirentOffset,
3318  NULL,
3319  &TargetLfn,
3320  &TargetOrigLfn );
3321 
3322  if (TargetDirent != NULL) {
3323 
3324 
3325  //
3326  // The name already exists, check if the user wants
3327  // to overwrite the name, and has access to do the overwrite
3328  // We cannot overwrite a directory.
3329  //
3330 
3331  if ((!ReplaceIfExists) ||
3332  (FlagOn(TargetDirent->Attributes, FAT_DIRENT_ATTR_DIRECTORY)) ||
3333  (FlagOn(TargetDirent->Attributes, FAT_DIRENT_ATTR_READ_ONLY))) {
3334 
3336  }
3337 
3338  //
3339  // Check that the file has no open user handles, if it does
3340  // then we will deny access. We do the check by searching
3341  // down the list of fcbs opened under our parent Dcb, and making
3342  // sure none of the maching Fcbs have a non-zero unclean count or
3343  // outstanding image sections.
3344  //
3345 
3346  for (Links = TargetDcb->Specific.Dcb.ParentDcbQueue.Flink;
3347  Links != &TargetDcb->Specific.Dcb.ParentDcbQueue; ) {
3348 
3349  TempFcb = CONTAINING_RECORD( Links, FCB, ParentDcbLinks );
3350 
3351  //
3352  // Advance now. The image section flush may cause the final
3353  // close, which will recursively happen underneath of us here.
3354  // It would be unfortunate if we looked through free memory.
3355  //
3356 
3357  Links = Links->Flink;
3358 
3359  if ((TempFcb->DirentOffsetWithinDirectory == TargetDirentOffset) &&
3360  ((TempFcb->UncleanCount != 0) ||
3362  MmFlushForDelete))) {
3363 
3364  //
3365  // If there are batch oplocks on this file then break the
3366  // oplocks before failing the rename.
3367  //
3368 
3370 
3371  if (FatIsFileOplockable( TempFcb ) &&
3373 #if (NTDDI_VERSION >= NTDDI_WIN7)
3374  ||
3375  FsRtlCurrentOplockH( FatGetFcbOplock(TempFcb) )
3376 #endif
3377  )) {
3378 
3379  //
3380  // Do all of our cleanup now since the IrpContext
3381  // could go away when this request is posted.
3382  //
3383 
3384  FatUnpinBcb( IrpContext, TargetDirentBcb );
3385 
3387  Irp,
3388  IrpContext,
3390  NULL );
3391 
3392  if (Status != STATUS_PENDING) {
3393 
3395  }
3396  }
3397 
3398  try_return( NOTHING );
3399  }
3400  }
3401 
3402  //
3403  // OK, this target is toast. Remember the Lfn offset.
3404  //
3405 
3406  TargetLfnOffset = TargetDirentOffset -
3407  FAT_LFN_DIRENTS_NEEDED(&TargetOrigLfn) *
3408  sizeof(DIRENT);
3409 
3410  DeleteTarget = TRUE;
3411  }
3412  }
3413 
3414 
3415  //
3416  // If we will need more dirents than we have, allocate them now.
3417  //
3418 
3419  if ((TargetDcb != Fcb->ParentDcb) ||
3420  (DirentsRequired !=
3422  Fcb->LfnOffsetWithinDirectory) / sizeof(DIRENT) + 1)) {
3423 
3424  //
3425  // Get some new allocation
3426  //
3427 
3428  NewOffset = FatCreateNewDirent( IrpContext,
3429  TargetDcb,
3430  DirentsRequired,
3431  FALSE );
3432 
3433  DeleteSourceDirent = TRUE;
3434 
3435  } else {
3436 
3437  NewOffset = Fcb->LfnOffsetWithinDirectory;
3438  }
3439 
3440  ContinueWithRename = TRUE;
3441 
3442  try_exit: NOTHING;
3443 
3444  } _SEH2_FINALLY {
3445 
3446  if (!ContinueWithRename) {
3447 
3448  //
3449  // Undo everything from above.
3450  //
3451 
3452  ExFreePool( UnicodeBuffer );
3453  FatUnpinBcb( IrpContext, TargetDirentBcb );
3454 
3455  }
3456  } _SEH2_END;
3457 
3458  //
3459  // Now, if we are already done, return here.
3460  //
3461 
3462  if (!ContinueWithRename) {
3463 
3464  return Status;
3465  }
3466 
3467  //
3468  // P H A S E 2: Actually perform the rename.
3469  //
3470 
3471  _SEH2_TRY {
3472 
3473  //
3474  // Report the fact that we are going to remove this entry.
3475  // If we renamed within the same directory and the new name for the
3476  // file did not previously exist, we report this as a rename old
3477  // name. Otherwise this is a removed file.
3478  //
3479 
3480  if (!RenamedAcrossDirectories && !DeleteTarget) {
3481 
3482  NotifyAction = FILE_ACTION_RENAMED_OLD_NAME;
3483 
3484  } else {
3485 
3486  NotifyAction = FILE_ACTION_REMOVED;
3487  }
3488 
3489  FatNotifyReportChange( IrpContext,
3490  Vcb,
3491  Fcb,
3492  ((NodeType( Fcb ) == FAT_NTC_FCB)
3495  NotifyAction );
3496 
3497  _SEH2_TRY {
3498 
3499  //
3500  // Capture a copy of the source dirent.
3501  //
3502 
3503  FatGetDirentFromFcbOrDcb( IrpContext, Fcb, FALSE, &OldDirent, &OldDirentBcb );
3504 
3505  Dirent = *OldDirent;
3506 
3507  //
3508  // Tunnel the source Fcb - the names are disappearing regardless of
3509  // whether the dirent allocation physically changed
3510  //
3511 
3512  FatTunnelFcbOrDcb( Fcb, SourceCcb );
3513 
3514  //
3515  // From here until very nearly the end of the operation, if we raise there
3516  // is no reasonable way to suppose we'd be able to undo the damage. Not
3517  // being a transactional filesystem, FAT is at the mercy of a lot of things
3518  // (as the astute reader has no doubt realized by now).
3519  //
3520 
3521  InvalidateFcbOnRaise = TRUE;
3522 
3523  //
3524  // Delete our current dirent(s) if we got a new one.
3525  //
3526 
3527  if (DeleteSourceDirent) {
3528 
3529  FatDeleteDirent( IrpContext, Fcb, NULL, FALSE );
3530  }
3531 
3532  //
3533  // Delete a target conflict if we were meant to.
3534  //
3535 
3536  if (DeleteTarget) {
3537 
3538  FatDeleteFile( IrpContext,
3539  TargetDcb,
3540  TargetLfnOffset,
3541  TargetDirentOffset,
3542  TargetDirent,
3543  &TargetLfn );
3544  }
3545 
3546  //
3547  // We need to evaluate any short names required. If there were any
3548  // conflicts in existing short names, they would have been deleted above.
3549  //
3550  // It isn't neccesary to worry about the UsingTunneledLfn case. Since we
3551  // actually already know whether CreateLfn will be set either NewName is
3552  // an Lfn and !UsingTunneledLfn is implied or NewName is a short name and
3553  // we can handle that externally.
3554  //
3555 
3556  FatSelectNames( IrpContext,
3557  TargetDcb,
3558  &NewOemName,
3559  &NewNameCopy,
3560  &NewOemName,
3561  (HaveTunneledInformation ? &UniTunneledShortName : NULL),
3564  &CreateLfn );
3565 
3566  if (!CreateLfn && UsingTunneledLfn) {
3567 
3568  CreateLfn = TRUE;
3569  RtlCopyUnicodeString( &NewNameCopy, &UniTunneledLongName );
3570 
3571  //
3572  // Short names are always upcase if an LFN exists
3573  //
3574 
3577  }
3578 
3579  //
3580  // OK, now setup the new dirent(s) for the new name.
3581  //
3582 
3583  FatPrepareWriteDirectoryFile( IrpContext,
3584  TargetDcb,
3585  NewOffset,
3586  sizeof(DIRENT),
3587  &NewDirentBcb,
3588 #ifndef __REACTOS__
3589  &NewDirent,
3590 #else
3591  (PVOID *)&NewDirent,
3592 #endif
3593  FALSE,
3594  TRUE,
3595  &Status );
3596 
3597  NT_ASSERT( NT_SUCCESS( Status ) );
3598 
3599  //
3600  // Deal with the special case of an LFN + Dirent structure crossing
3601  // a page boundry.
3602  //
3603 
3604  if ((NewOffset / PAGE_SIZE) !=
3605  ((NewOffset + (DirentsRequired - 1) * sizeof(DIRENT)) / PAGE_SIZE)) {
3606 
3607  SecondPageOffset = (NewOffset & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
3608 
3609  BytesInFirstPage = SecondPageOffset - NewOffset;
3610 
3611  DirentsInFirstPage = BytesInFirstPage / sizeof(DIRENT);
3612 
3613  FatPrepareWriteDirectoryFile( IrpContext,
3614  TargetDcb,
3615  SecondPageOffset,
3616  sizeof(DIRENT),
3617  &SecondPageBcb,
3618 #ifndef __REACTOS__
3619  &SecondPageDirent,
3620 #else
3621  (PVOID *)&SecondPageDirent,
3622 #endif
3623  FALSE,
3624  TRUE,
3625  &Status );
3626 
3627  NT_ASSERT( NT_SUCCESS( Status ) );
3628 
3629  FirstPageDirent = NewDirent;
3630 
3631  NewDirent = FsRtlAllocatePoolWithTag( PagedPool,
3632  DirentsRequired * sizeof(DIRENT),
3633  TAG_DIRENT );
3634 
3635  NewDirentFromPool = TRUE;
3636  }
3637 
3638  //
3639  // Bump up Dirent and DirentOffset
3640  //
3641 
3642  ShortDirent = NewDirent + DirentsRequired - 1;
3643  ShortDirentOffset = NewOffset + (DirentsRequired - 1) * sizeof(DIRENT);
3644 
3645  //
3646  // Fill in the fields of the dirent.
3647  //
3648 
3649  *ShortDirent = Dirent;
3650 
3651  FatConstructDirent( IrpContext,
3652  ShortDirent,
3653  &NewOemName,
3656  CreateLfn ? &NewNameCopy : NULL,
3657  Dirent.Attributes,
3658  FALSE,
3659  (HaveTunneledInformation ? &TunneledCreationTime : NULL) );
3660 
3661  if (HaveTunneledInformation) {
3662 
3663  //
3664  // Need to go in and fix the timestamps in the FCB. Note that we can't use
3665  // the TunneledCreationTime since the conversions may have failed.
3666  //
3667 
3668  Fcb->CreationTime = FatFatTimeToNtTime(IrpContext, ShortDirent->CreationTime, ShortDirent->CreationMSec);
3669  Fcb->LastWriteTime = FatFatTimeToNtTime(IrpContext, ShortDirent->LastWriteTime, 0);
3670  Fcb->LastAccessTime = FatFatDateToNtTime(IrpContext, ShortDirent->LastAccessDate);
3671  }
3672 
3673 
3674  //
3675  // If the dirent crossed pages, split the contents of the
3676  // temporary pool between the two pages.
3677  //
3678 
3679  if (NewDirentFromPool) {
3680 
3681  RtlCopyMemory( FirstPageDirent, NewDirent, BytesInFirstPage );
3682 
3683  RtlCopyMemory( SecondPageDirent,
3684  NewDirent + DirentsInFirstPage,
3685  DirentsRequired*sizeof(DIRENT) - BytesInFirstPage );
3686 
3687  ShortDirent = SecondPageDirent +
3688  (DirentsRequired - DirentsInFirstPage) - 1;
3689  }
3690 
3691  Dirent = *ShortDirent;
3692 
3693  } _SEH2_FINALLY {
3694 
3695  //
3696  // Remove the entry from the splay table, and then remove the
3697  // full file name and exact case lfn. It is important that we
3698  // always remove the name from the prefix table regardless of
3699  // other errors.
3700  //
3701 
3702  FatRemoveNames( IrpContext, Fcb );
3703 
3704  if (Fcb->FullFileName.Buffer != NULL) {
3705 
3708  }
3709 
3710  if (Fcb->ExactCaseLongName.Buffer) {
3711 
3714  }
3715 
3716  FatUnpinBcb( IrpContext, OldDirentBcb );
3717  FatUnpinBcb( IrpContext, TargetDirentBcb );
3718  FatUnpinBcb( IrpContext, NewDirentBcb );
3719  FatUnpinBcb( IrpContext, SecondPageBcb );
3720  } _SEH2_END;
3721 
3722  //
3723  // Now we need to update the location of the file's directory
3724  // offset and move the fcb from its current parent dcb to
3725  // the target dcb.
3726  //
3727 
3728  Fcb->LfnOffsetWithinDirectory = NewOffset;
3729  Fcb->DirentOffsetWithinDirectory = ShortDirentOffset;
3730 
3732 
3733  //
3734  // There is a deep reason we put files on the tail, others on the head,
3735  // which is to allow us to easily enumerate all child directories before
3736  // child files. This is important to let us maintain whole-volume lockorder
3737  // via BottomUp enumeration.
3738  //
3739 
3740  if (NodeType(Fcb) == FAT_NTC_FCB) {
3741 
3742  InsertTailList( &TargetDcb->Specific.Dcb.ParentDcbQueue,
3743  &Fcb->ParentDcbLinks );
3744 
3745  } else {
3746 
3747  InsertHeadList( &TargetDcb->Specific.Dcb.ParentDcbQueue,
3748  &Fcb->ParentDcbLinks );
3749  }
3750 
3751  OldParentDcb = Fcb->ParentDcb;
3752  Fcb->ParentDcb = TargetDcb;
3753 
3754 #if (NTDDI_VERSION >= NTDDI_WIN8)
3755  //
3756  // Break parent directory oplock on the old parent. Directory oplock
3757  // breaks are always advisory, so we will never block/get STATUS_PENDING
3758  // here.
3759  //
3760 
3761  FsRtlCheckOplockEx( FatGetFcbOplock(OldParentDcb),
3762  IrpContext->OriginatingIrp,
3763  OPLOCK_FLAG_PARENT_OBJECT,
3764  NULL,
3765  NULL,
3766  NULL );
3767 #endif
3768 
3769  //
3770  // If we renamed across directories, some cleanup is now in order.
3771  //
3772 
3773  if (RenamedAcrossDirectories) {
3774 
3775 #if (NTDDI_VERSION >= NTDDI_WIN8)
3776  //
3777  // Break parent directory oplock on the new parent. Directory oplock
3778  // breaks are always advisory, so we will never block/get STATUS_PENDING
3779  // here.
3780  //
3781 
3782  FsRtlCheckOplockEx( FatGetFcbOplock(TargetDcb),
3783  IrpContext->OriginatingIrp,
3784  OPLOCK_FLAG_PARENT_OBJECT,
3785  NULL,
3786  NULL,
3787  NULL );
3788 #endif
3789 
3790  //
3791  // See if we need to uninitialize the cachemap for the source directory.
3792  // Do this now in case we get unlucky and raise trying to finalize the
3793  // operation.
3794  //
3795 
3796  if (IsListEmpty(&OldParentDcb->Specific.Dcb.ParentDcbQueue) &&
3797  (OldParentDcb->OpenCount == 0) &&
3798  (OldParentDcb->Specific.Dcb.DirectoryFile != NULL)) {
3799 
3800  NT_ASSERT( NodeType(OldParentDcb) == FAT_NTC_DCB );
3801 
3802  DirectoryFileObject = OldParentDcb->Specific.Dcb.DirectoryFile;
3803 
3804  OldParentDcb->Specific.Dcb.DirectoryFile = NULL;
3805  }
3806 
3807  //
3808  // If we move a directory across directories, we have to change
3809  // the cluster number in its .. entry
3810  //
3811 
3812  if (NodeType(Fcb) == FAT_NTC_DCB) {
3813 
3814  FatPrepareWriteDirectoryFile( IrpContext,
3815  Fcb,
3816  sizeof(DIRENT),
3817  sizeof(DIRENT),
3818  &DotDotBcb,
3819 #ifndef __REACTOS__
3820  &DotDotDirent,
3821 #else
3822  (PVOID *)&DotDotDirent,
3823 #endif
3824  FALSE,
3825  TRUE,
3826  &Status );
3827 
3828  NT_ASSERT( NT_SUCCESS( Status ) );
3829 
3830  DotDotDirent->FirstClusterOfFile = (USHORT)
3833 
3834  if (FatIsFat32( Vcb )) {
3835 
3836  DotDotDirent->FirstClusterOfFileHi = (USHORT)
3838  0 : (TargetDcb->FirstClusterOfFile >> 16));
3839  }
3840  }
3841  }
3842 
3843  //
3844  // Now we need to setup the splay table and the name within
3845  // the fcb. Free the old short name at this point.
3846  //
3847 
3848  ExFreePool( Fcb->ShortName.Name.Oem.Buffer );
3849  Fcb->ShortName.Name.Oem.Buffer = NULL;
3850 
3851 
3852  FatConstructNamesInFcb( IrpContext,
3853  Fcb,
3854  &Dirent,
3855  CreateLfn ? &NewName : NULL );
3856 
3857  FatSetFullNameInFcb( IrpContext, Fcb, &NewName );
3858 
3859  //
3860  // The rest of the actions taken are not related to correctness of
3861  // the in-memory structures, so we shouldn't toast the Fcb if we
3862  // raise from here to the end.
3863  //
3864 
3865  InvalidateFcbOnRaise = FALSE;
3866 
3867  //
3868  // If a file, set the file as modified so that the archive bit
3869  // is set. We prevent this from adjusting the write time by
3870  // indicating the user flag in the ccb.
3871  //
3872 
3873  if (Fcb->Header.NodeTypeCode == FAT_NTC_FCB) {
3874 
3875  SetFlag( FileObject->Flags, FO_FILE_MODIFIED );
3877  }
3878 
3879  //
3880  // We have three cases to report.
3881  //
3882  // 1. If we overwrote an existing file, we report this as
3883  // a modified file.
3884  //
3885  // 2. If we renamed to a new directory, then we added a file.
3886  //
3887  // 3. If we renamed in the same directory, then we report the
3888  // the renamednewname.
3889  //
3890 
3891  if (DeleteTarget) {
3892 
3893  FatNotifyReportChange( IrpContext,
3894  Vcb,
3895  Fcb,
3903 
3904  } else if (RenamedAcrossDirectories) {
3905 
3906  FatNotifyReportChange( IrpContext,
3907  Vcb,
3908  Fcb,
3909  ((NodeType( Fcb ) == FAT_NTC_FCB)
3913 
3914  } else {
3915 
3916  FatNotifyReportChange( IrpContext,
3917  Vcb,
3918  Fcb,
3919  ((NodeType( Fcb ) == FAT_NTC_FCB)
3923  }
3924 
3925  //
3926  // We need to update the file name in the dirent. This value
3927  // is never used elsewhere, so we don't concern ourselves
3928  // with any error we may encounter. We let chkdsk fix the
3929  // disk at some later time.
3930  //
3931 
3932  if (!FatIsFat32(Vcb) &&
3933  Dirent.ExtendedAttributes != 0) {
3934 
3935  FatRenameEAs( IrpContext,
3936  Fcb,
3937  Dirent.ExtendedAttributes,
3938  &OldOemName );
3939  }
3940 
3941  FatUnpinBcb( IrpContext, DotDotBcb );
3942 
3943  FatUnpinRepinnedBcbs( IrpContext );
3944 
3945  //
3946  // Set our final status
3947  //
3948 
3950 
3951  } _SEH2_FINALLY {
3952 
3954 
3955  ExFreePool( UnicodeBuffer );
3956 
3957  if (UniTunneledLongName.Buffer != UniTunneledLongNameBuffer) {
3958 
3959  //
3960  // Free pool if the buffer was grown on tunneling lookup
3961  //
3962 
3963  ExFreePool(UniTunneledLongName.Buffer);
3964  }
3965 
3966  if (NewDirentFromPool) {
3967 
3968  ExFreePool( NewDirent );
3969  }
3970 
3971  FatUnpinBcb( IrpContext, TargetDirentBcb );
3972  FatUnpinBcb( IrpContext, DotDotBcb );
3973 
3974  //
3975  // Uninitialize the cachemap for the source directory if we need to.
3976  //
3977 
3978  if (DirectoryFileObject) {
3979 
3980  DebugTrace(0, Dbg, "Uninitialize our parent Stream Cache Map\n", 0);
3981 
3982  CcUninitializeCacheMap( DirectoryFileObject, NULL, NULL );
3983 
3984  ObDereferenceObject( DirectoryFileObject );
3985  }
3986 
3987  //
3988  // If this was an abnormal termination, then we are in trouble.
3989  // Should the operation have been in a sensitive state there is
3990  // nothing we can do but invalidate the Fcb.
3991  //
3992 
3993  if (_SEH2_AbnormalTermination() && InvalidateFcbOnRaise) {
3994 
3995  Fcb->FcbCondition = FcbBad;
3996  }
3997 
3998  DebugTrace(-1, Dbg, "FatSetRenameInfo -> %08lx\n", Status);
3999  } _SEH2_END;
4000 
4001  return Status;
4002 }
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN IN OUT BOOLEAN * AllLowerExtension
Definition: fatprocs.h:1303
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
VOID FatConstructDirent(IN PIRP_CONTEXT IrpContext, IN OUT PDIRENT Dirent, IN POEM_STRING FileName, IN BOOLEAN ComponentReallyLowercase, IN BOOLEAN ExtensionReallyLowercase, IN PUNICODE_STRING Lfn OPTIONAL, IN USHORT Attributes, IN BOOLEAN ZeroAndSetTimeFields, IN PLARGE_INTEGER SetCreationTime OPTIONAL)
Definition: dirsup.c:2171
LONGLONG CreationTime
Definition: cdstruc.h:1036
VOID FatConstructNamesInFcb(IN PIRP_CONTEXT IrpContext, PFCB Fcb, PDIRENT Dirent, PUNICODE_STRING Lfn OPTIONAL)
Definition: strucsup.c:3010
LARGE_INTEGER LastWriteTime
Definition: fatstruc.h:921
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
union _FILE_NAME_NODE::@710 Name
#define FILE_ACTION_RENAMED_OLD_NAME
PVOID NTAPI FsRtlAllocatePoolWithTag(IN POOL_TYPE PoolType, IN ULONG NumberOfBytes, IN ULONG Tag)
Definition: filter.c:229
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN * AllLowerComponent
Definition: fatprocs.h:1303
LARGE_INTEGER FatFatDateToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_DATE FatDate)
Definition: timesup.c:171
VOID FatUnicodeToUpcaseOem(IN PIRP_CONTEXT IrpContext, IN POEM_STRING OemString, IN PUNICODE_STRING UnicodeString)
Definition: namesup.c:632
FSRTL_ADVANCED_FCB_HEADER Header
Definition: cdstruc.h:931
USHORT MaximumLength
Definition: env_spec_w32.h:370
_In_ PIRP Irp
Definition: csq.h:116
struct _FCB::@711::@713 Dcb
Definition: cdstruc.h:908
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
uint16_t * PWSTR
Definition: typedefs.h:55
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
VOID FatUnpinRepinnedBcbs(IN PIRP_CONTEXT IrpContext)
Definition: cachesup.c:1407
Definition: cdstruc.h:1073
#define FatNotifyReportChange(I, V, F, FL, A)
Definition: fatprocs.h:2165
BOOLEAN ContainsWildCards
Definition: fatstruc.h:1374
VOID NTAPI FatOplockComplete(IN PVOID Context, IN PIRP Irp)
Definition: workque.c:35
LONG NTSTATUS
Definition: precomp.h:26
#define DebugTrace(INDENT, LEVEL, X, Y)
Definition: fatdata.h:313
UNICODE_STRING UnicodeQueryTemplate
Definition: fatstruc.h:1425
Definition: cdstruc.h:504
#define FAT_DIRENT_ATTR_READ_ONLY
Definition: fat.h:368
#define FILE_NOTIFY_CHANGE_SIZE
#define FILE_NOTIFY_CHANGE_LAST_WRITE
#define FAT_DIRENT_ATTR_DIRECTORY
Definition: fat.h:372
#define FILE_NOTIFY_CHANGE_FILE_NAME
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: fatstruc.h:728
VOID NTAPI ObDereferenceObject(IN PVOID Object)
Definition: obref.c:375
BOOLEAN ChicagoMode
Definition: fatstruc.h:86
uint16_t * PWCHAR
Definition: typedefs.h:55
STRING OEM_STRING
Definition: umtypes.h:203
LIST_ENTRY ParentDcbLinks
Definition: fatstruc.h:827
#define InsertTailList(ListHead, Entry)
#define FILE_NOTIFY_CHANGE_DIR_NAME
struct _FCB * ParentDcb
Definition: fatstruc.h:835
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define FatDirectoryKey(FcbOrDcb)
Definition: fatprocs.h:850
_SEH2_TRY
Definition: create.c:4226
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
#define FO_FILE_MODIFIED
Definition: iotypes.h:1747
#define CCB_FLAG_SKIP_SHORT_NAME_COMPARE
Definition: fatstruc.h:1252
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
LARGE_INTEGER FatFatTimeToNtTime(_In_ PIRP_CONTEXT IrpContext, _In_ FAT_TIME_STAMP FatTime, _In_ UCHAR TenMilliSeconds)
Definition: timesup.c:233
LARGE_INTEGER LastAccessTime
Definition: fatstruc.h:920
VOID FatSetFullNameInFcb(_In_ PIRP_CONTEXT IrpContext, _Inout_ PFCB Fcb, _In_ PUNICODE_STRING FinalName)
Definition: create.c:6718
BOOLEAN NTAPI FsRtlFindInTunnelCache(IN PTUNNEL Cache, IN ULONGLONG DirectoryKey, IN PUNICODE_STRING Name, OUT PUNICODE_STRING ShortName, OUT PUNICODE_STRING LongName, IN OUT PULONG DataLength, OUT PVOID Data)
Definition: tunnel.c:765
#define FAT_LFN_DIRENTS_NEEDED(NAME)
Definition: lfn.h:53
#define FatGetFcbOplock(F)
Definition: fatprocs.h:1656
#define FILE_ACTION_MODIFIED
PNON_PAGED_FCB NonPaged
Definition: fatstruc.h:810
#define FatUnpinBcb(IRPCONTEXT, BCB)
Definition: fatprocs.h:546
VOID FatEvaluateNameCase(IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING Name, IN OUT BOOLEAN *AllLowerComponent, IN OUT BOOLEAN *AllLowerExtension, IN OUT BOOLEAN *CreateLfn)
Definition: namesup.c:891
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define FILE_ACTION_REMOVED
#define _SEH2_AbnormalTermination()
Definition: pseh2_64.h:13
ULONG Flags
Definition: cdstruc.h:1086
Definition: bufpool.h:45
#define Dbg
Definition: fileinfo.c:29
IN PDCB TargetDcb
Definition: fatprocs.h:788
NodeType
Definition: Node.h:5
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:588
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define FILE_NOTIFY_CHANGE_CREATION
OEM_STRING Oem
Definition: fatstruc.h:692
#define PCHAR
Definition: match.c:90
VOID FatRemoveNames(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb)
Definition: splaysup.c:222
#define NTDDI_VERSION
Definition: k32.h:33
struct _LIST_ENTRY * Flink
Definition: typedefs.h:120
BOOLEAN NTAPI FsRtlAreNamesEqual(IN PCUNICODE_STRING Name1, IN PCUNICODE_STRING Name2, IN BOOLEAN IgnoreCase, IN PCWCH UpcaseTable OPTIONAL)
Definition: name.c:296
#define FatIsNameShortOemValid(IRPCONTEXT, NAME, CAN_CONTAIN_WILD_CARDS, PATH_NAME_OK, LEADING_BACKSLASH_OK)
Definition: fatprocs.h:1198
#define DebugUnwind(X)
Definition: fatdata.h:315
FAT_DATA FatData
Definition: fatdata.c:56
#define FatReleaseFcb(IRPCONTEXT, Fcb)
Definition: fatprocs.h:1644
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4798
#define try_return(S)
Definition: cdprocs.h:2179
VBO LfnOffsetWithinDirectory
Definition: fatstruc.h:912
#define Vcb
Definition: cdprocs.h:1415
#define MAX_LFN_CHARACTERS
Definition: lfn.h:50
#define NTDDI_WIN7
Definition: sdkddkver.h:112
#define FatIsFileOplockable(F)
Definition: fatprocs.h:2848
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define TAG_FILENAME_BUFFER
Definition: nodetype.h:167
BOOLEAN NTAPI FsRtlCurrentBatchOplock(IN POPLOCK Oplock)
Definition: oplock.c:1366
* PFILE_OBJECT
Definition: iotypes.h:1957
UNICODE_STRING FullFileName
Definition: fatstruc.h:1121
ULONG Flags
Definition: ntfs.h:532
PFCB FatGetNextFcbBottomUp(IN PIRP_CONTEXT IrpContext, IN PFCB Fcb, IN PFCB TerminationFcb)
Definition: strucsup.c:2513
NTSTATUS FatSetRenameInfo(IN PIRP_CONTEXT IrpContext, IN PIRP Irp, IN PVCB Vcb, IN PFCB Fcb, IN PCCB Ccb)
Definition: fileinfo.c:2694
unsigned char UCHAR
Definition: xmlstorage.h:181
union _LARGE_INTEGER LARGE_INTEGER
VBO * PVBO
Definition: fat.h:39
#define FILE_ACTION_RENAMED_NEW_NAME
CLONG UncleanCount
Definition: fatstruc.h:872
#define CCB_FLAG_USER_SET_LAST_WRITE
Definition: fatstruc.h:1265
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:588
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define NOTHING
Definition: env_spec_w32.h:461
Definition: typedefs.h:118
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
union _FCB::@711 Specific
#define FatIsFat32(VCB)
Definition: fatprocs.h:1446
Status
Definition: gdiplustypes.h:24
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
PFILE_OBJECT FileObject
Definition: iotypes.h:2815
_SEH2_END
Definition: create.c:4400
VBO DirentOffsetWithinDirectory
Definition: fatstruc.h:905
#define FILE_NOTIFY_CHANGE_EA
union _CCB::@715::@717::@719 OemQueryTemplate
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI CcUninitializeCacheMap(IN PFILE_OBJECT FileObject, IN OPTIONAL PLARGE_INTEGER TruncateSize, IN OPTIONAL PCACHE_UNINITIALIZE_EVENT UninitializeEvent)
Definition: fssup.c:286
#define FAT_NTC_ROOT_DCB
Definition: nodetype.h:31
#define FILE_NOTIFY_CHANGE_ATTRIBUTES
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4137
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
_SEH2_FINALLY
Definition: create.c:4371
CLONG OpenCount
Definition: fatstruc.h:880
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
#define FAT_NTC_DCB
Definition: nodetype.h:30
VOID FatTunnelFcbOrDcb(IN PFCB FcbOrDcb, IN PCCB Ccb OPTIONAL)
Definition: dirsup.c:652
ULONG FirstClusterOfFile
Definition: fatstruc.h:817
#define FILE_ACTION_ADDED
VOID FatStringTo8dot3(_In_ PIRP_CONTEXT IrpContext, _In_ OEM_STRING InputString, _Out_writes_bytes_(11) PFAT8DOT3 Output8dot3)
Definition: namesup.c:79
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203
IN PDCB IN POEM_STRING IN PUNICODE_STRING IN OUT POEM_STRING IN PUNICODE_STRING SuggestedShortName IN OUT BOOLEAN IN OUT BOOLEAN IN OUT BOOLEAN * CreateLfn
Definition: fatprocs.h:1303
#define DIRENT
Definition: fatfs.h:187
unsigned int ULONG
Definition: retypes.h:1
_In_ PFCB _In_ PDIRENT_ENUM_CONTEXT _Inout_ PDIRENT Dirent
Definition: cdprocs.h:424
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS NTAPI FsRtlCheckOplock(IN POPLOCK Oplock, IN PIRP Irp, IN PVOID Context, IN POPLOCK_WAIT_COMPLETE_ROUTINE CompletionRoutine OPTIONAL, IN POPLOCK_FS_PREPOST_IRP PostIrpRoutine OPTIONAL)
Definition: oplock.c:1172
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2774
_In_ PFCB Fcb
Definition: cdprocs.h:159
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:3014
#define FILE_NOTIFY_CHANGE_LAST_ACCESS
FILE_NAME_NODE ShortName
Definition: fatstruc.h:1114
BOOLEAN FatSpaceInName(IN PIRP_CONTEXT IrpContext, IN PUNICODE_STRING UnicodeName)
Definition: namesup.c:1003
TYPE_OF_OPEN FatDecodeFileObject(_In_ PFILE_OBJECT FileObject, _Outptr_ PVCB *Vcb, _Outptr_ PFCB *FcbOrDcb, _Outptr_ PCCB *Ccb)
Definition: filobsup.c:176
#define FAT_NTC_FCB
Definition: nodetype.h:29
UNICODE_STRING ExactCaseLongName
Definition: fatstruc.h:1138
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define TAG_DIRENT
Definition: vfat.h:549
#define PAGED_CODE()
#define NT_ASSERT
Definition: rtlfuncs.h:3312
FCB_CONDITION FcbCondition
Definition: fatstruc.h:849