Windows10文件夹进「自定义」属性页后,_wstat64检测权限异常
Windows 10文件夹自定义操作后
_wstat64权限检测异常问题 问题背景
在Windows 10系统中,进入文件夹属性的「自定义」选项卡并确认后,通过_wstat64检测到文件夹权限标记发生变化,但实际ACL(访问控制列表)并未改变。
重现步骤
- 创建一个新的空文件夹,例如
D:\folder_name; - 使用cl.exe编译测试程序:
cl.exe stat_test.cxx; - 运行编译后的程序:
stat_test.exe D:\folder_name,输出为:
path D:\folder_name, st.st_mode & S_IWRITE = 128
- 右键点击
D:\folder_name,选择「属性」,进入「自定义」选项卡后直接点击「确定」; - 再次运行程序:
stat_test.exe D:\folder_name,输出变为:
path D:\folder_name, st.st_mode & S_IWRITE = 0
现象说明
- 操作前后文件夹的ACL完全一致,但文件夹内生成了
desktop.ini文件; - 无法通过常规Windows操作恢复原检测状态,仅能在msys64中执行
chmod 777 "D:\folder_name"命令恢复; - 使用C++17文件库测试也得到相同结果。
疑问
- 请解释Windows此行为的原因;
- 如何避免该问题;
- 仅使用Windows工具如何恢复原状态?
测试代码
//compile with cl.exe stat_test.cxx #include <string> #include <windows.h> int main(int argc, char** argv) { std::string path = std::string(argv[1]); //get wide string size of path size_t requiredSize = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, NULL, 0); //initialize wide string to zero std::wstring wide(requiredSize, '\0'); //convert path to wide string MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, &wide[0], wide.size()); //get stat status struct _stat64 st; _wstat64(wide.c_str(), &st); //check if writable int flag = st.st_mode & S_IWRITE; printf("path %s, st.st_mode & S_IWRITE = %d\n", argv[1], flag); return 0; }
解答
1. 行为原因
_wstat64是Windows为兼容类Unix代码实现的接口,它返回的st_mode并非直接映射Windows的ACL,而是结合文件属性、NTFS权限及特殊标记做的语义转换。
当进入「自定义」选项卡确认后,系统会生成desktop.ini并给文件夹标记「自定义目录」属性。此时_wstat64会模拟Unix的只读权限语义,清除st_mode中的可写位,但这只是兼容层的逻辑转换——实际Windows ACL并未改变,你仍然具备文件夹的写入权限,只是兼容接口给出了不符合真实权限的结果。
2. 避免方法
- 无需求时不要进入「自定义」选项卡后直接确认;
- 放弃使用
_wstat64这类兼容接口,改用Windows原生API(如GetNamedSecurityInfo、AccessCheck)直接检测ACL和实际访问权限,这能准确反映Windows的真实权限状态; - 若必须使用
_wstat64,可先检查文件夹内是否存在系统生成的desktop.ini,再结合原生权限检测结果修正判断。
3. 纯Windows工具恢复方法
方式一:图形界面操作
- 打开文件夹选项,勾选「显示隐藏的文件、文件夹和驱动器」,取消勾选「隐藏受保护的操作系统文件」;
- 删除文件夹内的
desktop.ini文件; - 右键文件夹→「属性」,取消「只读」属性,点击「应用」,在弹出对话框中选择「将更改应用于此文件夹、子文件夹和文件」,确认后即可恢复。
方式二:命令行操作
打开命令提示符(CMD),执行以下命令:
:: 删除隐藏的desktop.ini del /f /a:h "D:\folder_name\desktop.ini" :: 移除文件夹的只读属性 attrib -r "D:\folder_name" /d /s
内容的提问来源于stack exchange,提问作者schorsch312
相关产品推荐
相关产品推荐

