ReactOS  0.4.14-dev-50-g13bb5e2
dirctl.c File Reference
#include "ext2fs.h"
Include dependency graph for dirctl.c:

Go to the source code of this file.

Functions

ULONG Ext2GetInfoLength (IN FILE_INFORMATION_CLASS FileInformationClass)
 
NTSTATUS Ext2ProcessEntry (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG in, IN PVOID Buffer, IN ULONG UsedLength, IN ULONG Length, IN ULONG FileIndex, IN PUNICODE_STRING pName, OUT PULONG EntrySize, IN BOOLEAN Single)
 
BOOLEAN Ext2IsWearingCloak (IN PEXT2_VCB Vcb, IN POEM_STRING OemName)
 
static int Ext2FillEntry (void *context, const char *name, int namlen, ULONG offset, __u32 ino, unsigned int d_type)
 
NTSTATUS Ext2QueryDirectory (IN PEXT2_IRP_CONTEXT IrpContext)
 
NTSTATUS Ext2NotifyChangeDirectory (IN PEXT2_IRP_CONTEXT IrpContext)
 
VOID Ext2NotifyReportChange (IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Mcb, IN ULONG Filter, IN ULONG Action)
 
NTSTATUS Ext2DirectoryControl (IN PEXT2_IRP_CONTEXT IrpContext)
 
BOOLEAN Ext2IsDirectoryEmpty (PEXT2_IRP_CONTEXT IrpContext, PEXT2_VCB Vcb, PEXT2_MCB Mcb)
 

Variables

PEXT2_GLOBAL Ext2Global
 

Function Documentation

◆ Ext2DirectoryControl()

NTSTATUS Ext2DirectoryControl ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 1236 of file dirctl.c.

