Snake Force / Ana Sayfa
Forum Anasayfası Forum Anasayfası > Programlama > Win32 Api
  Aktif Konular Aktif Konular
  SSS SSS  Forumu Ara   Kayıt Ol Kayıt Ol  Giriş Giriş


Win32 Api : Pipe's

 Yanıt Yaz Yanıt Yaz
Anket Sorusu: Bu tip api'ler hakkında örnekler vermeye devam edelimmi?
Oy Anket Seç Oylar Anket İstatistikleri
15 [83,33%]
2 [11,11%]
0 [0,00%]
1 [5,56%]

Yazar
Mesaj
  Konu Arama Konu Arama  Konu Seçenekleri Konu Seçenekleri
StreAmeR Açılır Kutu Gör
Yönetici
Yönetici
Simge

Kayıt Tarihi: 01/Ocak/2006
Konum: İstanbul
Aktif Durum: Aktif Değil
Gönderilenler: 107
  Alıntı StreAmeR Alıntı  Yanıt YazCevapla Mesajın Direkt Linki Konu: Win32 Api : Pipe's
    Gönderim Zamanı: 14/Nisan/2007 Saat 20:41
PIPE'lere ilk ihtiyaç duyduğum zaman, command prompt altında yaptığım "ping" sonuçlarını bire bir görmek istemiştim. Shell32Exec veya muadili execute api'leri ile komutu çalıştırabilyor ancak bir command-prompt penceresi açarak sonucu görebiliyordum. Bu da benim ve programımım görselliği açısından pek hoş olmuyordu. Amacım bu tarama sonuçlarını programıma ait pencerede kendisi için ayırdığım bir panel'de görünmesiydi.

               Aslında itiraf etmek gerekirse bu iş için microsoftun bir api sağladığını ilk aşamada düşünmemiştim. Bende kendi basit çözümümü devreye koyup sonuç çıktısını bir dosyaya yazdırıp tekrar oradan okuyup ekrana yazdırıyordum ki, bu iğrenç çözüm hiçte içime yatmamıştı. Araştırmalarım esnasında processler hakkında okuduğum makalelerin birinde Pipe'ler ile tanıştım.

               PIPE'ler Unnamed ve Named olarak iki kısımda irdelenir. Named olanlar biraz daha gelişmiş ipc tarzı işlem yapmak isteyenler için faydalıdır. Unnamed olanlar ise bizim ilgilendiğimiz ve her process için iki handle sağlayan tipleridir.  Win32 Process mimarisinde her çalışan process alanı için PROCESS_INFORMATION ve STARTUP_INFORMATION structları vardır. Bu yapılar sayesinde Create edeceğiniz veya Create edilmiş işlemlerden bilgi yazabilirsiniz/okuyabilirsiniz.

               Uygulamalarımızda Pipe'ler ile çalışabilmek için bazı ön hazırlıklar yapmalıyız. Bunlar yukarıda da yazdığım Structları tanımlamaktan ibarettir. Win32 uygulamanızda Unnamed pipe'ler ile çalışabilmek içi microsoftun bize sunduğu api "CreatePipe" api'sidir. SDK'da tanımlandığı gibi protoype'i aşağıda ki gibidir.

BOOL CreatePipe(

    PHANDLE hReadPipe, // okunacak veriler icin kullanilicak handle'in adresi
    PHANDLE hWritePipe, // yazilacak veriler icin kullanilicak handle'in adresi  
    LPSECURITY_ATTRIBUTES lpPipeAttributes, // security attributes yapısına pointer
    DWORD nSize  // pipe islemleri icin ayrilacak buffer (bu alanin miktarini siz belirteceksiniz) 
   ); 
 

Parametreler

hReadPipe

32 bitlik bir handle pointer'idir. Bu handle sayesinde pipe'mizin okuma ucundaki bilgileri ReadFile api'si ile istediğimiz bir hafıza alanına taşıyabiliriz. Uygulama içerisindeki kullanımı aşağıdaki örneklerde yer alıyor.

