mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: Elevate CreateDirectory, CreateHardLink nad CreateSymbolicLink
This commit is contained in:
parent
a22aab6972
commit
204ca8efd0
6 changed files with 78 additions and 8 deletions
|
|
@ -34,7 +34,7 @@ implementation
|
|||
{$R *.lfm}
|
||||
|
||||
uses
|
||||
LazFileUtils, uLng, uGlobs, uLog, uShowMsg, uOSUtils, DCStrUtils, DCOSUtils;
|
||||
LazFileUtils, uLng, uGlobs, uLog, uShowMsg, DCStrUtils, DCOSUtils, uAdministrator;
|
||||
|
||||
function ShowHardLinkForm(const sExistingFile, sLinkToCreate, CurrentPath: String): Boolean;
|
||||
begin
|
||||
|
|
@ -69,7 +69,7 @@ begin
|
|||
sSrc := GetAbsoluteFileName(FCurrentPath, sSrc);
|
||||
sDst := GetAbsoluteFileName(FCurrentPath, sDst);
|
||||
|
||||
if CreateHardLink(sSrc, sDst) then
|
||||
if CreateHardLinkUAC(sSrc, sDst) then
|
||||
begin
|
||||
// write log
|
||||
if (log_cp_mv_ln in gLogOptions) and (log_success in gLogOptions) then
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ type
|
|||
implementation
|
||||
|
||||
uses
|
||||
uFileSourceOperationUI, uFileProcs, uLog, uLng, uGlobs, DCOSUtils;
|
||||
uFileSourceOperationUI, uLog, uLng, uGlobs, DCOSUtils, uAdministrator;
|
||||
|
||||
constructor TFileSystemCreateDirectoryOperation.Create(
|
||||
aTargetFileSource: IFileSource;
|
||||
|
|
@ -44,11 +44,11 @@ end;
|
|||
|
||||
procedure TFileSystemCreateDirectoryOperation.MainExecute;
|
||||
begin
|
||||
if mbFileGetAttr(AbsolutePath) <> faInvalidAttributes then
|
||||
if FileGetAttrUAC(AbsolutePath) <> faInvalidAttributes then
|
||||
begin
|
||||
AskQuestion(Format(rsMsgErrDirExists, [AbsolutePath]), '', [fsourOk], fsourOk, fsourOk);
|
||||
end
|
||||
else if uFileProcs.mbForceDirectory(AbsolutePath) = False then
|
||||
else if ForceDirectoriesUAC(AbsolutePath) = False then
|
||||
begin
|
||||
if (log_dir_op in gLogOptions) and (log_errors in gLogOptions) then
|
||||
logWrite(Thread, Format(rsMsgLogError+rsMsgLogMkDir, [AbsolutePath]), lmtError);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ implementation
|
|||
{$R *.lfm}
|
||||
|
||||
uses
|
||||
LazFileUtils, uLng, uGlobs, uLog, uShowMsg, uOSUtils, DCStrUtils, DCOSUtils;
|
||||
LazFileUtils, uLng, uGlobs, uLog, uShowMsg, DCStrUtils, DCOSUtils, uAdministrator;
|
||||
|
||||
function ShowSymLinkForm(const sExistingFile, sLinkToCreate, CurrentPath: String): Boolean;
|
||||
begin
|
||||
|
|
@ -73,7 +73,7 @@ begin
|
|||
sSrc:= CreateRelativePath(sSrc, ExtractFileDir(sDst));
|
||||
end;
|
||||
|
||||
if CreateSymLink(sSrc, sDst) then
|
||||
if CreateSymbolicLinkUAC(sSrc, sDst) then
|
||||
begin
|
||||
// write log
|
||||
if (log_cp_mv_ln in gLogOptions) and (log_success in gLogOptions) then
|
||||
|
|
|
|||
|
|
@ -21,8 +21,10 @@ function FileCreateUAC(const FileName: String; Mode: LongWord): System.THandle;
|
|||
function DeleteFileUAC(const FileName: String): LongBool;
|
||||
function RenameFileUAC(const OldName, NewName: String): LongBool;
|
||||
|
||||
function ForceDirectoriesUAC(const Path: String): Boolean;
|
||||
function CreateDirectoryUAC(const Directory: String): Boolean;
|
||||
function RemoveDirectoryUAC(const Directory: String): Boolean;
|
||||
function DirectoryExistsUAC(const Directory : String): Boolean;
|
||||
|
||||
function CreateSymbolicLinkUAC(const Path, LinkName: String) : Boolean;
|
||||
function CreateHardLinkUAC(const Path, LinkName: String) : Boolean;
|
||||
|
|
@ -51,7 +53,8 @@ threadvar
|
|||
implementation
|
||||
|
||||
uses
|
||||
RtlConsts, DCOSUtils, LCLType, uShowMsg, uElevation, uSuperUser, fElevation;
|
||||
RtlConsts, DCStrUtils, DCOSUtils, LCLType, uShowMsg, uElevation, uSuperUser,
|
||||
fElevation;
|
||||
|
||||
resourcestring
|
||||
rsElevationRequired = 'You need to provide administrator permission';
|
||||
|
|
@ -234,6 +237,21 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function DirectoryExistsUAC(const Directory: String): Boolean;
|
||||
var
|
||||
LastError: Integer;
|
||||
begin
|
||||
Result:= mbDirectoryExists(Directory);
|
||||
if (not Result) and ElevationRequired then
|
||||
begin
|
||||
LastError:= GetLastOSError;
|
||||
if RequestElevation(rsElevationRequiredGetAttributes, Directory) then
|
||||
Result:= TWorkerProxy.Instance.DirectoryExists(Directory)
|
||||
else
|
||||
SetLastOSError(LastError);
|
||||
end;
|
||||
end;
|
||||
|
||||
function CreateHardLinkUAC(const Path, LinkName: String): Boolean;
|
||||
var
|
||||
LastError: Integer;
|
||||
|
|
@ -264,6 +282,42 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function ForceDirectoriesUAC(const Path: String): Boolean;
|
||||
var
|
||||
Index: Integer;
|
||||
ADirectory: String;
|
||||
ADirectoryPath: String;
|
||||
begin
|
||||
if Path = '' then Exit;
|
||||
ADirectoryPath := IncludeTrailingPathDelimiter(Path);
|
||||
Index:= 1;
|
||||
if Pos('\\', ADirectoryPath) = 1 then // if network path
|
||||
begin
|
||||
Index := CharPos(PathDelim, ADirectoryPath, 3); // index of the end of computer name
|
||||
Index := CharPos(PathDelim, ADirectoryPath, Index + 1); // index of the end of first remote directory
|
||||
end;
|
||||
|
||||
// Move past path delimiter at the beginning.
|
||||
if (Index = 1) and (ADirectoryPath[Index] = PathDelim) then
|
||||
Index := Index + 1;
|
||||
|
||||
while Index <= Length(ADirectoryPath) do
|
||||
begin
|
||||
if ADirectoryPath[Index] = PathDelim then
|
||||
begin
|
||||
ADirectory:= Copy(ADirectoryPath, 1, Index - 1);
|
||||
|
||||
if not DirectoryExistsUAC(ADirectory) then
|
||||
begin
|
||||
Result:= CreateDirectoryUAC(ADirectory);
|
||||
if not Result then Exit;
|
||||
end;
|
||||
end;
|
||||
Inc(Index);
|
||||
end;
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
{ TFileStreamUAC }
|
||||
|
||||
procedure TFileStreamUAC.SetSize64(const NewSize: Int64);
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ type
|
|||
function CreateSymbolicLink(const Path, LinkName: String): LongBool; inline;
|
||||
function CreateDirectory(const Directory: String): LongBool; inline;
|
||||
function RemoveDirectory(const Directory: String): LongBool; inline;
|
||||
function DirectoryExists(const Directory: String): LongBool; inline;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
|
|
@ -411,6 +412,11 @@ begin
|
|||
Result:= ProcessObject(RPC_RemoveDirectory, Directory);
|
||||
end;
|
||||
|
||||
function TWorkerProxy.DirectoryExists(const Directory: String): LongBool;
|
||||
begin
|
||||
Result:= ProcessObject(RPC_DirectoryExists, Directory);
|
||||
end;
|
||||
|
||||
constructor TWorkerProxy.Create;
|
||||
begin
|
||||
FClient:= TPipeTransport.Create(WorkerAddress + IntToStr(GetProcessID));
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ const
|
|||
|
||||
RPC_CreateDirectory = 5;
|
||||
RPC_RemoveDirectory = 6;
|
||||
RPC_DirectoryExists = 13;
|
||||
|
||||
type
|
||||
|
||||
|
|
@ -218,6 +219,15 @@ begin
|
|||
ATransport.WriteBuffer(Result, SizeOf(Result));
|
||||
ATransport.WriteBuffer(LastError, SizeOf(LastError));
|
||||
end;
|
||||
RPC_DirectoryExists:
|
||||
begin
|
||||
FileName:= ARequest.ReadAnsiString;
|
||||
DCDebug('DirectoryExists ', FileName);
|
||||
Result:= mbDirectoryExists(FileName);
|
||||
LastError:= GetLastOSError;
|
||||
ATransport.WriteBuffer(Result, SizeOf(Result));
|
||||
ATransport.WriteBuffer(LastError, SizeOf(LastError));
|
||||
end;
|
||||
RPC_Terminate: Halt;
|
||||
end;
|
||||
end;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue