Exemplo n.º 1
0
/*
 * @implemented
 */
BOOL
WINAPI
CopyFileExA(IN LPCSTR lpExistingFileName,
            IN LPCSTR lpNewFileName,
            IN LPPROGRESS_ROUTINE lpProgressRoutine OPTIONAL,
            IN LPVOID lpData OPTIONAL,
            IN LPBOOL pbCancel OPTIONAL,
            IN DWORD dwCopyFlags)
{
    BOOL Result = FALSE;
    UNICODE_STRING lpNewFileNameW;
    PUNICODE_STRING lpExistingFileNameW;

    lpExistingFileNameW = Basep8BitStringToStaticUnicodeString(lpExistingFileName);
    if (!lpExistingFileName)
    {
        return FALSE;
    }

    if (Basep8BitStringToDynamicUnicodeString(&lpNewFileNameW, lpNewFileName))
    {
        Result = CopyFileExW(lpExistingFileNameW->Buffer,
                             lpNewFileNameW.Buffer,
                             lpProgressRoutine,
                             lpData,
                             pbCancel,
                             dwCopyFlags);

        RtlFreeUnicodeString(&lpNewFileNameW);
    }

    return Result;
}
Exemplo n.º 2
0
BOOL My_CopyFileExW()
{
	LPCWSTR lpExistingFileName=NULL;
	LPCWSTR lpNewFileName=NULL;
	LPPROGRESS_ROUTINE lpProgressRoutine=NULL;
	LPVOID lpData=NULL;
	LPBOOL pbCancel=NULL;
	DWORD dwCopyFlags=NULL;
	BOOL returnVal_Real = NULL;
	BOOL returnVal_Intercepted = NULL;

	DWORD error_Real = 0;
	DWORD error_Intercepted = 0;
	disableInterception();
	returnVal_Real = CopyFileExW (lpExistingFileName,lpNewFileName,lpProgressRoutine,lpData,pbCancel,dwCopyFlags);
	error_Real = GetLastError();
	enableInterception();
	returnVal_Intercepted = CopyFileExW (lpExistingFileName,lpNewFileName,lpProgressRoutine,lpData,pbCancel,dwCopyFlags);
	error_Intercepted = GetLastError();
	return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted));
}
Exemplo n.º 3
0
/*
 * @implemented
 */
BOOL
WINAPI
CopyFileW (
	LPCWSTR	lpExistingFileName,
	LPCWSTR	lpNewFileName,
	BOOL	bFailIfExists
	)
{
	return CopyFileExW (lpExistingFileName,
	                    lpNewFileName,
	                    NULL,
	                    NULL,
	                    NULL,
	                    bFailIfExists);
}
Exemplo n.º 4
0
static BOOL transfer_file_local(BackgroundCopyFileImpl *file, const WCHAR *tmpname)
{
    static const WCHAR fileW[] = {'f','i','l','e',':','/','/',0};
    BackgroundCopyJobImpl *job = file->owner;
    const WCHAR *ptr;
    BOOL ret;

    transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING);

    if (strlenW(file->info.RemoteName) > 7 && !memicmpW(file->info.RemoteName, fileW, 7))
        ptr = file->info.RemoteName + 7;
    else
        ptr = file->info.RemoteName;

    if (!(ret = CopyFileExW(ptr, tmpname, progress_callback_local, file, NULL, 0)))
    {
        WARN("Local file copy failed: error %u\n", GetLastError());
        transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
    }

    SetEvent(job->done);
    return ret;
}
Exemplo n.º 5
0
BOOL
APIENTRY
MoveFileExW(
    LPCWSTR lpExistingFileName,
    LPCWSTR lpNewFileName,
    DWORD dwFlags
    )

/*++

Routine Description:

    An existing file can be renamed using MoveFile.

Arguments:

    lpExistingFileName - Supplies the name of an existing file that is to be
        renamed.

    lpNewFileName - Supplies the new name for the existing file.  The new
        name must reside in the same file system/drive as the existing
        file and must not already exist.

    dwFlags - Supplies optional flag bits to control the behavior of the
        rename.  The following bits are currently defined:

        MOVEFILE_REPLACE_EXISTING - if the new file name exists, replace
            it by renaming the old file name on top of the new file name.

        MOVEFILE_COPY_ALLOWED - if the new file name is on a different
            volume than the old file name, and causes the rename operation
            to fail, then setting this flag allows the MoveFileEx API
            call to simulate the rename with a call to CopyFile followed
            by a call to DeleteFile to the delete the old file if the
            CopyFile was successful.

        MOVEFILE_DELAY_UNTIL_REBOOT - dont actually do the rename now, but
            instead queue the rename so that it will happen the next time
            the system boots.  If this flag is set, then the lpNewFileName
            parameter may be NULL, in which case a delay DeleteFile of
            the old file name will occur the next time the system is
            booted.

            The delay rename/delete operations occur immediately after
            AUTOCHK is run, but prior to creating any paging files, so
            it can be used to delete paging files from previous boots
            before they are reused.

        MOVEFILE_WRITE_THROUGH - perform the rename operation in such a
            way that the file has actually been moved on the disk before
            the API returns to the caller.  Note that this flag causes a
            flush at the end of a copy operation (if one were allowed and
            necessary), and has no effect if the rename operation is
            delayed until the next reboot.

Return Value:

    TRUE - The operation was successful.

    FALSE/NULL - The operation failed. Extended error status is available
        using GetLastError.

--*/

