DelphiSiWin32

Win32 api funkcije.
Odgovori
Uporabniški avatar
gabr
Prispevkov: 4129
Pridružen: 28.08.2001 14:10:47

DelphiSiWin32

Odgovor Napisal/-a gabr » 17.01.2008 08:54:40

Zanimivo je tole ...

Zdumpal sem vse SIDe, ki jih vrne GetTokenInformation. Na moji mašini so to BUILTIN\ADMINISTRATORS, \EVERYONE in moj uporabniški SID. Na mašini od kolega (ki ima Visto z local admin pravicami priključeno v domeno, kjer ima domain admin pravice) vrne zadeva enake SIDe. Razlika je v tem, da ima BUILTIN\ADMINISTRATORS pri meni prižgane atribute SE_GROUP_MANDATORY, SE_GROUP_ENABLED_BY_DEFAULT, SE_GROUP_ENABLED in SE_GROUP_OWNER, pri njemu pa samo SE_GROUP_USE_FOR_DENY_ONLY.

Malo sem brskal po MSDN in našel tole:
SE_GROUP_ENABLED
A SID with this attribute is enabled for access checks. When the system performs an access check, it checks for access control entries (ACEs) that apply to the SID.

SE_GROUP_USE_FOR_DENY_ONLY
Since Windows 2000, a SID with this attribute is a deny-only SID. When the system performs an access check, it checks for ACEs that deny access to the SID. It ignores ACEs that allow access for the SID.


Both attributes are mutually exclusive. If one attribute is set, the other cannot be set. If neither attribute is set, the SID is ignored. Moreover, no process is ever allowed to remove a deny-only attribute from a SID.
Verjetno bo res najbolje, da v DSiIsAdmin enostavno skinem čekiranje SE_GROUP_ENABLED.

Gp

Uporabniški avatar
gabr
Prispevkov: 4129
Pridružen: 28.08.2001 14:10:47

DelphiSiWin32

Odgovor Napisal/-a gabr » 14.03.2008 10:07:14

DSiWin32 1.36a.
  • [-]Novi proceduri: DSiCenterRectInRect, DSiMakeRectFullyVisibleOnRect.
    [-]DSiIsAdmin je popravljen (hvala vsem, ki ste pomagali).
    [-]Dodan DSiTerminateProcessById.
    [-]Dodani trije preformance counter helperji: DSiPerfCounterToMS, DSiPerfCounterToUS, and DSiQueryPerfCounterAsUS.
Standardna lokacija: http://gp.17slon.com/gp/files/dsiwin32.zip

Gp

MP002
Prispevkov: 735
Pridružen: 21.02.2002 15:39:44

DelphiSiWin32

Odgovor Napisal/-a MP002 » 28.04.2008 13:13:28

Dokler sem pri delu s clipboardom uporabljal samo tekst, si sploh nisem mislil, da za kej druzga stvar ni tolk trivialna.
Tu bi meu lahko še pa še funkcionalnosti.
No, men je maltralo kako spravit nek poljeben html notr (link konkretno), da v raznih editorjih, ki HTML podpirajo ne kaže kodo pač pa "rezultat".
Hotu sem neki na hitrce narst, na koncu pa porabil dve uri.
Pomagal sem si z Googlom, vendar je bilo treba iz zastarelih primerov zlepit eno delujočo stvar.

Evo rezultat, da se ne bo še kdo zaeb*** po nepotrebnem:

Koda: Izberi vse

function GetHTMLTextFromClipBoard : string;
var
  CF_HTML: word;
  h: THandle;
  p: Pchar;
  start_idx, end_idx : integer;
begin
  CF_HTML := RegisterClipboardFormat('HTML Format');
  if IsClipboardFormatAvailable(CF_HTML) then
  begin
    OpenClipboard(Application.Handle);
    h := GetClipboardData(CF_HTML);
    p  := GlobalLock(h);
    GlobalUnlock(h);
    CloseClipboard();
  end;
  start_idx := Pos('<!--StartFragment-->', p); // len = 20
  end_idx := Pos('<!--EndFragment-->', p);
  Result := Copy(p, start_idx + 20, end_idx - start_idx - 20);
end;