hWritePipe

32 bitlik bir handle pointer'idir. Bu handle sayesinde pipe'mizin yazma ucuna koyduğumuz bilgileri WriteFile api'si ile STARTUPINFO yapısı kullanılarak belirtilen hafıza alanına koyabiliriz.

lpPipeAttributes

Aslında bu yapının amacı belirtilen SECURITY_ATTRIBUTES niteliklerinin child process'lere(yani çağrılan processlere) de geçip geçmeyeceği ile ilgilidir. Eğer bu tanımlamayı yapmaz ve boş geçer iseniz üzülürsünüz. Bi daha gidip alt process için gereksiz yere SECURITY_ATTRIBUTES yapısı build edersiniz. 

nSize

Pipe için buffer boyutunu belirtir. İstenilen boyut girilebilir ancak null geçip varsayılan boyutu sistemin sizin için ayarlamasınıda sağlayabilirsiniz.

Return Values

Fonksiyon herhangi bir problem ile karşılaşmaz ve görevini başarı ile yerine getirirse geriye sıfır harici rastgale bir sayı döndürür.
Eğer herhangi bir sebepten dolayı bir hata ile karşılaşır ise geriye sıfır değerini dönderir. Hata kodunun ne anlam içerdiğini bulabilmek için ise GetLastError api'si kullanılabilir.

               Sizde uygulamanızda console uygulamaları ile i/o işlemi yapacak ve sonuçları özelleştirip programınızda kullanacaksanız Anonymous Pipe'ler bu işler için çok uygundur. Aşağıda kodlarını verdiğim VBScript ve Masm32 kodlarını derleğip nasıl çalıştıkları hakkında daha tefferruatlı bilgi sahibi olabilirsiniz.


 

;developed by StreAmeR bilgislem@hotmail.com 20:25 29.12.2004
.386
.model flat,stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
include \masm32\include\gdi32.inc
includelib \masm32\lib\gdi32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD

.const
IDR_MAINMENU equ 101
IDM_ASSEMBLE equ 40001

.data
ClassName db "StrPipeClass",0
AppName  db "Tek-yönlü Pipe Örnegi ve 3 Asamali Thread",0
EditClass db "EDIT",0
CreatePipeError db "Pipe olusumu esnasında hata ile karsilasldi",0
CreateProcessErr db "Islem olusturulurken hata ile karsilasildi",0
CommandLine db "c:\windows\system32\cmd /c cd&dir C: /s/a",0
Command2 db "c:\windows\system32\netstat -a",0
Command3 db "c:\windows\system32\ipconfig -all",0

.data?
hInstance HINSTANCE ?
hwndEdit dd ?
ThreadID DWORD ?
count  db ?

.code
start:
 invoke GetModuleHandle,NULL
 mov hInstance,eax
 mov byte ptr[count],0
 invoke WinMain,hInstance,NULL,NULL,SW_SHOWDEFAULT
 invoke ExitProcess,eax
