Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.11.21;
Скачать: CL | DM;

Вниз

VirtualProtect   Найти похожие ветки 

 
Rem   (2004-10-07 12:27) [0]

Добрый день, мастера! Начну с главного, мне необходимо перехватить winapi"шную функцию CreateFile из одной другой проги, послать эту же функцию, но с другими параметрами из своей, получить результат и вернуть его той другой проге. Я знаю, что надо использовать функцию VirtualProtect, но я не знаю как, в MSDN практически ниче не описано по этому поводу, помогите мне плз решить эту проблему.


 
Суслик ©   (2004-10-07 12:30) [1]

эээ, ты куда-то не туда роешь...

это перехват api вызовов.
информации море.

дла начала см. книгу Рихтера Windows для профи - там несколько способов рассмотрено. Есть пример на rsdn -  #1 с.г. или #2 с.г. (см. в статьсях)


 
Digitman ©   (2004-10-07 12:55) [2]


> послать эту же функцию


"послать" - это ассоциируется с тремя веселыми буквами ... может все-таки, будешь точней ? кто, куда и по какому поводу "посылает" ? ... и оперируй понятиями не "прога", а хотя бы "трэд процесса" и "процесс" ... хоть что-то прояснится ..


 
Rem   (2004-10-07 13:06) [3]

Пример на VC у меня есть, но там очень мутно, может есть у кого-нть на дельфи примерчик


 
Rem   (2004-10-07 13:17) [4]

Окей, задача такая, из одного процесса (назовем его А) вызывается функция CreateFile с определенными параметрами. Мой процесс (процесс В), должен перехватить вызов этой функции, проверить параметры, и если в параметрах функции, вызванной процессом А, имя файла совпадает с моим именем фала, используемой в моем приложении, то процесс В вызывает функцию CreateFile с теми параметрами, кот. мне нужны (а именно указываю свой файл). CreateFile возвращает Handle на созданный файл, я этот Handle, должен передать порцессу А. Т.е. проблема в том, что одна программа (процесс А) используют такую затычку, что если файл создан, то она не запускается, а если не создан, то запускается. Я хочу обмануть эту прогу, перехватить вызов функции, создать свой файл и вернуть Handle процессу А. Таким образом Процесс А будет думать, что файл создан и запустится.


 
Игорь Шевченко ©   (2004-10-07 14:26) [5]


> CreateFile возвращает Handle на созданный файл, я этот Handle,
> должен передать порцессу А.


Не получится.


 
Digitman ©   (2004-10-07 16:32) [6]


> Rem


теперь понятно.

процесс А - это процесс GUI-приложения ?


 
Rem   (2004-10-07 16:53) [7]

да, это GUI приложение


 
Rem   (2004-10-07 16:57) [8]

Вообщем, я нашел один примерчик http://delphiworld.narod.ru/base/catch_dll_functions_calling.html, только вместо вызова MessageBoxA, я пишу CreateFileA, библиотеку kernel32.dll, ну и TMyProc с MyMessageBox"ом изменяю так, как нужно. Пробовал, но что-то не получается.


 
kaZaNoVa ©   (2004-10-07 22:22) [9]

Digitman ©   (07.10.04 12:55) [2]

> "послать" - это ассоциируется с тремя веселыми буквами
> ...

CAD  ?


 
kaZaNoVa ©   (2004-10-07 22:25) [10]

http://delphimaster.net/view/4-1093466109/
там есть ВСЁ - спасибо Digitman"у !!!


 
Digitman ©   (2004-10-08 08:11) [11]


> Rem   (07.10.04 16:53) [7]


если GUI , то можно воспользоваться механизмом установки глоб.хука

в общем же случае (для НТ-систем) - внедрение в АП процесса своей ДЛЛ вызовом CreateRemoteThread

как только внедренная тем или иным методом библиотека получит управление (в ходе ее иниц-ции), в этот момен как раз и можно осуществить перехват, например, модификацией EAT и IAT


 
Rem   (2004-10-08 13:00) [12]