procedure CopyHTMLToClipBoard(s_html : string; s_text : string = '');
  function MakeFragment(HTML: string) : string;

  // Helper routine to build a properly-formatted HTML fragment.

  const
    Version = 'Version:1.0'#13#10;
    StartHTML = 'StartHTML:';
    EndHTML = 'EndHTML:';
    StartFragment = 'StartFragment:';
    EndFragment = 'EndFragment:';
    HTMLIntro = '<html><head><title>HTML clipboard</title></head><body><!--StartFragment-->';
    HTMLExtro = '<!--EndFragment--></body></html>';
    NumberLengthAndCR = 10;

    // Let the compiler determine the description length.
    DescriptionLength = Length(Version) + Length(StartHTML) + Length(EndHTML) + Length(StartFragment) +
      Length(EndFragment) + 4 * NumberLengthAndCR;

  var
    Description: string;
    StartHTMLIndex,
    EndHTMLIndex,
    StartFragmentIndex,
    EndFragmentIndex: Integer;

  begin
    if s_text = '' then s_text := s_html;
    // The HTML clipboard format is defined by using byte positions in the entire block where HTML text and
    // fragments start and end. These positions are written in a description. Unfortunately the positions depend on the
    // length of the description but the description may change with varying positions.
    // To solve this dilemma the offsets are converted into fixed length strings which makes it possible to know
    // the description length in advance.
    StartHTMLIndex := DescriptionLength;              // position 0 after the description
    StartFragmentIndex := StartHTMLIndex + Length(HTMLIntro);
    EndFragmentIndex := StartFragmentIndex + Length(HTML);
    EndHTMLIndex := EndFragmentIndex + Length(HTMLExtro);

    Description := Version +
      SysUtils.Format('%s%.8d', [StartHTML, StartHTMLIndex]) + #13#10 +
      SysUtils.Format('%s%.8d', [EndHTML, EndHTMLIndex]) + #13#10 +
      SysUtils.Format('%s%.8d', [StartFragment, StartFragmentIndex]) + #13#10 +
      SysUtils.Format('%s%.8d', [EndFragment, EndFragmentIndex]) + #13#10;
    Result := Description + HTMLIntro + HTML + HTMLExtro;
  end;
var
  gMem: HGLOBAL;
  lp: PChar;
  Strings: array[0..1] of string;
  Formats: array[0..1] of UINT;
  i: Integer;
begin
  gMem := 0;
  {$IFNDEF USEVCLCLIPBOARD}
  Win32Check(OpenClipBoard(0));
  {$ENDIF}
  try
    //most descriptive first as per api docs
    Strings[0] := MakeFragment(s_html);
    Strings[1] := s_text;
    Formats[0] := RegisterClipboardFormat('HTML Format');
    Formats[1] := CF_TEXT;
    {$IFNDEF USEVCLCLIPBOARD}
    Win32Check(EmptyClipBoard);
    {$ENDIF}
    for i := 0 to High(Strings) do
    begin
      if Strings[i] = '' then Continue;
      //an extra "1" for the null terminator
      gMem := GlobalAlloc(GMEM_DDESHARE + GMEM_MOVEABLE, Length(Strings[i]) + 1);
      {Succeeded, now read the stream contents into the memory the pointer points at}
      try
        Win32Check(gmem <> 0);
        lp := GlobalLock(gMem);
        Win32Check(lp <> nil);
        CopyMemory(lp, PChar(Strings[i]), Length(Strings[i]) + 1);
      finally
        GlobalUnlock(gMem);
      end;
      Win32Check(gmem <> 0);
      SetClipboardData(Formats[i], gMEm);
      Win32Check(gmem <> 0);
      gmem := 0;
    end;
  finally
    {$IFNDEF USEVCLCLIPBOARD}
    Win32Check(CloseClipBoard);
    {$ENDIF}
  end;