WinMain proc hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
 LOCAL wc:WNDCLASSEX
 LOCAL msg:MSG
 LOCAL hwnd:HWND
 
 mov wc.cbSize,SIZEOF WNDCLASSEX
 mov wc.style, CS_HREDRAW+CS_VREDRAW
 mov wc.lpfnWndProc,OFFSET WndProc
 mov wc.cbClsExtra,NULL
 mov wc.cbWndExtra,NULL
 push hInst
 pop wc.hInstance
 mov wc.hbrBackground,COLOR_APPWORKSPACE
 mov wc.lpszMenuName,IDR_MAINMENU
 mov wc.lpszClassName,OFFSET ClassName
 invoke  LoadIcon,NULL,IDI_APPLICATION
 mov wc.hIcon,eax
 mov wc.hIconSm,eax
 invoke LoadCursor,NULL,IDC_ARROW
 mov wc.hCursor,eax

 invoke RegisterClassEx,addr wc
 invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR ClassName,ADDR AppName,
  WS_OVERLAPPEDWINDOW+WS_VISIBLE,640,
  480,400,200,NULL,NULL,
  hInst,NULL
 mov hwnd,eax
 
 .while TRUE
  invoke GetMessage,ADDR msg,NULL,0,0
  .BREAK .IF (!eax)
  invoke TranslateMessage, ADDR msg
  invoke DispatchMessage, ADDR msg
 .endw
 mov eax,msg.wParam
 ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT,wParam:WPARAM,lParam:LPARAM
 LOCAL rect:RECT
 LOCAL hdc:DWORD

 .if uMsg == WM_CREATE
  invoke CreateWindowEx,NULL,addr EditClass,NULL,
   WS_CHILD+WS_VISIBLE+ES_MULTILINE+ES_AUTOHSCROLL+ES_AUTOVSCROLL,
   0,0,0,0,hWnd,NULL,hInstance,NULL
  mov hwndEdit,eax
 .elseif uMsg==WM_CTLCOLOREDIT
  invoke SetTextColor,wParam,Yellow
  invoke SetBkColor,wParam,Black
  invoke GetStockObject,BLACK_BRUSH
  ret
 .elseif uMsg==WM_SIZE
  mov edx,lParam
  mov ecx,edx
  shr ecx,16
  and edx,0ffffh
  invoke MoveWindow,hwndEdit,0,0,edx,ecx,TRUE
 .elseif uMsg==WM_COMMAND
  .if lParam==0
   mov eax,wParam
   .if ax==IDM_ASSEMBLE
    mov  eax,OFFSET ThreadProc
    invoke CreateThread,NULL,NULL,eax,
                                        NULL,NORMAL_PRIORITY_CLASS,
                                        ADDR ThreadID
    invoke CloseHandle,eax
   .endif
  .endif
 .elseif uMsg==WM_DESTROY
   invoke PostQuitMessage,NULL
  .else
   invoke DefWindowProc,hWnd,uMsg,wParam,lParam
   ret
.endif
  xor eax,eax
  ret
WndProc endp

ThreadProc proc hWnd:HWND
 LOCAL hRead:DWORD
 LOCAL hWrite:DWORD
 LOCAL startupinfo:STARTUPINFO
 LOCAL pinfo:PROCESS_INFORMATION
 LOCAL buffer[4096]:byte
 LOCAL bytesRead:DWORD
 LOCAL sat:SECURITY_ATTRIBUTES

 mov sat.nLength,sizeof SECURITY_ATTRIBUTES
 mov sat.lpSecurityDescriptor,NULL
 mov sat.bInheritHandle,TRUE
 invoke CreatePipe,addr hRead,addr hWrite,addr sat,addr buffer
  .if eax==NULL
   invoke MessageBox,hWnd,addr CreatePipeError,addr AppName,MB_ICONERROR+MB_OK
  .else
   mov startupinfo.cb,sizeof STARTUPINFO
   invoke GetStartupInfo,addr startupinfo
   mov eax,hWrite
   mov startupinfo.hStdOutput,eax
   mov startupinfo.hStdError,eax
   mov startupinfo.dwFlags,STARTF_USESHOWWINDOW+STARTF_USESTDHANDLES
   mov startupinfo.wShowWindow,SW_HIDE
   inc byte ptr[count]

   .if count==1
    invoke CreateProcess,NULL,addr CommandLine,NULL,NULL,TRUE,NULL,NULL,NULL,
    addr startupinfo,addr pinfo

   .elseif count==2
    invoke CreateProcess,NULL,addr Command2,NULL,NULL,TRUE,NULL,NULL,NULL,
    addr startupinfo,addr pinfo
   .elseif count==3
    invoke CreateProcess,NULL,addr Command3,NULL,NULL,TRUE,NULL,NULL,NULL,
    addr startupinfo,addr pinfo
    mov byte ptr[count],0
   .endif

  .if eax==NULL
   invoke MessageBox,hWnd,Addr CreateProcessErr,addr AppName,MB_ICONERROR+MB_OK
  .else
   invoke CloseHandle,hWrite
  .while TRUE
   invoke RtlZeroMemory,addr buffer,4096
   invoke ReadFile,hRead,addr buffer,4095,addr bytesRead,NULL
   .if eax==NULL
   .break
   .else
   invoke SendMessage,hwndEdit,EM_SETSEL,-1,0
   invoke SendMessage,hwndEdit,EM_REPLACESEL,FALSE,addr buffer
  .endif
  .endw
  .endif
   invoke CloseHandle,hRead
   ret
  .endif

