N
NetSword
Unregistered / Unconfirmed
GUEST, unregistred user!
哪位大侠对C++比较熟悉,能否把下面的程序用Delphi来实现?我自己转换后运行时出现问题,附上我转换
后的Delphi代码,大家可以比较看看,我错在哪儿。
BOOL TestDlg::GetUserSid(PSID* ppSid)
{
HANDLE hToken;
BOOL bRes;
DWORD cbBuffer, cbRequired;
PTOKEN_USER pUserInfo;
// The User's SID can be obtained from the process token
bRes = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
if (FALSE == bRes)
{
return FALSE;
}
// Set buffer size to 0 for first call to determine
// the size of buffer we need.
cbBuffer = 0;
bRes = GetTokenInformation(hToken, TokenUser, NULL, cbBuffer, &cbRequired);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
return FALSE;
}
// Allocate a buffer for our token user data
cbBuffer = cbRequired;
pUserInfo = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbBuffer);
if (NULL == pUserInfo)
{
return FALSE;
}
// Make the "real" call
bRes = GetTokenInformation(hToken, TokenUser, pUserInfo, cbBuffer, &cbRequired);
if (FALSE == bRes)
{
return FALSE;
}
// Make another copy of the SID for the return value
cbBuffer = GetLengthSid(pUserInfo->User.Sid);
*ppSid = (PSID) HeapAlloc(GetProcessHeap(), 0, cbBuffer);
if (NULL == *ppSid)
{
return FALSE;
}
bRes = CopySid(cbBuffer, *ppSid, pUserInfo->User.Sid);
if (FALSE == bRes)
{
HeapFree(GetProcessHeap(), 0, *ppSid);
return FALSE;
}
bRes = HeapFree(GetProcessHeap(), 0, pUserInfo);
return TRUE;
}
void TestDlg::GetSidString(PSID pSid, LPTSTR szBuffer)
{
//convert SID to string
SID_IDENTIFIER_AUTHORITY *psia = ::GetSidIdentifierAuthority( pSid );
DWORD dwTopAuthority = psia->Value[5];
_stprintf(szBuffer, _T("S-1-%lu"), dwTopAuthority);
TCHAR szTemp[32];
int iSubAuthorityCount = *(GetSidSubAuthorityCount(pSid));
for (int i = 0; i<iSubAuthorityCount; i++)
{
DWORD dwSubAuthority = *(GetSidSubAuthority(pSid, i));
_stprintf(szTemp, _T("%lu"), dwSubAuthority);
_tcscat(szBuffer, _T("-"));
_tcscat(szBuffer, szTemp);
}
}
BOOL TestDlg::GetOldSD(HKEY hKey, LPCTSTR pszSubKey, BYTE** pSD)
{
BOOL bRet = FALSE;
HKEY hNewKey = NULL;
DWORD dwSize = 0;
LONG lRetCode;
*pSD = NULL;
lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, READ_CONTROL, &hNewKey);
if(lRetCode != ERROR_SUCCESS)
goto cleanup;
lRetCode = RegGetKeySecurity(hNewKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, *pSD, &dwSize);
if (lRetCode == ERROR_INSUFFICIENT_BUFFER)
{
*pSD = new BYTE[dwSize];
lRetCode = RegGetKeySecurity(hNewKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, *pSD, &dwSize);
if(lRetCode != ERROR_SUCCESS)
{
delete *pSD;
*pSD = NULL;
goto cleanup;
}
}
else if (lRetCode != ERROR_SUCCESS)
goto cleanup;
bRet = TRUE; // indicate success
cleanup:
if (hNewKey)
{
RegCloseKey(hNewKey);
}
return bRet;
}
BOOL TestDlg::CreateNewSD(PSID pSid, SECURITY_DESCRIPTOR* pSD, PACL* ppDacl)
{
BOOL bRet = FALSE;
PSID pSystemSid = NULL;
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
ACCESS_ALLOWED_ACE* pACE = NULL;
DWORD dwAclSize;
DWORD dwAceSize;
// prepare a Sid representing local system account
if(!AllocateAndInitializeSid(&sia, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, &pSystemSid))
{
goto cleanup;
}
// compute size of new acl
dwAclSize = sizeof(ACL) + 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
GetLengthSid(pSid) + GetLengthSid(pSystemSid);
// allocate storage for Acl
*ppDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
if(*ppDacl == NULL)
goto cleanup;
if(!InitializeAcl(*ppDacl, dwAclSize, ACL_REVISION))
goto cleanup;
// if(!AddAccessAllowedAce(pDacl, ACL_REVISION, KEY_WRITE, pSid))
// goto cleanup;
// add current user
dwAceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid);
pACE = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize);
pACE->Mask = KEY_READ | KEY_WRITE | KEY_ALL_ACCESS;
pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pACE->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
pACE->Header.AceSize = dwAceSize;
memcpy(&pACE->SidStart, pSid, GetLengthSid(pSid));
if (!AddAce(*ppDacl, ACL_REVISION, MAXDWORD, pACE, dwAceSize))
goto cleanup;
// add local system account
HeapFree(GetProcessHeap(), 0, pACE);
pACE = NULL;
dwAceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSystemSid);
pACE = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize);
pACE->Mask = KEY_READ | KEY_WRITE | KEY_ALL_ACCESS;
pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pACE->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
pACE->Header.AceSize = dwAceSize;
memcpy(&pACE->SidStart, pSystemSid, GetLengthSid(pSystemSid));
if (!AddAce(*ppDacl, ACL_REVISION, MAXDWORD, pACE, dwAceSize))
goto cleanup;
if(!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
goto cleanup;
if(!SetSecurityDescriptorDacl(pSD, TRUE, *ppDacl, FALSE))
goto cleanup;
bRet = TRUE; // indicate success
cleanup:
if(pACE != NULL)
HeapFree(GetProcessHeap(), 0, pACE);
if(pSystemSid != NULL)
FreeSid(pSystemSid);
return bRet;
}
BOOL TestDlg::RegSetPrivilege(HKEY hKey, LPCTSTR pszSubKey,
SECURITY_DESCRIPTOR* pSD, BOOL bRecursive)
{
BOOL bRet = FALSE;
HKEY hSubKey = NULL;
LONG lRetCode;
LPTSTR pszKeyName = NULL;;
DWORD dwSubKeyCnt;
DWORD dwMaxSubKey;
DWORD dwValueCnt;
DWORD dwMaxValueName;
DWORD dwMaxValueData;
DWORD i;
if (!pszSubKey)
goto cleanup;
// open the key for WRITE_DAC access
lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, WRITE_DAC, &hSubKey);
if(lRetCode != ERROR_SUCCESS)
goto cleanup;
// apply the security descriptor to the registry key
lRetCode = RegSetKeySecurity(hSubKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, pSD);
if( lRetCode != ERROR_SUCCESS )
goto cleanup;
if (bRecursive)
{
// reopen the key for KEY_READ access
RegCloseKey(hSubKey);
hSubKey = NULL;
lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, KEY_READ, &hSubKey);
if(lRetCode != ERROR_SUCCESS)
goto cleanup;
// first get an info about this subkey ...
lRetCode = RegQueryInfoKey(hSubKey, 0, 0, 0, &dwSubKeyCnt, &dwMaxSubKey,
0, &dwValueCnt, &dwMaxValueName, &dwMaxValueData, 0, 0);
if( lRetCode != ERROR_SUCCESS )
goto cleanup;
// enumerate the subkeys and call RegTreeWalk() recursivly
pszKeyName = new TCHAR [MAX_PATH + 1];
for (i=0 ; i<dwSubKeyCnt; i++)
{
lRetCode = RegEnumKey(hSubKey, i, pszKeyName, MAX_PATH + 1);
if(lRetCode == ERROR_SUCCESS)
{
RegSetPrivilege(hSubKey, pszKeyName, pSD, TRUE);
}
else if(lRetCode == ERROR_NO_MORE_ITEMS)
{
break;
}
}
delete [] pszKeyName ;
}
bRet = TRUE; // indicate success
cleanup:
if (hSubKey)
{
RegCloseKey(hSubKey);
}
return bRet;
}
void TestDlg::OnButton1()
{
// 清除IE表单自动完成历史记录
CString sKey;
DWORD dwRet;
// if (IsWindows2k() || IsWindowsNT())//这一步可以忽略
{
CString sBaseKey;
SECURITY_DESCRIPTOR NewSD;
BYTE* pOldSD;
PACL pDacl = NULL;
PSID pSid = NULL;
TCHAR szSid[256];
if (GetUserSid(&pSid))
{
//get the hiden key name
GetSidString(pSid, szSid);
sKey = _T("Software//Microsoft//Protected Storage System Provider//");
sKey += szSid;
//get old SD
sBaseKey = sKey;
GetOldSD(HKEY_CURRENT_USER, sBaseKey, &pOldSD);
//set new SD and then clear
if (CreateNewSD(pSid, &NewSD, &pDacl))
{
RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, FALSE);
sKey += _T("//Data");
RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, FALSE);
sKey += _T("//e161255a-37c3-11d2-bcaa-00c04fd929db");
RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, TRUE);
dwRet = SHDeleteKey(HKEY_CURRENT_USER, sKey);
}
if (pDacl != NULL)
HeapFree(GetProcessHeap(), 0, pDacl);
//restore old SD
if (pOldSD)
{
RegSetPrivilege(HKEY_CURRENT_USER, sBaseKey,
(SECURITY_DESCRIPTOR*)pOldSD, FALSE);
delete pOldSD;
}
}
if (pSid)
HeapFree(GetProcessHeap(), 0, pSid);
}
}
==============================================================================================
unit CleanerMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, shellapi, registry;
type
PSID_AND_ATTRIBUTES = ^SID_AND_ATTRIBUTES;
SID_AND_ATTRIBUTES = record
Sid: PSID;
Attributes: DWORD;
end;
PTOKEN_USER = ^TOKEN_USER;
TOKEN_USER = record
User: SID_AND_ATTRIBUTES;
end;
ACE_HEADER = record
AceType: BYTE;
AceFlags: BYTE;
AceSize: WORD;
end;
PACCESS_ALLOWED_ACE = ^ACCESS_ALLOWED_ACE;
ACCESS_ALLOWED_ACE = record
Header: ACE_HEADER;
Mask: ACCESS_MASK;
SidStart: DWORD;
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function GetUserSid(var pASid: PSID): BOOL;
var
hToken: THANDLE;
bRes: BOOL;
cbBuffer, cbRequired: DWORD;
pUserInfo: PTOKEN_USER;
begin
// The User's SID can be obtained from the process token
bRes := OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, hToken);
if (FALSE = bRes) then
begin
Result := FALSE;
end;
cbBuffer := 0;
bRes := GetTokenInformation(hToken, TokenUser, nil, cbBuffer, cbRequired);
if (GetLastError() <> ERROR_INSUFFICIENT_BUFFER) then
begin
Result := FALSE;
end;
// Allocate a buffer for our token user data
cbBuffer := cbRequired;
pUserInfo := PTOKEN_USER(HeapAlloc(GetProcessHeap(), 0, cbBuffer));
if (nil = pUserInfo) then
begin
Result := FALSE;
end;
// Make the "real" call
bRes := GetTokenInformation(hToken, TokenUser, pUserInfo, cbBuffer, cbRequired);
if (FALSE = bRes) then
begin
Result := FALSE;
end;
// Make another copy of the SID for the return value
cbBuffer := GetLengthSid(pUserInfo^.User.Sid);
pASid := PSID(HeapAlloc(GetProcessHeap(), 0, cbBuffer));
if (nil = pASid) then
begin
Result := FALSE;
end;
bRes := CopySid(cbBuffer, pASid, pUserInfo^.User.Sid);
if (FALSE = bRes) then
begin
HeapFree(GetProcessHeap(), 0, pASid);
Result := FALSE;
end;
bRes := HeapFree(GetProcessHeap(), 0, pUserInfo);
Result := TRUE;
end;
procedure GetSidString(pASid: PSID; var szBuffer: array of Char);
var
I: Integer;
S, S2: string;
szTemp: array[0..31] of char;
iSubAuthorityCount: Integer;
psia: PSIDIdentifierAuthority;
//psia: Pointer;
//psia : SID_IDENTIFIER_AUTHORITY;
dwSubAuthority, dwTopAuthority: DWORD;
pSubAuthority: PDWORD;
pbSubAuthorityCount: PUCHAR;
begin
//convert SID to string
psia := GetSidIdentifierAuthority(pASid);
dwTopAuthority := psia^.Value[5];
//_stprintf(szBuffer, _T("S-1-%lu"), dwTopAuthority);
s := format('S-1-%u', [dwTopAuthority]);
pbSubAuthorityCount := GetSidSubAuthorityCount(pASid);
iSubAuthorityCount := pbSubAuthorityCount^;
for I := 0 to iSubAuthorityCount - 1 do
begin
pSubAuthority := GetSidSubAuthority(pASid, i);
dwSubAuthority := pSubAuthority^;
s2 := format('%u', [dwSubAuthority]);
s := s + '-' + s2;
end;
strpcopy(szBuffer, s);
end;
//function GetOldSD(AhKey: HKEY; pszSubKey: PChar; var pSD: PByte): BOOL;
function GetOldSD(AhKey: HKEY; pszSubKey: PChar; var pSD: PSecurityDescriptor): BOOL;
var
bRet: BOOL;
hNewKey: HKEY;
dwSize: DWORD;
lRetCode: LONGINT;
label cleanup;
begin
hNewKey := 0;
dwSize := 0;
pSD := nil;
bRet := FALSE;
lRetCode := RegOpenKeyEx(AhKey, pszSubKey, 0, READ_CONTROL, hNewKey);
if lRetCode <> ERROR_SUCCESS then
goto cleanup;
lRetCode := RegGetKeySecurity(hNewKey,
DACL_SECURITY_INFORMATION, pSD, dwSize);
if (lRetCode = ERROR_INSUFFICIENT_BUFFER) then
begin
GetMem(pSD, dwSize);
lRetCode := RegGetKeySecurity(hNewKey,
DACL_SECURITY_INFORMATION, pSD, dwSize);
if (lRetCode <> ERROR_SUCCESS) then
begin
freemem(pSD);
pSD := nil;
goto cleanup;
end;
end
else if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
bRet := TRUE; // indicate success
cleanup:
if (hNewKey <> 0) then
begin
RegCloseKey(hNewKey);
end;
result := bRet;
end;
function CreateNewSD(ApSid: PSID; pSD: PSecurityDescriptor; var ppDacl: PACL): BOOL;
//const
// SECURITY_NT_AUTHORITY: array[0..5] of byte = (0,0,0,0,0,5);
const
HEAP_ZERO_MEMORY = $8;
ACCESS_ALLOWED_ACE_TYPE = $0;
CONTAINER_INHERIT_ACE = 2;
OBJECT_INHERIT_ACE = 1;
ACL_REVISION = 2;
SECURITY_LOCAL_SYSTEM_RID = $12;
var
bRet: BOOL;
pSystemSid: PSID;
//pSystemSid: PSIDIdentifierAuthority;
//sia: SID_IDENTIFIER_AUTHORITY;
sia: TSIDIdentifierAuthority;
//pACE: PACCESS_ALLOWED_ACE;
pACE: PACCESS_ALLOWED_ACE;
dwAclSize: DWORD;
dwAceSize: DWORD;
label cleanup;
begin
bRet := FALSE;
pSystemSid := nil;
// sia := SECURITY_NT_AUTHORITY;
sia.Value[0] := 0;
sia.Value[1] := 0;
sia.Value[2] := 0;
sia.Value[3] := 0;
sia.Value[4] := 0;
sia.Value[5] := 5;
pACE := nil;
// prepare a Sid representing local system account
if (not AllocateAndInitializeSid(sia, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, pSystemSid)) then
begin
goto cleanup;
end;
// compute size of new acl
dwAclSize := sizeof(ACL) + 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
GetLengthSid(ApSid) + GetLengthSid(pSystemSid);
// allocate storage for Acl
ppDacl := PACL(HeapAlloc(GetProcessHeap(), 0, dwAclSize));
if ppDacl = nil then
goto cleanup;
if (not InitializeAcl(ppDacl^, dwAclSize, ACL_REVISION)) then
goto cleanup;
// if not AddAccessAllowedAce(ppDacl^, ACL_REVISION, KEY_WRITE, pSid) then
// goto cleanup;
// add current user
dwAceSize := sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(ApSid);
pACE := PACCESS_ALLOWED_ACE(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize));
pACE^.Mask := KEY_READ or KEY_WRITE or KEY_ALL_ACCESS;
pACE^.Header.AceType := ACCESS_ALLOWED_ACE_TYPE;
pACE^.Header.AceFlags := CONTAINER_INHERIT_ACE or OBJECT_INHERIT_ACE;
pACE^.Header.AceSize := dwAceSize;
Move(ApSid, pACE^.SidStart, GetLengthSid(ApSid));
if (not AddAce(ppDacl^, ACL_REVISION, MAXDWORD, pACE, dwAceSize)) then
goto cleanup;
// add local system account
HeapFree(GetProcessHeap(), 0, pACE);
pACE := nil;
// add local system account
dwAceSize := sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSystemSid);
pACE := PACCESS_ALLOWED_ACE(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize));
pACE^.Mask := KEY_READ or KEY_WRITE or KEY_ALL_ACCESS;
pACE^.Header.AceType := ACCESS_ALLOWED_ACE_TYPE;
pACE^.Header.AceFlags := CONTAINER_INHERIT_ACE or OBJECT_INHERIT_ACE;
pACE^.Header.AceSize := dwAceSize;
Move(pSystemSid, pACE^.SidStart, GetLengthSid(pSystemSid));
if (not AddAce(ppDacl^, ACL_REVISION, MAXDWORD, pACE, dwAceSize)) then
begin
//大家注意,就是这一步出错,错误信息居然是:参数错误。不知道是怎么回事。
// showmessage(inttostr(getlasterror()));
RaiseLastOSError;
// goto cleanup;
end;
if (not InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) then
goto cleanup;
if (not SetSecurityDescriptorDacl(pSD, TRUE, ppDacl, FALSE)) then
goto cleanup;
bRet := TRUE; // indicate success
cleanup:
if (pACE <> nil) then
HeapFree(GetProcessHeap(), 0, pACE);
if (pSystemSid <> nil) then
FreeSid(pSystemSid);
Result := bRet;
end;
function RegSetPrivilege(AhKey: HKEY; pszSubKey: PChar;
pSD: PSecurityDescriptor; bRecursive: BOOL): BOOL;
var
bRet: BOOL;
hSubKey: HKEY;
lRetCode: LONGINT;
pszKeyName: pchar;
dwSubKeyCnt: DWORD;
dwMaxSubKey: DWORD;
dwValueCnt: DWORD;
dwMaxValueName: DWORD;
dwMaxValueData: DWORD;
i: DWORD;
label cleanup;
begin
bRet := FALSE;
hSubKey := 0;
pszKeyName := nil;
if (pszSubKey = nil) then
goto cleanup;
// open the key for WRITE_DAC access
lRetCode := RegOpenKeyEx(AhKey, pszSubKey, 0, WRITE_DAC, hSubKey);
if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
// apply the security descriptor to the registry key
lRetCode := RegSetKeySecurity(hSubKey,
DACL_SECURITY_INFORMATION, pSD);
if (lRetCode <> ERROR_SUCCESS) then
begin
// RaiseLastOSError;
goto cleanup;
end;
if (bRecursive) then
begin
// reopen the key for KEY_READ access
RegCloseKey(hSubKey);
hSubKey := 0;
lRetCode := RegOpenKeyEx(AhKey, pszSubKey, 0, KEY_READ, hSubKey);
if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
// first get an info about this subkey ...
lRetCode := RegQueryInfoKey(hSubKey, 0, 0, 0, @dwSubKeyCnt, @dwMaxSubKey,
0, @dwValueCnt, @dwMaxValueName, @dwMaxValueData, 0, 0);
if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
// enumerate the subkeys and call RegTreeWalk() recursivly
getmem(pszKeyName, MAX_PATH + 1);
for I := 0 to dwSubKeyCnt - 1 do // Iterate
begin
lRetCode := RegEnumKey(hSubKey, i, pszKeyName, MAX_PATH + 1);
if (lRetCode = ERROR_SUCCESS) then
begin
RegSetPrivilege(hSubKey, pszKeyName, pSD, TRUE);
end
else if (lRetCode = ERROR_NO_MORE_ITEMS) then
begin
break;
end;
end;
freemem(pszKeyName);
end;
bRet := TRUE; // indicate success
cleanup:
if (hSubKey <> 0) then
begin
RegCloseKey(hSubKey);
end;
result := bRet;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
pNewSD: PSecurityDescriptor;
//pOldSD: PChar ;
pOldSD: PSecurityDescriptor;
pDacl: PACL;
pASid: PSID;
szSid: array[0..255] of char;
S, sKey, sBaseKey, sUserName: string;
szKey, szBaseKey: array[0..255] of char;
iRet: integer;
dwRet: dword;
dwSize: DWORD;
szUserName: PChar;
begin
pDacl := nil;
pASid := nil;
if GetUserSid(pASid) then
begin
GetSidString(pASid, szSid);
s := strpas(szSid);
Memo1.Lines.Add(s);
sKey := 'Software/Microsoft/Protected Storage System Provider/';
sKey := sKey + s;
StrPCopy(szKey, sKey);
Memo1.Lines.Add(sKey);
sBaseKey := sKey;
StrPCopy(szBaseKey, sBaseKey);
if GetOldSD(HKEY_CURRENT_USER, szBaseKey, pOldSD) then
Memo1.Lines.Add('Call GetOldSD() OK ')
else
Memo1.Lines.Add('Call GetOldSD() Fail ');
GetMem(pNewSD, Sizeof(SECURITY_DESCRIPTOR));//FreeMem
if CreateNewSD(pASid, pNewSD, pDacl) then
begin
Memo1.Lines.Add('Call CreateNewSD() OK ');
StrPCopy(szKey, sKey);
RegSetPrivilege(HKEY_CURRENT_USER, szKey, pNewSD, FALSE);
sKey := sKey + '/Data';
StrPCopy(szKey, sKey);
RegSetPrivilege(HKEY_CURRENT_USER, szKey, pNewSD, FALSE);
sKey := sKey + '/e161255a-37c3-11d2-bcaa-00c04fd929db';
StrPCopy(szKey, sKey);
RegSetPrivilege(HKEY_CURRENT_USER, szKey, pNewSD, FALSE);
//dwRet := SHDeleteKey(HKEY_CURRENT_USER, szKey);
iRet := RegDeleteValue(HKEY_CURRENT_USER, szKey);
end
else
Memo1.Lines.Add('Call CreateNewSD() Fail ');
if (pDacl <> nil) then
HeapFree(GetProcessHeap(), 0, pDacl);
//restore old SD
if (pOldSD <> nil) then
begin
RegSetPrivilege(HKEY_CURRENT_USER, szBaseKey,
pOldSD, FALSE);
dispose(pOldSD);
end;
if (pASid <> nil) then
HeapFree(GetProcessHeap(), 0, pASid);
end;
FreeMem(pNewSD);
end;
end.
后的Delphi代码,大家可以比较看看,我错在哪儿。
BOOL TestDlg::GetUserSid(PSID* ppSid)
{
HANDLE hToken;
BOOL bRes;
DWORD cbBuffer, cbRequired;
PTOKEN_USER pUserInfo;
// The User's SID can be obtained from the process token
bRes = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
if (FALSE == bRes)
{
return FALSE;
}
// Set buffer size to 0 for first call to determine
// the size of buffer we need.
cbBuffer = 0;
bRes = GetTokenInformation(hToken, TokenUser, NULL, cbBuffer, &cbRequired);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
return FALSE;
}
// Allocate a buffer for our token user data
cbBuffer = cbRequired;
pUserInfo = (PTOKEN_USER) HeapAlloc(GetProcessHeap(), 0, cbBuffer);
if (NULL == pUserInfo)
{
return FALSE;
}
// Make the "real" call
bRes = GetTokenInformation(hToken, TokenUser, pUserInfo, cbBuffer, &cbRequired);
if (FALSE == bRes)
{
return FALSE;
}
// Make another copy of the SID for the return value
cbBuffer = GetLengthSid(pUserInfo->User.Sid);
*ppSid = (PSID) HeapAlloc(GetProcessHeap(), 0, cbBuffer);
if (NULL == *ppSid)
{
return FALSE;
}
bRes = CopySid(cbBuffer, *ppSid, pUserInfo->User.Sid);
if (FALSE == bRes)
{
HeapFree(GetProcessHeap(), 0, *ppSid);
return FALSE;
}
bRes = HeapFree(GetProcessHeap(), 0, pUserInfo);
return TRUE;
}
void TestDlg::GetSidString(PSID pSid, LPTSTR szBuffer)
{
//convert SID to string
SID_IDENTIFIER_AUTHORITY *psia = ::GetSidIdentifierAuthority( pSid );
DWORD dwTopAuthority = psia->Value[5];
_stprintf(szBuffer, _T("S-1-%lu"), dwTopAuthority);
TCHAR szTemp[32];
int iSubAuthorityCount = *(GetSidSubAuthorityCount(pSid));
for (int i = 0; i<iSubAuthorityCount; i++)
{
DWORD dwSubAuthority = *(GetSidSubAuthority(pSid, i));
_stprintf(szTemp, _T("%lu"), dwSubAuthority);
_tcscat(szBuffer, _T("-"));
_tcscat(szBuffer, szTemp);
}
}
BOOL TestDlg::GetOldSD(HKEY hKey, LPCTSTR pszSubKey, BYTE** pSD)
{
BOOL bRet = FALSE;
HKEY hNewKey = NULL;
DWORD dwSize = 0;
LONG lRetCode;
*pSD = NULL;
lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, READ_CONTROL, &hNewKey);
if(lRetCode != ERROR_SUCCESS)
goto cleanup;
lRetCode = RegGetKeySecurity(hNewKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, *pSD, &dwSize);
if (lRetCode == ERROR_INSUFFICIENT_BUFFER)
{
*pSD = new BYTE[dwSize];
lRetCode = RegGetKeySecurity(hNewKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, *pSD, &dwSize);
if(lRetCode != ERROR_SUCCESS)
{
delete *pSD;
*pSD = NULL;
goto cleanup;
}
}
else if (lRetCode != ERROR_SUCCESS)
goto cleanup;
bRet = TRUE; // indicate success
cleanup:
if (hNewKey)
{
RegCloseKey(hNewKey);
}
return bRet;
}
BOOL TestDlg::CreateNewSD(PSID pSid, SECURITY_DESCRIPTOR* pSD, PACL* ppDacl)
{
BOOL bRet = FALSE;
PSID pSystemSid = NULL;
SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
ACCESS_ALLOWED_ACE* pACE = NULL;
DWORD dwAclSize;
DWORD dwAceSize;
// prepare a Sid representing local system account
if(!AllocateAndInitializeSid(&sia, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, &pSystemSid))
{
goto cleanup;
}
// compute size of new acl
dwAclSize = sizeof(ACL) + 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
GetLengthSid(pSid) + GetLengthSid(pSystemSid);
// allocate storage for Acl
*ppDacl = (PACL)HeapAlloc(GetProcessHeap(), 0, dwAclSize);
if(*ppDacl == NULL)
goto cleanup;
if(!InitializeAcl(*ppDacl, dwAclSize, ACL_REVISION))
goto cleanup;
// if(!AddAccessAllowedAce(pDacl, ACL_REVISION, KEY_WRITE, pSid))
// goto cleanup;
// add current user
dwAceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid);
pACE = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize);
pACE->Mask = KEY_READ | KEY_WRITE | KEY_ALL_ACCESS;
pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pACE->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
pACE->Header.AceSize = dwAceSize;
memcpy(&pACE->SidStart, pSid, GetLengthSid(pSid));
if (!AddAce(*ppDacl, ACL_REVISION, MAXDWORD, pACE, dwAceSize))
goto cleanup;
// add local system account
HeapFree(GetProcessHeap(), 0, pACE);
pACE = NULL;
dwAceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSystemSid);
pACE = (ACCESS_ALLOWED_ACE *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize);
pACE->Mask = KEY_READ | KEY_WRITE | KEY_ALL_ACCESS;
pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
pACE->Header.AceFlags = CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE;
pACE->Header.AceSize = dwAceSize;
memcpy(&pACE->SidStart, pSystemSid, GetLengthSid(pSystemSid));
if (!AddAce(*ppDacl, ACL_REVISION, MAXDWORD, pACE, dwAceSize))
goto cleanup;
if(!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION))
goto cleanup;
if(!SetSecurityDescriptorDacl(pSD, TRUE, *ppDacl, FALSE))
goto cleanup;
bRet = TRUE; // indicate success
cleanup:
if(pACE != NULL)
HeapFree(GetProcessHeap(), 0, pACE);
if(pSystemSid != NULL)
FreeSid(pSystemSid);
return bRet;
}
BOOL TestDlg::RegSetPrivilege(HKEY hKey, LPCTSTR pszSubKey,
SECURITY_DESCRIPTOR* pSD, BOOL bRecursive)
{
BOOL bRet = FALSE;
HKEY hSubKey = NULL;
LONG lRetCode;
LPTSTR pszKeyName = NULL;;
DWORD dwSubKeyCnt;
DWORD dwMaxSubKey;
DWORD dwValueCnt;
DWORD dwMaxValueName;
DWORD dwMaxValueData;
DWORD i;
if (!pszSubKey)
goto cleanup;
// open the key for WRITE_DAC access
lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, WRITE_DAC, &hSubKey);
if(lRetCode != ERROR_SUCCESS)
goto cleanup;
// apply the security descriptor to the registry key
lRetCode = RegSetKeySecurity(hSubKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, pSD);
if( lRetCode != ERROR_SUCCESS )
goto cleanup;
if (bRecursive)
{
// reopen the key for KEY_READ access
RegCloseKey(hSubKey);
hSubKey = NULL;
lRetCode = RegOpenKeyEx(hKey, pszSubKey, 0, KEY_READ, &hSubKey);
if(lRetCode != ERROR_SUCCESS)
goto cleanup;
// first get an info about this subkey ...
lRetCode = RegQueryInfoKey(hSubKey, 0, 0, 0, &dwSubKeyCnt, &dwMaxSubKey,
0, &dwValueCnt, &dwMaxValueName, &dwMaxValueData, 0, 0);
if( lRetCode != ERROR_SUCCESS )
goto cleanup;
// enumerate the subkeys and call RegTreeWalk() recursivly
pszKeyName = new TCHAR [MAX_PATH + 1];
for (i=0 ; i<dwSubKeyCnt; i++)
{
lRetCode = RegEnumKey(hSubKey, i, pszKeyName, MAX_PATH + 1);
if(lRetCode == ERROR_SUCCESS)
{
RegSetPrivilege(hSubKey, pszKeyName, pSD, TRUE);
}
else if(lRetCode == ERROR_NO_MORE_ITEMS)
{
break;
}
}
delete [] pszKeyName ;
}
bRet = TRUE; // indicate success
cleanup:
if (hSubKey)
{
RegCloseKey(hSubKey);
}
return bRet;
}
void TestDlg::OnButton1()
{
// 清除IE表单自动完成历史记录
CString sKey;
DWORD dwRet;
// if (IsWindows2k() || IsWindowsNT())//这一步可以忽略
{
CString sBaseKey;
SECURITY_DESCRIPTOR NewSD;
BYTE* pOldSD;
PACL pDacl = NULL;
PSID pSid = NULL;
TCHAR szSid[256];
if (GetUserSid(&pSid))
{
//get the hiden key name
GetSidString(pSid, szSid);
sKey = _T("Software//Microsoft//Protected Storage System Provider//");
sKey += szSid;
//get old SD
sBaseKey = sKey;
GetOldSD(HKEY_CURRENT_USER, sBaseKey, &pOldSD);
//set new SD and then clear
if (CreateNewSD(pSid, &NewSD, &pDacl))
{
RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, FALSE);
sKey += _T("//Data");
RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, FALSE);
sKey += _T("//e161255a-37c3-11d2-bcaa-00c04fd929db");
RegSetPrivilege(HKEY_CURRENT_USER, sKey, &NewSD, TRUE);
dwRet = SHDeleteKey(HKEY_CURRENT_USER, sKey);
}
if (pDacl != NULL)
HeapFree(GetProcessHeap(), 0, pDacl);
//restore old SD
if (pOldSD)
{
RegSetPrivilege(HKEY_CURRENT_USER, sBaseKey,
(SECURITY_DESCRIPTOR*)pOldSD, FALSE);
delete pOldSD;
}
}
if (pSid)
HeapFree(GetProcessHeap(), 0, pSid);
}
}
==============================================================================================
unit CleanerMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, shellapi, registry;
type
PSID_AND_ATTRIBUTES = ^SID_AND_ATTRIBUTES;
SID_AND_ATTRIBUTES = record
Sid: PSID;
Attributes: DWORD;
end;
PTOKEN_USER = ^TOKEN_USER;
TOKEN_USER = record
User: SID_AND_ATTRIBUTES;
end;
ACE_HEADER = record
AceType: BYTE;
AceFlags: BYTE;
AceSize: WORD;
end;
PACCESS_ALLOWED_ACE = ^ACCESS_ALLOWED_ACE;
ACCESS_ALLOWED_ACE = record
Header: ACE_HEADER;
Mask: ACCESS_MASK;
SidStart: DWORD;
end;
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function GetUserSid(var pASid: PSID): BOOL;
var
hToken: THANDLE;
bRes: BOOL;
cbBuffer, cbRequired: DWORD;
pUserInfo: PTOKEN_USER;
begin
// The User's SID can be obtained from the process token
bRes := OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, hToken);
if (FALSE = bRes) then
begin
Result := FALSE;
end;
cbBuffer := 0;
bRes := GetTokenInformation(hToken, TokenUser, nil, cbBuffer, cbRequired);
if (GetLastError() <> ERROR_INSUFFICIENT_BUFFER) then
begin
Result := FALSE;
end;
// Allocate a buffer for our token user data
cbBuffer := cbRequired;
pUserInfo := PTOKEN_USER(HeapAlloc(GetProcessHeap(), 0, cbBuffer));
if (nil = pUserInfo) then
begin
Result := FALSE;
end;
// Make the "real" call
bRes := GetTokenInformation(hToken, TokenUser, pUserInfo, cbBuffer, cbRequired);
if (FALSE = bRes) then
begin
Result := FALSE;
end;
// Make another copy of the SID for the return value
cbBuffer := GetLengthSid(pUserInfo^.User.Sid);
pASid := PSID(HeapAlloc(GetProcessHeap(), 0, cbBuffer));
if (nil = pASid) then
begin
Result := FALSE;
end;
bRes := CopySid(cbBuffer, pASid, pUserInfo^.User.Sid);
if (FALSE = bRes) then
begin
HeapFree(GetProcessHeap(), 0, pASid);
Result := FALSE;
end;
bRes := HeapFree(GetProcessHeap(), 0, pUserInfo);
Result := TRUE;
end;
procedure GetSidString(pASid: PSID; var szBuffer: array of Char);
var
I: Integer;
S, S2: string;
szTemp: array[0..31] of char;
iSubAuthorityCount: Integer;
psia: PSIDIdentifierAuthority;
//psia: Pointer;
//psia : SID_IDENTIFIER_AUTHORITY;
dwSubAuthority, dwTopAuthority: DWORD;
pSubAuthority: PDWORD;
pbSubAuthorityCount: PUCHAR;
begin
//convert SID to string
psia := GetSidIdentifierAuthority(pASid);
dwTopAuthority := psia^.Value[5];
//_stprintf(szBuffer, _T("S-1-%lu"), dwTopAuthority);
s := format('S-1-%u', [dwTopAuthority]);
pbSubAuthorityCount := GetSidSubAuthorityCount(pASid);
iSubAuthorityCount := pbSubAuthorityCount^;
for I := 0 to iSubAuthorityCount - 1 do
begin
pSubAuthority := GetSidSubAuthority(pASid, i);
dwSubAuthority := pSubAuthority^;
s2 := format('%u', [dwSubAuthority]);
s := s + '-' + s2;
end;
strpcopy(szBuffer, s);
end;
//function GetOldSD(AhKey: HKEY; pszSubKey: PChar; var pSD: PByte): BOOL;
function GetOldSD(AhKey: HKEY; pszSubKey: PChar; var pSD: PSecurityDescriptor): BOOL;
var
bRet: BOOL;
hNewKey: HKEY;
dwSize: DWORD;
lRetCode: LONGINT;
label cleanup;
begin
hNewKey := 0;
dwSize := 0;
pSD := nil;
bRet := FALSE;
lRetCode := RegOpenKeyEx(AhKey, pszSubKey, 0, READ_CONTROL, hNewKey);
if lRetCode <> ERROR_SUCCESS then
goto cleanup;
lRetCode := RegGetKeySecurity(hNewKey,
DACL_SECURITY_INFORMATION, pSD, dwSize);
if (lRetCode = ERROR_INSUFFICIENT_BUFFER) then
begin
GetMem(pSD, dwSize);
lRetCode := RegGetKeySecurity(hNewKey,
DACL_SECURITY_INFORMATION, pSD, dwSize);
if (lRetCode <> ERROR_SUCCESS) then
begin
freemem(pSD);
pSD := nil;
goto cleanup;
end;
end
else if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
bRet := TRUE; // indicate success
cleanup:
if (hNewKey <> 0) then
begin
RegCloseKey(hNewKey);
end;
result := bRet;
end;
function CreateNewSD(ApSid: PSID; pSD: PSecurityDescriptor; var ppDacl: PACL): BOOL;
//const
// SECURITY_NT_AUTHORITY: array[0..5] of byte = (0,0,0,0,0,5);
const
HEAP_ZERO_MEMORY = $8;
ACCESS_ALLOWED_ACE_TYPE = $0;
CONTAINER_INHERIT_ACE = 2;
OBJECT_INHERIT_ACE = 1;
ACL_REVISION = 2;
SECURITY_LOCAL_SYSTEM_RID = $12;
var
bRet: BOOL;
pSystemSid: PSID;
//pSystemSid: PSIDIdentifierAuthority;
//sia: SID_IDENTIFIER_AUTHORITY;
sia: TSIDIdentifierAuthority;
//pACE: PACCESS_ALLOWED_ACE;
pACE: PACCESS_ALLOWED_ACE;
dwAclSize: DWORD;
dwAceSize: DWORD;
label cleanup;
begin
bRet := FALSE;
pSystemSid := nil;
// sia := SECURITY_NT_AUTHORITY;
sia.Value[0] := 0;
sia.Value[1] := 0;
sia.Value[2] := 0;
sia.Value[3] := 0;
sia.Value[4] := 0;
sia.Value[5] := 5;
pACE := nil;
// prepare a Sid representing local system account
if (not AllocateAndInitializeSid(sia, 1, SECURITY_LOCAL_SYSTEM_RID,
0, 0, 0, 0, 0, 0, 0, pSystemSid)) then
begin
goto cleanup;
end;
// compute size of new acl
dwAclSize := sizeof(ACL) + 2 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) +
GetLengthSid(ApSid) + GetLengthSid(pSystemSid);
// allocate storage for Acl
ppDacl := PACL(HeapAlloc(GetProcessHeap(), 0, dwAclSize));
if ppDacl = nil then
goto cleanup;
if (not InitializeAcl(ppDacl^, dwAclSize, ACL_REVISION)) then
goto cleanup;
// if not AddAccessAllowedAce(ppDacl^, ACL_REVISION, KEY_WRITE, pSid) then
// goto cleanup;
// add current user
dwAceSize := sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(ApSid);
pACE := PACCESS_ALLOWED_ACE(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize));
pACE^.Mask := KEY_READ or KEY_WRITE or KEY_ALL_ACCESS;
pACE^.Header.AceType := ACCESS_ALLOWED_ACE_TYPE;
pACE^.Header.AceFlags := CONTAINER_INHERIT_ACE or OBJECT_INHERIT_ACE;
pACE^.Header.AceSize := dwAceSize;
Move(ApSid, pACE^.SidStart, GetLengthSid(ApSid));
if (not AddAce(ppDacl^, ACL_REVISION, MAXDWORD, pACE, dwAceSize)) then
goto cleanup;
// add local system account
HeapFree(GetProcessHeap(), 0, pACE);
pACE := nil;
// add local system account
dwAceSize := sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSystemSid);
pACE := PACCESS_ALLOWED_ACE(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwAceSize));
pACE^.Mask := KEY_READ or KEY_WRITE or KEY_ALL_ACCESS;
pACE^.Header.AceType := ACCESS_ALLOWED_ACE_TYPE;
pACE^.Header.AceFlags := CONTAINER_INHERIT_ACE or OBJECT_INHERIT_ACE;
pACE^.Header.AceSize := dwAceSize;
Move(pSystemSid, pACE^.SidStart, GetLengthSid(pSystemSid));
if (not AddAce(ppDacl^, ACL_REVISION, MAXDWORD, pACE, dwAceSize)) then
begin
//大家注意,就是这一步出错,错误信息居然是:参数错误。不知道是怎么回事。
// showmessage(inttostr(getlasterror()));
RaiseLastOSError;
// goto cleanup;
end;
if (not InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) then
goto cleanup;
if (not SetSecurityDescriptorDacl(pSD, TRUE, ppDacl, FALSE)) then
goto cleanup;
bRet := TRUE; // indicate success
cleanup:
if (pACE <> nil) then
HeapFree(GetProcessHeap(), 0, pACE);
if (pSystemSid <> nil) then
FreeSid(pSystemSid);
Result := bRet;
end;
function RegSetPrivilege(AhKey: HKEY; pszSubKey: PChar;
pSD: PSecurityDescriptor; bRecursive: BOOL): BOOL;
var
bRet: BOOL;
hSubKey: HKEY;
lRetCode: LONGINT;
pszKeyName: pchar;
dwSubKeyCnt: DWORD;
dwMaxSubKey: DWORD;
dwValueCnt: DWORD;
dwMaxValueName: DWORD;
dwMaxValueData: DWORD;
i: DWORD;
label cleanup;
begin
bRet := FALSE;
hSubKey := 0;
pszKeyName := nil;
if (pszSubKey = nil) then
goto cleanup;
// open the key for WRITE_DAC access
lRetCode := RegOpenKeyEx(AhKey, pszSubKey, 0, WRITE_DAC, hSubKey);
if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
// apply the security descriptor to the registry key
lRetCode := RegSetKeySecurity(hSubKey,
DACL_SECURITY_INFORMATION, pSD);
if (lRetCode <> ERROR_SUCCESS) then
begin
// RaiseLastOSError;
goto cleanup;
end;
if (bRecursive) then
begin
// reopen the key for KEY_READ access
RegCloseKey(hSubKey);
hSubKey := 0;
lRetCode := RegOpenKeyEx(AhKey, pszSubKey, 0, KEY_READ, hSubKey);
if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
// first get an info about this subkey ...
lRetCode := RegQueryInfoKey(hSubKey, 0, 0, 0, @dwSubKeyCnt, @dwMaxSubKey,
0, @dwValueCnt, @dwMaxValueName, @dwMaxValueData, 0, 0);
if (lRetCode <> ERROR_SUCCESS) then
goto cleanup;
// enumerate the subkeys and call RegTreeWalk() recursivly
getmem(pszKeyName, MAX_PATH + 1);
for I := 0 to dwSubKeyCnt - 1 do // Iterate
begin
lRetCode := RegEnumKey(hSubKey, i, pszKeyName, MAX_PATH + 1);
if (lRetCode = ERROR_SUCCESS) then
begin
RegSetPrivilege(hSubKey, pszKeyName, pSD, TRUE);
end
else if (lRetCode = ERROR_NO_MORE_ITEMS) then
begin
break;
end;
end;
freemem(pszKeyName);
end;
bRet := TRUE; // indicate success
cleanup:
if (hSubKey <> 0) then
begin
RegCloseKey(hSubKey);
end;
result := bRet;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
pNewSD: PSecurityDescriptor;
//pOldSD: PChar ;
pOldSD: PSecurityDescriptor;
pDacl: PACL;
pASid: PSID;
szSid: array[0..255] of char;
S, sKey, sBaseKey, sUserName: string;
szKey, szBaseKey: array[0..255] of char;
iRet: integer;
dwRet: dword;
dwSize: DWORD;
szUserName: PChar;
begin
pDacl := nil;
pASid := nil;
if GetUserSid(pASid) then
begin
GetSidString(pASid, szSid);
s := strpas(szSid);
Memo1.Lines.Add(s);
sKey := 'Software/Microsoft/Protected Storage System Provider/';
sKey := sKey + s;
StrPCopy(szKey, sKey);
Memo1.Lines.Add(sKey);
sBaseKey := sKey;
StrPCopy(szBaseKey, sBaseKey);
if GetOldSD(HKEY_CURRENT_USER, szBaseKey, pOldSD) then
Memo1.Lines.Add('Call GetOldSD() OK ')
else
Memo1.Lines.Add('Call GetOldSD() Fail ');
GetMem(pNewSD, Sizeof(SECURITY_DESCRIPTOR));//FreeMem
if CreateNewSD(pASid, pNewSD, pDacl) then
begin
Memo1.Lines.Add('Call CreateNewSD() OK ');
StrPCopy(szKey, sKey);
RegSetPrivilege(HKEY_CURRENT_USER, szKey, pNewSD, FALSE);
sKey := sKey + '/Data';
StrPCopy(szKey, sKey);
RegSetPrivilege(HKEY_CURRENT_USER, szKey, pNewSD, FALSE);
sKey := sKey + '/e161255a-37c3-11d2-bcaa-00c04fd929db';
StrPCopy(szKey, sKey);
RegSetPrivilege(HKEY_CURRENT_USER, szKey, pNewSD, FALSE);
//dwRet := SHDeleteKey(HKEY_CURRENT_USER, szKey);
iRet := RegDeleteValue(HKEY_CURRENT_USER, szKey);
end
else
Memo1.Lines.Add('Call CreateNewSD() Fail ');
if (pDacl <> nil) then
HeapFree(GetProcessHeap(), 0, pDacl);
//restore old SD
if (pOldSD <> nil) then
begin
RegSetPrivilege(HKEY_CURRENT_USER, szBaseKey,
pOldSD, FALSE);
dispose(pOldSD);
end;
if (pASid <> nil) then
HeapFree(GetProcessHeap(), 0, pASid);
end;
FreeMem(pNewSD);
end;
end.