/*
一个文件的所有者,大概也就是创建者,这是一个简单的问题,你想过吗?
一般人不会关注,只有安全的人才去关注,并有所获,深入深入再深入.
本文修改自MSDN的:Finding the Owner of a File Object in C++.
再次说明,改编自VS2008的MSDN,非网络上的MSDN的代码.
made by correy
made at 2014.03.29
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/
#include "aclapi.h" //这个在VC及SDK和WDK都有.
bool get_owner_of_file(IN wchar_t * filename, OUT wchar_t * owner)
{
if (!filename || !owner) {
return false;
}
HANDLE hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
_tprintf(TEXT("CreateFile error = %d\n"), GetLastError());
return false;
}
PSID pSidOwner = (PSID)GlobalAlloc(GMEM_FIXED, sizeof(PSID));// Allocate memory for the SID structure.
if (!pSidOwner) {//这两个内存申请,微软竟然不判断失败的情况.
return false;
}
PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR));// Allocate memory for the security descriptor structure.
if (!pSD) {//经测试.这个变量不用申请,没有用.
GlobalFree(pSidOwner);
return false;
}
// Get the owner SID of the file.
DWORD dwRtnCode = GetSecurityInfo(hFile, SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, &pSidOwner, NULL, NULL, NULL, &pSD);//除了签三个参数,剩余的都是OUT类型.
if (dwRtnCode != ERROR_SUCCESS) {
_tprintf(TEXT("GetSecurityInfo error = %d\n"), GetLastError());
GlobalFree(pSidOwner);
GlobalFree(pSD);
return false;
}
// First call to LookupAccountSid to get the buffer sizes.
DWORD dwAcctName = 1, dwDomainName = 1;
SID_NAME_USE eUse = SidTypeUnknown;
BOOL bRtnBool = LookupAccountSid(NULL, pSidOwner, 0, (LPDWORD)&dwAcctName, 0, (LPDWORD)&dwDomainName, &eUse); //返回两个值的大小.
LPTSTR AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName);// Reallocate memory for the buffers.
if (AcctName == NULL) {// Check GetLastError for GlobalAlloc error condition.
_tprintf(TEXT("GlobalAlloc error = %d\n"), GetLastError());
GlobalFree(pSidOwner);
GlobalFree(pSD);
return false;
}
LPTSTR DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName); //其实这个也不是我们想要的.但必须得有,不然下面的函数运行失败.
if (DomainName == NULL) {// Check GetLastError for GlobalAlloc error condition.
_tprintf(TEXT("GlobalAlloc error = %d\n"), GetLastError());
GlobalFree(pSidOwner);
GlobalFree(pSD);
GlobalFree(AcctName);
return false;
}
bRtnBool = LookupAccountSid(// Second call to LookupAccountSid to get the account name.
NULL, // name of local or remote computer
pSidOwner, // security identifier
AcctName, // account name buffer
(LPDWORD)&dwAcctName, // size of account name buffer
DomainName, // domain name.这个域名也会返回
(LPDWORD)&dwDomainName, // size of domain name buffer.
&eUse); // SID type.这个也会返回.
if (bRtnBool == FALSE) {// Check GetLastError for LookupAccountSid error condition.
if (GetLastError() == ERROR_NONE_MAPPED) {
_tprintf(TEXT("Account owner not found for specified SID.\n"));
} else {
_tprintf(TEXT("Error in LookupAccountSid.\n"));
}
} else if (bRtnBool == TRUE) {
_tprintf(TEXT("Account owner = %s\n"), AcctName);// Print the account name.
lstrcpy(owner, AcctName);
}
GlobalFree(pSidOwner);
GlobalFree(pSD);
//GlobalFree(AcctName);//释放出错.
//GlobalFree(DomainName);//释放出错.
return !!bRtnBool;
}
int main(int argc, char **argv)
{
wchar_t owner_user[MAX_PATH] = {0};
bool b = get_owner_of_file(L"f:\\test.exe", owner_user);
if (b) {
_tprintf(TEXT("Account owner = %s\n"), owner_user);
} else {
_tprintf(TEXT("Account owner not found\n"));
}
return 0;
}
没有评论:
发表评论