Ага, спасибо, тут вообщем немного поменялась ситуация. Вообщем все сложно, есть дллка - это актив искина, в этой дллке есть класс, в нем объявлен метод, этот метод вызывает функцию CreateFile со своими параметрами, мне надо перехватить вызов этой функции, вызвать эту же функцию, но со своими параметрами. Как это можно сделать, в каком процессе загружена эта дллка? Вобщем решение такое, что я узнаю процесс, этот процесс загружает мою дллку, которая перехватывает вызов функции CreateFile. Основная проблема определить в каком процессе выполняется дллка-актив иксина. Я думал, что в explorer"e, внедрил туда свой код, кот. перехватывает вызов, но ничего не получилось. Может это так, тогда (если это так) подскажите мне где у меня ошибка.


 
Rem   (2004-10-08 13:04) [13]

Ага, спасибо, тут вообщем немного поменялась ситуация. Вообщем все сложно, есть дллка - это актив искина, в этой дллке есть класс, в нем объявлен метод, этот метод вызывает функцию CreateFile со своими параметрами, мне надо перехватить вызов этой функции, вызвать эту же функцию, но со своими параметрами. Как это можно сделать, в каком процессе загружена эта дллка? Вобщем решение такое, что я узнаю процесс, этот процесс загружает мою дллку, которая перехватывает вызов функции CreateFile. Основная проблема определить в каком процессе выполняется дллка-актив иксина. Я думал, что в explorer"e, внедрил туда свой код, кот. перехватывает вызов, но ничего не получилось. Может это так, тогда (если это так) подскажите мне где у меня ошибка.


 
Digitman ©   (2004-10-08 13:24) [14]


> это актив искина


"актив искина" - это по сути обычная ДЛЛ .. а ДЛЛ грузится и исполняется в АП затребовавшего ее (тем или иным образом - неважно) процесса


 
Rem   (2004-10-08 14:39) [15]

Помогите плз, у меня не получается, вот код

type
 PImageDosHeader = ^TImageDosHeader;
 _IMAGE_DOS_HEADER = packed record
   e_magic: Word;
   e_cblp: Word;
   e_cp: Word;
   e_crlc: Word;
   e_cparhdr: Word;
   e_minalloc: Word;
   e_maxalloc: Word;
   e_ss: Word;
   e_sp: Word;
   e_csum: Word;
   e_ip: Word;
   e_cs: Word;
   e_lfarlc: Word;
   e_ovno: Word;
   e_res: array[0..3] of Word;
   e_oemid: Word;
   e_oeminfo: Word;
   e_res2: array[0..9] of Word;
   e_lfanew: LongInt;
 end;
 TImageDosHeader = _IMAGE_DOS_HEADER;
 IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;

 //***************************************
 PImageDataDirectory = ^TImageDataDirectory;
 _IMAGE_DATA_DIRECTORY = record
   VirtualAddress: DWORD;
   Size: DWORD;
 end;
 //
 TImageDataDirectory = _IMAGE_DATA_DIRECTORY;
 IMAGE_DATA_DIRECTORY = _IMAGE_DATA_DIRECTORY;
 //

 //*************
 PImageOptionalHeader = ^TImageOptionalHeader;
 _IMAGE_OPTIONAL_HEADER = packed record
   Magic: Word;
   MajorLinkerVersion: Byte;
   MinorLinkerVersion: Byte;
   SizeOfCode: DWORD;
   SizeOfInitializedData: DWORD;
   SizeOfUninitializedData: DWORD;
   AddressOfEntryPoint: DWORD;
   BaseOfCode: DWORD;
   BaseOfData: DWORD;
   ImageBase: DWORD;
   SectionAlignment: DWORD;
   FileAlignment: DWORD;
   MajorOperatingSystemVersion: Word;
   MinorOperatingSystemVersion: Word;
   MajorImageVersion: Word;
   MinorImageVersion: Word;
   MajorSubsystemVersion: Word;
   MinorSubsystemVersion: Word;
   Win32VersionValue: DWORD;
   SizeOfImage: DWORD;
   SizeOfHeaders: DWORD;
   CheckSum: DWORD;
   Subsystem: Word;
   DllCharacteristics: Word;
   SizeOfStackReserve: DWORD;
   SizeOfStackCommit: DWORD;
   SizeOfHeapReserve: DWORD;
   SizeOfHeapCommit: DWORD;
   LoaderFlags: DWORD;
   NumberOfRvaAndSizes: DWORD;
   DataDirectory: packed array[0..IMAGE_NUMBEROF_DIRECTORY_ENTRIES - 1] of TImageDataDirectory;
 end;
 TImageOptionalHeader = _IMAGE_OPTIONAL_HEADER;
 IMAGE_OPTIONAL_HEADER = _IMAGE_OPTIONAL_HEADER;

 PImageNtHeaders = ^TImageNtHeaders;
 _IMAGE_NT_HEADERS = packed record
   Signature: DWORD;
   FileHeader: TImageFileHeader;
   OptionalHeader: TImageOptionalHeader;
 end;
 TImageNtHeaders = _IMAGE_NT_HEADERS;
 IMAGE_NT_HEADERS = _IMAGE_NT_HEADERS;

 PImage_import_by_name = ^TImage_import_by_mame;
 _IMAGE_IMPORT_BY_NAME = packed record
   Hint: Word;
   Name: Byte;
 end;
 TImage_import_by_mame = _IMAGE_IMPORT_BY_NAME;

 _u1 = packed record
   case Integer of
     0: (ForwarderString: PByte);
     1: (Functionn: PDWORD);
     2: (Ordinal: DWORD);
     3: (AddressOfData: PImage_import_by_name);
 end;
 PImageThunkData = ^TImageThunkData;
 _IMAGE_THUNK_DATA = packed record
   u1: _u1;
 end;
 TImageThunkData = _IMAGE_THUNK_DATA;
 IMAGE_THUNK_DATA = _IMAGE_THUNK_DATA;
 _temp_charcteristics = record
   case Integer of
     0: (Characteristics: DWORD);
     1: (OriginalFirstThunk: PImageThunkData);
 end;

 PImageImportDescriptor = ^TImageImportDescriptor;
 _IMAGE_IMPORT_DESCRIPTOR = packed record

   t: _temp_charcteristics;
   TimeDateStamp: DWord;
   ForwarderChain: DWORD;
   Name: DWORD;
   FirstThunk: PImageThunkData;
 end;
 TImageImportDescriptor = _IMAGE_IMPORT_DESCRIPTOR;
 IMAGE_IMPORT_DESCRIPTOR = _IMAGE_IMPORT_DESCRIPTOR;
 PPointer = ^Pointer;