ThreadProc endp


end start 


 

Bunuda Excel'de macro alanında deneyebilirsiniz. Yaptığı iş ilgili hücreden aldığı ip adresine ping atıp sonuçları belirtilen hücrelere yazmaktır. Bir nevi ip scanner işte.

 


'Developed by StreAmeR with Win32Api
'bilgislem@hotmail.com; loginit@gmail.com


Option Base 1
Option Explicit

Private Declare Function CreatePipe Lib "Kernel32" ( _
    phReadPipe As Long, _
    phWritePipe As Long, _
    lpPipeAttributes As Any, _
    ByVal nSize As Long) As Long

Private Declare Function ReadFile Lib "Kernel32" ( _
    ByVal hFile As Long, _
    ByVal lpBuffer As String, _
    ByVal nNumberOfBytesToRead As Long, _
    lpNumberOfBytesRead As Long, _
    ByVal lpOverlapped As Any) As Long
   
Private Declare Function GetSystemDirectoryA Lib "Kernel32" ( _
    lpBuffer As String, iSize As Long) As Long
    
  
Private Type SECURITY_ATTRIBUTES
    nLength As Long
    lpSecurityDescriptor As Long
    bInheritHandle As Long
End Type

Private Type STARTUPINFO
    cb As Long
    lpReserved As Long
    lpDesktop As Long
    lpTitle As Long
    dwX As Long
    dwY As Long
    dwXSize As Long
    dwYSize As Long
    dwXCountChars As Long
    dwYCountChars As Long
    dwFillAttribute As Long
    dwFlags As Long
    wShowWindow As Integer
    cbReserved2 As Integer
    lpReserved2 As Long
    hStdInput As Long
    hStdOutput As Long
    hStdError As Long
End Type

Private Type PROCESS_INFORMATION
    hProcess As Long
    hThread As Long
    dwProcessId As Long
    dwThreadID As Long
End Type

Private Declare Function CreateProcessA Lib "Kernel32" (ByVal _
   lpApplicationName As Long, ByVal lpCommandLine As String, _
   lpProcessAttributes As Any, lpThreadAttributes As Any, _
   ByVal bInheritHandles As Long, ByVal dwCreationFlags As Long, _
   ByVal lpEnvironment As Long, ByVal lpCurrentDirectory As Long, _
   lpStartupInfo As Any, lpProcessInformation As Any) As Long

Private Declare Function WaitForSingleObject Lib "Kernel32" _
    (ByVal hHandle As Long, ByVal dwMilliseconds As Long) As Long

Private Declare Function CloseHandle Lib "Kernel32" (ByVal _
   hObject As Long) As Long

Const SW_SHOWMINNOACTIVE = 7
Const SW_HIDE = 0
Const STARTF_USESHOWWINDOW = &H1
Const INFINITE = -1&
Private Const NORMAL_PRIORITY_CLASS = &H20&
Private Const STARTF_USESTDHANDLES = &H100&

Dim ExecCmd As String
Private Function ExecCmdPipe(ByVal CmdLine As String) As String
   
    Dim proc As PROCESS_INFORMATION, ret As Long, bSuccess As Long
    Dim start As STARTUPINFO
    Dim sa As SECURITY_ATTRIBUTES
    Dim hReadPipe As Long, hWritePipe As Long
    Dim bytesread As Long, mybuff As String
    Dim i As Integer

    Dim sReturnStr As String
   
