C++代码转换到Delphi代码后出现问题。(200分)

  • 主题发起人 主题发起人 NetSword
  • 开始时间 开始时间
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.
 
代码太长,看得头晕。
大概看来,你对指计的变换不够理解,多看一下C程序,在转换方面应注意类型方面的
相等,与返回值的方法。
 
你指的错误位置指对了吗?AddAce的定义都没有,我们怎么判断错在哪里啊?
 
提到错误的地方我觉得没有错,但是就是出错了,难道C++会有一些语法转换到Delphi时
无法转换么?

我用的是Delphi6 update2,在Windows单元中6030和28220行都有定义啊。
function AddAce; external advapi32 name 'AddAce';
 
不好意思,没注意看。
这段代码的作用是?
由于是运行时错误,调试起来比较麻烦。建议把可运行的C++代码贴出来,以便比较。
 
我已经编译通过了上面的C++文件。结果运行到第二个if (!AddAce())的时候,返回的也是
true,只不过那C++代码没有像你的Delphi代码那样抛出异常。
 
to Sachow:
这段代码的作用是: 清除IE表单自动完成历史记录

非常感谢你的帮助!错误出现在最关键的地方,如果这条语句通过了,这部分程序代码就应该ok了。
我也是感到很奇怪的,但是我实在在找不出我到底错在哪儿?我也在怀疑是不是有些C++语法
在转到Delphi时会不可用,不知道你是否遇到过这样的问题?
 
真的没有人知道是怎么回事么?高手们,抽空帮忙看看啊。
 
找到问题了,你错在用Move的地方,可以有两种解决方法:
1、以强制类型转换代替内存拷贝
pACE^.SidStart := DWORD(pSystemSid^);
2、仍使用内存拷贝,但要注意参数
Move(pSystemSid^, pACE^.SidStart, GetLengthSid(pSystemSid));

你的两个用Move的地方都应该改。
 
谢谢,我试一下先。:-)
 
非常感谢Sachow,谢谢你的帮助!!!
你真是个大好人啊。:-)
 
后退
顶部