win64下的netwkstagetinfo Access_violation
我有代码,在 WIN32 下可以正常工作很多年。但是昨天,在 WIN64 下编译后,在尝试获取 wki100_langroup 字段时,我遇到了奇怪的 ACCESS_VIOLATION 错误。这段代码哪里错了? (计算机不在域中,在 Delphi 11 调试窗口中我可以看到,该字段为空)
const
NERR_SUCCESS = 0;
type
WKSTA_INFO_100 = record
wki100_platform_id: DWORD;
wki100_computername: LPWSTR;
wki100_langroup: LPWSTR;
wki100_ver_major: DWORD;
wki100_ver_minor: DWORD;
end;
LPWKSTA_INFO_100 = ^WKSTA_INFO_100;
function NetWkstaGetInfo(ServerName: LPWSTR; Level: DWORD; var BufPtr: Pointer): DWORD; stdcall;
external 'netapi32.dll' Name 'NetWkstaGetInfo';
function GetDomain: string;
var
PBuf: Pointer;
Res: Integer;
begin
Result := '';
Res := NetWkstaGetInfo(nil, 100, PBuf);
if (Res = NERR_Success) then begin
Result := LPWKSTA_INFO_100(PBuf)^.wki100_langroup; // ACCESS_VIOLATION here
if Assigned(PBuf) then
NetApiBufferFree(PBuf);
end;
end;
更新: 将指针更改为 PByte 后,我有相同的异常
function NetWkstaGetInfo(ServerName: LPWSTR; Level: DWORD; BufPtr: PByte): DWORD; stdcall;
external 'netapi32.dll' Name 'NetWkstaGetInfo';
function GetDomain: string;
var
PBuf: PByte;
Res: Integer;
begin
Result := '';
Res := NetWkstaGetInfo(nil, 100, @PBuf);
if (Res = NERR_Success) then begin
Result := LPWKSTA_INFO_100(PBuf)^.wki100_langroup; // ACCESS_VIOLATION here
if Assigned(PBuf) then
NetApiBufferFree(PBuf);
end;
end;
I'm have code, which works fine during many years under WIN32. But yesterday, after compiling under WIN64 I'm got strange ACCESS_VIOLATION error when trying get wki100_langroup field. Where wrong this code? (Computer not in domain and in Delphi 11 debug window I can see, that this field is empty)
const
NERR_SUCCESS = 0;
type
WKSTA_INFO_100 = record
wki100_platform_id: DWORD;
wki100_computername: LPWSTR;
wki100_langroup: LPWSTR;
wki100_ver_major: DWORD;
wki100_ver_minor: DWORD;
end;
LPWKSTA_INFO_100 = ^WKSTA_INFO_100;
function NetWkstaGetInfo(ServerName: LPWSTR; Level: DWORD; var BufPtr: Pointer): DWORD; stdcall;
external 'netapi32.dll' Name 'NetWkstaGetInfo';
function GetDomain: string;
var
PBuf: Pointer;
Res: Integer;
begin
Result := '';
Res := NetWkstaGetInfo(nil, 100, PBuf);
if (Res = NERR_Success) then begin
Result := LPWKSTA_INFO_100(PBuf)^.wki100_langroup; // ACCESS_VIOLATION here
if Assigned(PBuf) then
NetApiBufferFree(PBuf);
end;
end;
Update:
After changing Pointer to PByte I have the same exception
function NetWkstaGetInfo(ServerName: LPWSTR; Level: DWORD; BufPtr: PByte): DWORD; stdcall;
external 'netapi32.dll' Name 'NetWkstaGetInfo';
function GetDomain: string;
var
PBuf: PByte;
Res: Integer;
begin
Result := '';
Res := NetWkstaGetInfo(nil, 100, @PBuf);
if (Res = NERR_Success) then begin
Result := LPWKSTA_INFO_100(PBuf)^.wki100_langroup; // ACCESS_VIOLATION here
if Assigned(PBuf) then
NetApiBufferFree(PBuf);
end;
end;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
症状表明,其他一些代码更改了
wksta_info_100
记录类型的默认记录对齐。在没有影响的32位编译器下,由于记录中的所有值也为32位,因此即使指定了其他比对大小,它们也将正确对齐。
在64位编译器
DWord
下是32位,而LPWSTR为64位。使用默认的8个字节对齐,这意味着将在wki100_platform_id
之后插入4个填充字节。如果使用其他一些对齐,则以下字段将不在正确的位置。要纠正此问题,您需要在键入声明之前指定8个字节对齐
{$ a8}
。The symptoms suggest that some other code changed default record alignment for
WKSTA_INFO_100
record type.Under 32-bit compiler that wouldn't have an impact because all values in the record are also 32-bit therefore they will be correctly aligned even if other alignment size is specified.
Under 64-bit compiler
DWORD
is 32-bit, while LPWSTR is 64-bit. With default 8 byte alignment that means there will be 4 padding bytes inserted afterwki100_platform_id
. If some other alignment is used following fields will not be at correct positions.To correct this you need to specify 8 byte alignment
{$A8}
before type declaration.