function MakePtr(base: Dword; Offset: DWORD): Pointer;
begin
 Result := Pointer(Base + Offset);
end;

function InterceptDllCall(hLocalModule: HModule; c_szDllName: Pchar; c_szApiName: PChar;
                         pApiNew: Pointer; p_pApiOrg: PPointer; pApiToChange: Pointer): Boolean;
var
 pDosHeader: PImageDosHeader;
 pNtHeader: PImageNtHeaders;
 PImportDesc: PImageImportDescriptor;
 dwProtect: DWORD;
 dwNewProtect: DWORD;
 dwAddressToInterCept: DWORD;
 pThunk: PImageThunkData;
begin
 pDosHeader := PImageDosHeader(hLocalModule);
 Result := False;
 if (pApiToChange <> nil) then dwAddressToIntercept := DWORD(pApiToChange)
                          else dwAddressToIntercept := Dword(GetProcAddress(GetModuleHandle(c_szDllName), c_szApiName));
 if IsBadReadPtr(Pointer(hLocalModule), sizeof(PImageNtHeaders)) then Exit;
 if pDosHeader.e_magic <> IMAGE_DOS_SIGNATURE then exit;
 pNtHeader := PImageNtHeaders(MakePtr(DWord(pDOSHeader),DWord(pDOSHeader.e_lfanew)));
 if pNTHeader.signature <> IMAGE_NT_SIGNATURE then exit;
 pImportDesc := PImageImportDescriptor(MakePtr(hLocalModule,pNtHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Virtual Address));
 if (PImportDesc = PImageImportDescriptor(pNtHeader)) then exit;
 while (pImportDesc.Name > 0) do
   begin
     pThunk := PImageThunkData(MakePtr(DWord(hLocalModule), Dword(pImportDesc.FirstThunk)));
     while (pThunk.u1.Functionn <> nil) do
       begin
         if DWord(pThunk.u1.Functionn) = dwAddressToIntercept then
           begin
             if not IsBadWritePtr(Pointer(@pThunk.u1.Functionn), sizeof(DWORD)) then
               begin
                 if (p_pApiOrg <> nil) then p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
                 pThunk.u1.Functionn := pApiNew;
                 Result := True;
               end                                                              else
               begin
                 if VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),PAGE_EXECUTE_READWRITE, @dwProtect) then
                   begin
                     if (p_pApiOrg <> nil) then p_pApiOrg^ := Pointer(pThunk.u1.Functionn);
                     pThunk.u1.Functionn := PDWORD(pApiNew);
                     Result := True;
                     dwNewProtect := dwProtect;
                     VirtualProtect(Pointer(@pThunk.u1.Functionn), sizeof(DWORD),dwNewProtect, @dwProtect);
                   end;
               end;
           end;
         Inc(PThunk);
       end;
     Inc(pImportDEsc);
   end;
