SJohnson
asked on
Using DeviceIOControl
Hi all,
This one is tricky. We need to know how to use the DeviceIOControl function to retrieve the starting cluster of a file.
We have the procedure working perfectly in MS VC 5, but it will not work in D4. Here's what we have so far:
const
VWIN32_DIOC_DOS_IOCTL = 1;
implementation
{$R *.DFM}
function drive_lock(hDevice:HFILE;d rive : integer; lock_level : integer; permission : integer):BOOLEAN;
type
dioc_regs = record
reg_EBX,
reg_EDX,
reg_ECX,
reg_EAX,
reg_EDI,
reg_ESI,
reg_Flags : Integer;
end;
var
regs : ^dioc_regs;
fResult : boolean;
cb : DWord;
begin
GetMem(Regs, SizeOf(regs));
regs.reg_EAX := $440d;
regs.reg_EBX := drive or (lock_level shl 8);
regs.reg_ECX := $084a;
regs.reg_EDX := permission;
regs.reg_Flags := $0001;
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
regs,SizeOf(regs),
regs,SizeOf(regs),
cb,
Nil);
if (not(fResult) or ((regs.reg_Flags and 1)=1)) then
Result := FALSE
else
Result := TRUE;
end;
function drive_unlock(hDevice:HFILE ;drive : integer):BOOLEAN;
type
dioc_regs = packed record
reg_EBX : integer;
reg_EDX : integer;
reg_ECX : integer;
reg_EAX : integer;
reg_EDI : integer;
reg_ESI : integer;
reg_Flags : integer;
end;
var
regs : ^dioc_regs;
fResult : boolean;
cb : dword;
begin
Regs := NIL;
regs.reg_EAX := $440d;
regs.reg_EBX := drive;
regs.reg_ECX := $086a;
regs.reg_Flags := $0001;
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
regs,SizeOf(regs),
regs,SizeOf(regs),
cb,
Nil);
if (not(fResult) or ((regs.reg_Flags and 1)=1)) then
result := FALSE
else
Result := TRUE;
end;
function get_cluster(hDevice:HFILE; filename : PChar):integer;
type
dioc_regs = packed record
reg_EBX : integer;
reg_EDX : integer;
reg_ECX : integer;
reg_EAX : integer;
reg_EDI : integer;
reg_ESI : integer;
reg_Flags : integer;
end;
var
regs : ^dioc_regs;
fResult : boolean;
cb : dword;
begin
Regs := NIL;
GetMem(Regs, SizeOf(Regs));
regs.reg_EAX := $440d;
regs.reg_EBX := 0;
regs.reg_ECX := $0871;
regs.reg_EDX := DWord(filename);
regs.reg_Flags := $0001;
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
regs,SizeOf(regs),
regs,SizeOf(regs),
cb,
Nil);
if (not(fResult) or ((regs.reg_Flags and 1)=1)) then
Result := 0
else
Result := ((regs.reg_EAX and $ffff) or ((regs.reg_EDX and $ffff) shl 16));
end;
procedure TForm1.Button1Click(Sender : TObject);
var
hDevice : HFILE;
drive : integer;
Ps: Integer;
P: PSecurityAttributes;
begin
drive := 2;
P := NIL;
hDevice := CreateFile('\\.\vwin32',
0,0, P,0,FILE_FLAG_DELETE_ON_CL OSE,0);
if (not(drive_lock(hDevice,dr ive,1,1))) then
ShowMessage('failed lock')
else begin
MessageBox(0,'locked','Sys tem',0);
ps := get_cluster(hDevice,'c:\au toexec.bat ');
if (ps = 0) then
MessageBox(0,'failed to get cluster','System',0)
else begin
//print out the cluster from pos
end;
if (not(drive_unlock(hDevice, drive)))th en
MessageBox(0,'failed to unlock','System',0)
else
MessageBox(0,'unlocked','S ystem',0);
end;
CloseHandle(hDevice);
end;
end.
I dont know if we have done something wrong here or not, but we are just about to give up (hence the large amounts of points).
To do what we want to do, we first need to lock the drive, then retrieve the cluster number, then unlock the drive again.
I really need this answered ASAP. Any help at all would be greatfully appreciated.
Code or examples can be posted directly to me at stuartj@futureschool.com.a u
Many thanks,
Stuart Johnson.
This one is tricky. We need to know how to use the DeviceIOControl function to retrieve the starting cluster of a file.
We have the procedure working perfectly in MS VC 5, but it will not work in D4. Here's what we have so far:
const
VWIN32_DIOC_DOS_IOCTL = 1;
implementation
{$R *.DFM}
function drive_lock(hDevice:HFILE;d
type
dioc_regs = record
reg_EBX,
reg_EDX,
reg_ECX,
reg_EAX,
reg_EDI,
reg_ESI,
reg_Flags : Integer;
end;
var
regs : ^dioc_regs;
fResult : boolean;
cb : DWord;
begin
GetMem(Regs, SizeOf(regs));
regs.reg_EAX := $440d;
regs.reg_EBX := drive or (lock_level shl 8);
regs.reg_ECX := $084a;
regs.reg_EDX := permission;
regs.reg_Flags := $0001;
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
regs,SizeOf(regs),
regs,SizeOf(regs),
cb,
Nil);
if (not(fResult) or ((regs.reg_Flags and 1)=1)) then
Result := FALSE
else
Result := TRUE;
end;
function drive_unlock(hDevice:HFILE
type
dioc_regs = packed record
reg_EBX : integer;
reg_EDX : integer;
reg_ECX : integer;
reg_EAX : integer;
reg_EDI : integer;
reg_ESI : integer;
reg_Flags : integer;
end;
var
regs : ^dioc_regs;
fResult : boolean;
cb : dword;
begin
Regs := NIL;
regs.reg_EAX := $440d;
regs.reg_EBX := drive;
regs.reg_ECX := $086a;
regs.reg_Flags := $0001;
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
regs,SizeOf(regs),
regs,SizeOf(regs),
cb,
Nil);
if (not(fResult) or ((regs.reg_Flags and 1)=1)) then
result := FALSE
else
Result := TRUE;
end;
function get_cluster(hDevice:HFILE;
type
dioc_regs = packed record
reg_EBX : integer;
reg_EDX : integer;
reg_ECX : integer;
reg_EAX : integer;
reg_EDI : integer;
reg_ESI : integer;
reg_Flags : integer;
end;
var
regs : ^dioc_regs;
fResult : boolean;
cb : dword;
begin
Regs := NIL;
GetMem(Regs, SizeOf(Regs));
regs.reg_EAX := $440d;
regs.reg_EBX := 0;
regs.reg_ECX := $0871;
regs.reg_EDX := DWord(filename);
regs.reg_Flags := $0001;
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
regs,SizeOf(regs),
regs,SizeOf(regs),
cb,
Nil);
if (not(fResult) or ((regs.reg_Flags and 1)=1)) then
Result := 0
else
Result := ((regs.reg_EAX and $ffff) or ((regs.reg_EDX and $ffff) shl 16));
end;
procedure TForm1.Button1Click(Sender
var
hDevice : HFILE;
drive : integer;
Ps: Integer;
P: PSecurityAttributes;
begin
drive := 2;
P := NIL;
hDevice := CreateFile('\\.\vwin32',
0,0, P,0,FILE_FLAG_DELETE_ON_CL
if (not(drive_lock(hDevice,dr
ShowMessage('failed lock')
else begin
MessageBox(0,'locked','Sys
ps := get_cluster(hDevice,'c:\au
if (ps = 0) then
MessageBox(0,'failed to get cluster','System',0)
else begin
//print out the cluster from pos
end;
if (not(drive_unlock(hDevice,
MessageBox(0,'failed to unlock','System',0)
else
MessageBox(0,'unlocked','S
end;
CloseHandle(hDevice);
end;
end.
I dont know if we have done something wrong here or not, but we are just about to give up (hence the large amounts of points).
To do what we want to do, we first need to lock the drive, then retrieve the cluster number, then unlock the drive again.
I really need this answered ASAP. Any help at all would be greatfully appreciated.
Code or examples can be posted directly to me at stuartj@futureschool.com.a
Many thanks,
Stuart Johnson.
Be sure that Align Record Fields (Project/Options/Compiler) is unchecked. Otherwise your DIOC_REGS structure might be stored in memory in a way that DeviceIOControl can't recognise..
ASKER
Hi Blackman,
I just tried that, unfortunately it did not work. I still can not lock the drive.
Thanks for the suggestions though!
Stuart.
I just tried that, unfortunately it did not work. I still can not lock the drive.
Thanks for the suggestions though!
Stuart.
Is it the Drive_lock procedure that fails?
ASKER
Yep! Certainly is. The return of fResult (see code) is FALSE. And the regs.reg_Flags returns 1, so it is failing in both places.
Stu.
Stu.
Could you give me an example of how you call the drive_lock procedure so I can test it..
Hi there,
I think the problem is with the ID of the DRIVE. The drives starts from 1 so if you want to access something on C you should give
drive := 3;
please try and report it, though I have only NT OS(so I can not test it)
Regards, Igor
I think the problem is with the ID of the DRIVE. The drives starts from 1 so if you want to access something on C you should give
drive := 3;
please try and report it, though I have only NT OS(so I can not test it)
Regards, Igor
I've just studied the Win32 Help and I think that you have to implement the call in this way (note the @'s):
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
@regs,SizeOf(regs),
@regs,SizeOf(regs),
cb,
Nil);
fResult := DeviceIOControl(hDevice,
VWIN32_DIOC_DOS_IOCTL,
@regs,SizeOf(regs),
@regs,SizeOf(regs),
cb,
Nil);
something stupid ... you know lock only works when there is actually a disk or cd-rom in the drive... as I said, something very stupid but I wanted to let you know. Zif.
Hi Stuart,
unfortunately I have only NT, so that could will not work. If you have the Platform SDK from MS, you can trace all API calls from the Directory Snoop app with the tool APIMON.EXE. Just select ntdll.dll and kernel32.dll as known DLLs, enable tracing and you get all API calls in a trace file, including ALL PARAMETERS ! I think this would help you quite a bit...
.I love reverse engineering...
Slash/d003303
unfortunately I have only NT, so that could will not work. If you have the Platform SDK from MS, you can trace all API calls from the Directory Snoop app with the tool APIMON.EXE. Just select ntdll.dll and kernel32.dll as known DLLs, enable tracing and you get all API calls in a trace file, including ALL PARAMETERS ! I think this would help you quite a bit...
.I love reverse engineering...
Slash/d003303
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
It looks like you just implemented my last comment...
Hey guys
drive := ord('C')-ord('A')+1; = 3 which as I said before!!!!
Cheers ;-) no problem in any case
drive := ord('C')-ord('A')+1; = 3 which as I said before!!!!
Cheers ;-) no problem in any case
ASKER
Madshi,
Well done!! I havent had a look at what you did, but it worked perfectly! Enjoy your points! :)
Stu.
Well done!! I havent had a look at what you did, but it worked perfectly! Enjoy your points! :)
Stu.
Just for your information,
what is WRONG IS DRIVE PARAMETER...
so if you want to do it on DRIVE D set drive = 4. In your original code it is 2 which means drive B. All of you please make a note of this there is no magic in that and there is only single faulty line in the original code which is drive = 2(should be drive =3)...
your pal
igor
what is WRONG IS DRIVE PARAMETER...
so if you want to do it on DRIVE D set drive = 4. In your original code it is 2 which means drive B. All of you please make a note of this there is no magic in that and there is only single faulty line in the original code which is drive = 2(should be drive =3)...
your pal
igor
Sorry @regs should also be canged so BlackMan is also right.
ASKER
Hi Igore,
FYI, I accidently changed the drive from 3 to 2 yesterday before posting. It had always been set to 3 (C:), therefore it was my mistake.
But something else has changed, it it has fixed what we where doing. As I said, I didnt have a chance to look through it, but I will early next week. I think it had something to do with pointer assignments.
Thanks for your input anyway!
Stuart.
FYI, I accidently changed the drive from 3 to 2 yesterday before posting. It had always been set to 3 (C:), therefore it was my mistake.
But something else has changed, it it has fixed what we where doing. As I said, I didnt have a chance to look through it, but I will early next week. I think it had something to do with pointer assignments.
Thanks for your input anyway!
Stuart.
Hmm, inter, guess we'll have to stop posting comments, huh? :-)
BlackMan, inter,
sorry again, if I only implemented your comments. However, I didn't look at them before I sent my answer. :-)
Regards, Madshi.
sorry again, if I only implemented your comments. However, I didn't look at them before I sent my answer. :-)
Regards, Madshi.
O.k., that sounds not so nice...
I did look at your comments, but I did not read them in detail. When I found that there was no complete solution, I just compared stu's sources with my own (I'm using DeviceIOControl myself) - not with your comments.
But if you think you deserve some points, too: Just write me how much points you want and I will post a dummy question for you. :-)
Madshi.
I did look at your comments, but I did not read them in detail. When I found that there was no complete solution, I just compared stu's sources with my own (I'm using DeviceIOControl myself) - not with your comments.
But if you think you deserve some points, too: Just write me how much points you want and I will post a dummy question for you. :-)
Madshi.
ASKER
Stuart.