https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8a0495063b9446e8d940f…
commit 8a0495063b9446e8d940fa64fadd30046c733711
Author: Bernhard Feichtinger <43303168+BieHDC(a)users.noreply.github.com>
AuthorDate: Tue Nov 13 20:45:27 2018 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Sun Nov 25 11:29:18 2018 +0100
[NTOS:MM] Handle unimplemeted case for MiCheckForUserStackOverflow
---
ntoskrnl/mm/ARM3/pagfault.c | 23 ++++++++++++++++++++++-
1 file changed, 22 insertions(+), 1 deletion(-)
diff --git a/ntoskrnl/mm/ARM3/pagfault.c b/ntoskrnl/mm/ARM3/pagfault.c
index c75c4596e6..77aaf754df 100644
--- a/ntoskrnl/mm/ARM3/pagfault.c
+++ b/ntoskrnl/mm/ARM3/pagfault.c
@@ -81,8 +81,29 @@ MiCheckForUserStackOverflow(IN PVOID Address,
/* Do we have at least one page between here and the end of the stack? */
if (((ULONG_PTR)NextStackAddress - PAGE_SIZE) <= (ULONG_PTR)DeallocationStack)
{
- /* We don't -- Windows would try to make this guard page valid now */
+ /* We don't -- Trying to make this guard page valid now */
DPRINT1("Close to our death...\n");
+
+ /* Calculate the next memory address */
+ NextStackAddress = (PVOID)((ULONG_PTR)PAGE_ALIGN(DeallocationStack) + GuranteedSize);
+
+ /* Allocate the memory */
+ Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
+ &NextStackAddress,
+ 0,
+ &GuranteedSize,
+ MEM_COMMIT,
+ PAGE_READWRITE);
+ if (NT_SUCCESS(Status))
+ {
+ /* Success! */
+ Teb->NtTib.StackLimit = NextStackAddress;
+ }
+ else
+ {
+ DPRINT1("Failed to allocate memory\n");
+ }
+
return STATUS_STACK_OVERFLOW;
}
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=40f066657ea194997e9c0…
commit 40f066657ea194997e9c06777e9942fac4ff6762
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Nov 25 00:27:44 2018 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Nov 25 10:38:54 2018 +0100
[MC] Add messages 5730-5769 to netmsg.dll.
---
sdk/include/reactos/mc/netmsgmsg.mc | 500 ++++++++++++++++++++++++++++++++++++
1 file changed, 500 insertions(+)
diff --git a/sdk/include/reactos/mc/netmsgmsg.mc b/sdk/include/reactos/mc/netmsgmsg.mc
index 59b4a32ab9..ff8eb1c264 100644
--- a/sdk/include/reactos/mc/netmsgmsg.mc
+++ b/sdk/include/reactos/mc/netmsgmsg.mc
@@ -9185,3 +9185,503 @@ Language=Russian
Replication of the %1 Domain Object \"%2\" from primary domain controller\n
%3 failed with the following error: %n%4
.
+
+MessageId=5730
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonFailedGlobalGroupDelta
+Language=English
+Replication of the %1 Global Group \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+Language=Russian
+Replication of the %1 Global Group \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+
+MessageId=5731
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonFailedLocalGroupDelta
+Language=English
+Replication of the %1 Local Group \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+Language=Russian
+Replication of the %1 Local Group \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+
+MessageId=5732
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonFailedUserDelta
+Language=English
+Replication of the %1 User \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+Language=Russian
+Replication of the %1 User \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+
+MessageId=5733
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonFailedPolicyDelta
+Language=English
+Replication of the %1 Policy Object \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+Language=Russian
+Replication of the %1 Policy Object \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+
+MessageId=5734
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonFailedTrustedDomainDelta
+Language=English
+Replication of the %1 Trusted Domain Object \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+Language=Russian
+Replication of the %1 Trusted Domain Object \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+
+MessageId=5735
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonFailedAccountDelta
+Language=English
+Replication of the %1 Account Object \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+Language=Russian
+Replication of the %1 Account Object \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+
+MessageId=5736
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonFailedSecretDelta
+Language=English
+Replication of the %1 Secret \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+Language=Russian
+Replication of the %1 Secret \"%2\" from primary domain controller\n
+%3 failed with the following error: %n%4
+.
+
+MessageId=5737
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonSystemError
+Language=English
+The system returned the following unexpected error code: %n%1
+.
+Language=Russian
+The system returned the following unexpected error code: %n%1
+.
+
+MessageId=5738
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonDuplicateMachineAccounts
+Language=English
+Netlogon has detected two machine accounts for server \"%1\".\n
+The server can be either a Windows 2000 Server that is a member of the\n
+domain or the server can be a LAN Manager server with an account in the\n
+SERVERS global group. It cannot be both.
+.
+Language=Russian
+Netlogon has detected two machine accounts for server \"%1\".\n
+The server can be either a Windows 2000 Server that is a member of the\n
+domain or the server can be a LAN Manager server with an account in the\n
+SERVERS global group. It cannot be both.
+.
+
+MessageId=5739
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonTooManyGlobalGroups
+Language=English
+This domain has more global groups than can be replicated to a LanMan\n
+BDC. Either delete some of your global groups or remove the LanMan\n
+BDCs from the domain.
+.
+Language=Russian
+This domain has more global groups than can be replicated to a LanMan\n
+BDC. Either delete some of your global groups or remove the LanMan\n
+BDCs from the domain.
+.
+
+MessageId=5740
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonBrowserDriver
+Language=English
+The Browser driver returned the following error to Netlogon: %n%1
+.
+Language=Russian
+The Browser driver returned the following error to Netlogon: %n%1
+.
+
+MessageId=5741
+Severity=Success
+Facility=System
+SymbolicName=NELOG_NetlogonAddNameFailure
+Language=English
+Netlogon could not register the %1<1B> name for the following reason: %n%2
+.
+Language=Russian
+Netlogon could not register the %1<1B> name for the following reason: %n%2
+.
+
+MessageId=5742
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplMessages
+Language=English
+Service failed to retrieve messages needed to boot remote boot clients.
+.
+Language=Russian
+Service failed to retrieve messages needed to boot remote boot clients.
+.
+
+MessageId=5743
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplXnsBoot
+Language=English
+Service experienced a severe error and can no longer provide remote boot\n
+for 3Com 3Start remote boot clients.
+.
+Language=Russian
+Service experienced a severe error and can no longer provide remote boot\n
+for 3Com 3Start remote boot clients.
+.
+
+MessageId=5744
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplSystem
+Language=English
+Service experienced a severe system error and will shut itself down.
+.
+Language=Russian
+Service experienced a severe system error and will shut itself down.
+.
+
+MessageId=5745
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaTimeout
+Language=English
+Client with computer name %1 failed to acknowledge receipt of the\n
+boot data. Remote boot of this client was not completed.
+.
+Language=Russian
+Client with computer name %1 failed to acknowledge receipt of the\n
+boot data. Remote boot of this client was not completed.
+.
+
+MessageId=5746
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaFileOpen
+Language=English
+Client with computer name %1 was not booted due to an error in opening\n
+file %2.
+.
+Language=Russian
+Client with computer name %1 was not booted due to an error in opening\n
+file %2.
+.
+
+MessageId=5747
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaFileRead
+Language=English
+Client with computer name %1 was not booted due to an error in reading\n
+file %2.
+.
+Language=Russian
+Client with computer name %1 was not booted due to an error in reading\n
+file %2.
+.
+
+MessageId=5748
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaMemory
+Language=English
+Client with computer name %1 was not booted due to insufficient memory\n
+at the remote boot server.
+.
+Language=Russian
+Client with computer name %1 was not booted due to insufficient memory\n
+at the remote boot server.
+.
+
+MessageId=5749
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaFileChecksum
+Language=English
+Client with computer name %1 will be booted without using checksums\n
+because checksum for file %2 could not be calculated.
+.
+Language=Russian
+Client with computer name %1 will be booted without using checksums\n
+because checksum for file %2 could not be calculated.
+.
+
+MessageId=5750
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaFileLineCount
+Language=English
+Client with computer name %1 was not booted due to too many lines in\n
+file %2.
+.
+Language=Russian
+Client with computer name %1 was not booted due to too many lines in\n
+file %2.
+.
+
+MessageId=5751
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaBbcFile
+Language=English
+Client with computer name %1 was not booted because the boot block\n
+configuration file %2 for this client does not contain boot block\n
+line and/or loader line.
+.
+Language=Russian
+Client with computer name %1 was not booted because the boot block\n
+configuration file %2 for this client does not contain boot block\n
+line and/or loader line.
+.
+
+MessageId=5752
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaFileSize
+Language=English
+Client with computer name %1 was not booted due to a bad size of\n
+file %2.
+.
+Language=Russian
+Client with computer name %1 was not booted due to a bad size of\n
+file %2.
+.
+
+MessageId=5753
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaInternal
+Language=English
+Client with computer name %1 was not booted due to remote boot\n
+service internal error.
+.
+Language=Russian
+Client with computer name %1 was not booted due to remote boot\n
+service internal error.
+.
+
+MessageId=5754
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaWrongVersion
+Language=English
+Client with computer name %1 was not booted because file %2 has an\n
+invalid boot header.
+.
+Language=Russian
+Client with computer name %1 was not booted because file %2 has an\n
+invalid boot header.
+.
+
+MessageId=5755
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplWkstaNetwork
+Language=English
+Client with computer name %1 was not booted due to network error.
+.
+Language=Russian
+Client with computer name %1 was not booted due to network error.
+.
+
+MessageId=5756
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplAdapterResource
+Language=English
+Client with adapter id %1 was not booted due to lack of resources.
+.
+Language=Russian
+Client with adapter id %1 was not booted due to lack of resources.
+.
+
+MessageId=5757
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplFileCopy
+Language=English
+Service experienced error copying file or directory %1.
+.
+Language=Russian
+Service experienced error copying file or directory %1.
+.
+
+MessageId=5758
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplFileDelete
+Language=English
+Service experienced error deleting file or directory %1.
+.
+Language=Russian
+Service experienced error deleting file or directory %1.
+.
+
+MessageId=5759
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplFilePerms
+Language=English
+Service experienced error setting permissions on file or directory %1.
+.
+Language=Russian
+Service experienced error setting permissions on file or directory %1.
+.
+
+MessageId=5760
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplCheckConfigs
+Language=English
+Service experienced error evaluating RPL configurations.
+.
+Language=Russian
+Service experienced error evaluating RPL configurations.
+.
+
+MessageId=5761
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplCreateProfiles
+Language=English
+Service experienced error creating RPL profiles for all configurations.
+.
+Language=Russian
+Service experienced error creating RPL profiles for all configurations.
+.
+
+MessageId=5762
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplRegistry
+Language=English
+Service experienced error accessing registry.
+.
+Language=Russian
+Service experienced error accessing registry.
+.
+
+MessageId=5763
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplReplaceRPLDISK
+Language=English
+Service experienced error replacing possibly outdated RPLDISK.SYS.
+.
+Language=Russian
+Service experienced error replacing possibly outdated RPLDISK.SYS.
+.
+
+MessageId=5764
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplCheckSecurity
+Language=English
+Service experienced error adding security accounts or setting\n
+file permissions. These accounts are the RPLUSER local group\n
+and the user accounts for the individual RPL workstations.
+.
+Language=Russian
+Service experienced error adding security accounts or setting\n
+file permissions. These accounts are the RPLUSER local group\n
+and the user accounts for the individual RPL workstations.
+.
+
+MessageId=5765
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplBackupDatabase
+Language=English
+Service failed to back up its database.
+.
+Language=Russian
+Service failed to back up its database.
+.
+
+MessageId=5766
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplInitDatabase
+Language=English
+Service failed to initialize from its database. The database may be\n
+missing or corrupted. Service will attempt restoring the database\n
+from the backup.
+.
+Language=Russian
+Service failed to initialize from its database. The database may be\n
+missing or corrupted. Service will attempt restoring the database\n
+from the backup.
+.
+
+MessageId=5767
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplRestoreDatabaseFailure
+Language=English
+Service failed to restore its database from the backup. Service\n
+will not start.
+.
+Language=Russian
+Service failed to restore its database from the backup. Service\n
+will not start.
+.
+
+MessageId=5768
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplRestoreDatabaseSuccess
+Language=English
+Service successfully restored its database from the backup.
+.
+Language=Russian
+Service successfully restored its database from the backup.
+.
+
+MessageId=5769
+Severity=Success
+Facility=System
+SymbolicName=NELOG_RplInitRestoredDatabase
+Language=English
+Service failed to initialize from its restored database. Service\n
+will not start.
+.
+Language=Russian
+Service failed to initialize from its restored database. Service\n
+will not start.
+.
https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b77824a3759c70e905420…
commit b77824a3759c70e9054207078ccce33ec435afcf
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Nov 11 17:17:48 2018 +0100
Commit: Pierre Schweitzer <pierre(a)reactos.org>
CommitDate: Sun Nov 25 09:00:40 2018 +0100
[FASTFAT] Improvements for volume dismount + minor bugfixing.
- Cache the RootFcb so that its cleanup can be handled separately
during dismounting.
- Force volume dismount at cleanup if the VCB_DISMOUNT_PENDING flag
is set.
- Actually dismount a volume if its VCB has been flagged as not good,
or if we force dismounting.
NOTE: In their *CheckForDismount() function, our 3rd-party FS drivers
as well as MS' fastfat, perform a comparison check of the current VCB's
VPB ReferenceCount with some sort of "dangling"/"residual" open count.
It seems to be related to the fact that the volume root directory as
well as auxiliary data stream(s) are still opened, and only these are
allowed to be opened at that moment. After analysis it appears that for
the ReactOS' fastfat, this number is equal to "3".
- On dismounting, cleanup and destroy the RootFcb, VolumeFcb and the
FATFileObject. Then cleanup the SpareVPB or the IoVPB members, and
finish by removing the dismounted volume from the VolumeListEntry
and cleaning up the notify synchronization object and the resources.
- During dismounting, and on shutdown, flush the volume before
resetting its dirty bit.
- On shutdown, after volume flushing, try to unmount it without forcing.
- Release the VCB resources only when we actually dismount the volume
in VfatCheckForDismount().
- Initialize first the notify list and the synchronization object,
before sending the FSRTL_VOLUME_MOUNT notification.
- If we failed at mounting a volume but its VCB's FATFileObject was
already initialized, first call CcUninitializeCacheMap() on it
before dereferencing it.
- Send FSRTL_VOLUME_LOCK, FSRTL_VOLUME_LOCK_FAILED and
FSRTL_VOLUME_UNLOCK notifications during volume locking (and failure)
and volume unlocking.
- Flush the volume before locking it, and clean its dirty bit if needed.
NOTE: In addition to checking for VCB_CLEAR_DIRTY, we also check for the
presence of the VCB_IS_DIRTY flag before cleaning up the dirty bit: this
allows us to not re-clean the bit if it has been previously cleaned.
This is needed for instance in this scenario:
- The volume is locked (it gets flushed and the dirty bit is possibly cleared);
- The volume then gets formatted with a completely different FS, that
possibly clears up the first sector (e.g. BTRFS ignores 1st sector);
- The volume is then dismounted: if we didn't check whether VCB_IS_DIRTY
was set prior to resetting it, we could attempt clearing it again! But
now that the volume's filesystem has been completely changed, we would
then try to modify the dirty bit on an erroneous position on disk!
That's why it should not be touched in this case during dismounting.
- The volume is unlocked (same comment as above), and later can be
detected as being BTRFS.
---
drivers/filesystems/fastfat/cleanup.c | 2 +-
drivers/filesystems/fastfat/close.c | 4 +-
drivers/filesystems/fastfat/fat.c | 6 --
drivers/filesystems/fastfat/fcb.c | 20 +++--
drivers/filesystems/fastfat/flush.c | 4 +-
drivers/filesystems/fastfat/fsctl.c | 92 +++++++++++++--------
drivers/filesystems/fastfat/misc.c | 141 +++++++++++++++++++++++++++------
drivers/filesystems/fastfat/shutdown.c | 17 ++--
drivers/filesystems/fastfat/vfat.h | 15 +++-
9 files changed, 220 insertions(+), 81 deletions(-)
diff --git a/drivers/filesystems/fastfat/cleanup.c b/drivers/filesystems/fastfat/cleanup.c
index 291cd77a2f..d09df956ca 100644
--- a/drivers/filesystems/fastfat/cleanup.c
+++ b/drivers/filesystems/fastfat/cleanup.c
@@ -161,7 +161,7 @@ VfatCleanupFile(
#ifdef ENABLE_SWAPOUT
if (IsVolume && BooleanFlagOn(DeviceExt->Flags, VCB_DISMOUNT_PENDING))
{
- VfatCheckForDismount(DeviceExt, FALSE);
+ VfatCheckForDismount(DeviceExt, TRUE);
}
#endif
diff --git a/drivers/filesystems/fastfat/close.c b/drivers/filesystems/fastfat/close.c
index d8f85a85a4..b6c250f92c 100644
--- a/drivers/filesystems/fastfat/close.c
+++ b/drivers/filesystems/fastfat/close.c
@@ -21,8 +21,8 @@ VfatCommonCloseFile(
PDEVICE_EXTENSION DeviceExt,
PVFATFCB pFcb)
{
- /* Nothing to do for volumes */
- if (BooleanFlagOn(pFcb->Flags, FCB_IS_VOLUME))
+ /* Nothing to do for volumes or for the FAT file object */
+ if (BooleanFlagOn(pFcb->Flags, FCB_IS_FAT | FCB_IS_VOLUME))
{
return;
}
diff --git a/drivers/filesystems/fastfat/fat.c b/drivers/filesystems/fastfat/fat.c
index 8d4ecd9cde..591e60b4fd 100644
--- a/drivers/filesystems/fastfat/fat.c
+++ b/drivers/filesystems/fastfat/fat.c
@@ -20,12 +20,6 @@
#define CACHEPAGESIZE(pDeviceExt) ((pDeviceExt)->FatInfo.BytesPerCluster > PAGE_SIZE ? \
(pDeviceExt)->FatInfo.BytesPerCluster : PAGE_SIZE)
-/* FIXME: because volume is not cached, we have to perform direct IOs
- * The day this is fixed, just comment out that line, and check
- * it still works (and delete old code ;-))
- */
-#define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
-
/* FUNCTIONS ****************************************************************/
/*
diff --git a/drivers/filesystems/fastfat/fcb.c b/drivers/filesystems/fastfat/fcb.c
index ed85ab277c..a791c27a40 100644
--- a/drivers/filesystems/fastfat/fcb.c
+++ b/drivers/filesystems/fastfat/fcb.c
@@ -277,6 +277,7 @@ vfatDestroyFCB(
#endif
FsRtlUninitializeFileLock(&pFCB->FileLock);
+
if (!vfatFCBIsRoot(pFCB) &&
!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT) && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME))
{
@@ -317,11 +318,15 @@ _vfatGrabFCB(
{
DPRINT1("Inc ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func);
}
+#else
+ DPRINT("Grabbing FCB at %p: %wZ, refCount:%d\n",
+ pFCB, &pFCB->PathNameU, pFCB->RefCount);
#endif
ASSERT(ExIsResourceAcquiredExclusive(&pVCB->DirResource));
- ASSERT(pFCB != pVCB->VolumeFcb);
+ ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT));
+ ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
ASSERT(pFCB->RefCount > 0);
++pFCB->RefCount;
}
@@ -350,7 +355,7 @@ _vfatReleaseFCB(
DPRINT1("Dec ref count (%d, oc: %d) for: %p (%wZ) at: %s(%d) %s\n", pFCB->RefCount, pFCB->OpenHandleCount, pFCB, &pFCB->PathNameU, File, Line, Func);
}
#else
- DPRINT("releasing FCB at %p: %wZ, refCount:%d\n",
+ DPRINT("Releasing FCB at %p: %wZ, refCount:%d\n",
pFCB, &pFCB->PathNameU, pFCB->RefCount);
#endif
@@ -360,7 +365,8 @@ _vfatReleaseFCB(
{
ULONG RefCount;
- ASSERT(pFCB != pVCB->VolumeFcb);
+ ASSERT(!BooleanFlagOn(pFCB->Flags, FCB_IS_FAT));
+ ASSERT(pFCB != pVCB->VolumeFcb && !BooleanFlagOn(pFCB->Flags, FCB_IS_VOLUME));
ASSERT(pFCB->RefCount > 0);
RefCount = --pFCB->RefCount;
@@ -647,6 +653,8 @@ vfatMakeRootFCB(
NTSTATUS Status = STATUS_SUCCESS;
UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\");
+ ASSERT(pVCB->RootFcb == NULL);
+
FCB = vfatNewFCB(pVCB, &NameU);
if (vfatVolumeIsFatX(pVCB))
{
@@ -690,6 +698,9 @@ vfatMakeRootFCB(
vfatFCBInitializeCacheFromVolume(pVCB, FCB);
vfatAddFCBToTable(pVCB, FCB);
+ /* Cache it */
+ pVCB->RootFcb = FCB;
+
return FCB;
}
@@ -705,6 +716,7 @@ vfatOpenRootFCB(
{
FCB = vfatMakeRootFCB(pVCB);
}
+ ASSERT(FCB == pVCB->RootFcb);
return FCB;
}
@@ -747,8 +759,6 @@ vfatAttachFCBToFileObject(
{
PVFATCCB newCCB;
- UNREFERENCED_PARAMETER(vcb);
-
#ifdef KDBG
if (DebugFile.Buffer != NULL && FsRtlIsNameInExpression(&DebugFile, &fcb->LongNameU, FALSE, NULL))
{
diff --git a/drivers/filesystems/fastfat/flush.c b/drivers/filesystems/fastfat/flush.c
index 22a8c6d08f..2861998420 100644
--- a/drivers/filesystems/fastfat/flush.c
+++ b/drivers/filesystems/fastfat/flush.c
@@ -59,7 +59,9 @@ VfatFlushVolume(
KEVENT Event;
IO_STATUS_BLOCK IoStatusBlock;
- DPRINT("VfatFlushVolume(DeviceExt %p, FatFcb %p)\n", DeviceExt, VolumeFcb);
+ DPRINT("VfatFlushVolume(DeviceExt %p, VolumeFcb %p)\n", DeviceExt, VolumeFcb);
+
+ ASSERT(VolumeFcb == DeviceExt->VolumeFcb);
ListEntry = DeviceExt->FcbListHead.Flink;
while (ListEntry != &DeviceExt->FcbListHead)
diff --git a/drivers/filesystems/fastfat/fsctl.c b/drivers/filesystems/fastfat/fsctl.c
index 6523487368..d8394e46a7 100644
--- a/drivers/filesystems/fastfat/fsctl.c
+++ b/drivers/filesystems/fastfat/fsctl.c
@@ -531,7 +531,6 @@ VfatMount(
NTSTATUS Status;
PVFATFCB Fcb = NULL;
PVFATFCB VolumeFcb = NULL;
- PVFATCCB Ccb = NULL;
PDEVICE_OBJECT DeviceToMount;
PVPB Vpb;
UNICODE_STRING NameU = RTL_CONSTANT_STRING(L"\\$$Fat$$");
@@ -706,23 +705,14 @@ VfatMount(
goto ByeBye;
}
- Ccb = ExAllocateFromNPagedLookasideList(&VfatGlobalData->CcbLookasideList);
- if (Ccb == NULL)
- {
- Status = STATUS_INSUFFICIENT_RESOURCES;
+ Status = vfatAttachFCBToFileObject(DeviceExt, Fcb, DeviceExt->FATFileObject);
+ if (!NT_SUCCESS(Status))
goto ByeBye;
- }
- RtlZeroMemory(Ccb, sizeof (VFATCCB));
- DeviceExt->FATFileObject->FsContext = Fcb;
- DeviceExt->FATFileObject->FsContext2 = Ccb;
- DeviceExt->FATFileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
DeviceExt->FATFileObject->PrivateCacheMap = NULL;
- DeviceExt->FATFileObject->Vpb = DeviceObject->Vpb;
Fcb->FileObject = DeviceExt->FATFileObject;
- Fcb->Flags |= FCB_IS_FAT;
-
+ Fcb->Flags = FCB_IS_FAT;
Fcb->RFCB.FileSize.QuadPart = DeviceExt->FatInfo.FATSectors * DeviceExt->FatInfo.BytesPerSector;
Fcb->RFCB.ValidDataLength = Fcb->RFCB.FileSize;
Fcb->RFCB.AllocationSize = Fcb->RFCB.FileSize;
@@ -798,9 +788,15 @@ VfatMount(
SetFlag(DeviceExt->Flags, VCB_IS_SYS_OR_HAS_PAGE);
}
- FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT);
- FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
+ /* Initialize the notify list and synchronization object */
InitializeListHead(&DeviceExt->NotifyList);
+ FsRtlNotifyInitializeSync(&DeviceExt->NotifySync);
+
+ /* The VCB is OK for usage */
+ SetFlag(DeviceExt->Flags, VCB_GOOD);
+
+ /* Send the mount notification */
+ FsRtlNotifyVolumeEvent(DeviceExt->FATFileObject, FSRTL_VOLUME_MOUNT);
DPRINT("Mount success\n");
@@ -811,15 +807,24 @@ ByeBye:
{
/* Cleanup */
if (DeviceExt && DeviceExt->FATFileObject)
- ObDereferenceObject (DeviceExt->FATFileObject);
+ {
+ LARGE_INTEGER Zero = {{0,0}};
+ PVFATCCB Ccb = (PVFATCCB)DeviceExt->FATFileObject->FsContext2;
+
+ CcUninitializeCacheMap(DeviceExt->FATFileObject,
+ &Zero,
+ NULL);
+ ObDereferenceObject(DeviceExt->FATFileObject);
+ if (Ccb)
+ vfatDestroyCCB(Ccb);
+ DeviceExt->FATFileObject = NULL;
+ }
+ if (Fcb)
+ vfatDestroyFCB(Fcb);
if (DeviceExt && DeviceExt->SpareVPB)
ExFreePoolWithTag(DeviceExt->SpareVPB, TAG_VPB);
if (DeviceExt && DeviceExt->Statistics)
ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS);
- if (Fcb)
- vfatDestroyFCB(Fcb);
- if (Ccb)
- vfatDestroyCCB(Ccb);
if (DeviceObject)
IoDeleteDevice(DeviceObject);
}
@@ -1125,6 +1130,11 @@ VfatLockOrUnlockVolume(
return STATUS_ACCESS_DENIED;
}
+ if (Lock)
+ {
+ FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_LOCK);
+ }
+
/* Deny locking if we're not alone */
if (Lock && DeviceExt->OpenHandleCount != 1)
{
@@ -1208,6 +1218,8 @@ VfatLockOrUnlockVolume(
}
}
+ FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_LOCK_FAILED);
+
return STATUS_ACCESS_DENIED;
#if 1
@@ -1225,6 +1237,18 @@ VfatLockOrUnlockVolume(
/* Finally, proceed */
if (Lock)
{
+ /* Flush volume & files */
+ VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
+
+ /* The volume is now clean */
+ if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) &&
+ BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY))
+ {
+ /* Drop the dirty bit */
+ if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE)))
+ ClearFlag(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY);
+ }
+
DeviceExt->Flags |= VCB_VOLUME_LOCKED;
Vpb->Flags |= VPB_LOCKED;
}
@@ -1232,6 +1256,8 @@ VfatLockOrUnlockVolume(
{
DeviceExt->Flags &= ~VCB_VOLUME_LOCKED;
Vpb->Flags &= ~VPB_LOCKED;
+
+ FsRtlNotifyVolumeEvent(IrpContext->Stack->FileObject, FSRTL_VOLUME_UNLOCK);
}
return STATUS_SUCCESS;
@@ -1277,25 +1303,35 @@ VfatDismountVolume(
ExAcquireResourceExclusiveLite(&DeviceExt->FatResource, TRUE);
- /* We're performing a clean shutdown */
- if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY))
+ /* Flush volume & files */
+ VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext);
+
+ /* The volume is now clean */
+ if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) &&
+ BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY))
{
/* Drop the dirty bit */
if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE)))
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
}
- /* Flush volume & files */
- VfatFlushVolume(DeviceExt, (PVFATFCB)FileObject->FsContext);
-
/* Rebrowse the FCB in order to free them now */
while (!IsListEmpty(&DeviceExt->FcbListHead))
{
NextEntry = RemoveTailList(&DeviceExt->FcbListHead);
Fcb = CONTAINING_RECORD(NextEntry, VFATFCB, FcbListEntry);
+
+ if (Fcb == DeviceExt->RootFcb)
+ DeviceExt->RootFcb = NULL;
+ else if (Fcb == DeviceExt->VolumeFcb)
+ DeviceExt->VolumeFcb = NULL;
+
vfatDestroyFCB(Fcb);
}
+ /* We are uninitializing, the VCB cannot be used anymore */
+ ClearFlag(DeviceExt->Flags, VCB_GOOD);
+
/* Mark we're being dismounted */
DeviceExt->Flags |= VCB_DISMOUNT_PENDING;
#ifndef ENABLE_SWAPOUT
@@ -1304,12 +1340,6 @@ VfatDismountVolume(
ExReleaseResourceLite(&DeviceExt->FatResource);
- /* Release a few resources and quit, we're done */
- ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS);
- ExDeleteResourceLite(&DeviceExt->DirResource);
- ExDeleteResourceLite(&DeviceExt->FatResource);
- ObDereferenceObject(DeviceExt->FATFileObject);
-
return STATUS_SUCCESS;
}
diff --git a/drivers/filesystems/fastfat/misc.c b/drivers/filesystems/fastfat/misc.c
index ad5f4bcec3..2068e8b5e4 100644
--- a/drivers/filesystems/fastfat/misc.c
+++ b/drivers/filesystems/fastfat/misc.c
@@ -416,23 +416,43 @@ VfatLockUserBuffer(
BOOLEAN
VfatCheckForDismount(
IN PDEVICE_EXTENSION DeviceExt,
- IN BOOLEAN Create)
+ IN BOOLEAN Force)
{
KIRQL OldIrql;
+ ULONG UnCleanCount;
PVPB Vpb;
BOOLEAN Delete;
- DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Create);
+ DPRINT1("VfatCheckForDismount(%p, %u)\n", DeviceExt, Force);
+
+ /* If the VCB is OK (not under uninitialization) and we don't force dismount, do nothing */
+ if (BooleanFlagOn(DeviceExt->Flags, VCB_GOOD) && !Force)
+ {
+ return FALSE;
+ }
+
+ /*
+ * NOTE: In their *CheckForDismount() function, our 3rd-party FS drivers
+ * as well as MS' fastfat, perform a comparison check of the current VCB's
+ * VPB ReferenceCount with some sort of "dangling"/"residual" open count,
+ * depending on whether or not we are in IRP_MJ_CREATE.
+ * It seems to be related to the fact that the volume root directory as
+ * well as auxiliary data stream(s) are still opened, and only these are
+ * allowed to be opened at that moment. After analysis it appears that for
+ * the ReactOS' fastfat, this number is equal to "3".
+ */
+ UnCleanCount = 3;
/* Lock VPB */
IoAcquireVpbSpinLock(&OldIrql);
/* Reference it and check if a create is being done */
Vpb = DeviceExt->IoVPB;
- if (Vpb->ReferenceCount != Create)
+ DPRINT("Vpb->ReferenceCount = %d\n", Vpb->ReferenceCount);
+ if (Vpb->ReferenceCount != UnCleanCount || DeviceExt->OpenHandleCount != 0)
{
- /* Copy the VPB to our local own to prepare later dismount */
- if (DeviceExt->SpareVPB != NULL)
+ /* If we force-unmount, copy the VPB to our local own to prepare later dismount */
+ if (Force && Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
{
RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
@@ -443,9 +463,12 @@ VfatCheckForDismount(
DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
DeviceExt->SpareVPB = NULL;
DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
+
+ /* We are uninitializing, the VCB cannot be used anymore */
+ ClearFlag(DeviceExt->Flags, VCB_GOOD);
}
- /* Don't do anything */
+ /* Don't do anything for now */
Delete = FALSE;
}
else
@@ -453,12 +476,30 @@ VfatCheckForDismount(
/* Otherwise, delete the volume */
Delete = TRUE;
- /* Check if it has a VPB and unmount it */
- if (Vpb->RealDevice->Vpb == Vpb)
+ /* Swap the VPB with our local own */
+ if (Vpb->RealDevice->Vpb == Vpb && DeviceExt->SpareVPB != NULL)
{
- Vpb->DeviceObject = NULL;
- Vpb->Flags &= ~VPB_MOUNTED;
+ RtlZeroMemory(DeviceExt->SpareVPB, sizeof(VPB));
+ DeviceExt->SpareVPB->Type = IO_TYPE_VPB;
+ DeviceExt->SpareVPB->Size = sizeof(VPB);
+ DeviceExt->SpareVPB->RealDevice = DeviceExt->IoVPB->RealDevice;
+ DeviceExt->SpareVPB->DeviceObject = NULL;
+ DeviceExt->SpareVPB->Flags = DeviceExt->IoVPB->Flags & VPB_REMOVE_PENDING;
+ DeviceExt->IoVPB->RealDevice->Vpb = DeviceExt->SpareVPB;
+ DeviceExt->SpareVPB = NULL;
+ DeviceExt->IoVPB->Flags |= VPB_PERSISTENT;
+
+ /* We are uninitializing, the VCB cannot be used anymore */
+ ClearFlag(DeviceExt->Flags, VCB_GOOD);
}
+
+ /*
+ * We defer setting the VPB's DeviceObject to NULL for later because
+ * we want to handle the closing of the internal opened meta-files.
+ */
+
+ /* Clear the mounted and locked flags in the VPB */
+ ClearFlag(Vpb->Flags, VPB_MOUNTED | VPB_LOCKED);
}
/* Release lock and return status */
@@ -467,34 +508,82 @@ VfatCheckForDismount(
/* If we were to delete, delete volume */
if (Delete)
{
- PVPB DelVpb;
+ LARGE_INTEGER Zero = {{0,0}};
+ PVFATFCB Fcb;
+
+ /* We are uninitializing, the VCB cannot be used anymore */
+ ClearFlag(DeviceExt->Flags, VCB_GOOD);
+
+ /* Invalidate and close the internal opened meta-files */
+ if (DeviceExt->RootFcb)
+ {
+ Fcb = DeviceExt->RootFcb;
+ CcUninitializeCacheMap(Fcb->FileObject,
+ &Zero,
+ NULL);
+ ObDereferenceObject(Fcb->FileObject);
+ DeviceExt->RootFcb = NULL;
+ vfatDestroyFCB(Fcb);
+ }
+ if (DeviceExt->VolumeFcb)
+ {
+ Fcb = DeviceExt->VolumeFcb;
+#ifndef VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+ CcUninitializeCacheMap(Fcb->FileObject,
+ &Zero,
+ NULL);
+ ObDereferenceObject(Fcb->FileObject);
+#endif
+ DeviceExt->VolumeFcb = NULL;
+ vfatDestroyFCB(Fcb);
+ }
+ if (DeviceExt->FATFileObject)
+ {
+ Fcb = (PVFATFCB)DeviceExt->FATFileObject->FsContext;
+ CcUninitializeCacheMap(DeviceExt->FATFileObject,
+ &Zero,
+ NULL);
+ ObDereferenceObject(DeviceExt->FATFileObject);
+ DeviceExt->FATFileObject->FsContext = NULL;
+ DeviceExt->FATFileObject = NULL;
+ vfatDestroyFCB(Fcb);
+ }
+
+ /*
+ * Now that the closing of the internal opened meta-files has been
+ * handled, we can now set the VPB's DeviceObject to NULL.
+ */
+ Vpb->DeviceObject = NULL;
/* If we have a local VPB, we'll have to delete it
* but we won't dismount us - something went bad before
*/
if (DeviceExt->SpareVPB)
{
- DelVpb = DeviceExt->SpareVPB;
+ ExFreePool(DeviceExt->SpareVPB);
}
- /* Otherwise, dismount our device if possible */
- else
+ /* Otherwise, delete any of the available VPB if its reference count is zero */
+ else if (DeviceExt->IoVPB->ReferenceCount == 0)
{
- if (DeviceExt->IoVPB->ReferenceCount)
- {
- ObfDereferenceObject(DeviceExt->StorageDevice);
- IoDeleteDevice(DeviceExt->VolumeDevice);
- return Delete;
- }
-
- DelVpb = DeviceExt->IoVPB;
+ ExFreePool(DeviceExt->IoVPB);
}
- /* Delete any of the available VPB and dismount */
- ExFreePool(DelVpb);
+ /* Remove the volume from the list */
+ ExAcquireResourceExclusiveLite(&VfatGlobalData->VolumeListLock, TRUE);
+ RemoveEntryList(&DeviceExt->VolumeListEntry);
+ ExReleaseResourceLite(&VfatGlobalData->VolumeListLock);
+
+ /* Uninitialize the notify synchronization object */
+ FsRtlNotifyUninitializeSync(&DeviceExt->NotifySync);
+
+ /* Release resources */
+ ExFreePoolWithTag(DeviceExt->Statistics, TAG_STATS);
+ ExDeleteResourceLite(&DeviceExt->DirResource);
+ ExDeleteResourceLite(&DeviceExt->FatResource);
+
+ /* Dismount our device if possible */
ObfDereferenceObject(DeviceExt->StorageDevice);
IoDeleteDevice(DeviceExt->VolumeDevice);
-
- return Delete;
}
return Delete;
diff --git a/drivers/filesystems/fastfat/shutdown.c b/drivers/filesystems/fastfat/shutdown.c
index c9e2bd5431..8e36745335 100644
--- a/drivers/filesystems/fastfat/shutdown.c
+++ b/drivers/filesystems/fastfat/shutdown.c
@@ -74,15 +74,19 @@ VfatShutdown(
ListEntry = ListEntry->Flink;
ExAcquireResourceExclusiveLite(&DeviceExt->DirResource, TRUE);
- /* It was a clean volume mounted */
- if (DeviceExt->VolumeFcb->Flags & VCB_CLEAR_DIRTY)
+
+ /* Flush volume & files */
+ Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
+
+ /* We're performing a clean shutdown */
+ if (BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_CLEAR_DIRTY) &&
+ BooleanFlagOn(DeviceExt->VolumeFcb->Flags, VCB_IS_DIRTY))
{
- /* So, drop the dirty bit we set */
+ /* Drop the dirty bit */
if (NT_SUCCESS(SetDirtyStatus(DeviceExt, FALSE)))
DeviceExt->VolumeFcb->Flags &= ~VCB_IS_DIRTY;
}
- Status = VfatFlushVolume(DeviceExt, DeviceExt->VolumeFcb);
if (NT_SUCCESS(Status))
{
Status = VfatDiskShutDown(DeviceExt);
@@ -97,7 +101,10 @@ VfatShutdown(
}
ExReleaseResourceLite(&DeviceExt->DirResource);
- /* FIXME: Unmount the logical volume */
+ /* Unmount the logical volume */
+#ifdef ENABLE_SWAPOUT
+ VfatCheckForDismount(DeviceExt, FALSE);
+#endif
if (!NT_SUCCESS(Status))
Irp->IoStatus.Status = Status;
diff --git a/drivers/filesystems/fastfat/vfat.h b/drivers/filesystems/fastfat/vfat.h
index e6c7c73e1d..77b2998dad 100644
--- a/drivers/filesystems/fastfat/vfat.h
+++ b/drivers/filesystems/fastfat/vfat.h
@@ -16,12 +16,16 @@
#define INIT_SECTION /* Done via alloc_text for MSC */
#endif
+
#define USE_ROS_CC_AND_FS
-#if 0
-#ifndef _MSC_VER
#define ENABLE_SWAPOUT
-#endif
-#endif
+
+/* FIXME: because volume is not cached, we have to perform direct IOs
+ * The day this is fixed, just comment out that line, and check
+ * it still works (and delete old code ;-))
+ */
+#define VOLUME_IS_NOT_CACHED_WORK_AROUND_IT
+
#define ROUND_DOWN(n, align) \
(((ULONG)n) & ~((align) - 1l))
@@ -244,6 +248,8 @@ typedef union _DIR_ENTRY DIR_ENTRY, *PDIR_ENTRY;
#define VCB_IS_SYS_OR_HAS_PAGE 0x0008
#define VCB_IS_DIRTY 0x4000 /* Volume is dirty */
#define VCB_CLEAR_DIRTY 0x8000 /* Clean dirty flag at shutdown */
+/* VCB condition state */
+#define VCB_GOOD 0x0010 /* If not set, the VCB is improper for usage */
typedef struct
{
@@ -326,6 +332,7 @@ typedef struct DEVICE_EXTENSION
BOOLEAN AvailableClustersValid;
ULONG Flags;
struct _VFATFCB *VolumeFcb;
+ struct _VFATFCB *RootFcb;
PSTATISTICS Statistics;
/* Pointers to functions for manipulating FAT. */