end;


 
Rem   (2004-10-08 14:46) [16]

Продолжение предыдущего...

var InterceptDllCall : function(hLocalModule: HModule; c_szDllName: Pchar; c_szApiName: PChar;
                         pApiNew: Pointer; p_pApiOrg: PPointer; pApiToChange: Pointer): Boolean;

type TMyProc= function (lpFileName: PAnsiChar; dwDesiredAccess : Cardinal; dwShareMode : Cardinal;
                       lpSecurityAttributes : PSecurityAttributes; dwCreationDisposition : Cardinal;
                       dwFlagsAndAttributes : Cardinal; hTemplateFile : Cardinal): THandle; stdcall;
    PTMyProc=^TMyProc;

var OldCreateProc : PTMyProc=nil;

function MapRuleCreateFile(lpFileName: PAnsiChar; dwDesiredAccess : Cardinal; dwShareMode : Cardinal;
                          lpSecurityAttributes : PSecurityAttributes; dwCreationDisposition : Cardinal;
                          dwFlagsAndAttributes : Cardinal; hTemplateFile : Cardinal): THandle; stdcall;
begin
 Result:=CreatFile(PAnsiChar("c:\TMP.tmp"),1,2,nil,2,4,0);
end;

procedure Start;
begin
   CreateFile(PAnsiChar("c:\Before.TMP"),1,2,nil,2,4,0);
   InterceptDllCall(hInstance,"Kernel32.dll","CreateFileA", Pointer(@MapRuleCreateFile),PPointer(@OldCreateProc),nil);
   {Здесь через интерфейс вызываем функцию из дллки, в которой (дллке) должна вызываться функция CreateFile, но ничего не работает}
   
end;


 
Digitman ©   (2004-10-08 15:17) [17]


> у меня не получается


мы догадываться должны, что у тебя там "не получается" ? у тебя языка нет детально описать проблему ?


 
Rem   (2004-10-08 15:40) [18]

Вообщем, не получается перехватить функцию CreateFile, т.е. через интерфейс вызывается метод класса, он в свою очередь вызывает CreateFile, и, вот используя вышеописанный код, мне не удается перехватить вызов CreateFile. Если вы утверждаете, что дллка находится в моем процессе, то функция CreateFile должна перехватываться. Этотим кодом я пробовал перехватывать сообщение MessageBox, все замечательно перехватывался, но MessageBox вызывался из моего процесса. Так вот напрашивается вывод, что дллка загружается не в мой процесс.


 
Digitman ©   (2004-10-08 15:47) [19]

ты хоть определись, в каком тек.процессе происходит перехват ...

на то есть ф-ции GetCurrentThreadId и MaunThreadId


 
Rem   (2004-10-09 01:22) [20]

вот я не могу определить в каком процессе загружена актив икс дллка, чтобы произвести перехват. Я перехватываю в своем процессе, ты утверждаешь, что актив икс дллка загружается в мой процесс, тогда почему не перехватывается функцию вышеописанным кодом?


 
Rem   (2004-10-09 01:31) [21]

Вообщем, есть актив икс дллка, в ней описан класс, в этом классе есть метод, этот метод вызывает функцию CreateFile. Мне именно надо перехватить вызов этой функции в этом методе. Имя метода я знаю. Объект этого класса я использую у себя в программе. Явной загрузки дллки, т.е. через LoadLibrary, у меня не было, я получаю доступ к методам через интерфейс.

> ты хоть определись, в каком тек.процессе происходит перехват
> ...

И вот тут вопрос, как я могу определиться в каком тек. процессе идет перехват, если я не знаю в каком процессе загружена актив икс дллка. Если в моем, тогда почему не перехватывается функцию вышеописанным кодом?


 
Rem   (2004-10-11 11:13) [22]

Господа, ну промогите мне плз, я в тупике... Может есть другой выход, мне надо сделать так, чтоб не создавался файл с указанным именем или хотя бы удалить его после создания, но удалить его просто нельзя, т.к. он создан не мной и с монопольным доступом.


 
Erik1 ©   (2004-10-11 11:41) [23]

