coverting physical drive to logical drive how to?
-
- Posts: 87
- Joined: Thu Jun 02, 2005 3:46 am
coverting physical drive to logical drive how to?
Need to convert \Device\HarddiskVolume1\WINDOWS\system32\calc.exe
to C:\windows\system32\calc.exe
I'm hooking createsection btw
Thanks!
to C:\windows\system32\calc.exe
I'm hooking createsection btw
Thanks!
-
- Posts: 87
- Joined: Thu Jun 02, 2005 3:46 am
Anyone want to take a stab at converting this to a function that you can feed in the symbolic link (device\hardiskvolume) and returns the drive letter + path?? I'm just not that savy in delphi yet. I will keep trying though
Code: Select all
Procedure MapSymbolicLinks(const LV: TListView);
const mem_sz = 16000;
var
p: PChar;
sz, i: cardinal;
buf: array [0..MAX_PATH] of char;
sl: TStringList;
begin
sl := TStringList.Create();
try
GetMem(p, mem_sz);
ZeroMemory(@buf, sizeof(buf));
sz := QueryDosDevice(nil, @p^, mem_sz);
for i := 1 to sz do
if p[i] = #0 then
p[i] := #10;
sl.CommaText := p;
lv.Items.BeginUpdate();
for i := 0 to sl.count-1 do
begin
with
Lv.Items.Add() do
begin
Caption := sl[i];
QueryDosDevice(@PChar(sl[i])^, @buf, sizeof(buf));
with Subitems do
Add(buf);
end;
end;
finally
FreeMem(p);
sl.Free;
Lv.Items.EndUpdate();
end;
end;
The least painful way is the create a second string list object and make it function as a hash table with name = value pairs so that you can just feed in the symbolic name and return the logical name.
Enjoy.
--Iconic
Enjoy.
Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const mem_sz = 16000;
var
p: PChar;
sz, i: cardinal;
buf: array [0..MAX_PATH] of char;
sl, sl2: TStringList;
begin
if SymLink = '' then
Exit;
Sl := TStringList.Create();
Sl2 := TStringList.Create();
try
GetMem(p, mem_sz);
ZeroMemory(@buf, sizeof(buf));
sz := QueryDosDevice(nil, @p^, mem_sz);
for i := 1 to sz do
if (p[i] = #0) then
p[i] := #10;
Sl.CommaText := p;
for i := 0 to Sl.Count-1 do
begin
QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
Sl2.values[buf]:= Sl[i];
end;
if (SymLink[1] <> '\') then
result := Sl2.Values['\' + SymLink]
else
result := Sl2.Values[SymLink]
finally
FreeMem(p);
Sl.Free;
Sl2.Free;
end;
end;
The least painful way is the create a second string list object and make it function as a hash table with name = value pairs so that you can just feed in the symbolic name and return the logical name.
Enjoy.
If you're a performance freak then after the call to QueryDosDevice() in the last "for" loop, check to see if buf = symlink, set the result to sl and Break the loop, that way the entire list doesn't need to be filled.
--Iconic
Enjoy.
Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const mem_sz = 16000;
var
p: PChar;
sz, i: cardinal;
buf: array [0..MAX_PATH] of char;
sl, sl2: TStringList;
begin
result := '';
if SymLink = '' then
Exit;
Sl := TStringList.Create();
Sl2 := TStringList.Create();
try
GetMem(p, mem_sz);
ZeroMemory(@buf, sizeof(buf));
sz := QueryDosDevice(nil, @p^, mem_sz);
for i := 1 to sz do
if (p[i] = #0) then
p[i] := #10;
Sl.CommaText := p;
for i := 0 to Sl.Count-1 do
begin
QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
Sl2.values[buf]:= Sl[i];
end;
if (SymLink[1] <> '\') then
result := Sl2.Values['\' + SymLink]
else
result := Sl2.Values[SymLink]
finally
FreeMem(p);
Sl.Free;
Sl2.Free;
end;
end;
If you're a performance freak then after the call to QueryDosDevice() in the last "for" loop, check to see if buf = symlink, set the result to sl and Break the loop, that way the entire list doesn't need to be filled.
--Iconic
no problem
I hooked NtCreateSection() last month, or maybe it was in late Jul. can't remember. I have posted some test code on the forum that u can look at it if u so desire.
Also, that hash table idea is handy for mapping between logical and symbolic link names and I usually create a shared memory section that holds the table mappings so that I can look them up easily and save my program from allocating a 16k buffer and looping twice everytime I want to look up a name equivalent. If you end up just calling the function multiple times and you want "real time" results I'd suggest you break the loop and disregard the hash table idea, on my machine it takes approx. 33 ms. to complete, depending on which symbolic name I feed in, which might be the last name gathered when the loop finishes and the list fills. breaking the loop with the equivalent name takes 0 - 5 ms for me. So if you're calling it repeatedly I'd suggest breaking the loop and not using the table. I use a table to avoid many function calls, function calls = cpu time and in NtCreateSection that could be a lot of calls.
optimized for you, since you're new to Delphi.
--Iconic
I hooked NtCreateSection() last month, or maybe it was in late Jul. can't remember. I have posted some test code on the forum that u can look at it if u so desire.
Also, that hash table idea is handy for mapping between logical and symbolic link names and I usually create a shared memory section that holds the table mappings so that I can look them up easily and save my program from allocating a 16k buffer and looping twice everytime I want to look up a name equivalent. If you end up just calling the function multiple times and you want "real time" results I'd suggest you break the loop and disregard the hash table idea, on my machine it takes approx. 33 ms. to complete, depending on which symbolic name I feed in, which might be the last name gathered when the loop finishes and the list fills. breaking the loop with the equivalent name takes 0 - 5 ms for me. So if you're calling it repeatedly I'd suggest breaking the loop and not using the table. I use a table to avoid many function calls, function calls = cpu time and in NtCreateSection that could be a lot of calls.
optimized for you, since you're new to Delphi.
Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const mem_sz = 16000;
var
p: PChar;
sz, i: cardinal;
buf: array [0..MAX_PATH] of char;
sl: TStringList;
begin
result := '';
if SymLink = '' then
Exit;
Sl := TStringList.Create();
try
GetMem(p, mem_sz);
ZeroMemory(@buf, sizeof(buf));
sz := QueryDosDevice(nil, @p^, mem_sz);
for i := 1 to sz do
if (p[i] = #0) then
p[i] := #10;
Sl.CommaText := p;
for i := 0 to Sl.Count-1 do
begin
QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
if (lstrcmpi(@PChar(SymLink)^, @buf) = 0) then
begin
result := Sl[i];
Break;
end;
end;
finally
FreeMem(p);
Sl.Free();
end;
end;
Why are you writing: @PChar(Sl)^ ?
Its the same as PChar(Sl)...
Its the same as PChar(Sl)...
Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
function GetMemNeeded: Integer;
var
dwSize: DWord;
pTargetString: PChar;
begin
dwSize := 1;
repeat
pTargetString := StrAlloc(dwSize);
Result := QueryDosDevice(nil,pTargetString,dwSize);
StrDispose(pTargetString);
dwSize := dwSize+dwSize;
until Result <> 0;
end;
var
pTargetString: PChar;
buf: PChar;
dwMemNeeded: Integer;
dwFrom: Integer;
pDevice: PChar;
I: Integer;
begin
Result := '';
dwMemNeeded := GetMemNeeded;
pTargetString := StrAlloc(dwMemNeeded);
buf := StrAlloc(MAX_PATH);
dwMemNeeded := QueryDosDevice(nil, pTargetString, dwMemNeeded);
for i := 0 to dwMemNeeded-1 do
begin
if pTargetString[i] = '#' then
pTargetString[i] := #0;
end;
dwFrom := 0;
while (dwFrom < dwMemNeeded) do
begin
pDevice := PChar(@pTargetString[dwFrom]);
QueryDosDevice(pDevice, buf, MAX_PATH);
if (buf = SymLink) then
Result := pDevice;
dwFrom := dwFrom+Length(pDevice)+1;
end;
StrDispose(buf);
StrDispose(pTargetString);
end;
The way I have it is fine, it's identical to a simple PChar typecast as u have shown and the reason I do it is because I have always written it like this so it's habitual. By the way, StrAlloc() is somewhat deprecated so I could also wonder why one would use it here, in your code. It's mainly used for backwards compatibility. There's also more than 1 way to do something.
--Iconic
--Iconic
Result empty
Why, it's doesn't work for me? The result it's empty. I'm using this code to get the device string:
And this:
Anyone can help me, please?
Code: Select all
function FileNameFromFileHandle(const hF: HFILE): string; stdcall;
type
UNICODE_STRING = packed record
len: Word;
maxlen: Word;
buf: PWideChar;
end;
OBJECT_NAME_INFORMATION = record
name: UNICODE_STRING;
end;
const
ONI = 1;
UNICODE_MAX_PATH = MAX_PATH *sizeof(WCHAR);
var
ret: Integer;
status: Integer;
pONI: ^OBJECT_NAME_INFORMATION;
ZwQueryObject: TZwQueryObject;
begin
result := '';
@ZwQueryObject := GetProcAddress(GetModuleHandleW('ntdll.dll'), 'ZwQueryObject');
if @ZwQueryObject = nil then
Exit;
GetMem(pONI, UNICODE_MAX_PATH);
ZeroMemory(pOni, sizeof(OBJECT_NAME_INFORMATION));
status := ZwQueryObject(hF, ONI, @pONI^, UNICODE_MAX_PATH, ret);
if NT_SUCCESS(status) then
result := WideToAnsiEx(@pONI^.name.buf^);
FreeMem(pONI);
end;
Code: Select all
function LogicFromSymbolic(const SymLink: string): string;
const
mem_sz = 16000;
var
p: PChar;
sz, i: cardinal;
buf: array [0..MAX_PATH] of char;
sl: TStringList;
begin
result := '';
if SymLink = '' then Exit;
Sl := TStringList.Create();
try
GetMem(p, mem_sz);
ZeroMemory(@buf, sizeof(buf));
sz := QueryDosDevice(nil, @p^, mem_sz);
for i := 1 to sz do
if (p[i] = #0) then
p[i] := #10;
Sl.CommaText := p;
MsgOk(IntToStr(SL.Count));
for i := 0 to Sl.Count-1 do
begin
QueryDosDevice(@PChar(Sl[i])^, @buf, sizeof(buf));
if (lstrcmpi(@PChar(SymLink)^, @buf) = 0) then
begin
result := Sl[i];
Break;
end;
end;
finally
FreeMem(p);
Sl.Free();
end;
end;