📄 shareenum.cpp
字号:
//////////////////////////////////////////////////////////////
// Copyright (C) 2002-2003 Bryce Cogswell
// www.sysinternals.com
// cogswell@winternals.com
//
// You may modify and use this code for personal use only.
// Redistribution in any form is expressly prohibited
// without permission by the author.
//////////////////////////////////////////////////////////////
#define _WIN32_WINNT 0x0400 // WM_MOUSEWHEEL support
#include <windows.h>
#include <stdio.h>
#include <commctrl.h>
#include <tchar.h>
#include <ctype.h>
#include <lm.h>
#include <Aclapi.h>
#include <comdef.h> // bstr_t support
#include "shareenum.h"
#include "resource.h"
#include "resizer.h"
#include "listview.h"
bool IsDomainAdmin( const TCHAR * domain );
int Properties( HINSTANCE hInst, HWND hParent, const TCHAR * shareName );
const TCHAR ALL_DOMAINS[] = _T(" <All domains>");
struct {
HINSTANCE hInst;
HWND Abort; // 'abort in progress' window
CShare * ShareList;
TCHAR LocalComputerName[ MAX_PATH ];
long ThreadCount;
long MaxThreads;
HWND hMainDlg;
} g;
#define THREAD_STACK_SIZE 0 // (256*1024)
static struct LISTVIEW_COLUMN Columns[] =
{
{ TEXT("Share Path"), 240, DATATYPE_TEXT},
{ TEXT("Local Path"), 100, DATATYPE_TEXT},
{ TEXT("Domain"), 100, DATATYPE_TEXT},
{ TEXT("Type"), 80, DATATYPE_TEXT},
{ TEXT("Everyone"), 80, DATATYPE_TEXT},
{ TEXT("Other Read"), 120, DATATYPE_TEXT},
{ TEXT("Other Write"), 120, DATATYPE_TEXT},
{ TEXT("Deny"), 80, DATATYPE_TEXT},
{ NULL, 0, (DATATYPE)-1}
};
PSID EveryoneSid()
{
static PSID sid = NULL;
if ( sid == NULL ) {
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
AllocateAndInitializeSid( &SIDAuthWorld, 1,
SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0,
&sid );
}
return sid;
}
PSID LocalAdminSid()
{
static PSID sid = NULL;
if ( sid == NULL ) {
SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
AllocateAndInitializeSid( &ntauth, 2,
SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
&sid );
}
return sid;
}
PSID SystemSid()
{
static PSID sid = NULL;
if ( sid == NULL ) {
SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_NT_AUTHORITY;
AllocateAndInitializeSid( &SIDAuthWorld, 1,
SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0,
&sid );
}
return sid;
}
TCHAR * GetTextualSid( PSID pSid )
{
PSID_IDENTIFIER_AUTHORITY psia;
DWORD dwSubAuthorities;
DWORD dwSidRev=SID_REVISION;
DWORD dwCounter;
DWORD dwSidSize;
// Validate the binary SID.
if ( ! IsValidSid( pSid ) )
return NULL;
// Get the identifier authority value from the SID.
psia = GetSidIdentifierAuthority( pSid );
// Get the number of subauthorities in the SID.
dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
// Compute the buffer length.
// S-SID_REVISION- + IdentifierAuthority- + subauthorities- + NULL
dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
// Check input buffer length.
// If too small, indicate the proper size and set last error.
TCHAR * TextualSid = new TCHAR[ dwSidSize ];
// Add 'S' prefix and revision number to the string.
dwSidSize = wsprintf( TextualSid, TEXT("S-%lu-"), dwSidRev );
// Add SID identifier authority to the string.
if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) ) {
dwSidSize += wsprintf( TextualSid + dwSidSize,
TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
(USHORT)psia->Value[0],
(USHORT)psia->Value[1],
(USHORT)psia->Value[2],
(USHORT)psia->Value[3],
(USHORT)psia->Value[4],
(USHORT)psia->Value[5]);
} else {
dwSidSize += wsprintf( TextualSid + dwSidSize,
TEXT("%lu"),
(ULONG)(psia->Value[5] ) +
(ULONG)(psia->Value[4] << 8) +
(ULONG)(psia->Value[3] << 16) +
(ULONG)(psia->Value[2] << 24) );
}
// Add SID subauthorities to the string.
//
for ( dwCounter = 0; dwCounter < dwSubAuthorities; dwCounter++ ) {
dwSidSize += wsprintf( TextualSid + dwSidSize, TEXT("-%lu"), *GetSidSubAuthority(pSid, dwCounter) );
}
return TextualSid;
}
int AddListviewRow( HWND hListview, const TCHAR * path, const TCHAR * domain, const TCHAR * localpath, const TCHAR * type,
const TCHAR * Everyone, const TCHAR * OtherRead, const TCHAR * OtherWrite,
const TCHAR * deny )
{
CShare * share = new CShare( path, localpath, domain, type, Everyone, OtherRead, OtherWrite, deny, ',' );
share->InsertInList( &g.ShareList );
// Add to listview
LVITEM item;
item.mask = LVIF_TEXT | LVIF_IMAGE;
item.iItem = 0x7FFFFFFF;
item.iSubItem = 0;
item.iImage = 0;
item.pszText = (TCHAR *) path;
item.iItem = ListView_InsertItem( hListview, &item );
// set param to index, so we can look ourself up during sorting
item.mask = LVIF_PARAM;
item.lParam = item.iItem;
ListView_SetItem( hListview, &item );
item.mask = LVIF_TEXT;
item.iSubItem += 1;
item.pszText = (TCHAR *) localpath;
ListView_SetItem( hListview, &item );
item.iSubItem += 1;
item.pszText = (TCHAR *) domain;
ListView_SetItem( hListview, &item );
item.iSubItem += 1;
item.pszText = (TCHAR *) type;
ListView_SetItem( hListview, &item );
item.iSubItem += 1;
item.pszText = (TCHAR *) Everyone;
ListView_SetItem( hListview, &item );
item.iSubItem += 1;
item.pszText = (TCHAR *) OtherRead;
ListView_SetItem( hListview, &item );
item.iSubItem += 1;
item.pszText = (TCHAR *) OtherWrite;
ListView_SetItem( hListview, &item );
item.iSubItem += 1;
item.pszText = (TCHAR *) deny;
ListView_SetItem( hListview, &item );
return item.iItem;
}
int GetAccountName( TCHAR * buf, const TCHAR * host, PSID sid )
{
TCHAR domainName[ MAX_PATH ];
TCHAR userName[ MAX_PATH ];
DWORD nameLength = MAX_PATH - 1;
SID_NAME_USE snu;
#if 1
if ( EqualSid( sid, EveryoneSid() ) )
// hardwire name so we work internationally
return _stprintf( buf, _T("Everyone") );
#endif
// lookup account on local system
if ( LookupAccountSid( NULL, sid, userName, &nameLength, domainName, &nameLength, &snu ) ) {
if ( domainName[0] )
return _stprintf( buf, _T("%s\\%s"), domainName, userName );
else
return _stprintf( buf, _T("%s"), userName );
}
// look up account on remote system
if ( LookupAccountSid( host, sid, userName, &nameLength, domainName, &nameLength, &snu ) ) {
if ( domainName[0] )
return _stprintf( buf, _T("%s\\%s"), domainName, userName );
else
return _stprintf( buf, _T("%s"), userName );
}
TCHAR * text = GetTextualSid( sid );
int nb = _stprintf( buf, _T("%s"), text );
delete []text;
return nb;
}
void GetMask( ACCESS_MASK mask, bool * Read, bool * Write )
{
#define READ_MASK (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA)
#define WRITE_MASK (FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_DATA|FILE_WRITE_EA)
*Read = (mask & READ_MASK ) != 0;
*Write = (mask & WRITE_MASK) != 0;
}
int GetMask( TCHAR * buf, ACCESS_MASK mask )
{
#define READ_MASK (FILE_READ_ATTRIBUTES|FILE_READ_DATA|FILE_READ_EA)
#define WRITE_MASK (FILE_APPEND_DATA|FILE_WRITE_ATTRIBUTES|FILE_WRITE_DATA|FILE_WRITE_EA)
bool Read = (mask & READ_MASK ) != 0;
bool Write = (mask & WRITE_MASK) != 0;
if ( Read && Write )
return _stprintf( buf, _T("Read/Write (%X)"), mask );
if ( Read )
return _stprintf( buf, _T("Read (%X)"), mask );
if ( Write )
return _stprintf( buf, _T("Write (%X)"), mask );
return _stprintf( buf, _T("Special (%X)"), mask );
}
bool ACLtext( PACL Acl, const TCHAR * host, TCHAR * EveryoneRead, TCHAR * EveryoneWrite, TCHAR * OtherRead, TCHAR * OtherWrite, TCHAR * deny )
{
ACL_SIZE_INFORMATION aclSizeInfo;
ACL_REVISION_INFORMATION aclRevInfo;
struct USER_PERM {
PSID sid;
ACCESS_MASK mask[ ACCESS_MAX_MS_ACE_TYPE ];
};
EveryoneRead[0] = 0;
EveryoneWrite[0] = 0;
OtherRead[0] = 0;
OtherWrite[0] = 0;
deny[0] = 0;
if ( ! GetAclInformation( Acl, &aclSizeInfo, sizeof(ACL_SIZE_INFORMATION), AclSizeInformation ) ) {
_stprintf( EveryoneRead, TEXT("Could not get AclSizeInformation") );
return false;
}
if ( ! GetAclInformation( Acl, &aclRevInfo, sizeof(ACL_REVISION_INFORMATION), AclRevisionInformation ) ) {
_stprintf( EveryoneRead, TEXT("Could not get AclRevisionInformation"));
return false;
}
USER_PERM * UserList = new USER_PERM[ aclSizeInfo.AceCount ];
DWORD UserCnt = 0;
for ( ULONG i = 0; i < aclSizeInfo.AceCount; i++ ) {
LPVOID ace;
if ( ! GetAce( Acl, i, &ace ) )
break;
ACE_HEADER * aceHeader = (ACE_HEADER *) ace;
ACCESS_MASK aceMask;
PSID aceSid;
if ( aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE ) {
ACCESS_ALLOWED_ACE * paaace = (ACCESS_ALLOWED_ACE *) ace;
aceMask = paaace->Mask;
aceSid = &paaace->SidStart;
} else if ( aceHeader->AceType == ACCESS_DENIED_ACE_TYPE ) {
ACCESS_DENIED_ACE * padace = (ACCESS_DENIED_ACE *) ace;
aceMask = padace->Mask;
aceSid = &padace->SidStart;
} else {
// Unrecognized
continue;
}
if ( ! IsValidSid( aceSid ) )
// not a valid sid
continue;
for ( DWORD u = 0; u < UserCnt; ++u )
if ( EqualSid( UserList[u].sid, aceSid ) )
break;
if ( u >= UserCnt ) {
UserList[u].sid = aceSid;
memset( UserList[u].mask, 0, sizeof UserList[u].mask );
++UserCnt;
}
// add mask to list of masks
UserList[u].mask[ aceHeader->AceType ] |= aceMask;
}
for ( i = 0; i < UserCnt; ++i ) {
USER_PERM * user = &UserList[i];
TCHAR ** read;
TCHAR ** write;
if ( EqualSid( user->sid, EveryoneSid() ) ) {
read = &EveryoneRead;
write = &EveryoneWrite;
} else {
read = &OtherRead;
write = &OtherWrite;
}
if ( user->mask[ACCESS_ALLOWED_ACE_TYPE] ) {
bool bRead, bWrite;
GetMask( user->mask[ACCESS_ALLOWED_ACE_TYPE], &bRead, &bWrite );
if ( bRead ) {
*read += GetAccountName( *read, host, user->sid );
*read += _stprintf( *read, _T(", ") );
}
if ( bWrite ) {
*write += GetAccountName( *write, host, user->sid );
*write += _stprintf( *write, _T(", ") );
}
}
if ( user->mask[ACCESS_DENIED_ACE_TYPE] ) {
deny += GetAccountName( deny, host, user->sid );
deny += _stprintf( deny, _T(":") );
deny += GetMask( deny, user->mask[ACCESS_DENIED_ACE_TYPE] );
deny += _stprintf( deny, _T(" ") );
}
}
delete []UserList;
return true;
}
//==============================================================
//
// EnumerateDomains
//
// Create a list of computer domains accessible to this system
//
//==============================================================
class CWorker {
public:
void Start()
{
HANDLE hThread = NULL;
InterlockedIncrement( &g.ThreadCount );
#if _MT
if ( g.MaxThreads == 0 || g.ThreadCount < g.MaxThreads ) {
DWORD id;
hThread = CreateThread( NULL, THREAD_STACK_SIZE, Work, this, CREATE_SUSPENDED, &id );
}
#endif
if ( hThread ) {
// thread created
UpdateStatus();
SetThreadPriority( hThread, THREAD_PRIORITY_LOWEST );
ResumeThread( hThread );
} else {
// thread create failed, so don't use separate thread
Work();
}
}
virtual ~CWorker()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -