Finding the Owner of a File Object Program Example
The following example uses the GetSecurityInfo() and LookupAccountSid() functions to find and print the name of the owner of a file. The file exists in C:\JohnnyDir directory on the local machine. The file own by Johnny, however the computer used to run this program logged as Mike spoon.
Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.
Then, add the source file and give it a suitable name.
Next, add the following source code.
// Finding the Owner of a File Object
#include <windows.h>
#include <stdio.h>
#include <aclapi.h>
int wmain(int argc, WCHAR *argv[])
{
DWORD dwRtnCode = 0;
PSID pSidOwner;
BOOL bRtnBool = TRUE;
// Dummy initial value, no string...
LPTSTR AcctName = L, DomainName = L;
DWORD dwAcctName = 1, dwDomainName = 1;
// Dummy initial value, just use the defined one but unknown
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD = {0};
// Get the handle of the file object.
hFile = CreateFile(
L\\\\?\\C:\\JohnnyDir\\ThisisJohnnyfile.txt, // The file name and the path if any
GENERIC_READ, // Access right
FILE_SHARE_READ, // Share mode
NULL, // Security attribute for inherited or not by child
OPEN_EXISTING, // Open the file, fail if not exist
FILE_ATTRIBUTE_NORMAL, // file attribute flag, Normal
NULL); // Handle to template file if GENERIC_READ right access
// Verify
if(hFile == INVALID_HANDLE_VALUE)
{
wprintf(LCreateFile() failed, error = %u\n, GetLastError());
// Just exit, 0 - OK, non-zero - failed
return -1;
}
else
wprintf(LGot the handle to the file!\n);
// Allocate memory for the SID structure.
wprintf(LAllocating buffer for pSidOwner & pSD\n);
pSidOwner = (PSID)GlobalAlloc(GMEM_FIXED, sizeof(PSID));
// Allocate memory for the security descriptor structure.
pSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GMEM_FIXED, sizeof(PSECURITY_DESCRIPTOR));
// Get the owner SID of the file. Try for other object such as
// SE_SERVICE, SE_PRINTER, SE_REGISTRY_KEY, SE_KERNEL_OBJECT, SE_WINDOW_OBJECT etc.
// for 2nd parameter and 3rd parameter such as DACL_SECURITY_INFORMATION,
// GROUP_SECURITY_INFORMATION and SACL_SECURITY_INFORMATION
dwRtnCode = GetSecurityInfo(
hFile,// Handle to the file
SE_FILE_OBJECT,// Directory or file
OWNER_SECURITY_INFORMATION, // Owner information of the (file) object
&pSidOwner,// Pointer to the owner of the (file) object
NULL,
NULL,
NULL,
&pSD);// Pointer to the security descriptor of the (file) object
// Check GetLastError for GetSecurityInfo error condition.
if(dwRtnCode != ERROR_SUCCESS)
{
wprintf(LGetSecurityInfo() failed, error %u\n, GetLastError());
return -1;
}
else
wprintf(LGetSecurityInfo() - Got the SID of the file!\n);
// First call to LookupAccountSid() to get the buffer size AcctName.
bRtnBool = LookupAccountSid(
NULL, // Local computer
pSidOwner, // Pointer to the SID to lookup for
AcctName, // The account name of the SID (pSIDOwner)
(LPDWORD)&dwAcctName, // Size of the AcctName in TCHAR
DomainName, // Pointer to the name of the Domain where the account name was found
(LPDWORD)&dwDomainName, // Size of the DomainName in TCHAR
&eUse); // Value of the SID_NAME_USE enum type that specify the SID type
// Allocate memory for the AcctName.
AcctName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwAcctName);
// VErify
if(AcctName == NULL)
{
wprintf(LGlobalAlloc() - Failed to allocate buffer for AcctName, error %u\n, GetLastError());
return -1;
}
else
wprintf(LBuffer allocated for AcctName!\n);
DomainName = (LPTSTR)GlobalAlloc(GMEM_FIXED, dwDomainName);
// Check GetLastError() for GlobalAlloc() error condition.
if(DomainName == NULL)
{
wprintf(LGlobalAlloc() failed to allocate buffer for DomainName, error %u\n, GetLastError());
return -1;
}
else
wprintf(LBuffer allocated for DomainName!\n);
// Second call to LookupAccountSid() to get the account name.
bRtnBool = LookupAccountSid(
NULL, // name of local or remote computer
pSidOwner, // security identifier, SID
AcctName, // account name buffer
(LPDWORD)&dwAcctName, // size of account name buffer
DomainName, // domain name
(LPDWORD)&dwDomainName, // size of domain name buffer
&eUse); // SID type
// Verify
if(bRtnBool == FALSE)
{
DWORD dwErrorCode = GetLastError();
if(dwErrorCode == ERROR_NONE_MAPPED)
wprintf(LAccount owner not found for specified SID.\n);
else
{
wprintf(LLookupAccountSid() failed, error %u\n, GetLastError());
return -1;
}
}
else if (bRtnBool == TRUE)
// Print the account name.
wprintf(LThe file owner: %s\n, AcctName);
if(CloseHandle(hFile) != 0)
wprintf(LhFile handle was closed successfully!\n);
else
wprintf(LFailed to close hFile handle, error %u\n, GetLastError());
return 0;
}
Build and run the project. The following screenshot is a sample output.
Then, let verify through the ThisisJohnnyfile.txt file property page and it confirmed that the owner is a local user Johnny.