用Win32 API设置windows XP中FAT32文件夹共享的读写权限
2012-06-15 11:17
197 查看
首先是将文件夹设为共享的代码:
//Set a folder for net share
NET_API_STATUS AddNetShare(LPSTR sharedFolderPath, LPSTR shareName)
{
DWORD level = 2;
SHARE_INFO_2 si;
DWORD parmErr = 0;
si.shi2_netname = shareName; //share name
si.shi2_type = STYPE_DISKTREE;
si.shi2_remark = (LPSTR)L"This
is a shared folder."; //remark for the shared folder
si.shi2_path = sharedFolderPath; //path of the shared folder
si.shi2_permissions = ACCESS_ALL; //this parameter doesn't work
acctually
si.shi2_passwd = NULL; //no password need
si.shi2_max_uses = -1; //unlimited connected
si.shi2_current_uses = 0;
NET_API_STATUS res = NetShareAdd(NULL, level, (LPBYTE)&si, &parmErr);
return res;
}
注意,在上篇中谈到过,SHARE_INFO_2中的shi2_permissions对于Windows XP无效,你可以设为任意值,但对文件夹的共享读写权限不起作用。
如果只调用上面的函数将文件夹设为共享,则默认情况下,网络用户拥有全部读写权限,但很多时候我们不希望网络用户修改共享文件的内容,这样就必须编程将共享权限设置为只读,下面就是设置共享权限的代码:
enum NetShareAccessPermission
{
NetShareReadOnly = 0x001200a9, //readonly permission
NetShareFullControl = 0x001f01ff //full control permission
};
//Set access permission for net shared folder
DWORD SetNetsharePermission(LPTSTR shareName, NetShareAccessPermission permission)
{
DWORD res = 0;
PACL pOldDacl = NULL, pNewDacl = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
res = GetNamedSecurityInfo(shareName,
SE_LMSHARE,
DACL_SECURITY_INFORMATION ,
NULL,
NULL,
&pOldDacl,
NULL,
&pSD);
if (res != ERROR_SUCCESS)
{
goto Cleanup;
}
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = permission; //Set access permission (defined in enum NetShareAccessPermission)
ea.grfAccessMode = SET_ACCESS ;
ea.grfInheritance= CONTAINER_INHERIT_ACE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.ptstrName = L"Everyone";
res = SetEntriesInAcl(1, &ea, pOldDacl, &pNewDacl);
if (res != ERROR_SUCCESS)
{
goto Cleanup;
}
res = SetNamedSecurityInfo(shareName,
SE_LMSHARE,
DACL_SECURITY_INFORMATION ,
NULL,
NULL,
pNewDacl,
NULL);
Cleanup: //Release resource
if (pSD != NULL)
{
LocalFree((HLOCAL) pSD);
}
if (pNewDacl != NULL)
{
LocalFree((HLOCAL) pNewDacl);
}
return res;
}
这段代码最关键的语句是:
ea.grfAccessPermissions = permission;
其中的permission参数是一个自定义的NetShareAccessPermission枚举,如果permission==NetShareReadOnly(即0x001200a9),这样就可以将共享文件夹设为只读了。
但问题的关键是为什么要自己定义一个这样的枚举?0x001200a9和0x001f01ff这两个密码一般的十六进制数是哪里来的?难道MSDN中没有定义一个这样的枚举或宏吗?
实际上,MSDN中的确存在几个预定义的可以为ea.grfAccessPermissions 赋值的宏,上面那两个十六进制数是一个与设置文件系统安全性有关的DWORD开关变量,名为ACCESS_MASK,具体定义可以参考MSDN。win32 API函数的头文件中已经定义了几个可以为这个参数赋值的宏,如GENERIC_READ,KEY_READ等,不过这两个宏在MSDN中也是语焉不详(还是我这个菜鸟实在菜到家了,人家明明说的清清楚楚,就你一个睁眼瞎……),但你可以在VS中输入这两个宏,然后选中后右键转入定义这两个东东的头文件,在头文件有少量的解释。在这个头文件中我们还可以看到更多的预定义的宏。
不幸的是,我没有找到我要的宏,KEY_READ是用来设置注册表只读权限的,GENERIC_READ,呃,我也不知道是用来设置什么的,只知道这两个宏对我的共享权限设置除了引发一些怪异的行为外,没什么帮助。
这样只能靠自己手动的设置那个恐怖的32位的开关变量了。对于一个32位的二进制数,一共有4G种组合,假设我试一种组合要花30s,将吃饭睡觉上XX的时间都搭上,一天24小时,算一下,呃,我要花3800年才试的完……
不过,我可以考虑将这项光荣的任务交给我未来的儿子,然后来个递归,利用“子又有子,子又有孙,子子孙孙无穷匮也,而const不可增”……
不过好在我思维还算缜密,我考虑到无法保证我会有儿子,这样我的递归很可能由于条件不满足产生异常而终止……
我一向不打无把握的仗,想到了一种投机取巧的办法:我可以先通过Windows的UI设置共享文件夹的权限,然后编程获取相关的变量和结构体的值,将这些值保存下来,先不管这些值看得懂看不懂(事实上,不太可能看得懂,又是一些32位的开关量,又是一些3800年),给我们的代码赋值就行了。
我没找到直接获取ACCESS_MASK的API,于是想办法通过VS的调试功能来获取,下面是我用来获取ACCESS_MASK的代码:
//Get the value of access mask
void GetAceTest()
{
DWORD res = 0;
PACL pOldDacl = NULL, pNewDacl = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
ACCESS_ALLOWED_ACE* pAce;
LPTSTR shareName=(LPTSTR)L"TestShareFolder";
res = GetNamedSecurityInfo(shareName,
SE_LMSHARE,
DACL_SECURITY_INFORMATION ,
NULL,
NULL,
&pOldDacl,
NULL,
&pSD);
GetAce(pOldDacl,0,(LPVOID*)&pAce);
ACCESS_MASK Mask=pAce->Mask;
return;
}
ACCESS_MASK是和ACE直接关联的,至于ACE么,呃,说来话长,还是看MSDN吧。
但要注意的是GetAce()的第二个参数要设为0,因为ACEs是从0开始索引的,如果不小心设为1了,你在VS调试器中看到的东西足够让你郁闷了。
//Set a folder for net share
NET_API_STATUS AddNetShare(LPSTR sharedFolderPath, LPSTR shareName)
{
DWORD level = 2;
SHARE_INFO_2 si;
DWORD parmErr = 0;
si.shi2_netname = shareName; //share name
si.shi2_type = STYPE_DISKTREE;
si.shi2_remark = (LPSTR)L"This
is a shared folder."; //remark for the shared folder
si.shi2_path = sharedFolderPath; //path of the shared folder
si.shi2_permissions = ACCESS_ALL; //this parameter doesn't work
acctually
si.shi2_passwd = NULL; //no password need
si.shi2_max_uses = -1; //unlimited connected
si.shi2_current_uses = 0;
NET_API_STATUS res = NetShareAdd(NULL, level, (LPBYTE)&si, &parmErr);
return res;
}
注意,在上篇中谈到过,SHARE_INFO_2中的shi2_permissions对于Windows XP无效,你可以设为任意值,但对文件夹的共享读写权限不起作用。
如果只调用上面的函数将文件夹设为共享,则默认情况下,网络用户拥有全部读写权限,但很多时候我们不希望网络用户修改共享文件的内容,这样就必须编程将共享权限设置为只读,下面就是设置共享权限的代码:
enum NetShareAccessPermission
{
NetShareReadOnly = 0x001200a9, //readonly permission
NetShareFullControl = 0x001f01ff //full control permission
};
//Set access permission for net shared folder
DWORD SetNetsharePermission(LPTSTR shareName, NetShareAccessPermission permission)
{
DWORD res = 0;
PACL pOldDacl = NULL, pNewDacl = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
res = GetNamedSecurityInfo(shareName,
SE_LMSHARE,
DACL_SECURITY_INFORMATION ,
NULL,
NULL,
&pOldDacl,
NULL,
&pSD);
if (res != ERROR_SUCCESS)
{
goto Cleanup;
}
ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = permission; //Set access permission (defined in enum NetShareAccessPermission)
ea.grfAccessMode = SET_ACCESS ;
ea.grfInheritance= CONTAINER_INHERIT_ACE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.ptstrName = L"Everyone";
res = SetEntriesInAcl(1, &ea, pOldDacl, &pNewDacl);
if (res != ERROR_SUCCESS)
{
goto Cleanup;
}
res = SetNamedSecurityInfo(shareName,
SE_LMSHARE,
DACL_SECURITY_INFORMATION ,
NULL,
NULL,
pNewDacl,
NULL);
Cleanup: //Release resource
if (pSD != NULL)
{
LocalFree((HLOCAL) pSD);
}
if (pNewDacl != NULL)
{
LocalFree((HLOCAL) pNewDacl);
}
return res;
}
这段代码最关键的语句是:
ea.grfAccessPermissions = permission;
其中的permission参数是一个自定义的NetShareAccessPermission枚举,如果permission==NetShareReadOnly(即0x001200a9),这样就可以将共享文件夹设为只读了。
但问题的关键是为什么要自己定义一个这样的枚举?0x001200a9和0x001f01ff这两个密码一般的十六进制数是哪里来的?难道MSDN中没有定义一个这样的枚举或宏吗?
实际上,MSDN中的确存在几个预定义的可以为ea.grfAccessPermissions 赋值的宏,上面那两个十六进制数是一个与设置文件系统安全性有关的DWORD开关变量,名为ACCESS_MASK,具体定义可以参考MSDN。win32 API函数的头文件中已经定义了几个可以为这个参数赋值的宏,如GENERIC_READ,KEY_READ等,不过这两个宏在MSDN中也是语焉不详(还是我这个菜鸟实在菜到家了,人家明明说的清清楚楚,就你一个睁眼瞎……),但你可以在VS中输入这两个宏,然后选中后右键转入定义这两个东东的头文件,在头文件有少量的解释。在这个头文件中我们还可以看到更多的预定义的宏。
不幸的是,我没有找到我要的宏,KEY_READ是用来设置注册表只读权限的,GENERIC_READ,呃,我也不知道是用来设置什么的,只知道这两个宏对我的共享权限设置除了引发一些怪异的行为外,没什么帮助。
这样只能靠自己手动的设置那个恐怖的32位的开关变量了。对于一个32位的二进制数,一共有4G种组合,假设我试一种组合要花30s,将吃饭睡觉上XX的时间都搭上,一天24小时,算一下,呃,我要花3800年才试的完……
不过,我可以考虑将这项光荣的任务交给我未来的儿子,然后来个递归,利用“子又有子,子又有孙,子子孙孙无穷匮也,而const不可增”……
不过好在我思维还算缜密,我考虑到无法保证我会有儿子,这样我的递归很可能由于条件不满足产生异常而终止……
我一向不打无把握的仗,想到了一种投机取巧的办法:我可以先通过Windows的UI设置共享文件夹的权限,然后编程获取相关的变量和结构体的值,将这些值保存下来,先不管这些值看得懂看不懂(事实上,不太可能看得懂,又是一些32位的开关量,又是一些3800年),给我们的代码赋值就行了。
我没找到直接获取ACCESS_MASK的API,于是想办法通过VS的调试功能来获取,下面是我用来获取ACCESS_MASK的代码:
//Get the value of access mask
void GetAceTest()
{
DWORD res = 0;
PACL pOldDacl = NULL, pNewDacl = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;
ACCESS_ALLOWED_ACE* pAce;
LPTSTR shareName=(LPTSTR)L"TestShareFolder";
res = GetNamedSecurityInfo(shareName,
SE_LMSHARE,
DACL_SECURITY_INFORMATION ,
NULL,
NULL,
&pOldDacl,
NULL,
&pSD);
GetAce(pOldDacl,0,(LPVOID*)&pAce);
ACCESS_MASK Mask=pAce->Mask;
return;
}
ACCESS_MASK是和ACE直接关联的,至于ACE么,呃,说来话长,还是看MSDN吧。
但要注意的是GetAce()的第二个参数要设为0,因为ACEs是从0开始索引的,如果不小心设为1了,你在VS调试器中看到的东西足够让你郁闷了。
相关文章推荐
- 【转帖】用Win32 API设置windows XP中FAT32文件夹共享的读写权限
- 用Win32 API设置windows XP中FAT32文件夹共享的读写权限(一)
- 用Win32 API设置windows XP中FAT32文件夹共享的读写权限(二)
- 在 Windows XP 中如何禁用简单文件共享和如何设置共享文件夹的权限
- 如何使用Windows XP共享文件夹与文件并设置权限
- 在 Windows XP 中如何禁用简单共享和设置共享文件夹的权限
- windows 2003 server共享文件夹权限设置问题(文件夹共享设置和计算机管理设置)
- 在Win XP及Win 2003下使用程序方式(C#)设置共享文件夹的文件夹权限的问题及解决方案。
- 共享文件夹的权限设置和远程访问
- Win2003共享文件夹权限设置以及如何不需要密码访问共享文件?
- linux系统常用命令 -设置文件夹读写权限
- 【ZT】共享文件夹权限设置迁移复制
- windows共享文件夹权限设置方法
- Ubantu安装虚拟机VirtualBox使用Windows XP |设置文件夹共享| USB2.0虚实共用
- 使用DOS命令共享文件夹并设置共享权限
- 使用VirtualBox在Ubuntu下虚拟Windows XP共享文件夹设置方法
- Windows中合理设置共享文件夹访问权限
- 如何在XP HOME版下设置共享文件夹及其权限?
- VirtualBox 共享文件夹权限设置及使用方法