А может тебе перехватить все вызовы CreateFile, во всех активных процесах? Кроме своего конечно. И если вызов происходит с именем нужного тебе файла то подменяй его. Скорее всего тебе придется перехватить еще ReadFile и WriteFile. Но все это муторно и непонятно. Может проще залезть в Dll и изменить ей имя файла?


 
Rem   (2004-10-11 12:28) [24]


> Может проще залезть в Dll и изменить ей имя файла?

Нет, это не проще т.к. это грубый хак, мне этого нельзя делать, я не для себя пишу, а по поводу всех активных процессов, я пробовал, но также не хочет отлавливать, может у меня ошибка в коде, посмотрите плз, но я пробовал на функции MessageBox - все работает нормально.


 
Erik1 ©   (2004-10-11 13:49) [25]

В коде у тебя точно ошибка, точнее весь код ошибка. Как я понял ты пытаешся отловить вызов API в своем процессе, а тебе нужно в чужом! Думаю, что это explorer.exe


 
Rem   (2004-10-12 08:30) [26]

Я пробовал отлавливать в explorer.exe, но не отлавливается, функцию InterceptDllCall я запихивал в дллку, а в своей проге писал все остальное, плюс еще следующую функцию:

//Процедура подключения дллки к процессу
//pID - идентификатор процесса
//LibName - подключаемая библиотека
procedure AttachDllToProcess(pID: integer; LibName: string);
var ThreadID     : Cardinal;
   ThreadHndl   : THandle;
   AllocBuffer  : Pointer;
   BytesWritten : Cardinal;
   ProcAddr     : Pointer;
   ExitCode     : Cardinal;
   hProcess     : integer;
begin
hProcess:=OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, false, pID);
if (hProcess=0) then Exit;
AllocBuffer:=VirtualAllocEx(hProcess, nil, length(LibName)+1, MEM_COMMIT, PAGE_READWRITE);
if (AllocBuffer<>nil) then WriteProcessMemory(hProcess, AllocBuffer, PChar(LibName), length(LibName)+1, BytesWritten)
                     else Exit;
ProcAddr:=GetProcAddress(LoadLibrary(PChar("Kernel32.dll")), PChar("LoadLibraryA"));
ThreadHndl:=CreateRemoteThread(hProcess, nil, 0, ProcAddr, AllocBuffer, 0, ThreadID);
WaitForSingleObject(ThreadHndl, INFINITE);
GetExitCodeThread(ThreadHndl, ExitCode);
CloseHandle(ThreadHndl);
VirtualFreeEx(hProcess, AllocBuffer, 0, MEM_RELEASE);
CloseHandle(hProcess);
end;

//Функция ищет процесс, к кот. надо подключиться и
//вызывает функцию подключения дллки к найденному процессу
function PrepareToAttachToDLL(PathToDll : PAnsiChar):boolean;
var
   hSnapshoot: THandle;
   pe32: TProcessEntry32;
   PathToDLL : PAnsiChar;
   hndDLLHandle : THandle;
begin
Result:=false;
//Получаем PID процесса эксплорера
hSnapshoot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshoot = -1) then Exit;
pe32.dwSize := SizeOf(TProcessEntry32);
if (Process32First(hSnapshoot, pe32)) then
 repeat
   //Пробовал подключать дллку ко всем порцессам,
   //закомментировав строку ниже, т.е.  
   //if pe32.szExeFile="explorer.exe" then
   if pe32.szExeFile="explorer.exe" then
     begin
       //Здесь именно подключаем дллку к найденному процессу
       AttachDllToProcess(pe32.th32ProcessID,PathToIntrcptDll);
       hndDLLHandle:=LoadLibraryA(PathToDll);
       if hndDLLHandle<>0 then
         begin
           @InterceptDllCall:=GetProcAddress(hndDLLHandle,"InterceptDllCall");
           if Addr(InterceptDllCall)<>nil then
             InterceptDllCall(pe32.th32ProcessID{HInstance},"Kernel32.dll","CreateFileA", Pointer(@MapRuleCreateFile),PPointer(@OldCreateProc),nil);
         end;
       CloseHandle(hSnapshoot);
       Result:=true;
       exit;
     end;
 until not Process32Next(hSnapshoot, pe32);
CloseHandle (hSnapshoot);
end;