end;
Primer klica:
CopyHTMLToClipBoard(<a href="http://www.delphi-si">Delphi-SI</a>");
CopyHTMLToClipBoard(<a href="http://www.delphi-si">Delphi-SI</a>", "Ta urejevalnik ne podpira HTML kode.");

Se mi zdi, da teh funkcij lahko daš še pa še... ker očitno Delphi implementacija je mal boga.
Me je pa navdušlo tole: custom clipboard formats.
To bi bilo zanimivo na nivojev recordov, datasetov,... iiiiii...

Uporabniški avatar
gabr
Prispevkov: 4129
Pridružen: 28.08.2001 14:10:47

DelphiSiWin32

Odgovor Napisal/-a gabr » 29.04.2008 09:54:10

Zanimivo, se strinjam.

Čisto mimogrede - v GetHTMLTextFromClipboard delaš z neinicializirano spremenljivko 'p', kadar na odložišču ni HTML formata.

Gp

Uporabniški avatar
gabr
Prispevkov: 4129
Pridružen: 28.08.2001 14:10:47

DelphiSiWin32

Odgovor Napisal/-a gabr » 29.04.2008 10:48:09

Aaaaarg, kakšna nagnusna koda! Se vidi, da si jo zguglal in da jo je spravil skupaj folk, ki o Win32 ne ve nič :(((

Testi na napačnih mestih, manjkajoči testi, odklepanja, ki so narobe sparjena z zaklepanji in še in še ...

Zdaj imam skoraj že porihtano, ampak sem moral zatulit, da se sprostim.

Gp

Uporabniški avatar
gabr
Prispevkov: 4129
Pridružen: 28.08.2001 14:10:47

DelphiSiWin32

Odgovor Napisal/-a gabr » 29.04.2008 11:13:28

DSiWin32 1.38
  • [-]Funkcije za delo s HTML formatom na odložišču: DSiIsHtmlFormatOnClipboard, DSiGetHtmlFormatFromClipboard, DSiCopyHtmlFormatToClipboard.
    [-]Družina funkcij DSiInterlocked*64, ki jo je prispeval Will DeWitt Jr.
    [-]DSiYield.
Standardna lokacija: http://gp.17slon.com/gp/files/dsiwin32.zip

Gp

MP002
Prispevkov: 735
Pridružen: 21.02.2002 15:39:44

DelphiSiWin32

Odgovor Napisal/-a MP002 » 29.04.2008 19:34:30

Hehehe!
No, očitno je stvar prišla pravi osebi v roke.

GJ
Prispevkov: 1078
Pridružen: 13.03.2004 12:34:48

DelphiSiWin32

Odgovor Napisal/-a GJ » 29.04.2008 23:16:37

@Gabr
Sem si po dolgem času pogledal malo spet knjižnico, če je kaj novega.. :D

Glej glej vidm, da si tudi atomic funkcije oziroma Interlocked funkcije notr spravu..
Ne vem od kje si tole preplonku ampak mi je v uč padl tole..

Koda: Izberi vse

 
function DSiInterlockedExchange64(var target: int64; value: int64): int64; register;
asm
{     ->          EAX     target }
{                 ESP+4   value  }
{     <-          EDX:EAX Result }
          PUSH    EDI
          PUSH    EBX

          MOV     EDI, EAX

          MOV     EAX, [EDI]
          MOV     EDX, [EDI+4]

          MOV     EBX, DWORD PTR [value]
          MOV     ECX, DWORD PTR [value+4]
@@1:
LOCK      CMPXCHG8B [EDI]
          JNZ     @@1
          // Returns initial value in target

          POP     EBX
          POP     EDI
end; { DSiInterlockedExchange64 }
 
Tole ni safe trade ampak trouble trade.. :D
Narobe je tole..

Koda: Izberi vse

  
LOCK      CMPXCHG8B [EDI]
          JNZ     @@1
Sicer se napaka redko zgodi ampak, ko pa se, trade zmrzne!
Vrednost [EDI] se glede na EAX in EDX med tem, ko si jih bral lahko spremeni in sledi zamrznitev thrada!
Pravilno je..

Koda: Izberi vse

  
function DSiInterlockedExchange64(var target: int64; value: int64): int64; register;
asm
{     ->          EAX     target }
{                 ESP+4   value  }
{     <-          EDX:EAX Result }
          PUSH    EDI
          PUSH    EBX

          MOV     EDI, EAX

          MOV     EBX, DWORD PTR [value]
          MOV     ECX, DWORD PTR [value+4]
@@1:
          MOV     EAX, [EDI]
          MOV     EDX, [EDI+4]
LOCK      CMPXCHG8B [EDI]
          JNZ     @@1
          // Returns initial value in target

          POP     EBX
          POP     EDI
end; { DSiInterlockedExchange64 }
 
Al pa jest ne vem kaj ta funkcija počne sploh..:P
Pa vse ostale funkcije kjer testiraš Z flag po CMPXCHG8B imajo isto napakico..

LP :D GJ
Zadnjič spremenil GJ, dne 29.04.2008 23:21:10, skupaj popravljeno 1 krat.
Kdor se zadnji smeje, se smeje zadnji!

Uporabniški avatar
gabr
Prispevkov: 4129
Pridružen: 28.08.2001 14:10:47

DelphiSiWin32

Odgovor Napisal/-a gabr » 29.04.2008 23:30:32

Saj piše v headerju, od kje sem jih dobil. Sem prebrskal cel net gori in doli in so to edine Interlocked64 funkcije, ki sem jih našel. Pravilnosti pa nisem kaj dosti gledal - priznam.

Bom spravil tvoje pripombe do avtorja, da vidimo, kaj bo povedal.

Gp

GJ
Prispevkov: 1078
Pridružen: 13.03.2004 12:34:48

DelphiSiWin32

Odgovor Napisal/-a GJ » 30.04.2008 00:02:43

Saj piše v headerju, od kje sem jih dobil. Sem prebrskal cel net gori in doli in so to edine Interlocked64 funkcije, ki sem jih našel. Pravilnosti pa nisem kaj dosti gledal - priznam.

Bom spravil tvoje pripombe do avtorja, da vidimo, kaj bo povedal.

Gp
Aha sem najdu!

He, he..
Glej..

Koda: Izberi vse

  
          MOV     EAX, [EDI]
          MOV     EDX, [EDI+4]
@@1:
LOCK      CMPXCHG8B [EDI]
          JNZ     @@1
Najprej naložiš z lokacije [EDI] 64 bitno vrednost v EAX in EDX!
Nakar sledi 'LOCK CMPXCHG8B [EDI]', če je vrednost ostala nespremenjena se izvrši zamenjava z ECX in EBX drugače pa se zacikla!
Zanka ostane zaciklana toliko časa dokler je ne vrže ven thrade timer ali pa se po naključju najde na lokaciji [EDI] ponovno vrednost, ki se nahaja v EAX in EDX.

Ni kej mislt!
Funkcija na enoprocesorski mašini še dela, na več procesorski pa se lahko zacikla in to nikoli ne veš kdaj!

LP :D GJ
Zadnjič spremenil GJ, dne 30.04.2008 00:05:02, skupaj popravljeno 1 krat.
Kdor se zadnji smeje, se smeje zadnji!

Odgovori