VB/DELPHI: ZwQueryInformationFile в потоке

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
M.A.R.K
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 68
Зарегистрирован: 11.11.2007 (Вс) 11:50
Откуда: Иркутск

VB/DELPHI: ZwQueryInformationFile в потоке

Сообщение M.A.R.K » 04.03.2008 (Вт) 9:39

Delphi:
Код: Выделить всё
library ssxp_handle;
uses
  SysUtils,
  Classes,
  windows;

{$R *.res}
type
pIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
IO_STATUS_BLOCK = Packed Record
  Status : Cardinal;
  Information : DWORD;
end;
TFNI = Packed Record
  FileNameLength : DWORD;
  FileName : array [0..MAX_PATH - 1] of WideChar;
end;

function ZwQueryInformationFile(hFile : THandle;
  IOB : pIO_STATUS_BLOCK; FileInformation : Pointer;
  Length : DWORD;FileInformationClass : DWORD): Cardinal; stdcall; external 'ntdll.dll';

function Test(ParamHandle : Pointer) : DWORD;stdcall;
var
  IO_S_B : IO_STATUS_BLOCK;
  FNI : TFNI;
  Handle : THandle;
begin
  Handle := THandle(ParamHandle);
  ZeroMemory(@FNI,SizeOf(FNI));
  ZwQueryInformationFile(Handle,@IO_S_B,@FNI,SizeOf(FNI),9);
end;
function hFile_Test(ParamHandle : THandle;ParamProcessId : DWORD) : BOOL; stdcall;
var
  hThread : THandle;
  Handle : THandle;
  hProcess : THandle;
begin
  hProcess := OpenProcess(PROCESS_DUP_HANDLE,FALSE,ParamProcessId);
  if hProcess <> INVALID_HANDLE_VALUE then
  begin
    DuplicateHandle(hProcess,ParamHandle,GetCurrentProcess,@Handle,0,FALSE,DUPLICATE_SAME_ACCESS);
    hThread := CreateThread(nil,0,@Test,@Handle,0,PDWORD(0)^);
    Case WaitForSingleObject(hthread,50) of
    WAIT_TIMEOUT:
    begin
      TerminateThread(hThread,0);
      hFile_test := FALSE;
    end;
    WAIT_OBJECT_0:
    begin
      hFile_test := TRUE;
    end;
    end;
  end
  else
  begin
    hFile_test := FALSE;
  end;
end;
exports hFile_Test;
begin

end.

Visual Basic:
Код: Выделить всё
Declare Function hFile_Test Lib "c:\Test.dll" (ByVal dwHandle As Long, ByVal dwProcessId As Long) As Boolean
Sub GetHandles()
Dim TSize As Long
Dim SHI_Handles() As TSYSTEM_HANDLE_INFORMATION
Dim ReturnVariable As Long, ReturnVariable2 As Long
Dim mPtr As Long
Dim i As Long
Dim hThread As Long
Dim ThreadId As Long
Dim wfso As Long
Dim Current_hProcess As Long

TSize = 1000
Do
    mPtr = VirtualAlloc(0, TSize, MEM_COMMIT, PAGE_READWRITE)
    ReturnVariable = ZwQuerySystemInformation(SystemHandleInformation, mPtr, TSize, ReturnVariable2)
    If ReturnVariable = STATUS_INFO_LEGTH_MISMATCH Then
        Call VirtualFree(mPtr, TSize, MEM_DECOMMIT)
        TSize = TSize * 2
    Else
        Exit Do
    End If
