2013. május 10., péntek

ASP.NET double-postback bug


ASP.NET double-postback bug


THE BUG:
An example of this bug is detailed here:
http://www.velocityreviews.com/forums/t119525-repost-gridview-imagebutton-causes-double-postback.html

It is also detailed here:
http://www.dotnetspider.com/qa/Question8706.aspx

The issue occurs if you have any image tags rendered by your controls which have an empty source. As soon as the browser hits that <img src=""/> tag it does a refresh of the page. The main problem with this double postback is that the second run is NOT a postback - the Page.IsPostBack property is false - but I still have all my viewstate values. This issue is incredibly frustrating as the natural inclination is to look at controls causing partial postbacks - but you'd be looking in the wrong place. I had this issue in IE 6,7 and Firefox 2.


THE FIX:
To stop the double post-backs, just make sure all your ASP.NET controls (Image Buttons, Image Columns in grids, normal Images), all have a src attribute filled in - or otherwise, make them invisible. Otherwise, you will have phantom postbacks coming to haunt you when you least need it

2010. október 28., csütörtök

setting file permission in delphi

In order to change permissions of files in Vista or Win2008 you have to use JWSCL (JEDI Windows Security Code Library)

JwInitWellKnownSIDs;
UserToken := TJwSecurityToken.CreateTokenEffective(MAXIMUM_ALLOWED);
Owner := UserToken.GetTokenOwner;
try
  FileObject := TJwSecureFileObject.Create(FilePath);
  if not FileObject.AccessCheck(WRITE_DAC) then //Make me owner if we cant access DACL
    begin //try to become owner
      JwEnablePrivilege('SeTakeOwnershipPrivilege', pst_Enable);
      FileObject.Owner := Owner;
    end;
  DACL := FileObject.GetDACL;
  DACL.Clear;
  DACL.Add(TJwDiscretionaryAccessControlEntryAllow.Create(nil, [afObjectInheritAce,afContainerInheritAce], GENERIC_ALL, JwUsersSID, false));
  FileObject.SetDACL(DACL);
  FreeAndNil(FileObject);
finally
  FileObject.Free;
end;

2010. október 11., hétfő

get target of symlink in delphi

For more information and C# code click here!


unit Symlink;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

const
  SE_BACKUP_NAME = 'SeBackupPrivilege';
  SYMLINK_PATH = 'your symlink path';
  FILE_FLAG_BACKUP_SEMANTICS = $02000000;
  FILE_FLAG_OPEN_REPARSE_POINT = $00200000;
  FILE_DEVICE_FILE_SYSTEM = 9;
  FILE_ANY_ACCESS = 0;
  FSCTL_GET_REPARSE_POINT = 42;
  METHOD_BUFFERED  = 0;
  MAXIMUM_REPARSE_DATABUFFER_SIZE = 16 * 1024;
  IO_REPARSE_TAG_MOUNT_POINT = $A0000003;  // Moiunt point or junction, see winnt.h
  IO_REPARSE_TAG_SYMLINK = $A000000C;
type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
  _REPARSE_DATA_BUFFER = record
    ReparseTag: DWORD;
    ReparseDataLength: Word;
    Reserved: Word;
    SubstituteNameOffset: Word;
    SubstituteNamelength: Word;
    PrintNameOffset: Word;
    PrintNameLength: Word;
    pathBuffer: array[0..MAXIMUM_REPARSE_DATABUFFER_SIZE] of CHAR;
  end;
  TReparseDataBuffer = _REPARSE_DATA_BUFFER;
var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetSymlinkTarget(aSymlinkPath : String): String;
var
  lSuccess : Boolean;
  lToken : THandle;
  lTokenPrivileges : TOKEN_PRIVILEGES;
  lRLength : Cardinal;
  secAttr: TSecurityAttributes;
  lFileHandle : THandle;
  lControlCode: Cardinal;
  lBytesReturned : Cardinal;
  lReparseBuffer : TReparseDataBuffer;
  iCounter : Integer;
  lTargetPath : String;
begin
  Result := aSymlinkPath;
  lTargetPath := emptyStr;

  //not in all cases, we need to have backup privileges
  lSuccess := OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, lToken);

  if lSuccess
    then
      begin
        lSuccess:= LookupPrivilegeValue(nil,PWideChar(SE_BACKUP_NAME),lTokenPrivileges.Privileges[0].Luid);

        if lSuccess then
          begin
            lTokenPrivileges.PrivilegeCount := 1;
            lTokenPrivileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
            lSuccess := AdjustTokenPrivileges(lToken,false, lTokenPrivileges, sizeOf(lTokenPrivileges),nil,lRlength);
          end;

        CloseHandle(lToken);

        if(lSuccess) then
          begin
            FillChar(secAttr,sizeOf(secAttr),#0);
            secAttr.nLength := sizeof(secAttr);
            secAttr.lpSecurityDescriptor := nil;
            secAttr.bInheritHandle := True;

            // Open the file and get its handle
            lFileHandle := CreateFile(PWideChar(aSymlinkPath), GENERIC_READ, FILE_SHARE_READ, @secAttr, OPEN_ALWAYS,  FILE_FLAG_OPEN_REPARSE_POINT or FILE_FLAG_BACKUP_SEMANTICS, 0);
            if lFileHandle <> 0 then
              begin
                ShowMessage('File is opened ' + SysErrorMessage(GetLastError));
                // Make up the control code - see CTL_CODE on ntddk.h
                lControlCode := (FILE_DEVICE_FILE_SYSTEM shl 16) or (FILE_ANY_ACCESS shl 12) or (FSCTL_GET_REPARSE_POINT shl 2) or METHOD_BUFFERED;

                lSuccess := DeviceIOControl(lFileHandle,lControlCode,nil,0,@lReparseBuffer, MAXIMUM_REPARSE_DATABUFFER_SIZE, lBytesReturned, nil);
                 ShowMessage('DeviceIOControl ' + BoolToSTR(lSuccess) + ' ' + SysErrorMessage(GetLastError));
                if lSuccess then
                  if (lReparseBuffer.ReparseTag = IO_REPARSE_TAG_SYMLINK) then
                    begin
                      for iCounter := 0 to (lReparseBuffer.PrintNameLength div 2) - 1  do
                        begin
                          // for some reason symlinks seem to have an extra two characters on the front
                          lTargetPath := lTargetPath + lReparseBuffer.pathBuffer[(lReparseBuffer.PrintNameOffset div 2) + 2 + iCounter];
                        end;
                      Result := lTargetPath;
                    end;

              end;
            CloseHandle(lFileHandle);
          end;
      end
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   ShowMessage(GetSymlinkTarget(SYMLINK_PATH));
end;
end.

2010. október 7., csütörtök

read 64bit registry entry

A delphi can't read normally the 64bit registry entries. With a small addition you can open it for read:

lReg := TRegistry.Create(KEY_READ or $0100);
lReg.RootKey := HKEY_LOCAL_MACHINE;
lOpenResult := lReg.OpenKey('Software\...',False);

It's important to use OpenKey instead of OpenKeyReadOnly because OpenKeyReadOnly overwrites the access parameter.

preface

This is a technical blog. A place where i can gather all the problems and perheps solutions what I met as a user and developer.