1237 {
1238  NTSTATUS Status;
1239 
1240  ASSERT(IrpContext);
1241 
1242  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1243  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1244 
1245  switch (IrpContext->MinorFunction) {
1246 
1248  Status = Ext2QueryDirectory(IrpContext);
1249  break;
1250 
1252  Status = Ext2NotifyChangeDirectory(IrpContext);
1253  break;
1254 
1255  default:
1257  Ext2CompleteIrpContext(IrpContext, Status);
1258  }
1259 
1260  return Status;
1261 }
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY
Definition: rdpdr.c:56
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
#define IRP_MN_QUERY_DIRECTORY
Definition: rdpdr.c:55
NTSTATUS Ext2QueryDirectory(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dirctl.c:525
NTSTATUS Ext2NotifyChangeDirectory(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dirctl.c:1029
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
Status
Definition: gdiplustypes.h:24

Referenced by Ext2DispatchRequest().

◆ Ext2FillEntry()

static int Ext2FillEntry ( void context,
const char name,
int  namlen,
ULONG  offset,
__u32  ino,
unsigned int  d_type 
)
static

Definition at line 415 of file dirctl.c.

417 {
419  PEXT2_IRP_CONTEXT IrpContext = fc->efc_irp;
420 
421  PEXT2_FCB Fcb = IrpContext->Fcb;
422  PEXT2_CCB Ccb = IrpContext->Ccb;
423  PEXT2_VCB Vcb = Fcb->Vcb;
424 
425  OEM_STRING Oem;
426  UNICODE_STRING Unicode = { 0 };
429  USHORT NameLen;
430  int rc = 0;
431 
432  if (fc->efc_start > 0 && (fc->efc_single || (fc->efc_size <
433  fc->efc_start + namlen * 2 + Ext2GetInfoLength(fc->efc_fi)) )) {
434  rc = 1;
435  goto errorout;
436  }
437 
438 
439  Oem.Buffer = (void *)name;
440  Oem.Length = namlen & 0xFF;
441  Oem.MaximumLength = Oem.Length;
442 
443  /* skip . and .. */
444  if ((Oem.Length == 1 && name[0] == '.') || (Oem.Length == 2 &&
445  name[0] == '.' && name[1] == '.' )) {
446  goto errorout;
447  }
448 
449  if (Ext2IsWearingCloak(Vcb, &Oem)) {
450  goto errorout;
451  }
452 
453  NameLen = (USHORT)Ext2OEMToUnicodeSize(Vcb, &Oem);
454  if (NameLen <= 0) {
455  fc->efc_status = STATUS_INSUFFICIENT_RESOURCES;
456  rc = -ENOMEM;
457  goto errorout;
458  }
459 
460  Unicode.MaximumLength = NameLen + 2;
461  Unicode.Buffer = Ext2AllocatePool(
462  PagedPool,
463  Unicode.MaximumLength,
465  );
466  if (!Unicode.Buffer) {
467  DEBUG(DL_ERR, ( "Ex2QueryDirectory: failed to "
468  "allocate InodeFileName.\n"));
469  fc->efc_status = STATUS_INSUFFICIENT_RESOURCES;
470  rc = -ENOMEM;
471  goto errorout;
472  }
473  RtlZeroMemory(Unicode.Buffer, Unicode.MaximumLength);
474  INC_MEM_COUNT(PS_INODE_NAME, Unicode.Buffer, Unicode.MaximumLength);
475 
476  Status = Ext2OEMToUnicode(Vcb, &Unicode, &Oem);
477  if (!NT_SUCCESS(Status)) {
478  DEBUG(DL_ERR, ( "Ex2QueryDirectory: Ext2OEMtoUnicode failed with %xh.\n", Status));
479  fc->efc_status = STATUS_INSUFFICIENT_RESOURCES;
480  rc = -ENOMEM;
481  goto errorout;
482  }
483 
484  if (FsRtlDoesNameContainWildCards( &Ccb->DirectorySearchPattern) ?
485  FsRtlIsNameInExpression(&Ccb->DirectorySearchPattern,
486  &Unicode, TRUE, NULL) :
487  !RtlCompareUnicodeString(&Ccb->DirectorySearchPattern,
488  &Unicode, TRUE)) {
489  Status = Ext2ProcessEntry(fc->efc_irp, Vcb, Fcb, fc->efc_fi, ino, fc->efc_buf,
490  CEILING_ALIGNED(ULONG, fc->efc_start, 8),
491  fc->efc_size - CEILING_ALIGNED(ULONG, fc->efc_start, 8),
492  offset, &Unicode, &EntrySize, fc->efc_single);
493  if (NT_SUCCESS(Status)) {
494  if (EntrySize > 0) {
495  fc->efc_prev = CEILING_ALIGNED(ULONG, fc->efc_start, 8);
496  fc->efc_start = fc->efc_prev + EntrySize;
497  } else {
498  DbgBreak();
499  }
500  } else {
502  if (fc->efc_start == 0) {
503  fc->efc_start = EntrySize;
504  } else {
506  }
507  }
508  rc = 1;
509  }
510  }
511 
512 errorout:
513 
514  fc->efc_status = Status;
515  if (Unicode.Buffer) {
516  DEC_MEM_COUNT(PS_INODE_NAME, Unicode.Buffer, Unicode.MaximumLength );
518  }
519 
520  return rc;
521 }
#define TRUE
Definition: types.h:120
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define DEC_MEM_COUNT(_i, _p, _s)
Definition: ext2fs.h:599
USHORT MaximumLength
Definition: env_spec_w32.h:370
Definition: http.c:6587
#define CEILING_ALIGNED(T, A, B)
Definition: ext2fs.h:111
LONG NTSTATUS
Definition: precomp.h:26
GLintptr offset
Definition: glext.h:5920
#define EXT2_INAME_MAGIC
Definition: ext2fs.h:292
STRING OEM_STRING
Definition: umtypes.h:203
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
Definition: arc.h:48
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
#define PS_INODE_NAME
Definition: common.h:26
PEXT2_CCB Ccb
Definition: ext2fs.h:1060
NTSTATUS Ext2ProcessEntry(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG in, IN PVOID Buffer, IN ULONG UsedLength, IN ULONG Length, IN ULONG FileIndex, IN PUNICODE_STRING pName, OUT PULONG EntrySize, IN BOOLEAN Single)
Definition: dirctl.c:60
smooth NULL
Definition: ftsmooth.c:416
#define INC_MEM_COUNT(_i, _p, _s)
Definition: ext2fs.h:598
ULONG Ext2OEMToUnicodeSize(IN PEXT2_VCB Vcb, IN PANSI_STRING Oem)
Definition: misc.c:183
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define Vcb
Definition: cdprocs.h:1425
LPFOR_CONTEXT fc
Definition: for.c:53
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
PEXT2_FCB Fcb
Definition: ext2fs.h:1059
NTSTATUS Ext2OEMToUnicode(IN PEXT2_VCB Vcb, IN OUT PUNICODE_STRING Oem, IN POEM_STRING Unicode)
Definition: misc.c:206
Status
Definition: gdiplustypes.h:24
#define DL_ERR
Definition: ext2fs.h:1397
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
unsigned short USHORT
Definition: pedump.c:61
ULONG Ext2GetInfoLength(IN FILE_INFORMATION_CLASS FileInformationClass)
Definition: dirctl.c:30
Definition: name.c:36
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
PVCB Vcb
Definition: cdstruc.h:939
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
#define DEBUG(args)
Definition: rdesktop.h:129
BOOLEAN Ext2IsWearingCloak(IN PEXT2_VCB Vcb, IN POEM_STRING OemName)
Definition: dirctl.c:372
_In_ PFCB Fcb
Definition: cdprocs.h:151
return STATUS_SUCCESS
Definition: btrfs.c:2966
PVOID Ext2AllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: debug.c:2684

Referenced by Ext2QueryDirectory().

◆ Ext2GetInfoLength()

ULONG Ext2GetInfoLength ( IN FILE_INFORMATION_CLASS  FileInformationClass)

Definition at line 30 of file dirctl.c.

31 {
32  switch (FileInformationClass) {
33 
36 
39 
42 
45 
48 
51 
52  default:
53  break;
54  }
55 
56  return 0;
57 }
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254

Referenced by Ext2FillEntry(), and Ext2ProcessEntry().

◆ Ext2IsDirectoryEmpty()

BOOLEAN Ext2IsDirectoryEmpty ( PEXT2_IRP_CONTEXT  IrpContext,
PEXT2_VCB  Vcb,
PEXT2_MCB  Mcb 
)

Definition at line 1265 of file dirctl.c.

1270 {
1271  if (!IsMcbDirectory(Mcb) || IsMcbSymLink(Mcb)) {
1272  return TRUE;
1273  }
1274 
1275  return !!ext3_is_dir_empty(IrpContext, &Mcb->Inode);
1276 }
#define TRUE
Definition: types.h:120
#define IsMcbDirectory(Mcb)
Definition: ext2fs.h:958
#define IsMcbSymLink(Mcb)
Definition: ext2fs.h:953
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:334
int ext3_is_dir_empty(struct ext2_icb *icb, struct inode *inode)
Definition: htree.c:2038

◆ Ext2IsWearingCloak()

BOOLEAN Ext2IsWearingCloak ( IN PEXT2_VCB  Vcb,
IN POEM_STRING  OemName 
)

Definition at line 372 of file dirctl.c.

376 {
377  size_t PatLen = 0;
378 
379  /* we could not filter the files: "." and ".." */
380  if (OemName->Length >= 1 && OemName->Buffer[0] == '.') {
381 
382  if ( OemName->Length == 2 && OemName->Buffer[1] == '.') {
383  return FALSE;
384  } else if (OemName->Length == 1) {
385  return FALSE;
386  }
387  }
388 
389  /* checking name prefix */
390  if (Vcb->bHidingPrefix) {
391  PatLen = strlen(&Vcb->sHidingPrefix[0]);
392  if (PatLen > 0 && PatLen <= OemName->Length) {
393  if ( _strnicmp( OemName->Buffer,
394  Vcb->sHidingPrefix,
395  PatLen ) == 0) {
396  return TRUE;
397  }
398  }
399  }
400 
401  /* checking name suffix */
402  if (Vcb->bHidingSuffix) {
403  PatLen = strlen(&Vcb->sHidingSuffix[0]);
404  if (PatLen > 0 && PatLen <= OemName->Length) {
405  if ( _strnicmp(&OemName->Buffer[OemName->Length - PatLen],
406  Vcb->sHidingSuffix, PatLen ) == 0) {
407  return TRUE;
408  }
409  }
410  }
411 
412  return FALSE;
413 }
#define TRUE
Definition: types.h:120
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
_Check_return_ _CRTIMP int __cdecl _strnicmp(_In_reads_or_z_(_MaxCount) const char *_Str1, _In_reads_or_z_(_MaxCount) const char *_Str2, _In_ size_t _MaxCount)
#define Vcb
Definition: cdprocs.h:1425
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
IN PDCB IN POEM_STRING OemName
Definition: fatprocs.h:1294

Referenced by Ext2FillEntry(), and Ext2QueryDirectory().

◆ Ext2NotifyChangeDirectory()

NTSTATUS Ext2NotifyChangeDirectory ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 1029 of file dirctl.c.

1032 {
1036  PEXT2_VCB Vcb = NULL;
1037  PEXT2_FCB Fcb = NULL;
1038  PEXT2_CCB Ccb = NULL;
1039  PIRP Irp = NULL;
1044 
1045  BOOLEAN bFcbAcquired = FALSE;
1046 
1047  _SEH2_TRY {
1048 
1049  ASSERT(IrpContext);
1050  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
1051  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
1052 
1053  //
1054  // Always set the wait flag in the Irp context for the original request.
1055  //
1056 
1057  SetFlag( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
1058 
1059  DeviceObject = IrpContext->DeviceObject;
1060 
1063  _SEH2_LEAVE;
1064  }
1065 
1067 
1068  ASSERT(Vcb != NULL);
1069  ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
1070  (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
1071 
1072  FileObject = IrpContext->FileObject;
1073  Fcb = (PEXT2_FCB) FileObject->FsContext;
1074  ASSERT(Fcb);
1075  if (Fcb->Identifier.Type == EXT2VCB) {
1076  DbgBreak();
1078  _SEH2_LEAVE;
1079  }
1080  ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
1081  (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
1082 
1083  Ccb = (PEXT2_CCB) FileObject->FsContext2;
1084  ASSERT(Ccb);
1085  ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
1086  (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
1087 
1088  /* do nothing if target fie was deleted */
1091  _SEH2_LEAVE;
1092  }
1093 
1094  if (!IsDirectory(Fcb)) {
1095  DbgBreak();
1097  _SEH2_LEAVE;
1098  }
1099 
1101  &Fcb->MainResource,
1102  TRUE )) {
1103  bFcbAcquired = TRUE;
1104  } else {
1106  _SEH2_LEAVE;
1107  }
1108 
1109  Irp = IrpContext->Irp;
1110 
1112 
1113 #ifndef _GNU_NTIFS_
1114 
1116  IrpSp->Parameters.NotifyDirectory.CompletionFilter;
1117 
1118 #else // _GNU_NTIFS_
1119 
1121  IrpSp)->Parameters.NotifyDirectory.CompletionFilter;
1122 
1123 #endif // _GNU_NTIFS_
1124 
1126 
1129  _SEH2_LEAVE;
1130  }
1131 
1132  FsRtlNotifyFullChangeDirectory( Vcb->NotifySync,
1133  &Vcb->NotifyList,
1134  FileObject->FsContext2,
1135  (PSTRING)(&Fcb->Mcb->FullName),
1136  WatchTree,
1137  FALSE,
1139  Irp,
1140  NULL,
1141  NULL );
1142 
1144 
1146 
1147  /*
1148  Currently the driver is read-only but here is an example on how to use the
1149  FsRtl-functions to report a change:
1150 
1151  ANSI_STRING TestString;
1152  USHORT FileNamePartLength;
1153 
1154  RtlInitAnsiString(&TestString, "\\ntifs.h");
1155 
1156  FileNamePartLength = 7;
1157 
1158  FsRtlNotifyReportChange(
1159  Vcb->NotifySync, // PNOTIFY_SYNC NotifySync
1160  &Vcb->NotifyList, // PLIST_ENTRY NotifyList
1161  &TestString, // PSTRING FullTargetName
1162  &FileNamePartLength, // PUSHORT FileNamePartLength
1163  FILE_NOTIFY_CHANGE_NAME // ULONG FilterMatch
1164  );
1165 
1166  or
1167 
1168  ANSI_STRING TestString;
1169 
1170  RtlInitAnsiString(&TestString, "\\ntifs.h");
1171 
1172  FsRtlNotifyFullReportChange(
1173  Vcb->NotifySync, // PNOTIFY_SYNC NotifySync
1174  &Vcb->NotifyList, // PLIST_ENTRY NotifyList
1175  &TestString, // PSTRING FullTargetName
1176  1, // USHORT TargetNameOffset
1177  NULL, // PSTRING StreamName OPTIONAL
1178  NULL, // PSTRING NormalizedParentName OPTIONAL
1179  FILE_NOTIFY_CHANGE_NAME, // ULONG FilterMatch
1180  0, // ULONG Action
1181  NULL // PVOID TargetContext
1182  );
1183  */
1184 
1185  } _SEH2_FINALLY {
1186 
1187  if (bFcbAcquired) {
1189  }
1190 
1191  if (!IrpContext->ExceptionInProgress) {
1192  if (CompleteRequest) {
1193  if (Status == STATUS_PENDING) {
1194  Ext2QueueRequest(IrpContext);
1195  } else {
1196  Ext2CompleteIrpContext(IrpContext, Status);
1197  }
1198  } else {
1199  IrpContext->Irp = NULL;
1200  Ext2CompleteIrpContext(IrpContext, Status);
1201  }
1202  }
1203  } _SEH2_END;
1204 
1205  return Status;
1206 }
struct _EXT2_FCB * PEXT2_FCB
#define STATUS_DELETE_PENDING
Definition: ntstatus.h:308
#define TRUE
Definition: types.h:120
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
VOID NTAPI FsRtlNotifyFullChangeDirectory(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PVOID FsContext, IN PSTRING FullDirectoryName, IN BOOLEAN WatchTree, IN BOOLEAN IgnoreBuffer, IN ULONG CompletionFilter, IN PIRP NotifyIrp, IN PCHECK_FOR_TRAVERSE_ACCESS TraverseCallback OPTIONAL, IN PSECURITY_SUBJECT_CONTEXT SubjectContext OPTIONAL)
Definition: notify.c:1458
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN WatchTree
Definition: fltkernel.h:2239
#define FCB_DELETE_PENDING
Definition: ext2fs.h:879
_SEH2_TRY
Definition: create.c:4250
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
NTFSIDENTIFIER Identifier
Definition: ntfs.h:511
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:150
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define STATUS_FILE_DELETED
Definition: udferr_usr.h:172
#define STATUS_PENDING
Definition: ntstatus.h:82
#define Vcb
Definition: cdprocs.h:1425
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1955
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
ULONG Flags
Definition: ntfs.h:532
CD_MCB Mcb
Definition: cdstruc.h:1022
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
ULONG Type
Definition: ntfs.h:95
#define SL_WATCH_TREE
Definition: iotypes.h:1796
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ERESOURCE MainResource
Definition: ntfs.h:524
Status
Definition: gdiplustypes.h:24
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
_SEH2_END
Definition: create.c:4424
_In_ PIO_STACK_LOCATION IrpSp
Definition: create.c:4157
_SEH2_FINALLY
Definition: create.c:4395
_Inout_ PLIST_ENTRY _In_ PVOID _In_ PSTRING _In_ BOOLEAN _In_ BOOLEAN _In_ ULONG CompletionFilter
Definition: fltkernel.h:2239
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:607
unsigned int ULONG
Definition: retypes.h:1
#define DbgBreak()
Definition: ext2fs.h:46
struct _EXT2_VCB * PEXT2_VCB
IO_STACK_LOCATION * PEXTENDED_IO_STACK_LOCATION
Definition: ext2fs.h:174
#define _SEH2_LEAVE
Definition: filesup.c:20
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
struct _EXT2_CCB * PEXT2_CCB
ULONG Size
Definition: ntfs.h:96

