Article View: pl.comp.lang.delphi
Article #334647Problem z GetLastError i DeviceIoControl
From: Jan Drawski
Date: Mon, 09 Jan 2012 23:01
Date: Mon, 09 Jan 2012 23:01
112 lines
4433 bytes
4433 bytes
Windows XP i Turbo Delphi. Poniższy przykład (działający) tylko obrazuje
problem, który mam w trochę innym kodzie.
Problem jest gdy jest taka kolejność:
DeviceIoControl
GetLastError
Dodanie informacji o błędzie lub sukcesie do memo
DeviceIoControl
GetLastError
Dodanie informacji o błędzie lub sukcesie do memo
Pomimo poprawnego wykonania dwa razy DeviceIoControl za drugim razem
jest błąd 5 ERROR_ACCESS_DENIED.
Jeżeli zmieni się kolejność na
DeviceIoControl
GetLastError
DeviceIoControl
GetLastError
Dodanie informacji o błędzie lub sukcesie do memo
Dodanie informacji o błędzie lub sukcesie do memo
to w obu przypadkach jest sukces.
W poniższym przykładzie jest dwa razy sukces i raz błąd mimo poprawnego
wykonania wszystkich takich samych funkcji.
Dlaczego tak jest? Co można zrobić aby za każdym razem otrzymać poprawną
wartość GetLastError?
procedure TForm1.Button1Click(Sender: TObject);
function GetLD(Drive: Char): Cardinal;
var
Buffer : String;
begin
Buffer := Format('\\.\%s:',[Drive]);
Result := CreateFile(PChar(Buffer),GENERIC_READ or
GENERIC_WRITE,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
If Result = INVALID_HANDLE_VALUE Then
begin
Result :=
CreateFile(PChar(Buffer),GENERIC_READ,FILE_SHARE_READ,nil,OPEN_EXISTING,0,0);
end;
end;
const
FILE_DEVICE_DISK = $00000007;
METHOD_BUFFERED = 0;
FILE_ANY_ACCESS = 0;
IOCTL_DISK_BASE = FILE_DEVICE_DISK;
IOCTL_VOLUME_BASE = DWORD('V');
IOCTL_DISK_GET_LENGTH_INFO = $80070017;
IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS = ((IOCTL_VOLUME_BASE shl 16) or
(FILE_ANY_ACCESS shl 14) or (0 shl 2) or METHOD_BUFFERED);
type
TDiskExtent = record
DiskNumber: Cardinal;
StartingOffset: Int64;
ExtentLength: Int64;
end;
DISK_EXTENT = TDiskExtent;
PDiskExtent = ^TDiskExtent;
TVolumeDiskExtents = record
NumberOfDiskExtents: Cardinal;
Extents: array[0..0] of TDiskExtent;
end;
VOLUME_DISK_EXTENTS = TVolumeDiskExtents;
PVolumeDiskExtents = ^TVolumeDiskExtents;
var
LD : DWORD;
DiskExtents : PVolumeDiskExtents;
BytesReturned : Cardinal;
LastErr, LastErr1, LastErr2: Cardinal;
begin
LD := GetLD('D');
DiskExtents := AllocMem(Max_Path);
ZeroMemory(DiskExtents, Max_Path);
DeviceIOControl(LD, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil, 0,
DiskExtents, Max_Path, BytesReturned, nil);
LastErr := GetLastError;
ZeroMemory(DiskExtents, Max_Path);
DeviceIOControl(LD, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil, 0,
DiskExtents, Max_Path, BytesReturned, nil);
LastErr1 := GetLastError;
case LastErr of
0: memo1.Lines.Add('Sukces');
5: memo1.Lines.Add('Błąd dostępu')
else
memo1.Lines.Add('Błąd: ' + IntToStr(LastErr));
end;
case LastErr1 of
0: memo1.Lines.Add('Sukces');
5: memo1.Lines.Add('Błąd dostępu') //ERROR_ACCESS_DENIED
else
memo1.Lines.Add('Błąd: ' + IntToStr(LastErr));
end;
ZeroMemory(DiskExtents, Max_Path);
DeviceIOControl(LD, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, nil, 0,
DiskExtents, Max_Path, BytesReturned, nil);
LastErr2 := GetLastError;
case LastErr2 of
0: memo1.Lines.Add('Sukces');
5: memo1.Lines.Add('Błąd dostępu')
else
memo1.Lines.Add('Błąd: ' + IntToStr(LastErr));
end;
CloseHandle(LD);
FreeMem(DiskExtents);
end;
--
Pozdrawiam
Jan Drawski
Technical Details
Message-ID:
<jefrl9$636$1@inews.gazeta.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!not-for-mailShow Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.gazeta.pl!not-for-mail From: Jan Drawski <sdfhdfhdf@op.pl> Newsgroups: pl.comp.lang.delphi Subject: Problem z GetLastError i DeviceIoControl Date: Tue, 10 Jan 2012 00:01:57 +0100 Organization: "Portal Gazeta.pl -> http://www.gazeta.pl" Lines: 112 Message-ID: <jefrl9$636$1@inews.gazeta.pl> NNTP-Posting-Host: apn-77-115-86-149.dynamic.gprs.plus.pl Mime-Version: 1.0 X-Trace: inews.gazeta.pl 1326150121 6246 77.115.86.149 (9 Jan 2012 23:02:01 GMT) X-Complaints-To: usenet@agora.pl NNTP-Posting-Date: Mon, 9 Jan 2012 23:02:01 +0000 (UTC) X-User: miszek23 User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; pl-PL; rv:1.9.1.16) Gecko/20101125 Thunderbird/3.0.11 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit