Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Мьютекс


Автор: koTexe 26.4.2006, 15:07
Здравствуйте, у меня такой вопрос, можно ли найти хендел окна создавшего мьютекс. 

Автор: Snowy 26.4.2006, 15:15
Нет. Мьютекс вещь самостоятельная.
Винде совершенно все равно, кто его создал.
Главное, кто работает с его хэндлом.
Но список тредов, работающих с мьютексом она также не предоставляет.
И влезть в ее внутреннюю кухню она не дает. 

Автор: Rouse_ 26.4.2006, 17:06
Можно, но сложно. Ищи NtQueryMutant() 

Автор: Nickel 29.4.2006, 19:03
Написал код, чтоб получить ID процесса создавшего мьютекс. Думаю это то что ты хотел, если надо, можно будет узнать какие окна создал этот процесс. На всякий случай получаем привелегии отладчика, вдруг понадобится мьютекс системного процесса.
Код

type
PSYSTEM_HANDLE_INFORMATION = ^SYSTEM_HANDLE_INFORMATION;
SYSTEM_HANDLE_INFORMATION = packed record
   ProcessId: dword;
   ObjectTypeNumber: byte;
   Flags: byte;
   Handle: word;
   pObject: pointer;
   GrantedAccess: dword;
end;

PSYSTEM_HANDLE_INFORMATION_EX = ^SYSTEM_HANDLE_INFORMATION_EX;
SYSTEM_HANDLE_INFORMATION_EX = packed record
   NumberOfHandles: dword;
   Information: array [0..0] of SYSTEM_HANDLE_INFORMATION;
end;

PUnicodeString = ^TUnicodeString;
  TUnicodeString = packed record
    Length: Word;
    MaximumLength: Word;
    Buffer: PWideChar;
end;

const SystemHandleInformation  =    16;
      OB_TYPE_MUTANT = 11;
      ObjectNameInformation = 1;

function ZwQueryObject(ObjectHandle: THandle;
  ObjectInformationClass: integer; ObjectInformation:Pointer;
  Length: ULONG; ReturnLength: PULONG): cardinal; stdcall;
  external 'ntdll.dll';
  
Function ZwQuerySystemInformation(ASystemInformationClass: dword;
                                  ASystemInformation: Pointer;
                                  ASystemInformationLength: dword;
                                  AReturnLength:PCardinal): cardinal;
                                  stdcall;external 'ntdll.dll';


Function GetSystemHandleTable:Pointer;
var
 mSize: dword;
 mPtr: pointer;
 St: cardinal;
begin
 Result := nil;
 mSize := $4000;
 repeat
   mPtr := VirtualAlloc(nil, mSize, MEM_COMMIT or MEM_RESERVE, PAGE_READWRITE);
   if mPtr = nil then Exit;
   St := ZwQuerySystemInformation(SystemHandleInformation, mPtr, mSize, nil);
   if St = cardinal($C0000004) then
      begin
        VirtualFree(mPtr, 0, MEM_RELEASE);
        mSize := mSize * 2;
      end;
 until St <> cardinal($C0000004);
 if St = 0
   then Result := mPtr
   else VirtualFree(mPtr, 0, MEM_RELEASE);
end;

function EnablePrivilege(Process: dword; lpPrivilegeName: PChar):Boolean;
var
  hToken: dword;
  NameValue: Int64;
  tkp: TOKEN_PRIVILEGES;
  ReturnLength: dword;
begin
  Result:=false;
  OpenProcessToken(Process, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
  if not LookupPrivilegeValue(nil, lpPrivilegeName, NameValue) then
    begin
     CloseHandle(hToken);
     exit;
    end;
  tkp.PrivilegeCount := 1;
  tkp.Privileges[0].Luid := NameValue;
  tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
  AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TOKEN_PRIVILEGES),
    tkp, ReturnLength);
  if GetLastError() <> ERROR_SUCCESS then
     begin
      CloseHandle(hToken);
      exit;
     end;
  Result:=true;
  CloseHandle(hToken);
end;

function SeekMutantProcess(Name:string):cardinal;
var inf:PSYSTEM_HANDLE_INFORMATION_EX;
    i:integer;
    process,h:cardinal;
    p:pointer;
    s:string;
begin
  Result:=0;
  EnablePrivilege(INVALID_HANDLE_VALUE ,'SeDebugPrivilege');
  p:=GetMemory(max_path);
  ZeroMemory(p,max_path);
  inf:=GetSystemHandleTable;
  for i:=0 to inf.NumberOfHandles-1 do
    if inf.Information[i].ObjectTypeNumber=OB_TYPE_MUTANT then
      begin
       process:=OpenProcess(PROCESS_DUP_HANDLE,false,
            inf.Information[i].ProcessId);
       DuplicateHandle(process,inf.Information[i].Handle,
            GetCurrentProcess,@h,0,false,0);
       CloseHandle(process);
       ZwQueryObject(h,ObjectNameInformation,p,max_path,nil);
       CloseHandle(h);
       s:=ExtractFileName(WideCharToString(
                TUnicodeString(p^).Buffer));
       ZeroMemory(p,max_path);
       if s=Name then Result:=inf.Information[i].ProcessId;
       //Form1.ListBox1.Items.Add(s);
  end;
end;


Пример:
Код

procedure TForm1.Button1Click(Sender: TObject);
begin
  CreateMutex(nil,false,'mut');
  ShowMessage('Õåíäë ñîçäàòåëÿ ìüþòåêñà - '+IntToStr(SeekMutantProcess('mut'))
             +#13+'Õåíäë òåêóùåãî ïðîöåññà - '+IntToStr(GetCurrentProcessId));
end;

ЗЫ: мой пост удалили или браузер взглючил? 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)