Referenced by Ext2DirectoryControl().

◆ Ext2NotifyReportChange()

VOID Ext2NotifyReportChange ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN PEXT2_MCB  Mcb,
IN ULONG  Filter,
IN ULONG  Action 
)

Definition at line 1209 of file dirctl.c.

1215 {
1216  USHORT Offset;
1217 
1218  Offset = (USHORT) ( Mcb->FullName.Length -
1219  Mcb->ShortName.Length);
1220 
1221  FsRtlNotifyFullReportChange( Vcb->NotifySync,
1222  &(Vcb->NotifyList),
1223  (PSTRING) (&Mcb->FullName),
1224  (USHORT) Offset,
1225  (PSTRING)NULL,
1226  (PSTRING) NULL,
1227  (ULONG) Filter,
1228  (ULONG) Action,
1229  (PVOID) NULL );
1230 
1231  // ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
1232 }
VOID NTAPI FsRtlNotifyFullReportChange(IN PNOTIFY_SYNC NotifySync, IN PLIST_ENTRY NotifyList, IN PSTRING FullTargetName, IN USHORT TargetNameOffset, IN PSTRING StreamName OPTIONAL, IN PSTRING NormalizedParentName OPTIONAL, IN ULONG FilterMatch, IN ULONG Action, IN PVOID TargetContext)
Definition: notify.c:1523
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_Must_inspect_result_ _In_opt_ PFLT_FILTER Filter
Definition: fltkernel.h:1802
smooth NULL
Definition: ftsmooth.c:416
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING _In_opt_ PSTRING _In_ ULONG _In_ ULONG Action
Definition: fsrtlfuncs.h:738
#define Vcb
Definition: cdprocs.h:1425
unsigned short USHORT
Definition: pedump.c:61
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:334
unsigned int ULONG
Definition: retypes.h:1

Referenced by Ext2Cleanup(), Ext2CreateFile(), Ext2DeleteReparsePoint(), Ext2QueryEa(), Ext2SetEa(), Ext2SetFileInformation(), Ext2SetLinkInfo(), Ext2SetRenameInfo(), Ext2SetReparsePoint(), and Ext2WriteFile().

◆ Ext2ProcessEntry()

NTSTATUS Ext2ProcessEntry ( IN PEXT2_IRP_CONTEXT  IrpContext,
IN PEXT2_VCB  Vcb,
IN PEXT2_FCB  Dcb,
IN FILE_INFORMATION_CLASS  FileInformationClass,
IN ULONG  in,
IN PVOID  Buffer,
IN ULONG  UsedLength,
IN ULONG  Length,
IN ULONG  FileIndex,
IN PUNICODE_STRING  pName,
OUT PULONG  EntrySize,
IN BOOLEAN  Single 
)

Definition at line 60 of file dirctl.c.