{
    NTSTATUS Status;
    BOOLEAN ReplaceIfExists;
    OBJECT_ATTRIBUTES Obja;
    HANDLE Handle;
    UNICODE_STRING OldFileName;
    UNICODE_STRING NewFileName;
    IO_STATUS_BLOCK IoStatusBlock;
    PFILE_RENAME_INFORMATION NewName;
    BOOLEAN TranslationStatus;
    RTL_RELATIVE_NAME RelativeName;
    PVOID FreeBuffer;
    ULONG OpenFlags;
    BOOLEAN fDoCrossVolumeMove;
    BOOLEAN b;

#ifdef _CAIRO_
    OBJECTID oid;
    OBJECTID *poid; // only can be valid when fDoCrossVolumeMove = TRUE
#else
    PVOID poid = NULL;
#endif

    //
    // if the target is a device, do not allow the rename !
    //
    if ( lpNewFileName ) {
        if ( RtlIsDosDeviceName_U((PWSTR)lpNewFileName) ) {
            SetLastError(ERROR_ALREADY_EXISTS);
            return FALSE;
        }
    }

    if (dwFlags & MOVEFILE_REPLACE_EXISTING) {
        ReplaceIfExists = TRUE;
    } else {
        ReplaceIfExists = FALSE;
    }

    TranslationStatus = RtlDosPathNameToNtPathName_U(
                            lpExistingFileName,
                            &OldFileName,
                            NULL,
                            &RelativeName
                            );

    if ( !TranslationStatus ) {
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
    }

    FreeBuffer = OldFileName.Buffer;

    if (!(dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT)) {

        if ( RelativeName.RelativeName.Length ) {
            OldFileName = *(PUNICODE_STRING)&RelativeName.RelativeName;
        } else {
            RelativeName.ContainingDirectory = NULL;
        }
        InitializeObjectAttributes(
            &Obja,
            &OldFileName,
            OBJ_CASE_INSENSITIVE,
            RelativeName.ContainingDirectory,
            NULL
            );

        //
        // Open the file for delete access
        //

        OpenFlags = FILE_SYNCHRONOUS_IO_NONALERT |
                    FILE_OPEN_FOR_BACKUP_INTENT |
                    (dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0;

        Status = NtOpenFile(
                    &Handle,
#ifdef _CAIRO_
                    FILE_READ_ATTRIBUTES |
#endif
                    (ACCESS_MASK)DELETE | SYNCHRONIZE,
                    &Obja,
                    &IoStatusBlock,
                    FILE_SHARE_READ | FILE_SHARE_WRITE,
                    OpenFlags
                    );

        if ( !NT_SUCCESS(Status) ) {
            RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
            BaseSetLastNTError(Status);
            return FALSE;
        }
    }

    if (!(dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) ||
        (lpNewFileName != NULL)) {
        TranslationStatus = RtlDosPathNameToNtPathName_U(
                                lpNewFileName,
                                &NewFileName,
                                NULL,
                                NULL
                                );

        if ( !TranslationStatus ) {
            RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
            SetLastError(ERROR_PATH_NOT_FOUND);
            NtClose(Handle);
            return FALSE;
            }
    } else {
        RtlInitUnicodeString( &NewFileName, NULL );
    }

    if (dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT) {
        //
        // copy allowed is not permitted on delayed renames
        //


        //
        // (typical stevewo hack, preserved for sentimental value)
        //
        // If ReplaceIfExists is TRUE, prepend an exclamation point
        // to the new filename in order to pass this bit of data
        // along to the session manager.
        //
        if (ReplaceIfExists &&
            (NewFileName.Length != 0)) {
            PWSTR NewBuffer;

            NewBuffer = RtlAllocateHeap( RtlProcessHeap(),
                                         MAKE_TAG( TMP_TAG ),
                                         NewFileName.Length + sizeof(WCHAR) );
            if (NewBuffer != NULL) {
                NewBuffer[0] = L'!';
                CopyMemory(&NewBuffer[1], NewFileName.Buffer, NewFileName.Length);
                NewFileName.Length += sizeof(WCHAR);
                NewFileName.MaximumLength += sizeof(WCHAR);
                RtlFreeHeap(RtlProcessHeap(), 0, NewFileName.Buffer);
                NewFileName.Buffer = NewBuffer;
            }
        }

        if ( dwFlags & MOVEFILE_COPY_ALLOWED ) {
            Status = STATUS_INVALID_PARAMETER;
        } else {
            Status = BasepMoveFileDelayed(&OldFileName, &NewFileName);
        }
        RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
        RtlFreeHeap(RtlProcessHeap(), 0, NewFileName.Buffer);

        if (NT_SUCCESS(Status)) {
            return(TRUE);
        } else {
            BaseSetLastNTError(Status);
            return(FALSE);
        }
    }

    RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);
    FreeBuffer = NewFileName.Buffer;

    NewName = RtlAllocateHeap(RtlProcessHeap(), MAKE_TAG( TMP_TAG ), NewFileName.Length+sizeof(*NewName));
    if (NewName != NULL) {
        RtlMoveMemory( NewName->FileName, NewFileName.Buffer, NewFileName.Length );

        NewName->ReplaceIfExists = ReplaceIfExists;
        NewName->RootDirectory = NULL;
        NewName->FileNameLength = NewFileName.Length;
        RtlFreeHeap(RtlProcessHeap(), 0, FreeBuffer);

        Status = NtSetInformationFile(
                    Handle,
                    &IoStatusBlock,
                    NewName,
                    NewFileName.Length+sizeof(*NewName),
                    FileRenameInformation
                    );
        RtlFreeHeap(RtlProcessHeap(), 0, NewName);
    } else {
        Status = STATUS_NO_MEMORY;
    }

    fDoCrossVolumeMove = (Status == STATUS_NOT_SAME_DEVICE) &&
                         (dwFlags & MOVEFILE_COPY_ALLOWED);

#ifdef _CAIRO_
    if (fDoCrossVolumeMove)
    {
        // Get the object'd OBJECTID
        poid = RtlQueryObjectId(Handle, &oid) == STATUS_SUCCESS ? &oid : NULL;
    }
#endif

    NtClose(Handle);
    if ( NT_SUCCESS(Status) ) {
        return TRUE;
    } else if ( fDoCrossVolumeMove ) {
        HELPER_CONTEXT Context;

        Context.pObjectId = poid;
        Context.dwFlags = dwFlags;
        b = CopyFileExW(
                lpExistingFileName,
                lpNewFileName,
                poid || dwFlags & MOVEFILE_WRITE_THROUGH ? BasepCrossVolumeMoveHelper : NULL,
                &Context,
                NULL,
                ReplaceIfExists ? 0 : COPY_FILE_FAIL_IF_EXISTS
                );
        if ( b ) {

            //
            // the copy worked... Delete the source of the rename
            // if it fails, try a set attributes and then a delete
            //

            if (!DeleteFileW( lpExistingFileName ) ) {

                //
                // If the delete fails, we will return true, but possibly
                // leave the source dangling
                //

                SetFileAttributesW(lpExistingFileName,FILE_ATTRIBUTE_NORMAL);
                DeleteFileW( lpExistingFileName );

            }
            return TRUE;
        } else {
            return FALSE;
        }
    } else {
        BaseSetLastNTError(Status);
        return FALSE;
    }
}
Exemplo n.º 6
0
/*
 * @implemented
 */