mybuff = String(10 * 1024, Chr$(65))
sa.nLength = Len(sa)
sa.bInheritHandle = 1&
sa.lpSecurityDescriptor = 0&
ret = CreatePipe(hReadPipe, hWritePipe, sa, 0)
    If ret = 0 Then
        ExecCmd = "Hata. CreatePipe icra edilmeye çalışılırken durdu. " & Err.LastDllError
        Exit Function

    End If
   
start.cb = Len(start)
start.hStdOutput = hWritePipe
start.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW
start.wShowWindow = SW_HIDE

ret& = CreateProcessA(0&, CmdLine$, sa, sa, 1&, _
        NORMAL_PRIORITY_CLASS, 0&, 0&, start, proc)
   
    If ret <> 1 Then
        sReturnStr = "Hata: CreateProcess çalıştırılamadı ." & Err.LastDllError
    End If

ret = WaitForSingleObject(proc.hProcess, INFINITE)

bSuccess = ReadFile(hReadPipe, mybuff, Len(mybuff), bytesread, 0&)
    If bSuccess = 1 Then
        sReturnStr = Left(mybuff, bytesread)
    Else
        sReturnStr = "Error: ReadFile durdu. " & Err.LastDllError
    End If
   
    ret = CloseHandle(proc.hProcess)
    ret = CloseHandle(proc.hThread)
    ret = CloseHandle(hReadPipe)
    ret = CloseHandle(hWritePipe)
   
    ExecCmd = sReturnStr
End Function


Sub Pipe()
Dim s, coz As String
Dim Aranacak, Aranan, bulunan, f, al, kez, i, satir
Dim say As Integer
satir = 2
kez = Sheets("Sayfa1").Range("E4")
Aranacak = Sheets("Sayfa1").Range("C4")
bulunan = InStr(1, Aranacak, ".", vbTextCompare)
bulunan = InStr(bulunan + 1, Aranacak, ".", vbTextCompare)
bulunan = InStr(bulunan + 1, Aranacak, ".", vbTextCompare)
al = Mid$(Aranacak, 1, bulunan)
bulunan = Mid$(Aranacak, bulunan + 1, 3)

For i = 1 To kez
s = al & bulunan
Sheets("Sayfa1").Range("C4") = s
s = "c:windowssystem32ping " & s & " -n 1"
ExecCmdPipe (s)
Aranan = "Kaybolan = 0"
coz = ExecCmd
f = InStr(1, coz, Aranan, vbTextCompare)
If f = 0 Then
    Sheets("Sayfa1").Range("b" & satir) = Sheets("Sayfa1").Range("C4") & " ip'li makine deaktiv"
Else
Sheets("Sayfa1").Range("b" & satir) = Sheets("Sayfa1").Range("C4") & " ip'li makine aktif"
End If
satir = satir + 1
bulunan = bulunan + 1
Next
End Sub


Pipe'lerde bir de şöyle bir zaaf vardır ki çok uzun buffer gerektiren işlemlerde ve birebir aynı anda i/o gerektiren uygulamalarda yetersiz kalıyor. Örneğin tüm partition'in çıktısını almaya çalıştığınız bir "dir c: /s/a" işleminde süreç devam ediyor ancak çıktı alma işlemi yarıda kesilebiliyor. Ayrıca 7zip gibi sıkıştırma işlemini ekrana anlık olarak istatistik veren uygulamalarda da uzun süreli gecikmeler yaşanıyor. Ama yinede bu kadar kabahat kadı kızında da olur diyor ve kullanmaya devam ediyoruz.

"Don't be in a hurry to condemn because he doesn't do what you do or think as you think or as fast. There was a time when you didn't know what you know today"
Yukarı Dön
 Yanıt Yaz Yanıt Yaz

Forum Atla Forum İzinleri Açılır Kutu Gör

Bulletin Board Software by Web Wiz Forums® version 9.06
Copyright ©2001-2007 Web Wiz

Bu Sayfa 0,109 Saniyede Yüklendi.