74 {
78 
81 
83 
84  PEXT2_MCB Mcb = NULL;
86 
88  struct inode Inode = { 0 };
89 
90  ULONG InfoLength = 0;
91  ULONG NameLength = 0;
92 #ifndef __REACTOS__
93  ULONG dwBytes = 0;
94 #endif
95  LONGLONG FileSize = 0;
98 
99  BOOLEAN IsEntrySymlink = FALSE;
100 
101  *EntrySize = 0;
102  NameLength = pName->Length;
103  ASSERT((UsedLength & 7) == 0);
104 
106  if (InfoLength == 0) {
107  DEBUG(DL_ERR, ("Ext2ProcessDirEntry: Invalid Info Class %xh for %wZ in %wZ\n",
108  FileInformationClass, pName, &Dcb->Mcb->FullName ));
110  }
111 
112  if (InfoLength + NameLength > Length) {
113  DEBUG(DL_INF, ( "Ext2PricessDirEntry: Buffer is not enough.\n"));
115  if (UsedLength || InfoLength > Length) {
116  DEBUG(DL_CP, ("Ext2ProcessDirEntry: Buffer overflows for %wZ in %wZ\n",
117  pName, &Dcb->Mcb->FullName ));
118  return Status;
119  }
120  }
121 
122  DEBUG(DL_CP, ("Ext2ProcessDirEntry: %wZ in %wZ\n", pName, &Dcb->Mcb->FullName ));
123 
124  Mcb = Ext2SearchMcb(Vcb, Dcb->Mcb, pName);
125  if (NULL != Mcb) {
126  if (S_ISLNK(Mcb->Inode.i_mode) && NULL == Mcb->Target) {
127  Ext2FollowLink( IrpContext, Vcb, Dcb->Mcb, Mcb, 0);
128  }
129 
130  } else {
131 
132  Inode.i_ino = in;
133  Inode.i_sb = &Vcb->sb;
134  if (!Ext2LoadInode(Vcb, &Inode)) {
135  DEBUG(DL_ERR, ("Ext2PricessDirEntry: Loading inode %xh (%wZ) error.\n",
136  in, pName ));
137  DbgBreak();
139  goto errorout;
140  }
141 
142  if (S_ISDIR(Inode.i_mode) || S_ISREG(Inode.i_mode)) {
143  } else if (S_ISLNK(Inode.i_mode)) {
144  DEBUG(DL_RES, ("Ext2ProcessDirEntry: SymLink: %wZ\\%wZ\n",
145  &Dcb->Mcb->FullName, pName));
146  Ext2LookupFile(IrpContext, Vcb, pName, Dcb->Mcb, &Mcb,0);
147 
148  if (Mcb && IsMcbSpecialFile(Mcb)) {
149  Ext2DerefMcb(Mcb);
150  Mcb = NULL;
151  }
152  } else {
153  Inode.i_size = 0;
154  }
155  }
156 
157  if (Mcb != NULL) {
158 
159  FileAttributes = Mcb->FileAttr;
160  if (IsMcbSymLink(Mcb)) {
161  Target = Mcb->Target;
162  ASSERT(Target);
164  if (IsMcbDirectory(Target)) {
165  FileSize = 0;
167  } else {
168  FileSize = Target->Inode.i_size;
169  }
170  if (IsFileDeleted(Target)) {
172  FileSize = 0;
173  }
174  } else {
175  if (IsMcbDirectory(Mcb)) {
176  FileSize = 0;
177  } else {
178  FileSize = Mcb->Inode.i_size;
179  }
180  }
181 
182  if (IsInodeSymLink(&Mcb->Inode)) {
183  IsEntrySymlink = TRUE;
184  }
185 
186  } else {
187 
188  if (S_ISDIR(Inode.i_mode)) {
189  FileSize = 0;
190  } else {
191  FileSize = Inode.i_size;
192  }
193 
194  if (S_ISDIR(Inode.i_mode)) {
196  } else if (S_ISLNK(Inode.i_mode)) {
198  IsEntrySymlink = TRUE;
199  } else {
201  }
202 
203  if (!Ext2CheckInodeAccess(Vcb, &Inode, Ext2FileCanWrite)) {
205  }
206  }
207 
208  if (FileAttributes == 0)
210 
212 
213  /* process special files under root directory */
214  if (IsRoot(Dcb)) {
215  /* set hidden and system attributes for Recycled /
216  RECYCLER / pagefile.sys */
221  }
222  }
223 
224  /* set hidden attribute for all entries starting with '.' */
225  if (( pName->Length >= 4 && pName->Buffer[0] == L'.') &&
226  ((pName->Length == 4 && pName->Buffer[1] != L'.') ||
227  pName->Length >= 6 )) {
229  }
230 
231  switch (FileInformationClass) {
232 
234  FIF = (PFILE_ID_FULL_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength);
236  FFI = (PFILE_FULL_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength);
238  FDI = (PFILE_DIRECTORY_INFORMATION) ((PUCHAR)Buffer + UsedLength);
239 
240  if (!Single) {
241  FDI->NextEntryOffset = CEILING_ALIGNED(ULONG, InfoLength + NameLength, 8);
242  }
243 
244  FDI->FileIndex = FileIndex;
245 
246  if (Mcb) {
247 
248  FDI->CreationTime = Mcb->CreationTime;
249  FDI->LastAccessTime = Mcb->LastAccessTime;
250  FDI->LastWriteTime = Mcb->LastWriteTime;
251  FDI->ChangeTime = Mcb->ChangeTime;
252 
253  } else {
254 
255  FDI->CreationTime = Ext2NtTime(Inode.i_ctime);
256  FDI->LastAccessTime = Ext2NtTime(Inode.i_atime);
257  FDI->LastWriteTime = Ext2NtTime(Inode.i_mtime);
258  FDI->ChangeTime = Ext2NtTime(Inode.i_mtime);
259  }
260 
262  FDI->EndOfFile.QuadPart = FileSize;
264 
265  FDI->FileNameLength = NameLength;
266  if (InfoLength + NameLength > Length) {
267  NameLength = Length - InfoLength;
268  }
269 
270  if (FIF) {
271  FIF->FileId.QuadPart = (LONGLONG) in;
272  if (IsEntrySymlink) {
274  }
275  RtlCopyMemory(&FIF->FileName[0], &pName->Buffer[0], NameLength);
276  } else if (FFI) {
277  if (IsEntrySymlink) {
279  }
280  RtlCopyMemory(&FFI->FileName[0], &pName->Buffer[0], NameLength);
281  } else {
282  RtlCopyMemory(&FDI->FileName[0], &pName->Buffer[0], NameLength);
283  }
284 
285  *EntrySize = InfoLength + NameLength;
286  break;
287 
288 
290  FIB = (PFILE_ID_BOTH_DIR_INFORMATION)((PUCHAR)Buffer + UsedLength);
292  FBI = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR)Buffer + UsedLength);
293 
294  if (!Single) {
295  FBI->NextEntryOffset = CEILING_ALIGNED(ULONG, InfoLength + NameLength, 8);
296  }
297 
298  FBI->FileIndex = FileIndex;
299  FBI->EndOfFile.QuadPart = FileSize;
301 
302  if (Mcb) {
303 
304  FBI->CreationTime = Mcb->CreationTime;
305  FBI->LastAccessTime = Mcb->LastAccessTime;
306  FBI->LastWriteTime = Mcb->LastWriteTime;
307  FBI->ChangeTime = Mcb->ChangeTime;
308 
309  } else {
310 
311  FBI->CreationTime = Ext2NtTime(Inode.i_ctime);
312  FBI->LastAccessTime = Ext2NtTime(Inode.i_atime);
313  FBI->LastWriteTime = Ext2NtTime(Inode.i_mtime);
314  FBI->ChangeTime = Ext2NtTime(Inode.i_mtime);
315  }
316 
318 
319  FBI->FileNameLength = NameLength;
320  if (InfoLength + NameLength > Length) {
321  NameLength = Length - InfoLength;
322  }
323 
324  if (FIB) {
325  FIB->FileId.QuadPart = (LONGLONG)in;
326  if (IsEntrySymlink) {
328  }
329  RtlCopyMemory(&FIB->FileName[0], &pName->Buffer[0], NameLength);
330  } else {
331  RtlCopyMemory(&FBI->FileName[0], &pName->Buffer[0], NameLength);
332  }
333 
334  *EntrySize = InfoLength + NameLength;
335  break;
336 
338 
339  FNI = (PFILE_NAMES_INFORMATION) ((PUCHAR)Buffer + UsedLength);
340  if (!Single) {
341  FNI->NextEntryOffset = CEILING_ALIGNED(ULONG, InfoLength + NameLength, 8);
342  }
343 
344  FNI->FileNameLength = NameLength;
345  if (InfoLength + NameLength > Length) {
346  NameLength = Length - InfoLength;
347  }
348  RtlCopyMemory(&FNI->FileName[0], &pName->Buffer[0], NameLength);
349 
350  *EntrySize = InfoLength + NameLength;
351  break;
352 
353  default:
355  break;
356  }
357 
358  if (Mcb) {
359  Ext2DerefMcb(Mcb);
360  }
361 
362 errorout:
363 
364  DEBUG(DL_CP, ("Ext2ProcessDirEntry: Status = %xh for %wZ in %wZ\n",
365  Status, pName, &Dcb->Mcb->FullName ));
366 
367  return Status;
368 }
LARGE_INTEGER LastAccessTime
Definition: winternl.h:517
#define Ext2DerefMcb(Mcb)
Definition: ext2fs.h:987
#define IsInodeSymLink(I)
Definition: ext2fs.h:281
struct _FILE_BOTH_DIR_INFORMATION * PFILE_BOTH_DIR_INFORMATION
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
Definition: halp.h:205
NTSTATUS Ext2FollowLink(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_MCB Parent, IN PEXT2_MCB Mcb, IN ULONG Linkdep)
Definition: create.c:67
#define IsMcbDirectory(Mcb)
Definition: ext2fs.h:958
BOOLEAN Ext2LookupFile(PEXT2_VOLUME_INFO Volume, PCSTR FileName, PEXT2_FILE_INFO Ext2FileInfo)
Definition: ext2.c:205
#define CEILING_ALIGNED(T, A, B)
Definition: ext2fs.h:111
LARGE_INTEGER Ext2NtTime(IN ULONG i_time)
Definition: misc.c:40
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
umode_t i_mode
Definition: fs.h:87
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
struct _FILE_ID_BOTH_DIR_INFORMATION * PFILE_ID_BOTH_DIR_INFORMATION
struct _FILE_DIRECTORY_INFORMATION * PFILE_DIRECTORY_INFORMATION
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:75
__u32 i_atime
Definition: fs.h:81
struct _FILE_FULL_DIRECTORY_INFORMATION * PFILE_FULL_DIR_INFORMATION
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
__u32 i_mtime
Definition: fs.h:83
Definition: fs.h:78
#define S_ISLNK(m)
Definition: ext2fs.h:368
LARGE_INTEGER ChangeTime
Definition: winternl.h:519
LARGE_INTEGER LastWriteTime
Definition: from_kernel.h:143
LARGE_INTEGER EndOfFile
Definition: winternl.h:520
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
LARGE_INTEGER AllocationSize
Definition: from_kernel.h:146
unsigned char BOOLEAN
#define DL_CP
Definition: ext2fs.h:1405
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:959
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN Ext2LoadInode(IN PEXT2_VCB Vcb, IN struct inode *Inode)
Definition: generic.c:504
struct _FILE_NAMES_INFORMATION * PFILE_NAMES_INFORMATION
Definition: bufpool.h:45
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE _In_ ACCESS_MASK _In_ POBJECT_ATTRIBUTES _Out_ PIO_STATUS_BLOCK _In_opt_ PLARGE_INTEGER _In_ ULONG FileAttributes
Definition: fltkernel.h:1230
#define FILE_ATTRIBUTE_REPARSE_POINT
Definition: ntifs_ex.h:381
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
int64_t LONGLONG
Definition: typedefs.h:66
#define BLOCK_SIZE
Definition: dlist.c:220
__u32 i_ctime
Definition: fs.h:82
static LPSTR pName
Definition: security.c:75
loff_t i_size
Definition: fs.h:80
#define DL_INF
Definition: ext2fs.h:1399
uint64_t ULONGLONG
Definition: typedefs.h:65
#define S_ISDIR(mode)
Definition: various.h:18
#define IsMcbSymLink(Mcb)
Definition: ext2fs.h:953
#define Vcb
Definition: cdprocs.h:1425
LARGE_INTEGER LastWriteTime
Definition: winternl.h:518
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Must_inspect_result_ typedef _In_ ULONG _In_ BOOLEAN Target
Definition: iotypes.h:1068
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOLEAN Ext2IsSpecialSystemFile(IN PUNICODE_STRING FileName, IN BOOLEAN bDirectory)
Definition: create.c:224
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:126
#define STATUS_INVALID_INFO_CLASS
Definition: ntstatus.h:226
static const WCHAR L[]
Definition: oid.c:1250
_Must_inspect_result_ _In_ PFLT_INSTANCE _Out_ PBOOLEAN IsDirectory
Definition: fltkernel.h:1139
PEXT2_MCB Ext2SearchMcb(PEXT2_VCB Vcb, PEXT2_MCB Parent, PUNICODE_STRING FileName)
Definition: memory.c:1598
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
__u32 i_ino
Definition: fs.h:79
ClearFlag(Dirent->Flags, DIRENT_FLAG_NOT_PERSISTENT)
Status
Definition: gdiplustypes.h:24
#define DL_ERR
Definition: ext2fs.h:1397
#define DL_RES
Definition: ext2fs.h:1403
IN PFCB IN PFILE_OBJECT FileObject IN ULONG AllocationSize
Definition: fatprocs.h:310
#define SetFlag(_F, _SF)
Definition: ext2fs.h:187
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
GLuint in
Definition: glext.h:9616
LARGE_INTEGER CreationTime
Definition: winternl.h:516
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:334
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
ULONG Ext2GetInfoLength(IN FILE_INFORMATION_CLASS FileInformationClass)
Definition: dirctl.c:30
LARGE_INTEGER CreationTime
Definition: from_kernel.h:141
#define IsMcbSpecialFile(Mcb)
Definition: ext2fs.h:955
int Ext2CheckInodeAccess(PEXT2_VCB Vcb, struct inode *in, int attempt)
Definition: access.c:20
#define IsRoot(Fcb)
Definition: ext2fs.h:282
unsigned int ULONG
Definition: retypes.h:1
struct super_block * i_sb
Definition: fs.h:96
#define DbgBreak()
Definition: ext2fs.h:46
#define DEBUG(args)
Definition: rdesktop.h:129
LARGE_INTEGER LastAccessTime
Definition: from_kernel.h:142
struct _FILE_ID_FULL_DIR_INFORMATION * PFILE_ID_FULL_DIR_INFORMATION
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:524
return STATUS_SUCCESS
Definition: btrfs.c:2966
#define S_ISREG(mode)
Definition: various.h:17
_In_ PIO_STACK_LOCATION _Inout_ PFILE_OBJECT _Inout_ PVCB _Outptr_result_maybenull_ PDCB * Dcb
Definition: create.c:4157
#define Ext2FileCanWrite
Definition: ext2fs.h:427
#define IO_REPARSE_TAG_SYMLINK
Definition: iotypes.h:6884
LARGE_INTEGER AllocationSize
Definition: winternl.h:521
LONGLONG QuadPart
Definition: typedefs.h:112
WCHAR FileName[ANYSIZE_ARRAY]
Definition: winternl.h:539