BOOL
WINAPI
MoveFileWithProgressW (
	LPCWSTR			lpExistingFileName,
	LPCWSTR			lpNewFileName,
	LPPROGRESS_ROUTINE	lpProgressRoutine,
	LPVOID			lpData,
	DWORD			dwFlags
	)
{
	HANDLE hFile = NULL, hNewFile = NULL;
	IO_STATUS_BLOCK IoStatusBlock;
    OBJECT_ATTRIBUTES ObjectAttributes;
	PFILE_RENAME_INFORMATION FileRename;
	NTSTATUS errCode;
	BOOL Result;
	UNICODE_STRING DstPathU;
	BOOL folder = FALSE;

	TRACE("MoveFileWithProgressW()\n");

	if (dwFlags & MOVEFILE_DELAY_UNTIL_REBOOT)
		return add_boot_rename_entry( lpExistingFileName, lpNewFileName, dwFlags );

//    if (dwFlags & MOVEFILE_WRITE_THROUGH)
//        FIXME("MOVEFILE_WRITE_THROUGH unimplemented\n");

    if (!lpNewFileName)
        return DeleteFileW(lpExistingFileName);

    /* validate & translate the filename */
    if (!RtlDosPathNameToNtPathName_U (lpNewFileName,
				           &DstPathU,
				           NULL,
				           NULL))
    {
        WARN("Invalid destination path\n");
        SetLastError(ERROR_PATH_NOT_FOUND);
        return FALSE;
    }

    InitializeObjectAttributes(&ObjectAttributes,
                               &DstPathU,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);

    errCode = NtOpenFile( &hNewFile,
                          GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
                          &ObjectAttributes,
                          &IoStatusBlock,
                          0,
                          FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
                          ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_WRITE_THROUGH : 0) );

    if (NT_SUCCESS(errCode)) /* Destination exists */
    {
        NtClose(hNewFile);

        if (!(dwFlags & MOVEFILE_REPLACE_EXISTING))
        {
			SetLastError(ERROR_ALREADY_EXISTS);
			return FALSE;
	}
	else if (GetFileAttributesW(lpNewFileName) & FILE_ATTRIBUTE_DIRECTORY)
	{
		SetLastError(ERROR_ACCESS_DENIED);
		return FALSE;
	}
    }

	hFile = CreateFileW (lpExistingFileName,
	                     GENERIC_ALL,
	                     FILE_SHARE_WRITE|FILE_SHARE_READ,
	                     NULL,
	                     OPEN_EXISTING,
	                     FILE_FLAG_BACKUP_SEMANTICS |
	                     ((dwFlags & MOVEFILE_WRITE_THROUGH) ? FILE_FLAG_WRITE_THROUGH : 0),
	                     NULL);

	if (hFile == INVALID_HANDLE_VALUE)
	{
	    return FALSE;
	}

	FileRename = RtlAllocateHeap(
		RtlGetProcessHeap(),
		HEAP_ZERO_MEMORY,
		sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length);
	if( !FileRename ) {
		CloseHandle(hFile);
		SetLastError(ERROR_NOT_ENOUGH_MEMORY);
		return FALSE;
	}
	if( dwFlags & MOVEFILE_REPLACE_EXISTING ) {
		FileRename->ReplaceIfExists = TRUE;
	}
	else {
		FileRename->ReplaceIfExists = FALSE;
	}


	memcpy(FileRename->FileName, DstPathU.Buffer, DstPathU.Length);
        RtlFreeHeap (RtlGetProcessHeap (),
		     0,
		     DstPathU.Buffer);

	FileRename->FileNameLength = DstPathU.Length;
	errCode = NtSetInformationFile (hFile,
	                                &IoStatusBlock,
	                                FileRename,
	                                sizeof(FILE_RENAME_INFORMATION) + DstPathU.Length,
	                                FileRenameInformation);
	CloseHandle(hFile);
	RtlFreeHeap(RtlGetProcessHeap(), 0, FileRename);

	if (GetFileAttributesW(lpExistingFileName) & FILE_ATTRIBUTE_DIRECTORY)
	{
           folder = TRUE;
	}

	
	/*
	 *  FIXME:
	 *  Fail now move the folder 
	 *  Before we fail at CreateFileW 
	 */
	 
	 
	if (NT_SUCCESS(errCode))
	{
		Result = TRUE;
	}
	else 
	{
 	        if (folder==FALSE)
		{
		    Result = CopyFileExW (lpExistingFileName,
		                      lpNewFileName,
		                      lpProgressRoutine,
		                      lpData,
		                      NULL,
		                      (dwFlags & MOVEFILE_REPLACE_EXISTING) ? 0 : COPY_FILE_FAIL_IF_EXISTS);
 		    if (Result)
		    {
			/* Cleanup the source file */			
	                Result = DeleteFileW (lpExistingFileName);
		    }
                  }
		 else
		 {
		   /* move folder code start */
		   WIN32_FIND_DATAW findBuffer;
		   LPWSTR lpExistingFileName2 = NULL;
		   LPWSTR lpNewFileName2 = NULL; 
		   LPWSTR lpDeleteFile = NULL;
		   INT size;
		   INT size2;
		   BOOL loop = TRUE;
		   BOOL Result = FALSE;
		   INT max_size = MAX_PATH;


		   		   /* Build the string */
		   size = wcslen(lpExistingFileName); 
		   if (size+6> max_size)
			   max_size = size + 6;

		   lpDeleteFile = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR));
		   if (lpDeleteFile == NULL)		   
		       return FALSE;		  		  

		   lpNewFileName2 = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR));
		   if (lpNewFileName2 == NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *)  lpDeleteFile);
			 return FALSE;
		   }

		   lpExistingFileName2 = (LPWSTR) HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,max_size * sizeof(WCHAR));
		   if (lpExistingFileName2 == NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);		  	  		    		
		     HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		     return FALSE;
		   }		   		   
		
		   wcscpy( (WCHAR *)lpExistingFileName2,lpExistingFileName);
		   wcscpy( (WCHAR *)&lpExistingFileName2[size],L"\\*.*\0");
	  
		   /* Get the file name */
		   memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW));
		   hFile = FindFirstFileW(lpExistingFileName2,  &findBuffer);
		   if (hFile == INVALID_HANDLE_VALUE) 
		       loop=FALSE;

		   if (findBuffer.cFileName[0] == L'\0')
		       loop=FALSE;
		

		    /* FIXME 
			 * remove readonly flag from source folder and do not set the readonly flag to dest folder 
			 */
		   RemoveReadOnlyAttributeW(lpExistingFileName);
           RemoveReadOnlyAttributeW(lpNewFileName);
		   //CreateDirectoryExW(lpExistingFileName,lpNewFileName,NULL);
		   CreateDirectoryW(lpNewFileName, NULL);
		  		   
		   /* search the files/folders and move them */
		   while (loop==TRUE)
		   {	
		     Result = TRUE;

		     if ((!wcscmp(findBuffer.cFileName,L"..")) || (!wcscmp(findBuffer.cFileName,L".")))
		     {		  
		       loop = FindNextFileW(hFile, &findBuffer);		  
		  		  
		       if (!loop)
		       {					 
		         size = wcslen(lpExistingFileName2)-4;
		         FindClose(hFile);
		         hFile = INVALID_HANDLE_VALUE;

		         wcscpy( &lpExistingFileName2[size],L"\0");

		         if (wcsncmp(lpExistingFileName,lpExistingFileName2,size))
		         {  
				   DWORD Attributes;

				   /* delete folder */					  				 
				   TRACE("MoveFileWithProgressW : Delete folder : %S\n",lpDeleteFile);

				   /* remove system folder flag other wise we can not delete the folder */
				   Attributes = GetFileAttributesW(lpExistingFileName2);
                   if (Attributes != INVALID_FILE_ATTRIBUTES)
                   {	
                     SetFileAttributesW(lpExistingFileName2,(Attributes & ~FILE_ATTRIBUTE_SYSTEM));
				   }
				   
				   RemoveReadOnlyAttributeW(lpExistingFileName2);
					 				   
				   Result = RemoveDirectoryW(lpExistingFileName2);
				   if (Result == FALSE)
				       break;
				 				 
				   loop=TRUE;				 				 
				   size = wcslen(lpExistingFileName); 
				
				   if (size+6>max_size)
				   {				       
		              if (lpNewFileName2 != NULL)		          		
		                  HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		              if (lpExistingFileName2 != NULL)		          	  
		                  HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		              if (lpDeleteFile != NULL)		   		
		                  HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				      return FALSE;
				   }

				   wcscpy( lpExistingFileName2,lpExistingFileName);
				   wcscpy( &lpExistingFileName2[size],L"\\*.*\0");

				   /* Get the file name */
				   memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW));
				   hFile = FindFirstFileW(lpExistingFileName2, &findBuffer);	                 
		         }
               } 		  
               continue;		  		  
             }
	  	  	  
		     if (findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		     {	               

               /* Build the new src string */		  		  		  
               size = wcslen(findBuffer.cFileName); 
               size2= wcslen(lpExistingFileName2);

               if (size2+size+6>max_size)
               {
	              FindClose(hFile);    		 

		         if (lpNewFileName2 != NULL)		          		
		              HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		         if (lpExistingFileName2 != NULL)		          	  
		              HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		         if (lpDeleteFile != NULL)		   		
		              HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				 return FALSE;			      				 
	           }

	            wcscpy( &lpExistingFileName2[size2-3],findBuffer.cFileName);			   			  
                wcscpy( &lpExistingFileName2[size2+size-3],L"\0");
			   

			   /* Continue */
			   wcscpy( lpDeleteFile,lpExistingFileName2);
	           wcscpy( &lpExistingFileName2[size2+size-3],L"\\*.*\0");
          
		  
	           /* Build the new dst string */
	           size = wcslen(lpExistingFileName2) + wcslen(lpNewFileName);
	           size2 = wcslen(lpExistingFileName);
		  
	           if (size>max_size)
	           {
	             FindClose(hFile);    		 

		         if (lpNewFileName2 != NULL)		          		
		              HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		         if (lpExistingFileName2 != NULL)		          	  
		              HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		         if (lpDeleteFile != NULL)		   		
		              HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				 return FALSE;			     
	           }

	           wcscpy( lpNewFileName2,lpNewFileName);		 		  
	           size = wcslen(lpNewFileName);		 
	           wcscpy( &lpNewFileName2[size], &lpExistingFileName2[size2]);
	           size = wcslen(lpNewFileName2);
	           wcscpy( &lpNewFileName2[size-4],L"\0");
	           
	           /* Create Folder */	          

			   /* FIXME 
			    * remove readonly flag from source folder and do not set the readonly flag to dest folder 
				*/
			   RemoveReadOnlyAttributeW(lpDeleteFile);
			   RemoveReadOnlyAttributeW(lpNewFileName2);

			   CreateDirectoryW(lpNewFileName2,NULL);
	           //CreateDirectoryExW(lpDeleteFile, lpNewFileName2,NULL);
			   

			   /* set new search path  from src string */
	           FindClose(hFile);
	           memset(&findBuffer,0,sizeof(WIN32_FIND_DATAW));
	           hFile = FindFirstFileW(lpExistingFileName2, &findBuffer);
	         }
		     else
		     {
		  
	           /* Build the new string */		  		  		  		  
	           size = wcslen(findBuffer.cFileName); 
	           size2= wcslen(lpExistingFileName2);
	           wcscpy( lpDeleteFile,lpExistingFileName2);	   
	           wcscpy( &lpDeleteFile[size2-3],findBuffer.cFileName);	   
		  
	           /* Build dest string */
	           size = wcslen(lpDeleteFile) + wcslen(lpNewFileName);
	           size2 = wcslen(lpExistingFileName);

	           if (size>max_size)
	           {                 				  
			      FindClose(hFile);    		 

		          if (lpNewFileName2 != NULL)		          		
		              HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		           
		          if (lpExistingFileName2 != NULL)		          	  
		              HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		           		   
		          if (lpDeleteFile != NULL)		   		
		              HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		          
				  return FALSE;
			   }
		  
               wcscpy( lpNewFileName2,lpNewFileName);		 		  
               size = wcslen(lpNewFileName);		 
               wcscpy(&lpNewFileName2[size],&lpDeleteFile[size2]);
		 
              
			   /* overrite existsen file, if the file got the flag have readonly 
			    * we need reomve that flag 
				*/
			   
			    /* copy file */
			   
			   TRACE("MoveFileWithProgressW : Copy file : %S to %S\n",lpDeleteFile, lpNewFileName2);
			   RemoveReadOnlyAttributeW(lpDeleteFile);
			   RemoveReadOnlyAttributeW(lpNewFileName2);
			  
			   Result = CopyFileExW (lpDeleteFile,
		                      lpNewFileName2,
		                      lpProgressRoutine,
		                      lpData,
		                      NULL,
		                      0);

			   if (Result == FALSE)                                
                   break;
              
               /* delete file */               		            
			   TRACE("MoveFileWithProgressW : remove readonly flag from file : %S\n",lpNewFileName2);
			   Result = RemoveReadOnlyAttributeW(lpDeleteFile);
			   if (Result == FALSE)
			       break;

               TRACE("MoveFileWithProgressW : Delete file : %S\n",lpDeleteFile);
			   Result = DeleteFileW(lpDeleteFile);
               if (Result == FALSE)                               
                   break;
              
             }	  	              
             loop = FindNextFileW(hFile, &findBuffer);	  	  
           }

           
		   /* Remove last folder */
           if ((loop == FALSE) && (Result != FALSE))
		   {
		     DWORD Attributes;

			 Attributes = GetFileAttributesW(lpDeleteFile);
             if (Attributes != INVALID_FILE_ATTRIBUTES)
             {	
                SetFileAttributesW(lpDeleteFile,(Attributes & ~FILE_ATTRIBUTE_SYSTEM));
			 }
					 				   				 
		     Result = RemoveDirectoryW(lpExistingFileName);		     
		   }
           
		   /* Cleanup */
		   FindClose(hFile);    
		   
		   if (lpNewFileName2 != NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *)  lpNewFileName2);
		     lpNewFileName2 = NULL;
		   }

		   if (lpExistingFileName2 != NULL)
		   {	  
		     HeapFree(GetProcessHeap(),0,(VOID *) lpExistingFileName2);		
		     lpExistingFileName2 = NULL;
		   }

		   if (lpDeleteFile != NULL)
		   {		
		     HeapFree(GetProcessHeap(),0,(VOID *) lpDeleteFile);		
		     lpDeleteFile = NULL;
		   }

           return Result;

		   // end move folder code		 
		  }
	}
	
	
	return Result;
}
Exemplo n.º 7
0
int
iop_cp(io_args_t *const args)
{
	const char *const src = args->arg1.src;
	const char *const dst = args->arg2.dst;
	const IoCrs crs = args->arg3.crs;
	const io_confirm confirm = args->confirm;
	const int cancellable = args->cancellable;
	struct stat st;

	char block[BLOCK_SIZE];
	FILE *in, *out;
	size_t nread;
	int error;
	struct stat src_st;
	const char *open_mode = "wb";

	ioeta_update(args->estim, src, dst, 0, 0);

#ifdef _WIN32
	if(is_symlink(src) || crs != IO_CRS_APPEND_TO_FILES)
	{
		DWORD flags;
		int error;
		wchar_t *utf16_src, *utf16_dst;

		flags = COPY_FILE_COPY_SYMLINK;
		if(crs == IO_CRS_FAIL)
		{
			flags |= COPY_FILE_FAIL_IF_EXISTS;
		}
		else if(path_exists(dst, DEREF))
		{
			/* Ask user whether to overwrite destination file. */
			if(confirm != NULL && !confirm(args, src, dst))
			{
				return 0;
			}
		}

		utf16_src = utf8_to_utf16(src);
		utf16_dst = utf8_to_utf16(dst);

		error = CopyFileExW(utf16_src, utf16_dst, &win_progress_cb, args, NULL,
				flags) == 0;

		if(error)
		{
			/* FIXME: use real system error message here. */
			(void)ioe_errlst_append(&args->result.errors, dst, IO_ERR_UNKNOWN,
					"Copy file failed");
		}

		free(utf16_src);
		free(utf16_dst);

		ioeta_update(args->estim, NULL, NULL, 1, 0);

		return error;
	}
#endif

	/* Create symbolic link rather than copying file it points to.  This check
	 * should go before directory check as is_dir() resolves symbolic links. */
	if(is_symlink(src))
	{
		char link_target[PATH_MAX];
		int error;

		io_args_t ln_args = {
			.arg1.path = link_target,
			.arg2.target = dst,
			.arg3.crs = crs,

			.cancellable = cancellable,

			.result = args->result,
		};

		if(get_link_target(src, link_target, sizeof(link_target)) != 0)
		{
			(void)ioe_errlst_append(&args->result.errors, src, IO_ERR_UNKNOWN,
					"Failed to get symbolic link target");
			return 1;
		}

		error = iop_ln(&ln_args);
		args->result = ln_args.result;

		if(error != 0)
		{
			(void)ioe_errlst_append(&args->result.errors, src, IO_ERR_UNKNOWN,
					"Failed to make symbolic link");
			return 1;
		}
		return 0;
	}

	if(is_dir(src))
	{
		(void)ioe_errlst_append(&args->result.errors, src, EISDIR,
				strerror(EISDIR));
		return 1;
	}

	if(os_stat(src, &st) != 0)
	{
		(void)ioe_errlst_append(&args->result.errors, src, errno, strerror(errno));
		return 1;
	}

#ifndef _WIN32
	/* Fifo/socket/device files don't need to be opened, their content is not
	 * accessed. */
	if(S_ISFIFO(st.st_mode) || S_ISSOCK(st.st_mode) || S_ISBLK(st.st_mode) ||
			S_ISCHR(st.st_mode))
	{
		in = NULL;
	}
	else
#endif
	{
		in = os_fopen(src, "rb");
		if(in == NULL)
		{
			(void)ioe_errlst_append(&args->result.errors, src, errno,
					strerror(errno));
			return 1;
		}
	}

	if(crs == IO_CRS_APPEND_TO_FILES)
	{
		open_mode = "ab";
	}
	else if(crs != IO_CRS_FAIL)
	{
		int ec;

		if(path_exists(dst, DEREF))
		{
			/* Ask user whether to overwrite destination file. */
			if(confirm != NULL && !confirm(args, src, dst))
			{
				if(in != NULL && fclose(in) != 0)
				{
					(void)ioe_errlst_append(&args->result.errors, src, errno,
							strerror(errno));
				}
				return 0;
			}
		}

		ec = unlink(dst);
		if(ec != 0 && errno != ENOENT)
		{
			(void)ioe_errlst_append(&args->result.errors, dst, errno,
					strerror(errno));
			if(in != NULL && fclose(in) != 0)
			{
				(void)ioe_errlst_append(&args->result.errors, src, errno,
						strerror(errno));
			}
			return ec;
		}

		/* XXX: possible improvement would be to generate temporary file name in the
		 * destination directory, write to it and then overwrite destination file,
		 * but this approach has disadvantage of requiring more free space on
		 * destination file system. */
	}
	else if(path_exists(dst, DEREF))
	{
		(void)ioe_errlst_append(&args->result.errors, src, EEXIST,
				strerror(EEXIST));
		if(in != NULL && fclose(in) != 0)
		{
			(void)ioe_errlst_append(&args->result.errors, src, errno,
					strerror(errno));
		}
		return 1;
	}

#ifndef _WIN32
	/* Replicate fifo without even opening it. */
	if(S_ISFIFO(st.st_mode))
	{
		if(mkfifo(dst, st.st_mode & 07777) != 0)
		{
			(void)ioe_errlst_append(&args->result.errors, src, errno,
					strerror(errno));
			return 1;
		}
		return 0;
	}

	/* Replicate socket or device file without even opening it. */
	if(S_ISSOCK(st.st_mode) || S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
	{
		if(mknod(dst, st.st_mode & (S_IFMT | 07777), st.st_rdev) != 0)
		{
			(void)ioe_errlst_append(&args->result.errors, src, errno,
					strerror(errno));
			return 1;
		}
		return 0;
	}
#endif

	out = os_fopen(dst, open_mode);
	if(out == NULL)
	{
		(void)ioe_errlst_append(&args->result.errors, dst, errno, strerror(errno));
		if(fclose(in) != 0)
		{
			(void)ioe_errlst_append(&args->result.errors, src, errno,
					strerror(errno));
		}
		return 1;
	}

	error = 0;

	if(crs == IO_CRS_APPEND_TO_FILES)
	{
		fpos_t pos;
		/* The following line is required for stupid Windows sometimes.  Why?
		 * Probably because it's stupid...  Won't harm other systems. */
		fseek(out, 0, SEEK_END);
		error = fgetpos(out, &pos) != 0 || fsetpos(in, &pos) != 0;

		if(!error)
		{
			ioeta_update(args->estim, NULL, NULL, 0, get_file_size(dst));
		}
	}

	/* TODO: use sendfile() if platform supports it. */

	while((nread = fread(&block, 1, sizeof(block), in)) != 0U)
	{
		if(cancellable && ui_cancellation_requested())
		{
			error = 1;
			break;
		}

		if(fwrite(&block, 1, nread, out) != nread)
		{
			(void)ioe_errlst_append(&args->result.errors, dst, errno,
					strerror(errno));
			error = 1;
			break;
		}

		ioeta_update(args->estim, NULL, NULL, 0, nread);
	}
	if(nread == 0U && !feof(in) && ferror(in))
	{
		(void)ioe_errlst_append(&args->result.errors, src, errno, strerror(errno));
	}

	if(fclose(in) != 0)
	{
		(void)ioe_errlst_append(&args->result.errors, src, errno, strerror(errno));
	}
	if(fclose(out) != 0)
	{
		(void)ioe_errlst_append(&args->result.errors, dst, errno, strerror(errno));
	}

	if(error == 0 && os_lstat(src, &src_st) == 0)
	{
		error = os_chmod(dst, src_st.st_mode & 07777);
		if(error != 0)
		{
			(void)ioe_errlst_append(&args->result.errors, dst, errno,
					strerror(errno));
		}
	}

	ioeta_update(args->estim, NULL, NULL, 1, 0);

	return error;
}

#ifdef _WIN32

static DWORD CALLBACK win_progress_cb(LARGE_INTEGER total,
		LARGE_INTEGER transferred, LARGE_INTEGER stream_size,
		LARGE_INTEGER stream_transfered, DWORD stream_num, DWORD reason,
		HANDLE src_file, HANDLE dst_file, LPVOID param)
{
	static LONGLONG last_size;

	io_args_t *const args = param;

	const char *const src = args->arg1.src;
	const char *const dst = args->arg2.dst;
	ioeta_estim_t *const estim = args->estim;

	if(transferred.QuadPart < last_size)
	{
		last_size = 0;
	}

	ioeta_update(estim, src, dst, 0, transferred.QuadPart - last_size);

	last_size = transferred.QuadPart;

	if(args->cancellable && ui_cancellation_requested())
	{
		return PROGRESS_CANCEL;
	}

	return PROGRESS_CONTINUE;
}

#endif

/* TODO: implement iop_chown(). */
int iop_chown(io_args_t *const args);

/* TODO: implement iop_chgrp(). */
int iop_chgrp(io_args_t *const args);

/* TODO: implement iop_chmod(). */
int iop_chmod(io_args_t *const args);

int
iop_ln(io_args_t *const args)
{
	const char *const path = args->arg1.path;
	const char *const target = args->arg2.target;
	const int overwrite = args->arg3.crs != IO_CRS_FAIL;

	int result;

#ifdef _WIN32
	char cmd[6 + PATH_MAX*2 + 1];
	char *escaped_path, *escaped_target;
	char base_dir[PATH_MAX + 2];
#endif

#ifndef _WIN32
	result = symlink(path, target);
	if(result != 0 && errno == EEXIST && overwrite && is_symlink(target))
	{
		result = remove(target);
		if(result == 0)
		{
			result = symlink(path, target);
			if(result != 0)
			{
				(void)ioe_errlst_append(&args->result.errors, path, errno,
						strerror(errno));
			}
		}
		else
		{
			(void)ioe_errlst_append(&args->result.errors, target, errno,
					strerror(errno));
		}
	}
	else if(result != 0 && errno != 0)
	{
		(void)ioe_errlst_append(&args->result.errors, target, errno,
				strerror(errno));
	}
#else
	if(!overwrite && path_exists(target, DEREF))
	{
		(void)ioe_errlst_append(&args->result.errors, target, EEXIST,
				strerror(EEXIST));
		return -1;
	}

	if(overwrite && !is_symlink(target))
	{
		(void)ioe_errlst_append(&args->result.errors, target, IO_ERR_UNKNOWN,
				"Target is not a symbolic link");
		return -1;
	}

	escaped_path = shell_like_escape(path, 0);
	escaped_target = shell_like_escape(target, 0);
	if(escaped_path == NULL || escaped_target == NULL)
	{
		(void)ioe_errlst_append(&args->result.errors, target, IO_ERR_UNKNOWN,
				"Not enough memory");
		free(escaped_target);
		free(escaped_path);
		return -1;
	}

	if(GetModuleFileNameA(NULL, base_dir, ARRAY_LEN(base_dir)) == 0)
	{
		(void)ioe_errlst_append(&args->result.errors, target, IO_ERR_UNKNOWN,
				"Failed to find win_helper");
		free(escaped_target);
		free(escaped_path);
		return -1;
	}

	break_atr(base_dir, '\\');
	snprintf(cmd, sizeof(cmd), "%s\\win_helper -s %s %s", base_dir, escaped_path,
			escaped_target);

	result = os_system(cmd);
	if(result != 0)
	{
		(void)ioe_errlst_append(&args->result.errors, target, IO_ERR_UNKNOWN,
				"Running win_helper has failed");
	}

	free(escaped_target);
	free(escaped_path);
#endif

	return result;
}
Exemplo n.º 8
0
BOOL processFile(BackgroundCopyFileImpl *file, BackgroundCopyJobImpl *job)
{
    static const WCHAR prefix[] = {'B','I','T', 0};
    DLBindStatusCallback *callbackObj;
    WCHAR tmpDir[MAX_PATH];
    WCHAR tmpName[MAX_PATH];
    HRESULT hr;

    if (!GetTempPathW(MAX_PATH, tmpDir))
    {
        ERR("Couldn't create temp file name: %d\n", GetLastError());
        /* Guessing on what state this should give us */
        transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
        return FALSE;
    }

    if (!GetTempFileNameW(tmpDir, prefix, 0, tmpName))
    {
        ERR("Couldn't create temp file: %d\n", GetLastError());
        /* Guessing on what state this should give us */
        transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
        return FALSE;
    }

    callbackObj = DLBindStatusCallbackConstructor(file);
    if (!callbackObj)
    {
        ERR("Out of memory\n");
        transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSIENT_ERROR);
        return FALSE;
    }

    EnterCriticalSection(&job->cs);
    file->fileProgress.BytesTotal = BG_SIZE_UNKNOWN;
    file->fileProgress.BytesTransferred = 0;
    file->fileProgress.Completed = FALSE;
    LeaveCriticalSection(&job->cs);

    TRACE("Transferring: %s -> %s -> %s\n",
          debugstr_w(file->info.RemoteName),
          debugstr_w(tmpName),
          debugstr_w(file->info.LocalName));

    transitionJobState(job, BG_JOB_STATE_QUEUED, BG_JOB_STATE_TRANSFERRING);

    DeleteUrlCacheEntryW(file->info.RemoteName);
    hr = URLDownloadToFileW(NULL, file->info.RemoteName, tmpName, 0,
                            &callbackObj->IBindStatusCallback_iface);
    IBindStatusCallback_Release(&callbackObj->IBindStatusCallback_iface);
    if (hr == INET_E_DOWNLOAD_FAILURE)
    {
        TRACE("URLDownload failed, trying local file copy\n");
        if (!CopyFileExW(file->info.RemoteName, tmpName, copyProgressCallback,
                         file, NULL, 0))
        {
            ERR("Local file copy failed: error %d\n", GetLastError());
            transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
            return FALSE;
        }
    }
    else if (FAILED(hr))
    {
        ERR("URLDownload failed: eh 0x%08x\n", hr);
        transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_ERROR);
        return FALSE;
    }

    if (transitionJobState(job, BG_JOB_STATE_TRANSFERRING, BG_JOB_STATE_QUEUED))
    {
        lstrcpyW(file->tempFileName, tmpName);

        EnterCriticalSection(&job->cs);
        file->fileProgress.Completed = TRUE;
        job->jobProgress.FilesTransferred++;
        LeaveCriticalSection(&job->cs);

        return TRUE;
    }
    else
    {
        DeleteFileW(tmpName);
        return FALSE;
    }
}