Loop
Call CopyMemory(ByVal VarPtr(HandleCount), ByVal mPtr, 4)
ReDim SHI_Handles(HandleCount)
mPtr = mPtr + 4
Current_hProcess = GetCurrentProcess
For i = 0 To Int(HandleCount / 2)
    Call CopyMemory(ByVal VarPtr(SHI_Handles(i)), ByVal mPtr, 16)
    mPtr = mPtr + 16
    If SHI_Handles(i).ObjectTypeNumber = hFileType Then
        ReDim Preserve Handles(i)
        Handles(i).Handle = SHI_Handles(i).Handle
        Handles(i).ProcessID = SHI_Handles(i).ProcessID
            If hFile_Test(SHI_Handles(i).Handle, SHI_Handles(i).ProcessID) Then
                frmMain.List1.AddItem "yes yes yes yes yes"
            End If
        End If
    End If
Next
MsgBox f
Call VirtualFree(mPtr, TSize, MEM_DECOMMIT)
End Sub

Задача:
1) С помошью hFile_Test (VB) проверяю описатель на зависание в DLL. Т.к. пытался это сделать на VB, от чего летели одни ошибки...
В данном случае в List1 пищутся одни "yes yes yes yes yes", тоесть hFile_Test всегда возвращает TRUE, почему? :?
Посоветуйте, что мне изменить...
Примечание: Писал этот код целиком на Delphi, все работает, а совместно c VB не хочеть... :wink:
Заранее благодарен.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 04.03.2008 (Вт) 10:11

А если в твоем VB-шном коде (переделанном моем :wink: ) использовать ту ДЛЛ, которую я писал на асме, результат такой же?
А я все практикую лечение травами...

M.A.R.K
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 68
Зарегистрирован: 11.11.2007 (Вс) 11:50
Откуда: Иркутск

Сообщение M.A.R.K » 04.03.2008 (Вт) 10:21

Twister, неожидал, что это твой код. Ты настоящий спец... :)
Твою DLL я не пробовал вставлять.
Скажи, на глаз, в моем Delphi коде (сам писал :wink: ) есть ошибки?

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 04.03.2008 (Вт) 10:54

На глаз ни чего сказать не могу - посему и спрашиваю, пробовал ли юзать мою ДЛЛ.
Одно могу сказать - у меня все работает... :wink:
А я все практикую лечение травами...

M.A.R.K
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 68
Зарегистрирован: 11.11.2007 (Вс) 11:50
Откуда: Иркутск

Сообщение M.A.R.K » 06.03.2008 (Чт) 6:55

1) Twister, я подключал твою Асм-DLL, все работает...
2) Готовый рабочий код:
Delphi:
Код: Выделить всё
library ssxp_handle;
uses
  SysUtils,
  Classes,
  windows;

{$R *.res}
type
pTHandle = ^THandle;
pIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
IO_STATUS_BLOCK = Packed Record
  Status : Cardinal;
  Information : DWORD;
end;
TFNI = Packed Record
  FileNameLength : DWORD;
  FileName : array [0..MAX_PATH - 1] of WideChar;
end;

function ZwQueryInformationFile(hFile : THandle;
  IOB : pIO_STATUS_BLOCK; FileInformation : Pointer;
  Length : DWORD;FileInformationClass : DWORD): Cardinal; stdcall; external 'ntdll.dll';

function Test(ParamHandle : Pointer) : DWORD;stdcall;
var
  IO_S_B : IO_STATUS_BLOCK;
  FNI : TFNI;
  Handle : THandle;
begin
  Handle := pTHandle(ParamHandle)^;
  ZeroMemory(@FNI,SizeOf(TFNI));
  ZwQueryInformationFile(Handle,@IO_S_B,@FNI,MAX_PATH,9);
end;
function hFile_Test(ParamHandle : THandle) : BOOL; stdcall;
var
  hThread : THandle;
begin
  hThread := CreateThread(nil,0,@Test,@ParamHandle,0,PDWORD(0)^);
    Case WaitForSingleObject(hThread,50) of
    WAIT_TIMEOUT:
    begin
      TerminateThread(hThread,0);
      hFile_test := FALSE;
    end;
    WAIT_OBJECT_0:
    begin
      hFile_test := TRUE;
    end;
    end;
end;
exports hFile_Test;
begin

end.

Код: Выделить всё
Option Explicit