//Переписываем тогда процедуру Start
procedure Start;
var PTH : PAnsiChar;
begin
  CreateFile(PAnsiChar("c:\Before.TMP"),1,2,nil,2,4,0);
  GetMem(PTH,sizeof("C:\MyLib.dll"))
  PTH:="C:\MyLib.dll";
  PrepareToAttachToDLL(PTH);
  InterceptDllCall(hInstance,"Kernel32.dll","CreateFileA", Pointer(@MapRuleCreateFile),PPointer(@OldCreateProc),nil);
  {Здесь через интерфейс вызываем функцию из дллки, в которой (дллке) должна вызываться функция CreateFile, но ничего не работает}
 
end;



 
Rem   (2004-10-12 09:04) [27]

А если попробовать другой путь, не перехват функций, а, например, можно ли удалить файл средствами winapi, если он создан другим процессом с монопольным доступом?


 
Rem   (2004-10-12 10:30) [28]

Вообщем, я пробую отслеживать изменения файловой системы при создании файла, вот код, кот. это делает:

procedure ChangeFileSystem;
var     ChangeHandle : THandle;
begin
ChangeHandle:= FindFirstChangeNotification(FileName,false, FILE_NOTIFY_CHANGE_FILE_NAME);
if ChangeHandle <> INVALID_HANDLE_VALUE then
 while true do
   begin
     if WaitForSingleObject(ChangeHandle,500) = WAIT_OBJECT_0 then
       begin
         //Событие...
       end;
     FindNextChangeNotification(ChangeHandle);
   end;
end;

И вот где написано событие, что должно быть? Я определил, что я вызываю функцию создания файла и вызвается эта процедура, но файл еще не создан, т.е. фактическим можно перехватить событие создания файла. А какое событие создания файла?


 
Юра   (2004-10-12 10:48) [29]

Хмм. рановато ты за это дело взялся, имхо. Поучи матчасть сначала, хотя бы того же Рихтера.


 
Erik1 ©   (2004-10-12 10:49) [30]

Ты вобще понимаеш, что твоя функция неможет работать? Если будеш продолжать в такомже духе тебе просто перестанут отвечать. Ты посмотри как осуцествляется перехват у Digitman. Он тут давал пример как это надо делать. Пользуйся поисковиками! Вобщето есть очень простое решение, надо сделать path который будет изменять dll в памяти и менять имя создоваемого файла. Для этого есть спецальные программы по созданию таких пачей.
 Или изучи перехват API функций.


 
Rem   (2004-10-12 11:43) [31]

Да, я понимаю, извиняюсь если что не так, у Digitman есть функция RtlEnterCriticalSection и RtlLeaveCriticalSection, откуда он их взял, компилятор на них ругается?


 
Суслик ©   (2004-10-12 11:56) [32]


> откуда он их взял

прежде чем справшивать сделай сквозной поиск по исходникам, поставляемым с дельфи.

в 99% случаев помогает.


 
Rem   (2004-10-12 13:13) [33]


> прежде чем справшивать сделай сквозной поиск по исходникам

Если б нашел, не спрашивал бы...


 
Суслик ©   (2004-10-12 14:07) [34]


> [33] Rem   (12.10.04 13:13)

действительно нет.
Это 1%, когда поиск не помогает :(


 
Rem   (2004-10-12 14:25) [35]

но, если Rtl убрать, а оставить все остальное, то получается winайпишная функция


 
Rem   (2004-10-12 14:44) [36]

У меня ошибка вываливается в процедуре LockLoader, все таки не понятно, откуда взята функция RtlEnterCriticalSection.


 
Rem   (2004-10-12 15:07) [37]

Господа, большое спасибо всем за помощь, у меня все получилось!!!



Страницы: 1 вся ветка

Текущий архив: 2004.11.21;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.032 c
14-1099916384
syte_ser78
2004-11-08 15:19
2004.11.21
отслеживание посещаемости сетевой папки


1-1099464334
Uran
2004-11-03 09:45
2004.11.21
Проверка содержит ли строка дату


1-1099547174
diabolik_krsk
2004-11-04 08:46
2004.11.21
Автоматический переход фокуса с TEdit на TEdit


3-1098418036
Denis_Ac
2004-10-22 08:07
2004.11.21
Заполнение DBCombobox/ DBListBox


3-1098189214
Григорьев Антон
2004-10-19 16:33
2004.11.21
Арифметическое И в Access