Referenced by Ext2FillEntry(), and Ext2QueryDirectory().

◆ Ext2QueryDirectory()

NTSTATUS Ext2QueryDirectory ( IN PEXT2_IRP_CONTEXT  IrpContext)

Definition at line 525 of file dirctl.c.

526 {
529  PEXT2_VCB Vcb = NULL;
531  PEXT2_FCB Fcb = NULL;
532  PEXT2_MCB Mcb = NULL;
533  PEXT2_CCB Ccb = NULL;
534  PIRP Irp = NULL;
535  PIO_STACK_LOCATION IoStackLocation = NULL;
536 
537  ULONG Length;
538  ULONG FileIndex;
540  PUCHAR Buffer;
541 
544  BOOLEAN IndexSpecified;
545  BOOLEAN FirstQuery;
546  BOOLEAN FcbResourceAcquired = FALSE;
547 
548  USHORT NameLen;
550 
551  OEM_STRING Oem = { 0 };
552  UNICODE_STRING Unicode = { 0 };
553  PEXT2_DIR_ENTRY2 pDir = NULL;
554 
556  ULONG RecLen = 0;
557  ULONG EntrySize = 0;
558 
559  EXT2_FILLDIR_CONTEXT fc = { 0 };
560 
561  _SEH2_TRY {
562 
563  ASSERT(IrpContext);
564  ASSERT((IrpContext->Identifier.Type == EXT2ICX) &&
565  (IrpContext->Identifier.Size == sizeof(EXT2_IRP_CONTEXT)));
566 
567  DeviceObject = IrpContext->DeviceObject;
568 
569  //
570  // This request is not allowed on the main device object
571  //
574  _SEH2_LEAVE;
575  }
576 
578  ASSERT(Vcb != NULL);
579  ASSERT((Vcb->Identifier.Type == EXT2VCB) &&
580  (Vcb->Identifier.Size == sizeof(EXT2_VCB)));
581 
582  if (!IsMounted(Vcb)) {
584  _SEH2_LEAVE;
585  }
586 
587  if (FlagOn(Vcb->Flags, VCB_VOLUME_LOCKED)) {
589  _SEH2_LEAVE;
590  }
591 
592  FileObject = IrpContext->FileObject;
593  Fcb = (PEXT2_FCB) FileObject->FsContext;
594  if (Fcb == NULL) {
596  _SEH2_LEAVE;
597  }
598  Mcb = Fcb->Mcb;
599  if (NULL == Mcb) {
601  _SEH2_LEAVE;
602  }
603  ASSERT (!IsMcbSymLink(Mcb));
604 
605  //
606  // This request is not allowed on volumes
607  //
608  if (Fcb->Identifier.Type == EXT2VCB) {
610  _SEH2_LEAVE;
611  }
612 
613  ASSERT((Fcb->Identifier.Type == EXT2FCB) &&
614  (Fcb->Identifier.Size == sizeof(EXT2_FCB)));
615 
616  if (!IsMcbDirectory(Mcb)) {
618  _SEH2_LEAVE;
619  }
620 
621  if (IsFileDeleted(Mcb)) {
623  _SEH2_LEAVE;
624  }
625 
626  Ccb = (PEXT2_CCB) FileObject->FsContext2;
627 
628  ASSERT(Ccb);
629  ASSERT((Ccb->Identifier.Type == EXT2CCB) &&
630  (Ccb->Identifier.Size == sizeof(EXT2_CCB)));
631 
632  Irp = IrpContext->Irp;
633  IoStackLocation = IoGetCurrentIrpStackLocation(Irp);
634 
635 #ifndef _GNU_NTIFS_
636 
637  fi = IoStackLocation->Parameters.QueryDirectory.FileInformationClass;
638 
639  Length = IoStackLocation->Parameters.QueryDirectory.Length;
640 
641  FileName = (PUNICODE_STRING)IoStackLocation->Parameters.QueryDirectory.FileName;
642 
643  FileIndex = IoStackLocation->Parameters.QueryDirectory.FileIndex;
644 
645 #else // _GNU_NTIFS_
646 
648  IoStackLocation)->Parameters.QueryDirectory.FileInformationClass;
649 
651  IoStackLocation)->Parameters.QueryDirectory.Length;
652 
654  IoStackLocation)->Parameters.QueryDirectory.FileName;
655 
656  FileIndex = ((PEXTENDED_IO_STACK_LOCATION)
657  IoStackLocation)->Parameters.QueryDirectory.FileIndex;
658 
659 #endif // _GNU_NTIFS_
660 
662  IoStackLocation)->Flags, SL_RESTART_SCAN);
664  IoStackLocation)->Flags, SL_RETURN_SINGLE_ENTRY);
665  IndexSpecified = FlagOn(((PEXTENDED_IO_STACK_LOCATION)
666  IoStackLocation)->Flags, SL_INDEX_SPECIFIED);
667 
669  if (Buffer == NULL) {
670  DbgBreak();
672  _SEH2_LEAVE;
673  }
674 
675  if (!IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {
677  _SEH2_LEAVE;
678  }
679 
681  &Fcb->MainResource,
682  IsFlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) )) {
684  _SEH2_LEAVE;
685  }
686  FcbResourceAcquired = TRUE;
687 
688  if (FileName != NULL) {
689 
690  if (Ccb->DirectorySearchPattern.Buffer != NULL) {
691 
692  FirstQuery = FALSE;
693 
694  } else {
695 
696  FirstQuery = TRUE;
697 
698  Ccb->DirectorySearchPattern.Length =
699  Ccb->DirectorySearchPattern.MaximumLength =
700  FileName->Length;
701 
702  Ccb->DirectorySearchPattern.Buffer =
705 
706  if (Ccb->DirectorySearchPattern.Buffer == NULL) {
707  DEBUG(DL_ERR, ( "Ex2QueryDirectory: failed to allocate SerarchPattern.\n"));
709  _SEH2_LEAVE;
710  }
711 
713  Ccb->DirectorySearchPattern.Buffer,
714  Ccb->DirectorySearchPattern.MaximumLength);
715 
717  &(Ccb->DirectorySearchPattern),
718  FileName,
719  FALSE);
720 
721  if (!NT_SUCCESS(Status)) {
722  _SEH2_LEAVE;
723  }
724  }
725 
726  } else if (Ccb->DirectorySearchPattern.Buffer != NULL) {
727 
728  FirstQuery = FALSE;
729  FileName = &Ccb->DirectorySearchPattern;
730 
731  } else {
732 
733  FirstQuery = TRUE;
734 
735  Ccb->DirectorySearchPattern.Length =
736  Ccb->DirectorySearchPattern.MaximumLength = 2;
737 
738  Ccb->DirectorySearchPattern.Buffer =
740 
741  if (Ccb->DirectorySearchPattern.Buffer == NULL) {
742  DEBUG(DL_ERR, ( "Ex2QueryDirectory: failed to allocate SerarchPattern (1st).\n"));
744  _SEH2_LEAVE;
745  }
746 
748  Ccb->DirectorySearchPattern.Buffer,
749  Ccb->DirectorySearchPattern.MaximumLength);
750 
751  RtlZeroMemory(Ccb->DirectorySearchPattern.Buffer, 4);
753  Ccb->DirectorySearchPattern.Buffer,
754  L"*\0", 2);
755  }
756 
757  if (IndexSpecified) {
758  Ccb->filp.f_pos = FileIndex;
759  } else {
760  if (RestartScan || FirstQuery) {
761  Ccb->filp.f_pos = FileIndex = 0;
762  } else {
763  FileIndex = (ULONG)Ccb->filp.f_pos;
764  }
765  }
766 
768 
769  fc.efc_irp = IrpContext;
770  fc.efc_buf = Buffer;
771  fc.efc_size = Length;
772  fc.efc_start = 0;
773  fc.efc_single = ReturnSingleEntry;
774  fc.efc_fi = fi;
775  fc.efc_status = STATUS_SUCCESS;
776 
777 #ifdef EXT2_HTREE_INDEX
778 
779  if (EXT3_HAS_COMPAT_FEATURE(Mcb->Inode.i_sb,
781  ((EXT3_I(&Mcb->Inode)->i_flags & EXT3_INDEX_FL) ||
782  ((Mcb->Inode.i_size >> BLOCK_BITS) == 1)) ) {
783  int rc = ext3_dx_readdir(&Ccb->filp, Ext2FillEntry, &fc);
784  Status = fc.efc_status;
785  if (rc != ERR_BAD_DX_DIR) {
786  goto errorout;
787  }
788  /*
789  * We don't set the inode dirty flag since it's not
790  * critical that it get flushed back to the disk.
791  */
792  EXT3_I(&Mcb->Inode)->i_flags &= ~EXT3_INDEX_FL;
793  }
794 #endif
795 
796  if (Mcb->Inode.i_size <= Ccb->filp.f_pos) {
798  _SEH2_LEAVE;
799  }
800 
801  pDir = Ext2AllocatePool(
802  PagedPool,
803  sizeof(EXT2_DIR_ENTRY2),
805  );
806 
807  if (!pDir) {
808  DEBUG(DL_ERR, ( "Ex2QueryDirectory: failed to allocate pDir.\n"));
810  _SEH2_LEAVE;
811  }
812 
814  ByteOffset = FileIndex;
815 
816  DEBUG(DL_CP, ("Ex2QueryDirectory: Dir: %wZ Index=%xh Pattern : %wZ.\n",
817  &Fcb->Mcb->FullName, FileIndex, &Ccb->DirectorySearchPattern));
818 
819  while ((ByteOffset < Mcb->Inode.i_size) &&
820  (CEILING_ALIGNED(ULONG, fc.efc_start, 8) < Length)) {
821 
822  RtlZeroMemory(pDir, sizeof(EXT2_DIR_ENTRY2));
823 
825  IrpContext,
826  Vcb,
827  Mcb,
829  (PVOID)pDir,
830  sizeof(EXT2_DIR_ENTRY2),
831  FALSE,
832  &EntrySize);
833 
834  if (!NT_SUCCESS(Status)) {
835  DbgBreak();
836  _SEH2_LEAVE;
837  }
838 
839  if (pDir->rec_len == 0) {
840  RecLen = BLOCK_SIZE - (ByteOffset & (BLOCK_SIZE - 1));
841  } else {
842  RecLen = ext3_rec_len_from_disk(pDir->rec_len);
843  }
844 
845  if (!pDir->inode || pDir->inode >= INODES_COUNT) {
846  goto ProcessNextEntry;
847  }
848 
849  /* skip . and .. */
850  if ((pDir->name_len == 1 && pDir->name[0] == '.') ||
851  (pDir->name_len == 2 && pDir->name[0] == '.' && pDir->name[1] == '.' )) {
852  goto ProcessNextEntry;
853  }
854 
855  Oem.Buffer = pDir->name;
856  Oem.Length = (pDir->name_len & 0xff);
857  Oem.MaximumLength = Oem.Length;
858 
859  if (Ext2IsWearingCloak(Vcb, &Oem)) {
860  goto ProcessNextEntry;
861  }
862 
863  NameLen = (USHORT) Ext2OEMToUnicodeSize(Vcb, &Oem);
864 
865  if (NameLen <= 0) {
866  DEBUG(DL_CP, ("Ext2QueryDirectory: failed to count unicode length for inode: %xh\n",
867  pDir->inode));
869  break;
870  }
871 
872  if ( Unicode.Buffer != NULL && Unicode.MaximumLength > NameLen) {
873  /* reuse buffer */
874  } else {
875  /* free and re-allocate it */
876  if (Unicode.Buffer) {
878  Unicode.Buffer,
879  Unicode.MaximumLength);
881  }
882  Unicode.MaximumLength = NameLen + 2;
883  Unicode.Buffer = Ext2AllocatePool(
884  PagedPool, Unicode.MaximumLength,
886  );
887  if (!Unicode.Buffer) {
888  DEBUG(DL_ERR, ( "Ex2QueryDirectory: failed to "
889  "allocate InodeFileName.\n"));
891  _SEH2_LEAVE;
892  }
893  INC_MEM_COUNT(PS_INODE_NAME, Unicode.Buffer, Unicode.MaximumLength);
894  }
895 
896  Unicode.Length = 0;
897  RtlZeroMemory(Unicode.Buffer, Unicode.MaximumLength);
898 
899  Status = Ext2OEMToUnicode(Vcb, &Unicode, &Oem);
900  if (!NT_SUCCESS(Status)) {
901  DEBUG(DL_ERR, ( "Ex2QueryDirectory: Ext2OEMtoUnicode failed with %xh.\n", Status));
903  _SEH2_LEAVE;
904  }
905 
906  DEBUG(DL_CP, ( "Ex2QueryDirectory: process inode: %xh / %wZ (%d).\n",
907  pDir->inode, &Unicode, Unicode.Length));
908 
910  &(Ccb->DirectorySearchPattern)) ?
912  &(Ccb->DirectorySearchPattern),
913  &Unicode,
914  TRUE,
915  NULL) :
917  &(Ccb->DirectorySearchPattern),
918  &Unicode,
919  TRUE) ) {
920 
922  IrpContext,
923  Vcb,
924  Fcb,
925  fi,
926  pDir->inode,
927  Buffer,
928  CEILING_ALIGNED(ULONG, fc.efc_start, 8),
929  Length - CEILING_ALIGNED(ULONG, fc.efc_start, 8),
930  ByteOffset,
931  &Unicode,
932  &EntrySize,
934  );
935 
936  if (NT_SUCCESS(Status)) {
937  if (EntrySize > 0) {
938  fc.efc_prev = CEILING_ALIGNED(ULONG, fc.efc_start, 8);
939  fc.efc_start = fc.efc_prev + EntrySize;
940  } else {
941  DbgBreak();
942  }
943  } else {
945  if (fc.efc_start == 0) {
946  fc.efc_start = EntrySize;
947  } else {
949  }
950  } else {
951  _SEH2_LEAVE;
952  }
953  break;
954  }
955  }
956 
957 ProcessNextEntry:
958 
959  ByteOffset += RecLen;
960  Ccb->filp.f_pos = ByteOffset;
961 
962  if (fc.efc_start && ReturnSingleEntry) {
964  goto errorout;
965  }
966  }
967 
968 errorout:
969 
970  ((PULONG)((PUCHAR)Buffer + fc.efc_prev))[0] = 0;
971  FileIndex = ByteOffset;
972 
974  /* just return fc.efc_start/EntrySize bytes that we filled */
975  } else if (!fc.efc_start) {
976  if (NT_SUCCESS(Status)) {
977  if (FirstQuery) {
979  } else {
981  }
982  }
983  } else {
985  }
986 
987  } _SEH2_FINALLY {
988 
989  if (FcbResourceAcquired) {
991  }
992 
993  if (pDir != NULL) {
996  }
997 
998  if (Unicode.Buffer != NULL) {
999  DEC_MEM_COUNT(PS_INODE_NAME, Unicode.Buffer, Unicode.MaximumLength);
1001  }
1002 
1003  if (!IrpContext->ExceptionInProgress) {
1004 
1005  if ( Status == STATUS_PENDING ||
1006  Status == STATUS_CANT_WAIT) {
1007 
1009  IrpContext->Irp,
1010  Length,
1011  IoWriteAccess );
1012 
1013  if (NT_SUCCESS(Status)) {
1014  Status = Ext2QueueRequest(IrpContext);
1015  } else {
1016  Ext2CompleteIrpContext(IrpContext, Status);
1017  }
1018  } else {
1019  IrpContext->Irp->IoStatus.Information = fc.efc_start;
1020  Ext2CompleteIrpContext(IrpContext, Status);
1021  }
1022  }
1023  } _SEH2_END;
1024 
1025  return Status;
1026 }
#define EXT3_INDEX_FL
Definition: ext3_fs.h:220
struct _EXT2_FCB * PEXT2_FCB
BOOLEAN Ext2ReadInode(PEXT2_VOLUME_INFO Volume, ULONG Inode, PEXT2_INODE InodeBuffer)
Definition: ext2.c:909
#define IsMounted(Vcb)
Definition: ext2fs.h:803
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define IRP_CONTEXT_FLAG_WAIT
Definition: cdstruc.h:1221
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSTATUS RtlUpcaseUnicodeString(PUNICODE_STRING dst, PUNICODE_STRING src, BOOLEAN Alloc)
Definition: string_lib.cpp:46
#define IsMcbDirectory(Mcb)
Definition: ext2fs.h:958
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN _In_ ULONG _In_opt_ PULONG _In_ BOOLEAN RestartScan
Definition: fltkernel.h:2298
#define SL_INDEX_SPECIFIED
Definition: iotypes.h:1794
#define DEC_MEM_COUNT(_i, _p, _s)
Definition: ext2fs.h:599
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define CEILING_ALIGNED(T, A, B)
Definition: ext2fs.h:111
_In_ PIRP Irp
Definition: csq.h:116
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
Definition: ext3_fs.h:774
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ BOOLEAN ReturnSingleEntry
Definition: fltkernel.h:2295
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
NTSTATUS Ext2LockUserBuffer(IN PIRP Irp, IN ULONG Length, IN LOCK_OPERATION Operation)
Definition: block.c:101
#define EXT2_INAME_MAGIC
Definition: ext2fs.h:292
STRING OEM_STRING
Definition: umtypes.h:203
_In_ UCHAR EntrySize
Definition: iofuncs.h:640
BOOLEAN NTAPI FsRtlDoesNameContainWildCards(IN PUNICODE_STRING Name)
Definition: name.c:464
BOOLEAN NTAPI FsRtlIsNameInExpression(IN PUNICODE_STRING Expression, IN PUNICODE_STRING Name, IN BOOLEAN IgnoreCase, IN PWCHAR UpcaseTable OPTIONAL)
Definition: name.c:514
#define PS_INODE_NAME
Definition: common.h:26
_SEH2_TRY
Definition: create.c:4250
int ext3_dx_readdir(struct file *filp, filldir_t filldir, void *context)
NTFSIDENTIFIER Identifier
Definition: ntfs.h:511
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define STATUS_NOT_A_DIRECTORY
Definition: udferr_usr.h:169
NTSTATUS Ext2QueueRequest(IN PEXT2_IRP_CONTEXT IrpContext)
Definition: dispatch.c:150
NTSTATUS Ext2ProcessEntry(IN PEXT2_IRP_CONTEXT IrpContext, IN PEXT2_VCB Vcb, IN PEXT2_FCB Dcb, IN FILE_INFORMATION_CLASS FileInformationClass, IN ULONG in, IN PVOID Buffer, IN ULONG UsedLength, IN ULONG Length, IN ULONG FileIndex, IN PUNICODE_STRING pName, OUT PULONG EntrySize, IN BOOLEAN Single)
Definition: dirctl.c:60
#define IsFlagOn(a, b)
Definition: ext2fs.h:177
#define STATUS_INVALID_USER_BUFFER
Definition: udferr_usr.h:166
#define EXT2_DIRSP_MAGIC
Definition: ext2fs.h:296
PVOID DeviceExtension
Definition: env_spec_w32.h:418
unsigned char BOOLEAN
#define DL_CP
Definition: ext2fs.h:1405
#define BLOCK_BITS
Definition: stream.h:22
#define IsFileDeleted(Mcb)
Definition: ext2fs.h:959
smooth NULL
Definition: ftsmooth.c:416
#define INC_MEM_COUNT(_i, _p, _s)
Definition: ext2fs.h:598
Definition: bufpool.h:45
_Inout_ PFILE_OBJECT FileObject
Definition: cdprocs.h:593
#define PS_DIR_ENTRY
Definition: common.h:27
ULONG Ext2OEMToUnicodeSize(IN PEXT2_VCB Vcb, IN PANSI_STRING Oem)
Definition: misc.c:183
#define EXT3_HAS_COMPAT_FEATURE(sb, mask)
Definition: ext3_fs.h:645
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
static int Ext2FillEntry(void *context, const char *name, int namlen, ULONG offset, __u32 ino, unsigned int d_type)
Definition: dirctl.c:415
#define BLOCK_SIZE
Definition: dlist.c:220
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MORE_FILES
Definition: udferr_usr.h:128
uint64_t ULONGLONG
Definition: typedefs.h:65
#define IsMcbSymLink(Mcb)
Definition: ext2fs.h:953
#define Vcb
Definition: cdprocs.h:1425
LPFOR_CONTEXT fc
Definition: for.c:53
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
* PFILE_OBJECT
Definition: iotypes.h:1955
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
CD_MCB Mcb
Definition: cdstruc.h:1022
_In_ PPCI_DEVICE_PRESENCE_PARAMETERS Parameters
Definition: iotypes.h:872
static const WCHAR L[]
Definition: oid.c:1250
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
NTSTATUS Ext2CompleteIrpContext(IN PEXT2_IRP_CONTEXT IrpContext, IN NTSTATUS Status)
Definition: read.c:32
ULONG Type
Definition: ntfs.h:95
_Inout_ PFILE_OBJECT _In_ TYPE_OF_OPEN PFCB _In_opt_ PCCB Ccb
Definition: cdprocs.h:593
#define FlagOn(_F, _SF)
Definition: ext2fs.h:179
ERESOURCE MainResource
Definition: ntfs.h:524
NTSTATUS Ext2OEMToUnicode(IN PEXT2_VCB Vcb, IN OUT PUNICODE_STRING Oem, IN POEM_STRING Unicode)
Definition: misc.c:206
#define EXT2_DENTRY_MAGIC
Definition: ext2fs.h:295
Status
Definition: gdiplustypes.h:24
#define DL_ERR
Definition: ext2fs.h:1397
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
__drv_aliasesMem FORCEINLINE PIO_STACK_LOCATION IoGetCurrentIrpStackLocation(_In_ PIRP Irp)
Definition: iofuncs.h:2745
struct _FileName FileName
Definition: fatprocs.h:884
#define SL_RETURN_SINGLE_ENTRY
Definition: iotypes.h:1793
_SEH2_END
Definition: create.c:4424
#define EXT3_FEATURE_COMPAT_DIR_INDEX
Definition: ext3_fs.h:669
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
unsigned short USHORT
Definition: pedump.c:61
IN PVCB IN ULONG IN OUT PULONG IN BOOLEAN OUT PLARGE_MCB Mcb
Definition: fatprocs.h:334
#define PS_DIR_PATTERN
Definition: common.h:28
#define STATUS_NO_SUCH_FILE
Definition: udferr_usr.h:137
_SEH2_FINALLY
Definition: create.c:4395
unsigned int * PULONG
Definition: retypes.h:1
#define SL_RESTART_SCAN
Definition: iotypes.h:1792
UNICODE_STRING * PUNICODE_STRING
Definition: env_spec_w32.h:373
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define VCB_VOLUME_LOCKED
Definition: ext2fs.h:780
static unsigned ext3_rec_len_from_disk(__le16 dlen)
Definition: ext3_fs.h:871
#define STATUS_VOLUME_DISMOUNTED
Definition: ntstatus.h:733
#define IsExt2FsDevice(DO)
Definition: ext2fs.h:607
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define INODES_COUNT
Definition: ext2fs.h:97
#define DbgBreak()
Definition: ext2fs.h:46
VOID Ext2FreePool(IN PVOID P, IN ULONG Tag)
Definition: debug.c:2697
struct _EXT2_VCB * PEXT2_VCB
#define DEBUG(args)
Definition: rdesktop.h:129
BOOLEAN Ext2IsWearingCloak(IN PEXT2_VCB Vcb, IN POEM_STRING OemName)
Definition: dirctl.c:372
#define _SEH2_LEAVE
Definition: filesup.c:20
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
_In_ PFCB Fcb
Definition: cdprocs.h:151
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2966
struct _EXT2_CCB * PEXT2_CCB
PVOID Ext2AllocatePool(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes, IN ULONG Tag)
Definition: debug.c:2684
ULONG Size
Definition: ntfs.h:96
PVOID Ext2GetUserBuffer(IN PIRP Irp)
Definition: block.c:134
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:716
#define STATUS_CANT_WAIT
Definition: ntstatus.h:438

Referenced by Ext2DirectoryControl().

Variable Documentation

◆ Ext2Global

PEXT2_GLOBAL Ext2Global

Definition at line 16 of file init.c.