Declare Function ZwQuerySystemInformation Lib "ntdll.dll" (ByVal InformationClass As Long, ByVal Buf As Long, ByVal bufSize As Long, ByVal ReturnSize As Long) As Long
Declare Function ZwQueryInformationFile Lib "ntdll.dll" (ByVal hFile As Long, ByVal IoStatusBlock As Long, ByVal Buff As Long, ByVal bufSize As Long, ByVal FileInformation As Long) As Long
Declare Function ZqQueryInformationProcess Lib "ntdll.dll" (ByVal hProcess As Long, ByVal InformationClass As Long, ByVal Buf As Long, ByVal bufSize As Long, ByVal ReturnSize As Long) As Long
Declare Function VirtualAlloc Lib "kernel32.dll" (ByVal Address As Long, ByVal Size As Long, ByVal AllocateType As Long, ByVal Protect As Long) As Long
Declare Function VirtualFree Lib "kernel32.dll" (ByVal Address As Long, ByVal Size As Long, ByVal FreeType As Long) As Long
Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Declare Function DuplicateHandle Lib "kernel32.dll" (ByVal hSourceProcessHandle As Long, ByVal hSourceHandle As Long, ByVal hTargetProcessHandle As Long, ByRef lpTargetHandle As Long, ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwOptions As Long) As Long
Declare Function CreateThread Lib "kernel32" (lpThreadAttributes As Any, ByVal dwStackSize As Long, ByVal lpStartAddress As Long, lpParameter As Any, ByVal dwCreationFlags As Long, lpThreadID As Long) As Long
Declare Function WaitForSingleObject Lib "kernel32" (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long
Declare Function TerminateThread Lib "kernel32.dll" (ByVal hThread As Long, ByVal dwExitCode As Long) As Long
Declare Function WideCharToMultiByte Lib "kernel32" (ByVal codepage As Long, ByVal dwFlags As Long, lpWideCharStr As Any, ByVal cchWideChar As Long, lpMultiByteStr As Any, ByVal cchMultiByte As Long, ByVal lpDefaultChar As String, ByVal lpUsedDefaultChar As Long) As Long
Declare Sub ZeroMemory Lib "kernel32" Alias "RtlMoveMemory" (Dest As Any, ByVal numBytes As Long)
Declare Function hFile_Test Lib "c:\Project_Startup_System\GetFilePath.dll" (ByVal dwHandle As Long) As Boolean
Declare Function TestFile Lib "c:\LockedFile.dll" (ByVal FileHandle As Long) As Boolean

Const SystemHandleInformation = 16
Const MEM_COMMIT = &H1000
Const MEM_DECOMMIT = &H4000
Const PAGE_READWRITE = &H4
Const STATUS_INFO_LEGTH_MISMATCH = &HC0000004
Const GENERIC_READ = &H80000000
Const OPEN_EXISTING = 3
Const PROCESS_DUP_HANDLE = &H40
Const DUPLICATE_SAME_ACCESS = 2
Const DUPLICATE_CLOSE_SOURCE = 1
Const STATUS_TIMEOUT = 258
Const STATUS_WAIT_0 = 0

Type HANDLE_TYPE
    Handle As Integer
    ProcessID As Long
    Path As String
End Type
Type TSYSTEM_HANDLE_INFORMATION
    ProcessID As Long
    ObjectTypeNumber As Byte
    Flags As Byte
    Handle As Integer
    Object As Long
    GrantedAccess As Long
End Type
Type TGetFileNameThread
    Handle As Long
    Path As String
End Type
Type FILE_NAME_INFO
    FileNameLength As Long
    FileName As String * 256
End Type
Type IO_STATUS_BLOCK
    Status As Long
    Information As Long
End Type

Global Handles() As HANDLE_TYPE
Global HandleCount As Long
Global hFileType As Long
Global f As Long
Public Sub GetFileType()
Dim TSize As Long
Dim SHI_Handles() As TSYSTEM_HANDLE_INFORMATION
Dim ReturnVariable As Long, ReturnVariable2 As Long
Dim mPtr As Long
Dim i As Long
Dim hNullFile As Long
Dim CurPID As Long

hNullFile = CreateFile("NUL", GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0)
TSize = 1000
CurPID = GetCurrentProcessId
Do
    mPtr = VirtualAlloc(0, TSize, MEM_COMMIT, PAGE_READWRITE)
    ReturnVariable = ZwQuerySystemInformation(SystemHandleInformation, mPtr, TSize, ReturnVariable2)
    If ReturnVariable = STATUS_INFO_LEGTH_MISMATCH Then
        Call VirtualFree(mPtr, TSize, MEM_DECOMMIT)
        TSize = TSize * 2
    Else
        Exit Do
    End If
Loop
Call CopyMemory(ByVal VarPtr(HandleCount), ByVal mPtr, 4)
ReDim SHI_Handles(HandleCount)
mPtr = mPtr + 4
For i = 0 To HandleCount - 1
    Call CopyMemory(ByVal VarPtr(SHI_Handles(i)), ByVal mPtr, 16)
    mPtr = mPtr + 16
    If (SHI_Handles(i).ProcessID = CurPID) And (SHI_Handles(i).Handle = hNullFile) Then hFileType = SHI_Handles(i).ObjectTypeNumber
Next
Call CloseHandle(hNullFile)
Call VirtualFree(mPtr, TSize, MEM_DECOMMIT)
End Sub
Function GetFilePathThread(Parameters As TGetFileNameThread)
Dim Buf As FILE_NAME_INFO
Dim IO_S_B As IO_STATUS_BLOCK
If ZwQueryInformationFile(Parameters.Handle, ByVal VarPtr(IO_S_B), ByVal VarPtr(Buf), Len(Buf), 9) = 0 Then
    f = f + 1
End If
End Function
Sub GetHandles()
Dim TSize As Long
Dim SHI_Handles() As TSYSTEM_HANDLE_INFORMATION
Dim ReturnVariable As Long, ReturnVariable2 As Long
Dim mPtr As Long
Dim i As Long
Dim hProcess As Long
Dim hFile As Long
Dim hThread As Long
Dim ThreadId As Long
Dim wfso As Long
Dim Current_hProcess As Long
Dim GetFilePathThreadVariable As TGetFileNameThread
Dim er As Long

TSize = 1000
Do
    mPtr = VirtualAlloc(0, TSize, MEM_COMMIT, PAGE_READWRITE)
    ReturnVariable = ZwQuerySystemInformation(SystemHandleInformation, mPtr, TSize, ReturnVariable2)
    If ReturnVariable = STATUS_INFO_LEGTH_MISMATCH Then
        Call VirtualFree(mPtr, TSize, MEM_DECOMMIT)
        TSize = TSize * 2
    Else
        Exit Do
    End If
Loop
Call CopyMemory(ByVal VarPtr(HandleCount), ByVal mPtr, 4)
ReDim SHI_Handles(HandleCount)
mPtr = mPtr + 4
Current_hProcess = GetCurrentProcess
For i = 0 To HandleCount - 1
    Call CopyMemory(ByVal VarPtr(SHI_Handles(i)), ByVal mPtr, 16)
    mPtr = mPtr + 16
    If SHI_Handles(i).ObjectTypeNumber = hFileType Then
        ReDim Preserve Handles(i)
        Handles(i).Handle = SHI_Handles(i).Handle
        Handles(i).ProcessID = SHI_Handles(i).ProcessID
        hProcess = OpenProcess(PROCESS_DUP_HANDLE, False, SHI_Handles(i).ProcessID)
        If hProcess <> 0 Then
            Call DuplicateHandle(hProcess, SHI_Handles(i).Handle, Current_hProcess, hFile, 0, 0, DUPLICATE_SAME_ACCESS)
            If hFile_Test(hFile) Then
                frmMain.List1.AddItem "Миссия выполнена..."
            Else
                frmMain.List1.AddItem "Миссия провалена..."
            End If
            Call CloseHandle(hProcess)
            Call CloseHandle(hFile)
        End If
    End If
Next
Call VirtualFree(mPtr, TSize, MEM_DECOMMIT)
End Sub

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 06.03.2008 (Чт) 7:36

Код: Выделить всё
CreateThread(nil,0,@Test,@ParamHandle,0,PDWORD(0)^);

Что за порнуха последним параметром? :lol:

И вообще, если пишешь системные вещи на Делфях, то лучше выбрасывать RTL, как завещал ms-rem - так код будет эффективнее. Можешь посмотреть как я реализовал это в своем плагине к Винампу - http://twister.orgfree.com/projects
А я все практикую лечение травами...

M.A.R.K
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 68
Зарегистрирован: 11.11.2007 (Вс) 11:50
Откуда: Иркутск

Сообщение M.A.R.K » 20.03.2008 (Чт) 8:59

Еще проблемка:
Код: Выделить всё
library t_fpfh;
uses
  SysUtils,
  Classes,
  windows;

{$R *.res}
type
pTHandle = ^THandle;
pIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;
IO_STATUS_BLOCK = Packed Record
  Status : Cardinal;
  Information : DWORD;
end;
pThreadParam = ^ThreadParam;
ThreadParam = Packed Record
  Handle : THandle;
  FilePath : array[0..MAX_PATH-1] of Char;
  Status : Cardinal;
end;
TFNI = Packed Record
  FileNameLength : DWORD;
  FileName : array [0..MAX_PATH - 1] of WideChar;
  FileNameObject : array [0..MAX_PATH - 1] of WideChar;
end;
TUNICODE_STRING = packed record
  Length : WORD;
  MaximumLength : WORD;
  Buffer : array [0..MAX_PATH - 1] of WideChar;
end;
TOBJECT_NAME_INFORMATION = packed record
  Name : TUNICODE_STRING;
end;

function NtQueryObject(ObjectHandle: THandle;
  ObjectInformationClass: DWORD; ObjectInformation: Pointer;
  ObjectInformationLength: ULONG;
  ReturnLength: PDWORD): Cardinal; stdcall; external 'ntdll.dll';

function ZwQueryInformationFile(hFile : THandle;
  IOB : pIO_STATUS_BLOCK; FileInformation : Pointer;
  Length : DWORD;FileInformationClass : DWORD): Cardinal; stdcall; external 'ntdll.dll';

function Test(Param : Pointer) : DWORD;stdcall;
var
  IO_S_B : IO_STATUS_BLOCK;
  FNI : TFNI;
  ONI: TOBJECT_NAME_INFORMATION;
  TP : ThreadParam;
begin
  TP := pThreadParam(Param)^;
  ZeroMemory(@FNI,SizeOf(TFNI));
  TP.Status := ZwQueryInformationFile(TP.Handle,@IO_S_B,@FNI,MAX_PATH*2,9);
  if TP.Status = 0 then
  begin
    TP.Status := NtQueryObject(TP.Handle,1,@ONI,MAX_PATH * 2,nil);
    if TP.Status = 0 then
      begin
        WideCharToMultiByte(CP_ACP,0,@FNI.FileName,FNI.FileNameLength,@TP.FilePath,MAX_PATH,nil,nil);
        WideCharToMultiByte(CP_ACP,0,@ONI.Name.Buffer[ONI.Name.MaximumLength - ONI.Name.Length],ONI.Name.Length,@TP.FileNameObject,MAX_PATH,nil,nil);
      end;
  end;
  pThreadParam(Param)^ := TP;
end;
function FilePath_From_hFile(ParamHandle : THandle;var Path : PAnsiChar;var PathObject : PAnsiChar) : BOOL; stdcall;
var
  hThread : THandle;
  TP : ThreadParam;
begin
  ZeroMemory(@TP,SizeOf(ThreadParam));
  TP.Handle := ParamHandle;
  hThread := CreateThread(nil,0,@Test,@TP,0,PDWORD(0)^);
    Case WaitForSingleObject(hThread,50) of
    WAIT_TIMEOUT:
    begin
      TerminateThread(hThread,0);
      FilePath_From_hFile := FALSE;
      StrPCopy(Path,'');
      StrPCopy(PathObject,'');
    end;
    WAIT_OBJECT_0:
    begin
      if TP.Status = 0 then
      FilePath_From_hFile := TRUE;
      StrPCopy(Path,TP.FilePath);
      StrPCopy(PathObject,TP.FilePath);
    end;
    end;
  CloseHandle(hThread);
end;
exports FilePath_From_hFile;
begin

end.

Код: Выделить всё
Declare Function FilePath_From_hFile Lib "t_fpfh" (ByVal dwHandle As Long, Path As String, PathObject As String) As Boolean

Если вызвать FilePath_From_hFile, то VB вылетает...
Если убрать из кода функции "FilePath_From_hFile" строку "StrPCopy(PathObject,[любой текст]);", то все работает.
Я имею подозрение на эту строку (Возможно неправильное объявление функции):
Код: Выделить всё
...
function FilePath_From_hFile(ParamHandle : THandle;var Path : PAnsiChar;var PathObject : PAnsiChar) : BOOL; stdcall;
...

Подскажите, что нужно исправить...
Заранее благодарен.

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 20.03.2008 (Чт) 9:21

Как ты вызываешь FilePath_From_hFile из VB?
Ты некорректно объявил функцию в Delphi - var не нужен, ибо получилось, что передается не указатель на строку, а указатель на указатель...
А я все практикую лечение травами...

M.A.R.K
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 68
Зарегистрирован: 11.11.2007 (Вс) 11:50
Откуда: Иркутск

Сообщение M.A.R.K » 21.03.2008 (Пт) 8:13

Twister писал(а):Как ты вызываешь FilePath_From_hFile из VB?

Код: Выделить всё
Declare Function FilePath_From_hFile Lib "t_fpfh" (ByVal dwHandle As Long, Path As String, PathObject As String) As Boolean
Dim String1 as string
Dim String2 as string
if FilePath_From_hFile(Handle,String1,String2) then
  MsgBox "Ок:" + String1 + String2
else
  MsgBox "Дела плохи..."
end if

Twister
Теоретик
Теоретик
Аватара пользователя
 
Сообщения: 2251
Зарегистрирован: 28.06.2005 (Вт) 12:32
Откуда: Алматы

Сообщение Twister » 21.03.2008 (Пт) 9:59

Дела и вправду плохи...

Рекомендую абстрагироваться от понятия строка и иметь ввиду, что есть только набор байт и указатель на него.

Объяви так:
Код: Выделить всё
Declare Function FilePath_From_hFile Lib "t_fpfh" (ByVal dwHandle As Long, byval lpPath As long, byval lpPathObject As long) As Boolean

Код: Выделить всё
function FilePath_From_hFile(ParamHandle: DWORD; lpPath, lpPathObject: PChar): BOOL; stdcall;

И работай с указателями - больше нервов съэкономишь... :wink:
А я все практикую лечение травами...

M.A.R.K
Обычный пользователь
Обычный пользователь
Аватара пользователя
 
Сообщения: 68
Зарегистрирован: 11.11.2007 (Вс) 11:50
Откуда: Иркутск

Сообщение M.A.R.K » 22.03.2008 (Сб) 8:37

Twister
1) (Delphi) Я так понимаю, что будет другой код, вместо [StrPCopy(Path,TP.FilePath);], тогда как мне поместить в [Path : PChar] строку [FilePath : array[0..MAX_PATH-1] of Char;]?
2) (VB) Как мне из [ByVal Path As Long] получить строку?


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: SemrushBot, Yandex-бот и гости: 70

    TopList