Windows: VolumeInfoReadOnlyFlag registry option
authorJeffrey Altman <jaltman@your-file-system.com>
Thu, 14 Mar 2013 17:05:28 +0000 (13:05 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Sat, 16 Mar 2013 22:08:25 +0000 (15:08 -0700)
Windows 7 Explorer Shell has a bug when processing drive letters
mapped to UNC paths whose target volume information specifies the
FILE_READ_ONLY_VOLUME flag.  When set, not only is the .readonly
volume treated as read only but all volumes that can be accessed via the
drive letter.   This bug is fixed in Windows 8.

Add a registry configuration option to permit configuration of the
behavior.  Sites that do not use drive letter mappings will want to
enable it even on Windows 7 because it permits the Explorer Shell
to disable the "Delete" and "Rename" options and others when the current
directory is read only.

The default is disabled on Win7 and below; enabled on Win8 and above.

Change-Id: I73bbaf7d40918650b1a217ed44409c0679920536
Reviewed-on: http://gerrit.openafs.org/9606
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>
Tested-by: Jeffrey Altman <jaltman@your-file-system.com>

doc/xml/ReleaseNotesWindows/relnotes.xml
src/WINNT/afsd/afsd.h
src/WINNT/afsd/afsd_init.c
src/WINNT/afsrdr/user/RDRFunction.c

index eda6e55..cdaf472 100644 (file)
@@ -4326,6 +4326,31 @@ Default: 0</para>
           <para>0: use the older I/O processing mechanism.</para>
           <para>1: use the new Direct I/O processing mechanism.</para>
         </section>
+        <section>
+          <title id="Regkey_TransarcAFSDaemon_Parameters_VolumeInfoReadOnlyFlag">Value: VolumeInfoReadOnlyFlag</title>
+          <indexterm significance="normal">
+            <primary>VolumeInfoReadOnlyFlag</primary>
+          </indexterm>
+          <para>Regkey: [HKLM\SYSTEM\CurrentControlSet\Services\TransarcAFSDaemon\Parameters]</para>
+          <para>Type: DWORD {0, 1}
+          </para>
+          <para>
+            Default: 1</para>
+          <para>The Win32 GetVolumeInformation and GetVolumeInformationByHandle APIs permit
+            applications to query volume attributes such as Case Preserving, Case Insensitive
+            lookups, support for hard links, support for reparse points, support for Unicode and
+            whether or not the volume is read only.  The FILE_READ_ONLY_VOLUME flag when set permits
+            applications such as the Explorer Shell to disable the "Delete" and "Rename" options and
+            prevent copying files into the volume without issuing the request to the file system.
+            Unfortunately, the Windows 7 explorer shell has a bug when a drive letter is mapped to a
+            UNC path.  If the mapped path refers to a read only volume, then all volumes accessible
+            via the drive letter are also treated as read only.  This bug is fixed in Windows 8 and
+            Server 2012.  To improve application compatibility the setting of the
+            FILE_READ_ONLY_VOLUME flag is disabled by default on Windows 7 and below and enabled on
+            Windows 8 and above.</para>
+          <para>0: prevent setting the FILE_READ_ONLY_VOLUME flag. (default on Win7 and below).</para>
+          <para>1: permit setting the FILE_READ_ONLY_VOLUME flag. (default on Win8 and above)</para>
+        </section>
       </section>
       <section>
         <title id="Regkey_TransarcAFSDaemon_Parameters_GlobalAutoMapper">Regkey:
index f583124..5705a04 100644 (file)
@@ -118,6 +118,7 @@ extern int cm_dnsEnabled;
 extern int cm_readonlyVolumeVersioning;
 extern int cm_shortNames;
 extern int cm_directIO;
+extern int cm_volumeInfoReadOnlyFlag;
 
 extern long rx_mtu;
 
index c966486..3de99f4 100644 (file)
@@ -79,6 +79,7 @@ int cm_virtualCache = 0;
 afs_int32 cm_verifyData = 0;
 int cm_shortNames = 1;
 int cm_directIO = 1;
+int cm_volumeInfoReadOnlyFlag = 0;
 
 int smb_UseV3 = 1;
 afs_uint32 smb_Enabled = 1;
@@ -1388,6 +1389,22 @@ afsd_InitCM(char **reasonP)
     afsi_log("CM ShortNames is %u", cm_shortNames);
 
     dummyLen = sizeof(DWORD);
+    code = RegQueryValueEx(parmKey, "VolumeInfoReadOnlyFlag", NULL, NULL,
+                           (BYTE *) &dwValue, &dummyLen);
+    if (code == ERROR_SUCCESS) {
+        cm_volumeInfoReadOnlyFlag = (unsigned short) dwValue;
+    } else {
+        /* enable by default on Win 8 and Server 2012 */
+        if (osVersion.dwMajorVersion > 6 ||
+            osVersion.dwMajorVersion == 6 &&
+            osVersion.dwMinorVersion >= 2)
+            cm_volumeInfoReadOnlyFlag = 1;
+        else
+            cm_volumeInfoReadOnlyFlag = 0;
+    }
+    afsi_log("CM VolumeInfoReadOnlyFlag is %u", cm_volumeInfoReadOnlyFlag);
+
+    dummyLen = sizeof(DWORD);
     code = RegQueryValueEx(parmKey, "DirectIO", NULL, NULL,
                            (BYTE *) &dwValue, &dummyLen);
     if (code == ERROR_SUCCESS) {
index 95856df..cb678bb 100644 (file)
@@ -5834,7 +5834,8 @@ RDR_GetVolumeInfo( IN cm_user_t     *userp,
         memcpy(&pResultCB->VolumeCreationTime, &ft, sizeof(ft));
 
         pResultCB->AvailableAllocationUnits.QuadPart = 0;
-        pResultCB->FileSystemAttributes |= FILE_READ_ONLY_VOLUME;
+        if (cm_volumeInfoReadOnlyFlag)
+            pResultCB->FileSystemAttributes |= FILE_READ_ONLY_VOLUME;
 
         pResultCB->VolumeLabelLength = cm_Utf8ToUtf16( "Freelance.Local.Root", -1, pResultCB->VolumeLabel,
                                                        (sizeof(pResultCB->VolumeLabel) / sizeof(WCHAR)) + 1);
@@ -5853,7 +5854,7 @@ RDR_GetVolumeInfo( IN cm_user_t     *userp,
         }
         volType = cm_VolumeType(volp, scp->fid.volume);
 
-        if (volType == ROVOL || volType == BACKVOL)
+        if (cm_volumeInfoReadOnlyFlag && (volType == ROVOL || volType == BACKVOL))
             pResultCB->FileSystemAttributes |= FILE_READ_ONLY_VOLUME;
 
         flags = CM_SCACHESYNC_NEEDCALLBACK | CM_SCACHESYNC_GETSTATUS;